From fa29ff4c43032762d0976ca5d4d479eb7cbc18c5 Mon Sep 17 00:00:00 2001 From: AlphaX-Projects <77661270+AlphaX-Projects@users.noreply.github.com> Date: Wed, 8 May 2024 13:16:23 +0200 Subject: [PATCH 01/11] Update UI Refactor and added new functioms --- README.md | 4 +- build.js | 29 +- config/build.config.js | 16 +- config/coin.config.js | 10 +- config/config.js | 46 +- config/crypto.config.js | 2 +- config/customConfig.js | 8 +- config/default.config.js | 3 +- config/styles.config.js | 2 +- config/user.config.js | 9 +- core/config/config.js | 2 +- core/config/default.build.options.js | 216 +- core/config/default.coin.config.js | 16 +- core/config/default.crypto.config.js | 16 +- core/config/default.styles.config.js | 69 +- core/config/default.user.config.js | 75 +- core/config/load-config.js | 25 +- core/font/switch-theme.css | 2 + core/language/us.json | 11 +- core/public/index.html | 254 +- core/server/ServerFactory.js | 47 +- core/server/routes/createCommonRoutes.js | 192 +- core/server/routes/createPrimaryRoutes.js | 247 +- core/server/server.js | 26 +- core/src/apiKeyUtils.js | 83 +- core/src/components/WebWorkerFile.js | 6 +- core/src/components/app-info.js | 222 +- core/src/components/app-view.js | 5671 +++---- core/src/components/base.js | 29 +- .../beginner-tour/sync-indicator.js | 80 +- .../beginner-tour/tour-component.js | 542 +- core/src/components/check-for-update.js | 15 +- core/src/components/computePowWorker.js | 114 +- core/src/components/computePowWorkerFile.js | 134 +- .../controllers/coin-balances-controller.js | 559 +- .../friends-view/ChatSideNavHeads.js | 391 +- .../friends-view/add-friends-modal.js | 633 +- core/src/components/friends-view/avatar.js | 473 +- .../friends-view/beginner-checklist.js | 454 +- .../friends-view/computePowWorkerFile.src.js | 136 +- .../friends-view/core-sync-status.js | 104 +- core/src/components/friends-view/feed-item.js | 743 +- .../friends-view/friend-item-actions.js | 250 +- .../components/friends-view/friends-feed.js | 733 +- .../friends-view/friends-side-panel-parent.js | 90 +- .../friends-view/friends-side-panel.js | 208 +- .../friends-view/friends-view-css.js | 182 - .../components/friends-view/friends-view.js | 491 +- .../friends-view/profile-modal-update.js | 896 +- core/src/components/friends-view/profile.js | 1617 +- .../friends-view/save-settings-qdn.js | 878 +- core/src/components/language-selector.js | 171 +- .../login-view/create-account-section.js | 1135 +- .../components/login-view/login-section.js | 1359 +- core/src/components/login-view/login-view.js | 655 +- .../src/components/login-view/welcome-page.js | 102 +- .../src/components/logout-view/logout-view.js | 111 +- core/src/components/main-app.js | 117 +- core/src/components/new-selector.js | 200 +- .../notification-bell-general.js | 656 +- .../notification-view/notification-bell.js | 517 +- .../components/notification-view/popover.js | 106 +- core/src/components/qort-theme-toggle.js | 172 +- core/src/components/search-modal.js | 68 +- .../components/settings-view/account-view.js | 202 +- .../components/settings-view/export-keys.js | 916 +- .../settings-view/notifications-view.js | 370 +- .../components/settings-view/qr-login-view.js | 193 +- .../components/settings-view/security-view.js | 406 +- .../components/settings-view/user-settings.js | 405 +- core/src/components/show-plugin.js | 4308 +++-- core/src/components/start-minting.js | 556 +- core/src/components/theme-toggle.js | 65 +- .../user-info-view/user-info-view.js | 3371 ++-- core/src/components/wallet-profile.js | 186 +- core/src/cryptoUtils.js | 101 +- core/src/custom-elements/frag-file-input.js | 115 - core/src/data/defaultQapps.js | 11 + core/src/epml.js | 2 +- .../confirm-transaction-dialog.js | 155 +- .../functional-components/frag-file-input.js | 93 + .../functional-components/loading-ripple.js | 277 +- core/src/functional-components/my-button.js | 60 +- core/src/functional-components/mykey-page.js | 185 +- .../random-sentence-generator.js | 78 +- .../functional-components/settings-page.js | 352 +- .../side-menu-item-style.js | 157 - .../functional-components/side-menu-item.js | 372 +- core/src/functional-components/side-menu.js | 120 +- core/src/functional-components/snackbar.js | 126 +- .../functional-components/verb-past-tense.js | 10 +- core/src/functional-components/wordlists.js | 19 +- core/src/initStore.js | 50 +- core/src/localStorageHelpers.js | 30 +- core/src/lockScreen.js | 16 +- core/src/main.js | 4 +- core/src/notifications/config.js | 18 +- core/src/notifications/controller.js | 144 +- core/src/notifications/dispatcher.js | 22 +- .../notification-actions/index.js | 2 +- .../notification-actions/new-message.js | 467 +- core/src/notifications/types.js | 2 +- core/src/persistState.js | 29 +- core/src/plugins/addPluginRoutes.js | 10 +- core/src/plugins/load-plugins.js | 69 +- core/src/plugins/plugin-mainjs-loader.html | 11 +- core/src/plugins/plugin-mainjs-loader.js | 9 +- core/src/plugins/routes.js | 130 +- core/src/plugins/streams.js | 85 +- core/src/redux/app/actions/app-core.js | 238 +- core/src/redux/app/actions/init-worker.js | 52 +- core/src/redux/app/actions/login.js | 52 +- core/src/redux/app/actions/node-config.js | 156 +- core/src/redux/app/actions/plugins.js | 46 +- core/src/redux/app/app-action-types.js | 2 +- core/src/redux/app/app-actions.js | 38 +- core/src/redux/app/app-reducer.js | 689 +- core/src/redux/app/reducers/init-workers.js | 64 +- core/src/redux/app/reducers/login-reducer.js | 44 +- core/src/redux/app/reducers/manage-node.js | 75 +- core/src/redux/config/config-actions.js | 36 +- core/src/redux/config/config-reducer.js | 56 +- .../config/reducers/load-config-from-api.js | 42 +- core/src/redux/reducers.js | 13 +- core/src/redux/user/actions/claim-airdrop.js | 18 +- .../redux/user/actions/notification-config.js | 63 +- core/src/redux/user/actions/store-wallet.js | 66 +- .../redux/user/actions/update-account-info.js | 18 +- core/src/redux/user/actions/update-name.js | 74 +- core/src/redux/user/user-actions.js | 8 +- core/src/redux/user/user-reducer.js | 122 +- core/src/stateAwait.js | 34 +- core/src/store.js | 13 +- core/src/styles/app-styles.js | 107 +- core/src/styles/app-theme.js | 98 +- core/src/styles/core-css.js | 4753 ++++++ core/src/styles/styles.scss | 4 +- core/src/styles/switch-theme.css | 19 +- core/src/tradebot/addTradeBotRoutes.js | 10 +- core/src/tradebot/trade-bot-routes.js | 62 +- core/src/transactionRequest.js | 12 +- core/src/worker.js | 22 +- core/tooling/build.js | 43 +- core/tooling/generateBuildConfig.js | 157 +- core/tooling/generateES5BuildConfig.js | 122 +- core/tooling/utils.js | 19 +- core/tooling/watch-inlines.js | 26 +- core/tooling/watch.js | 47 +- .../translate/directives/lang-changed-base.js | 58 +- core/translate/directives/lang-changed.js | 7 +- .../directives/translate-unsafe-html.js | 6 +- core/translate/directives/translate.js | 6 +- core/translate/helpers.js | 18 +- core/translate/util.js | 48 +- core/ui-core.js | 12 +- crypto/api/createTransaction.js | 3 - crypto/api/fetch-request.js | 2 + crypto/api/transactions/AirdropTransaction.js | 5 +- .../api/transactions/DelegationTransaction.js | 3 +- .../api/transactions/DeployAtTransaction.js | 17 +- crypto/api/transactions/MessageTransaction.js | 9 +- crypto/api/transactions/PaymentTransaction.js | 7 +- .../api/transactions/PublicizeTransaction.js | 11 +- crypto/api/transactions/TransactionBase.js | 11 +- .../transactions/TransferPrivsTransaction.js | 19 +- .../transactions/arbitrary/signArbitrary.js | 10 +- .../arbitrary/signArbitraryWithFee.js | 12 +- crypto/api/transactions/arbitraryV3.js | 1 + crypto/api/transactions/chat/ChatBase.js | 12 +- .../api/transactions/chat/ChatTransaction.js | 10 +- .../transactions/chat/GroupChatTransaction.js | 8 +- .../transactions/chat/decryptChatMessage.js | 29 +- crypto/api/transactions/chat/signChat.js | 4 +- .../groups/AddGroupAdminTransaction.js | 5 +- .../groups/CancelGroupBanTransaction.js | 5 +- .../groups/CancelGroupInviteTransaction.js | 5 +- .../groups/CreateGroupTransaction.js | 30 +- .../groups/GroupBanTransaction.js | 7 +- .../groups/GroupInviteTransaction.js | 5 +- .../groups/GroupKickTransaction.js | 7 +- .../groups/JoinGroupTransaction.js | 5 +- .../groups/LeaveGroupTransaction.js | 5 +- .../groups/RemoveGroupAdminTransaction.js | 5 +- .../groups/UpdateGroupTransaction.js | 155 +- .../transactions/names/BuyNameTransacion.js | 5 +- .../names/CancelSellNameTransacion.js | 5 +- .../names/RegisterNameTransaction.js | 5 +- .../transactions/names/SellNameTransacion.js | 5 +- .../names/UpdateNameTransaction.js | 5 +- .../polls/CreatePollTransaction.js | 25 +- .../polls/VoteOnPollTransaction.js | 13 +- .../RemoveRewardShareTransaction.js | 9 +- .../reward-share/RewardShareTransaction.js | 21 +- .../tradebot/signTradeBotTransaction.js | 6 +- .../tradeoffer/cancelAllOffers.js | 8 +- crypto/api/transactions/transactions.js | 54 +- electron-builder.yml | 1 + electron.js | 472 +- img/qdcgroup.png | Bin 0 -> 14569 bytes img/qgcgroup.png | Bin 0 -> 28235 bytes lib/detect-platform.js | 6 +- lib/i18n.js | 303 +- lib/preload.js | 2 +- package-lock.json | 922 +- package.json | 26 +- plugins/build-config.js | 202 +- plugins/build.js | 28 +- plugins/default-plugins.js | 6 +- plugins/epml.js | 3 +- .../become-minter/become-minter-css.src.js | 253 - .../core/become-minter/become-minter.src.js | 211 +- .../become-minter/components/not-sponsored.js | 132 - .../become-minter/components/yes-sponsored.js | 107 - .../plugins/core/components/ButtonIconCopy.js | 137 +- plugins/plugins/core/components/ChatGifs.js | 923 ++ .../core/components/ChatGifs/ChatGifs-css.js | 521 - .../core/components/ChatGifs/ChatGifs.js | 980 -- .../ChatGifs/ChatGifsExplore-css.js | 157 - .../components/ChatGifs/ChatGifsExplore.js | 170 - .../core/components/ChatGifsExplore.js | 191 + .../core/components/ChatGroupInvites.js | 346 +- .../core/components/ChatGroupManager.js | 361 +- .../core/components/ChatGroupSettings.js | 358 +- .../core/components/ChatGroupsManagement.js | 411 +- .../core/components/ChatGroupsModal.js | 119 +- plugins/plugins/core/components/ChatHead.js | 482 +- plugins/plugins/core/components/ChatImage.js | 580 +- .../plugins/core/components/ChatLeaveGroup.js | 380 +- .../plugins/core/components/ChatMessage.js | 185 +- plugins/plugins/core/components/ChatModals.js | 662 +- .../plugins/core/components/ChatPage-css.js | 1154 -- plugins/plugins/core/components/ChatPage.js | 6464 ++++---- .../plugins/core/components/ChatRightPanel.js | 430 +- .../components/ChatRightPanelResources.js | 757 +- .../core/components/ChatScroller-css.js | 819 - .../plugins/core/components/ChatScroller.js | 3288 ++-- .../core/components/ChatSeachResults.js | 66 - .../core/components/ChatSearchResults-css.js | 120 - .../core/components/ChatSearchResults.js | 137 +- plugins/plugins/core/components/ChatSelect.js | 342 +- .../core/components/ChatSideNavHeads.js | 330 +- .../core/components/ChatTextEditor copy.js | 825 - .../plugins/core/components/ChatTextEditor.js | 1060 +- .../core/components/ChatWelcomePage.js | 809 +- .../plugins/core/components/ImageComponent.js | 227 +- .../plugins/core/components/LevelFounder.js | 202 +- plugins/plugins/core/components/NameMenu.js | 930 +- plugins/plugins/core/components/QRCode.js | 917 +- .../core/components/QortalFileSaver.js | 276 +- .../core/components/QortalQrcodeGenerator.js | 349 +- .../plugins/core/components/ReusableImage.js | 264 +- plugins/plugins/core/components/TimeAgo.js | 95 +- .../plugins/core/components/TipUser-css.js | 85 - plugins/plugins/core/components/TipUser.js | 517 +- plugins/plugins/core/components/ToolTip.js | 148 +- .../core/components/TradeInfoView-css.js | 1124 -- .../plugins/core/components/TradeInfoView.js | 464 +- .../plugins/core/components/TraderInfoView.js | 3389 ++-- plugins/plugins/core/components/UserInfo.js | 145 + .../core/components/UserInfo/UserInfo-css.js | 68 - .../core/components/UserInfo/UserInfo.js | 133 - .../core/components/WrapperModal-css.js | 57 - .../plugins/core/components/WrapperModal.js | 71 +- .../core/components/computePowWorker.js | 116 +- .../core/components/computePowWorkerFile.js | 136 +- .../core/components/frag-file-input.js | 173 +- .../plugins/core/components/plugins-css.js | 13539 ++++++++++++++++ .../core/components/qdn-action-constants.js | 102 +- .../core/components/qdn-action-encryption.js | 632 +- .../core/components/qdn-action-types.js | 77 +- .../core/components/qortal-info-view.js | 3143 ++-- plugins/plugins/core/components/snackbar.js | 139 +- .../time-elements/extended-time-element.js | 180 +- .../core/components/time-elements/index.js | 1375 +- .../time-elements/local-time-element.js | 177 +- .../time-elements/relative-time-element.js | 92 +- .../components/time-elements/relative-time.js | 554 +- .../time-elements/time-ago-element.js | 39 +- .../time-elements/time-until-element.js | 39 +- .../core/components/time-elements/utils.js | 320 +- .../components/webworkerDecodeMessages.js | 4653 +++--- .../core/components/webworkerSortMessages.js | 20 +- plugins/plugins/core/connect.js | 17 +- .../data-management/data-management.src.js | 932 ++ .../core/{qdn => }/data-management/index.html | 0 .../group-management/group-management.src.js | 6865 ++++---- .../group-transaction.src.js | 169 - .../group-transaction/index.html | 55 - plugins/plugins/core/index.html | 1 - plugins/plugins/core/main.src.js | 226 +- .../chain-messaging/chain-messaging.src.js | 96 - .../core/messaging/chain-messaging/index.html | 55 - plugins/plugins/core/messaging/index.html | 55 - .../plugins/core/messaging/messaging.src.js | 201 - .../messaging/q-chat/computePowWorker.src.js | 82 - .../core/messaging/q-chat/q-chat-css.src.js | 479 - .../core/{minting => minting-info}/index.html | 0 .../core/minting-info/minting-info.src.js | 776 + .../plugins/core/minting/minting-info.src.js | 899 - .../name-registration.src.js | 1878 +-- .../core/names-market/names-market.src.js | 2013 +-- .../node-management/node-management.src.js | 1007 +- .../core/overview-page/overview-page-css.js | 745 - .../core/overview-page/overview-page.src.js | 850 +- plugins/plugins/core/puzzles/puzzles.src.js | 669 +- plugins/plugins/core/q-app/q-apps.src.js | 2502 ++- .../core/{messaging => }/q-chat/index.html | 0 .../core/{messaging => }/q-chat/q-chat.src.js | 616 +- .../core/{qdn => q-website}/index.html | 4 +- .../plugins/core/q-website/q-websites.src.js | 976 ++ .../plugins/core/qdn/browser/browser.src.js | 2025 +-- .../core/qdn/browser/computePowWorker.src.js | 82 - .../qdn/browser/computePowWorkerFile.src.js | 91 - .../data-management/data-management.src.js | 1099 -- .../plugins/core/qdn/publish/publish.src.js | 1263 +- plugins/plugins/core/qdn/websites.src.js | 1116 -- .../core/qortal-lottery/qortal-lottery.src.js | 1428 +- .../core/reward-share/reward-share.src.js | 1139 +- .../sponsorship-list-css.src.js | 484 - .../sponsorship-list/sponsorship-list.src.js | 149 +- .../plugins/core/streams/AddressWatcher.js | 112 +- .../streams/UnconfirmedTransactionWatcher.js | 78 +- plugins/plugins/core/streams/onNewBlock.js | 376 +- plugins/plugins/core/streams/streams.js | 341 +- .../core/trade-bot/trade-bot-portal-css.js | 679 - .../core/trade-bot/trade-bot-portal.src.js | 6469 ++++---- .../core/trade-portal/charts/arrr-charts.js | 68 +- .../core/trade-portal/charts/btc-charts.js | 68 +- .../core/trade-portal/charts/dgb-charts.js | 68 +- .../core/trade-portal/charts/doge-charts.js | 68 +- .../core/trade-portal/charts/ltc-charts.js | 68 +- .../core/trade-portal/charts/rvn-charts.js | 68 +- .../core/trade-portal/trade-portal-css.js | 687 - .../core/trade-portal/trade-portal.src.js | 5366 +++--- plugins/plugins/core/wallet/wallet-app.src.js | 10791 ++++++------ plugins/plugins/utils/blocks-needed.js | 23 - plugins/plugins/utils/bytesToMegabytes.js | 3 - plugins/plugins/utils/classes.js | 926 ++ plugins/plugins/utils/cropAddress.js | 8 - plugins/plugins/utils/functions.js | 208 + .../plugins/utils/getUserNameFromAddress.js | 20 - plugins/plugins/utils/id-generation.js | 14 - plugins/plugins/utils/keyCodes.js | 1 - plugins/plugins/utils/loader.js | 52 - plugins/plugins/utils/publish-image.js | 248 - plugins/plugins/utils/publish-modal.css | 147 - plugins/plugins/utils/publish-modal.js | 270 - plugins/plugins/utils/queue.js | 71 - .../plugins/utils/replace-messages-edited.js | 251 - .../plugins/utils/roundToNearestDecimal.js | 4 - plugins/plugins/utils/warning-modal.js | 252 - plugins/watch.js | 3 +- scripts/afterPack.js | 52 +- scripts/notarize.js | 33 +- server.js | 30 +- watch-inline.js | 25 +- watch.js | 19 +- 357 files changed, 82113 insertions(+), 83085 deletions(-) delete mode 100644 core/src/components/friends-view/friends-view-css.js delete mode 100644 core/src/custom-elements/frag-file-input.js create mode 100644 core/src/functional-components/frag-file-input.js delete mode 100644 core/src/functional-components/side-menu-item-style.js create mode 100644 core/src/styles/core-css.js create mode 100644 img/qdcgroup.png create mode 100644 img/qgcgroup.png delete mode 100644 plugins/plugins/core/become-minter/become-minter-css.src.js delete mode 100644 plugins/plugins/core/become-minter/components/not-sponsored.js delete mode 100644 plugins/plugins/core/become-minter/components/yes-sponsored.js create mode 100644 plugins/plugins/core/components/ChatGifs.js delete mode 100644 plugins/plugins/core/components/ChatGifs/ChatGifs-css.js delete mode 100644 plugins/plugins/core/components/ChatGifs/ChatGifs.js delete mode 100644 plugins/plugins/core/components/ChatGifs/ChatGifsExplore-css.js delete mode 100644 plugins/plugins/core/components/ChatGifs/ChatGifsExplore.js create mode 100644 plugins/plugins/core/components/ChatGifsExplore.js delete mode 100644 plugins/plugins/core/components/ChatPage-css.js delete mode 100644 plugins/plugins/core/components/ChatScroller-css.js delete mode 100644 plugins/plugins/core/components/ChatSeachResults.js delete mode 100644 plugins/plugins/core/components/ChatSearchResults-css.js delete mode 100644 plugins/plugins/core/components/ChatTextEditor copy.js delete mode 100644 plugins/plugins/core/components/TipUser-css.js delete mode 100644 plugins/plugins/core/components/TradeInfoView-css.js create mode 100644 plugins/plugins/core/components/UserInfo.js delete mode 100644 plugins/plugins/core/components/UserInfo/UserInfo-css.js delete mode 100644 plugins/plugins/core/components/UserInfo/UserInfo.js delete mode 100644 plugins/plugins/core/components/WrapperModal-css.js create mode 100644 plugins/plugins/core/components/plugins-css.js create mode 100644 plugins/plugins/core/data-management/data-management.src.js rename plugins/plugins/core/{qdn => }/data-management/index.html (100%) delete mode 100644 plugins/plugins/core/group-management/group-transaction/group-transaction.src.js delete mode 100644 plugins/plugins/core/group-management/group-transaction/index.html delete mode 100644 plugins/plugins/core/index.html delete mode 100644 plugins/plugins/core/messaging/chain-messaging/chain-messaging.src.js delete mode 100644 plugins/plugins/core/messaging/chain-messaging/index.html delete mode 100644 plugins/plugins/core/messaging/index.html delete mode 100644 plugins/plugins/core/messaging/messaging.src.js delete mode 100644 plugins/plugins/core/messaging/q-chat/computePowWorker.src.js delete mode 100644 plugins/plugins/core/messaging/q-chat/q-chat-css.src.js rename plugins/plugins/core/{minting => minting-info}/index.html (100%) create mode 100644 plugins/plugins/core/minting-info/minting-info.src.js delete mode 100644 plugins/plugins/core/minting/minting-info.src.js delete mode 100644 plugins/plugins/core/overview-page/overview-page-css.js rename plugins/plugins/core/{messaging => }/q-chat/index.html (100%) rename plugins/plugins/core/{messaging => }/q-chat/q-chat.src.js (74%) rename plugins/plugins/core/{qdn => q-website}/index.html (94%) create mode 100644 plugins/plugins/core/q-website/q-websites.src.js delete mode 100644 plugins/plugins/core/qdn/browser/computePowWorker.src.js delete mode 100644 plugins/plugins/core/qdn/browser/computePowWorkerFile.src.js delete mode 100644 plugins/plugins/core/qdn/data-management/data-management.src.js delete mode 100644 plugins/plugins/core/qdn/websites.src.js delete mode 100644 plugins/plugins/core/sponsorship-list/sponsorship-list-css.src.js delete mode 100644 plugins/plugins/core/trade-bot/trade-bot-portal-css.js delete mode 100644 plugins/plugins/core/trade-portal/trade-portal-css.js delete mode 100644 plugins/plugins/utils/blocks-needed.js delete mode 100644 plugins/plugins/utils/bytesToMegabytes.js create mode 100644 plugins/plugins/utils/classes.js delete mode 100644 plugins/plugins/utils/cropAddress.js create mode 100644 plugins/plugins/utils/functions.js delete mode 100644 plugins/plugins/utils/getUserNameFromAddress.js delete mode 100644 plugins/plugins/utils/id-generation.js delete mode 100644 plugins/plugins/utils/keyCodes.js delete mode 100644 plugins/plugins/utils/loader.js delete mode 100644 plugins/plugins/utils/publish-image.js delete mode 100644 plugins/plugins/utils/publish-modal.css delete mode 100644 plugins/plugins/utils/publish-modal.js delete mode 100644 plugins/plugins/utils/queue.js delete mode 100644 plugins/plugins/utils/replace-messages-edited.js delete mode 100644 plugins/plugins/utils/roundToNearestDecimal.js delete mode 100644 plugins/plugins/utils/warning-modal.js diff --git a/README.md b/README.md index 6af149dc..f9116d7f 100644 --- a/README.md +++ b/README.md @@ -26,8 +26,8 @@ Easiest way to install the lastest required packages on Linux is via nvm. ``` source ~/.profile ``` (For Debian based distro)
``` source ~/.bashrc ``` (For Fedora / CentOS)
``` nvm ls-remote ``` (Fetch list of available versions)
-``` nvm install v18.17.1 ``` (LTS: Hydrogen supported by Electron V27)
-``` npm --location=global install npm@10.5.0 ```
+``` nvm install v20.11.1 ``` (LTS: Iron supported by Electron V30)
+``` npm --location=global install npm@10.7.0 ```
Adding via binary package mirror will only work if you have set the package path. You can do a node or java build via ports instead by downloading ports with portsnap fetch method. diff --git a/build.js b/build.js index b635217e..f0ba308f 100644 --- a/build.js +++ b/build.js @@ -1,28 +1,23 @@ const path = require('path') const uiCore = require('./core/ui-core.js') - +const config = require('./config/config.js') +const pluginsController = require('./plugins/default-plugins.js') const generateBuildConfig = uiCore('generate_build_config') const build = uiCore('build') - -const config = require('./config/config.js') - -const pluginsController = require('./plugins/default-plugins.js') const buildDefalutPlugins = pluginsController('build') - srcConfig = { - ...config.build, - options: { - ...config.build.options, - outputDir: path.join(__dirname, '/builtWWW'), - sassOutputDir: path.join(__dirname, '/builtWWW/styles.bundle.css'), - } + ...config.build, + options: { + ...config.build.options, + outputDir: path.join(__dirname, '/builtWWW'), + sassOutputDir: path.join(__dirname, '/builtWWW/styles.bundle.css') + } } const { buildConfig, inlineConfigs } = generateBuildConfig(srcConfig) -build(buildConfig.options, buildConfig.outputs, buildConfig.outputOptions, buildConfig.inputOptions, inlineConfigs) - .then(() => { - console.log("Building and Bundling Plugins"); - buildDefalutPlugins() - }) +build(buildConfig.options, buildConfig.outputs, buildConfig.outputOptions, buildConfig.inputOptions, inlineConfigs).then(() => { + console.log("Building and Bundling Plugins") + buildDefalutPlugins() +}) \ No newline at end of file diff --git a/config/build.config.js b/config/build.config.js index 938710f4..e40f22bf 100644 --- a/config/build.config.js +++ b/config/build.config.js @@ -2,13 +2,13 @@ const path = require('path') const defaultConfig = require('./default.config.js') const build = { - options: { - outputDir: path.join(__dirname, '../build'), - imgDir: path.join(__dirname, '../img') - }, - aliases: { - 'qortal-ui-crypto': path.join(__dirname, '../crypto/api.js') - } + options: { + outputDir: path.join(__dirname, '../build'), + imgDir: path.join(__dirname, '../img') + }, + aliases: { + 'qortal-ui-crypto': path.join(__dirname, '../crypto/api.js') + } } -module.exports = build +module.exports = build \ No newline at end of file diff --git a/config/coin.config.js b/config/coin.config.js index bcd320e9..0f0f1c3d 100644 --- a/config/coin.config.js +++ b/config/coin.config.js @@ -1,8 +1,8 @@ const defaultConfig = require('./default.config.js') module.exports = { - name: 'Qortal', - symbol: 'Qort', - addressVersion: 58, // Q for Qortal - logo: '/img/QORT_LOGO.svg' -} + name: 'Qortal', + symbol: 'Qort', + addressVersion: 58, // Q for Qortal + logo: '/img/QORT_LOGO.svg' +} \ No newline at end of file diff --git a/config/config.js b/config/config.js index 8fd79649..992f6466 100644 --- a/config/config.js +++ b/config/config.js @@ -1,27 +1,33 @@ let config = require('./default.config.js') -let userConfig = {} -try { - userConfig = require('./customConfig.js') -} catch (e) { - console.warn(e) - console.warn('Error loading user config') -} -const checkKeys = (storeObj, newObj) => { - for (const key in newObj) { - if (!Object.prototype.hasOwnProperty.call(storeObj, key)) return - if (typeof newObj[key] === 'object') { - storeObj[key] = checkKeys(storeObj[key], newObj[key]) - } else { - storeObj[key] = newObj[key] - } - } - return storeObj +let userConfig = {} + +try { + userConfig = require('./customConfig.js') +} catch (e) { + console.warn(e) + console.warn('Error loading user config') +} + +const checkKeys = (storeObj, newObj) => { + for (const key in newObj) { + if (!Object.prototype.hasOwnProperty.call(storeObj, key)) { + return + } + + if (typeof newObj[key] === 'object') { + storeObj[key] = checkKeys(storeObj[key], newObj[key]) + } else { + storeObj[key] = newObj[key] + } + } + + return storeObj } const getConfig = customConfig => { - config = checkKeys(config, customConfig) - return config + config = checkKeys(config, customConfig) + return config } -module.exports = getConfig(userConfig) +module.exports = getConfig(userConfig) \ No newline at end of file diff --git a/config/crypto.config.js b/config/crypto.config.js index 968d2e8e..34ea6e98 100644 --- a/config/crypto.config.js +++ b/config/crypto.config.js @@ -1,3 +1,3 @@ const defaultConfig = require('./default.config.js') -module.exports = {} +module.exports = {} \ No newline at end of file diff --git a/config/customConfig.js b/config/customConfig.js index 6c6d12f3..ab37e550 100644 --- a/config/customConfig.js +++ b/config/customConfig.js @@ -4,10 +4,4 @@ const styles = require('./styles.config.js') const build = require('./build.config.js') const user = require('./user.config.js') -module.exports = { - coin, - styles, - build, - user, - crypto -} +module.exports = { coin, styles, build, user, crypto } \ No newline at end of file diff --git a/config/default.config.js b/config/default.config.js index 8d23d608..d0476954 100644 --- a/config/default.config.js +++ b/config/default.config.js @@ -1,5 +1,4 @@ const uiCore = require('../core/ui-core.js') const defaultConfig = uiCore('default_config') - -module.exports = defaultConfig +module.exports = defaultConfig \ No newline at end of file diff --git a/config/styles.config.js b/config/styles.config.js index 4ba52ba2..7c6d6c73 100644 --- a/config/styles.config.js +++ b/config/styles.config.js @@ -1 +1 @@ -module.exports = {} +module.exports = {} \ No newline at end of file diff --git a/config/user.config.js b/config/user.config.js index ef45ffdb..15f71ce0 100644 --- a/config/user.config.js +++ b/config/user.config.js @@ -1,10 +1,11 @@ const user = require('./default.config.js').user + module.exports = { node: 0, // set to mainnet server: { primary: { port: 12388, // set as default UI port - address: '0.0.0.0', // can specify an IP for a fixed bind - }, - }, -} + address: '0.0.0.0' // can specify an IP for a fixed bind + } + } +} \ No newline at end of file diff --git a/core/config/config.js b/core/config/config.js index 2e228fbc..ef8d5633 100644 --- a/core/config/config.js +++ b/core/config/config.js @@ -4,4 +4,4 @@ const user = require('./default.user.config.js') const styles = require('./default.styles.config.js') const build = require('./default.build.options.js') -module.exports = { coin, crypto, user, styles, build } +module.exports = { coin, crypto, user, styles, build } \ No newline at end of file diff --git a/core/config/default.build.options.js b/core/config/default.build.options.js index 0ad66df8..6940eaa1 100644 --- a/core/config/default.build.options.js +++ b/core/config/default.build.options.js @@ -4,132 +4,132 @@ const { makeSourceAbsolute } = require('../tooling/utils.js') const srcDir = '../src' const options = { - inputFile: path.join(__dirname, '../src/main.js'), - outputDir: path.join(__dirname, '../build'), - sassOutputDir: path.join(__dirname, '../build/styles.bundle.css'), - imgDir: path.join(__dirname, '../img') + inputFile: path.join(__dirname, '../src/main.js'), + outputDir: path.join(__dirname, '../build'), + sassOutputDir: path.join(__dirname, '../build/styles.bundle.css'), + imgDir: path.join(__dirname, '../img') } const aliases = { - 'qortal-ui-crypto': '../../crypto/api.js' + 'qortal-ui-crypto': '../../crypto/api.js' } const apiComponents = { - api: { - file: '../../crypto/api.js', - className: 'api' - } + api: { + file: '../../crypto/api.js', + className: 'api' + } } const functionalComponents = { - 'loading-ripple': { - file: 'functional-components/loading-ripple.js', - className: 'LoadingRipple' - }, - 'confirm-transaction-dialog': { - file: 'functional-components/confirm-transaction-dialog', - className: 'ConfirmTransactionDialog' - } + 'loading-ripple': { + file: 'functional-components/loading-ripple.js', + className: 'LoadingRipple' + }, + 'confirm-transaction-dialog': { + file: 'functional-components/confirm-transaction-dialog', + className: 'ConfirmTransactionDialog' + } } const inlineComponents = [ - { - className: 'worker', - input: path.join(__dirname, srcDir, 'worker.js'), - output: 'worker.js' - }, - { - className: 'PluginMainJSLoader', - input: path.join(__dirname, srcDir, '/plugins/plugin-mainjs-loader.js'), - output: 'plugins/plugin-mainjs-loader.js' - } + { + className: 'worker', + input: path.join(__dirname, srcDir, 'worker.js'), + output: 'worker.js' + }, + { + className: 'PluginMainJSLoader', + input: path.join(__dirname, srcDir, '/plugins/plugin-mainjs-loader.js'), + output: 'plugins/plugin-mainjs-loader.js' + } ] const elementComponents = { - 'main-app': { - file: 'components/main-app.js', - className: 'MainApp', - children: { - 'app-styles': { - file: 'styles/app-styles.js', - className: 'AppStyles', - children: { - 'app-theme': { - className: 'AppTheme', - file: 'styles/app-theme.js' - } - } - }, - 'app-view': { - file: 'components/app-view.js', - className: 'AppView', - children: { - 'show-plugin': { - file: 'components/show-plugin.js', - className: 'ShowPlugin' - }, - 'wallet-profile': { - file: 'components/wallet-profile.js', - className: 'WalletProfile' - }, - 'app-info': { - file: 'components/app-info.js', - className: 'AppInfo' - } - } - }, - 'login-view': { - file: 'components/login-view/login-view.js', - className: 'LoginView', - children: { - 'create-account-section': { - file: 'components/login-view/create-account-section.js', - className: 'CreateAccountSection' - }, - 'login-section': { - file: 'components/login-view/login-section.js', - className: 'LoginSection' - } - } - }, - 'settings-view': { - file: 'components/settings-view/user-settings.js', - className: 'UserSettings', - children: { - 'account-view': { - file: 'components/settings-view/account-view.js', - className: 'AccountView' - }, - 'security-view': { - file: 'components/settings-view/security-view.js', - className: 'SecurityView' - }, - 'qr-login-view': { - file: 'components/settings-view/qr-login-view.js', - className: 'QRLoginView' - }, - 'notifications-view': { - file: 'components/settings-view/notifications-view.js', - className: 'NotificationsView' - } - } - }, - 'user-info-view': { - file: 'components/user-info-view/user-info-view.js', - className: 'UserInfoView' - } - } - } + 'main-app': { + file: 'components/main-app.js', + className: 'MainApp', + children: { + 'app-styles': { + file: 'styles/app-styles.js', + className: 'AppStyles', + children: { + 'app-theme': { + className: 'AppTheme', + file: 'styles/app-theme.js' + } + } + }, + 'app-view': { + file: 'components/app-view.js', + className: 'AppView', + children: { + 'show-plugin': { + file: 'components/show-plugin.js', + className: 'ShowPlugin' + }, + 'wallet-profile': { + file: 'components/wallet-profile.js', + className: 'WalletProfile' + }, + 'app-info': { + file: 'components/app-info.js', + className: 'AppInfo' + } + } + }, + 'login-view': { + file: 'components/login-view/login-view.js', + className: 'LoginView', + children: { + 'create-account-section': { + file: 'components/login-view/create-account-section.js', + className: 'CreateAccountSection' + }, + 'login-section': { + file: 'components/login-view/login-section.js', + className: 'LoginSection' + } + } + }, + 'settings-view': { + file: 'components/settings-view/user-settings.js', + className: 'UserSettings', + children: { + 'account-view': { + file: 'components/settings-view/account-view.js', + className: 'AccountView' + }, + 'security-view': { + file: 'components/settings-view/security-view.js', + className: 'SecurityView' + }, + 'qr-login-view': { + file: 'components/settings-view/qr-login-view.js', + className: 'QRLoginView' + }, + 'notifications-view': { + file: 'components/settings-view/notifications-view.js', + className: 'NotificationsView' + } + } + }, + 'user-info-view': { + file: 'components/user-info-view/user-info-view.js', + className: 'UserInfoView' + } + } + } } makeSourceAbsolute(path.join(__dirname, srcDir), elementComponents) makeSourceAbsolute(path.join(__dirname, srcDir), functionalComponents) module.exports = { - options, - elementComponents, - functionalComponents, - inlineComponents, - apiComponents, - aliases -} + options, + elementComponents, + functionalComponents, + inlineComponents, + apiComponents, + aliases +} \ No newline at end of file diff --git a/core/config/default.coin.config.js b/core/config/default.coin.config.js index ef1dbb00..0f7775d1 100644 --- a/core/config/default.coin.config.js +++ b/core/config/default.coin.config.js @@ -1,11 +1,11 @@ const coin = { - name: 'Qortal', - symbol: 'QORT', - addressCount: 1, - addressVersion: 58, - decimals: 100000000, - logo: '/img/QORT_LOGO.png', - icon: '/img/QORT_LOGO.png' + name: 'Qortal', + symbol: 'QORT', + addressCount: 1, + addressVersion: 58, + decimals: 100000000, + logo: '/img/QORT_LOGO.png', + icon: '/img/QORT_LOGO.png' } -module.exports = coin +module.exports = coin \ No newline at end of file diff --git a/core/config/default.crypto.config.js b/core/config/default.crypto.config.js index f8a1b22d..270f7c5a 100644 --- a/core/config/default.crypto.config.js +++ b/core/config/default.crypto.config.js @@ -1,11 +1,11 @@ const crypto = { - kdfThreads: 16, - staticSalt: '4ghkVQExoneGqZqHTMMhhFfxXsVg2A75QeS1HCM5KAih', // Base58 encoded - bcryptRounds: 11, // Note it's kinda bcryptRounds * log.2.16, cause it runs on all 16 threads - bcryptVersion: '2a', - get staticBcryptSalt () { - return `$${this.bcryptVersion}$${this.bcryptRounds}$IxVE941tXVUD4cW0TNVm.O` - } + kdfThreads: 16, + staticSalt: '4ghkVQExoneGqZqHTMMhhFfxXsVg2A75QeS1HCM5KAih', // Base58 encoded + bcryptRounds: 11, // Note it's kinda bcryptRounds * log.2.16, cause it runs on all 16 threads + bcryptVersion: '2a', + get staticBcryptSalt() { + return `$${this.bcryptVersion}$${this.bcryptRounds}$IxVE941tXVUD4cW0TNVm.O` + } } -module.exports = crypto +module.exports = crypto \ No newline at end of file diff --git a/core/config/default.styles.config.js b/core/config/default.styles.config.js index 17123264..b99bff62 100644 --- a/core/config/default.styles.config.js +++ b/core/config/default.styles.config.js @@ -1,40 +1,41 @@ const styles = { - breakpoints: { - desktop: '', - laptop: '', - tablet: '', - mobile: '' - }, - theme: { - colors: { - primary: '#03a9f4', /* Sets the text color to the theme primary color. */ - primaryBg: '#e8eaf6', /* Sets the background color to the theme primary color. */ - onPrimary: '#fff', /* Sets the text color to the color configured for text on the primary color. */ + breakpoints: { + desktop: '', + laptop: '', + tablet: '', + mobile: '' + }, + theme: { + colors: { + primary: '#03a9f4', /* Sets the text color to the theme primary color. */ + primaryBg: '#e8eaf6', /* Sets the background color to the theme primary color. */ + onPrimary: '#fff', /* Sets the text color to the color configured for text on the primary color. */ - secondary: '#03a9f4', /* Sets the text color to the theme secondary color. */ - secondaryBg: '#fce4ec', /* Sets the background color to the theme secondary color. */ - onSecondary: '#fff', /* Sets the text color to the color configured for text on the secondary color. */ + secondary: '#03a9f4', /* Sets the text color to the theme secondary color. */ + secondaryBg: '#fce4ec', /* Sets the background color to the theme secondary color. */ + onSecondary: '#fff', /* Sets the text color to the color configured for text on the secondary color. */ - surface: '#fff', /* Sets the background color to the surface background color. */ - onSurface: '#333', /* Sets the text color to the color configured for text on the surface color. */ - background: '#eee', /* Sets the background color to the theme background color. */ + surface: '#fff', /* Sets the background color to the surface background color. */ + onSurface: '#333', /* Sets the text color to the color configured for text on the surface color. */ + background: '#eee', /* Sets the background color to the theme background color. */ - warning: '#FFA000', - error: '#F44336' - }, + warning: '#FFA000', + error: '#F44336' + }, - addressColors: [ - '#256480', - '#002530', - '#02564e', - '#d32f2f', - '#795548', - '#004d40', - '#006064', - '#9c27b0', - '#2196f3', - '#d81b60' - ] - } + addressColors: [ + '#256480', + '#002530', + '#02564e', + '#d32f2f', + '#795548', + '#004d40', + '#006064', + '#9c27b0', + '#2196f3', + '#d81b60' + ] + } } -module.exports = styles + +module.exports = styles \ No newline at end of file diff --git a/core/config/default.user.config.js b/core/config/default.user.config.js index fb0363b7..e5f02519 100644 --- a/core/config/default.user.config.js +++ b/core/config/default.user.config.js @@ -1,42 +1,43 @@ const path = require('path') const user = { - node: 0, - nodeSettings: { - pingInterval: 30 * 1000, - }, - server: { - writeHosts: { - enabled: true, - }, - relativeTo: path.join(__dirname, '../'), - primary: { - domain: '0.0.0.0', - address: '0.0.0.0', - port: 12388, - directory: './src/', - page404: './src/404.html', - host: '0.0.0.0', - }, - }, - tls: { - enabled: false, - options: { - key: '', - cert: '', - }, - }, - constants: { - pollingInterval: 30 * 1000, // How long between checking for new unconfirmed transactions and new blocks (in milliseconds). - workerURL: '/build/worker.js', - }, + node: 0, + nodeSettings: { + pingInterval: 30 * 1000 + }, + server: { + writeHosts: { + enabled: true + }, + relativeTo: path.join(__dirname, '../'), + primary: { + domain: '0.0.0.0', + address: '0.0.0.0', + port: 12388, + directory: './src/', + page404: './src/404.html', + host: '0.0.0.0' + } + }, + tls: { + enabled: false, + options: { + key: '', + cert: '' + } + }, + constants: { + pollingInterval: 30 * 1000, // How long between checking for new unconfirmed transactions and new blocks (in milliseconds). + workerURL: '/build/worker.js' + }, - // Notification Settings (All defaults to true) - notifications: { - q_chat: { - playSound: true, - showNotification: true, - }, - }, + // Notification Settings (All defaults to true) + notifications: { + q_chat: { + playSound: true, + showNotification: true + } + } } -module.exports = user + +module.exports = user \ No newline at end of file diff --git a/core/config/load-config.js b/core/config/load-config.js index c6d7ae44..0ad62ace 100644 --- a/core/config/load-config.js +++ b/core/config/load-config.js @@ -1,21 +1,22 @@ let config = require('./config.js') const checkKeys = (storeObj, newObj) => { - for (const key in newObj) { - if (!Object.prototype.hasOwnProperty.call(storeObj, key)) return + for (const key in newObj) { + if (!Object.prototype.hasOwnProperty.call(storeObj, key)) return - if (typeof newObj[key] === 'object') { - storeObj[key] = checkKeys(storeObj[key], newObj[key]) - } else { - storeObj[key] = newObj[key] - } - } - return storeObj + if (typeof newObj[key] === 'object') { + storeObj[key] = checkKeys(storeObj[key], newObj[key]) + } else { + storeObj[key] = newObj[key] + } + } + + return storeObj } const getConfig = customConfig => { - config = checkKeys(config, customConfig) - return config + config = checkKeys(config, customConfig) + return config } -module.exports = getConfig +module.exports = getConfig \ No newline at end of file diff --git a/core/font/switch-theme.css b/core/font/switch-theme.css index e7e27c5b..4c56f166 100644 --- a/core/font/switch-theme.css +++ b/core/font/switch-theme.css @@ -6,6 +6,7 @@ html { --plugback: #ffffff; --border: #d0d6de; --border2: #dde2e8; + --border3: #080808; --copybutton: #707584; --chat-group: #080808; --chat-bubble: #9f9f9f0a; @@ -83,6 +84,7 @@ html[theme="dark"] { --plugback: #0f1a2e; --border: #0b305e; --border2: #0b305e; + --border3: #767676; --copybutton: #d0d6de; --chat-group: #ffffff; --chat-bubble: #9694941a; diff --git a/core/language/us.json b/core/language/us.json index 203007d9..85af3543 100644 --- a/core/language/us.json +++ b/core/language/us.json @@ -945,7 +945,16 @@ "gchange56": "Group Name To Search", "gchange57": "Private Group Name Not Found", "gchange58": "Note that group name must be an exact match.", - "gchange59": "Show / Hide Ticker" + "gchange59": "Show / Hide Ticker", + "gchange60": "Please enter an group name", + "gchange61": "Please enter an description", + "gchange62": "Are you sure to update this group?", + "gchange63": "On pressing confirm, the update group request will be sent!", + "gchange64": "Current Owner / New Owner", + "gchange65": "Only replace this address if you want to transfer the group!", + "gchange66": "Invalid Owner / New Owner Address", + "gchange67": "Group Update Successful!", + "gchange68": "Set Group Avatar" }, "puzzlepage": { "pchange1": "Puzzles", diff --git a/core/public/index.html b/core/public/index.html index 4fdc606c..76ff26e4 100644 --- a/core/public/index.html +++ b/core/public/index.html @@ -1,139 +1,121 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Qortal UI - - - - - - - -
- - - - - -
- - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + Qortal UI + + + + +
+ + +
+ + diff --git a/core/server/ServerFactory.js b/core/server/ServerFactory.js index e4d2c5be..4c8b6a3f 100644 --- a/core/server/ServerFactory.js +++ b/core/server/ServerFactory.js @@ -3,32 +3,33 @@ const Hapi = require('@hapi/hapi') const Inert = require('@hapi/inert') function serverFactory(routes, address, port, tls) { - this.server = new Hapi.Server({ - routes: { - files: { - relativeTo: Path.join(__dirname, '../') - } - }, - address: address, - port: port, - tls: tls - }) + this.server = new Hapi.Server({ + routes: { + files: { + relativeTo: Path.join(__dirname, '../') + } + }, + address: address, + port: port, + tls: tls + }) - this.startServer = async () => { - try { - await this.server.register([Inert]) + this.startServer = async () => { + try { + await this.server.register([Inert]) - this.server.route(routes) + this.server.route(routes) - await this.server.start() + await this.server.start() - delete this.startServer - return this.server - } catch (e) { - console.error(e) - throw e - } - } + delete this.startServer + + return this.server + } catch (e) { + console.error(e) + throw e + } + } } -module.exports = serverFactory +module.exports = serverFactory \ No newline at end of file diff --git a/core/server/routes/createCommonRoutes.js b/core/server/routes/createCommonRoutes.js index 4eed35f7..5ba2df12 100644 --- a/core/server/routes/createCommonRoutes.js +++ b/core/server/routes/createCommonRoutes.js @@ -1,106 +1,106 @@ const path = require('path') const routesOptions = { - security: { - hsts: { - maxAge: 15768000, - includeSubDomains: true, - preload: true - }, - xframe: 'sameorigin' - } + security: { + hsts: { + maxAge: 15768000, + includeSubDomains: true, + preload: true + }, + xframe: 'sameorigin' + } } const createRoutes = config => [ + { + method: 'GET', + path: '/img/{param*}', + handler: { + directory: { + path: config.build.options.imgDir, + redirectToSlash: true, + index: true + } + }, + options: routesOptions + }, + { + method: 'GET', + path: '/language/{param*}', + handler: { + directory: { + path: path.join(__dirname, '../../language'), + redirectToSlash: true, + index: true + } + }, + options: routesOptions + }, + { + method: 'GET', + path: '/font/{param*}', + handler: { + directory: { + path: path.join(__dirname, '../../font'), + redirectToSlash: true, + index: true + } + }, + options: routesOptions + }, + { + method: 'GET', + path: '/sound/{param*}', + handler: { + directory: { + path: path.join(__dirname, '../../sound/'), + redirectToSlash: true, + index: true + } + }, + options: routesOptions + }, + { + method: 'GET', + path: '/emoji/{param*}', + handler: { + directory: { + path: path.join(__dirname, '../../emoji/'), + redirectToSlash: true, + index: true + } + }, + options: routesOptions + }, + { + method: 'GET', + path: '/memory-pow/{param*}', + handler: { + directory: { + path: path.join(__dirname, '../../memory-pow/'), + redirectToSlash: true, + index: true + } + }, + options: routesOptions + }, + { + method: 'GET', + path: '/getConfig', + handler: (request, h) => { + const response = { + config: { + ...config + } + } - { - method: 'GET', - path: '/img/{param*}', - handler: { - directory: { - path: config.build.options.imgDir, - redirectToSlash: true, - index: true - } - }, - options: routesOptions - }, - { - method: 'GET', - path: '/language/{param*}', - handler: { - directory: { - path: path.join(__dirname, '../../language'), - redirectToSlash: true, - index: true - } - }, - options: routesOptions - }, - { - method: 'GET', - path: '/font/{param*}', - handler: { - directory: { - path: path.join(__dirname, '../../font'), - redirectToSlash: true, - index: true - } - }, - options: routesOptions - }, - { - method: 'GET', - path: '/sound/{param*}', - handler: { - directory: { - path: path.join(__dirname, '../../sound/'), - redirectToSlash: true, - index: true - } - }, - options: routesOptions - }, - { - method: 'GET', - path: '/emoji/{param*}', - handler: { - directory: { - path: path.join(__dirname, '../../emoji/'), - redirectToSlash: true, - index: true - } - }, - options: routesOptions - }, - { - method: 'GET', - path: '/memory-pow/{param*}', - handler: { - directory: { - path: path.join(__dirname, '../../memory-pow/'), - redirectToSlash: true, - index: true - } - }, - options: routesOptions - }, - { - method: 'GET', - path: '/getConfig', - handler: (request, h) => { - const response = { - config: { - ...config - } - } + delete response.config.user.tls + delete response.config.build - delete response.config.user.tls - delete response.config.build - return JSON.stringify(response) - }, - options: routesOptions - } + return JSON.stringify(response) + }, + options: routesOptions + } ] -module.exports = createRoutes +module.exports = createRoutes \ No newline at end of file diff --git a/core/server/routes/createPrimaryRoutes.js b/core/server/routes/createPrimaryRoutes.js index ef398aae..0eae497c 100644 --- a/core/server/routes/createPrimaryRoutes.js +++ b/core/server/routes/createPrimaryRoutes.js @@ -1,141 +1,140 @@ const path = require('path') - const createCommonRoutes = require('./createCommonRoutes.js') const createPrimaryRoutes = (config, plugins) => { - const routes = createCommonRoutes(config) + const routes = createCommonRoutes(config) - let myPlugins = plugins + let myPlugins = plugins - const pluginFolders = {} + const pluginFolders = {} - const routesOptions = { - security: { - hsts: { - maxAge: 15768000, - includeSubDomains: true, - preload: true - }, - xframe: 'sameorigin' - } - } + const routesOptions = { + security: { + hsts: { + maxAge: 15768000, + includeSubDomains: true, + preload: true + }, + xframe: 'sameorigin' + } + } - plugins.reduce((obj, plugin) => { - obj[plugin.name] = plugin.folder - return obj - }, pluginFolders) + plugins.reduce((obj, plugin) => { + obj[plugin.name] = plugin.folder + return obj + }, pluginFolders) - routes.push( - { - method: 'GET', - path: '/', - handler: (request, reply) => { - return reply.redirect('/app') - }, - options: routesOptions - }, - { - method: 'GET', - path: '/{path*}', - handler: (request, h) => { - const filePath = path.join(__dirname, '../../public/index.html') - const response = h.file(filePath, { - confine: true - }) - response.header('Access-Control-Allow-Origin', request.info.host) - return response - }, - options: routesOptions - }, - { - method: 'GET', - path: '/getPlugins', - handler: (request, h) => { - return { plugins: myPlugins.map(p => p.name) } - }, - options: routesOptions - }, - { - method: 'GET', - path: '/build/{param*}', - handler: { - directory: { - path: config.build.options.outputDir, - redirectToSlash: true, - index: true - } - }, - options: routesOptions - }, - { - method: 'GET', - path: '/src/{param*}', - handler: { - directory: { - path: path.join(__dirname, '../../src'), - redirectToSlash: true, - index: true - } - }, - options: routesOptions - }, - { - method: 'GET', - path: '/plugin/{path*}', - handler: (request, h) => { + routes.push( + { + method: 'GET', + path: '/', + handler: (request, reply) => { + return reply.redirect('/app') + }, + options: routesOptions + }, + { + method: 'GET', + path: '/{path*}', + handler: (request, h) => { + const filePath = path.join(__dirname, '../../public/index.html') + const response = h.file(filePath, { + confine: true + }) + response.header('Access-Control-Allow-Origin', request.info.host) + return response + }, + options: routesOptions + }, + { + method: 'GET', + path: '/getPlugins', + handler: (request, h) => { + return { plugins: myPlugins.map(p => p.name) } + }, + options: routesOptions + }, + { + method: 'GET', + path: '/build/{param*}', + handler: { + directory: { + path: config.build.options.outputDir, + redirectToSlash: true, + index: true + } + }, + options: routesOptions + }, + { + method: 'GET', + path: '/src/{param*}', + handler: { + directory: { + path: path.join(__dirname, '../../src'), + redirectToSlash: true, + index: true + } + }, + options: routesOptions + }, + { + method: 'GET', + path: '/plugin/{path*}', + handler: (request, h) => { - const plugin = request.params.path.split('/')[0] - const filePath = path.join(pluginFolders[plugin], '../', request.params.path) + const plugin = request.params.path.split('/')[0] + const filePath = path.join(pluginFolders[plugin], '../', request.params.path) - const response = h.file(filePath, { - confine: false - }) - response.header('Access-Control-Allow-Origin', request.info.host) - return response - }, - options: routesOptions - }, - { - method: 'GET', - path: '/plugin/404', - handler: (request, h) => { - const response = h.file(path.join(config.server.primary.page404)) - response.header('Access-Control-Allow-Origin', request.info.host) - return response - }, - options: routesOptions - }, - { - method: 'GET', - path: '/qortal-components/plugin-mainjs-loader.html', - handler: (request, h) => { - const response = h.file(path.join(__dirname, '../../src/plugins/plugin-mainjs-loader.html'), { - confine: false - }) - response.header('Access-Control-Allow-Origin', request.info.host) - return response - }, - options: routesOptions - }, - { - method: 'GET', - path: '/qortal-components/plugin-mainjs-loader.js', - handler: (request, h) => { - const file = path.join(config.build.options.outputDir, '/plugins/plugin-mainjs-loader.js') + const response = h.file(filePath, { + confine: false + }) + response.header('Access-Control-Allow-Origin', request.info.host) + return response + }, + options: routesOptions + }, + { + method: 'GET', + path: '/plugin/404', + handler: (request, h) => { + const response = h.file(path.join(config.server.primary.page404)) + response.header('Access-Control-Allow-Origin', request.info.host) + return response + }, + options: routesOptions + }, + { + method: 'GET', + path: '/qortal-components/plugin-mainjs-loader.html', + handler: (request, h) => { + const response = h.file(path.join(__dirname, '../../src/plugins/plugin-mainjs-loader.html'), { + confine: false + }) + response.header('Access-Control-Allow-Origin', request.info.host) + return response + }, + options: routesOptions + }, + { + method: 'GET', + path: '/qortal-components/plugin-mainjs-loader.js', + handler: (request, h) => { + const file = path.join(config.build.options.outputDir, '/plugins/plugin-mainjs-loader.js') - const response = h.file(file, { - confine: false - }) - response.header('Access-Control-Allow-Origin', request.info.host) - return response - }, - options: routesOptions - }, + const response = h.file(file, { + confine: false + }) + response.header('Access-Control-Allow-Origin', request.info.host) + return response + }, + options: routesOptions + } - ) + ) - return routes + return routes } -module.exports = createPrimaryRoutes +module.exports = createPrimaryRoutes \ No newline at end of file diff --git a/core/server/server.js b/core/server/server.js index 5ccf2618..2a562b55 100644 --- a/core/server/server.js +++ b/core/server/server.js @@ -3,22 +3,20 @@ const ServerFactory = require('./ServerFactory.js') const createPrimaryRoutes = require('./routes/createPrimaryRoutes.js') const createServer = (config, plugins) => { - this.start = async function () { - const primaryServer = new ServerFactory(createPrimaryRoutes(config, plugins), config.user.server.primary.host, config.user.server.primary.port, config.user.tls.enabled ? config.user.tls.options : void 0) - primaryServer.startServer() - .then(server => { - console.log(`Qortal UI Server started at ${server.info.uri} and listening on ${server.info.address}`) - }) - .catch(e => { - console.error(e) - }) - } - return this -} + this.start = async function () { + const primaryServer = new ServerFactory(createPrimaryRoutes(config, plugins), config.user.server.primary.host, config.user.server.primary.port, config.user.tls.enabled ? config.user.tls.options : void 0) + primaryServer.startServer().then(server => { + console.log(`Qortal UI Server started at ${server.info.uri} and listening on ${server.info.address}`) + }).catch(e => { + console.error(e) + }) + } + return this +} const serverExports = { - createServer + createServer } -module.exports = serverExports +module.exports = serverExports \ No newline at end of file diff --git a/core/src/apiKeyUtils.js b/core/src/apiKeyUtils.js index e65772b0..08d23ce1 100644 --- a/core/src/apiKeyUtils.js +++ b/core/src/apiKeyUtils.js @@ -1,54 +1,55 @@ import * as api from 'qortal-ui-crypto' -import mykey from './functional-components/mykey-page.js' - -'use strict' +import mykey from './functional-components/mykey-page' export const checkApiKey = async (nodeConfig) => { + let selectedNode = nodeConfig.knownNodes[nodeConfig.node] + let apiKey = selectedNode.apiKey - let selectedNode = nodeConfig.knownNodes[nodeConfig.node]; - let apiKey = selectedNode.apiKey; + // Attempt to generate an API key + const generateUrl = '/admin/apikey/generate' - // Attempt to generate an API key - const generateUrl = "/admin/apikey/generate"; - let generateRes = await api.request(generateUrl, { - method: "POST" - }); + let generateRes = await api.request(generateUrl, { + method: 'POST' + }) - if (generateRes != null && generateRes.error == null && generateRes.length >= 8) { - console.log("Generated API key"); - apiKey = generateRes; + if (generateRes != null && generateRes.error == null && generateRes.length >= 8) { + console.log('Generated API key') - // Store the generated API key - selectedNode.apiKey = apiKey; - nodeConfig.knownNodes[nodeConfig.node] = selectedNode; - localStorage.setItem('myQortalNodes', JSON.stringify(nodeConfig.knownNodes)); - } - else { - console.log("Unable to generate API key"); - } + apiKey = generateRes - // Now test the API key - let testResult = await testApiKey(apiKey); - if (testResult === true) { - console.log("API key test passed"); - } - else { - console.log("API key test failed"); - mykey.show(); - this.dispatchEvent( + // Store the generated API key + selectedNode.apiKey = apiKey + nodeConfig.knownNodes[nodeConfig.node] = selectedNode + localStorage.setItem('myQortalNodes', JSON.stringify(nodeConfig.knownNodes)) + } else { + console.log("Unable to generate API key") + } + + // Now test the API key + let testResult = await testApiKey(apiKey) + + if (testResult === true) { + console.log('API key test passed') + } else { + console.log('API key test failed') + + mykey.show() + + this.dispatchEvent( new CustomEvent('disable-tour', { - bubbles: true, - composed: true - }), - ); - } + bubbles: true, + composed: true + }) + ) + } } export const testApiKey = async (apiKey) => { - const testUrl = "/admin/apikey/test?apiKey=" + apiKey; - let testRes = await api.request(testUrl, { - method: "GET" - }); - return testRes === true; + const testUrl = '/admin/apikey/test?apiKey=' + apiKey -} + let testRes = await api.request(testUrl, { + method: 'GET' + }) + + return testRes === true +} \ No newline at end of file diff --git a/core/src/components/WebWorkerFile.js b/core/src/components/WebWorkerFile.js index 3b8c2b87..ab699e69 100644 --- a/core/src/components/WebWorkerFile.js +++ b/core/src/components/WebWorkerFile.js @@ -1,5 +1,3 @@ -import WebWorker from 'web-worker:./computePowWorkerFile.js'; +import WebWorker from 'web-worker:./computePowWorkerFile.js' -// You can add any initialization or configuration for the Web Worker here - -export default WebWorker; \ No newline at end of file +export default WebWorker \ No newline at end of file diff --git a/core/src/components/app-info.js b/core/src/components/app-info.js index 46aacbbe..d05fa7ca 100644 --- a/core/src/components/app-info.js +++ b/core/src/components/app-info.js @@ -1,147 +1,107 @@ -import {css, html, LitElement} from 'lit' -import {connect} from 'pwa-helpers' -import {store} from '../store.js' -import {translate} from '../../translate' +import { html, LitElement } from 'lit' +import { connect } from 'pwa-helpers' +import { store } from '../store' +import { appInfoStyles } from '../styles/core-css' + +// Multi language support +import { translate } from '../../translate' class AppInfo extends connect(store)(LitElement) { - static get properties() { - return { - nodeInfo: { type: Array }, - coreInfo: { type: Array }, - nodeConfig: { type: Object }, - theme: { type: String, reflect: true } - } - } + static get properties() { + return { + nodeInfo: { type: Array }, + coreInfo: { type: Array }, + nodeConfig: { type: Object }, + theme: { type: String, reflect: true } + } + } - static get styles() { - return css` - * { - --mdc-theme-primary: rgb(3, 169, 244); - --paper-input-container-focus-color: var(--mdc-theme-primary); - } + static get styles() { + return [appInfoStyles] + } - .normal { - --mdc-theme-primary: rgb(3, 169, 244); - } + constructor() { + super() + this.nodeInfo = [] + this.coreInfo = [] + this.nodeConfig = {} + this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light' + } - #profileInMenu { - flex: 0 0 100px; - padding:12px; - border-top: 1px solid var(--border); - background: var(--sidetopbar); - } + render() { + return html` +
+ ${translate("appinfo.uiversion")}: ${this.nodeConfig.version ? this.nodeConfig.version : ''} + ${this._renderCoreVersion()} + ${translate("appinfo.blockheight")}: ${this.nodeInfo.height ? this.nodeInfo.height : ''} ${this._renderStatus()} + ${translate("appinfo.peers")}: ${this.nodeInfo.numberOfConnections ? this.nodeInfo.numberOfConnections : ''} +
+ ` + } - .info { - margin: 0; - font-size: 14px; - font-weight: 100; - display: inline-block; - width: 100%; - padding-bottom: 8px; - color: var(--black); - } + firstUpdated() { + this.getNodeInfo() + this.getCoreInfo() - .blue { - color: #03a9f4; - margin: 0; - font-size: 14px; - font-weight: 200; - display: inline; - } + setInterval(() => { + this.getNodeInfo() + this.getCoreInfo() + }, 60000) + } - .black { - color: var(--black); - margin: 0; - font-size: 14px; - font-weight: 200; - display: inline; - } - ` - } + async getNodeInfo() { + const appinfoNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node] + const appinfoUrl = appinfoNode.protocol + '://' + appinfoNode.domain + ':' + appinfoNode.port + const url = `${appinfoUrl}/admin/status` - constructor() { - super() - this.nodeInfo = [] - this.coreInfo = [] - this.nodeConfig = {} - this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light' - } + await fetch(url).then(response => { + return response.json() + }).then(data => { + this.nodeInfo = data + }).catch(err => { + console.error('Request failed', err) + }) + } - render() { - return html` -
- ${translate("appinfo.uiversion")}: ${this.nodeConfig.version ? this.nodeConfig.version : ''} - ${this._renderCoreVersion()} - ${translate("appinfo.blockheight")}: ${this.nodeInfo.height ? this.nodeInfo.height : ''} ${this._renderStatus()} - ${translate("appinfo.peers")}: ${this.nodeInfo.numberOfConnections ? this.nodeInfo.numberOfConnections : ''} - -
- ` - } + async getCoreInfo() { + const appinfoNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node] + const appinfoUrl = appinfoNode.protocol + '://' + appinfoNode.domain + ':' + appinfoNode.port + const url = `${appinfoUrl}/admin/info` - firstUpdated() { - this.getNodeInfo() - this.getCoreInfo() + await fetch(url).then(response => { + return response.json() + }).then(data => { + this.coreInfo = data + }).catch(err => { + console.error('Request failed', err) + }) + } - setInterval(() => { - this.getNodeInfo() - this.getCoreInfo() - }, 60000) - } + _renderStatus() { + if (this.nodeInfo.isMintingPossible === true && this.nodeInfo.isSynchronizing === true) { + this.cssStatus = 'blue' + return html`${translate("appinfo.minting")}` + } else if (this.nodeInfo.isMintingPossible === true && this.nodeInfo.isSynchronizing === false) { + this.cssStatus = 'blue' + return html`${translate("appinfo.minting")}` + } else if (this.nodeInfo.isMintingPossible === false && this.nodeInfo.isSynchronizing === true) { + this.cssStatus = 'black' + return html`(${translate("appinfo.synchronizing")}... ${this.nodeInfo.syncPercent !== undefined ? this.nodeInfo.syncPercent + '%' : ''})` + } else if (this.nodeInfo.isMintingPossible === false && this.nodeInfo.isSynchronizing === false) { + this.cssStatus = 'black' + return '' + } else { + return '' + } + } - async getNodeInfo() { - const appinfoNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node] - const appinfoUrl = appinfoNode.protocol + '://' + appinfoNode.domain + ':' + appinfoNode.port - const url = `${appinfoUrl}/admin/status` + _renderCoreVersion() { + return html`${translate("appinfo.coreversion")}: ${this.coreInfo.buildVersion ? this.coreInfo.buildVersion : ''}` + } - await fetch(url).then(response => { - return response.json() - }).then(data => { - this.nodeInfo = data - }).catch(err => { - console.error('Request failed', err) - }) - } - - async getCoreInfo() { - const appinfoNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node] - const appinfoUrl = appinfoNode.protocol + '://' + appinfoNode.domain + ':' + appinfoNode.port - const url = `${appinfoUrl}/admin/info` - - await fetch(url).then(response => { - return response.json() - }).then(data => { - this.coreInfo = data - }).catch(err => { - console.error('Request failed', err) - }) - } - - _renderStatus() { - if (this.nodeInfo.isMintingPossible === true && this.nodeInfo.isSynchronizing === true) { - this.cssStatus = 'blue' - return html`${translate("appinfo.minting")}` - } else if (this.nodeInfo.isMintingPossible === true && this.nodeInfo.isSynchronizing === false) { - this.cssStatus = 'blue' - return html`${translate("appinfo.minting")}` - } else if (this.nodeInfo.isMintingPossible === false && this.nodeInfo.isSynchronizing === true) { - this.cssStatus = 'black' - return html`(${translate("appinfo.synchronizing")}... ${this.nodeInfo.syncPercent !== undefined ? this.nodeInfo.syncPercent + '%' : ''})` - } else if (this.nodeInfo.isMintingPossible === false && this.nodeInfo.isSynchronizing === false) { - this.cssStatus = 'black' - return '' - } else { - return '' - } - } - - _renderCoreVersion() { - return html`${translate("appinfo.coreversion")}: ${this.coreInfo.buildVersion ? this.coreInfo.buildVersion : ''}` - } - - stateChanged(state) { - this.nodeConfig = state.app.nodeConfig - } + stateChanged(state) { + this.nodeConfig = state.app.nodeConfig + } } -window.customElements.define('app-info', AppInfo) +window.customElements.define('app-info', AppInfo) \ No newline at end of file diff --git a/core/src/components/app-view.js b/core/src/components/app-view.js index 612d3a2a..d458a54e 100644 --- a/core/src/components/app-view.js +++ b/core/src/components/app-view.js @@ -1,20 +1,43 @@ -import {css, html, LitElement} from 'lit' -import {connect} from 'pwa-helpers' -import {store} from '../store.js' -import {Epml} from '../epml.js' -import {addTradeBotRoutes} from '../tradebot/addTradeBotRoutes.js' -import {get, translate} from '../../translate' -import localForage from 'localforage' -import {decryptData, encryptData} from '../lockScreen.js' -import {setChatLastSeen} from '../redux/app/app-actions.js' +import { html, LitElement } from 'lit' +import { connect } from 'pwa-helpers' +import { store } from '../store' +import { Epml } from '../epml' +import { addTradeBotRoutes } from '../tradebot/addTradeBotRoutes' +import { get, translate } from '../../translate' +import { decryptData, encryptData } from '../lockScreen' +import { setChatLastSeen } from '../redux/app/app-actions' +import { appViewStyles } from '../styles/core-css' import isElectron from 'is-electron' +import localForage from 'localforage' +import './app-info' +import './check-for-update' +import './new-selector' +import './search-modal' +import './show-plugin' +import './theme-toggle' +import './wallet-profile' +import './controllers/coin-balances-controller' +import './beginner-tour/tour-component' +import './beginner-tour/sync-indicator' +import './friends-view/beginner-checklist' +import './friends-view/core-sync-status' +import './friends-view/friends-side-panel-parent' +import './friends-view/profile' +import './friends-view/save-settings-qdn' +import './logout-view/logout-view' +import './notification-view/notification-bell' +import './notification-view/notification-bell-general' +import './settings-view/user-settings' +import './user-info-view/user-info-view' +import '../functional-components/side-menu' +import '../functional-components/side-menu-item' import '@material/mwc-button' import '@material/mwc-icon' -import '@polymer/paper-icon-button/paper-icon-button.js' -import '@polymer/paper-progress/paper-progress.js' -import '@polymer/paper-dialog/paper-dialog.js' -import '@polymer/iron-icons/iron-icons.js' import '@polymer/app-layout/app-layout.js' +import '@polymer/iron-icons/iron-icons.js' +import '@polymer/paper-icon-button/paper-icon-button.js' +import '@polymer/paper-dialog/paper-dialog.js' +import '@polymer/paper-progress/paper-progress.js' import '@polymer/paper-ripple' import '@vaadin/button' import '@vaadin/icon' @@ -23,3326 +46,3042 @@ import '@vaadin/password-field' import '@vaadin/text-field' import '@vaadin/tooltip' -import './wallet-profile.js' -import './app-info.js' -import './show-plugin.js' -import './theme-toggle.js' -import './new-selector.js' -import './settings-view/user-settings.js' -import './logout-view/logout-view.js' -import './check-for-update.js' -import './search-modal.js' -import './user-info-view/user-info-view.js' -import '../functional-components/side-menu.js' -import '../functional-components/side-menu-item.js' -import './notification-view/notification-bell.js' -import './notification-view/notification-bell-general.js' -import './friends-view/friends-side-panel-parent.js' -import './friends-view/save-settings-qdn.js' -import './friends-view/core-sync-status.js' -import './friends-view/profile.js' -import './beginner-tour/tour-component.js' -import './beginner-tour/sync-indicator.js' -import './friends-view/beginner-checklist.js' -import './controllers/coin-balances-controller.js' - const chatLastSeen = localForage.createInstance({ - name: "chat-last-seen", + name: 'chat-last-seen' }) const parentEpml = new Epml({ type: 'WINDOW', source: window.parent }) class AppView extends connect(store)(LitElement) { - static get properties() { - return { - config: { type: Object }, - urls: { type: Object }, - nodeType: { type: String, reflect: true }, - theme: { type: String, reflect: true }, - addressInfo: { type: Object }, - botQortWallet: { type: String }, - botBtcWallet: { type: String }, - botLtcWallet: { type: String }, - botDogeWallet: { type: String }, - botDgbWallet: { type: String }, - botRvnWallet: { type: String }, - botArrrWallet: { type: String }, - arrrWalletAddress: { type: String }, - qortWalletBalance: { type: Number }, - btcWalletBalance: { type: Number }, - ltcWalletBalance: { type: Number }, - dogeWalletBalance: { type: Number }, - dgbWalletBalance: { type: Number }, - rvnWalletBalance: { type: Number }, - arrrWalletBalance: { type: Number }, - failedTradesList: { type: Array }, - tradesOpenBtcQortal: { type: Array }, - myTradesOpenLtcQortal: { type: Array }, - tradesFailedBtcQortal: { type: Array }, - tradesOpenBtcQortalCleaned: { type: Array }, - tradesOpenLtcQortal: { type: Array }, - tradesFailedLtcQortal: { type: Array }, - tradesOpenLtcQortalCleaned: { type: Array }, - tradesOpenDogeQortal: { type: Array }, - tradesFailedDogeQortal: { type: Array }, - tradesOpenDogeQortalCleaned: { type: Array }, - tradesOpenDgbQortal: { type: Array }, - tradesFailedDgbQortal: { type: Array }, - tradesOpenDgbQortalCleaned: { type: Array }, - tradesOpenRvnQortal: { type: Array }, - tradesFailedRvnQortal: { type: Array }, - tradesOpenRvnQortalCleaned: { type: Array }, - tradesOpenArrrQortal: { type: Array }, - tradesFailedArrrQortal: { type: Array }, - tradesOpenArrrQortalCleaned: { type: Array }, - tradeBotBtcBook: { type: Array }, - tradeBotLtcBook: { type: Array }, - tradeBotDogeBook: { type: Array }, - tradeBotDgbBook: { type: Array }, - tradeBotRvnBook: { type: Array }, - tradeBotArrrBook: { type: Array }, - tradeBotBtcAt: { type: Array }, - tradeBotLtcAt: { type: Array }, - tradeBotDogeAt: { type: Array }, - tradeBotDgbAt: { type: Array }, - tradeBotRvnAt: { type: Array }, - tradeBotArrrAt: { type: Array }, - tradeBotAvailableBtcQortal: { type: Array }, - tradeBotAvailableLtcQortal: { type: Array }, - tradeBotAvailableDogeQortal: { type: Array }, - tradeBotAvailableDgbQortal: { type: Array }, - tradeBotAvailableRvnQortal: { type: Array }, - tradeBotAvailableArrrQortal: { type: Array }, - checkBtcAlice: { type: String }, - checkLtcAlice: { type: String }, - checkDogeAlice: { type: String }, - checkDgbAlice: { type: String }, - checkRvnAlice: { type: String }, - checkArrrAlice: { type: String }, - reAddBtcAmount: { type: Number }, - reAddLtcAmount: { type: Number }, - reAddDogeAmount: { type: Number }, - reAddDgbAmount: { type: Number }, - reAddRvnAmount: { type: Number }, - reAddArrrAmount: { type: Number }, - reAddBtcPrice: { type: Number }, - reAddLtcPrice: { type: Number }, - reAddDogePrice: { type: Number }, - reAddDgbPrice: { type: Number }, - reAddRvnPrice: { type: Number }, - reAddArrrPrice: { type: Number }, - botBtcBuyAtAddress: { type: String }, - botLtcBuyAtAddress: { type: String }, - botDogeBuyAtAddress: { type: String }, - botDgbBuyAtAddress: { type: String }, - botRvnBuyAtAddress: { type: String }, - botArrrBuyAtAddress: { type: String }, - balanceTicker: { type: String }, - salt: { type: String }, - storageData: { type: String }, - lockScreenPass: { type: String }, - lockScreenSet: { type: String }, - lockPass: { type: String }, - lockSet: { type: String }, - myLockScreenPass: { type: String }, - myLockScreenSet: { type: String }, - helperMessage: { type: String }, - showSyncMessages: { type: Boolean } - } - } + static get properties() { + return { + config: { type: Object }, + urls: { type: Object }, + nodeType: { type: String, reflect: true }, + theme: { type: String, reflect: true }, + addressInfo: { type: Object }, + botQortWallet: { type: String }, + botBtcWallet: { type: String }, + botLtcWallet: { type: String }, + botDogeWallet: { type: String }, + botDgbWallet: { type: String }, + botRvnWallet: { type: String }, + botArrrWallet: { type: String }, + arrrWalletAddress: { type: String }, + qortWalletBalance: { type: Number }, + btcWalletBalance: { type: Number }, + ltcWalletBalance: { type: Number }, + dogeWalletBalance: { type: Number }, + dgbWalletBalance: { type: Number }, + rvnWalletBalance: { type: Number }, + arrrWalletBalance: { type: Number }, + failedTradesList: { type: Array }, + tradesOpenBtcQortal: { type: Array }, + myTradesOpenLtcQortal: { type: Array }, + tradesFailedBtcQortal: { type: Array }, + tradesOpenBtcQortalCleaned: { type: Array }, + tradesOpenLtcQortal: { type: Array }, + tradesFailedLtcQortal: { type: Array }, + tradesOpenLtcQortalCleaned: { type: Array }, + tradesOpenDogeQortal: { type: Array }, + tradesFailedDogeQortal: { type: Array }, + tradesOpenDogeQortalCleaned: { type: Array }, + tradesOpenDgbQortal: { type: Array }, + tradesFailedDgbQortal: { type: Array }, + tradesOpenDgbQortalCleaned: { type: Array }, + tradesOpenRvnQortal: { type: Array }, + tradesFailedRvnQortal: { type: Array }, + tradesOpenRvnQortalCleaned: { type: Array }, + tradesOpenArrrQortal: { type: Array }, + tradesFailedArrrQortal: { type: Array }, + tradesOpenArrrQortalCleaned: { type: Array }, + tradeBotBtcBook: { type: Array }, + tradeBotLtcBook: { type: Array }, + tradeBotDogeBook: { type: Array }, + tradeBotDgbBook: { type: Array }, + tradeBotRvnBook: { type: Array }, + tradeBotArrrBook: { type: Array }, + tradeBotBtcAt: { type: Array }, + tradeBotLtcAt: { type: Array }, + tradeBotDogeAt: { type: Array }, + tradeBotDgbAt: { type: Array }, + tradeBotRvnAt: { type: Array }, + tradeBotArrrAt: { type: Array }, + tradeBotAvailableBtcQortal: { type: Array }, + tradeBotAvailableLtcQortal: { type: Array }, + tradeBotAvailableDogeQortal: { type: Array }, + tradeBotAvailableDgbQortal: { type: Array }, + tradeBotAvailableRvnQortal: { type: Array }, + tradeBotAvailableArrrQortal: { type: Array }, + checkBtcAlice: { type: String }, + checkLtcAlice: { type: String }, + checkDogeAlice: { type: String }, + checkDgbAlice: { type: String }, + checkRvnAlice: { type: String }, + checkArrrAlice: { type: String }, + reAddBtcAmount: { type: Number }, + reAddLtcAmount: { type: Number }, + reAddDogeAmount: { type: Number }, + reAddDgbAmount: { type: Number }, + reAddRvnAmount: { type: Number }, + reAddArrrAmount: { type: Number }, + reAddBtcPrice: { type: Number }, + reAddLtcPrice: { type: Number }, + reAddDogePrice: { type: Number }, + reAddDgbPrice: { type: Number }, + reAddRvnPrice: { type: Number }, + reAddArrrPrice: { type: Number }, + botBtcBuyAtAddress: { type: String }, + botLtcBuyAtAddress: { type: String }, + botDogeBuyAtAddress: { type: String }, + botDgbBuyAtAddress: { type: String }, + botRvnBuyAtAddress: { type: String }, + botArrrBuyAtAddress: { type: String }, + salt: { type: String }, + storageData: { type: String }, + lockScreenPass: { type: String }, + lockScreenSet: { type: String }, + lockPass: { type: String }, + lockSet: { type: String }, + myLockScreenPass: { type: String }, + myLockScreenSet: { type: String }, + helperMessage: { type: String }, + showSyncMessages: { type: Boolean } + } + } - static get styles() { - return [ - css` - * { - --mdc-theme-primary: rgb(3, 169, 244); - --mdc-theme-secondary: var(--mdc-theme-primary); - --mdc-theme-error: rgb(255, 89, 89); - --lumo-primary-text-color: rgb(0, 167, 245); - --lumo-primary-color-50pct: rgba(0, 167, 245, 0.5); - --lumo-primary-color-10pct: rgba(0, 167, 245, 0.1); - --lumo-primary-color: hsl(199, 100%, 48%); - --lumo-base-color: var(--white); - --lumo-body-text-color: var(--black); - --lumo-secondary-text-color: var(--sectxt); - --lumo-contrast-60pct: var(--vdicon); - --item-selected-color: var(--nav-selected-color); - --item-selected-color-text: var(--nav-selected-color-text); - --item-color-active: var(--nav-color-active); - --item-color-hover: var(--nav-color-hover); - --item-text-color: var(--nav-text-color); - --item-icon-color: var(--nav-icon-color); - --item-border-color: var(--nav-border-color); - --item-border-selected-color: var(--nav-border-selected-color); - } + static get styles() { + return [appViewStyles] + } - :host { - --app-drawer-width: 260px; - } + constructor() { + super() + this.urls = [] + this.nodeType = '' + this.addressInfo = {} + this.botQortWallet = '' + this.botBtcWallet = '' + this.botLtcWallet = '' + this.botDogeWallet = '' + this.botDgbWallet = '' + this.botRvnWallet = '' + this.botArrrWallet = '' + this.arrrWalletAddress = '' + this.qortWalletBalance = 0 + this.btcWalletBalance = 0 + this.ltcWalletBalance = 0 + this.dogeWalletBalance = 0 + this.dgbWalletBalance = 0 + this.rvnWalletBalance = 0 + this.arrrWalletBalance = 0 + this.failedTradesList = [] + this.tradesOpenBtcQortal = [] + this.myTradesOpenLtcQortal = [] + this.tradesFailedBtcQortal = [] + this.tradesOpenBtcQortalCleaned = [] + this.tradesOpenLtcQortal = [] + this.tradesFailedLtcQortal = [] + this.tradesOpenLtcQortalCleaned = [] + this.tradesOpenDogeQortal = [] + this.tradesFailedDogeQortal = [] + this.tradesOpenDogeQortalCleaned = [] + this.tradesOpenDgbQortal = [] + this.tradesFailedDgbQortal = [] + this.tradesOpenDgbQortalCleaned = [] + this.tradesOpenRvnQortal = [] + this.tradesFailedRvnQortal = [] + this.tradesOpenRvnQortalCleaned = [] + this.tradesOpenArrrQortal = [] + this.tradesFailedArrrQortal = [] + this.tradesOpenArrrQortalCleaned = [] + this.tradeBotBtcBook = [] + this.tradeBotLtcBook = [] + this.tradeBotDogeBook = [] + this.tradeBotDgbBook = [] + this.tradeBotRvnBook = [] + this.tradeBotArrrBook = [] + this.tradeBotBtcAt = [] + this.tradeBotLtcAt = [] + this.tradeBotDogeAt = [] + this.tradeBotDgbAt = [] + this.tradeBotRvnAt = [] + this.tradeBotArrrAt = [] + this.tradeBotAvailableBtcQortal = [] + this.tradeBotAvailableLtcQortal = [] + this.tradeBotAvailableDogeQortal = [] + this.tradeBotAvailableDgbQortal = [] + this.tradeBotAvailableRvnQortal = [] + this.tradeBotAvailableArrrQortal = [] + this.checkBtcAlice = '' + this.checkLtcAlice = '' + this.checkDogeAlice = '' + this.checkDgbAlice = '' + this.checkRvnAlice = '' + this.checkArrrAlice = '' + this.reAddBtcAmount = 0 + this.reAddLtcAmount = 0 + this.reAddDogeAmount = 0 + this.reAddDgbAmount = 0 + this.reAddRvnAmount = 0 + this.reAddArrrAmount = 0 + this.reAddBtcPrice = 0 + this.reAddLtcPrice = 0 + this.reAddDogePrice = 0 + this.reAddDgbPrice = 0 + this.reAddRvnPrice = 0 + this.reAddArrrPrice = 0 + this.botBtcBuyAtAddress = '' + this.botLtcBuyAtAddress = '' + this.botDogeBuyAtAddress = '' + this.botDgbBuyAtAddress = '' + this.botRvnBuyAtAddress = '' + this.botArrrBuyAtAddress = '' + this.salt = '' + this.storageData = '' + this.lockScreenPass = '' + this.lockScreenSet = '' + this.lockPass = '' + this.lockSet = '' + this.myLockScreenPass = '' + this.myLockScreenSet = '' + this.helperMessage = '' + this.getTourElements = this.getTourElements.bind(this) + this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light' + } - app-drawer-layout:not([narrow]) [drawer-toggle]:not(side-menu-item) { - display: none; - } + render() { + return html` + + + + + + + + + + +
+ + + +
+
+ + + + + + +
+
 
+ +
     
+ +
   
+ +
  
+ ${this.renderLockButton()} +
  
+ +
  
+
+ this.openSettings()} title="${translate("settings.settings")}"> +
+
  
+ +
 
+
+ this.openLogout()} title="${translate("logout.logout")}"> +
+
  
+
+
+ + + ${!this.showSyncMessages ? html` + + ` : html``} +
+
+ + + + +
+

Qortal UI ${translate("login.lp1")}

+
+
+
+

${translate("login.lp2")}

+

${translate("login.lp3")}

+
+
+ password + +
+
+ password + +
+
+ ${translate("login.lp4")} + ${translate("login.lp5")} +
+
+ +
+

Qortal UI ${translate("login.lp1")}

+
+
+
+

${translate("login.lessthen8")}

+
+
+ ${translate("login.lp4")} + ${translate("login.lp5")} +
+
+ +
+ UI
+ ${translate("login.lp9")} + ${translate("login.lp10")} +
+
+ password + +
+ ${this.helperMessage} +
+
+
+
+ +
+
+ + ` + } - app-drawer { - box-shadow: var(--shadow-2); - } + async firstUpdated() { + addTradeBotRoutes(parentEpml) - app-header { - box-shadow: var(--shadow-2); - } + parentEpml.imReady() - app-toolbar { - background: var(--sidetopbar); - color: var(--black); - border-top: var(--border); - height: 48px; - padding: 3px; - } + this.clearTheCache() + this.helperMessage = this.renderHelperPass() + this.showSyncMessages = store.getState().app.showSyncIndicator + this.salt = '' + this.salt = Base58.encode(store.getState().app.wallet._addresses[0].keyPair.privateKey) + this.storageData = '' + this.storageData = store.getState().app.selectedAddress.address + this.lockScreenPass = '' + this.lockScreenPass = 'lockScreenPass-' + this.storageData + this.lockScreenSet = '' + this.lockScreenSet = 'lockScreenSet-' + this.storageData + this.lockPass = '' + this.lockPass = encryptData(false, this.salt) + this.lockSet = '' + this.lockSet = encryptData(false, this.salt) - paper-progress { - --paper-progress-active-color: var(--mdc-theme-primary); - } + if (localStorage.getItem(this.lockScreenPass) === null && localStorage.getItem(this.lockScreenSet) === null) { + localStorage.setItem(this.lockScreenPass, this.lockPass) + localStorage.setItem(this.lockScreenSet, this.lockSet) - .s-menu { - list-style: none; - padding: 0px 0px; - background: var(--sidetopbar); - border-radius: 2px; - width: 100%; - border-top: 1px solid var(--border); - outline: none; - } - - .search { - display: inline; - width: 50%; - align-items: center; - } - - #sideBar { - height: 100vh; - display: flex; - flex-direction: column; - background: var(--sidetopbar); - } - - .sideBarMenu { - overflow-y: auto; - flex: 1 1; - } - - .sideBarMenu::-webkit-scrollbar-track { - background-color: whitesmoke; - border-radius: 7px; - } - - .sideBarMenu::-webkit-scrollbar { - width: 6px; - border-radius: 7px; - background-color: whitesmoke; - } - - .sideBarMenu::-webkit-scrollbar-thumb { - background-color: rgb(180, 176, 176); - border-radius: 7px; - transition: all 0.3s ease-in-out; - } - - #balanceheader { - flex: 0 0 24px; - padding: 12px 12px 45px 12px; - border-bottom: 1px solid var(--border); - background: var(--sidetopbar); - } - - .balanceheadertext { - position: absolute; - margin: auto; - font-size: 14px; - font-weight: 400; - width: 250px; - display: inline; - padding-top: 5px; - padding-bottom: 5px; - color: var(--nav-text-color); - } - - #balances { - flex: 0 0 24px; - padding: 12px; - background: var(--sidetopbar); - } - - .balancelist { - align-items: center; - float: left; - opacity: 1; - position: relative; - } - - .balanceinfo { - position: absolute; - margin: auto; - font-size: 14px; - font-weight: 100; - width: 250px; - display: inline; - padding-top: 5px; - padding-bottom: 5px; - color: var(--black); - } - - .qort { - animation: animate1 4s 2s 1 ease-in-out ; - color: var(--black); - opacity: 0; - } - - .btc { - animation: animate2 4s 8s 1 ease-in-out ; - color: var(--black); - opacity: 0; - } - - .ltc { - animation: animate3 4s 14s 1 ease-in-out ; - color: var(--black); - opacity: 0; - } - - .doge { - animation: animate4 4s 20s 1 ease-in-out ; - color: var(--black); - opacity: 0; - } - - .dgb { - animation: animate5 4s 26s 1 ease-in-out ; - color: var(--black); - opacity: 0; - } - - .rvn { - animation: animate6 4s 32s 1 ease-in-out ; - color: var(--black); - opacity: 0; - } - - .arrr { - animation: animate7 4s 38s 1 ease-in-out ; - color: var(--black); - opacity: 0; - } - - @keyframes animate1 { - 0%,100% { opacity: 0; } - 50% { opacity: 10; } - } - - @keyframes animate2 { - 0%,100% { opacity: 0; } - 50% { opacity: 10; } - } - - @keyframes animate3 { - 0%,100% { opacity: 0; } - 50% { opacity: 10; } - } - - @keyframes animate4 { - 0%,100% { opacity: 0; } - 50% { opacity: 10; } - } - - @keyframes animate5 { - 0%,100% { opacity: 0; } - 50% { opacity: 10; } - } - - @keyframes animate6 { - 0%,100% { opacity: 0; } - 50% { opacity: 10; } - } - - @keyframes animate7 { - 0%,100% { opacity: 0; } - 50% { opacity: 10; } - } - - .sideBarMenu::-webkit-scrollbar-thumb:hover { - background-color: rgb(148, 146, 146); - cursor: pointer; - } - - .balanceButton { - background-color: #03a9f4; - color: #ffffff; - margin-left: 12px; - margin-right: 12px; - padding-top: 5px; - padding-bottom: 5px; - } - - .red { - --mdc-theme-primary: #C6011F; - } - - .setpass-wrapper { - width: 100%; - min-width: 400px; - max-width: 450px; - text-align: center; - background: var(--white); - border: 1px solid var(--black); - border-radius: 15px; - padding: 10px 10px 0px; - box-shadow: 0px 10px 15px rgba(0, 0, 0, 0.1); + this.myLockScreenPass = '' + this.myLockScreenPass = decryptData(localStorage.getItem(this.lockScreenPass), this.salt) + this.myLockScreenSet = '' + this.myLockScreenSet = decryptData(localStorage.getItem(this.lockScreenSet), this.salt) + } else { + this.myLockScreenPass = '' + this.myLockScreenPass = decryptData(localStorage.getItem(this.lockScreenPass), this.salt) + this.myLockScreenSet = '' + this.myLockScreenSet = decryptData(localStorage.getItem(this.lockScreenSet), this.salt) } - .lock-wrapper { - width: 100%; - height: 100%; - min-width: 600px; - max-width: 600px; - min-height: 400px; - max-height: 400px; - text-align: center; - background: url("/img/qortal-lock.jpg"); - border: 1px solid var(--black); - border-radius: 25px; - padding: 10px 10px 0px; + if (this.myLockScreenSet === true) { + this.shadowRoot.getElementById('lockScreenActive').open() } - .text-wrapper { - width: 100%; - height: 100%; - min-width: 280px; - max-width: 280px; - min-height: 64px; - max-height: 64px; - text-align: center; - margin-left: 35px; - margin-top: 125px; - overflow: hidden; + var drawerTog = this.shadowRoot.getElementById('mb') + var drawerOut = this.shadowRoot.getElementById('appsidebar') + + drawerTog.addEventListener('mouseover', function () { + drawerTog.click() + }) + + drawerOut.addEventListener('mouseleave', function () { + drawerTog.click() + }) + + await this.getNodeType() + + const myAppNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node] + const nodeAppUrl = myAppNode.protocol + '://' + myAppNode.domain + ':' + myAppNode.port + const appDelay = ms => new Promise(res => setTimeout(res, ms)) + + await appDelay(3000) + + this.botQortWallet = store.getState().app.selectedAddress.address + this.botBtcWallet = store.getState().app.selectedAddress.btcWallet.address + this.botLtcWallet = store.getState().app.selectedAddress.ltcWallet.address + this.botDogeWallet = store.getState().app.selectedAddress.dogeWallet.address + this.botDgbWallet = store.getState().app.selectedAddress.dgbWallet.address + this.botRvnWallet = store.getState().app.selectedAddress.rvnWallet.address + this.botArrrWallet = store.getState().app.selectedAddress.arrrWallet.address + + await this.botBtcTradebook() + await this.botLtcTradebook() + await this.botDogeTradebook() + await this.botDgbTradebook() + await this.botRvnTradebook() + await this.botArrrTradebook() + + window.addEventListener('storage', async () => { + this.failedTradesList = JSON.parse(localStorage.getItem('failedTrades') || '[]') + this.tradeBotBtcBook = JSON.parse(localStorage.getItem(this.botBtcWallet) || '[]') + this.tradeBotLtcBook = JSON.parse(localStorage.getItem(this.botLtcWallet) || '[]') + this.tradeBotDogeBook = JSON.parse(localStorage.getItem(this.botDogeWallet) || '[]') + this.tradeBotDgbBook = JSON.parse(localStorage.getItem(this.botDgbWallet) || '[]') + this.tradeBotRvnBook = JSON.parse(localStorage.getItem(this.botRvnWallet) || '[]') + this.tradeBotArrrBook = JSON.parse(localStorage.getItem(this.botArrrWallet) || '[]') + }) + + if (localStorage.getItem('failedTrades') === null) { + localStorage.setItem('failedTrades', '') + + var oldFailedTrades = JSON.parse(localStorage.getItem('failedTrades') || '[]') + + const addFixedFail = { + timestamp: 1699792400000, + recipient: 'QSMfgUCXahYHg38RidZ4FuWbVV8KGngDjP' + } + + oldFailedTrades.push(addFixedFail) + + localStorage.setItem('failedTrades', JSON.stringify(oldFailedTrades)) + + this.failedTradesList = JSON.parse(localStorage.getItem('failedTrades') || '[]') + } else { + this.failedTradesList = JSON.parse(localStorage.getItem('failedTrades') || '[]') } - .lock-title-white { - font-family: 'magistralbold'; - font-weight: 700; - font-size: 26px; - line-height: 32px; - color: #ffffff; + const unconfirmedTransactions = async () => { + const unconfirmedTransactionslUrl = `${nodeAppUrl}/transactions/unconfirmed?txType=MESSAGE&limit=0&reverse=true` + var addFailedTrades = JSON.parse(localStorage.getItem('failedTrades') || '[]') + await fetch(unconfirmedTransactionslUrl).then(response => { + return response.json() + }).then(data => { + data.map(item => { + const unconfirmedNessageTimeDiff = Date.now() - item.timestamp + const timeOneHour = 60 * 60 * 1000 + if (Number(unconfirmedNessageTimeDiff) > Number(timeOneHour)) { + const addIt = { + timestamp: item.timestamp, + recipient: item.recipient + } + addFailedTrades.push(addIt) + } + }) + + localStorage.setItem('failedTrades', JSON.stringify(addFailedTrades)) + + this.failedTradesList = JSON.parse(localStorage.getItem('failedTrades') || '[]') + }) } - .lock-title-red { - font-family: 'magistralbold'; - font-weight: 700; - font-size: 26px; - line-height: 32px; - color: #df3636; + await unconfirmedTransactions() + + const filterUnconfirmedTransactions = async () => { + let cleanFailedTrades = this.failedTradesList.reduce((newArray, cut) => { + if (!newArray.some(obj => obj.recipient === cut.recipient)) { + newArray.push(cut) + } + + return newArray + }, []) + + localStorage.setItem('failedTrades', JSON.stringify(cleanFailedTrades)) + + this.failedTradesList = JSON.parse(localStorage.getItem('failedTrades') || '[]') } - ` - ] - } - constructor() { - super() - this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light' - this.urls = [] - this.nodeType = '' - this.addressInfo = {} - this.botQortWallet = '' - this.botBtcWallet = '' - this.botLtcWallet = '' - this.botDogeWallet = '' - this.botDgbWallet = '' - this.botRvnWallet = '' - this.botArrrWallet = '' - this.arrrWalletAddress = '' - this.qortWalletBalance = 0 - this.btcWalletBalance = 0 - this.ltcWalletBalance = 0 - this.dogeWalletBalance = 0 - this.dgbWalletBalance = 0 - this.rvnWalletBalance = 0 - this.arrrWalletBalance = 0 - this.failedTradesList = [] - this.tradesOpenBtcQortal = [] - this.myTradesOpenLtcQortal = [] - this.tradesFailedBtcQortal = [] - this.tradesOpenBtcQortalCleaned = [] - this.tradesOpenLtcQortal = [] - this.tradesFailedLtcQortal = [] - this.tradesOpenLtcQortalCleaned = [] - this.tradesOpenDogeQortal = [] - this.tradesFailedDogeQortal = [] - this.tradesOpenDogeQortalCleaned = [] - this.tradesOpenDgbQortal = [] - this.tradesFailedDgbQortal = [] - this.tradesOpenDgbQortalCleaned = [] - this.tradesOpenRvnQortal = [] - this.tradesFailedRvnQortal = [] - this.tradesOpenRvnQortalCleaned = [] - this.tradesOpenArrrQortal = [] - this.tradesFailedArrrQortal = [] - this.tradesOpenArrrQortalCleaned = [] - this.tradeBotBtcBook = [] - this.tradeBotLtcBook = [] - this.tradeBotDogeBook = [] - this.tradeBotDgbBook = [] - this.tradeBotRvnBook = [] - this.tradeBotArrrBook = [] - this.tradeBotBtcAt = [] - this.tradeBotLtcAt = [] - this.tradeBotDogeAt = [] - this.tradeBotDgbAt = [] - this.tradeBotRvnAt = [] - this.tradeBotArrrAt = [] - this.tradeBotAvailableBtcQortal = [] - this.tradeBotAvailableLtcQortal = [] - this.tradeBotAvailableDogeQortal = [] - this.tradeBotAvailableDgbQortal = [] - this.tradeBotAvailableRvnQortal = [] - this.tradeBotAvailableArrrQortal = [] - this.checkBtcAlice = '' - this.checkLtcAlice = '' - this.checkDogeAlice = '' - this.checkDgbAlice = '' - this.checkRvnAlice = '' - this.checkArrrAlice = '' - this.reAddBtcAmount = 0 - this.reAddLtcAmount = 0 - this.reAddDogeAmount = 0 - this.reAddDgbAmount = 0 - this.reAddRvnAmount = 0 - this.reAddArrrAmount = 0 - this.reAddBtcPrice = 0 - this.reAddLtcPrice = 0 - this.reAddDogePrice = 0 - this.reAddDgbPrice = 0 - this.reAddRvnPrice = 0 - this.reAddArrrPrice = 0 - this.botBtcBuyAtAddress = '' - this.botLtcBuyAtAddress = '' - this.botDogeBuyAtAddress = '' - this.botDgbBuyAtAddress = '' - this.botRvnBuyAtAddress = '' - this.botArrrBuyAtAddress = '' - this.balanceTicker = html` -
-
-
- ` - this.salt = '' - this.storageData = '' - this.lockScreenPass = '' - this.lockScreenSet = '' - this.lockPass = '' - this.lockSet = '' - this.myLockScreenPass = '' - this.myLockScreenSet = '' - this.helperMessage = '' - this.getTourElements = this.getTourElements.bind(this) - } + await filterUnconfirmedTransactions() - getTourElements(){ - let els = {} - const el1 = this.shadowRoot.querySelector("core-sync-status").shadowRoot.getElementById("core-sync-status-id") - const el2 = this.shadowRoot.querySelector("show-plugin").shadowRoot.getElementById("showPluginId") - const el3 = this.shadowRoot.querySelector("beginner-checklist").shadowRoot.getElementById("popover-notification") - if(el1) { - els['core-sync-status-id'] = el1 - } - if(el2) { - els['tab'] = el2 - } - if(el3) { - els['checklist'] = el3 - } + const getOpenTradesBTC = async () => { + let timerBTC - return els - } + if (this.isEmptyArray(this.tradeBotBtcBook) === true) { + clearTimeout(timerBTC) + timerBTC = setTimeout(getOpenTradesBTC, 150000) + } else { + await this.updateBtcWalletBalance() + const tradesOpenBtcQortalUrl = `${nodeAppUrl}/crosschain/tradeoffers?foreignBlockchain=BITCOIN&limit=0` - render() { - return html` - - - - - - - - - - -
- - - -
-
- - - - - - -
-
 
- -
     
- -
   
- -
  
- ${this.renderLockButton()} -
  
- -
  
-
- this.openSettings()} title="${translate("settings.settings")}"> -
-
  
- -
 
-
- this.openLogout()} title="${translate("logout.logout")}"> -
-
  
-
-
- - - ${!this.showSyncMessages ? html`` : html``} -
-
- - - - -
-

Qortal UI ${translate("login.lp1")}

-
-
-
-

${translate("login.lp2")}

-

${translate("login.lp3")}

-
-
- password - -
-
- password - -
-
- ${translate("login.lp4")} - ${translate("login.lp5")} -
-
- -
-

Qortal UI ${translate("login.lp1")}

-
-
-
-

${translate("login.lessthen8")}

-
-
- ${translate("login.lp4")} - ${translate("login.lp5")} -
-
- -
- UI
- ${translate("login.lp9")} - ${translate("login.lp10")} -
-
- password - -
- ${this.helperMessage} -
-
-
-
- -
-
-
- - ` - } + const tradesOpenBtcQortal = await fetch(tradesOpenBtcQortalUrl).then(response => { + return response.json() + }) - async firstUpdated() { + this.tradesOpenBtcQortal = tradesOpenBtcQortal.map(item => { + const expiryTime = item.creatorPresenceExpiry + if (Number(expiryTime) > Date.now()) { + const calcedPrice = parseFloat(item.expectedForeignAmount) / parseFloat(item.qortAmount) + const roundedPrice = (Math.round(parseFloat(calcedPrice) * 1e8) / 1e8).toFixed(8) + return { + qortAmount: item.qortAmount, + price: roundedPrice, + foreignAmount: item.expectedForeignAmount, + qortalCreator: item.qortalCreator, + qortalAtAddress: item.qortalAtAddress, + qortalCreatorTradeAddress: item.qortalCreatorTradeAddress + } + } + }).filter(item => !!item) - addTradeBotRoutes(parentEpml) - parentEpml.imReady() + const unconfirmedTransactionsBTC = async () => { + const unconfirmedTransactionsUrlBTC = `${nodeAppUrl}/transactions/unconfirmed?txType=MESSAGE&limit=0&reverse=true` + var addFailedTradesBTC = JSON.parse(localStorage.getItem('failedTrades') || '[]') - this.clearTheCache() + await fetch(unconfirmedTransactionsUrlBTC).then(response => { + return response.json() + }).then(data => { + data.map(item => { + const unconfirmedNessageTimeDiffBTC = Date.now() - item.timestamp + const timeOneHourBTC = 60 * 60 * 1000 + if (Number(unconfirmedNessageTimeDiffBTC) > Number(timeOneHourBTC)) { + const addItBTC = { + timestamp: item.timestamp, + recipient: item.recipient + } + addFailedTradesBTC.push(addItBTC) + } + }) - this.helperMessage = this.renderHelperPass() + localStorage.setItem('failedTrades', JSON.stringify(addFailedTradesBTC)) + this.failedTradesList = JSON.parse(localStorage.getItem('failedTrades') || '[]') + }) + } - this.showSyncMessages = store.getState().app.showSyncIndicator + await unconfirmedTransactionsBTC() - this.salt = '' - this.salt = Base58.encode(store.getState().app.wallet._addresses[0].keyPair.privateKey) + const filterUnconfirmedTransactionsBTC = async () => { + let cleanFailedTradesBTC = this.failedTradesList.reduce((newArray, cut) => { + if (!newArray.some(obj => obj.recipient === cut.recipient)) { + newArray.push(cut) + } - this.storageData = '' - this.storageData = store.getState().app.selectedAddress.address + return newArray + }, []) - this.lockScreenPass = '' - this.lockScreenPass = 'lockScreenPass-' + this.storageData + localStorage.setItem('failedTrades', JSON.stringify(cleanFailedTradesBTC)) + this.failedTradesList = JSON.parse(localStorage.getItem('failedTrades') || '[]') + } - this.lockScreenSet = '' - this.lockScreenSet = 'lockScreenSet-' + this.storageData + await filterUnconfirmedTransactionsBTC() - this.lockPass = '' - this.lockPass = encryptData(false, this.salt) + this.tradesOpenBtcQortalCleaned = this.tradesOpenBtcQortal - this.lockSet = '' - this.lockSet = encryptData(false, this.salt) + const filterOpenOfferBTC = async () => { + this.failedTradesList.forEach(item => { + const recipientToRemove = item.recipient - if (localStorage.getItem(this.lockScreenPass) === null && localStorage.getItem(this.lockScreenSet) === null) { - localStorage.setItem(this.lockScreenPass, this.lockPass) - localStorage.setItem(this.lockScreenSet, this.lockSet) - this.myLockScreenPass = '' - this.myLockScreenPass = decryptData(localStorage.getItem(this.lockScreenPass), this.salt) - this.myLockScreenSet = '' - this.myLockScreenSet = decryptData(localStorage.getItem(this.lockScreenSet), this.salt) - } else { - this.myLockScreenPass = '' - this.myLockScreenPass = decryptData(localStorage.getItem(this.lockScreenPass), this.salt) - this.myLockScreenSet = '' - this.myLockScreenSet = decryptData(localStorage.getItem(this.lockScreenSet), this.salt) - } + this.tradesOpenBtcQortalCleaned = this.tradesOpenBtcQortalCleaned.filter(obj => { + return obj.qortalCreatorTradeAddress !== recipientToRemove + }) + }) + } - if (this.myLockScreenSet === true) { - this.shadowRoot.getElementById('lockScreenActive').open() - } + await filterOpenOfferBTC() + await appDelay(1000) + await filterMyBotPriceTradesBTC() - var drawerTog = this.shadowRoot.getElementById("mb") - var drawerOut = this.shadowRoot.getElementById("appsidebar") + setTimeout(getOpenTradesBTC, 150000) + } + } - drawerTog.addEventListener('mouseover', function () { - drawerTog.click() - }) - - drawerOut.addEventListener('mouseleave', function () { - drawerTog.click() - }) - - await this.getNodeType() - - const myAppNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node] - const nodeAppUrl = myAppNode.protocol + '://' + myAppNode.domain + ':' + myAppNode.port - const appDelay = ms => new Promise(res => setTimeout(res, ms)) - - await appDelay(3000) - - this.botQortWallet = store.getState().app.selectedAddress.address - this.botBtcWallet = store.getState().app.selectedAddress.btcWallet.address - this.botLtcWallet = store.getState().app.selectedAddress.ltcWallet.address - this.botDogeWallet = store.getState().app.selectedAddress.dogeWallet.address - this.botDgbWallet = store.getState().app.selectedAddress.dgbWallet.address - this.botRvnWallet = store.getState().app.selectedAddress.rvnWallet.address - this.botArrrWallet = store.getState().app.selectedAddress.arrrWallet.address - - await this.botBtcTradebook() - await this.botLtcTradebook() - await this.botDogeTradebook() - await this.botDgbTradebook() - await this.botRvnTradebook() - await this.botArrrTradebook() - - window.addEventListener('storage', async () => { - this.failedTradesList = JSON.parse(localStorage.getItem("failedTrades") || "[]") - this.tradeBotBtcBook = JSON.parse(localStorage.getItem(this.botBtcWallet) || "[]") - this.tradeBotLtcBook = JSON.parse(localStorage.getItem(this.botLtcWallet) || "[]") - this.tradeBotDogeBook = JSON.parse(localStorage.getItem(this.botDogeWallet) || "[]") - this.tradeBotDgbBook = JSON.parse(localStorage.getItem(this.botDgbWallet) || "[]") - this.tradeBotRvnBook = JSON.parse(localStorage.getItem(this.botRvnWallet) || "[]") - this.tradeBotArrrBook = JSON.parse(localStorage.getItem(this.botArrrWallet) || "[]") - }) - - if (localStorage.getItem("failedTrades") === null) { - localStorage.setItem("failedTrades", "") - - var oldFailedTrades = JSON.parse(localStorage.getItem("failedTrades") || "[]") - - const addFixedFail = { - timestamp: 1699792400000, - recipient: 'QSMfgUCXahYHg38RidZ4FuWbVV8KGngDjP' - } - - oldFailedTrades.push(addFixedFail) - - localStorage.setItem("failedTrades", JSON.stringify(oldFailedTrades)) - - this.failedTradesList = JSON.parse(localStorage.getItem("failedTrades") || "[]") - } else { - this.failedTradesList = JSON.parse(localStorage.getItem("failedTrades") || "[]") - } - - const unconfirmedTransactions = async () => { - const unconfirmedTransactionslUrl = `${nodeAppUrl}/transactions/unconfirmed?txType=MESSAGE&limit=0&reverse=true` - var addFailedTrades = JSON.parse(localStorage.getItem("failedTrades") || "[]") - await fetch(unconfirmedTransactionslUrl).then(response => { - return response.json() - }).then(data => { - data.map(item => { - const unconfirmedNessageTimeDiff = Date.now() - item.timestamp - const timeOneHour = 60 * 60 * 1000 - if (Number(unconfirmedNessageTimeDiff) > Number(timeOneHour)) { - const addIt = { - timestamp: item.timestamp, - recipient: item.recipient - } - addFailedTrades.push(addIt) - } - }) - localStorage.setItem("failedTrades", JSON.stringify(addFailedTrades)) - this.failedTradesList = JSON.parse(localStorage.getItem("failedTrades") || "[]") - }) - } - - await unconfirmedTransactions() - - const filterUnconfirmedTransactions = async () => { - let cleanFailedTrades = this.failedTradesList.reduce((newArray, cut) => { - if(!newArray.some(obj => obj.recipient === cut.recipient)) { - newArray.push(cut) - } - return newArray - },[]) - localStorage.setItem("failedTrades", JSON.stringify(cleanFailedTrades)) - this.failedTradesList = JSON.parse(localStorage.getItem("failedTrades") || "[]") - } - - await filterUnconfirmedTransactions() - - const getOpenTradesBTC = async () => { - let timerBTC - - if (this.isEmptyArray(this.tradeBotBtcBook) === true) { - clearTimeout(timerBTC) - timerBTC = setTimeout(getOpenTradesBTC, 150000) - } else { - await this.updateBtcWalletBalance() - const tradesOpenBtcQortalUrl = `${nodeAppUrl}/crosschain/tradeoffers?foreignBlockchain=BITCOIN&limit=0` - - const tradesOpenBtcQortal = await fetch(tradesOpenBtcQortalUrl).then(response => { - return response.json() - }) - - this.tradesOpenBtcQortal = tradesOpenBtcQortal.map(item => { - const expiryTime = item.creatorPresenceExpiry - if (Number(expiryTime) > Date.now()) { - const calcedPrice = parseFloat(item.expectedForeignAmount) / parseFloat(item.qortAmount) - const roundedPrice = (Math.round(parseFloat(calcedPrice) * 1e8) / 1e8).toFixed(8) - return { - qortAmount: item.qortAmount, - price: roundedPrice, - foreignAmount: item.expectedForeignAmount, - qortalCreator: item.qortalCreator, - qortalAtAddress: item.qortalAtAddress, - qortalCreatorTradeAddress: item.qortalCreatorTradeAddress - } - } - }).filter(item => !!item) - - const unconfirmedTransactionsBTC = async () => { - const unconfirmedTransactionsUrlBTC = `${nodeAppUrl}/transactions/unconfirmed?txType=MESSAGE&limit=0&reverse=true` - var addFailedTradesBTC = JSON.parse(localStorage.getItem("failedTrades") || "[]") - await fetch(unconfirmedTransactionsUrlBTC).then(response => { - return response.json() - }).then(data => { - data.map(item => { - const unconfirmedNessageTimeDiffBTC = Date.now() - item.timestamp - const timeOneHourBTC = 60 * 60 * 1000 - if (Number(unconfirmedNessageTimeDiffBTC) > Number(timeOneHourBTC)) { - const addItBTC = { - timestamp: item.timestamp, - recipient: item.recipient - } - addFailedTradesBTC.push(addItBTC) - } - }) - localStorage.setItem("failedTrades", JSON.stringify(addFailedTradesBTC)) - this.failedTradesList = JSON.parse(localStorage.getItem("failedTrades") || "[]") - }) - } - - await unconfirmedTransactionsBTC() - - const filterUnconfirmedTransactionsBTC = async () => { - let cleanFailedTradesBTC = this.failedTradesList.reduce((newArray, cut) => { - if(!newArray.some(obj => obj.recipient === cut.recipient)) { - newArray.push(cut) - } - return newArray - },[]) - localStorage.setItem("failedTrades", JSON.stringify(cleanFailedTradesBTC)) - this.failedTradesList = JSON.parse(localStorage.getItem("failedTrades") || "[]") - } - - await filterUnconfirmedTransactionsBTC() - - this.tradesOpenBtcQortalCleaned = this.tradesOpenBtcQortal - - const filterOpenOfferBTC = async () => { - this.failedTradesList.forEach(item => { - const recipientToRemove = item.recipient - this.tradesOpenBtcQortalCleaned = this.tradesOpenBtcQortalCleaned.filter(obj => { - return obj.qortalCreatorTradeAddress !== recipientToRemove - }) - }) - } - - await filterOpenOfferBTC() - await appDelay(1000) - await filterMyBotPriceTradesBTC() - setTimeout(getOpenTradesBTC, 150000) - } - } - - const filterMyBotPriceTradesBTC = async () => { - const tradeBotBtcUrl = `${nodeAppUrl}/crosschain/tradebot?foreignBlockchain=BITCOIN&apiKey=${this.getApiKey()}` + const filterMyBotPriceTradesBTC = async () => { + const tradeBotBtcUrl = `${nodeAppUrl}/crosschain/tradebot?foreignBlockchain=BITCOIN&apiKey=${this.getApiKey()}` this.tradeBotBtcAt = await fetch(tradeBotBtcUrl).then(response => { return response.json() }) - await appDelay(1000) + await appDelay(1000) - this.tradeBotAvailableBtcQortal = this.tradesOpenBtcQortalCleaned.map(item => { - const listprice = parseFloat(item.price) - const listamount = parseFloat(item.qortAmount) - const checkprice = parseFloat(this.tradeBotBtcBook[0].botBtcPrice) - const checkamount = parseFloat(this.tradeBotBtcBook[0].botBtcQortAmount) - if (Number(listprice) <= Number(checkprice) && Number(listamount) <= Number(checkamount)) { - return { - qortAmount: item.qortAmount, - price: item.price, - foreignAmount: item.foreignAmount, - qortalCreator: item.qortalCreator, - qortalAtAddress: item.qortalAtAddress, - qortalCreatorTradeAddress: item.qortalCreatorTradeAddress - } - } - }).filter(item => !!item) + this.tradeBotAvailableBtcQortal = this.tradesOpenBtcQortalCleaned.map(item => { + const listprice = parseFloat(item.price) + const listamount = parseFloat(item.qortAmount) + const checkprice = parseFloat(this.tradeBotBtcBook[0].botBtcPrice) + const checkamount = parseFloat(this.tradeBotBtcBook[0].botBtcQortAmount) - this.tradeBotAvailableBtcQortal.sort((a, b) => parseFloat(a.price) - parseFloat(b.price)) + if (Number(listprice) <= Number(checkprice) && Number(listamount) <= Number(checkamount)) { + return { + qortAmount: item.qortAmount, + price: item.price, + foreignAmount: item.foreignAmount, + qortalCreator: item.qortalCreator, + qortalAtAddress: item.qortalAtAddress, + qortalCreatorTradeAddress: item.qortalCreatorTradeAddress + } + } + }).filter(item => !!item) - if (this.isEmptyArray(this.tradeBotAvailableBtcQortal) === true) { - return - } else { - this.checkBtcAlice = this.tradeBotAvailableBtcQortal[0].qortalAtAddress - } + this.tradeBotAvailableBtcQortal.sort((a, b) => parseFloat(a.price) - parseFloat(b.price)) - await appDelay(1000) + if (this.isEmptyArray(this.tradeBotAvailableBtcQortal) === true) { + return + } else { + this.checkBtcAlice = this.tradeBotAvailableBtcQortal[0].qortalAtAddress + } - if (this.tradeBotBtcAt.some(item => item.atAddress === this.checkBtcAlice)) { - return - } + await appDelay(1000) - await appDelay(1000) + if (this.tradeBotBtcAt.some(item => item.atAddress === this.checkBtcAlice)) { + return + } - if (this.isEmptyArray(this.tradeBotAvailableBtcQortal) === true) { + await appDelay(1000) - } else { - const botbtcprice = this.round(parseFloat(this.tradeBotBtcBook[0].botBtcPrice)) - const changebtcamount = parseFloat(this.tradeBotBtcBook[0].botBtcQortAmount) - const reducebtcamount = parseFloat(this.tradeBotAvailableBtcQortal[0].qortAmount) - const tradebtcataddress = this.tradeBotAvailableBtcQortal[0].qortalAtAddress - const newbtcamount = this.round(parseFloat(changebtcamount - reducebtcamount)) + if (this.isEmptyArray(this.tradeBotAvailableBtcQortal) === true) { - this.reAddBtcAmount = this.round(parseFloat(this.tradeBotBtcBook[0].botBtcQortAmount)) - this.reAddBtcPrice = this.round(parseFloat(this.tradeBotBtcBook[0].botBtcPrice)) + } else { + const botbtcprice = this.round(parseFloat(this.tradeBotBtcBook[0].botBtcPrice)) + const changebtcamount = parseFloat(this.tradeBotBtcBook[0].botBtcQortAmount) + const reducebtcamount = parseFloat(this.tradeBotAvailableBtcQortal[0].qortAmount) + const tradebtcataddress = this.tradeBotAvailableBtcQortal[0].qortalAtAddress + const newbtcamount = this.round(parseFloat(changebtcamount - reducebtcamount)) - localStorage.removeItem(this.botBtcWallet) - localStorage.setItem(this.botBtcWallet, "") + this.reAddBtcAmount = this.round(parseFloat(this.tradeBotBtcBook[0].botBtcQortAmount)) + this.reAddBtcPrice = this.round(parseFloat(this.tradeBotBtcBook[0].botBtcPrice)) - var oldBtcTradebook = JSON.parse(localStorage.getItem(this.botBtcWallet) || "[]") + localStorage.removeItem(this.botBtcWallet) + localStorage.setItem(this.botBtcWallet, '') - const newBtcTradebookItem = { - botBtcQortAmount: newbtcamount, - botBtcPrice: botbtcprice - } + var oldBtcTradebook = JSON.parse(localStorage.getItem(this.botBtcWallet) || '[]') - oldBtcTradebook.push(newBtcTradebookItem) + const newBtcTradebookItem = { + botBtcQortAmount: newbtcamount, + botBtcPrice: botbtcprice + } - localStorage.setItem(this.botBtcWallet, JSON.stringify(oldBtcTradebook)) + oldBtcTradebook.push(newBtcTradebookItem) - this.tradeBotBtcBook = JSON.parse(localStorage.getItem(this.botBtcWallet) || "[]") + localStorage.setItem(this.botBtcWallet, JSON.stringify(oldBtcTradebook)) - this.botBtcBuyAtAddress = tradebtcataddress + this.tradeBotBtcBook = JSON.parse(localStorage.getItem(this.botBtcWallet) || '[]') - await appDelay(1000) + this.botBtcBuyAtAddress = tradebtcataddress - await this.buyBtcAction() + await appDelay(1000) - if (this.isEmptyArray(this.tradeBotBtcBook) === true) { - return - } else { - const botamount = parseFloat(this.tradeBotBtcBook[0].botBtcQortAmount) + await this.buyBtcAction() - if (Number(botamount) === 0) { - this.removeBotBTCTradebook() - } - } + if (this.isEmptyArray(this.tradeBotBtcBook) === true) { + return + } else { + const botamount = parseFloat(this.tradeBotBtcBook[0].botBtcQortAmount) - if (this.isEmptyArray(this.tradeBotBtcBook) === true) { + if (Number(botamount) === 0) { + this.removeBotBTCTradebook() + } + } - } else { - const checkBotBtcFunds = this.round(parseFloat(this.tradeBotBtcBook[0].botBtcQortAmount) * parseFloat(this.tradeBotBtcBook[0].botBtcPrice)) - const myBotBtcFunds = this.round(parseFloat(this.btcWalletBalance)) + if (this.isEmptyArray(this.tradeBotBtcBook) === true) { - if (Number(myBotBtcFunds) < Number(checkBotBtcFunds)) { - this.removeBotBTCTradebook() - } - } - } - } + } else { + const checkBotBtcFunds = this.round(parseFloat(this.tradeBotBtcBook[0].botBtcQortAmount) * parseFloat(this.tradeBotBtcBook[0].botBtcPrice)) + const myBotBtcFunds = this.round(parseFloat(this.btcWalletBalance)) - const getOpenTradesLTC = async () => { - let timerLTC + if (Number(myBotBtcFunds) < Number(checkBotBtcFunds)) { + this.removeBotBTCTradebook() + } + } + } + } - if (this.isEmptyArray(this.tradeBotLtcBook) === true) { - clearTimeout(timerLTC) - timerLTC = setTimeout(getOpenTradesLTC, 150000) - } else { - await this.updateLtcWalletBalance() + const getOpenTradesLTC = async () => { + let timerLTC - const getTradesOpenLtcQortal = async () => { - const tradesOpenLtcQortalUrl = `${nodeAppUrl}/crosschain/tradeoffers?foreignBlockchain=LITECOIN&limit=0` + if (this.isEmptyArray(this.tradeBotLtcBook) === true) { + clearTimeout(timerLTC) + timerLTC = setTimeout(getOpenTradesLTC, 150000) + } else { + await this.updateLtcWalletBalance() - await fetch(tradesOpenLtcQortalUrl).then(response => { - return response.json() - }).then(data => { - this.myTradesOpenLtcQortal = data - }) - } + const getTradesOpenLtcQortal = async () => { + const tradesOpenLtcQortalUrl = `${nodeAppUrl}/crosschain/tradeoffers?foreignBlockchain=LITECOIN&limit=0` - await getTradesOpenLtcQortal() + await fetch(tradesOpenLtcQortalUrl).then(response => { + return response.json() + }).then(data => { + this.myTradesOpenLtcQortal = data + }) + } - const filterTradesOpenLtcQortal = async () => { - this.tradesOpenLtcQortal = this.myTradesOpenLtcQortal.map(item => { - const expiryTime = item.creatorPresenceExpiry - if (Number(expiryTime) > Date.now()) { - const calcedPrice = parseFloat(item.expectedForeignAmount) / parseFloat(item.qortAmount) - const roundedPrice = (Math.round(parseFloat(calcedPrice) * 1e8) / 1e8).toFixed(8) - return { - qortAmount: item.qortAmount, - price: roundedPrice, - foreignAmount: item.expectedForeignAmount, - qortalCreator: item.qortalCreator, - qortalAtAddress: item.qortalAtAddress, - qortalCreatorTradeAddress: item.qortalCreatorTradeAddress - } - } - }).filter(item => !!item) - } + await getTradesOpenLtcQortal() - await filterTradesOpenLtcQortal() + const filterTradesOpenLtcQortal = async () => { + this.tradesOpenLtcQortal = this.myTradesOpenLtcQortal.map(item => { + const expiryTime = item.creatorPresenceExpiry + if (Number(expiryTime) > Date.now()) { + const calcedPrice = parseFloat(item.expectedForeignAmount) / parseFloat(item.qortAmount) + const roundedPrice = (Math.round(parseFloat(calcedPrice) * 1e8) / 1e8).toFixed(8) + return { + qortAmount: item.qortAmount, + price: roundedPrice, + foreignAmount: item.expectedForeignAmount, + qortalCreator: item.qortalCreator, + qortalAtAddress: item.qortalAtAddress, + qortalCreatorTradeAddress: item.qortalCreatorTradeAddress + } + } + }).filter(item => !!item) + } - const unconfirmedTransactionsLTC = async () => { - const unconfirmedTransactionsUrlLTC = `${nodeAppUrl}/transactions/unconfirmed?txType=MESSAGE&limit=0&reverse=true` - var addFailedTradesLTC = JSON.parse(localStorage.getItem("failedTrades") || "[]") - await fetch(unconfirmedTransactionsUrlLTC).then(response => { - return response.json() - }).then(data => { - data.map(item => { - const unconfirmedNessageTimeDiffLTC = Date.now() - item.timestamp - const timeOneHourLTC = 60 * 60 * 1000 - if (Number(unconfirmedNessageTimeDiffLTC) > Number(timeOneHourLTC)) { - const addItLTC = { - timestamp: item.timestamp, - recipient: item.recipient - } - addFailedTradesLTC.push(addItLTC) - } - }) - localStorage.setItem("failedTrades", JSON.stringify(addFailedTradesLTC)) - this.failedTradesList = JSON.parse(localStorage.getItem("failedTrades") || "[]") - }) - } + await filterTradesOpenLtcQortal() - await unconfirmedTransactionsLTC() + const unconfirmedTransactionsLTC = async () => { + const unconfirmedTransactionsUrlLTC = `${nodeAppUrl}/transactions/unconfirmed?txType=MESSAGE&limit=0&reverse=true` + var addFailedTradesLTC = JSON.parse(localStorage.getItem('failedTrades') || '[]') - const filterUnconfirmedTransactionsLTC = async () => { - let cleanFailedTradesLTC = this.failedTradesList.reduce((newArray, cut) => { - if(!newArray.some(obj => obj.recipient === cut.recipient)) { - newArray.push(cut) - } - return newArray - },[]) - localStorage.setItem("failedTrades", JSON.stringify(cleanFailedTradesLTC)) - this.failedTradesList = JSON.parse(localStorage.getItem("failedTrades") || "[]") - } + await fetch(unconfirmedTransactionsUrlLTC).then(response => { + return response.json() + }).then(data => { + data.map(item => { + const unconfirmedNessageTimeDiffLTC = Date.now() - item.timestamp + const timeOneHourLTC = 60 * 60 * 1000 + if (Number(unconfirmedNessageTimeDiffLTC) > Number(timeOneHourLTC)) { + const addItLTC = { + timestamp: item.timestamp, + recipient: item.recipient + } + addFailedTradesLTC.push(addItLTC) + } + }) - await filterUnconfirmedTransactionsLTC() + localStorage.setItem('failedTrades', JSON.stringify(addFailedTradesLTC)) + this.failedTradesList = JSON.parse(localStorage.getItem('failedTrades') || '[]') + }) + } - this.tradesOpenLtcQortalCleaned = this.tradesOpenLtcQortal + await unconfirmedTransactionsLTC() - const filterOpenOfferLTC = async () => { - this.failedTradesList.forEach(item => { - const recipientToRemove = item.recipient - this.tradesOpenLtcQortalCleaned = this.tradesOpenLtcQortalCleaned.filter(obj => { - return obj.qortalCreatorTradeAddress !== recipientToRemove - }) - }) - } + const filterUnconfirmedTransactionsLTC = async () => { + let cleanFailedTradesLTC = this.failedTradesList.reduce((newArray, cut) => { + if (!newArray.some(obj => obj.recipient === cut.recipient)) { + newArray.push(cut) + } - await filterOpenOfferLTC() - await appDelay(1000) - await filterMyBotPriceTradesLTC() - setTimeout(getOpenTradesLTC, 150000) - } - } + return newArray + }, []) - const filterMyBotPriceTradesLTC = async () => { - const tradeBotLtcUrl = `${nodeAppUrl}/crosschain/tradebot?foreignBlockchain=LITECOIN&apiKey=${this.getApiKey()}` + localStorage.setItem('failedTrades', JSON.stringify(cleanFailedTradesLTC)) + this.failedTradesList = JSON.parse(localStorage.getItem('failedTrades') || '[]') + } + + await filterUnconfirmedTransactionsLTC() + + this.tradesOpenLtcQortalCleaned = this.tradesOpenLtcQortal + + const filterOpenOfferLTC = async () => { + this.failedTradesList.forEach(item => { + const recipientToRemove = item.recipient + this.tradesOpenLtcQortalCleaned = this.tradesOpenLtcQortalCleaned.filter(obj => { + return obj.qortalCreatorTradeAddress !== recipientToRemove + }) + }) + } + + await filterOpenOfferLTC() + await appDelay(1000) + await filterMyBotPriceTradesLTC() + + setTimeout(getOpenTradesLTC, 150000) + } + } + + const filterMyBotPriceTradesLTC = async () => { + const tradeBotLtcUrl = `${nodeAppUrl}/crosschain/tradebot?foreignBlockchain=LITECOIN&apiKey=${this.getApiKey()}` this.tradeBotLtcAt = await fetch(tradeBotLtcUrl).then(response => { return response.json() }) - await appDelay(1000) + await appDelay(1000) - this.tradeBotAvailableLtcQortal = this.tradesOpenLtcQortalCleaned.map(item => { - const listprice = parseFloat(item.price) - const listamount = parseFloat(item.qortAmount) - const checkprice = parseFloat(this.tradeBotLtcBook[0].botLtcPrice) - const checkamount = parseFloat(this.tradeBotLtcBook[0].botLtcQortAmount) - if (Number(listprice) <= Number(checkprice) && Number(listamount) <= Number(checkamount)) { - return { - qortAmount: item.qortAmount, - price: item.price, - foreignAmount: item.foreignAmount, - qortalCreator: item.qortalCreator, - qortalAtAddress: item.qortalAtAddress, - qortalCreatorTradeAddress: item.qortalCreatorTradeAddress - } - } - }).filter(item => !!item) + this.tradeBotAvailableLtcQortal = this.tradesOpenLtcQortalCleaned.map(item => { + const listprice = parseFloat(item.price) + const listamount = parseFloat(item.qortAmount) + const checkprice = parseFloat(this.tradeBotLtcBook[0].botLtcPrice) + const checkamount = parseFloat(this.tradeBotLtcBook[0].botLtcQortAmount) - this.tradeBotAvailableLtcQortal.sort((a, b) => parseFloat(a.price) - parseFloat(b.price)) + if (Number(listprice) <= Number(checkprice) && Number(listamount) <= Number(checkamount)) { + return { + qortAmount: item.qortAmount, + price: item.price, + foreignAmount: item.foreignAmount, + qortalCreator: item.qortalCreator, + qortalAtAddress: item.qortalAtAddress, + qortalCreatorTradeAddress: item.qortalCreatorTradeAddress + } + } + }).filter(item => !!item) - if (this.isEmptyArray(this.tradeBotAvailableLtcQortal) === true) { - return - } else { - this.checkLtcAlice = this.tradeBotAvailableLtcQortal[0].qortalAtAddress - } + this.tradeBotAvailableLtcQortal.sort((a, b) => parseFloat(a.price) - parseFloat(b.price)) - await appDelay(1000) + if (this.isEmptyArray(this.tradeBotAvailableLtcQortal) === true) { + return + } else { + this.checkLtcAlice = this.tradeBotAvailableLtcQortal[0].qortalAtAddress + } - if (this.tradeBotLtcAt.some(item => item.atAddress === this.checkLtcAlice)) { - return - } + await appDelay(1000) - await appDelay(1000) + if (this.tradeBotLtcAt.some(item => item.atAddress === this.checkLtcAlice)) { + return + } - if (this.isEmptyArray(this.tradeBotAvailableLtcQortal) === true) { + await appDelay(1000) - } else { - const botltcprice = this.round(parseFloat(this.tradeBotLtcBook[0].botLtcPrice)) - const changeltcamount = parseFloat(this.tradeBotLtcBook[0].botLtcQortAmount) - const reduceltcamount = parseFloat(this.tradeBotAvailableLtcQortal[0].qortAmount) - const tradeltcataddress = this.tradeBotAvailableLtcQortal[0].qortalAtAddress - const newltcamount = this.round(parseFloat(changeltcamount - reduceltcamount)) + if (this.isEmptyArray(this.tradeBotAvailableLtcQortal) === true) { - this.reAddLtcAmount = this.round(parseFloat(this.tradeBotLtcBook[0].botLtcQortAmount)) - this.reAddLtcPrice = this.round(parseFloat(this.tradeBotLtcBook[0].botLtcPrice)) + } else { + const botltcprice = this.round(parseFloat(this.tradeBotLtcBook[0].botLtcPrice)) + const changeltcamount = parseFloat(this.tradeBotLtcBook[0].botLtcQortAmount) + const reduceltcamount = parseFloat(this.tradeBotAvailableLtcQortal[0].qortAmount) + const tradeltcataddress = this.tradeBotAvailableLtcQortal[0].qortalAtAddress + const newltcamount = this.round(parseFloat(changeltcamount - reduceltcamount)) - localStorage.removeItem(this.botLtcWallet) - localStorage.setItem(this.botLtcWallet, "") + this.reAddLtcAmount = this.round(parseFloat(this.tradeBotLtcBook[0].botLtcQortAmount)) + this.reAddLtcPrice = this.round(parseFloat(this.tradeBotLtcBook[0].botLtcPrice)) - var oldLtcTradebook = JSON.parse(localStorage.getItem(this.botLtcWallet) || "[]") + localStorage.removeItem(this.botLtcWallet) + localStorage.setItem(this.botLtcWallet, '') - const newLtcTradebookItem = { - botLtcQortAmount: newltcamount, - botLtcPrice: botltcprice - } + var oldLtcTradebook = JSON.parse(localStorage.getItem(this.botLtcWallet) || '[]') - oldLtcTradebook.push(newLtcTradebookItem) + const newLtcTradebookItem = { + botLtcQortAmount: newltcamount, + botLtcPrice: botltcprice + } - localStorage.setItem(this.botLtcWallet, JSON.stringify(oldLtcTradebook)) + oldLtcTradebook.push(newLtcTradebookItem) - this.tradeBotLtcBook = JSON.parse(localStorage.getItem(this.botLtcWallet) || "[]") + localStorage.setItem(this.botLtcWallet, JSON.stringify(oldLtcTradebook)) - this.botLtcBuyAtAddress = tradeltcataddress + this.tradeBotLtcBook = JSON.parse(localStorage.getItem(this.botLtcWallet) || '[]') - await appDelay(1000) + this.botLtcBuyAtAddress = tradeltcataddress - await this.buyLtcAction() + await appDelay(1000) - if (this.isEmptyArray(this.tradeBotLtcBook) === true) { - return - } else { - const botamount = parseFloat(this.tradeBotLtcBook[0].botLtcQortAmount) + await this.buyLtcAction() - if (Number(botamount) === 0) { - this.removeBotLTCTradebook() - } - } + if (this.isEmptyArray(this.tradeBotLtcBook) === true) { + return + } else { + const botamount = parseFloat(this.tradeBotLtcBook[0].botLtcQortAmount) - if (this.isEmptyArray(this.tradeBotLtcBook) === true) { + if (Number(botamount) === 0) { + this.removeBotLTCTradebook() + } + } - } else { - const checkBotLtcFunds = this.round(parseFloat(this.tradeBotLtcBook[0].botLtcQortAmount) * parseFloat(this.tradeBotLtcBook[0].botLtcPrice)) - const myBotLtcFunds = this.round(parseFloat(this.ltcWalletBalance)) + if (this.isEmptyArray(this.tradeBotLtcBook) === true) { - if (Number(myBotLtcFunds) < Number(checkBotLtcFunds)) { - this.removeBotLTCTradebook() - } - } - } - } + } else { + const checkBotLtcFunds = this.round(parseFloat(this.tradeBotLtcBook[0].botLtcQortAmount) * parseFloat(this.tradeBotLtcBook[0].botLtcPrice)) + const myBotLtcFunds = this.round(parseFloat(this.ltcWalletBalance)) - const getOpenTradesDOGE = async () => { - let timerDOGE + if (Number(myBotLtcFunds) < Number(checkBotLtcFunds)) { + this.removeBotLTCTradebook() + } + } + } + } - if (this.isEmptyArray(this.tradeBotDogeBook) === true) { - clearTimeout(timerDOGE) - timerDOGE = setTimeout(getOpenTradesDOGE, 150000) - } else { - await this.updateDogeWalletBalance() - const tradesOpenDogeQortalUrl = `${nodeAppUrl}/crosschain/tradeoffers?foreignBlockchain=DOGECOIN&limit=0` + const getOpenTradesDOGE = async () => { + let timerDOGE - const tradesOpenDogeQortal = await fetch(tradesOpenDogeQortalUrl).then(response => { - return response.json() - }) + if (this.isEmptyArray(this.tradeBotDogeBook) === true) { + clearTimeout(timerDOGE) + timerDOGE = setTimeout(getOpenTradesDOGE, 150000) + } else { + await this.updateDogeWalletBalance() + const tradesOpenDogeQortalUrl = `${nodeAppUrl}/crosschain/tradeoffers?foreignBlockchain=DOGECOIN&limit=0` - this.tradesOpenDogeQortal = tradesOpenDogeQortal.map(item => { - const expiryTime = item.creatorPresenceExpiry - if (Number(expiryTime) > Date.now()) { - const calcedPrice = parseFloat(item.expectedForeignAmount) / parseFloat(item.qortAmount) - const roundedPrice = (Math.round(parseFloat(calcedPrice) * 1e8) / 1e8).toFixed(8) - return { - qortAmount: item.qortAmount, - price: roundedPrice, - foreignAmount: item.expectedForeignAmount, - qortalCreator: item.qortalCreator, - qortalAtAddress: item.qortalAtAddress, - qortalCreatorTradeAddress: item.qortalCreatorTradeAddress - } - } - }).filter(item => !!item) + const tradesOpenDogeQortal = await fetch(tradesOpenDogeQortalUrl).then(response => { + return response.json() + }) - const unconfirmedTransactionsDOGE = async () => { - const unconfirmedTransactionsUrlDOGE = `${nodeAppUrl}/transactions/unconfirmed?txType=MESSAGE&limit=0&reverse=true` - var addFailedTradesDOGE = JSON.parse(localStorage.getItem("failedTrades") || "[]") - await fetch(unconfirmedTransactionsUrlDOGE).then(response => { - return response.json() - }).then(data => { - data.map(item => { - const unconfirmedNessageTimeDiffDOGE = Date.now() - item.timestamp - const timeOneHourDOGE = 60 * 60 * 1000 - if (Number(unconfirmedNessageTimeDiffDOGE) > Number(timeOneHourDOGE)) { - const addItDOGE = { - timestamp: item.timestamp, - recipient: item.recipient - } - addFailedTradesDOGE.push(addItDOGE) - } - }) - localStorage.setItem("failedTrades", JSON.stringify(addFailedTradesDOGE)) - this.failedTradesList = JSON.parse(localStorage.getItem("failedTrades") || "[]") - }) - } + this.tradesOpenDogeQortal = tradesOpenDogeQortal.map(item => { + const expiryTime = item.creatorPresenceExpiry + if (Number(expiryTime) > Date.now()) { + const calcedPrice = parseFloat(item.expectedForeignAmount) / parseFloat(item.qortAmount) + const roundedPrice = (Math.round(parseFloat(calcedPrice) * 1e8) / 1e8).toFixed(8) + return { + qortAmount: item.qortAmount, + price: roundedPrice, + foreignAmount: item.expectedForeignAmount, + qortalCreator: item.qortalCreator, + qortalAtAddress: item.qortalAtAddress, + qortalCreatorTradeAddress: item.qortalCreatorTradeAddress + } + } + }).filter(item => !!item) - await unconfirmedTransactionsDOGE() + const unconfirmedTransactionsDOGE = async () => { + const unconfirmedTransactionsUrlDOGE = `${nodeAppUrl}/transactions/unconfirmed?txType=MESSAGE&limit=0&reverse=true` + var addFailedTradesDOGE = JSON.parse(localStorage.getItem('failedTrades') || '[]') - const filterUnconfirmedTransactionsDOGE = async () => { - let cleanFailedTradesDOGE = this.failedTradesList.reduce((newArray, cut) => { - if(!newArray.some(obj => obj.recipient === cut.recipient)) { - newArray.push(cut) - } - return newArray - },[]) - localStorage.setItem("failedTrades", JSON.stringify(cleanFailedTradesDOGE)) - this.failedTradesList = JSON.parse(localStorage.getItem("failedTrades") || "[]") - } + await fetch(unconfirmedTransactionsUrlDOGE).then(response => { + return response.json() + }).then(data => { + data.map(item => { + const unconfirmedNessageTimeDiffDOGE = Date.now() - item.timestamp + const timeOneHourDOGE = 60 * 60 * 1000 + if (Number(unconfirmedNessageTimeDiffDOGE) > Number(timeOneHourDOGE)) { + const addItDOGE = { + timestamp: item.timestamp, + recipient: item.recipient + } + addFailedTradesDOGE.push(addItDOGE) + } + }) - await filterUnconfirmedTransactionsDOGE() + localStorage.setItem('failedTrades', JSON.stringify(addFailedTradesDOGE)) + this.failedTradesList = JSON.parse(localStorage.getItem('failedTrades') || '[]') + }) + } - this.tradesOpenDogeQortalCleaned = this.tradesOpenDogeQortal + await unconfirmedTransactionsDOGE() - const filterOpenOfferDOGE = async () => { - this.failedTradesList.forEach(item => { - const recipientToRemove = item.recipient - this.tradesOpenDogeQortalCleaned = this.tradesOpenDogeQortalCleaned.filter(obj => { - return obj.qortalCreatorTradeAddress !== recipientToRemove - }) - }) - } + const filterUnconfirmedTransactionsDOGE = async () => { + let cleanFailedTradesDOGE = this.failedTradesList.reduce((newArray, cut) => { + if (!newArray.some(obj => obj.recipient === cut.recipient)) { + newArray.push(cut) + } - await filterOpenOfferDOGE() - await appDelay(1000) - await filterMyBotPriceTradesDOGE() - setTimeout(getOpenTradesDOGE, 150000) - } - } + return newArray + }, []) - const filterMyBotPriceTradesDOGE = async () => { - const tradeBotDogeUrl = `${nodeAppUrl}/crosschain/tradebot?foreignBlockchain=DOGECOIN&apiKey=${this.getApiKey()}` + localStorage.setItem('failedTrades', JSON.stringify(cleanFailedTradesDOGE)) + this.failedTradesList = JSON.parse(localStorage.getItem('failedTrades') || '[]') + } + + await filterUnconfirmedTransactionsDOGE() + + this.tradesOpenDogeQortalCleaned = this.tradesOpenDogeQortal + + const filterOpenOfferDOGE = async () => { + this.failedTradesList.forEach(item => { + const recipientToRemove = item.recipient + this.tradesOpenDogeQortalCleaned = this.tradesOpenDogeQortalCleaned.filter(obj => { + return obj.qortalCreatorTradeAddress !== recipientToRemove + }) + }) + } + + await filterOpenOfferDOGE() + await appDelay(1000) + await filterMyBotPriceTradesDOGE() + + setTimeout(getOpenTradesDOGE, 150000) + } + } + + const filterMyBotPriceTradesDOGE = async () => { + const tradeBotDogeUrl = `${nodeAppUrl}/crosschain/tradebot?foreignBlockchain=DOGECOIN&apiKey=${this.getApiKey()}` this.tradeBotDogeAt = await fetch(tradeBotDogeUrl).then(response => { return response.json() }) - await appDelay(1000) + await appDelay(1000) - this.tradeBotAvailableDogeQortal = this.tradesOpenDogeQortalCleaned.map(item => { - const listprice = parseFloat(item.price) - const listamount = parseFloat(item.qortAmount) - const checkprice = parseFloat(this.tradeBotDogeBook[0].botDogePrice) - const checkamount = parseFloat(this.tradeBotDogeBook[0].botDogeQortAmount) - if (Number(listprice) <= Number(checkprice) && Number(listamount) <= Number(checkamount)) { - return { - qortAmount: item.qortAmount, - price: item.price, - foreignAmount: item.foreignAmount, - qortalCreator: item.qortalCreator, - qortalAtAddress: item.qortalAtAddress, - qortalCreatorTradeAddress: item.qortalCreatorTradeAddress - } - } - }).filter(item => !!item) + this.tradeBotAvailableDogeQortal = this.tradesOpenDogeQortalCleaned.map(item => { + const listprice = parseFloat(item.price) + const listamount = parseFloat(item.qortAmount) + const checkprice = parseFloat(this.tradeBotDogeBook[0].botDogePrice) + const checkamount = parseFloat(this.tradeBotDogeBook[0].botDogeQortAmount) - this.tradeBotAvailableDogeQortal.sort((a, b) => parseFloat(a.price) - parseFloat(b.price)) + if (Number(listprice) <= Number(checkprice) && Number(listamount) <= Number(checkamount)) { + return { + qortAmount: item.qortAmount, + price: item.price, + foreignAmount: item.foreignAmount, + qortalCreator: item.qortalCreator, + qortalAtAddress: item.qortalAtAddress, + qortalCreatorTradeAddress: item.qortalCreatorTradeAddress + } + } + }).filter(item => !!item) - if (this.isEmptyArray(this.tradeBotAvailableDogeQortal) === true) { - return - } else { - this.checkDogeAlice = this.tradeBotAvailableDogeQortal[0].qortalAtAddress - } + this.tradeBotAvailableDogeQortal.sort((a, b) => parseFloat(a.price) - parseFloat(b.price)) - await appDelay(1000) + if (this.isEmptyArray(this.tradeBotAvailableDogeQortal) === true) { + return + } else { + this.checkDogeAlice = this.tradeBotAvailableDogeQortal[0].qortalAtAddress + } - if (this.tradeBotDogeAt.some(item => item.atAddress === this.checkDogeAlice)) { - return - } + await appDelay(1000) - await appDelay(1000) + if (this.tradeBotDogeAt.some(item => item.atAddress === this.checkDogeAlice)) { + return + } - if (this.isEmptyArray(this.tradeBotAvailableDogeQortal) === true) { + await appDelay(1000) - } else { - const botdogeprice = this.round(parseFloat(this.tradeBotDogeBook[0].botDogePrice)) - const changedogeamount = parseFloat(this.tradeBotDogeBook[0].botDogeQortAmount) - const reducedogeamount = parseFloat(this.tradeBotAvailableDogeQortal[0].qortAmount) - const tradedogeataddress = this.tradeBotAvailableDogeQortal[0].qortalAtAddress - const newdogeamount = this.round(parseFloat(changedogeamount - reducedogeamount)) + if (this.isEmptyArray(this.tradeBotAvailableDogeQortal) === true) { - this.reAddDogeAmount = this.round(parseFloat(this.tradeBotDogeBook[0].botDogeQortAmount)) - this.reAddDogePrice = this.round(parseFloat(this.tradeBotDogeBook[0].botDogePrice)) + } else { + const botdogeprice = this.round(parseFloat(this.tradeBotDogeBook[0].botDogePrice)) + const changedogeamount = parseFloat(this.tradeBotDogeBook[0].botDogeQortAmount) + const reducedogeamount = parseFloat(this.tradeBotAvailableDogeQortal[0].qortAmount) + const tradedogeataddress = this.tradeBotAvailableDogeQortal[0].qortalAtAddress + const newdogeamount = this.round(parseFloat(changedogeamount - reducedogeamount)) - localStorage.removeItem(this.botDogeWallet) - localStorage.setItem(this.botDogeWallet, "") + this.reAddDogeAmount = this.round(parseFloat(this.tradeBotDogeBook[0].botDogeQortAmount)) + this.reAddDogePrice = this.round(parseFloat(this.tradeBotDogeBook[0].botDogePrice)) - var oldDogeTradebook = JSON.parse(localStorage.getItem(this.botDogeWallet) || "[]") + localStorage.removeItem(this.botDogeWallet) + localStorage.setItem(this.botDogeWallet, '') - const newDogeTradebookItem = { - botDogeQortAmount: newdogeamount, - botDogePrice: botdogeprice - } + var oldDogeTradebook = JSON.parse(localStorage.getItem(this.botDogeWallet) || '[]') - oldDogeTradebook.push(newDogeTradebookItem) + const newDogeTradebookItem = { + botDogeQortAmount: newdogeamount, + botDogePrice: botdogeprice + } - localStorage.setItem(this.botDogeWallet, JSON.stringify(oldDogeTradebook)) + oldDogeTradebook.push(newDogeTradebookItem) - this.tradeBotDogeBook = JSON.parse(localStorage.getItem(this.botDogeWallet) || "[]") + localStorage.setItem(this.botDogeWallet, JSON.stringify(oldDogeTradebook)) - this.botDogeBuyAtAddress = tradedogeataddress + this.tradeBotDogeBook = JSON.parse(localStorage.getItem(this.botDogeWallet) || '[]') - await appDelay(1000) + this.botDogeBuyAtAddress = tradedogeataddress - await this.buyDogeAction() + await appDelay(1000) - if (this.isEmptyArray(this.tradeBotDogeBook) === true) { - return - } else { - const botamount = parseFloat(this.tradeBotDogeBook[0].botDogeQortAmount) + await this.buyDogeAction() - if (Number(botamount) === 0) { - this.removeBotDOGETradebook() - } - } + if (this.isEmptyArray(this.tradeBotDogeBook) === true) { + return + } else { + const botamount = parseFloat(this.tradeBotDogeBook[0].botDogeQortAmount) - if (this.isEmptyArray(this.tradeBotDogeBook) === true) { + if (Number(botamount) === 0) { + this.removeBotDOGETradebook() + } + } - } else { - const checkBotDogeFunds = this.round(parseFloat(this.tradeBotDogeBook[0].botDogeQortAmount) * parseFloat(this.tradeBotDogeBook[0].botDogePrice)) - const myBotDogeFunds = this.round(parseFloat(this.dogeWalletBalance)) + if (this.isEmptyArray(this.tradeBotDogeBook) === true) { - if (Number(myBotDogeFunds) < Number(checkBotDogeFunds)) { - this.removeBotDOGETradebook() - } - } - } - } + } else { + const checkBotDogeFunds = this.round(parseFloat(this.tradeBotDogeBook[0].botDogeQortAmount) * parseFloat(this.tradeBotDogeBook[0].botDogePrice)) + const myBotDogeFunds = this.round(parseFloat(this.dogeWalletBalance)) - const getOpenTradesDGB = async () => { - let timerDGB + if (Number(myBotDogeFunds) < Number(checkBotDogeFunds)) { + this.removeBotDOGETradebook() + } + } + } + } - if (this.isEmptyArray(this.tradeBotDgbBook) === true) { - clearTimeout(timerDGB) - timerDGB = setTimeout(getOpenTradesDGB, 150000) - } else { - await this.updateDgbWalletBalance() - const tradesOpenDgbQortalUrl = `${nodeAppUrl}/crosschain/tradeoffers?foreignBlockchain=DIGIYBYTE&limit=0` + const getOpenTradesDGB = async () => { + let timerDGB - const tradesOpenDgbQortal = await fetch(tradesOpenDgbQortalUrl).then(response => { - return response.json() - }) + if (this.isEmptyArray(this.tradeBotDgbBook) === true) { + clearTimeout(timerDGB) + timerDGB = setTimeout(getOpenTradesDGB, 150000) + } else { + await this.updateDgbWalletBalance() + const tradesOpenDgbQortalUrl = `${nodeAppUrl}/crosschain/tradeoffers?foreignBlockchain=DIGIYBYTE&limit=0` - this.tradesOpenDgbQortal = tradesOpenDgbQortal.map(item => { - const expiryTime = item.creatorPresenceExpiry - if (Number(expiryTime) > Date.now()) { - const calcedPrice = parseFloat(item.expectedForeignAmount) / parseFloat(item.qortAmount) - const roundedPrice = (Math.round(parseFloat(calcedPrice) * 1e8) / 1e8).toFixed(8) - return { - qortAmount: item.qortAmount, - price: roundedPrice, - foreignAmount: item.expectedForeignAmount, - qortalCreator: item.qortalCreator, - qortalAtAddress: item.qortalAtAddress, - qortalCreatorTradeAddress: item.qortalCreatorTradeAddress - } - } - }).filter(item => !!item) + const tradesOpenDgbQortal = await fetch(tradesOpenDgbQortalUrl).then(response => { + return response.json() + }) - const unconfirmedTransactionsDGB = async () => { - const unconfirmedTransactionsUrlDGB = `${nodeAppUrl}/transactions/unconfirmed?txType=MESSAGE&limit=0&reverse=true` - var addFailedTradesDGB = JSON.parse(localStorage.getItem("failedTrades") || "[]") - await fetch(unconfirmedTransactionsUrlDGB).then(response => { - return response.json() - }).then(data => { - data.map(item => { - const unconfirmedNessageTimeDiffDGB = Date.now() - item.timestamp - const timeOneHourDGB = 60 * 60 * 1000 - if (Number(unconfirmedNessageTimeDiffDGB) > Number(timeOneHourDGB)) { - const addItDGB = { - timestamp: item.timestamp, - recipient: item.recipient - } - addFailedTradesDGB.push(addItDGB) - } - }) - localStorage.setItem("failedTrades", JSON.stringify(addFailedTradesDGB)) - this.failedTradesList = JSON.parse(localStorage.getItem("failedTrades") || "[]") - }) - } + this.tradesOpenDgbQortal = tradesOpenDgbQortal.map(item => { + const expiryTime = item.creatorPresenceExpiry + if (Number(expiryTime) > Date.now()) { + const calcedPrice = parseFloat(item.expectedForeignAmount) / parseFloat(item.qortAmount) + const roundedPrice = (Math.round(parseFloat(calcedPrice) * 1e8) / 1e8).toFixed(8) + return { + qortAmount: item.qortAmount, + price: roundedPrice, + foreignAmount: item.expectedForeignAmount, + qortalCreator: item.qortalCreator, + qortalAtAddress: item.qortalAtAddress, + qortalCreatorTradeAddress: item.qortalCreatorTradeAddress + } + } + }).filter(item => !!item) - await unconfirmedTransactionsDGB() + const unconfirmedTransactionsDGB = async () => { + const unconfirmedTransactionsUrlDGB = `${nodeAppUrl}/transactions/unconfirmed?txType=MESSAGE&limit=0&reverse=true` + var addFailedTradesDGB = JSON.parse(localStorage.getItem('failedTrades') || '[]') - const filterUnconfirmedTransactionsDGB = async () => { - let cleanFailedTradesDGB = this.failedTradesList.reduce((newArray, cut) => { - if(!newArray.some(obj => obj.recipient === cut.recipient)) { - newArray.push(cut) - } - return newArray - },[]) - localStorage.setItem("failedTrades", JSON.stringify(cleanFailedTradesDGB)) - this.failedTradesList = JSON.parse(localStorage.getItem("failedTrades") || "[]") - } + await fetch(unconfirmedTransactionsUrlDGB).then(response => { + return response.json() + }).then(data => { + data.map(item => { + const unconfirmedNessageTimeDiffDGB = Date.now() - item.timestamp + const timeOneHourDGB = 60 * 60 * 1000 + if (Number(unconfirmedNessageTimeDiffDGB) > Number(timeOneHourDGB)) { + const addItDGB = { + timestamp: item.timestamp, + recipient: item.recipient + } + addFailedTradesDGB.push(addItDGB) + } + }) - await filterUnconfirmedTransactionsDGB() + localStorage.setItem('failedTrades', JSON.stringify(addFailedTradesDGB)) + this.failedTradesList = JSON.parse(localStorage.getItem('failedTrades') || '[]') + }) + } - this.tradesOpenDgbQortalCleaned = this.tradesOpenDgbQortal + await unconfirmedTransactionsDGB() - const filterOpenOfferDGB = async () => { - this.failedTradesList.forEach(item => { - const recipientToRemove = item.recipient - this.tradesOpenDgbQortalCleaned = this.tradesOpenDgbQortalCleaned.filter(obj => { - return obj.qortalCreatorTradeAddress !== recipientToRemove - }) - }) - } + const filterUnconfirmedTransactionsDGB = async () => { + let cleanFailedTradesDGB = this.failedTradesList.reduce((newArray, cut) => { + if (!newArray.some(obj => obj.recipient === cut.recipient)) { + newArray.push(cut) + } - await filterOpenOfferDGB() - await appDelay(1000) - await filterMyBotPriceTradesDGB() - setTimeout(getOpenTradesDGB, 150000) - } - } + return newArray + }, []) - const filterMyBotPriceTradesDGB = async () => { - const tradeBotDgbUrl = `${nodeAppUrl}/crosschain/tradebot?foreignBlockchain=DIGIBYTE&apiKey=${this.getApiKey()}` + localStorage.setItem('failedTrades', JSON.stringify(cleanFailedTradesDGB)) + this.failedTradesList = JSON.parse(localStorage.getItem('failedTrades') || '[]') + } + + await filterUnconfirmedTransactionsDGB() + + this.tradesOpenDgbQortalCleaned = this.tradesOpenDgbQortal + + const filterOpenOfferDGB = async () => { + this.failedTradesList.forEach(item => { + const recipientToRemove = item.recipient + this.tradesOpenDgbQortalCleaned = this.tradesOpenDgbQortalCleaned.filter(obj => { + return obj.qortalCreatorTradeAddress !== recipientToRemove + }) + }) + } + + await filterOpenOfferDGB() + await appDelay(1000) + await filterMyBotPriceTradesDGB() + + setTimeout(getOpenTradesDGB, 150000) + } + } + + const filterMyBotPriceTradesDGB = async () => { + const tradeBotDgbUrl = `${nodeAppUrl}/crosschain/tradebot?foreignBlockchain=DIGIBYTE&apiKey=${this.getApiKey()}` this.tradeBotDgbAt = await fetch(tradeBotDgbUrl).then(response => { return response.json() }) - await appDelay(1000) + await appDelay(1000) - this.tradeBotAvailableDgbQortal = this.tradesOpenDgbQortalCleaned.map(item => { - const listprice = parseFloat(item.price) - const listamount = parseFloat(item.qortAmount) - const checkprice = parseFloat(this.tradeBotDgbBook[0].botDgbPrice) - const checkamount = parseFloat(this.tradeBotDgbBook[0].botDgbQortAmount) - if (Number(listprice) <= Number(checkprice) && Number(listamount) <= Number(checkamount)) { - return { - qortAmount: item.qortAmount, - price: item.price, - foreignAmount: item.foreignAmount, - qortalCreator: item.qortalCreator, - qortalAtAddress: item.qortalAtAddress, - qortalCreatorTradeAddress: item.qortalCreatorTradeAddress - } - } - }).filter(item => !!item) + this.tradeBotAvailableDgbQortal = this.tradesOpenDgbQortalCleaned.map(item => { + const listprice = parseFloat(item.price) + const listamount = parseFloat(item.qortAmount) + const checkprice = parseFloat(this.tradeBotDgbBook[0].botDgbPrice) + const checkamount = parseFloat(this.tradeBotDgbBook[0].botDgbQortAmount) - this.tradeBotAvailableDgbQortal.sort((a, b) => parseFloat(a.price) - parseFloat(b.price)) + if (Number(listprice) <= Number(checkprice) && Number(listamount) <= Number(checkamount)) { + return { + qortAmount: item.qortAmount, + price: item.price, + foreignAmount: item.foreignAmount, + qortalCreator: item.qortalCreator, + qortalAtAddress: item.qortalAtAddress, + qortalCreatorTradeAddress: item.qortalCreatorTradeAddress + } + } + }).filter(item => !!item) - if (this.isEmptyArray(this.tradeBotAvailableDgbQortal) === true) { - return - } else { - this.checkDgbAlice = this.tradeBotAvailableDgbQortal[0].qortalAtAddress - } + this.tradeBotAvailableDgbQortal.sort((a, b) => parseFloat(a.price) - parseFloat(b.price)) - await appDelay(1000) + if (this.isEmptyArray(this.tradeBotAvailableDgbQortal) === true) { + return + } else { + this.checkDgbAlice = this.tradeBotAvailableDgbQortal[0].qortalAtAddress + } - if (this.tradeBotDgbAt.some(item => item.atAddress === this.checkDgbAlice)) { - return - } + await appDelay(1000) - await appDelay(1000) + if (this.tradeBotDgbAt.some(item => item.atAddress === this.checkDgbAlice)) { + return + } - if (this.isEmptyArray(this.tradeBotAvailableDgbQortal) === true) { + await appDelay(1000) - } else { - const botdgbprice = this.round(parseFloat(this.tradeBotDgbBook[0].botDgbPrice)) - const changedgbamount = parseFloat(this.tradeBotDgbBook[0].botDgbQortAmount) - const reducedgbamount = parseFloat(this.tradeBotAvailableDgbQortal[0].qortAmount) - const tradedgbataddress = this.tradeBotAvailableDgbQortal[0].qortalAtAddress - const newdgbamount = this.round(parseFloat(changedgbamount - reducedgbamount)) + if (this.isEmptyArray(this.tradeBotAvailableDgbQortal) === true) { - this.reAddDgbAmount = this.round(parseFloat(this.tradeBotDgbBook[0].botDgbQortAmount)) - this.reAddDgbPrice = this.round(parseFloat(this.tradeBotDgbBook[0].botDgbPrice)) + } else { + const botdgbprice = this.round(parseFloat(this.tradeBotDgbBook[0].botDgbPrice)) + const changedgbamount = parseFloat(this.tradeBotDgbBook[0].botDgbQortAmount) + const reducedgbamount = parseFloat(this.tradeBotAvailableDgbQortal[0].qortAmount) + const tradedgbataddress = this.tradeBotAvailableDgbQortal[0].qortalAtAddress + const newdgbamount = this.round(parseFloat(changedgbamount - reducedgbamount)) - localStorage.removeItem(this.botDgbWallet) - localStorage.setItem(this.botDgbWallet, "") + this.reAddDgbAmount = this.round(parseFloat(this.tradeBotDgbBook[0].botDgbQortAmount)) + this.reAddDgbPrice = this.round(parseFloat(this.tradeBotDgbBook[0].botDgbPrice)) - var oldDgbTradebook = JSON.parse(localStorage.getItem(this.botDgbWallet) || "[]") + localStorage.removeItem(this.botDgbWallet) + localStorage.setItem(this.botDgbWallet, '') - const newDgbTradebookItem = { - botDgbQortAmount: newdgbamount, - botDgbPrice: botdgbprice - } + var oldDgbTradebook = JSON.parse(localStorage.getItem(this.botDgbWallet) || '[]') - oldDgbTradebook.push(newDgbTradebookItem) + const newDgbTradebookItem = { + botDgbQortAmount: newdgbamount, + botDgbPrice: botdgbprice + } - localStorage.setItem(this.botDgbWallet, JSON.stringify(oldDgbTradebook)) + oldDgbTradebook.push(newDgbTradebookItem) - this.tradeBotDgbBook = JSON.parse(localStorage.getItem(this.botDgbWallet) || "[]") + localStorage.setItem(this.botDgbWallet, JSON.stringify(oldDgbTradebook)) - this.botDgbBuyAtAddress = tradedgbataddress + this.tradeBotDgbBook = JSON.parse(localStorage.getItem(this.botDgbWallet) || '[]') - await appDelay(1000) + this.botDgbBuyAtAddress = tradedgbataddress - await this.buyDgbAction() + await appDelay(1000) - if (this.isEmptyArray(this.tradeBotDgbBook) === true) { - return - } else { - const botamount = parseFloat(this.tradeBotDgbBook[0].botDgbQortAmount) + await this.buyDgbAction() - if (Number(botamount) === 0) { - this.removeBotDGBTradebook() - } - } + if (this.isEmptyArray(this.tradeBotDgbBook) === true) { + return + } else { + const botamount = parseFloat(this.tradeBotDgbBook[0].botDgbQortAmount) - if (this.isEmptyArray(this.tradeBotDgbBook) === true) { + if (Number(botamount) === 0) { + this.removeBotDGBTradebook() + } + } - } else { - const checkBotDgbFunds = this.round(parseFloat(this.tradeBotDgbBook[0].botDgbQortAmount) * parseFloat(this.tradeBotDgbBook[0].botDgbPrice)) - const myBotDgbFunds = this.round(parseFloat(this.dgbWalletBalance)) + if (this.isEmptyArray(this.tradeBotDgbBook) === true) { - if (Number(myBotDgbFunds) < Number(checkBotDgbFunds)) { - this.removeBotDGBTradebook() - } - } - } - } + } else { + const checkBotDgbFunds = this.round(parseFloat(this.tradeBotDgbBook[0].botDgbQortAmount) * parseFloat(this.tradeBotDgbBook[0].botDgbPrice)) + const myBotDgbFunds = this.round(parseFloat(this.dgbWalletBalance)) - const getOpenTradesRVN = async () => { - let timerRVN + if (Number(myBotDgbFunds) < Number(checkBotDgbFunds)) { + this.removeBotDGBTradebook() + } + } + } + } - if (this.isEmptyArray(this.tradeBotRvnBook) === true) { - clearTimeout(timerRVN) - timerRVN = setTimeout(getOpenTradesRVN, 150000) - } else { - await this.updateRvnWalletBalance() - const tradesOpenRvnQortalUrl = `${nodeAppUrl}/crosschain/tradeoffers?foreignBlockchain=RAVENCOIN&limit=0` + const getOpenTradesRVN = async () => { + let timerRVN - const tradesOpenRvnQortal = await fetch(tradesOpenRvnQortalUrl).then(response => { - return response.json() - }) + if (this.isEmptyArray(this.tradeBotRvnBook) === true) { + clearTimeout(timerRVN) + timerRVN = setTimeout(getOpenTradesRVN, 150000) + } else { + await this.updateRvnWalletBalance() + const tradesOpenRvnQortalUrl = `${nodeAppUrl}/crosschain/tradeoffers?foreignBlockchain=RAVENCOIN&limit=0` - this.tradesOpenRvnQortal = tradesOpenRvnQortal.map(item => { - const expiryTime = item.creatorPresenceExpiry - if (Number(expiryTime) > Date.now()) { - const calcedPrice = parseFloat(item.expectedForeignAmount) / parseFloat(item.qortAmount) - const roundedPrice = (Math.round(parseFloat(calcedPrice) * 1e8) / 1e8).toFixed(8) - return { - qortAmount: item.qortAmount, - price: roundedPrice, - foreignAmount: item.expectedForeignAmount, - qortalCreator: item.qortalCreator, - qortalAtAddress: item.qortalAtAddress, - qortalCreatorTradeAddress: item.qortalCreatorTradeAddress - } - } - }).filter(item => !!item) + const tradesOpenRvnQortal = await fetch(tradesOpenRvnQortalUrl).then(response => { + return response.json() + }) - const unconfirmedTransactionsRVN = async () => { - const unconfirmedTransactionsUrlRVN = `${nodeAppUrl}/transactions/unconfirmed?txType=MESSAGE&limit=0&reverse=true` - var addFailedTradesRVN = JSON.parse(localStorage.getItem("failedTrades") || "[]") - await fetch(unconfirmedTransactionsUrlRVN).then(response => { - return response.json() - }).then(data => { - data.map(item => { - const unconfirmedNessageTimeDiffRVN = Date.now() - item.timestamp - const timeOneHourRVN = 60 * 60 * 1000 - if (Number(unconfirmedNessageTimeDiffRVN) > Number(timeOneHourRVN)) { - const addItRVN = { - timestamp: item.timestamp, - recipient: item.recipient - } - addFailedTradesRVN.push(addItRVN) - } - }) - localStorage.setItem("failedTrades", JSON.stringify(addFailedTradesRVN)) - this.failedTradesList = JSON.parse(localStorage.getItem("failedTrades") || "[]") - }) - } + this.tradesOpenRvnQortal = tradesOpenRvnQortal.map(item => { + const expiryTime = item.creatorPresenceExpiry + if (Number(expiryTime) > Date.now()) { + const calcedPrice = parseFloat(item.expectedForeignAmount) / parseFloat(item.qortAmount) + const roundedPrice = (Math.round(parseFloat(calcedPrice) * 1e8) / 1e8).toFixed(8) + return { + qortAmount: item.qortAmount, + price: roundedPrice, + foreignAmount: item.expectedForeignAmount, + qortalCreator: item.qortalCreator, + qortalAtAddress: item.qortalAtAddress, + qortalCreatorTradeAddress: item.qortalCreatorTradeAddress + } + } + }).filter(item => !!item) - await unconfirmedTransactionsRVN() + const unconfirmedTransactionsRVN = async () => { + const unconfirmedTransactionsUrlRVN = `${nodeAppUrl}/transactions/unconfirmed?txType=MESSAGE&limit=0&reverse=true` + var addFailedTradesRVN = JSON.parse(localStorage.getItem('failedTrades') || '[]') - const filterUnconfirmedTransactionsRVN = async () => { - let cleanFailedTradesRVN = this.failedTradesList.reduce((newArray, cut) => { - if(!newArray.some(obj => obj.recipient === cut.recipient)) { - newArray.push(cut) - } - return newArray - },[]) - localStorage.setItem("failedTrades", JSON.stringify(cleanFailedTradesRVN)) - this.failedTradesList = JSON.parse(localStorage.getItem("failedTrades") || "[]") - } + await fetch(unconfirmedTransactionsUrlRVN).then(response => { + return response.json() + }).then(data => { + data.map(item => { + const unconfirmedNessageTimeDiffRVN = Date.now() - item.timestamp + const timeOneHourRVN = 60 * 60 * 1000 + if (Number(unconfirmedNessageTimeDiffRVN) > Number(timeOneHourRVN)) { + const addItRVN = { + timestamp: item.timestamp, + recipient: item.recipient + } + addFailedTradesRVN.push(addItRVN) + } + }) - await filterUnconfirmedTransactionsRVN() + localStorage.setItem('failedTrades', JSON.stringify(addFailedTradesRVN)) + this.failedTradesList = JSON.parse(localStorage.getItem('failedTrades') || '[]') + }) + } - this.tradesOpenRvnQortalCleaned = this.tradesOpenRvnQortal + await unconfirmedTransactionsRVN() - const filterOpenOfferRVN = async () => { - this.failedTradesList.forEach(item => { - const recipientToRemove = item.recipient - this.tradesOpenRvnQortalCleaned = this.tradesOpenRvnQortalCleaned.filter(obj => { - return obj.qortalCreatorTradeAddress !== recipientToRemove - }) - }) - } + const filterUnconfirmedTransactionsRVN = async () => { + let cleanFailedTradesRVN = this.failedTradesList.reduce((newArray, cut) => { + if (!newArray.some(obj => obj.recipient === cut.recipient)) { + newArray.push(cut) + } - await filterOpenOfferRVN() - await appDelay(1000) - await filterMyBotPriceTradesRVN() - setTimeout(getOpenTradesRVN, 150000) - } - } + return newArray + }, []) - const filterMyBotPriceTradesRVN = async () => { - const tradeBotRvnUrl = `${nodeAppUrl}/crosschain/tradebot?foreignBlockchain=RAVENCOIN&apiKey=${this.getApiKey()}` + localStorage.setItem('failedTrades', JSON.stringify(cleanFailedTradesRVN)) + this.failedTradesList = JSON.parse(localStorage.getItem('failedTrades') || '[]') + } + + await filterUnconfirmedTransactionsRVN() + + this.tradesOpenRvnQortalCleaned = this.tradesOpenRvnQortal + + const filterOpenOfferRVN = async () => { + this.failedTradesList.forEach(item => { + const recipientToRemove = item.recipient + this.tradesOpenRvnQortalCleaned = this.tradesOpenRvnQortalCleaned.filter(obj => { + return obj.qortalCreatorTradeAddress !== recipientToRemove + }) + }) + } + + await filterOpenOfferRVN() + await appDelay(1000) + await filterMyBotPriceTradesRVN() + + setTimeout(getOpenTradesRVN, 150000) + } + } + + const filterMyBotPriceTradesRVN = async () => { + const tradeBotRvnUrl = `${nodeAppUrl}/crosschain/tradebot?foreignBlockchain=RAVENCOIN&apiKey=${this.getApiKey()}` this.tradeBotRvnAt = await fetch(tradeBotRvnUrl).then(response => { return response.json() }) - await appDelay(1000) + await appDelay(1000) - this.tradeBotAvailableRvnQortal = this.tradesOpenRvnQortalCleaned.map(item => { - const listprice = parseFloat(item.price) - const listamount = parseFloat(item.qortAmount) - const checkprice = parseFloat(this.tradeBotRvnBook[0].botRvnPrice) - const checkamount = parseFloat(this.tradeBotRvnBook[0].botRvnQortAmount) - if (Number(listprice) <= Number(checkprice) && Number(listamount) <= Number(checkamount)) { - return { - qortAmount: item.qortAmount, - price: item.price, - foreignAmount: item.foreignAmount, - qortalCreator: item.qortalCreator, - qortalAtAddress: item.qortalAtAddress, - qortalCreatorTradeAddress: item.qortalCreatorTradeAddress - } - } - }).filter(item => !!item) + this.tradeBotAvailableRvnQortal = this.tradesOpenRvnQortalCleaned.map(item => { + const listprice = parseFloat(item.price) + const listamount = parseFloat(item.qortAmount) + const checkprice = parseFloat(this.tradeBotRvnBook[0].botRvnPrice) + const checkamount = parseFloat(this.tradeBotRvnBook[0].botRvnQortAmount) + if (Number(listprice) <= Number(checkprice) && Number(listamount) <= Number(checkamount)) { + return { + qortAmount: item.qortAmount, + price: item.price, + foreignAmount: item.foreignAmount, + qortalCreator: item.qortalCreator, + qortalAtAddress: item.qortalAtAddress, + qortalCreatorTradeAddress: item.qortalCreatorTradeAddress + } + } + }).filter(item => !!item) - this.tradeBotAvailableRvnQortal.sort((a, b) => parseFloat(a.price) - parseFloat(b.price)) + this.tradeBotAvailableRvnQortal.sort((a, b) => parseFloat(a.price) - parseFloat(b.price)) - if (this.isEmptyArray(this.tradeBotAvailableRvnQortal) === true) { - return - } else { - this.checkRvnAlice = this.tradeBotAvailableRvnQortal[0].qortalAtAddress - } + if (this.isEmptyArray(this.tradeBotAvailableRvnQortal) === true) { + return + } else { + this.checkRvnAlice = this.tradeBotAvailableRvnQortal[0].qortalAtAddress + } - await appDelay(1000) + await appDelay(1000) - if (this.tradeBotRvnAt.some(item => item.atAddress === this.checkRvnAlice)) { - return - } + if (this.tradeBotRvnAt.some(item => item.atAddress === this.checkRvnAlice)) { + return + } - await appDelay(1000) + await appDelay(1000) - if (this.isEmptyArray(this.tradeBotAvailableRvnQortal) === true) { + if (this.isEmptyArray(this.tradeBotAvailableRvnQortal) === true) { - } else { - const botrvnprice = this.round(parseFloat(this.tradeBotRvnBook[0].botRvnPrice)) - const changervnamount = parseFloat(this.tradeBotRvnBook[0].botRvnQortAmount) - const reducervnamount = parseFloat(this.tradeBotAvailableRvnQortal[0].qortAmount) - const tradervnataddress = this.tradeBotAvailableRvnQortal[0].qortalAtAddress - const newrvnamount = this.round(parseFloat(changervnamount - reducervnamount)) + } else { + const botrvnprice = this.round(parseFloat(this.tradeBotRvnBook[0].botRvnPrice)) + const changervnamount = parseFloat(this.tradeBotRvnBook[0].botRvnQortAmount) + const reducervnamount = parseFloat(this.tradeBotAvailableRvnQortal[0].qortAmount) + const tradervnataddress = this.tradeBotAvailableRvnQortal[0].qortalAtAddress + const newrvnamount = this.round(parseFloat(changervnamount - reducervnamount)) - this.reAddRvnAmount = this.round(parseFloat(this.tradeBotRvnBook[0].botRvnQortAmount)) - this.reAddRvnPrice = this.round(parseFloat(this.tradeBotRvnBook[0].botRvnPrice)) + this.reAddRvnAmount = this.round(parseFloat(this.tradeBotRvnBook[0].botRvnQortAmount)) + this.reAddRvnPrice = this.round(parseFloat(this.tradeBotRvnBook[0].botRvnPrice)) - localStorage.removeItem(this.botRvnWallet) - localStorage.setItem(this.botRvnWallet, "") + localStorage.removeItem(this.botRvnWallet) + localStorage.setItem(this.botRvnWallet, '') - var oldRvnTradebook = JSON.parse(localStorage.getItem(this.botRvnWallet) || "[]") + var oldRvnTradebook = JSON.parse(localStorage.getItem(this.botRvnWallet) || '[]') - const newRvnTradebookItem = { - botRvnQortAmount: newrvnamount, - botRvnPrice: botrvnprice - } + const newRvnTradebookItem = { + botRvnQortAmount: newrvnamount, + botRvnPrice: botrvnprice + } - oldRvnTradebook.push(newRvnTradebookItem) + oldRvnTradebook.push(newRvnTradebookItem) - localStorage.setItem(this.botRvnWallet, JSON.stringify(oldRvnTradebook)) + localStorage.setItem(this.botRvnWallet, JSON.stringify(oldRvnTradebook)) - this.tradeBotRvnBook = JSON.parse(localStorage.getItem(this.botRvnWallet) || "[]") + this.tradeBotRvnBook = JSON.parse(localStorage.getItem(this.botRvnWallet) || '[]') - this.botRvnBuyAtAddress = tradervnataddress + this.botRvnBuyAtAddress = tradervnataddress - await appDelay(1000) + await appDelay(1000) - await this.buyRvnAction() + await this.buyRvnAction() - if (this.isEmptyArray(this.tradeBotRvnBook) === true) { - return - } else { - const botamount = parseFloat(this.tradeBotRvnBook[0].botRvnQortAmount) + if (this.isEmptyArray(this.tradeBotRvnBook) === true) { + return + } else { + const botamount = parseFloat(this.tradeBotRvnBook[0].botRvnQortAmount) - if (Number(botamount) === 0) { - this.removeBotRVNTradebook() - } - } + if (Number(botamount) === 0) { + this.removeBotRVNTradebook() + } + } - if (this.isEmptyArray(this.tradeBotRvnBook) === true) { + if (this.isEmptyArray(this.tradeBotRvnBook) === true) { - } else { - const checkBotRvnFunds = this.round(parseFloat(this.tradeBotRvnBook[0].botRvnQortAmount) * parseFloat(this.tradeBotRvnBook[0].botRvnPrice)) - const myBotRvnFunds = this.round(parseFloat(this.rvnWalletBalance)) + } else { + const checkBotRvnFunds = this.round(parseFloat(this.tradeBotRvnBook[0].botRvnQortAmount) * parseFloat(this.tradeBotRvnBook[0].botRvnPrice)) + const myBotRvnFunds = this.round(parseFloat(this.rvnWalletBalance)) - if (Number(myBotRvnFunds) < Number(checkBotRvnFunds)) { - this.removeBotRVNTradebook() - } - } - } - } + if (Number(myBotRvnFunds) < Number(checkBotRvnFunds)) { + this.removeBotRVNTradebook() + } + } + } + } - const getOpenTradesARRR = async () => { - let timerARRR + const getOpenTradesARRR = async () => { + let timerARRR - if (this.isEmptyArray(this.tradeBotArrrBook) === true) { - clearTimeout(timerARRR) - timerARRR = setTimeout(getOpenTradesARRR, 150000) - } else { - await this.updateArrrWalletBalance() - const tradesOpenArrrQortalUrl = `${nodeAppUrl}/crosschain/tradeoffers?foreignBlockchain=PIRATECHAIN&limit=0` + if (this.isEmptyArray(this.tradeBotArrrBook) === true) { + clearTimeout(timerARRR) + timerARRR = setTimeout(getOpenTradesARRR, 150000) + } else { + await this.updateArrrWalletBalance() + const tradesOpenArrrQortalUrl = `${nodeAppUrl}/crosschain/tradeoffers?foreignBlockchain=PIRATECHAIN&limit=0` - const tradesOpenArrrQortal = await fetch(tradesOpenArrrQortalUrl).then(response => { - return response.json() - }) + const tradesOpenArrrQortal = await fetch(tradesOpenArrrQortalUrl).then(response => { + return response.json() + }) - this.tradesOpenArrrQortal = tradesOpenArrrQortal.map(item => { - const expiryTime = item.creatorPresenceExpiry - if (Number(expiryTime) > Date.now()) { - const calcedPrice = parseFloat(item.expectedForeignAmount) / parseFloat(item.qortAmount) - const roundedPrice = (Math.round(parseFloat(calcedPrice) * 1e8) / 1e8).toFixed(8) - return { - qortAmount: item.qortAmount, - price: roundedPrice, - foreignAmount: item.expectedForeignAmount, - qortalCreator: item.qortalCreator, - qortalAtAddress: item.qortalAtAddress, - qortalCreatorTradeAddress: item.qortalCreatorTradeAddress - } - } - }).filter(item => !!item) + this.tradesOpenArrrQortal = tradesOpenArrrQortal.map(item => { + const expiryTime = item.creatorPresenceExpiry + if (Number(expiryTime) > Date.now()) { + const calcedPrice = parseFloat(item.expectedForeignAmount) / parseFloat(item.qortAmount) + const roundedPrice = (Math.round(parseFloat(calcedPrice) * 1e8) / 1e8).toFixed(8) + return { + qortAmount: item.qortAmount, + price: roundedPrice, + foreignAmount: item.expectedForeignAmount, + qortalCreator: item.qortalCreator, + qortalAtAddress: item.qortalAtAddress, + qortalCreatorTradeAddress: item.qortalCreatorTradeAddress + } + } + }).filter(item => !!item) - const unconfirmedTransactionsARRR = async () => { - const unconfirmedTransactionsUrlARRR = `${nodeAppUrl}/transactions/unconfirmed?txType=MESSAGE&limit=0&reverse=true` - var addFailedTradesARRR = JSON.parse(localStorage.getItem("failedTrades") || "[]") - await fetch(unconfirmedTransactionsUrlARRR).then(response => { - return response.json() - }).then(data => { - data.map(item => { - const unconfirmedNessageTimeDiffARRR = Date.now() - item.timestamp - const timeOneHourARRR = 60 * 60 * 1000 - if (Number(unconfirmedNessageTimeDiffARRR) > Number(timeOneHourARRR)) { - const addItARRR = { - timestamp: item.timestamp, - recipient: item.recipient - } - addFailedTradesARRR.push(addItARRR) - } - }) - localStorage.setItem("failedTrades", JSON.stringify(addFailedTradesARRR)) - this.failedTradesList = JSON.parse(localStorage.getItem("failedTrades") || "[]") - }) - } + const unconfirmedTransactionsARRR = async () => { + const unconfirmedTransactionsUrlARRR = `${nodeAppUrl}/transactions/unconfirmed?txType=MESSAGE&limit=0&reverse=true` + var addFailedTradesARRR = JSON.parse(localStorage.getItem('failedTrades') || '[]') - await unconfirmedTransactionsARRR() + await fetch(unconfirmedTransactionsUrlARRR).then(response => { + return response.json() + }).then(data => { + data.map(item => { + const unconfirmedNessageTimeDiffARRR = Date.now() - item.timestamp + const timeOneHourARRR = 60 * 60 * 1000 + if (Number(unconfirmedNessageTimeDiffARRR) > Number(timeOneHourARRR)) { + const addItARRR = { + timestamp: item.timestamp, + recipient: item.recipient + } + addFailedTradesARRR.push(addItARRR) + } + }) - const filterUnconfirmedTransactionsARRR = async () => { - let cleanFailedTradesARRR = this.failedTradesList.reduce((newArray, cut) => { - if(!newArray.some(obj => obj.recipient === cut.recipient)) { - newArray.push(cut) - } - return newArray - },[]) - localStorage.setItem("failedTrades", JSON.stringify(cleanFailedTradesARRR)) - this.failedTradesList = JSON.parse(localStorage.getItem("failedTrades") || "[]") - } + localStorage.setItem('failedTrades', JSON.stringify(addFailedTradesARRR)) + this.failedTradesList = JSON.parse(localStorage.getItem('failedTrades') || '[]') + }) + } - await filterUnconfirmedTransactionsARRR() + await unconfirmedTransactionsARRR() - this.tradesOpenArrrQortalCleaned = this.tradesOpenArrrQortal + const filterUnconfirmedTransactionsARRR = async () => { + let cleanFailedTradesARRR = this.failedTradesList.reduce((newArray, cut) => { + if (!newArray.some(obj => obj.recipient === cut.recipient)) { + newArray.push(cut) + } - const filterOpenOfferARRR = async () => { - this.failedTradesList.forEach(item => { - const recipientToRemove = item.recipient - this.tradesOpenArrrQortalCleaned = this.tradesOpenArrrQortalCleaned.filter(obj => { - return obj.qortalCreatorTradeAddress !== recipientToRemove - }) - }) - } + return newArray + }, []) - await filterOpenOfferARRR() - await appDelay(1000) - await filterMyBotPriceTradesARRR() - setTimeout(getOpenTradesARRR, 150000) - } - } + localStorage.setItem('failedTrades', JSON.stringify(cleanFailedTradesARRR)) + this.failedTradesList = JSON.parse(localStorage.getItem('failedTrades') || '[]') + } - const filterMyBotPriceTradesARRR = async () => { - const tradeBotArrrUrl = `${nodeAppUrl}/crosschain/tradebot?foreignBlockchain=PIRATECHAIN&apiKey=${this.getApiKey()}` + await filterUnconfirmedTransactionsARRR() + + this.tradesOpenArrrQortalCleaned = this.tradesOpenArrrQortal + + const filterOpenOfferARRR = async () => { + this.failedTradesList.forEach(item => { + const recipientToRemove = item.recipient + this.tradesOpenArrrQortalCleaned = this.tradesOpenArrrQortalCleaned.filter(obj => { + return obj.qortalCreatorTradeAddress !== recipientToRemove + }) + }) + } + + await filterOpenOfferARRR() + await appDelay(1000) + await filterMyBotPriceTradesARRR() + + setTimeout(getOpenTradesARRR, 150000) + } + } + + const filterMyBotPriceTradesARRR = async () => { + const tradeBotArrrUrl = `${nodeAppUrl}/crosschain/tradebot?foreignBlockchain=PIRATECHAIN&apiKey=${this.getApiKey()}` this.tradeBotArrrAt = await fetch(tradeBotArrrUrl).then(response => { return response.json() }) - await appDelay(1000) + await appDelay(1000) - this.tradeBotAvailableArrrQortal = this.tradesOpenArrrQortalCleaned.map(item => { - const listprice = parseFloat(item.price) - const listamount = parseFloat(item.qortAmount) - const checkprice = parseFloat(this.tradeBotArrrBook[0].botArrrPrice) - const checkamount = parseFloat(this.tradeBotArrrBook[0].botArrrQortAmount) - if (Number(listprice) <= Number(checkprice) && Number(listamount) <= Number(checkamount)) { - return { - qortAmount: item.qortAmount, - price: item.price, - foreignAmount: item.foreignAmount, - qortalCreator: item.qortalCreator, - qortalAtAddress: item.qortalAtAddress, - qortalCreatorTradeAddress: item.qortalCreatorTradeAddress - } - } - }).filter(item => !!item) - - this.tradeBotAvailableArrrQortal.sort((a, b) => parseFloat(a.price) - parseFloat(b.price)) - - if (this.isEmptyArray(this.tradeBotAvailableArrrQortal) === true) { - return - } else { - this.checkArrrAlice = this.tradeBotAvailableArrrQortal[0].qortalAtAddress - } - - await appDelay(1000) - - if (this.tradeBotArrrAt.some(item => item.atAddress === this.checkArrrAlice)) { - return - } - - await appDelay(1000) - - if (this.isEmptyArray(this.tradeBotAvailableArrrQortal) === true) { - - } else { - const botarrrprice = this.round(parseFloat(this.tradeBotArrrBook[0].botArrrPrice)) - const changearrramount = parseFloat(this.tradeBotArrrBook[0].botArrrQortAmount) - const reducearrramount = parseFloat(this.tradeBotAvailableArrrQortal[0].qortAmount) - const tradearrrataddress = this.tradeBotAvailableArrrQortal[0].qortalAtAddress - const newarrramount = this.round(parseFloat(changearrramount - reducearrramount)) - - this.reAddArrrAmount = this.round(parseFloat(this.tradeBotArrrBook[0].botArrrQortAmount)) - this.reAddArrrPrice = this.round(parseFloat(this.tradeBotArrrBook[0].botArrrPrice)) - - localStorage.removeItem(this.botArrrWallet) - localStorage.setItem(this.botArrrWallet, "") - - var oldArrrTradebook = JSON.parse(localStorage.getItem(this.botArrrWallet) || "[]") - - const newArrrTradebookItem = { - botArrrQortAmount: newarrramount, - botArrrPrice: botarrrprice - } - - oldArrrTradebook.push(newArrrTradebookItem) - - localStorage.setItem(this.botArrrWallet, JSON.stringify(oldArrrTradebook)) - - this.tradeBotArrrBook = JSON.parse(localStorage.getItem(this.botArrrWallet) || "[]") - - this.botArrrBuyAtAddress = tradearrrataddress - - await appDelay(1000) - - await this.buyArrrAction() - - if (this.isEmptyArray(this.tradeBotArrrBook) === true) { - return - } else { - const botamount = parseFloat(this.tradeBotArrrBook[0].botArrrQortAmount) - - if (Number(botamount) === 0) { - this.removeBotARRRTradebook() - } - } - - if (this.isEmptyArray(this.tradeBotArrrBook) === true) { - - } else { - const checkBotArrrFunds = this.round(parseFloat(this.tradeBotArrrBook[0].botArrrQortAmount) * parseFloat(this.tradeBotArrrBook[0].botArrrPrice)) - const myBotArrrFunds = this.round(parseFloat(this.arrrWalletBalance)) - - if (Number(myBotArrrFunds) < Number(checkBotArrrFunds)) { - this.removeBotARRRTradebook() - } - } - } - } - - const getChatLastSeen = async () => { - let items = [] - - await chatLastSeen.iterate(function (value, key, iterationNumber) { - items.push({ key, timestamp: value }) - }) - - store.dispatch(setChatLastSeen(items)) - return items - } - - await getOpenTradesBTC() - await appDelay(1000) - await getOpenTradesLTC() - await appDelay(1000) - await getOpenTradesDOGE() - await appDelay(1000) - await getOpenTradesDGB() - await appDelay(1000) - await getOpenTradesRVN() - await appDelay(1000) - await getOpenTradesARRR() - await getChatLastSeen() - setInterval(() => { - this.clearTheCache() - }, 60000) - } - - clearTheCache() { - if (!isElectron()) { - } else { - console.clear() - window.parent.electronAPI.clearMyCache() - window.parent.electronAPI.clearCache() - } - } - - async getNodeType() { - const myAppNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node] - const nodeAppUrl = myAppNode.protocol + '://' + myAppNode.domain + ':' + myAppNode.port - const url = `${nodeAppUrl}/admin/info` - await fetch(url).then((response) => { - return response.json() - }).then((data) => { - this.nodeType = data.type - }) - } - - renderNodeTypeMenu() { - const addressInfo = this.addressInfo - const isMinter = addressInfo?.error !== 124 && +addressInfo?.level > 0 - const isSponsor = +addressInfo?.level >= 5 - - if (this.nodeType === 'lite') { - return html` - - - - - - - - - - - - - - - - - ${this.renderNodeManagement()} - ` - } else { - return html` - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ${this.renderNodeManagement()} - - ` - } - } - - renderLockButton() { - if (this.myLockScreenPass === false && this.myLockScreenSet === false) { - return html` -
- this.openSetScreenLockPass()} title="${translate("login.lp11")}"> -
- ` - } else if (this.myLockScreenSet === false) { - return html` -
- this.setLockQortal()} title="${translate("login.lp11")}"> -
- ` - } else if (this.myLockScreenSet === true) { - return html` -
- -
- ` - } - } - - openSetScreenLockPass() { - this.shadowRoot.getElementById('lockPassword').value = '' - this.shadowRoot.getElementById('lockPasswordConfirm').value = '' - this.shadowRoot.getElementById('setLockScreenPass').open() - } - - closeSetScreenLockPass() { - this.shadowRoot.getElementById('setLockScreenPass').close() - } - - checkPass() { - const password = this.shadowRoot.getElementById('lockPassword').value - const rePassword = this.shadowRoot.getElementById('lockPasswordConfirm').value - - if (password === '') { - let snackbar1string = get("login.pleaseenter") - parentEpml.request('showSnackBar', `${snackbar1string}`) - return - } - - if (password != rePassword) { - let snackbar2string = get("login.notmatch") - parentEpml.request('showSnackBar', `${snackbar2string}`) - return - } - - if (password.length < 8) { - let snackbar3string = get("login.lessthen8") - parentEpml.request('showSnackBar', `${snackbar3string}`) - this.lowPass = '' - this.lowPass = password - this.extraConfirm() - } - - if (password.length >= 8) { - this.setNewScreenPass() - let snackbar4string = get("login.lp6") - parentEpml.request('showSnackBar', `${snackbar4string}`) - } - } - - extraConfirm() { - this.shadowRoot.getElementById('setLockScreenPass').close() - this.shadowRoot.getElementById('extraConfirmPass').open() - } - - closExtraConfirmPass() { - this.shadowRoot.getElementById('extraConfirmPass').close() - this.shadowRoot.getElementById('lockPassword').value = '' - this.shadowRoot.getElementById('lockPasswordConfirm').value = '' - } - - setNewScreenPass() { - const rawPassword = this.shadowRoot.getElementById('lockPassword').value - const cryptPassword = encryptData(rawPassword, this.salt) - localStorage.setItem(this.lockScreenPass, cryptPassword) - this.myLockScreenPass = '' - this.myLockScreenPass = decryptData(localStorage.getItem(this.lockScreenPass), this.salt) - this.shadowRoot.getElementById('setLockScreenPass').close() - this.shadowRoot.getElementById('extraConfirmPass').close() - this.shadowRoot.getElementById('lockPassword').value = '' - this.shadowRoot.getElementById('lockPasswordConfirm').value = '' - } - - setLockQortal() { - this.helperMessage = this.renderHelperPass() - this.lockSet = '' - this.lockSet = encryptData(true, this.salt) - localStorage.setItem(this.lockScreenSet, this.lockSet) - this.myLockScreenSet = '' - this.myLockScreenSet = decryptData(localStorage.getItem(this.lockScreenSet), this.salt) - this.shadowRoot.getElementById('lockScreenActive').open() - } - - passKeyListener(e) { - if (e.key === 'Enter') { - this.closeLockScreenActive() - } - } - - async closeLockScreenActive() { - const myPass = decryptData(localStorage.getItem(this.lockScreenPass), this.salt) - const checkPass = this.shadowRoot.getElementById('unlockPassword').value - const errDelay = ms => new Promise(res => setTimeout(res, ms)) - - if (checkPass === myPass) { - this.lockSet = '' - this.lockSet = encryptData(false, this.salt) - localStorage.setItem(this.lockScreenSet, this.lockSet) - this.myLockScreenSet = '' - this.myLockScreenSet = decryptData(localStorage.getItem(this.lockScreenSet), this.salt) - this.shadowRoot.getElementById('lockScreenActive').close() - this.shadowRoot.getElementById('unlockPassword').value = '' - this.helperMessage = this.renderHelperPass() - } else { - this.shadowRoot.getElementById('unlockPassword').value = '' - this.helperMessage = this.renderHelperErr() - await errDelay(3000) - this.helperMessage = this.renderHelperPass() - - } - } - - renderHelperPass() { - return html`${translate("login.pleaseenter")}` - } - - renderHelperErr() { - return html`${translate("login.lp8")}` - } - - renderNodeManagement() { - const checkNodeManagement = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node] - if ((checkNodeManagement.enableManagement = true)) { - return html` - - - - ` - } else { - return html`` - } - } - - async updateQortWalletBalance() { - let qortAddress = store.getState().app.selectedAddress.address - - await parentEpml.request('apiCall', { - url: `/addresses/balance/${qortAddress}?apiKey=${this.getApiKey()}`, - }).then((res) => { - this.qortWalletBalance = res - }) - } - - async updateBtcWalletBalance() { - let _url = `/crosschain/btc/walletbalance?apiKey=${this.getApiKey()}` - let _body = store.getState().app.selectedAddress.btcWallet.derivedMasterPublicKey - - await parentEpml.request('apiCall', { - url: _url, - method: 'POST', - body: _body, - }).then((res) => { - if (isNaN(Number(res))) { - //... - } else { - this.btcWalletBalance = (Number(res) / 1e8).toFixed(8) - } - }) - } - - async updateLtcWalletBalance() { - let _url = `/crosschain/ltc/walletbalance?apiKey=${this.getApiKey()}` - let _body = store.getState().app.selectedAddress.ltcWallet.derivedMasterPublicKey - - await parentEpml.request('apiCall', { - url: _url, - method: 'POST', - body: _body, - }).then((res) => { - if (isNaN(Number(res))) { - //... - } else { - this.ltcWalletBalance = (Number(res) / 1e8).toFixed(8) - } - }) - } - - async updateDogeWalletBalance() { - let _url = `/crosschain/doge/walletbalance?apiKey=${this.getApiKey()}` - let _body = store.getState().app.selectedAddress.dogeWallet.derivedMasterPublicKey - - await parentEpml.request('apiCall', { - url: _url, - method: 'POST', - body: _body, - }).then((res) => { - if (isNaN(Number(res))) { - //... - } else { - this.dogeWalletBalance = (Number(res) / 1e8).toFixed(8) - } - }) - } - - async updateDgbWalletBalance() { - let _url = `/crosschain/dgb/walletbalance?apiKey=${this.getApiKey()}` - let _body = store.getState().app.selectedAddress.dgbWallet.derivedMasterPublicKey - - await parentEpml.request('apiCall', { - url: _url, - method: 'POST', - body: _body, - }).then((res) => { - if (isNaN(Number(res))) { - //... - } else { - this.dgbWalletBalance = (Number(res) / 1e8).toFixed(8) - } - }) - } - - async updateRvnWalletBalance() { - let _url = `/crosschain/rvn/walletbalance?apiKey=${this.getApiKey()}` - let _body = store.getState().app.selectedAddress.rvnWallet.derivedMasterPublicKey - - await parentEpml.request('apiCall', { - url: _url, - method: 'POST', - body: _body, - }).then((res) => { - if (isNaN(Number(res))) { - //... - } else { - this.rvnWalletBalance = (Number(res) / 1e8).toFixed(8) - } - }) - } - - async updateArrrWalletBalance() { - let _url = `/crosschain/arrr/walletbalance?apiKey=${this.getApiKey()}` - let _body = store.getState().app.selectedAddress.arrrWallet.seed58 - - await parentEpml.request('apiCall', { - url: _url, - method: 'POST', - body: _body, - }).then((res) => { - if (isNaN(Number(res))) { - //... - } else { - this.arrrWalletBalance = (Number(res) / 1e8).toFixed(8) - } - }) - } - - botBtcTradebook() { - if (localStorage.getItem(this.botBtcWallet) === null) { - localStorage.setItem(this.botBtcWallet, "") - } else { - this.tradeBotBtcBook = JSON.parse(localStorage.getItem(this.botBtcWallet) || "[]") - } - } - - removeBotBTCTradebook() { - localStorage.removeItem(this.botBtcWallet) - localStorage.setItem(this.botBtcWallet, "") - this.tradeBotBtcBook = JSON.parse(localStorage.getItem(this.botBtcWallet) || "[]") - this.tradeBotAvailableBtcQortal = [] - } - - botLtcTradebook() { - if (localStorage.getItem(this.botLtcWallet) === null) { - localStorage.setItem(this.botLtcWallet, "") - } else { - this.tradeBotLtcBook = JSON.parse(localStorage.getItem(this.botLtcWallet) || "[]") - } - } - - removeBotLTCTradebook() { - localStorage.removeItem(this.botLtcWallet) - localStorage.setItem(this.botLtcWallet, "") - this.tradeBotLtcBook = JSON.parse(localStorage.getItem(this.botLtcWallet) || "[]") - this.tradeBotAvailableLtcQortal = [] - } - - botDogeTradebook() { - if (localStorage.getItem(this.botDogeWallet) === null) { - localStorage.setItem(this.botDogeWallet, "") - } else { - this.tradeBotDogeBook = JSON.parse(localStorage.getItem(this.botDogeWallet) || "[]") - } - } - - removeBotDOGETradebook() { - localStorage.removeItem(this.botDogeWallet) - localStorage.setItem(this.botDogeWallet, "") - this.tradeBotDogeBook = JSON.parse(localStorage.getItem(this.botDogeWallet) || "[]") - this.tradeBotAvailableDogeQortal = [] - } - - botDgbTradebook() { - if (localStorage.getItem(this.botDgbWallet) === null) { - localStorage.setItem(this.botDgbWallet, "") - } else { - this.tradeBotDgbBook = JSON.parse(localStorage.getItem(this.botDgbWallet) || "[]") - } - } - - botRvnTradebook() { - if (localStorage.getItem(this.botRvnWallet) === null) { - localStorage.setItem(this.botRvnWallet, "") - } else { - this.tradeBotRvnBook = JSON.parse(localStorage.getItem(this.botRvnWallet) || "[]") - } - } - - botArrrTradebook() { - if (localStorage.getItem(this.botArrrWallet) === null) { - localStorage.setItem(this.botArrrWallet, "") - } else { - this.tradeBotArrrBook = JSON.parse(localStorage.getItem(this.botArrrWallet) || "[]") - } - } - - async buyBtcAction() { - const makeRequest = async () => { + this.tradeBotAvailableArrrQortal = this.tradesOpenArrrQortalCleaned.map(item => { + const listprice = parseFloat(item.price) + const listamount = parseFloat(item.qortAmount) + const checkprice = parseFloat(this.tradeBotArrrBook[0].botArrrPrice) + const checkamount = parseFloat(this.tradeBotArrrBook[0].botArrrQortAmount) + + if (Number(listprice) <= Number(checkprice) && Number(listamount) <= Number(checkamount)) { + return { + qortAmount: item.qortAmount, + price: item.price, + foreignAmount: item.foreignAmount, + qortalCreator: item.qortalCreator, + qortalAtAddress: item.qortalAtAddress, + qortalCreatorTradeAddress: item.qortalCreatorTradeAddress + } + } + }).filter(item => !!item) + + this.tradeBotAvailableArrrQortal.sort((a, b) => parseFloat(a.price) - parseFloat(b.price)) + + if (this.isEmptyArray(this.tradeBotAvailableArrrQortal) === true) { + return + } else { + this.checkArrrAlice = this.tradeBotAvailableArrrQortal[0].qortalAtAddress + } + + await appDelay(1000) + + if (this.tradeBotArrrAt.some(item => item.atAddress === this.checkArrrAlice)) { + return + } + + await appDelay(1000) + + if (this.isEmptyArray(this.tradeBotAvailableArrrQortal) === true) { + + } else { + const botarrrprice = this.round(parseFloat(this.tradeBotArrrBook[0].botArrrPrice)) + const changearrramount = parseFloat(this.tradeBotArrrBook[0].botArrrQortAmount) + const reducearrramount = parseFloat(this.tradeBotAvailableArrrQortal[0].qortAmount) + const tradearrrataddress = this.tradeBotAvailableArrrQortal[0].qortalAtAddress + const newarrramount = this.round(parseFloat(changearrramount - reducearrramount)) + + this.reAddArrrAmount = this.round(parseFloat(this.tradeBotArrrBook[0].botArrrQortAmount)) + this.reAddArrrPrice = this.round(parseFloat(this.tradeBotArrrBook[0].botArrrPrice)) + + localStorage.removeItem(this.botArrrWallet) + localStorage.setItem(this.botArrrWallet, '') + + var oldArrrTradebook = JSON.parse(localStorage.getItem(this.botArrrWallet) || '[]') + + const newArrrTradebookItem = { + botArrrQortAmount: newarrramount, + botArrrPrice: botarrrprice + } + + oldArrrTradebook.push(newArrrTradebookItem) + + localStorage.setItem(this.botArrrWallet, JSON.stringify(oldArrrTradebook)) + + this.tradeBotArrrBook = JSON.parse(localStorage.getItem(this.botArrrWallet) || '[]') + + this.botArrrBuyAtAddress = tradearrrataddress + + await appDelay(1000) + + await this.buyArrrAction() + + if (this.isEmptyArray(this.tradeBotArrrBook) === true) { + return + } else { + const botamount = parseFloat(this.tradeBotArrrBook[0].botArrrQortAmount) + + if (Number(botamount) === 0) { + this.removeBotARRRTradebook() + } + } + + if (this.isEmptyArray(this.tradeBotArrrBook) === true) { + + } else { + const checkBotArrrFunds = this.round(parseFloat(this.tradeBotArrrBook[0].botArrrQortAmount) * parseFloat(this.tradeBotArrrBook[0].botArrrPrice)) + const myBotArrrFunds = this.round(parseFloat(this.arrrWalletBalance)) + + if (Number(myBotArrrFunds) < Number(checkBotArrrFunds)) { + this.removeBotARRRTradebook() + } + } + } + } + + const getChatLastSeen = async () => { + let items = [] + + await chatLastSeen.iterate(function (value, key, iterationNumber) { + items.push({ key, timestamp: value }) + }) + + store.dispatch(setChatLastSeen(items)) + return items + } + + await getOpenTradesBTC() + await appDelay(1000) + await getOpenTradesLTC() + await appDelay(1000) + await getOpenTradesDOGE() + await appDelay(1000) + await getOpenTradesDGB() + await appDelay(1000) + await getOpenTradesRVN() + await appDelay(1000) + await getOpenTradesARRR() + await getChatLastSeen() + + setInterval(() => { + this.clearTheCache() + }, 60000) + } + + getTourElements() { + let els = {} + + const el1 = this.shadowRoot.querySelector('core-sync-status').shadowRoot.getElementById('core-sync-status-id') + const el2 = this.shadowRoot.querySelector('show-plugin').shadowRoot.getElementById('showPluginId') + const el3 = this.shadowRoot.querySelector('beginner-checklist').shadowRoot.getElementById('popover-notification') + + if (el1) { + els['core-sync-status-id'] = el1 + } + + if (el2) { + els['tab'] = el2 + } + + if (el3) { + els['checklist'] = el3 + } + + return els + } + + clearTheCache() { + if (!isElectron()) { + } else { + console.clear() + + window.parent.electronAPI.clearMyCache() + window.parent.electronAPI.clearCache() + } + } + + async getNodeType() { + const myAppNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node] + const nodeAppUrl = myAppNode.protocol + '://' + myAppNode.domain + ':' + myAppNode.port + const url = `${nodeAppUrl}/admin/info` + + await fetch(url).then((response) => { + return response.json() + }).then((data) => { + this.nodeType = data.type + }) + } + + renderNodeTypeMenu() { + const addressInfo = this.addressInfo + const isMinter = addressInfo?.error !== 124 && +addressInfo?.level > 0 + const isSponsor = +addressInfo?.level >= 5 + + if (this.nodeType === 'lite') { + return html` + + + + + + + + + + + + + ${this.renderNodeManagement()} + ` + } else { + return html` + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${this.renderNodeManagement()} + + ` + } + } + + renderLockButton() { + if (this.myLockScreenPass === false && this.myLockScreenSet === false) { + return html` +
+ this.openSetScreenLockPass()} title="${translate("login.lp11")}"> +
+ ` + } else if (this.myLockScreenSet === false) { + return html` +
+ this.setLockQortal()} title="${translate("login.lp11")}"> +
+ ` + } else if (this.myLockScreenSet === true) { + return html` +
+ +
+ ` + } + } + + openSetScreenLockPass() { + this.shadowRoot.getElementById('lockPassword').value = '' + this.shadowRoot.getElementById('lockPasswordConfirm').value = '' + this.shadowRoot.getElementById('setLockScreenPass').open() + } + + closeSetScreenLockPass() { + this.shadowRoot.getElementById('setLockScreenPass').close() + } + + checkPass() { + const password = this.shadowRoot.getElementById('lockPassword').value + const rePassword = this.shadowRoot.getElementById('lockPasswordConfirm').value + + if (password === '') { + let snackbar1string = get("login.pleaseenter") + parentEpml.request('showSnackBar', `${snackbar1string}`) + return + } + + if (password != rePassword) { + let snackbar2string = get("login.notmatch") + parentEpml.request('showSnackBar', `${snackbar2string}`) + return + } + + if (password.length < 8) { + let snackbar3string = get("login.lessthen8") + parentEpml.request('showSnackBar', `${snackbar3string}`) + this.lowPass = '' + this.lowPass = password + this.extraConfirm() + } + + if (password.length >= 8) { + this.setNewScreenPass() + let snackbar4string = get("login.lp6") + parentEpml.request('showSnackBar', `${snackbar4string}`) + } + } + + extraConfirm() { + this.shadowRoot.getElementById('setLockScreenPass').close() + this.shadowRoot.getElementById('extraConfirmPass').open() + } + + closExtraConfirmPass() { + this.shadowRoot.getElementById('extraConfirmPass').close() + this.shadowRoot.getElementById('lockPassword').value = '' + this.shadowRoot.getElementById('lockPasswordConfirm').value = '' + } + + setNewScreenPass() { + const rawPassword = this.shadowRoot.getElementById('lockPassword').value + const cryptPassword = encryptData(rawPassword, this.salt) + + localStorage.setItem(this.lockScreenPass, cryptPassword) + + this.myLockScreenPass = '' + this.myLockScreenPass = decryptData(localStorage.getItem(this.lockScreenPass), this.salt) + this.shadowRoot.getElementById('setLockScreenPass').close() + this.shadowRoot.getElementById('extraConfirmPass').close() + this.shadowRoot.getElementById('lockPassword').value = '' + this.shadowRoot.getElementById('lockPasswordConfirm').value = '' + } + + setLockQortal() { + this.helperMessage = this.renderHelperPass() + this.lockSet = '' + this.lockSet = encryptData(true, this.salt) + + localStorage.setItem(this.lockScreenSet, this.lockSet) + + this.myLockScreenSet = '' + this.myLockScreenSet = decryptData(localStorage.getItem(this.lockScreenSet), this.salt) + this.shadowRoot.getElementById('lockScreenActive').open() + } + + passKeyListener(e) { + if (e.key === 'Enter') { + this.closeLockScreenActive() + } + } + + async closeLockScreenActive() { + const myPass = decryptData(localStorage.getItem(this.lockScreenPass), this.salt) + const checkPass = this.shadowRoot.getElementById('unlockPassword').value + const errDelay = ms => new Promise(res => setTimeout(res, ms)) + + if (checkPass === myPass) { + this.lockSet = '' + this.lockSet = encryptData(false, this.salt) + + localStorage.setItem(this.lockScreenSet, this.lockSet) + + this.myLockScreenSet = '' + this.myLockScreenSet = decryptData(localStorage.getItem(this.lockScreenSet), this.salt) + this.shadowRoot.getElementById('lockScreenActive').close() + this.shadowRoot.getElementById('unlockPassword').value = '' + this.helperMessage = this.renderHelperPass() + } else { + this.shadowRoot.getElementById('unlockPassword').value = '' + this.helperMessage = this.renderHelperErr() + + await errDelay(3000) + + this.helperMessage = this.renderHelperPass() + } + } + + renderHelperPass() { + return html`${translate("login.pleaseenter")}` + } + + renderHelperErr() { + return html`${translate("login.lp8")}` + } + + renderNodeManagement() { + const checkNodeManagement = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node] + + if ((checkNodeManagement.enableManagement = true)) { + return html` + + + + ` + } else { + return html`` + } + } + + async updateQortWalletBalance() { + let qortAddress = store.getState().app.selectedAddress.address + + await parentEpml.request('apiCall', { + url: `/addresses/balance/${qortAddress}?apiKey=${this.getApiKey()}`, + }).then((res) => { + this.qortWalletBalance = res + }) + } + + async updateBtcWalletBalance() { + let _url = `/crosschain/btc/walletbalance?apiKey=${this.getApiKey()}` + let _body = store.getState().app.selectedAddress.btcWallet.derivedMasterPublicKey + + await parentEpml.request('apiCall', { + url: _url, + method: 'POST', + body: _body, + }).then((res) => { + if (isNaN(Number(res))) { + //... + } else { + this.btcWalletBalance = (Number(res) / 1e8).toFixed(8) + } + }) + } + + async updateLtcWalletBalance() { + let _url = `/crosschain/ltc/walletbalance?apiKey=${this.getApiKey()}` + let _body = store.getState().app.selectedAddress.ltcWallet.derivedMasterPublicKey + + await parentEpml.request('apiCall', { + url: _url, + method: 'POST', + body: _body, + }).then((res) => { + if (isNaN(Number(res))) { + //... + } else { + this.ltcWalletBalance = (Number(res) / 1e8).toFixed(8) + } + }) + } + + async updateDogeWalletBalance() { + let _url = `/crosschain/doge/walletbalance?apiKey=${this.getApiKey()}` + let _body = store.getState().app.selectedAddress.dogeWallet.derivedMasterPublicKey + + await parentEpml.request('apiCall', { + url: _url, + method: 'POST', + body: _body, + }).then((res) => { + if (isNaN(Number(res))) { + //... + } else { + this.dogeWalletBalance = (Number(res) / 1e8).toFixed(8) + } + }) + } + + async updateDgbWalletBalance() { + let _url = `/crosschain/dgb/walletbalance?apiKey=${this.getApiKey()}` + let _body = store.getState().app.selectedAddress.dgbWallet.derivedMasterPublicKey + + await parentEpml.request('apiCall', { + url: _url, + method: 'POST', + body: _body, + }).then((res) => { + if (isNaN(Number(res))) { + //... + } else { + this.dgbWalletBalance = (Number(res) / 1e8).toFixed(8) + } + }) + } + + async updateRvnWalletBalance() { + let _url = `/crosschain/rvn/walletbalance?apiKey=${this.getApiKey()}` + let _body = store.getState().app.selectedAddress.rvnWallet.derivedMasterPublicKey + + await parentEpml.request('apiCall', { + url: _url, + method: 'POST', + body: _body, + }).then((res) => { + if (isNaN(Number(res))) { + //... + } else { + this.rvnWalletBalance = (Number(res) / 1e8).toFixed(8) + } + }) + } + + async updateArrrWalletBalance() { + let _url = `/crosschain/arrr/walletbalance?apiKey=${this.getApiKey()}` + let _body = store.getState().app.selectedAddress.arrrWallet.seed58 + + await parentEpml.request('apiCall', { + url: _url, + method: 'POST', + body: _body, + }).then((res) => { + if (isNaN(Number(res))) { + //... + } else { + this.arrrWalletBalance = (Number(res) / 1e8).toFixed(8) + } + }) + } + + botBtcTradebook() { + if (localStorage.getItem(this.botBtcWallet) === null) { + localStorage.setItem(this.botBtcWallet, '') + } else { + this.tradeBotBtcBook = JSON.parse(localStorage.getItem(this.botBtcWallet) || '[]') + } + } + + removeBotBTCTradebook() { + localStorage.removeItem(this.botBtcWallet) + localStorage.setItem(this.botBtcWallet, '') + + this.tradeBotBtcBook = JSON.parse(localStorage.getItem(this.botBtcWallet) || '[]') + this.tradeBotAvailableBtcQortal = [] + } + + botLtcTradebook() { + if (localStorage.getItem(this.botLtcWallet) === null) { + localStorage.setItem(this.botLtcWallet, '') + } else { + this.tradeBotLtcBook = JSON.parse(localStorage.getItem(this.botLtcWallet) || '[]') + } + } + + removeBotLTCTradebook() { + localStorage.removeItem(this.botLtcWallet) + localStorage.setItem(this.botLtcWallet, '') + + this.tradeBotLtcBook = JSON.parse(localStorage.getItem(this.botLtcWallet) || '[]') + this.tradeBotAvailableLtcQortal = [] + } + + botDogeTradebook() { + if (localStorage.getItem(this.botDogeWallet) === null) { + localStorage.setItem(this.botDogeWallet, '') + } else { + this.tradeBotDogeBook = JSON.parse(localStorage.getItem(this.botDogeWallet) || '[]') + } + } + + removeBotDOGETradebook() { + localStorage.removeItem(this.botDogeWallet) + localStorage.setItem(this.botDogeWallet, '') + + this.tradeBotDogeBook = JSON.parse(localStorage.getItem(this.botDogeWallet) || '[]') + this.tradeBotAvailableDogeQortal = [] + } + + botDgbTradebook() { + if (localStorage.getItem(this.botDgbWallet) === null) { + localStorage.setItem(this.botDgbWallet, '') + } else { + this.tradeBotDgbBook = JSON.parse(localStorage.getItem(this.botDgbWallet) || '[]') + } + } + + botRvnTradebook() { + if (localStorage.getItem(this.botRvnWallet) === null) { + localStorage.setItem(this.botRvnWallet, '') + } else { + this.tradeBotRvnBook = JSON.parse(localStorage.getItem(this.botRvnWallet) || '[]') + } + } + + botArrrTradebook() { + if (localStorage.getItem(this.botArrrWallet) === null) { + localStorage.setItem(this.botArrrWallet, '') + } else { + this.tradeBotArrrBook = JSON.parse(localStorage.getItem(this.botArrrWallet) || '[]') + } + } + + async buyBtcAction() { + const makeRequest = async () => { return await parentEpml.request('tradeBotRespondRequest', { atAddress: this.botBtcBuyAtAddress, foreignKey: store.getState().app.selectedAddress.btcWallet.derivedMasterPrivateKey, - receivingAddress: store.getState().app.selectedAddress.address, + receivingAddress: store.getState().app.selectedAddress.address }) - } + } - const manageResponse = (response) => { - if (response === true) { - let snack5string = get("tradepage.tchange23") - parentEpml.request('showSnackBar', `${snack5string}`) - } else if (response === false) { - localStorage.removeItem(this.botBtcWallet) - localStorage.setItem(this.botBtcWallet, "") + const manageResponse = (response) => { + if (response === true) { + let snack5string = get('tradepage.tchange23') + parentEpml.request('showSnackBar', `${snack5string}`) + } else if (response === false) { + localStorage.removeItem(this.botBtcWallet) + localStorage.setItem(this.botBtcWallet, '') - var oldBtcTradebook = JSON.parse(localStorage.getItem(this.botBtcWallet) || "[]") + var oldBtcTradebook = JSON.parse(localStorage.getItem(this.botBtcWallet) || '[]') - const newBtcTradebookItem = { - botBtcQortAmount: this.reAddBtcAmount, - botBtcPrice: this.reAddBtcPrice - } + const newBtcTradebookItem = { + botBtcQortAmount: this.reAddBtcAmount, + botBtcPrice: this.reAddBtcPrice + } - oldBtcTradebook.push(newBtcTradebookItem) + oldBtcTradebook.push(newBtcTradebookItem) - localStorage.setItem(this.botBtcWallet, JSON.stringify(oldBtcTradebook)) + localStorage.setItem(this.botBtcWallet, JSON.stringify(oldBtcTradebook)) - this.tradeBotBtcBook = JSON.parse(localStorage.getItem(this.botBtcWallet) || "[]") + this.tradeBotBtcBook = JSON.parse(localStorage.getItem(this.botBtcWallet) || '[]') - let snack6string = get("tradepage.tchange24") - parentEpml.request('showSnackBar', `${snack6string}`) - } else { - localStorage.removeItem(this.botBtcWallet) - localStorage.setItem(this.botBtcWallet, "") + let snack6string = get('tradepage.tchange24') + parentEpml.request('showSnackBar', `${snack6string}`) + } else { + localStorage.removeItem(this.botBtcWallet) + localStorage.setItem(this.botBtcWallet, '') - var oldBtcTradebook = JSON.parse(localStorage.getItem(this.botBtcWallet) || "[]") + var oldBtcTradebook = JSON.parse(localStorage.getItem(this.botBtcWallet) || '[]') - const newBtcTradebookItem = { - botBtcQortAmount: this.reAddBtcAmount, - botBtcPrice: this.reAddBtcPrice - } + const newBtcTradebookItem = { + botBtcQortAmount: this.reAddBtcAmount, + botBtcPrice: this.reAddBtcPrice + } - oldBtcTradebook.push(newBtcTradebookItem) + oldBtcTradebook.push(newBtcTradebookItem) - localStorage.setItem(this.botBtcWallet, JSON.stringify(oldBtcTradebook)) + localStorage.setItem(this.botBtcWallet, JSON.stringify(oldBtcTradebook)) - this.tradeBotBtcBook = JSON.parse(localStorage.getItem(this.botBtcWallet) || "[]") + this.tradeBotBtcBook = JSON.parse(localStorage.getItem(this.botBtcWallet) || '[]') - let snack7string = get("tradepage.tchange25") - parentEpml.request('showSnackBar', `${snack7string}: ${response.message}`) - } - } - const res = await makeRequest() - manageResponse(res) - } + let snack7string = get('tradepage.tchange25') + parentEpml.request('showSnackBar', `${snack7string}: ${response.message}`) + } + } - async buyLtcAction() { - const makeRequest = async () => { + const res = await makeRequest() + manageResponse(res) + } + + async buyLtcAction() { + const makeRequest = async () => { return await parentEpml.request('tradeBotRespondRequest', { atAddress: this.botLtcBuyAtAddress, foreignKey: store.getState().app.selectedAddress.ltcWallet.derivedMasterPrivateKey, - receivingAddress: store.getState().app.selectedAddress.address, + receivingAddress: store.getState().app.selectedAddress.address }) - } + } - const manageResponse = (response) => { - if (response === true) { - let snack5string = get("tradepage.tchange23") - parentEpml.request('showSnackBar', `${snack5string}`) - } else if (response === false) { - localStorage.removeItem(this.botLtcWallet) - localStorage.setItem(this.botLtcWallet, "") + const manageResponse = (response) => { + if (response === true) { + let snack5string = get('tradepage.tchange23') + parentEpml.request('showSnackBar', `${snack5string}`) + } else if (response === false) { + localStorage.removeItem(this.botLtcWallet) + localStorage.setItem(this.botLtcWallet, '') - var oldLtcTradebook = JSON.parse(localStorage.getItem(this.botLtcWallet) || "[]") + var oldLtcTradebook = JSON.parse(localStorage.getItem(this.botLtcWallet) || '[]') - const newLtcTradebookItem = { - botLtcQortAmount: this.reAddLtcAmount, - botLtcPrice: this.reAddLtcPrice - } + const newLtcTradebookItem = { + botLtcQortAmount: this.reAddLtcAmount, + botLtcPrice: this.reAddLtcPrice + } - oldLtcTradebook.push(newLtcTradebookItem) + oldLtcTradebook.push(newLtcTradebookItem) - localStorage.setItem(this.botLtcWallet, JSON.stringify(oldLtcTradebook)) + localStorage.setItem(this.botLtcWallet, JSON.stringify(oldLtcTradebook)) - this.tradeBotLtcBook = JSON.parse(localStorage.getItem(this.botLtcWallet) || "[]") + this.tradeBotLtcBook = JSON.parse(localStorage.getItem(this.botLtcWallet) || '[]') - let snack6string = get("tradepage.tchange24") - parentEpml.request('showSnackBar', `${snack6string}`) - } else { - localStorage.removeItem(this.botLtcWallet) - localStorage.setItem(this.botLtcWallet, "") + let snack6string = get('tradepage.tchange24') + parentEpml.request('showSnackBar', `${snack6string}`) + } else { + localStorage.removeItem(this.botLtcWallet) + localStorage.setItem(this.botLtcWallet, '') - var oldLtcTradebook = JSON.parse(localStorage.getItem(this.botLtcWallet) || "[]") + var oldLtcTradebook = JSON.parse(localStorage.getItem(this.botLtcWallet) || '[]') - const newLtcTradebookItem = { - botLtcQortAmount: this.reAddLtcAmount, - botLtcPrice: this.reAddLtcPrice - } + const newLtcTradebookItem = { + botLtcQortAmount: this.reAddLtcAmount, + botLtcPrice: this.reAddLtcPrice + } - oldLtcTradebook.push(newLtcTradebookItem) + oldLtcTradebook.push(newLtcTradebookItem) - localStorage.setItem(this.botLtcWallet, JSON.stringify(oldLtcTradebook)) + localStorage.setItem(this.botLtcWallet, JSON.stringify(oldLtcTradebook)) - this.tradeBotLtcBook = JSON.parse(localStorage.getItem(this.botLtcWallet) || "[]") + this.tradeBotLtcBook = JSON.parse(localStorage.getItem(this.botLtcWallet) || '[]') - let snack7string = get("tradepage.tchange25") - parentEpml.request('showSnackBar', `${snack7string}: ${response.message}`) - } - } - const res = await makeRequest() - manageResponse(res) - } + let snack7string = get('tradepage.tchange25') + parentEpml.request('showSnackBar', `${snack7string}: ${response.message}`) + } + } - async buyDogeAction() { - const makeRequest = async () => { + const res = await makeRequest() + manageResponse(res) + } + + async buyDogeAction() { + const makeRequest = async () => { return await parentEpml.request('tradeBotRespondRequest', { atAddress: this.botDogeBuyAtAddress, foreignKey: store.getState().app.selectedAddress.dogeWallet.derivedMasterPrivateKey, - receivingAddress: store.getState().app.selectedAddress.address, + receivingAddress: store.getState().app.selectedAddress.address }) - } + } - const manageResponse = (response) => { - if (response === true) { - let snack5string = get("tradepage.tchange23") - parentEpml.request('showSnackBar', `${snack5string}`) - } else if (response === false) { - localStorage.removeItem(this.botDogeWallet) - localStorage.setItem(this.botDogeWallet, "") + const manageResponse = (response) => { + if (response === true) { + let snack5string = get('tradepage.tchange23') + parentEpml.request('showSnackBar', `${snack5string}`) + } else if (response === false) { + localStorage.removeItem(this.botDogeWallet) + localStorage.setItem(this.botDogeWallet, '') - var oldDogeTradebook = JSON.parse(localStorage.getItem(this.botDogeWallet) || "[]") + var oldDogeTradebook = JSON.parse(localStorage.getItem(this.botDogeWallet) || '[]') - const newDogeTradebookItem = { - botDogeQortAmount: this.reAddDogeAmount, - botDogePrice: this.reAddDogePrice - } + const newDogeTradebookItem = { + botDogeQortAmount: this.reAddDogeAmount, + botDogePrice: this.reAddDogePrice + } - oldDogeTradebook.push(newDogeTradebookItem) + oldDogeTradebook.push(newDogeTradebookItem) - localStorage.setItem(this.botDogeWallet, JSON.stringify(oldDogeTradebook)) + localStorage.setItem(this.botDogeWallet, JSON.stringify(oldDogeTradebook)) - this.tradeBotDogeBook = JSON.parse(localStorage.getItem(this.botDogeWallet) || "[]") + this.tradeBotDogeBook = JSON.parse(localStorage.getItem(this.botDogeWallet) || '[]') - let snack6string = get("tradepage.tchange24") - parentEpml.request('showSnackBar', `${snack6string}`) - } else { - localStorage.removeItem(this.botDogeWallet) - localStorage.setItem(this.botDogeWallet, "") + let snack6string = get('tradepage.tchange24') + parentEpml.request('showSnackBar', `${snack6string}`) + } else { + localStorage.removeItem(this.botDogeWallet) + localStorage.setItem(this.botDogeWallet, '') - var oldDogeTradebook = JSON.parse(localStorage.getItem(this.botDogeWallet) || "[]") + var oldDogeTradebook = JSON.parse(localStorage.getItem(this.botDogeWallet) || '[]') - const newDogeTradebookItem = { - botDogeQortAmount: this.reAddDogeAmount, - botDogePrice: this.reAddDogePrice - } + const newDogeTradebookItem = { + botDogeQortAmount: this.reAddDogeAmount, + botDogePrice: this.reAddDogePrice + } - oldDogeTradebook.push(newDogeTradebookItem) + oldDogeTradebook.push(newDogeTradebookItem) - localStorage.setItem(this.botDogeWallet, JSON.stringify(oldDogeTradebook)) + localStorage.setItem(this.botDogeWallet, JSON.stringify(oldDogeTradebook)) - this.tradeBotDogeBook = JSON.parse(localStorage.getItem(this.botDogeWallet) || "[]") + this.tradeBotDogeBook = JSON.parse(localStorage.getItem(this.botDogeWallet) || '[]') - let snack7string = get("tradepage.tchange25") - parentEpml.request('showSnackBar', `${snack7string}: ${response.message}`) - } - } - const res = await makeRequest() - manageResponse(res) - } + let snack7string = get('tradepage.tchange25') + parentEpml.request('showSnackBar', `${snack7string}: ${response.message}`) + } + } - async buyDgbAction() { - const makeRequest = async () => { + const res = await makeRequest() + manageResponse(res) + } + + async buyDgbAction() { + const makeRequest = async () => { return await parentEpml.request('tradeBotRespondRequest', { atAddress: this.botDgbBuyAtAddress, foreignKey: store.getState().app.selectedAddress.dgbWallet.derivedMasterPrivateKey, - receivingAddress: store.getState().app.selectedAddress.address, + receivingAddress: store.getState().app.selectedAddress.address }) - } + } - const manageResponse = (response) => { - if (response === true) { - let snack5string = get("tradepage.tchange23") - parentEpml.request('showSnackBar', `${snack5string}`) - } else if (response === false) { - localStorage.removeItem(this.botDgbWallet) - localStorage.setItem(this.botDgbWallet, "") + const manageResponse = (response) => { + if (response === true) { + let snack5string = get('tradepage.tchange23') + parentEpml.request('showSnackBar', `${snack5string}`) + } else if (response === false) { + localStorage.removeItem(this.botDgbWallet) + localStorage.setItem(this.botDgbWallet, '') - var oldDgbTradebook = JSON.parse(localStorage.getItem(this.botDgbWallet) || "[]") + var oldDgbTradebook = JSON.parse(localStorage.getItem(this.botDgbWallet) || '[]') - const newDgbTradebookItem = { - botDgbQortAmount: this.reAddDgbAmount, - botDgbPrice: this.reAddDgbPrice - } + const newDgbTradebookItem = { + botDgbQortAmount: this.reAddDgbAmount, + botDgbPrice: this.reAddDgbPrice + } - oldDgbTradebook.push(newDgbTradebookItem) + oldDgbTradebook.push(newDgbTradebookItem) - localStorage.setItem(this.botDgbWallet, JSON.stringify(oldDgbTradebook)) + localStorage.setItem(this.botDgbWallet, JSON.stringify(oldDgbTradebook)) - this.tradeBotDgbBook = JSON.parse(localStorage.getItem(this.botDgbWallet) || "[]") + this.tradeBotDgbBook = JSON.parse(localStorage.getItem(this.botDgbWallet) || '[]') - let snack6string = get("tradepage.tchange24") - parentEpml.request('showSnackBar', `${snack6string}`) - } else { - localStorage.removeItem(this.botDgbWallet) - localStorage.setItem(this.botDgbWallet, "") + let snack6string = get('tradepage.tchange24') + parentEpml.request('showSnackBar', `${snack6string}`) + } else { + localStorage.removeItem(this.botDgbWallet) + localStorage.setItem(this.botDgbWallet, '') - var oldDgbTradebook = JSON.parse(localStorage.getItem(this.botDgbWallet) || "[]") + var oldDgbTradebook = JSON.parse(localStorage.getItem(this.botDgbWallet) || '[]') - const newDgbTradebookItem = { - botDgbQortAmount: this.reAddDgbAmount, - botDgbPrice: this.reAddDgbPrice - } + const newDgbTradebookItem = { + botDgbQortAmount: this.reAddDgbAmount, + botDgbPrice: this.reAddDgbPrice + } - oldDgbTradebook.push(newDgbTradebookItem) + oldDgbTradebook.push(newDgbTradebookItem) - localStorage.setItem(this.botDgbWallet, JSON.stringify(oldDgbTradebook)) + localStorage.setItem(this.botDgbWallet, JSON.stringify(oldDgbTradebook)) - this.tradeBotDgbBook = JSON.parse(localStorage.getItem(this.botDgbWallet) || "[]") + this.tradeBotDgbBook = JSON.parse(localStorage.getItem(this.botDgbWallet) || '[]') - let snack7string = get("tradepage.tchange25") - parentEpml.request('showSnackBar', `${snack7string}: ${response.message}`) - } - } - const res = await makeRequest() - manageResponse(res) - } + let snack7string = get('tradepage.tchange25') + parentEpml.request('showSnackBar', `${snack7string}: ${response.message}`) + } + } - async buyRvnAction() { - const makeRequest = async () => { + const res = await makeRequest() + manageResponse(res) + } + + async buyRvnAction() { + const makeRequest = async () => { return await parentEpml.request('tradeBotRespondRequest', { atAddress: this.botRvnBuyAtAddress, foreignKey: store.getState().app.selectedAddress.rvnWallet.derivedMasterPrivateKey, - receivingAddress: store.getState().app.selectedAddress.address, + receivingAddress: store.getState().app.selectedAddress.address }) - } + } - const manageResponse = (response) => { - if (response === true) { - let snack5string = get("tradepage.tchange23") - parentEpml.request('showSnackBar', `${snack5string}`) - } else if (response === false) { - localStorage.removeItem(this.botRvnWallet) - localStorage.setItem(this.botRvnWallet, "") + const manageResponse = (response) => { + if (response === true) { + let snack5string = get('tradepage.tchange23') + parentEpml.request('showSnackBar', `${snack5string}`) + } else if (response === false) { + localStorage.removeItem(this.botRvnWallet) + localStorage.setItem(this.botRvnWallet, '') - var oldRvnTradebook = JSON.parse(localStorage.getItem(this.botRvnWallet) || "[]") + var oldRvnTradebook = JSON.parse(localStorage.getItem(this.botRvnWallet) || '[]') - const newRvnTradebookItem = { - botRvnQortAmount: this.reAddRvnAmount, - botRvnPrice: this.reAddRvnPrice - } + const newRvnTradebookItem = { + botRvnQortAmount: this.reAddRvnAmount, + botRvnPrice: this.reAddRvnPrice + } - oldRvnTradebook.push(newRvnTradebookItem) + oldRvnTradebook.push(newRvnTradebookItem) - localStorage.setItem(this.botRvnWallet, JSON.stringify(oldRvnTradebook)) + localStorage.setItem(this.botRvnWallet, JSON.stringify(oldRvnTradebook)) - this.tradeBotRvnBook = JSON.parse(localStorage.getItem(this.botRvnWallet) || "[]") + this.tradeBotRvnBook = JSON.parse(localStorage.getItem(this.botRvnWallet) || '[]') - let snack6string = get("tradepage.tchange24") - parentEpml.request('showSnackBar', `${snack6string}`) - } else { - localStorage.removeItem(this.botRvnWallet) - localStorage.setItem(this.botRvnWallet, "") + let snack6string = get('tradepage.tchange24') + parentEpml.request('showSnackBar', `${snack6string}`) + } else { + localStorage.removeItem(this.botRvnWallet) + localStorage.setItem(this.botRvnWallet, '') - var oldRvnTradebook = JSON.parse(localStorage.getItem(this.botRvnWallet) || "[]") + var oldRvnTradebook = JSON.parse(localStorage.getItem(this.botRvnWallet) || '[]') - const newRvnTradebookItem = { - botRvnQortAmount: this.reAddRvnAmount, - botRvnPrice: this.reAddRvnPrice - } + const newRvnTradebookItem = { + botRvnQortAmount: this.reAddRvnAmount, + botRvnPrice: this.reAddRvnPrice + } - oldRvnTradebook.push(newRvnTradebookItem) + oldRvnTradebook.push(newRvnTradebookItem) - localStorage.setItem(this.botRvnWallet, JSON.stringify(oldRvnTradebook)) + localStorage.setItem(this.botRvnWallet, JSON.stringify(oldRvnTradebook)) - this.tradeBotRvnBook = JSON.parse(localStorage.getItem(this.botRvnWallet) || "[]") + this.tradeBotRvnBook = JSON.parse(localStorage.getItem(this.botRvnWallet) || '[]') - let snack7string = get("tradepage.tchange25") - parentEpml.request('showSnackBar', `${snack7string}: ${response.message}`) - } - } - const res = await makeRequest() - manageResponse(res) - } + let snack7string = get('tradepage.tchange25') + parentEpml.request('showSnackBar', `${snack7string}: ${response.message}`) + } + } - async buyArrrAction() { - const makeRequest = async () => { + const res = await makeRequest() + manageResponse(res) + } + + async buyArrrAction() { + const makeRequest = async () => { return await parentEpml.request('tradeBotRespondRequest', { atAddress: this.botArrrBuyAtAddress, foreignKey: store.getState().app.selectedAddress.arrrWallet.seed58, - receivingAddress: store.getState().app.selectedAddress.address, + receivingAddress: store.getState().app.selectedAddress.address }) - } + } - const manageResponse = (response) => { - if (response === true) { - let snack5string = get("tradepage.tchange23") - parentEpml.request('showSnackBar', `${snack5string}`) - } else if (response === false) { - localStorage.removeItem(this.botArrrWallet) - localStorage.setItem(this.botArrrWallet, "") + const manageResponse = (response) => { + if (response === true) { + let snack5string = get('tradepage.tchange23') + parentEpml.request('showSnackBar', `${snack5string}`) + } else if (response === false) { + localStorage.removeItem(this.botArrrWallet) + localStorage.setItem(this.botArrrWallet, '') - var oldArrrTradebook = JSON.parse(localStorage.getItem(this.botArrrWallet) || "[]") + var oldArrrTradebook = JSON.parse(localStorage.getItem(this.botArrrWallet) || '[]') - const newArrrTradebookItem = { - botArrrQortAmount: this.reAddArrrAmount, - botArrrPrice: this.reAddArrrPrice - } + const newArrrTradebookItem = { + botArrrQortAmount: this.reAddArrrAmount, + botArrrPrice: this.reAddArrrPrice + } - oldArrrTradebook.push(newArrrTradebookItem) + oldArrrTradebook.push(newArrrTradebookItem) - localStorage.setItem(this.botArrrWallet, JSON.stringify(oldArrrTradebook)) + localStorage.setItem(this.botArrrWallet, JSON.stringify(oldArrrTradebook)) - this.tradeBotArrrBook = JSON.parse(localStorage.getItem(this.botArrrWallet) || "[]") + this.tradeBotArrrBook = JSON.parse(localStorage.getItem(this.botArrrWallet) || '[]') - let snack6string = get("tradepage.tchange24") - parentEpml.request('showSnackBar', `${snack6string}`) - } else { - localStorage.removeItem(this.botArrrWallet) - localStorage.setItem(this.botArrrWallet, "") + let snack6string = get('tradepage.tchange24') + parentEpml.request('showSnackBar', `${snack6string}`) + } else { + localStorage.removeItem(this.botArrrWallet) + localStorage.setItem(this.botArrrWallet, '') - var oldArrrTradebook = JSON.parse(localStorage.getItem(this.botArrrWallet) || "[]") + var oldArrrTradebook = JSON.parse(localStorage.getItem(this.botArrrWallet) || '[]') - const newArrrTradebookItem = { - botArrrQortAmount: this.reAddArrrAmount, - botArrrPrice: this.reAddArrrPrice - } + const newArrrTradebookItem = { + botArrrQortAmount: this.reAddArrrAmount, + botArrrPrice: this.reAddArrrPrice + } - oldArrrTradebook.push(newArrrTradebookItem) + oldArrrTradebook.push(newArrrTradebookItem) - localStorage.setItem(this.botArrrWallet, JSON.stringify(oldArrrTradebook)) + localStorage.setItem(this.botArrrWallet, JSON.stringify(oldArrrTradebook)) - this.tradeBotArrrBook = JSON.parse(localStorage.getItem(this.botArrrWallet) || "[]") + this.tradeBotArrrBook = JSON.parse(localStorage.getItem(this.botArrrWallet) || '[]') - let snack7string = get("tradepage.tchange25") - parentEpml.request('showSnackBar', `${snack7string}: ${response.message}`) - } - } - const res = await makeRequest() - manageResponse(res) - } + let snack7string = get('tradepage.tchange25') + parentEpml.request('showSnackBar', `${snack7string}: ${response.message}`) + } + } - stateChanged(state) { - const split = state.app.url.split('/') - const sideurl = split[2] - this.config = state.config - this.urls = state.app.registeredUrls - this.addressInfo = state.app.accountInfo.addressInfo - this.showSyncMessages = state.app.showSyncIndicator + const res = await makeRequest() + manageResponse(res) + } - if (sideurl === "minting") { - this.shadowRoot.getElementById('qminter').setAttribute('selected', 'selected') - if (this.shadowRoot.getElementById('qbminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qbminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qiminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qiminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qwallet').hasAttribute('selected')) { - this.shadowRoot.getElementById('qwallet').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qtrade').hasAttribute('selected')) { - this.shadowRoot.getElementById('qtrade').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qbot').hasAttribute('selected')) { - this.shadowRoot.getElementById('qbot').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qrewardshare').hasAttribute('selected')) { - this.shadowRoot.getElementById('qrewardshare').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qchat').hasAttribute('selected')) { - this.shadowRoot.getElementById('qchat').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnamereg').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnamereg').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnamemarket').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnamemarket').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qweb').hasAttribute('selected')) { - this.shadowRoot.getElementById('qweb').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qapp').hasAttribute('selected')) { - this.shadowRoot.getElementById('qapp').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qgroupmange').hasAttribute('selected')) { - this.shadowRoot.getElementById('qgroupmange').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qpuzzles').hasAttribute('selected')) { - this.shadowRoot.getElementById('qpuzzles').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qdata').hasAttribute('selected')) { - this.shadowRoot.getElementById('qdata').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnode').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnode').removeAttribute('selected') - } - } else if (sideurl === "become-minter") { - this.shadowRoot.getElementById('qbminter').setAttribute('selected', 'selected') - if (this.shadowRoot.getElementById('qminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qiminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qiminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qwallet').hasAttribute('selected')) { - this.shadowRoot.getElementById('qwallet').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qtrade').hasAttribute('selected')) { - this.shadowRoot.getElementById('qtrade').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qbot').hasAttribute('selected')) { - this.shadowRoot.getElementById('qbot').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qrewardshare').hasAttribute('selected')) { - this.shadowRoot.getElementById('qrewardshare').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qchat').hasAttribute('selected')) { - this.shadowRoot.getElementById('qchat').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnamereg').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnamereg').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnamemarket').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnamemarket').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qweb').hasAttribute('selected')) { - this.shadowRoot.getElementById('qweb').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qapp').hasAttribute('selected')) { - this.shadowRoot.getElementById('qapp').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qgroupmange').hasAttribute('selected')) { - this.shadowRoot.getElementById('qgroupmange').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qpuzzles').hasAttribute('selected')) { - this.shadowRoot.getElementById('qpuzzles').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qdata').hasAttribute('selected')) { - this.shadowRoot.getElementById('qdata').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnode').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnode').removeAttribute('selected') - } - } else if (sideurl === "sponsorship-list") { - this.shadowRoot.getElementById('qiminter').setAttribute('selected', 'selected') - if (this.shadowRoot.getElementById('qminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qbminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qbminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qwallet').hasAttribute('selected')) { - this.shadowRoot.getElementById('qwallet').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qtrade').hasAttribute('selected')) { - this.shadowRoot.getElementById('qtrade').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qbot').hasAttribute('selected')) { - this.shadowRoot.getElementById('qbot').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qrewardshare').hasAttribute('selected')) { - this.shadowRoot.getElementById('qrewardshare').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qchat').hasAttribute('selected')) { - this.shadowRoot.getElementById('qchat').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnamereg').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnamereg').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnamemarket').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnamemarket').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qweb').hasAttribute('selected')) { - this.shadowRoot.getElementById('qweb').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qapp').hasAttribute('selected')) { - this.shadowRoot.getElementById('qapp').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qgroupmange').hasAttribute('selected')) { - this.shadowRoot.getElementById('qgroupmange').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qpuzzles').hasAttribute('selected')) { - this.shadowRoot.getElementById('qpuzzles').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qdata').hasAttribute('selected')) { - this.shadowRoot.getElementById('qdata').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnode').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnode').removeAttribute('selected') - } - } else if (sideurl === "wallet") { - this.shadowRoot.getElementById('qwallet').setAttribute('selected', 'selected') - if (this.shadowRoot.getElementById('qminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qbminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qbminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qiminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qiminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qtrade').hasAttribute('selected')) { - this.shadowRoot.getElementById('qtrade').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qbot').hasAttribute('selected')) { - this.shadowRoot.getElementById('qbot').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qrewardshare').hasAttribute('selected')) { - this.shadowRoot.getElementById('qrewardshare').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qchat').hasAttribute('selected')) { - this.shadowRoot.getElementById('qchat').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnamereg').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnamereg').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnamemarket').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnamemarket').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qweb').hasAttribute('selected')) { - this.shadowRoot.getElementById('qweb').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qapp').hasAttribute('selected')) { - this.shadowRoot.getElementById('qapp').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qgroupmange').hasAttribute('selected')) { - this.shadowRoot.getElementById('qgroupmange').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qpuzzles').hasAttribute('selected')) { - this.shadowRoot.getElementById('qpuzzles').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qdata').hasAttribute('selected')) { - this.shadowRoot.getElementById('qdata').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnode').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnode').removeAttribute('selected') - } - } else if (sideurl === "trade-portal") { - this.shadowRoot.getElementById('qtrade').setAttribute('selected', 'selected') - if (this.shadowRoot.getElementById('qminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qbminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qbminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qiminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qiminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qwallet').hasAttribute('selected')) { - this.shadowRoot.getElementById('qwallet').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qbot').hasAttribute('selected')) { - this.shadowRoot.getElementById('qbot').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qrewardshare').hasAttribute('selected')) { - this.shadowRoot.getElementById('qrewardshare').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qchat').hasAttribute('selected')) { - this.shadowRoot.getElementById('qchat').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnamereg').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnamereg').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnamemarket').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnamemarket').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qweb').hasAttribute('selected')) { - this.shadowRoot.getElementById('qweb').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qapp').hasAttribute('selected')) { - this.shadowRoot.getElementById('qapp').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qgroupmange').hasAttribute('selected')) { - this.shadowRoot.getElementById('qgroupmange').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qpuzzles').hasAttribute('selected')) { - this.shadowRoot.getElementById('qpuzzles').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qdata').hasAttribute('selected')) { - this.shadowRoot.getElementById('qdata').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnode').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnode').removeAttribute('selected') - } - } else if (sideurl === "trade-bot-portal") { - this.shadowRoot.getElementById('qbot').setAttribute('selected', 'selected') - if (this.shadowRoot.getElementById('qminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qbminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qbminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qiminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qiminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qwallet').hasAttribute('selected')) { - this.shadowRoot.getElementById('qwallet').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qtrade').hasAttribute('selected')) { - this.shadowRoot.getElementById('qtrade').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qrewardshare').hasAttribute('selected')) { - this.shadowRoot.getElementById('qrewardshare').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qchat').hasAttribute('selected')) { - this.shadowRoot.getElementById('qchat').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnamereg').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnamereg').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnamemarket').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnamemarket').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qweb').hasAttribute('selected')) { - this.shadowRoot.getElementById('qweb').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qapp').hasAttribute('selected')) { - this.shadowRoot.getElementById('qapp').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qgroupmange').hasAttribute('selected')) { - this.shadowRoot.getElementById('qgroupmange').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qpuzzles').hasAttribute('selected')) { - this.shadowRoot.getElementById('qpuzzles').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qdata').hasAttribute('selected')) { - this.shadowRoot.getElementById('qdata').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnode').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnode').removeAttribute('selected') - } - } else if (sideurl === "reward-share") { - this.shadowRoot.getElementById('qrewardshare').setAttribute('selected', 'selected') - if (this.shadowRoot.getElementById('qminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qbminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qbminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qiminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qiminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qwallet').hasAttribute('selected')) { - this.shadowRoot.getElementById('qwallet').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qtrade').hasAttribute('selected')) { - this.shadowRoot.getElementById('qtrade').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qbot').hasAttribute('selected')) { - this.shadowRoot.getElementById('qbot').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qchat').hasAttribute('selected')) { - this.shadowRoot.getElementById('qchat').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnamereg').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnamereg').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnamemarket').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnamemarket').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qweb').hasAttribute('selected')) { - this.shadowRoot.getElementById('qweb').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qapp').hasAttribute('selected')) { - this.shadowRoot.getElementById('qapp').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qgroupmange').hasAttribute('selected')) { - this.shadowRoot.getElementById('qgroupmange').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qpuzzles').hasAttribute('selected')) { - this.shadowRoot.getElementById('qpuzzles').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qdata').hasAttribute('selected')) { - this.shadowRoot.getElementById('qdata').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnode').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnode').removeAttribute('selected') - } - } else if (sideurl === "q-chat") { - this.shadowRoot.getElementById('qchat').setAttribute('selected', 'selected') - if (this.shadowRoot.getElementById('qminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qbminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qbminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qiminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qiminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qwallet').hasAttribute('selected')) { - this.shadowRoot.getElementById('qwallet').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qtrade').hasAttribute('selected')) { - this.shadowRoot.getElementById('qtrade').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qbot').hasAttribute('selected')) { - this.shadowRoot.getElementById('qbot').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qrewardshare').hasAttribute('selected')) { - this.shadowRoot.getElementById('qrewardshare').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnamereg').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnamereg').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnamemarket').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnamemarket').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qweb').hasAttribute('selected')) { - this.shadowRoot.getElementById('qweb').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qapp').hasAttribute('selected')) { - this.shadowRoot.getElementById('qapp').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qgroupmange').hasAttribute('selected')) { - this.shadowRoot.getElementById('qgroupmange').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qpuzzles').hasAttribute('selected')) { - this.shadowRoot.getElementById('qpuzzles').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qdata').hasAttribute('selected')) { - this.shadowRoot.getElementById('qdata').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnode').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnode').removeAttribute('selected') - } - } else if (sideurl === "name-registration") { - this.shadowRoot.getElementById('qnamereg').setAttribute('selected', 'selected') - if (this.shadowRoot.getElementById('qminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qbminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qbminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qiminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qiminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qwallet').hasAttribute('selected')) { - this.shadowRoot.getElementById('qwallet').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qtrade').hasAttribute('selected')) { - this.shadowRoot.getElementById('qtrade').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qbot').hasAttribute('selected')) { - this.shadowRoot.getElementById('qbot').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qrewardshare').hasAttribute('selected')) { - this.shadowRoot.getElementById('qrewardshare').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qchat').hasAttribute('selected')) { - this.shadowRoot.getElementById('qchat').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnamemarket').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnamemarket').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qweb').hasAttribute('selected')) { - this.shadowRoot.getElementById('qweb').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qapp').hasAttribute('selected')) { - this.shadowRoot.getElementById('qapp').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qgroupmange').hasAttribute('selected')) { - this.shadowRoot.getElementById('qgroupmange').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qpuzzles').hasAttribute('selected')) { - this.shadowRoot.getElementById('qpuzzles').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qdata').hasAttribute('selected')) { - this.shadowRoot.getElementById('qdata').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnode').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnode').removeAttribute('selected') - } - } else if (sideurl === "names-market") { - this.shadowRoot.getElementById('qnamemarket').setAttribute('selected', 'selected') - if (this.shadowRoot.getElementById('qminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qbminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qbminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qiminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qiminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qwallet').hasAttribute('selected')) { - this.shadowRoot.getElementById('qwallet').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qtrade').hasAttribute('selected')) { - this.shadowRoot.getElementById('qtrade').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qbot').hasAttribute('selected')) { - this.shadowRoot.getElementById('qbot').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qrewardshare').hasAttribute('selected')) { - this.shadowRoot.getElementById('qrewardshare').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qchat').hasAttribute('selected')) { - this.shadowRoot.getElementById('qchat').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnamereg').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnamereg').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qweb').hasAttribute('selected')) { - this.shadowRoot.getElementById('qweb').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qapp').hasAttribute('selected')) { - this.shadowRoot.getElementById('qapp').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qgroupmange').hasAttribute('selected')) { - this.shadowRoot.getElementById('qgroupmange').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qpuzzles').hasAttribute('selected')) { - this.shadowRoot.getElementById('qpuzzles').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qdata').hasAttribute('selected')) { - this.shadowRoot.getElementById('qdata').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnode').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnode').removeAttribute('selected') - } - } else if (sideurl === "websites") { - this.shadowRoot.getElementById('qweb').setAttribute('selected', 'selected') - if (this.shadowRoot.getElementById('qminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qbminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qbminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qiminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qiminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qwallet').hasAttribute('selected')) { - this.shadowRoot.getElementById('qwallet').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qtrade').hasAttribute('selected')) { - this.shadowRoot.getElementById('qtrade').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qbot').hasAttribute('selected')) { - this.shadowRoot.getElementById('qbot').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qrewardshare').hasAttribute('selected')) { - this.shadowRoot.getElementById('qrewardshare').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qchat').hasAttribute('selected')) { - this.shadowRoot.getElementById('qchat').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnamereg').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnamereg').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnamemarket').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnamemarket').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qapp').hasAttribute('selected')) { - this.shadowRoot.getElementById('qapp').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qgroupmange').hasAttribute('selected')) { - this.shadowRoot.getElementById('qgroupmange').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qpuzzles').hasAttribute('selected')) { - this.shadowRoot.getElementById('qpuzzles').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qdata').hasAttribute('selected')) { - this.shadowRoot.getElementById('qdata').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnode').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnode').removeAttribute('selected') - } - } else if (sideurl === "qapps") { - this.shadowRoot.getElementById('qapp').setAttribute('selected', 'selected') - if (this.shadowRoot.getElementById('qminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qbminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qbminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qiminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qiminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qwallet').hasAttribute('selected')) { - this.shadowRoot.getElementById('qwallet').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qtrade').hasAttribute('selected')) { - this.shadowRoot.getElementById('qtrade').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qbot').hasAttribute('selected')) { - this.shadowRoot.getElementById('qbot').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qrewardshare').hasAttribute('selected')) { - this.shadowRoot.getElementById('qrewardshare').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qchat').hasAttribute('selected')) { - this.shadowRoot.getElementById('qchat').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnamereg').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnamereg').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnamemarket').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnamemarket').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qweb').hasAttribute('selected')) { - this.shadowRoot.getElementById('qweb').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qgroupmange').hasAttribute('selected')) { - this.shadowRoot.getElementById('qgroupmange').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qpuzzles').hasAttribute('selected')) { - this.shadowRoot.getElementById('qpuzzles').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qdata').hasAttribute('selected')) { - this.shadowRoot.getElementById('qdata').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnode').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnode').removeAttribute('selected') - } - } else if (sideurl === "group-management") { - this.shadowRoot.getElementById('qgroupmange').setAttribute('selected', 'selected') - if (this.shadowRoot.getElementById('qminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qbminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qbminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qiminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qiminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qwallet').hasAttribute('selected')) { - this.shadowRoot.getElementById('qwallet').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qtrade').hasAttribute('selected')) { - this.shadowRoot.getElementById('qtrade').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qbot').hasAttribute('selected')) { - this.shadowRoot.getElementById('qbot').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qrewardshare').hasAttribute('selected')) { - this.shadowRoot.getElementById('qrewardshare').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qchat').hasAttribute('selected')) { - this.shadowRoot.getElementById('qchat').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnamereg').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnamereg').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnamemarket').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnamemarket').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qweb').hasAttribute('selected')) { - this.shadowRoot.getElementById('qweb').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qapp').hasAttribute('selected')) { - this.shadowRoot.getElementById('qapp').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qpuzzles').hasAttribute('selected')) { - this.shadowRoot.getElementById('qpuzzles').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qdata').hasAttribute('selected')) { - this.shadowRoot.getElementById('qdata').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnode').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnode').removeAttribute('selected') - } - } else if (sideurl === "puzzles") { - this.shadowRoot.getElementById('qpuzzles').setAttribute('selected', 'selected') - if (this.shadowRoot.getElementById('qminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qbminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qbminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qiminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qiminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qwallet').hasAttribute('selected')) { - this.shadowRoot.getElementById('qwallet').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qtrade').hasAttribute('selected')) { - this.shadowRoot.getElementById('qtrade').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qbot').hasAttribute('selected')) { - this.shadowRoot.getElementById('qbot').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qrewardshare').hasAttribute('selected')) { - this.shadowRoot.getElementById('qrewardshare').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qchat').hasAttribute('selected')) { - this.shadowRoot.getElementById('qchat').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnamereg').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnamereg').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnamemarket').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnamemarket').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qweb').hasAttribute('selected')) { - this.shadowRoot.getElementById('qweb').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qapp').hasAttribute('selected')) { - this.shadowRoot.getElementById('qapp').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qgroupmange').hasAttribute('selected')) { - this.shadowRoot.getElementById('qgroupmange').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qdata').hasAttribute('selected')) { - this.shadowRoot.getElementById('qdata').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnode').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnode').removeAttribute('selected') - } - } else if (sideurl === "data-management") { - this.shadowRoot.getElementById('qdata').setAttribute('selected', 'selected') - if (this.shadowRoot.getElementById('qminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qbminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qbminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qiminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qiminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qwallet').hasAttribute('selected')) { - this.shadowRoot.getElementById('qwallet').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qtrade').hasAttribute('selected')) { - this.shadowRoot.getElementById('qtrade').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qbot').hasAttribute('selected')) { - this.shadowRoot.getElementById('qbot').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qrewardshare').hasAttribute('selected')) { - this.shadowRoot.getElementById('qrewardshare').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qchat').hasAttribute('selected')) { - this.shadowRoot.getElementById('qchat').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnamereg').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnamereg').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnamemarket').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnamemarket').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qweb').hasAttribute('selected')) { - this.shadowRoot.getElementById('qweb').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qapp').hasAttribute('selected')) { - this.shadowRoot.getElementById('qapp').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qgroupmange').hasAttribute('selected')) { - this.shadowRoot.getElementById('qgroupmange').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qpuzzles').hasAttribute('selected')) { - this.shadowRoot.getElementById('qpuzzles').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnode').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnode').removeAttribute('selected') - } - } else if (sideurl === "node-management") { - this.shadowRoot.getElementById('qnode').setAttribute('selected', 'selected') - if (this.shadowRoot.getElementById('qminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qbminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qbminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qiminter').hasAttribute('selected')) { - this.shadowRoot.getElementById('qiminter').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qwallet').hasAttribute('selected')) { - this.shadowRoot.getElementById('qwallet').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qtrade').hasAttribute('selected')) { - this.shadowRoot.getElementById('qtrade').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qbot').hasAttribute('selected')) { - this.shadowRoot.getElementById('qbot').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qrewardshare').hasAttribute('selected')) { - this.shadowRoot.getElementById('qrewardshare').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qchat').hasAttribute('selected')) { - this.shadowRoot.getElementById('qchat').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnamereg').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnamereg').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qnamemarket').hasAttribute('selected')) { - this.shadowRoot.getElementById('qnamemarket').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qweb').hasAttribute('selected')) { - this.shadowRoot.getElementById('qweb').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qapp').hasAttribute('selected')) { - this.shadowRoot.getElementById('qapp').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qgroupmange').hasAttribute('selected')) { - this.shadowRoot.getElementById('qgroupmange').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qpuzzles').hasAttribute('selected')) { - this.shadowRoot.getElementById('qpuzzles').removeAttribute('selected') - } else if (this.shadowRoot.getElementById('qdata').hasAttribute('selected')) { - this.shadowRoot.getElementById('qdata').removeAttribute('selected') - } - } - } + stateChanged(state) { + const split = state.app.url.split('/') + const sideurl = split[2] + this.config = state.config + this.urls = state.app.registeredUrls + this.addressInfo = state.app.accountInfo.addressInfo + this.showSyncMessages = state.app.showSyncIndicator - openSettings() { - const settingsDialog = document.getElementById('main-app').shadowRoot.querySelector('app-view').shadowRoot.querySelector('user-settings') - settingsDialog.openSettings() - } + if (sideurl === 'minting') { + this.shadowRoot.getElementById('qminter').setAttribute('selected', 'selected') + if (this.shadowRoot.getElementById('qbminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qbminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qiminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qiminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qwallet').hasAttribute('selected')) { + this.shadowRoot.getElementById('qwallet').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qtrade').hasAttribute('selected')) { + this.shadowRoot.getElementById('qtrade').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qbot').hasAttribute('selected')) { + this.shadowRoot.getElementById('qbot').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qrewardshare').hasAttribute('selected')) { + this.shadowRoot.getElementById('qrewardshare').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qchat').hasAttribute('selected')) { + this.shadowRoot.getElementById('qchat').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnamereg').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnamereg').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnamemarket').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnamemarket').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qweb').hasAttribute('selected')) { + this.shadowRoot.getElementById('qweb').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qapp').hasAttribute('selected')) { + this.shadowRoot.getElementById('qapp').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qgroupmange').hasAttribute('selected')) { + this.shadowRoot.getElementById('qgroupmange').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qpuzzles').hasAttribute('selected')) { + this.shadowRoot.getElementById('qpuzzles').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qdata').hasAttribute('selected')) { + this.shadowRoot.getElementById('qdata').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnode').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnode').removeAttribute('selected') + } + } else if (sideurl === 'become-minter') { + this.shadowRoot.getElementById('qbminter').setAttribute('selected', 'selected') + if (this.shadowRoot.getElementById('qminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qiminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qiminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qwallet').hasAttribute('selected')) { + this.shadowRoot.getElementById('qwallet').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qtrade').hasAttribute('selected')) { + this.shadowRoot.getElementById('qtrade').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qbot').hasAttribute('selected')) { + this.shadowRoot.getElementById('qbot').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qrewardshare').hasAttribute('selected')) { + this.shadowRoot.getElementById('qrewardshare').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qchat').hasAttribute('selected')) { + this.shadowRoot.getElementById('qchat').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnamereg').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnamereg').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnamemarket').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnamemarket').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qweb').hasAttribute('selected')) { + this.shadowRoot.getElementById('qweb').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qapp').hasAttribute('selected')) { + this.shadowRoot.getElementById('qapp').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qgroupmange').hasAttribute('selected')) { + this.shadowRoot.getElementById('qgroupmange').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qpuzzles').hasAttribute('selected')) { + this.shadowRoot.getElementById('qpuzzles').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qdata').hasAttribute('selected')) { + this.shadowRoot.getElementById('qdata').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnode').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnode').removeAttribute('selected') + } + } else if (sideurl === 'sponsorship-list') { + this.shadowRoot.getElementById('qiminter').setAttribute('selected', 'selected') + if (this.shadowRoot.getElementById('qminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qbminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qbminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qwallet').hasAttribute('selected')) { + this.shadowRoot.getElementById('qwallet').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qtrade').hasAttribute('selected')) { + this.shadowRoot.getElementById('qtrade').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qbot').hasAttribute('selected')) { + this.shadowRoot.getElementById('qbot').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qrewardshare').hasAttribute('selected')) { + this.shadowRoot.getElementById('qrewardshare').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qchat').hasAttribute('selected')) { + this.shadowRoot.getElementById('qchat').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnamereg').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnamereg').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnamemarket').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnamemarket').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qweb').hasAttribute('selected')) { + this.shadowRoot.getElementById('qweb').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qapp').hasAttribute('selected')) { + this.shadowRoot.getElementById('qapp').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qgroupmange').hasAttribute('selected')) { + this.shadowRoot.getElementById('qgroupmange').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qpuzzles').hasAttribute('selected')) { + this.shadowRoot.getElementById('qpuzzles').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qdata').hasAttribute('selected')) { + this.shadowRoot.getElementById('qdata').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnode').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnode').removeAttribute('selected') + } + } else if (sideurl === 'wallet') { + this.shadowRoot.getElementById('qwallet').setAttribute('selected', 'selected') + if (this.shadowRoot.getElementById('qminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qbminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qbminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qiminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qiminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qtrade').hasAttribute('selected')) { + this.shadowRoot.getElementById('qtrade').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qbot').hasAttribute('selected')) { + this.shadowRoot.getElementById('qbot').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qrewardshare').hasAttribute('selected')) { + this.shadowRoot.getElementById('qrewardshare').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qchat').hasAttribute('selected')) { + this.shadowRoot.getElementById('qchat').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnamereg').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnamereg').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnamemarket').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnamemarket').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qweb').hasAttribute('selected')) { + this.shadowRoot.getElementById('qweb').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qapp').hasAttribute('selected')) { + this.shadowRoot.getElementById('qapp').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qgroupmange').hasAttribute('selected')) { + this.shadowRoot.getElementById('qgroupmange').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qpuzzles').hasAttribute('selected')) { + this.shadowRoot.getElementById('qpuzzles').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qdata').hasAttribute('selected')) { + this.shadowRoot.getElementById('qdata').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnode').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnode').removeAttribute('selected') + } + } else if (sideurl === 'trade-portal') { + this.shadowRoot.getElementById('qtrade').setAttribute('selected', 'selected') + if (this.shadowRoot.getElementById('qminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qbminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qbminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qiminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qiminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qwallet').hasAttribute('selected')) { + this.shadowRoot.getElementById('qwallet').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qbot').hasAttribute('selected')) { + this.shadowRoot.getElementById('qbot').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qrewardshare').hasAttribute('selected')) { + this.shadowRoot.getElementById('qrewardshare').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qchat').hasAttribute('selected')) { + this.shadowRoot.getElementById('qchat').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnamereg').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnamereg').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnamemarket').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnamemarket').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qweb').hasAttribute('selected')) { + this.shadowRoot.getElementById('qweb').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qapp').hasAttribute('selected')) { + this.shadowRoot.getElementById('qapp').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qgroupmange').hasAttribute('selected')) { + this.shadowRoot.getElementById('qgroupmange').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qpuzzles').hasAttribute('selected')) { + this.shadowRoot.getElementById('qpuzzles').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qdata').hasAttribute('selected')) { + this.shadowRoot.getElementById('qdata').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnode').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnode').removeAttribute('selected') + } + } else if (sideurl === 'trade-bot-portal') { + this.shadowRoot.getElementById('qbot').setAttribute('selected', 'selected') + if (this.shadowRoot.getElementById('qminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qbminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qbminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qiminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qiminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qwallet').hasAttribute('selected')) { + this.shadowRoot.getElementById('qwallet').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qtrade').hasAttribute('selected')) { + this.shadowRoot.getElementById('qtrade').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qrewardshare').hasAttribute('selected')) { + this.shadowRoot.getElementById('qrewardshare').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qchat').hasAttribute('selected')) { + this.shadowRoot.getElementById('qchat').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnamereg').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnamereg').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnamemarket').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnamemarket').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qweb').hasAttribute('selected')) { + this.shadowRoot.getElementById('qweb').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qapp').hasAttribute('selected')) { + this.shadowRoot.getElementById('qapp').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qgroupmange').hasAttribute('selected')) { + this.shadowRoot.getElementById('qgroupmange').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qpuzzles').hasAttribute('selected')) { + this.shadowRoot.getElementById('qpuzzles').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qdata').hasAttribute('selected')) { + this.shadowRoot.getElementById('qdata').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnode').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnode').removeAttribute('selected') + } + } else if (sideurl === 'reward-share') { + this.shadowRoot.getElementById('qrewardshare').setAttribute('selected', 'selected') + if (this.shadowRoot.getElementById('qminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qbminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qbminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qiminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qiminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qwallet').hasAttribute('selected')) { + this.shadowRoot.getElementById('qwallet').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qtrade').hasAttribute('selected')) { + this.shadowRoot.getElementById('qtrade').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qbot').hasAttribute('selected')) { + this.shadowRoot.getElementById('qbot').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qchat').hasAttribute('selected')) { + this.shadowRoot.getElementById('qchat').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnamereg').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnamereg').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnamemarket').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnamemarket').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qweb').hasAttribute('selected')) { + this.shadowRoot.getElementById('qweb').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qapp').hasAttribute('selected')) { + this.shadowRoot.getElementById('qapp').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qgroupmange').hasAttribute('selected')) { + this.shadowRoot.getElementById('qgroupmange').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qpuzzles').hasAttribute('selected')) { + this.shadowRoot.getElementById('qpuzzles').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qdata').hasAttribute('selected')) { + this.shadowRoot.getElementById('qdata').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnode').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnode').removeAttribute('selected') + } + } else if (sideurl === 'q-chat') { + this.shadowRoot.getElementById('qchat').setAttribute('selected', 'selected') + if (this.shadowRoot.getElementById('qminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qbminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qbminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qiminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qiminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qwallet').hasAttribute('selected')) { + this.shadowRoot.getElementById('qwallet').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qtrade').hasAttribute('selected')) { + this.shadowRoot.getElementById('qtrade').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qbot').hasAttribute('selected')) { + this.shadowRoot.getElementById('qbot').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qrewardshare').hasAttribute('selected')) { + this.shadowRoot.getElementById('qrewardshare').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnamereg').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnamereg').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnamemarket').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnamemarket').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qweb').hasAttribute('selected')) { + this.shadowRoot.getElementById('qweb').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qapp').hasAttribute('selected')) { + this.shadowRoot.getElementById('qapp').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qgroupmange').hasAttribute('selected')) { + this.shadowRoot.getElementById('qgroupmange').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qpuzzles').hasAttribute('selected')) { + this.shadowRoot.getElementById('qpuzzles').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qdata').hasAttribute('selected')) { + this.shadowRoot.getElementById('qdata').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnode').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnode').removeAttribute('selected') + } + } else if (sideurl === 'name-registration') { + this.shadowRoot.getElementById('qnamereg').setAttribute('selected', 'selected') + if (this.shadowRoot.getElementById('qminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qbminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qbminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qiminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qiminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qwallet').hasAttribute('selected')) { + this.shadowRoot.getElementById('qwallet').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qtrade').hasAttribute('selected')) { + this.shadowRoot.getElementById('qtrade').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qbot').hasAttribute('selected')) { + this.shadowRoot.getElementById('qbot').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qrewardshare').hasAttribute('selected')) { + this.shadowRoot.getElementById('qrewardshare').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qchat').hasAttribute('selected')) { + this.shadowRoot.getElementById('qchat').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnamemarket').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnamemarket').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qweb').hasAttribute('selected')) { + this.shadowRoot.getElementById('qweb').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qapp').hasAttribute('selected')) { + this.shadowRoot.getElementById('qapp').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qgroupmange').hasAttribute('selected')) { + this.shadowRoot.getElementById('qgroupmange').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qpuzzles').hasAttribute('selected')) { + this.shadowRoot.getElementById('qpuzzles').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qdata').hasAttribute('selected')) { + this.shadowRoot.getElementById('qdata').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnode').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnode').removeAttribute('selected') + } + } else if (sideurl === 'names-market') { + this.shadowRoot.getElementById('qnamemarket').setAttribute('selected', 'selected') + if (this.shadowRoot.getElementById('qminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qbminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qbminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qiminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qiminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qwallet').hasAttribute('selected')) { + this.shadowRoot.getElementById('qwallet').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qtrade').hasAttribute('selected')) { + this.shadowRoot.getElementById('qtrade').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qbot').hasAttribute('selected')) { + this.shadowRoot.getElementById('qbot').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qrewardshare').hasAttribute('selected')) { + this.shadowRoot.getElementById('qrewardshare').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qchat').hasAttribute('selected')) { + this.shadowRoot.getElementById('qchat').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnamereg').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnamereg').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qweb').hasAttribute('selected')) { + this.shadowRoot.getElementById('qweb').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qapp').hasAttribute('selected')) { + this.shadowRoot.getElementById('qapp').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qgroupmange').hasAttribute('selected')) { + this.shadowRoot.getElementById('qgroupmange').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qpuzzles').hasAttribute('selected')) { + this.shadowRoot.getElementById('qpuzzles').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qdata').hasAttribute('selected')) { + this.shadowRoot.getElementById('qdata').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnode').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnode').removeAttribute('selected') + } + } else if (sideurl === 'websites') { + this.shadowRoot.getElementById('qweb').setAttribute('selected', 'selected') + if (this.shadowRoot.getElementById('qminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qbminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qbminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qiminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qiminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qwallet').hasAttribute('selected')) { + this.shadowRoot.getElementById('qwallet').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qtrade').hasAttribute('selected')) { + this.shadowRoot.getElementById('qtrade').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qbot').hasAttribute('selected')) { + this.shadowRoot.getElementById('qbot').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qrewardshare').hasAttribute('selected')) { + this.shadowRoot.getElementById('qrewardshare').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qchat').hasAttribute('selected')) { + this.shadowRoot.getElementById('qchat').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnamereg').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnamereg').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnamemarket').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnamemarket').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qapp').hasAttribute('selected')) { + this.shadowRoot.getElementById('qapp').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qgroupmange').hasAttribute('selected')) { + this.shadowRoot.getElementById('qgroupmange').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qpuzzles').hasAttribute('selected')) { + this.shadowRoot.getElementById('qpuzzles').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qdata').hasAttribute('selected')) { + this.shadowRoot.getElementById('qdata').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnode').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnode').removeAttribute('selected') + } + } else if (sideurl === 'qapps') { + this.shadowRoot.getElementById('qapp').setAttribute('selected', 'selected') + if (this.shadowRoot.getElementById('qminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qbminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qbminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qiminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qiminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qwallet').hasAttribute('selected')) { + this.shadowRoot.getElementById('qwallet').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qtrade').hasAttribute('selected')) { + this.shadowRoot.getElementById('qtrade').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qbot').hasAttribute('selected')) { + this.shadowRoot.getElementById('qbot').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qrewardshare').hasAttribute('selected')) { + this.shadowRoot.getElementById('qrewardshare').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qchat').hasAttribute('selected')) { + this.shadowRoot.getElementById('qchat').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnamereg').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnamereg').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnamemarket').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnamemarket').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qweb').hasAttribute('selected')) { + this.shadowRoot.getElementById('qweb').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qgroupmange').hasAttribute('selected')) { + this.shadowRoot.getElementById('qgroupmange').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qpuzzles').hasAttribute('selected')) { + this.shadowRoot.getElementById('qpuzzles').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qdata').hasAttribute('selected')) { + this.shadowRoot.getElementById('qdata').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnode').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnode').removeAttribute('selected') + } + } else if (sideurl === 'group-management') { + this.shadowRoot.getElementById('qgroupmange').setAttribute('selected', 'selected') + if (this.shadowRoot.getElementById('qminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qbminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qbminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qiminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qiminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qwallet').hasAttribute('selected')) { + this.shadowRoot.getElementById('qwallet').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qtrade').hasAttribute('selected')) { + this.shadowRoot.getElementById('qtrade').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qbot').hasAttribute('selected')) { + this.shadowRoot.getElementById('qbot').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qrewardshare').hasAttribute('selected')) { + this.shadowRoot.getElementById('qrewardshare').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qchat').hasAttribute('selected')) { + this.shadowRoot.getElementById('qchat').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnamereg').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnamereg').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnamemarket').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnamemarket').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qweb').hasAttribute('selected')) { + this.shadowRoot.getElementById('qweb').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qapp').hasAttribute('selected')) { + this.shadowRoot.getElementById('qapp').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qpuzzles').hasAttribute('selected')) { + this.shadowRoot.getElementById('qpuzzles').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qdata').hasAttribute('selected')) { + this.shadowRoot.getElementById('qdata').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnode').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnode').removeAttribute('selected') + } + } else if (sideurl === 'puzzles') { + this.shadowRoot.getElementById('qpuzzles').setAttribute('selected', 'selected') + if (this.shadowRoot.getElementById('qminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qbminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qbminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qiminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qiminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qwallet').hasAttribute('selected')) { + this.shadowRoot.getElementById('qwallet').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qtrade').hasAttribute('selected')) { + this.shadowRoot.getElementById('qtrade').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qbot').hasAttribute('selected')) { + this.shadowRoot.getElementById('qbot').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qrewardshare').hasAttribute('selected')) { + this.shadowRoot.getElementById('qrewardshare').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qchat').hasAttribute('selected')) { + this.shadowRoot.getElementById('qchat').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnamereg').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnamereg').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnamemarket').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnamemarket').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qweb').hasAttribute('selected')) { + this.shadowRoot.getElementById('qweb').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qapp').hasAttribute('selected')) { + this.shadowRoot.getElementById('qapp').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qgroupmange').hasAttribute('selected')) { + this.shadowRoot.getElementById('qgroupmange').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qdata').hasAttribute('selected')) { + this.shadowRoot.getElementById('qdata').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnode').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnode').removeAttribute('selected') + } + } else if (sideurl === 'data-management') { + this.shadowRoot.getElementById('qdata').setAttribute('selected', 'selected') + if (this.shadowRoot.getElementById('qminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qbminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qbminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qiminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qiminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qwallet').hasAttribute('selected')) { + this.shadowRoot.getElementById('qwallet').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qtrade').hasAttribute('selected')) { + this.shadowRoot.getElementById('qtrade').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qbot').hasAttribute('selected')) { + this.shadowRoot.getElementById('qbot').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qrewardshare').hasAttribute('selected')) { + this.shadowRoot.getElementById('qrewardshare').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qchat').hasAttribute('selected')) { + this.shadowRoot.getElementById('qchat').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnamereg').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnamereg').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnamemarket').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnamemarket').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qweb').hasAttribute('selected')) { + this.shadowRoot.getElementById('qweb').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qapp').hasAttribute('selected')) { + this.shadowRoot.getElementById('qapp').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qgroupmange').hasAttribute('selected')) { + this.shadowRoot.getElementById('qgroupmange').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qpuzzles').hasAttribute('selected')) { + this.shadowRoot.getElementById('qpuzzles').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnode').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnode').removeAttribute('selected') + } + } else if (sideurl === 'node-management') { + this.shadowRoot.getElementById('qnode').setAttribute('selected', 'selected') + if (this.shadowRoot.getElementById('qminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qbminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qbminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qiminter').hasAttribute('selected')) { + this.shadowRoot.getElementById('qiminter').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qwallet').hasAttribute('selected')) { + this.shadowRoot.getElementById('qwallet').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qtrade').hasAttribute('selected')) { + this.shadowRoot.getElementById('qtrade').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qbot').hasAttribute('selected')) { + this.shadowRoot.getElementById('qbot').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qrewardshare').hasAttribute('selected')) { + this.shadowRoot.getElementById('qrewardshare').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qchat').hasAttribute('selected')) { + this.shadowRoot.getElementById('qchat').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnamereg').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnamereg').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qnamemarket').hasAttribute('selected')) { + this.shadowRoot.getElementById('qnamemarket').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qweb').hasAttribute('selected')) { + this.shadowRoot.getElementById('qweb').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qapp').hasAttribute('selected')) { + this.shadowRoot.getElementById('qapp').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qgroupmange').hasAttribute('selected')) { + this.shadowRoot.getElementById('qgroupmange').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qpuzzles').hasAttribute('selected')) { + this.shadowRoot.getElementById('qpuzzles').removeAttribute('selected') + } else if (this.shadowRoot.getElementById('qdata').hasAttribute('selected')) { + this.shadowRoot.getElementById('qdata').removeAttribute('selected') + } + } + } - openLogout() { - const logoutDialog = document.getElementById('main-app').shadowRoot.querySelector('app-view').shadowRoot.querySelector('logout-view') - logoutDialog.openLogout() - } + openSettings() { + const settingsDialog = document.getElementById('main-app').shadowRoot.querySelector('app-view').shadowRoot.querySelector('user-settings') + settingsDialog.openSettings() + } - getApiKey() { - const apiNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node] + openLogout() { + const logoutDialog = document.getElementById('main-app').shadowRoot.querySelector('app-view').shadowRoot.querySelector('logout-view') + logoutDialog.openLogout() + } + + getApiKey() { + const apiNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node] return apiNode.apiKey - } + } - isEmptyArray(arr) { - if (!arr) { - return true - } - return arr.length === 0 - } + isEmptyArray(arr) { + if (!arr) { + return true + } - round(number) { + return arr.length === 0 + } + + round(number) { return (Math.round(parseFloat(number) * 1e8) / 1e8).toFixed(8) - } + } } window.customElements.define('app-view', AppView) diff --git a/core/src/components/base.js b/core/src/components/base.js index e5382038..1928cdf0 100644 --- a/core/src/components/base.js +++ b/core/src/components/base.js @@ -1,26 +1,11 @@ -import {css, html, LitElement} from 'lit' -import {connect} from 'pwa-helpers' -import {store} from '../store.js' +import { html, LitElement } from 'lit' +import { connect } from 'pwa-helpers' +import { store } from '../store' class MyElement extends connect(store)(LitElement) { - static get properties () { - return { - } - } - - static get styles () { - return css`` - } - - render () { - return html` - - ` - } - - stateChanged (state) { - } + render () { + return html`` + } } -window.customElements.define('my-element', MyElement) +window.customElements.define('my-element', MyElement) \ No newline at end of file diff --git a/core/src/components/beginner-tour/sync-indicator.js b/core/src/components/beginner-tour/sync-indicator.js index 520344b1..6071f535 100644 --- a/core/src/components/beginner-tour/sync-indicator.js +++ b/core/src/components/beginner-tour/sync-indicator.js @@ -1,11 +1,13 @@ -import {css, html, LitElement} from 'lit' -import {store} from '../../store' -import {connect} from 'pwa-helpers' -import {translate} from '../../../translate' -import {parentEpml} from '../show-plugin' - +import { html, LitElement } from 'lit' +import { connect } from 'pwa-helpers' +import { store } from '../../store' +import { parentEpml } from '../show-plugin' +import { syncIndicator2Styles } from '../../styles/core-css' import '@material/mwc-icon' +// Multi language support +import {translate} from '../../../translate' + class SyncIndicator extends connect(store)(LitElement) { static get properties() { return { @@ -18,6 +20,10 @@ class SyncIndicator extends connect(store)(LitElement) { } } + static get styles() { + return [syncIndicator2Styles] + } + constructor() { super() this.blocksBehind = 0 @@ -32,64 +38,6 @@ class SyncIndicator extends connect(store)(LitElement) { this.hasOpened = false } - static get styles() { - return css` - * { - --mdc-theme-text-primary-on-background: var(--black); - box-sizing: border-box; - } - - :host { - box-sizing: border-box; - position: fixed; - bottom: 50px; - right: 25px; - z-index: 50000; - } - - .parent { - width: 360px; - padding: 10px; - border-radius: 8px; - border: 1px solid var(--black); - display: flex; - align-items: center; - gap: 10px; - user-select: none; - background: var(--white); - } - - .row { - display: flex; - gap: 10px; - width: 100%; - } - - .column { - display: flex; - flex-direction: column; - gap: 10px; - width: 100%; - } - - .bootstrap-button { - font-family: Roboto, sans-serif; - font-size: 16px; - color: var(--mdc-theme-primary); - background-color: transparent; - padding: 8px 10px; - border-radius: 5px; - border: none; - transition: all 0.3s ease-in-out; - } - - .bootstrap-button:hover { - cursor: pointer; - background-color: #03a8f475; - } - ` - } - render() { return html` ${!this.hasCoreRunning ? html` @@ -225,7 +173,7 @@ class SyncIndicator extends connect(store)(LitElement) { this.dispatchEvent( new CustomEvent('open-welcome-modal-sync', { bubbles: true, - composed: true, + composed: true }) ) } @@ -257,4 +205,4 @@ class SyncIndicator extends connect(store)(LitElement) { } } -customElements.define('sync-indicator', SyncIndicator) \ No newline at end of file +window.customElements.define('sync-indicator', SyncIndicator) \ No newline at end of file diff --git a/core/src/components/beginner-tour/tour-component.js b/core/src/components/beginner-tour/tour-component.js index 26b16276..7496a16d 100644 --- a/core/src/components/beginner-tour/tour-component.js +++ b/core/src/components/beginner-tour/tour-component.js @@ -1,16 +1,19 @@ -import {css, html, LitElement} from 'lit'; -import {driver} from 'driver.js'; -import 'driver.js/dist/driver.css'; -import '@material/mwc-icon'; -import '@polymer/paper-spinner/paper-spinner-lite.js'; -import '@vaadin/tooltip'; -import '@material/mwc-button'; -import {get, translate} from '../../../translate'; -import '@polymer/paper-dialog/paper-dialog.js'; -import {setNewTab} from '../../redux/app/app-actions.js'; -import {store} from '../../store.js'; -import {connect} from 'pwa-helpers'; -import './tour.css'; +import { html, LitElement } from 'lit' +import { connect } from 'pwa-helpers' +import { store } from '../../store' +import { setNewTab } from '../../redux/app/app-actions' +import { tourComponentStyles } from '../../styles/core-css' +import { driver } from 'driver.js' +import 'driver.js/dist/driver.css' +import './tour.css' +import '@material/mwc-button' +import '@material/mwc-icon' +import '@polymer/paper-dialog/paper-dialog.js' +import '@polymer/paper-spinner/paper-spinner-lite.js' +import '@vaadin/tooltip' + +// Multi language support +import { get, translate } from '../../../translate' class TourComponent extends connect(store)(LitElement) { static get properties() { @@ -18,242 +21,112 @@ class TourComponent extends connect(store)(LitElement) { getElements: { attribute: false }, dialogOpenedCongrats: { type: Boolean }, hasViewedTour: { type: Boolean }, - disableTour: {type: Boolean} - }; + disableTour: { type: Boolean }, + nodeUrl: { type: String }, + address: { type: String } + } + } + + static get styles() { + return [tourComponentStyles] } constructor() { - super(); - this.dialogOpenedCongrats = false; - this._controlOpenWelcomeModal = - this._controlOpenWelcomeModal.bind(this); - this.hasName = false; - this.nodeUrl = this.getNodeUrl(); - this.myNode = this.getMyNode(); + super() + this.dialogOpenedCongrats = false + this._controlOpenWelcomeModal = this._controlOpenWelcomeModal.bind(this) + this.hasName = false + this.nodeUrl = '' + this.address = '' this._disableTour = this._disableTour.bind(this) this.disableTour = false } - static get styles() { - return css` - * { - --mdc-theme-primary: rgb(3, 169, 244); - --mdc-theme-secondary: var(--mdc-theme-primary); - --mdc-theme-surface: var(--white); - --mdc-dialog-content-ink-color: var(--black); - box-sizing: border-box; - color: var(--black); - background: var(--white); - } - - :host { - box-sizing: border-box; - position: fixed; - bottom: 25px; - right: 25px; - z-index: 50000; - } - - .full-info-wrapper { - width: 100%; - min-width: 600px; - max-width: 600px; - text-align: center; - background: var(--white); - border: 1px solid var(--black); - border-radius: 15px; - padding: 25px; - box-shadow: 0px 10px 15px rgba(0, 0, 0, 0.1); - display: block !important; - } - - .buttons { - display: inline; - } - .accept-button { - font-family: Roboto, sans-serif; - letter-spacing: 0.3px; - font-weight: 300; - padding: 8px 5px; - border-radius: 3px; - text-align: center; - color: var(--black); - transition: all 0.3s ease-in-out; - display: flex; - align-items: center; - gap: 10px; - font-size: 18px; - justify-content: center; - outline: 1px solid var(--black); - } - - .accept-button:hover { - cursor: pointer; - background-color: #03a8f485; - } - - .close-button { - font-family: Roboto, sans-serif; - letter-spacing: 0.3px; - font-weight: 300; - padding: 8px 5px; - border-radius: 3px; - text-align: center; - color: #f44336; - transition: all 0.3s ease-in-out; - display: flex; - align-items: center; - gap: 10px; - font-size: 18px; - width:auto; - } - - .close-button:hover { - cursor: pointer; - background-color: #f4433663; - } - `; + render() { + return html` + + ${this.dialogOpenedCongrats && this.hasViewedTour ? html` + +

Congratulations!

+
+ ${translate("tour.tour13")} +
+
+ ${translate("tour.tour14")} +
+
+ ${translate("tour.tour15")} +
+
+
{ this.onClose() }}> + ${translate("general.close")} +
+
+
+ ` : ''} + ` } - _controlOpenWelcomeModal() { - this.isSynced = true - - const seenWelcomeSync = JSON.parse( - localStorage.getItem('welcome-sync') || 'false' - ); - if (this.hasName) return; - if (seenWelcomeSync) return; - if(!this.hasViewedTour) return - this.dialogOpenedCongrats = true; - } - - openWelcomeModal() { - this.dispatchEvent( - new CustomEvent('send-tour-finished', { - bubbles: true, - composed: true, - }) - ); - const seenWelcomeSync = JSON.parse( - localStorage.getItem('welcome-sync') || 'false' - ); - if (this.hasName) return; - if (seenWelcomeSync) return; - if(!this.isSynced) return - this.dialogOpenedCongrats = true; - } - - _disableTour(){ - this.disableTour = true - driver.reset() - } - - connectedCallback() { - super.connectedCallback(); - window.addEventListener( - 'open-welcome-modal-sync', - this._controlOpenWelcomeModal - ); - window.addEventListener( - 'disable-tour', - this._disableTour - ); - } - - disconnectedCallback() { - window.removeEventListener( - 'open-welcome-modal-sync', - this._controlOpenWelcomeModal - ); - window.addEventListener( - 'disable-tour', - this._disableTour - ); - super.disconnectedCallback(); - } - - getNodeUrl() { - const myNode = - window.parent.reduxStore.getState().app.nodeConfig.knownNodes[ - window.parent.reduxStore.getState().app.nodeConfig.node - ] - - return myNode.protocol + '://' + myNode.domain + ':' + myNode.port - } - getMyNode() { - return window.parent.reduxStore.getState().app.nodeConfig.knownNodes[ - window.parent.reduxStore.getState().app.nodeConfig.node - ] - } - - async getName(recipient) { - try { - const endpoint = `${this.nodeUrl}/names/address/${recipient}`; - const res = await fetch(endpoint); - const getNames = await res.json(); - - if (Array.isArray(getNames) && getNames.length > 0) { - return getNames[0].name; - } else { - return ''; - } - } catch (error) { - return ''; - } - } async firstUpdated() { + this.getNodeUrl() this.address = store.getState().app.selectedAddress.address - const hasViewedTour = JSON.parse( - localStorage.getItem(`hasViewedTour-${this.address}`) || 'false' - ); - const name = await this.getName(this.address); + + const hasViewedTour = JSON.parse(localStorage.getItem(`hasViewedTour-${this.address}`) || 'false') + const name = await this.getName(this.address) + if (name) { - this.hasName = true; + this.hasName = true } - this.hasViewedTour = hasViewedTour; + + this.hasViewedTour = hasViewedTour + if (!hasViewedTour) { try { if (name) { - this.hasViewedTour = true; - this.hasName = true; + this.hasViewedTour = true + this.hasName = true localStorage.setItem(`hasViewedTour-${this.address}`, JSON.stringify(true)) } } catch (error) { - console.log({ error }); + console.log({ error }) } } + await new Promise((res) => { setTimeout(() => { - res(); - }, 1000); - }); + res() + }, 1000) + }) + if (!this.hasViewedTour && this.disableTour !== true) { - const elements = this.getElements(); - let steps = [ - { - popover: { - title: get("tour.tour6"), - description: ` -
- -
-
-

${get("tour.tour7")}

-
-
-

${get("tour.tour8")}

-
-
-

${get("tour.tour9")}

-
- `, - // ... other options - }, - }, - ]; - const step2 = elements['core-sync-status-id']; - const step3 = elements['tab']; - const step4 = elements['checklist']; + const elements = this.getElements() + + let steps = [{ + popover: { + title: get("tour.tour6"), + description: ` +
+ +
+
+
+

${get("tour.tour7")}

+
+
+
+

${get("tour.tour8")}

+
+
+
+

${get("tour.tour9")}

+
+ ` + } + }] + + const step2 = elements['core-sync-status-id'] + const step3 = elements['tab'] + const step4 = elements['checklist'] if (step2) { steps.push({ @@ -261,58 +134,54 @@ class TourComponent extends connect(store)(LitElement) { popover: { title: get("tour.tour5"), description: ` -
-

${get("tour.tour1")}

-
-
- -

${get("tour.tour2")}

-
-
- -

${get("tour.tour3")}

-
-
- -

${get("tour.tour4")}

-
+
+

${get("tour.tour1")}

+
+
+ +

${get("tour.tour2")}

+
+
+ +

${get("tour.tour3")}

+
+
+ +

${get("tour.tour4")}

+
- `, - }, - }); + ` + } + }) } + if (step3) { steps.push({ element: step3, popover: { title: 'Tab View', description: ` -
-

${get("tour.tour10")} -

-
-
- -

You can also bookmark other Q-Apps and Plugins by clicking on the ${get( - 'tabmenu.tm19' - )} button

-
- `, - }, - }); - } - if (step4) { - steps.push( - { - element: step4, - popover: { - title: get("tour.tour11"), - description: get("tour.tour12"), - }, +
+

${get("tour.tour10")}

+
+
+ +

+ You can also bookmark other Q-Apps and Plugins by clicking on the ${get('tabmenu.tm19')} button +

+
+ ` } - );this.hasViewedTour + }) } - let currentStepIndex = 0; + + if (step4) { + steps.push({ element: step4, popover: { title: get("tour.tour11"), description: get("tour.tour12")}}) + this.hasViewedTour + } + + let currentStepIndex = 0 + const driverObj = driver({ popoverClass: 'driverjs-theme', showProgress: true, @@ -321,25 +190,93 @@ class TourComponent extends connect(store)(LitElement) { allowClose: false, onDestroyed: () => { localStorage.setItem(`hasViewedTour-${this.address}`, JSON.stringify(true)) - this.hasViewedTour = true; - this.openWelcomeModal(); + this.hasViewedTour = true + this.openWelcomeModal() } - }); + }) - driverObj.drive(); + driverObj.drive() } else { this.dispatchEvent( new CustomEvent('send-tour-finished', { bubbles: true, - composed: true, + composed: true }) - ); + ) + } + } + + _controlOpenWelcomeModal() { + this.isSynced = true + + const seenWelcomeSync = JSON.parse(localStorage.getItem('welcome-sync') || 'false') + + if (this.hasName) return + if (seenWelcomeSync) return + if (!this.hasViewedTour) return + + this.dialogOpenedCongrats = true + } + + openWelcomeModal() { + this.dispatchEvent( + new CustomEvent('send-tour-finished', { + bubbles: true, + composed: true + }) + ) + + const seenWelcomeSync = JSON.parse(localStorage.getItem('welcome-sync') || 'false') + + if (this.hasName) return + if (seenWelcomeSync) return + if (!this.isSynced) return + + this.dialogOpenedCongrats = true + } + + _disableTour() { + this.disableTour = true + driver.reset() + } + + connectedCallback() { + super.connectedCallback() + window.addEventListener('open-welcome-modal-sync', this._controlOpenWelcomeModal) + window.addEventListener('disable-tour', this._disableTour) + } + + disconnectedCallback() { + window.removeEventListener('open-welcome-modal-sync', this._controlOpenWelcomeModal) + window.addEventListener('disable-tour', this._disableTour) + super.disconnectedCallback() + } + + getNodeUrl() { + const myNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node] + const myNodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port + this.nodeUrl = myNodeUrl + } + + async getName(recipient) { + try { + const endpoint = `${this.nodeUrl}/names/address/${recipient}` + const res = await fetch(endpoint) + const getNames = await res.json() + + if (Array.isArray(getNames) && getNames.length > 0) { + return getNames[0].name + } else { + return '' + } + } catch (error) { + return '' } } visitQtube() { - this.onClose(); - const query = `?service=APP&name=Q-Tube`; + this.onClose() + const query = `?service=APP&name=Q-Tube` store.dispatch( setNewTab({ url: `qdn/browser/index.html${query}`, @@ -350,59 +287,16 @@ class TourComponent extends connect(store)(LitElement) { page: `qdn/browser/index.html${query}`, title: 'Q-Tube', menus: [], - parent: false, - }, + parent: false + } }) - ); + ) } onClose() { localStorage.setItem(`welcome-sync-${this.address}`, JSON.stringify(true)) - this.dialogOpenedCongrats = false; - } - - render() { - return html` - - ${this.dialogOpenedCongrats && this.hasViewedTour - ? html` - -

Congratulations!

-
- ${translate("tour.tour13")} -
-
- ${translate("tour.tour14")} -
- -
- ${translate("tour.tour15")} -
-
-
{ - this.onClose() - - }} - > - ${translate("general.close")} -
-
-
- ` - : ''} - `; + this.dialogOpenedCongrats = false } } -customElements.define('tour-component', TourComponent); + +window.customElements.define('tour-component', TourComponent) \ No newline at end of file diff --git a/core/src/components/check-for-update.js b/core/src/components/check-for-update.js index 26a9a70e..4b9fcacb 100644 --- a/core/src/components/check-for-update.js +++ b/core/src/components/check-for-update.js @@ -1,10 +1,11 @@ -import {css, html, LitElement} from 'lit' -import {translate} from '../../translate' +import { html, LitElement } from 'lit' import isElectron from 'is-electron' - import '@polymer/paper-icon-button/paper-icon-button.js' import '@polymer/iron-icons/iron-icons.js' +// Multi language support +import { translate } from '../../translate' + class CheckForUpdate extends LitElement { static get properties() { return { @@ -17,11 +18,6 @@ class CheckForUpdate extends LitElement { this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light' } - static styles = [ - css` - ` - ] - render() { return html` ${this.renderUpdateButton()} @@ -29,6 +25,7 @@ class CheckForUpdate extends LitElement { } firstUpdated() { + // ... } renderUpdateButton() { @@ -48,4 +45,4 @@ class CheckForUpdate extends LitElement { } } -window.customElements.define('check-for-update', CheckForUpdate) +window.customElements.define('check-for-update', CheckForUpdate) \ No newline at end of file diff --git a/core/src/components/computePowWorker.js b/core/src/components/computePowWorker.js index b89b9d84..37736224 100644 --- a/core/src/components/computePowWorker.js +++ b/core/src/components/computePowWorker.js @@ -1,82 +1,58 @@ -import {Sha256} from 'asmcrypto.js' +import { Sha256 } from 'asmcrypto.js' - -function sbrk(size, heap){ - let brk = 512 * 1024 // stack top - let old = brk - brk += size - - if (brk > heap.length) - throw new Error('heap exhausted') - - return old +function sbrk(size, heap) { + let brk = 512 * 1024 // stack top + let old = brk + brk += size + if (brk > heap.length) throw new Error('heap exhausted') + return old } self.addEventListener('message', async e => { - const response = await computePow(e.data.chatBytes, e.data.path, e.data.difficulty) - postMessage(response) + const response = await computePow(e.data.chatBytes, e.data.path, e.data.difficulty) + postMessage(response) }) - const memory = new WebAssembly.Memory({ initial: 256, maximum: 256 }) const heap = new Uint8Array(memory.buffer) - - const computePow = async (chatBytes, path, difficulty) => { - - let response = null - - await new Promise((resolve, reject)=> { - - const _chatBytesArray = Object.keys(chatBytes).map(function (key) { return chatBytes[key]; }); - const chatBytesArray = new Uint8Array(_chatBytesArray); - const chatBytesHash = new Sha256().process(chatBytesArray).finish().result; - const hashPtr = sbrk(32, heap); - const hashAry = new Uint8Array(memory.buffer, hashPtr, 32); - hashAry.set(chatBytesHash); - - - const workBufferLength = 8 * 1024 * 1024; - const workBufferPtr = sbrk(workBufferLength, heap); - - - - const importObject = { - env: { - memory: memory - }, - }; - - function loadWebAssembly(filename, imports) { - // Fetch the file and compile it - return fetch(filename) - .then(response => response.arrayBuffer()) - .then(buffer => WebAssembly.compile(buffer)) - .then(module => { - - // Create the instance. - return new WebAssembly.Instance(module, importObject); - }); -} - - -loadWebAssembly(path) - .then(wasmModule => { - response = { - nonce : wasmModule.exports.compute2(hashPtr, workBufferPtr, workBufferLength, difficulty), - chatBytesArray - } - - resolve() - - }); - - - }) - - return response -} + let response = null + await new Promise((resolve, reject) => { + const _chatBytesArray = Object.keys(chatBytes).map(function (key) { return chatBytes[key]; }) + const chatBytesArray = new Uint8Array(_chatBytesArray) + const chatBytesHash = new Sha256().process(chatBytesArray).finish().result + const hashPtr = sbrk(32, heap) + const hashAry = new Uint8Array(memory.buffer, hashPtr, 32) + hashAry.set(chatBytesHash) + const workBufferLength = 8 * 1024 * 1024 + const workBufferPtr = sbrk(workBufferLength, heap) + const importObject = { + env: { + memory: memory + } + } + function loadWebAssembly(filename, imports) { + // Fetch the file and compile it + return fetch(filename) + .then(response => response.arrayBuffer()) + .then(buffer => WebAssembly.compile(buffer)) + .then(module => { + // Create the instance. + return new WebAssembly.Instance(module, importObject) + }) + } + loadWebAssembly(path) + .then(wasmModule => { + response = { + nonce: wasmModule.exports.compute2(hashPtr, workBufferPtr, workBufferLength, difficulty), + chatBytesArray + } + resolve() + }) + }) + return response +} \ No newline at end of file diff --git a/core/src/components/computePowWorkerFile.js b/core/src/components/computePowWorkerFile.js index d9f5f662..a13e6ec7 100644 --- a/core/src/components/computePowWorkerFile.js +++ b/core/src/components/computePowWorkerFile.js @@ -1,92 +1,68 @@ import { Sha256 } from 'asmcrypto.js' - - -function sbrk(size, heap){ - let brk = 512 * 1024 // stack top - let old = brk - brk += size - - if (brk > heap.length) - throw new Error('heap exhausted') - - return old +function sbrk(size, heap) { + let brk = 512 * 1024 // stack top + let old = brk + brk += size + if (brk > heap.length) throw new Error('heap exhausted') + return old } - - - self.addEventListener('message', async e => { - const response = await computePow(e.data.convertedBytes, e.data.path) - postMessage(response) - -}) + const response = await computePow(e.data.convertedBytes, e.data.path) + postMessage(response) +}) const memory = new WebAssembly.Memory({ initial: 256, maximum: 256 }) const heap = new Uint8Array(memory.buffer) - - const computePow = async (convertedBytes, path) => { + let response = null + await new Promise((resolve, reject) => { + const _convertedBytesArray = Object.keys(convertedBytes).map( + function (key) { + return convertedBytes[key] + } + ) + const convertedBytesArray = new Uint8Array(_convertedBytesArray) + const convertedBytesHash = new Sha256() + .process(convertedBytesArray) + .finish().result + const hashPtr = sbrk(32, heap) + const hashAry = new Uint8Array( + memory.buffer, + hashPtr, + 32 + ) + hashAry.set(convertedBytesHash) + const difficulty = 14 + const workBufferLength = 8 * 1024 * 1024 + const workBufferPtr = sbrk( + workBufferLength, + heap + ) + const importObject = { + env: { + memory: memory + } + } + function loadWebAssembly(filename, imports) { + return fetch(filename) + .then(response => response.arrayBuffer()) + .then(buffer => WebAssembly.compile(buffer)) + .then(module => { + return new WebAssembly.Instance(module, importObject) + }) + } + loadWebAssembly(path) + .then(wasmModule => { + response = { + nonce: wasmModule.exports.compute2(hashPtr, workBufferPtr, workBufferLength, difficulty), - - let response = null - - await new Promise((resolve, reject)=> { - - const _convertedBytesArray = Object.keys(convertedBytes).map( - function (key) { - return convertedBytes[key] - } -) -const convertedBytesArray = new Uint8Array(_convertedBytesArray) -const convertedBytesHash = new Sha256() - .process(convertedBytesArray) - .finish().result -const hashPtr = sbrk(32, heap) -const hashAry = new Uint8Array( - memory.buffer, - hashPtr, - 32 -) - -hashAry.set(convertedBytesHash) -const difficulty = 14 -const workBufferLength = 8 * 1024 * 1024 -const workBufferPtr = sbrk( - workBufferLength, - heap -) - - const importObject = { - env: { - memory: memory - }, - }; - - function loadWebAssembly(filename, imports) { - return fetch(filename) - .then(response => response.arrayBuffer()) - .then(buffer => WebAssembly.compile(buffer)) - .then(module => { - return new WebAssembly.Instance(module, importObject); - }); -} - - -loadWebAssembly(path) - .then(wasmModule => { - response = { - nonce : wasmModule.exports.compute2(hashPtr, workBufferPtr, workBufferLength, difficulty), - - } - resolve() - - }); - - - }) - - return response + } + resolve() + }) + }) + return response } \ No newline at end of file diff --git a/core/src/components/controllers/coin-balances-controller.js b/core/src/components/controllers/coin-balances-controller.js index 7bcdabad..b5b8c483 100644 --- a/core/src/components/controllers/coin-balances-controller.js +++ b/core/src/components/controllers/coin-balances-controller.js @@ -1,320 +1,303 @@ -import {html, LitElement} from 'lit'; -import '@material/mwc-icon'; -import {store} from '../../store'; -import {connect} from 'pwa-helpers'; -import '@vaadin/tooltip'; -import {parentEpml} from '../show-plugin'; -import {setCoinBalances} from '../../redux/app/app-actions'; +import { html, LitElement } from 'lit' +import { connect } from 'pwa-helpers' +import { store } from '../../store' +import { parentEpml } from '../show-plugin' +import { setCoinBalances } from '../../redux/app/app-actions' class CoinBalancesController extends connect(store)(LitElement) { static get properties() { return { - coinList: { type: Object }, - }; + coinList: { type: Object } + } } constructor() { super(); this.coinList = {} - this.nodeUrl = this.getNodeUrl(); - this.myNode = this.getMyNode(); - this.fetchBalance = this.fetchBalance.bind(this) - this._updateCoinList = this._updateCoinList.bind(this) - this.stop = false + this.nodeUrl = this.getNodeUrl() + this.myNode = this.getMyNode() + this.fetchBalance = this.fetchBalance.bind(this) + this._updateCoinList = this._updateCoinList.bind(this) + this.stop = false } - getNodeUrl() { - const myNode = - store.getState().app.nodeConfig.knownNodes[ - store.getState().app.nodeConfig.node - ] + render() { + return html`` + } + getNodeUrl() { + const myNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node] return myNode.protocol + '://' + myNode.domain + ':' + myNode.port } + getMyNode() { - return store.getState().app.nodeConfig.knownNodes[ - store.getState().app.nodeConfig.node - ] + return store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node] } + async updateQortWalletBalance() { + let qortAddress = store.getState().app.selectedAddress.address - async updateArrrWalletBalance() { - let _url = `/crosschain/arrr/walletbalance?apiKey=${this.myNode.apiKey}` - let _body = store.getState().app.selectedAddress.arrrWallet.seed58 - - await parentEpml.request('apiCall', { - url: _url, - method: 'POST', - body: _body, - }).then((res) => { - if (isNaN(Number(res))) { - //... - } else { - this.arrrWalletBalance = (Number(res) / 1e8).toFixed(8) - store.dispatch( - setCoinBalances({ - type: 'arrr', - fullValue: Number(res) - }) - ); - } - }).catch(()=> { - console.log('error') - }) - } - async updateQortWalletBalance() { - let qortAddress = store.getState().app.selectedAddress.address - - await parentEpml.request('apiCall', { - url: `/addresses/balance/${qortAddress}?apiKey=${this.myNode.apiKey}`, - }).then((res) => { - this.qortWalletBalance = res - store.dispatch( - setCoinBalances({ - type: 'qort', - fullValue: Number(res) - }) - ); - }).catch(()=> { - console.log('error') - }) - } - - async updateRvnWalletBalance() { - let _url = `/crosschain/rvn/walletbalance?apiKey=${this.myNode.apiKey}` - let _body = store.getState().app.selectedAddress.rvnWallet.derivedMasterPublicKey - - await parentEpml.request('apiCall', { - url: _url, - method: 'POST', - body: _body, - }).then((res) => { - if (isNaN(Number(res))) { - //... - } else { - this.rvnWalletBalance = (Number(res) / 1e8).toFixed(8) - store.dispatch( - setCoinBalances({ - type: 'rvn', - fullValue: Number(res) - }) - ); - } - }).catch(()=> { - console.log('error') - }) - } - - async updateDgbWalletBalance() { - let _url = `/crosschain/dgb/walletbalance?apiKey=${this.myNode.apiKey}` - let _body = store.getState().app.selectedAddress.dgbWallet.derivedMasterPublicKey - - await parentEpml.request('apiCall', { - url: _url, - method: 'POST', - body: _body, - }).then((res) => { - if (isNaN(Number(res))) { - //... - } else { - this.dgbWalletBalance = (Number(res) / 1e8).toFixed(8) - store.dispatch( - setCoinBalances({ - type: 'dgb', - fullValue: Number(res) - }) - ); - } - }).catch(()=> { - console.log('error') - }) - } - - async updateDogeWalletBalance() { - let _url = `/crosschain/doge/walletbalance?apiKey=${this.myNode.apiKey}` - let _body = store.getState().app.selectedAddress.dogeWallet.derivedMasterPublicKey - - await parentEpml.request('apiCall', { - url: _url, - method: 'POST', - body: _body, - }).then((res) => { - if (isNaN(Number(res))) { - //... - } else { - this.dogeWalletBalance = (Number(res) / 1e8).toFixed(8) - store.dispatch( - setCoinBalances({ - type: 'doge', - fullValue: Number(res) - }) - ); - } - }).catch(()=> { - console.log('error') - }) - } - - async updateBtcWalletBalance() { - let _url = `/crosschain/btc/walletbalance?apiKey=${this.myNode.apiKey}` - let _body = store.getState().app.selectedAddress.btcWallet.derivedMasterPublicKey - - await parentEpml.request('apiCall', { - url: _url, - method: 'POST', - body: _body, - }).then((res) => { - if (isNaN(Number(res))) { - //... - } else { - this.btcWalletBalance = (Number(res) / 1e8).toFixed(8) - store.dispatch( - setCoinBalances({ - type: 'btc', - fullValue: Number(res) - }) - ); - } - }).catch(()=> { - console.log('error') - }) - } - - async updateLtcWalletBalance() { - let _url = `/crosschain/ltc/walletbalance?apiKey=${this.myNode.apiKey}` - let _body = store.getState().app.selectedAddress.ltcWallet.derivedMasterPublicKey - - await parentEpml.request('apiCall', { - url: _url, - method: 'POST', - body: _body, - }).then((res) => { - if (isNaN(Number(res))) { - //... - } else { - this.ltcWalletBalance = (Number(res) / 1e8).toFixed(8) - store.dispatch( - setCoinBalances({ - type: 'ltc', - fullValue: Number(res) - }) - ); - - } - }).catch(()=> { - console.log('error') - }) - } - - _updateCoinList(event) { - const copyCoinList = {...this.coinList} - const coin = event.detail - if(!copyCoinList[coin]){ - try { - if(coin === 'ltc'){ - this.updateLtcWalletBalance() - } else if(coin === 'qort'){ - this.updateQortWalletBalance() - } else if(coin === 'doge'){ - this.updateDogeWalletBalance() - } else if(coin === 'btc'){ - this.updateBtcWalletBalance() - } else if(coin === 'dgb'){ - this.updateDgbWalletBalance() - } else if(coin === 'rvn'){ - this.updateRvnWalletBalance() - }else if(coin === 'arrr'){ - this.updateArrrWalletBalance() - } - } catch (error) { - - } - } - copyCoinList[coin] = Date.now() + 120000; - this.coinList = copyCoinList - - this.requestUpdate() + await parentEpml.request('apiCall', { + url: `/addresses/balance/${qortAddress}?apiKey=${this.myNode.apiKey}`, + }).then((res) => { + this.qortWalletBalance = res + store.dispatch( + setCoinBalances({ + type: 'qort', + fullValue: Number(res) + }) + ) + }).catch(() => { + console.log('error') + }) } + async updateBtcWalletBalance() { + let _url = `/crosschain/btc/walletbalance?apiKey=${this.myNode.apiKey}` + let _body = store.getState().app.selectedAddress.btcWallet.derivedMasterPublicKey - async fetchCoins(arrayOfCoins){ - const getCoinBalances = (arrayOfCoins || []).map( - async (coin) => { - if(coin === 'ltc'){ - await this.updateLtcWalletBalance() - } else if(coin === 'qort'){ - await this.updateQortWalletBalance() - } else if(coin === 'doge'){ - await this.updateDogeWalletBalance() - } else if(coin === 'btc'){ - await this.updateBtcWalletBalance() - } else if(coin === 'dgb'){ - await this.updateDgbWalletBalance() - } else if(coin === 'rvn'){ - await this.updateRvnWalletBalance() - }else if(coin === 'arrr'){ - await this.updateArrrWalletBalance() - } - }) + await parentEpml.request('apiCall', { + url: _url, + method: 'POST', + body: _body + }).then((res) => { + if (isNaN(Number(res))) { + //... + } else { + this.btcWalletBalance = (Number(res) / 1e8).toFixed(8) + store.dispatch( + setCoinBalances({ + type: 'btc', + fullValue: Number(res) + }) + ) + } + }).catch(() => { + console.log('error') + }) + } - await Promise.all(getCoinBalances); + async updateLtcWalletBalance() { + let _url = `/crosschain/ltc/walletbalance?apiKey=${this.myNode.apiKey}` + let _body = store.getState().app.selectedAddress.ltcWallet.derivedMasterPublicKey - } + await parentEpml.request('apiCall', { + url: _url, + method: 'POST', + body: _body + }).then((res) => { + if (isNaN(Number(res))) { + //... + } else { + this.ltcWalletBalance = (Number(res) / 1e8).toFixed(8) + store.dispatch( + setCoinBalances({ + type: 'ltc', + fullValue: Number(res) + }) + ) - async fetchBalance(){ - try { - let arrayOfCoins = [] - const copyObject = {...this.coinList} - const currentDate = Date.now() - const array = Object.keys(this.coinList) - for (const key of array) { - const item = this.coinList[key] + } + }).catch(() => { + console.log('error') + }) + } - if(item < currentDate){ - delete copyObject[key] - } else { - arrayOfCoins.push(key) - } - } - if(!this.stop){ - this.stop = true - await this.fetchCoins(arrayOfCoins) - this.stop = false - } - this.coinList = copyObject - } catch (error) { - this.stop = false - } - } + async updateDogeWalletBalance() { + let _url = `/crosschain/doge/walletbalance?apiKey=${this.myNode.apiKey}` + let _body = store.getState().app.selectedAddress.dogeWallet.derivedMasterPublicKey - connectedCallback() { - super.connectedCallback(); - this.intervalID = setInterval(this.fetchBalance, 45000); - window.addEventListener( - 'ping-coin-controller-with-coin', - this._updateCoinList - ); + await parentEpml.request('apiCall', { + url: _url, + method: 'POST', + body: _body + }).then((res) => { + if (isNaN(Number(res))) { + //... + } else { + this.dogeWalletBalance = (Number(res) / 1e8).toFixed(8) + store.dispatch( + setCoinBalances({ + type: 'doge', + fullValue: Number(res) + }) + ) + } + }).catch(() => { + console.log('error') + }) + } + + async updateDgbWalletBalance() { + let _url = `/crosschain/dgb/walletbalance?apiKey=${this.myNode.apiKey}` + let _body = store.getState().app.selectedAddress.dgbWallet.derivedMasterPublicKey + + await parentEpml.request('apiCall', { + url: _url, + method: 'POST', + body: _body + }).then((res) => { + if (isNaN(Number(res))) { + //... + } else { + this.dgbWalletBalance = (Number(res) / 1e8).toFixed(8) + store.dispatch( + setCoinBalances({ + type: 'dgb', + fullValue: Number(res) + }) + ) + } + }).catch(() => { + console.log('error') + }) + } + + async updateRvnWalletBalance() { + let _url = `/crosschain/rvn/walletbalance?apiKey=${this.myNode.apiKey}` + let _body = store.getState().app.selectedAddress.rvnWallet.derivedMasterPublicKey + + await parentEpml.request('apiCall', { + url: _url, + method: 'POST', + body: _body + }).then((res) => { + if (isNaN(Number(res))) { + //... + } else { + this.rvnWalletBalance = (Number(res) / 1e8).toFixed(8) + store.dispatch( + setCoinBalances({ + type: 'rvn', + fullValue: Number(res) + }) + ) + } + }).catch(() => { + console.log('error') + }) + } + + async updateArrrWalletBalance() { + let _url = `/crosschain/arrr/walletbalance?apiKey=${this.myNode.apiKey}` + let _body = store.getState().app.selectedAddress.arrrWallet.seed58 + + await parentEpml.request('apiCall', { + url: _url, + method: 'POST', + body: _body, + }).then((res) => { + if (isNaN(Number(res))) { + //... + } else { + this.arrrWalletBalance = (Number(res) / 1e8).toFixed(8) + store.dispatch( + setCoinBalances({ + type: 'arrr', + fullValue: Number(res) + }) + ) + } + }).catch(() => { + console.log('error') + }) + } + + _updateCoinList(event) { + const copyCoinList = { ...this.coinList } + const coin = event.detail + + if (!copyCoinList[coin]) { + try { + if (coin === 'qort') { + this.updateQortWalletBalance() + } else if (coin === 'btc') { + this.updateBtcWalletBalance() + } else if (coin === 'ltc') { + this.updateLtcWalletBalance() + } else if (coin === 'doge') { + this.updateDogeWalletBalance() + } else if (coin === 'dgb') { + this.updateDgbWalletBalance() + } else if (coin === 'rvn') { + this.updateRvnWalletBalance() + } else if (coin === 'arrr') { + this.updateArrrWalletBalance() + } + } catch (error) { } + } + + copyCoinList[coin] = Date.now() + 120000 + + this.coinList = copyCoinList + this.requestUpdate() + } + + async fetchCoins(arrayOfCoins) { + const getCoinBalances = (arrayOfCoins || []).map(async (coin) => { + if (coin === 'qort') { + await this.updateQortWalletBalance() + } else if (coin === 'btc') { + await this.updateBtcWalletBalance() + } else if (coin === 'ltc') { + await this.updateLtcWalletBalance() + } else if (coin === 'doge') { + await this.updateDogeWalletBalance() + } else if (coin === 'dgb') { + await this.updateDgbWalletBalance() + } else if (coin === 'rvn') { + await this.updateRvnWalletBalance() + } else if (coin === 'arrr') { + await this.updateArrrWalletBalance() + } + }) + + await Promise.all(getCoinBalances) + } + + async fetchBalance() { + try { + let arrayOfCoins = [] + + const copyObject = { ...this.coinList } + const currentDate = Date.now() + const array = Object.keys(this.coinList) + + for (const key of array) { + const item = this.coinList[key] + + if (item < currentDate) { + delete copyObject[key] + } else { + arrayOfCoins.push(key) + } + } + + if (!this.stop) { + this.stop = true + + await this.fetchCoins(arrayOfCoins) + + this.stop = false + } + + this.coinList = copyObject + } catch (error) { + this.stop = false + } + } + + connectedCallback() { + super.connectedCallback() + this.intervalID = setInterval(this.fetchBalance, 45000) + window.addEventListener('ping-coin-controller-with-coin', this._updateCoinList) } disconnectedCallback() { - - super.disconnectedCallback(); - window.removeEventListener( - 'ping-coin-controller-with-coin', - this._updateCoinList - ); - if(this.intervalID){ - clearInterval(this.intervalID); - - } - - } - - - - render() { - return html``; + if (this.intervalID) { clearInterval(this.intervalID) } + window.removeEventListener('ping-coin-controller-with-coin', this._updateCoinList) + super.disconnectedCallback() } } -customElements.define('coin-balances-controller', CoinBalancesController); +window.customElements.define('coin-balances-controller', CoinBalancesController) \ No newline at end of file diff --git a/core/src/components/friends-view/ChatSideNavHeads.js b/core/src/components/friends-view/ChatSideNavHeads.js index d2f6ebdd..c69b09f8 100644 --- a/core/src/components/friends-view/ChatSideNavHeads.js +++ b/core/src/components/friends-view/ChatSideNavHeads.js @@ -1,221 +1,204 @@ -import {css, html, LitElement} from 'lit' -import {get} from '../../../translate' -import '@material/mwc-icon' -import '@vaadin/tooltip'; - +import { html, LitElement } from 'lit' +import { connect } from 'pwa-helpers' +import { store } from '../../store' +import { get } from '../../../translate' +import { chatSideNavHeadsStyles } from '../../styles/core-css' import './friend-item-actions' +import '@material/mwc-icon' +import '@vaadin/tooltip' -class ChatSideNavHeads extends LitElement { - static get properties() { - return { - selectedAddress: { type: Object }, - config: { type: Object }, - chatInfo: { type: Object }, - iconName: { type: String }, - activeChatHeadUrl: { type: String }, - isImageLoaded: { type: Boolean }, - setActiveChatHeadUrl: {attribute: false}, - openEditFriend: {attribute: false}, - closeSidePanel: {attribute: false, type: Object} - } - } +class ChatSideNavHeads extends connect(store)(LitElement) { + static get properties() { + return { + selectedAddress: { type: Object }, + config: { type: Object }, + chatInfo: { type: Object }, + iconName: { type: String }, + activeChatHeadUrl: { type: String }, + isImageLoaded: { type: Boolean }, + setActiveChatHeadUrl: { attribute: false }, + openEditFriend: { attribute: false }, + closeSidePanel: { attribute: false, type: Object } + } + } - static get styles() { - return css` - :host { - width: 100%; - } - ul { - list-style-type: none; - } - li { - padding: 10px 2px 10px 5px; - cursor: pointer; - width: 100%; - display: flex; - box-sizing: border-box; - font-size: 14px; - transition: 0.2s background-color; - } + static get styles() { + return [chatSideNavHeadsStyles] + } - li:hover { - background-color: var(--lightChatHeadHover); - } - - .active { - background: var(--menuactive); - border-left: 4px solid #3498db; - } - - .img-icon { - font-size:40px; - color: var(--chat-group); - } - - .status { - color: #92959e; - } - - .clearfix { - display: flex; - align-items: center; - } - - .clearfix:after { - visibility: hidden; - display: block; - font-size: 0; - content: " "; - clear: both; - height: 0; - } - ` - } - - constructor() { - super() - this.selectedAddress = {} - this.config = { - user: { - node: { - - } - } - } - this.chatInfo = {} - this.iconName = '' - this.activeChatHeadUrl = '' - this.isImageLoaded = false - this.imageFetches = 0 - } - - createImage(imageUrl) { - const imageHTMLRes = new Image(); - imageHTMLRes.src = imageUrl; - imageHTMLRes.style= "width:30px; height:30px; float: left; border-radius:50%; font-size:14px"; - imageHTMLRes.onclick= () => { - this.openDialogImage = true; - } - imageHTMLRes.onload = () => { - this.isImageLoaded = true; - } - imageHTMLRes.onerror = () => { - if (this.imageFetches < 4) { - setTimeout(() => { - this.imageFetches = this.imageFetches + 1; - imageHTMLRes.src = imageUrl; - }, 500); - } else { - this.isImageLoaded = false - } - }; - return imageHTMLRes; - } - - render() { - let avatarImg = "" - if (this.chatInfo.name) { - const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]; - const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port; - const avatarUrl = `${nodeUrl}/arbitrary/THUMBNAIL/${this.chatInfo.name}/qortal_avatar?async=true&apiKey=${myNode.apiKey}`; - avatarImg = this.createImage(avatarUrl) - } - - return html` -
  • { - const target = e.target - const popover = - this.shadowRoot.querySelector('friend-item-actions'); - if (popover) { - popover.openPopover(target); + constructor() { + super() + this.selectedAddress = {} + this.config = { + user: { + node: { } - }} class="clearfix" id=${`friend-item-parent-${this.chatInfo.name}`}> -
    - ${this.isImageLoaded ? html`${avatarImg}` : html``} - ${!this.isImageLoaded && !this.chatInfo.name && !this.chatInfo.groupName - ? html`account_circle` - : html``} - ${!this.isImageLoaded && this.chatInfo.name - ? html`
    - ${this.chatInfo.name.charAt(0)} -
    ` - : ""} - ${!this.isImageLoaded && this.chatInfo.groupName - ? html`
    - ${this.chatInfo.groupName.charAt(0)} -
    ` - : ""} -
    -
    - - ${this.chatInfo.groupName - ? this.chatInfo.groupName - : this.chatInfo.name !== undefined - ? (this.chatInfo.alias || this.chatInfo.name) - : this.chatInfo.address.substr(0, 15)} - -
    -
    + } + } + this.chatInfo = {} + this.iconName = '' + this.activeChatHeadUrl = '' + this.isImageLoaded = false + this.imageFetches = 0 + } -
    -
    - ${this.chatInfo.willFollow ? html` - connect_without_contact - - - ` : ''} -
    -
  • - { - this.openEditFriend(this.chatInfo) - }} - name=${this.chatInfo.name} - .closeSidePanel=${this.closeSidePanel} - > - ` - } + if (this.chatInfo.name) { + const myNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node] + const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port + const avatarUrl = `${nodeUrl}/arbitrary/THUMBNAIL/${this.chatInfo.name}/qortal_avatar?async=true` + avatarImg = this.createImage(avatarUrl) + } + return html` +
  • { + const target = e.target + const popover = this.shadowRoot.querySelector('friend-item-actions'); + if (popover) { + popover.openPopover(target); + } + }} + class="clearfix" id=${`friend-item-parent-${this.chatInfo.name}`} + > +
    + ${this.isImageLoaded ? html`${avatarImg}` : html``} + ${!this.isImageLoaded && !this.chatInfo.name && !this.chatInfo.groupName ? + html` + account_circle + ` + : html`` + } + ${!this.isImageLoaded && this.chatInfo.name ? + html` +
    + ${this.chatInfo.name.charAt(0)} +
    + ` : '' + } + ${!this.isImageLoaded && this.chatInfo.groupName ? + html` +
    + ${this.chatInfo.groupName.charAt(0)} +
    + ` : '' + } +
    +
    + + ${this.chatInfo.groupName + ? this.chatInfo.groupName + : this.chatInfo.name !== undefined + ? (this.chatInfo.alias || this.chatInfo.name) + : this.chatInfo.address.substr(0, 15) + } + +
    +
    +
    +
    + ${this.chatInfo.willFollow ? + html` + connect_without_contact + + ` : '' + } +
    +
  • + { + this.openEditFriend(this.chatInfo) + }} + name=${this.chatInfo.name} + .closeSidePanel=${this.closeSidePanel} + > + ` + } + firstUpdated() { + // ... + } - shouldUpdate(changedProperties) { - if(changedProperties.has('activeChatHeadUrl')){ - return true - } - if(changedProperties.has('chatInfo')){ - return true - } - return !!changedProperties.has('isImageLoaded'); + createImage(imageUrl) { + const imageHTMLRes = new Image() + imageHTMLRes.src = imageUrl + imageHTMLRes.style = "width:30px; height:30px; float: left; border-radius:50%; font-size:14px" + imageHTMLRes.onclick = () => { + this.openDialogImage = true + } - } + imageHTMLRes.onload = () => { + this.isImageLoaded = true + } - getUrl(chatUrl) { - this.setActiveChatHeadUrl(chatUrl) - } + imageHTMLRes.onerror = () => { + if (this.imageFetches < 4) { + setTimeout(() => { + this.imageFetches = this.imageFetches + 1 + imageHTMLRes.src = imageUrl + }, 500) + } else { + this.isImageLoaded = false + } + } + return imageHTMLRes + } + shouldUpdate(changedProperties) { + if (changedProperties.has('activeChatHeadUrl')) { + return true + } + + if (changedProperties.has('chatInfo')) { + return true + } + + return !!changedProperties.has('isImageLoaded') + } + + getUrl(chatUrl) { + this.setActiveChatHeadUrl(chatUrl) + } + + // Standard functions + getApiKey() { + const coreNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node] + return coreNode.apiKey + } + + isEmptyArray(arr) { + if (!arr) { return true } + return arr.length === 0 + } + + round(number) { + return (Math.round(parseFloat(number) * 1e8) / 1e8).toFixed(8) + } } -window.customElements.define('chat-side-nav-heads', ChatSideNavHeads) +window.customElements.define('chat-side-nav-heads', ChatSideNavHeads) \ No newline at end of file diff --git a/core/src/components/friends-view/add-friends-modal.js b/core/src/components/friends-view/add-friends-modal.js index 1e6f4ddd..b2026b8d 100644 --- a/core/src/components/friends-view/add-friends-modal.js +++ b/core/src/components/friends-view/add-friends-modal.js @@ -1,10 +1,11 @@ -import {css, html, LitElement} from 'lit'; -import {translate,} from '../../../translate' -import '@material/mwc-button'; -import '@material/mwc-dialog'; -import '@material/mwc-checkbox'; -import {connect} from 'pwa-helpers'; -import {store} from '../../store'; +import { html, LitElement } from 'lit' +import { connect } from 'pwa-helpers' +import { store } from '../../store' +import { translate, } from '../../../translate' +import { addFriendsModalStyles } from '../../styles/core-css' +import '@material/mwc-button' +import '@material/mwc-checkbox' +import '@material/mwc-dialog' import '@polymer/paper-spinner/paper-spinner-lite.js' class AddFriendsModal extends connect(store)(LitElement) { @@ -21,199 +22,195 @@ class AddFriendsModal extends connect(store)(LitElement) { editContent: { type: Object }, onClose: { attribute: false }, mySelectedFeeds: { type: Array }, - availableFeeedSchemas: {type: Array}, - isLoadingSchemas: {type: Boolean} - }; - } - - constructor() { - super(); - this.isOpen = false; - this.isLoading = false; - this.alias = ''; - this.willFollow = true; - this.notes = ''; - this.nodeUrl = this.getNodeUrl(); - this.myNode = this.getMyNode(); - this.mySelectedFeeds = []; - this.availableFeeedSchemas = []; - this.isLoadingSchemas= false; + availableFeeedSchemas: { type: Array }, + isLoadingSchemas: { type: Boolean } + } } static get styles() { - return css` - * { - --mdc-theme-primary: rgb(3, 169, 244); - --mdc-theme-secondary: var(--mdc-theme-primary); - --mdc-theme-surface: var(--white); - --mdc-dialog-content-ink-color: var(--black); - --mdc-dialog-min-width: 400px; - --mdc-dialog-max-width: 1024px; - box-sizing:border-box; - } - .input { - width: 90%; - outline: 0; - border-width: 0 0 2px; - border-color: var(--mdc-theme-primary); - background-color: transparent; - padding: 10px; - font-family: Roboto, sans-serif; - font-size: 15px; - color: var(--chat-bubble-msg-color); - box-sizing: border-box; - } - - .input::selection { - background-color: var(--mdc-theme-primary); - color: white; - } - - .input::placeholder { - opacity: 0.6; - color: var(--black); - } - - .modal-button { - font-family: Roboto, sans-serif; - font-size: 16px; - color: var(--mdc-theme-primary); - background-color: transparent; - padding: 8px 10px; - border-radius: 5px; - border: none; - transition: all 0.3s ease-in-out; - } - - .modal-button-red { - font-family: Roboto, sans-serif; - font-size: 16px; - color: #f44336; - background-color: transparent; - padding: 8px 10px; - border-radius: 5px; - border: none; - transition: all 0.3s ease-in-out; - } - - .modal-button-red:hover { - cursor: pointer; - background-color: #f4433663; - } - - .modal-button:hover { - cursor: pointer; - background-color: #03a8f475; - } - .checkbox-row { - position: relative; - display: flex; - align-items: center; - align-content: center; - font-family: Montserrat, sans-serif; - font-weight: 600; - color: var(--black); - } - .modal-overlay { - display: block; - position: fixed; - top: 0; - left: 0; - width: 100vw; - height: 100vh; - background-color: rgba( - 0, - 0, - 0, - 0.5 - ); /* Semi-transparent backdrop */ - z-index: 1000; - } - - .modal-content { - position: fixed; - top: 50vh; - left: 50vw; - transform: translate(-50%, -50%); - background-color: var(--mdc-theme-surface); - width: 80vw; - max-width: 600px; - padding: 20px; - box-shadow: rgba(0, 0, 0, 0.1) 0px 4px 6px; - z-index: 1001; - border-radius: 5px; - display: flex; - flex-direction:column; - } - - - .modal-overlay.hidden { - display: none; - } - .avatar { - width: 36px; - height: 36px; - display: flex; - align-items: center; - } - - .app-name { - display: flex; - gap: 20px; - align-items: center; - width: 100%; - cursor: pointer; - padding: 5px; - border-radius: 5px; - margin-bottom: 10px; - } - .inner-content { - display: flex; - flex-direction: column; - max-height: 75vh; - flex-grow: 1; - overflow: auto; - } - - .inner-content::-webkit-scrollbar-track { - background-color: whitesmoke; - border-radius: 7px; - } - - .inner-content::-webkit-scrollbar { - width: 12px; - border-radius: 7px; - background-color: whitesmoke; - } - - .inner-content::-webkit-scrollbar-thumb { - background-color: rgb(180, 176, 176); - border-radius: 7px; - transition: all 0.3s ease-in-out; - } - `; + return [addFriendsModalStyles] } - firstUpdated() {} + constructor() { + super() + this.isOpen = false + this.isLoading = false + this.alias = '' + this.willFollow = true + this.notes = '' + this.nodeUrl = this.getNodeUrl() + this.myNode = this.getMyNode() + this.mySelectedFeeds = [] + this.availableFeeedSchemas = [] + this.isLoadingSchemas = false + } + + render() { + return html` + + ` + } + + firstUpdated() { + // ... + } getNodeUrl() { - const myNode = - store.getState().app.nodeConfig.knownNodes[ - window.parent.reduxStore.getState().app.nodeConfig.node - ]; - - return myNode.protocol + '://' + myNode.domain + ':' + myNode.port; + const myNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node] + return myNode.protocol + '://' + myNode.domain + ':' + myNode.port } + getMyNode() { - return store.getState().app.nodeConfig.knownNodes[ - window.parent.reduxStore.getState().app.nodeConfig.node - ]; + return store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node] } clearFields() { - this.alias = ''; - this.willFollow = true; - this.notes = ''; + this.alias = '' + this.willFollow = true + this.notes = '' } addFriend() { @@ -223,10 +220,10 @@ class AddFriendsModal extends connect(store)(LitElement) { notes: this.notes, willFollow: this.willFollow, mySelectedFeeds: this.mySelectedFeeds + }) - }); - this.clearFields(); - this.onClose(); + this.clearFields() + this.onClose() } removeFriend() { @@ -239,244 +236,60 @@ class AddFriendsModal extends connect(store)(LitElement) { mySelectedFeeds: this.mySelectedFeeds }, true - ); - this.clearFields(); - this.onClose(); + ) + + this.clearFields() + this.onClose() } async updated(changedProperties) { - if ( - changedProperties && - changedProperties.has('editContent') && - this.editContent - ) { - this.userSelected = { - name: this.editContent.name ?? '', - }; - this.notes = this.editContent.notes ?? ''; - this.willFollow = this.editContent.willFollow ?? true; - this.alias = this.editContent.alias ?? ''; + if (changedProperties && changedProperties.has('editContent') && this.editContent) { + this.userSelected = { name: this.editContent.name ?? '' } + this.notes = this.editContent.notes ?? '' + this.willFollow = this.editContent.willFollow ?? true + this.alias = this.editContent.alias ?? '' this.requestUpdate() } - if ( - changedProperties && - changedProperties.has('isOpen') && this.isOpen - ) { + + if (changedProperties && changedProperties.has('isOpen') && this.isOpen) { await this.getAvailableFeedSchemas() } - } async getAvailableFeedSchemas() { try { - this.isLoadingSchemas= true - const url = `${this.nodeUrl}/arbitrary/resources/search?service=DOCUMENT&identifier=ui_schema_feed&prefix=true`; - const res = await fetch(url); - const data = await res.json(); + this.isLoadingSchemas = true + const url = `${this.nodeUrl}/arbitrary/resources/search?service=DOCUMENT&identifier=ui_schema_feed&prefix=true` + const res = await fetch(url) + const data = await res.json() + if (data.error === 401) { - this.availableFeeedSchemas = []; + this.availableFeeedSchemas = [] } else { - this.availableFeeedSchemas = data.filter( - (item) => item.identifier === 'ui_schema_feed' - ); + this.availableFeeedSchemas = data.filter((item) => item.identifier === 'ui_schema_feed') } - this.userFoundModalOpen = true; - } catch (error) {} finally { - this.isLoadingSchemas= false + + this.userFoundModalOpen = true + } catch (error) { + } finally { + this.isLoadingSchemas = false } } - render() { - return html` - - `; + round(number) { + return (Math.round(parseFloat(number) * 1e8) / 1e8).toFixed(8) } } -customElements.define('add-friends-modal', AddFriendsModal); +window.customElements.define('add-friends-modal', AddFriendsModal) \ No newline at end of file diff --git a/core/src/components/friends-view/avatar.js b/core/src/components/friends-view/avatar.js index e0714032..f00a9904 100644 --- a/core/src/components/friends-view/avatar.js +++ b/core/src/components/friends-view/avatar.js @@ -1,16 +1,17 @@ -import {css, html, LitElement} from 'lit'; -import axios from 'axios'; -import '@material/mwc-menu'; -import '@material/mwc-list/mwc-list-item.js'; -import {RequestQueueWithPromise} from '../../../../plugins/plugins/utils/queue'; -import '../../../../plugins/plugins/core/components/TimeAgo'; -import {connect} from 'pwa-helpers'; -import {store} from '../../store'; -import ShortUniqueId from 'short-unique-id'; +import { html, LitElement } from 'lit' +import { connect } from 'pwa-helpers' +import { store } from '../../store' +import { RequestQueueWithPromise } from '../../../../plugins/plugins/utils/classes' +import { avatarComponentStyles } from '../../styles/core-css' +import axios from 'axios' +import ShortUniqueId from 'short-unique-id' +import '../../../../plugins/plugins/core/components/TimeAgo' +import '@material/mwc-menu' +import '@material/mwc-list/mwc-list-item.js' -const requestQueue = new RequestQueueWithPromise(3); -const requestQueueRawData = new RequestQueueWithPromise(3); -const requestQueueStatus = new RequestQueueWithPromise(3); +const requestQueue = new RequestQueueWithPromise(3) +const requestQueueRawData = new RequestQueueWithPromise(3) +const requestQueueStatus = new RequestQueueWithPromise(3) export class AvatarComponent extends connect(store)(LitElement) { static get properties() { @@ -18,284 +19,210 @@ export class AvatarComponent extends connect(store)(LitElement) { resource: { type: Object }, isReady: { type: Boolean }, status: { type: Object }, - name: { type: String }, - }; + name: { type: String } + } } static get styles() { - return css` - * { - --mdc-theme-text-primary-on-background: var(--black); - box-sizing: border-box; - } - :host { - width: 100%; - box-sizing: border-box; - } - img { - width: 100%; - max-height: 30vh; - border-radius: 5px; - cursor: pointer; - position: relative; - } - .smallLoading, - .smallLoading:after { - border-radius: 50%; - width: 2px; - height: 2px; - } - - .defaultSize { - width: 100%; - height: 160px; - } - .parent-feed-item { - position: relative; - display: flex; - background-color: var(--chat-bubble-bg); - flex-grow: 0; - flex-direction: column; - align-items: flex-start; - justify-content: center; - border-radius: 5px; - padding: 12px 15px 4px 15px; - min-width: 150px; - width: 100%; - box-sizing: border-box; - cursor: pointer; - font-size: 16px; - } - .avatar { - width: 36px; - height: 36px; - border-radius: 50%; - overflow: hidden; - display: flex; - align-items: center; - } - .avatarApp { - width: 30px; - height: 30px; - border-radius: 50%; - overflow: hidden; - display: flex; - align-items: center; - } - .feed-item-name { - user-select: none; - color: #03a9f4; - margin-bottom: 5px; - } - - .app-name { - display: flex; - justify-content: space-between; - align-items: center; - width: 100%; - } - - mwc-menu { - position: absolute; - } - `; + return [avatarComponentStyles] } constructor() { - super(); + super() this.resource = { identifier: '', name: '', - service: '', - }; + service: '' + } this.status = { - status: '', - }; - this.isReady = false; - this.nodeUrl = this.getNodeUrl(); - this.myNode = this.getMyNode(); - this.isFetching = false; - this.uid = new ShortUniqueId(); - } - getNodeUrl() { - const myNode = - window.parent.reduxStore.getState().app.nodeConfig.knownNodes[ - window.parent.reduxStore.getState().app.nodeConfig.node - ]; - - return myNode.protocol + '://' + myNode.domain + ':' + myNode.port; - } - getMyNode() { - return window.parent.reduxStore.getState().app.nodeConfig.knownNodes[ - window.parent.reduxStore.getState().app.nodeConfig.node - ]; - } - - getApiKey() { - const myNode = - window.parent.reduxStore.getState().app.nodeConfig.knownNodes[ - window.parent.reduxStore.getState().app.nodeConfig.node - ]; - return myNode.apiKey; - } - - async fetchResource() { - try { - if (this.isFetching) return; - this.isFetching = true; - await axios.get( - `${this.nodeUrl}/arbitrary/resource/properties/${this.resource.service}/${this.resource.name}/${this.resource.identifier}?apiKey=${this.myNode.apiKey}` - ); - this.isFetching = false; - } catch (error) { - this.isFetching = false; + status: '' } - } - - async fetchVideoUrl() { - await this.fetchResource(); - } - - async getRawData() { - const url = `${this.nodeUrl}/arbitrary/${this.resource.service}/${this.resource.name}/${this.resource.identifier}?apiKey=${this.myNode.apiKey}`; - return await requestQueueRawData.enqueue(() => { - return axios.get(url); - }); - // const response2 = await fetch(url, { - // method: 'GET', - // headers: { - // 'Content-Type': 'application/json' - // } - // }) - - // const responseData2 = await response2.json() - // return responseData2 - } - - updateDisplayWithPlaceholders(display, resource, rawdata) { - const pattern = /\$\$\{([a-zA-Z0-9_\.]+)\}\$\$/g; - - for (const key in display) { - const value = display[key]; - - display[key] = value.replace(pattern, (match, p1) => { - if (p1.startsWith('rawdata.')) { - const dataKey = p1.split('.')[1]; - if (rawdata[dataKey] === undefined) { - console.error('rawdata key not found:', dataKey); - } - return rawdata[dataKey] || match; - } else if (p1.startsWith('resource.')) { - const resourceKey = p1.split('.')[1]; - if (resource[resourceKey] === undefined) { - console.error('resource key not found:', resourceKey); - } - return resource[resourceKey] || match; - } - return match; - }); - } - } - - async fetchStatus() { - let isCalling = false; - let percentLoaded = 0; - let timer = 24; - const response = await requestQueueStatus.enqueue(() => { - return axios.get( - `${this.nodeUrl}/arbitrary/resource/status/${this.resource.service}/${this.resource.name}/${this.resource.identifier}?apiKey=${this.myNode.apiKey}` - ); - }); - if (response && response.data && response.data.status === 'READY') { - this.status = response.data; - - return; - } - const intervalId = setInterval(async () => { - if (isCalling) return; - isCalling = true; - - const data = await requestQueue.enqueue(() => { - return axios.get( - `${this.nodeUrl}/arbitrary/resource/status/${this.resource.service}/${this.resource.name}/${this.resource.identifier}?apiKey=${this.myNode.apiKey}` - ); - }); - const res = data.data; - - isCalling = false; - if (res.localChunkCount) { - if (res.percentLoaded) { - if ( - res.percentLoaded === percentLoaded && - res.percentLoaded !== 100 - ) { - timer = timer - 5; - } else { - timer = 24; - } - if (timer < 0) { - clearInterval(intervalId); - } - percentLoaded = res.percentLoaded; - } - - this.status = res; - if (this.status.status === 'DOWNLOADED') { - await this.fetchResource(); - } - } - - // check if progress is 100% and clear interval if true - if (res.status === 'READY') { - clearInterval(intervalId); - this.status = res; - this.isReady = true; - } - }, 5000); // 1 second interval - } - - async _fetchImage() { - try { - await this.fetchVideoUrl(); - await this.fetchStatus(); - } catch (error) { - /* empty */ - } - } - - firstUpdated() { - this._fetchImage(); + this.isReady = false + this.nodeUrl = this.getNodeUrl() + this.myNode = this.getMyNode() + this.isFetching = false + this.uid = new ShortUniqueId() } render() { return html`
    - ${this.status.status !== 'READY' - ? html` - account_circle - ` - : ''} - ${this.status.status === 'READY' - ? html` -
    - -
    - ` - : ''} + ${this.status.status !== 'READY' ? + html` + account_circle + ` : '' + } + ${this.status.status === 'READY' ? + html` +
    + +
    + ` : '' + }
    - `; + ` + } + + firstUpdated() { + this._fetchImage() + } + + getNodeUrl() { + const myNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node] + return myNode.protocol + '://' + myNode.domain + ':' + myNode.port + } + + getMyNode() { + return store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node] + } + + async fetchResource() { + try { + if (this.isFetching) return + + this.isFetching = true + + await axios.get( + `${this.nodeUrl}/arbitrary/resource/properties/${this.resource.service}/${this.resource.name}/${this.resource.identifier}?apiKey=${this.myNode.apiKey}` + ) + + this.isFetching = false + } catch (error) { + this.isFetching = false + } + } + + async fetchVideoUrl() { + await this.fetchResource() + } + + async getRawData() { + const url = `${this.nodeUrl}/arbitrary/${this.resource.service}/${this.resource.name}/${this.resource.identifier}?apiKey=${this.myNode.apiKey}` + + return await requestQueueRawData.enqueue(() => { + return axios.get(url) + }) + } + + updateDisplayWithPlaceholders(display, resource, rawdata) { + const pattern = /\$\$\{([a-zA-Z0-9_\.]+)\}\$\$/g + + for (const key in display) { + const value = display[key] + + display[key] = value.replace(pattern, (match, p1) => { + if (p1.startsWith('rawdata.')) { + const dataKey = p1.split('.')[1] + + if (rawdata[dataKey] === undefined) { + console.error('rawdata key not found:', dataKey) + } + + return rawdata[dataKey] || match + } else if (p1.startsWith('resource.')) { + const resourceKey = p1.split('.')[1] + + if (resource[resourceKey] === undefined) { + console.error('resource key not found:', resourceKey) + } + + return resource[resourceKey] || match + } + + return match + }) + } + } + + async fetchStatus() { + let isCalling = false + let percentLoaded = 0 + let timer = 24 + + const response = await requestQueueStatus.enqueue(() => { + return axios.get( + `${this.nodeUrl}/arbitrary/resource/status/${this.resource.service}/${this.resource.name}/${this.resource.identifier}?apiKey=${this.myNode.apiKey}` + ) + }) + + if (response && response.data && response.data.status === 'READY') { + this.status = response.data + return + } + + const intervalId = setInterval(async () => { + if (isCalling) return + + isCalling = true + + const data = await requestQueue.enqueue(() => { + return axios.get( + `${this.nodeUrl}/arbitrary/resource/status/${this.resource.service}/${this.resource.name}/${this.resource.identifier}?apiKey=${this.myNode.apiKey}` + ) + }) + + const res = data.data + + isCalling = false + + if (res.localChunkCount) { + if (res.percentLoaded) { + if (res.percentLoaded === percentLoaded && res.percentLoaded !== 100) { + timer = timer - 5 + } else { + timer = 24 + } + + if (timer < 0) { + clearInterval(intervalId) + } + + percentLoaded = res.percentLoaded + } + + this.status = res + + if (this.status.status === 'DOWNLOADED') { + await this.fetchResource() + } + } + + // check if progress is 100% and clear interval if true + if (res.status === 'READY') { + clearInterval(intervalId) + this.status = res + this.isReady = true + } + }, 5000) // 5 second interval + } + + async _fetchImage() { + try { + await this.fetchVideoUrl() + await this.fetchStatus() + } catch (error) { + /* empty */ + } + } + + // Standard functions + getApiKey() { + const coreNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node] + return coreNode.apiKey + } + + isEmptyArray(arr) { + if (!arr) { return true } + return arr.length === 0 + } + + round(number) { + return (Math.round(parseFloat(number) * 1e8) / 1e8).toFixed(8) } } -customElements.define('avatar-component', AvatarComponent); +window.customElements.define('avatar-component', AvatarComponent) \ No newline at end of file diff --git a/core/src/components/friends-view/beginner-checklist.js b/core/src/components/friends-view/beginner-checklist.js index 4a688aed..8ef4bd6c 100644 --- a/core/src/components/friends-view/beginner-checklist.js +++ b/core/src/components/friends-view/beginner-checklist.js @@ -1,344 +1,214 @@ -import {css, html, LitElement} from 'lit'; -import {connect} from 'pwa-helpers'; - -import '@vaadin/item'; -import '@vaadin/list-box'; -import '@polymer/paper-icon-button/paper-icon-button.js'; -import '@polymer/iron-icons/iron-icons.js'; -import {store} from '../../store.js'; -import {setNewTab} from '../../redux/app/app-actions.js'; -import '@material/mwc-icon'; -import {get} from '../../../translate'; -import '../../../../plugins/plugins/core/components/TimeAgo.js'; -import '../notification-view/popover.js'; -import ShortUniqueId from 'short-unique-id'; +import { html, LitElement } from 'lit' +import { connect } from 'pwa-helpers' +import { store } from '../../store' +import { setNewTab } from '../../redux/app/app-actions' +import { get } from '../../../translate' +import { beginnerChecklistStyles } from '../../styles/core-css' +import ShortUniqueId from 'short-unique-id' +import '../notification-view/popover' +import '../../../../plugins/plugins/core/components/TimeAgo' +import '@material/mwc-icon' +import '@polymer/paper-icon-button/paper-icon-button.js' +import '@polymer/iron-icons/iron-icons.js' +import '@vaadin/item' +import '@vaadin/list-box' class BeginnerChecklist extends connect(store)(LitElement) { - static properties = { - notifications: { type: Array }, - showChecklist: { type: Boolean }, - theme: { type: String, reflect: true }, - isSynced: { type: Boolean }, - hasName: { type: Boolean }, - hasTourFinished: { type: Boolean }, - }; - - constructor() { - super(); - this.showChecklist = false; - this.initialFetch = false; - this.theme = localStorage.getItem('qortalTheme') - ? localStorage.getItem('qortalTheme') - : 'light'; - this.isSynced = false; - this.hasName = null; - this.nodeUrl = this.getNodeUrl(); - this.myNode = this.getMyNode(); - this.hasTourFinished = null; - this._controlTourFinished = this._controlTourFinished.bind(this); - this.uid = new ShortUniqueId(); + static get properties() { + return { + notifications: { type: Array }, + showChecklist: { type: Boolean }, + isSynced: { type: Boolean }, + hasName: { type: Boolean }, + hasTourFinished: { type: Boolean }, + theme: { type: String, reflect: true } + } } - _controlTourFinished() { - this.hasTourFinished = true; + static get styles() { + return [beginnerChecklistStyles] + } + + constructor() { + super() + this.showChecklist = false + this.initialFetch = false + this.isSynced = false + this.hasName = null + this.nodeUrl = this.getNodeUrl() + this.myNode = this.getMyNode() + this.hasTourFinished = null + this._controlTourFinished = this._controlTourFinished.bind(this) + this.uid = new ShortUniqueId() + this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light' + } + + render() { + return this.hasName === false || this.hasTourFinished === false ? + html` +
    + +
    this._toggleChecklist()}> + + checklist + + +
    +
    +
    +
    +

    Are you synced?

    + ${this.syncPercentage === 100 ? + html` + + task_alt + + ` + : html` + + radio_button_unchecked + + ` + } +
    +
    { + store.dispatch( + setNewTab({ + url: `group-management`, + id: this.uid.rnd(), + myPlugObj: { + url: 'name-registration', + domain: 'core', + page: 'name-registration/index.html', + title: 'Name Registration', + icon: 'vaadin:user-check', + mwcicon: 'manage_accounts', + pluginNumber: 'plugin-qCmtXAQmtu', + menus: [], + parent: false + }, + openExisting: true + }) + ); + this.handleBlur(); + }} + > +

    Do you have a name registered?

    + ${this.hasName ? + html` + + task_alt + + ` : html` + + radio_button_unchecked + + ` + } +
    +
    +
    +
    + ` + : '' } firstUpdated() { - this.address = store.getState().app.selectedAddress.address; - this.hasTourFinished = JSON.parse( - localStorage.getItem(`hasViewedTour-${this.address}`) || 'null' - ); + this.address = store.getState().app.selectedAddress.address + this.hasTourFinished = JSON.parse(localStorage.getItem(`hasViewedTour-${this.address}`) || 'null') + } + + _controlTourFinished() { + this.hasTourFinished = true } connectedCallback() { - super.connectedCallback(); - window.addEventListener( - 'send-tour-finished', - this._controlTourFinished - ); + super.connectedCallback() + window.addEventListener('send-tour-finished', this._controlTourFinished) } disconnectedCallback() { - window.removeEventListener( - 'send-tour-finished', - this._controlTourFinished - ); - - super.disconnectedCallback(); + window.removeEventListener('send-tour-finished', this._controlTourFinished) + super.disconnectedCallback() } getNodeUrl() { - const myNode = - window.parent.reduxStore.getState().app.nodeConfig.knownNodes[ - window.parent.reduxStore.getState().app.nodeConfig.node - ]; - - return myNode.protocol + '://' + myNode.domain + ':' + myNode.port; + const myNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node] + return myNode.protocol + '://' + myNode.domain + ':' + myNode.port } + getMyNode() { - return window.parent.reduxStore.getState().app.nodeConfig.knownNodes[ - window.parent.reduxStore.getState().app.nodeConfig.node - ]; + return store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node] } async getName(recipient) { try { - if (!recipient) return ''; - const endpoint = `${this.nodeUrl}/names/address/${recipient}`; - const res = await fetch(endpoint); - const getNames = await res.json(); + if (!recipient) return '' - this.hasName = Array.isArray(getNames) && getNames.length > 0; + const endpoint = `${this.nodeUrl}/names/address/${recipient}` + const res = await fetch(endpoint) + const getNames = await res.json() + + this.hasName = Array.isArray(getNames) && getNames.length > 0 } catch (error) { - return ''; + return '' } } stateChanged(state) { - if ( - state.app.nodeStatus && - state.app.nodeStatus.syncPercent !== this.syncPercentage - ) { - this.syncPercentage = state.app.nodeStatus.syncPercent; + if (state.app.nodeStatus && state.app.nodeStatus.syncPercent !== this.syncPercentage) { + this.syncPercentage = state.app.nodeStatus.syncPercent - if ( - !this.hasAttempted && - state.app.selectedAddress && - state.app.nodeStatus.syncPercent === 100 - ) { - this.hasAttempted = true; - this.getName(state.app.selectedAddress.address); + if (!this.hasAttempted && state.app.selectedAddress && state.app.nodeStatus.syncPercent === 100) { + this.hasAttempted = true + this.getName(state.app.selectedAddress.address) } } - if ( - state.app.accountInfo && - state.app.accountInfo.names.length && - state.app.nodeStatus && - state.app.nodeStatus.syncPercent === 100 && - this.hasName === false && - this.hasAttempted && - state.app.accountInfo && - state.app.accountInfo.names && + + if (state.app.accountInfo && + state.app.accountInfo.names.length && state.app.nodeStatus && state.app.nodeStatus.syncPercent === 100 && + this.hasName === false && this.hasAttempted && state.app.accountInfo && state.app.accountInfo.names && state.app.accountInfo.names.length > 0 ) { - this.hasName = true; + this.hasName = true } } handleBlur() { setTimeout(() => { if (!this.shadowRoot.contains(document.activeElement)) { - this.showChecklist = false; + this.showChecklist = false } - }, 0); - } - - render() { - return this.hasName === false || this.hasTourFinished === false - ? html` -
    - -
    this._toggleChecklist()} - > - checklist - - -
    - -
    -
    -
    -

    Are you synced?

    - ${this.syncPercentage === 100 - ? html` - task_alt - ` - : html` - radio_button_unchecked - `} -
    - -
    { - store.dispatch( - setNewTab({ - url: `group-management`, - id: this.uid.rnd(), - myPlugObj: { - url: 'name-registration', - domain: 'core', - page: 'name-registration/index.html', - title: 'Name Registration', - icon: 'vaadin:user-check', - mwcicon: 'manage_accounts', - pluginNumber: - 'plugin-qCmtXAQmtu', - menus: [], - parent: false, - }, - openExisting: true, - }) - ); - this.handleBlur(); - }} - > -

    Do you have a name registered?

    - ${this.hasName - ? html` - task_alt - ` - : html` - radio_button_unchecked - `} -
    -
    -
    -
    - ` - : ''; + }, 0) } _toggleChecklist() { - this.showChecklist = !this.showChecklist; + this.showChecklist = !this.showChecklist + if (this.showChecklist) { requestAnimationFrame(() => { - this.shadowRoot.getElementById('checklist-panel').focus(); - }); + this.shadowRoot.getElementById('checklist-panel').focus() + }) } } - static styles = css` - .layout { - display: flex; - flex-direction: column; - align-items: center; - position: relative; - } + // Standard functions + getApiKey() { + const coreNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node] + return coreNode.apiKey + } - .count { - position: absolute; - top: -5px; - right: -5px; - font-size: 12px; - background-color: red; - color: white; - border-radius: 50%; - width: 16px; - height: 16px; - display: flex; - align-items: center; - justify-content: center; - } + isEmptyArray(arr) { + if (!arr) { return true } + return arr.length === 0 + } - .nocount { - display: none; - } - - .popover-panel { - position: absolute; - width: 200px; - padding: 10px; - background-color: var(--white); - border: 1px solid var(--black); - border-radius: 4px; - box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); - top: 40px; - max-height: 350px; - overflow: auto; - scrollbar-width: thin; - scrollbar-color: #6a6c75 #a1a1a1; - } - - .popover-panel::-webkit-scrollbar { - width: 11px; - } - - .popover-panel::-webkit-scrollbar-track { - background: #a1a1a1; - } - - .popover-panel::-webkit-scrollbar-thumb { - background-color: #6a6c75; - border-radius: 6px; - border: 3px solid #a1a1a1; - } - - .list { - display: flex; - flex-direction: column; - gap: 15px; - } - - .task-list-item { - display: flex; - gap: 15px; - justify-content: space-between; - align-items: center; - } - - .checklist-item { - padding: 5px; - border-bottom: 1px solid; - display: flex; - justify-content: space-between; - cursor: pointer; - transition: 0.2s all; - } - - .checklist-item:hover { - background: var(--nav-color-hover); - } - - p { - font-size: 16px; - color: var(--black); - margin: 0px; - padding: 0px; - } - `; + round(number) { + return (Math.round(parseFloat(number) * 1e8) / 1e8).toFixed(8) + } } -customElements.define('beginner-checklist', BeginnerChecklist); +window.customElements.define('beginner-checklist', BeginnerChecklist) \ No newline at end of file diff --git a/core/src/components/friends-view/computePowWorkerFile.src.js b/core/src/components/friends-view/computePowWorkerFile.src.js index b8bd962d..eb4cb775 100644 --- a/core/src/components/friends-view/computePowWorkerFile.src.js +++ b/core/src/components/friends-view/computePowWorkerFile.src.js @@ -1,91 +1,67 @@ -import {Sha256} from 'asmcrypto.js' +import { Sha256 } from 'asmcrypto.js' - -function sbrk(size, heap){ - let brk = 512 * 1024 // stack top - let old = brk - brk += size - - if (brk > heap.length) - throw new Error('heap exhausted') - - return old +function sbrk(size, heap) { + let brk = 512 * 1024 // stack top + let old = brk + brk += size + if (brk > heap.length) throw new Error('heap exhausted') + return old } - - - self.addEventListener('message', async e => { - const response = await computePow(e.data.convertedBytes, e.data.path) - postMessage(response) - + const response = await computePow(e.data.convertedBytes, e.data.path) + postMessage(response) }) - const memory = new WebAssembly.Memory({ initial: 256, maximum: 256 }) const heap = new Uint8Array(memory.buffer) - - const computePow = async (convertedBytes, path) => { + let response = null + await new Promise((resolve, reject) => { + const _convertedBytesArray = Object.keys(convertedBytes).map( + function (key) { + return convertedBytes[key] + } + ) + const convertedBytesArray = new Uint8Array(_convertedBytesArray) + const convertedBytesHash = new Sha256() + .process(convertedBytesArray) + .finish().result + const hashPtr = sbrk(32, heap) + const hashAry = new Uint8Array( + memory.buffer, + hashPtr, + 32 + ) + hashAry.set(convertedBytesHash) + const difficulty = 14 + const workBufferLength = 8 * 1024 * 1024 + const workBufferPtr = sbrk( + workBufferLength, + heap + ) + const importObject = { + env: { + memory: memory + } + } + function loadWebAssembly(filename, imports) { + return fetch(filename) + .then(response => response.arrayBuffer()) + .then(buffer => WebAssembly.compile(buffer)) + .then(module => { + return new WebAssembly.Instance(module, importObject) + }) + } + loadWebAssembly(path) + .then(wasmModule => { + response = { + nonce: wasmModule.exports.compute2(hashPtr, workBufferPtr, workBufferLength, difficulty), - - let response = null - - await new Promise((resolve, reject)=> { - - const _convertedBytesArray = Object.keys(convertedBytes).map( - function (key) { - return convertedBytes[key] - } -) -const convertedBytesArray = new Uint8Array(_convertedBytesArray) -const convertedBytesHash = new Sha256() - .process(convertedBytesArray) - .finish().result -const hashPtr = sbrk(32, heap) -const hashAry = new Uint8Array( - memory.buffer, - hashPtr, - 32 -) - -hashAry.set(convertedBytesHash) -const difficulty = 14 -const workBufferLength = 8 * 1024 * 1024 -const workBufferPtr = sbrk( - workBufferLength, - heap -) - - const importObject = { - env: { - memory: memory - }, - }; - - function loadWebAssembly(filename, imports) { - return fetch(filename) - .then(response => response.arrayBuffer()) - .then(buffer => WebAssembly.compile(buffer)) - .then(module => { - return new WebAssembly.Instance(module, importObject); - }); -} - - -loadWebAssembly(path) - .then(wasmModule => { - response = { - nonce : wasmModule.exports.compute2(hashPtr, workBufferPtr, workBufferLength, difficulty), - - } - resolve() - - }); - - - }) - - return response -} + } + resolve() + }) + }) + return response +} \ No newline at end of file diff --git a/core/src/components/friends-view/core-sync-status.js b/core/src/components/friends-view/core-sync-status.js index a4345671..8c695b4d 100644 --- a/core/src/components/friends-view/core-sync-status.js +++ b/core/src/components/friends-view/core-sync-status.js @@ -1,7 +1,8 @@ -import {css, html, LitElement} from 'lit' -import {store} from '../../store' -import {connect} from 'pwa-helpers' -import {translate} from '../../../translate' +import { html, LitElement } from 'lit' +import { connect } from 'pwa-helpers' +import { store } from '../../store' +import { translate } from '../../../translate' +import { coreSyncStatusStyles } from '../../styles/core-css' class CoreSyncStatus extends connect(store)(LitElement) { static get properties() { @@ -12,6 +13,10 @@ class CoreSyncStatus extends connect(store)(LitElement) { } } + static get styles() { + return [coreSyncStatusStyles] + } + constructor() { super() this.nodeInfos = [] @@ -19,69 +24,6 @@ class CoreSyncStatus extends connect(store)(LitElement) { this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light' } - static get styles() { - return css` - .lineHeight { - line-height: 33%; - } - - .tooltip { - display: inline-block; - position: relative; - text-align: left; - } - - .tooltip .bottom { - min-width: 200px; - max-width: 250px; - top: 35px; - left: 50%; - transform: translate(-50%, 0); - padding: 10px 10px; - color: var(--black); - background-color: var(--white); - font-weight: normal; - font-size: 13px; - border-radius: 8px; - position: absolute; - z-index: 99999999; - box-sizing: border-box; - box-shadow: 0 1px 8px rgba(0,0,0,0.5); - border: 1px solid var(--black); - visibility: hidden; - opacity: 0; - transition: opacity 0.8s; - } - - .tooltip:hover .bottom { - visibility: visible; - opacity: 1; - } - - .tooltip .bottom i { - position: absolute; - bottom: 100%; - left: 50%; - margin-left: -12px; - width: 24px; - height: 12px; - overflow: hidden; - } - - .tooltip .bottom i::after { - content: ''; - position: absolute; - width: 12px; - height: 12px; - left: 50%; - transform: translate(-50%,50%) rotate(45deg); - background-color: var(--white); - border: 1px solid var(--black); - box-shadow: 0 1px 8px rgba(0,0,0,0.5); - } - ` - } - render() { return html`
    @@ -136,7 +78,7 @@ class CoreSyncStatus extends connect(store)(LitElement) {

    ${translate("walletprofile.wp3")}

    -

    ${translate("appinfo.coreversion")}: ${this.coreInfos.buildVersion ? (this.coreInfos.buildVersion).substring(0,12) : ''}

    +

    ${translate("appinfo.coreversion")}: ${this.coreInfos.buildVersion ? (this.coreInfos.buildVersion).substring(0, 12) : ''}

    ${translate("appinfo.synchronizing")}... ${this.nodeInfos.syncPercent !== undefined ? this.nodeInfos.syncPercent + '%' : ''}

    ${translate("appinfo.blockheight")}: ${this.nodeInfos.height ? this.nodeInfos.height : ''}

    ${translate("appinfo.peers")}: ${this.nodeInfos.numberOfConnections ? this.nodeInfos.numberOfConnections : ''}

    @@ -150,7 +92,7 @@ class CoreSyncStatus extends connect(store)(LitElement) {

    ${translate("walletprofile.wp3")}

    -

    ${translate("appinfo.coreversion")}: ${this.coreInfos.buildVersion ? (this.coreInfos.buildVersion).substring(0,12) : ''}

    +

    ${translate("appinfo.coreversion")}: ${this.coreInfos.buildVersion ? (this.coreInfos.buildVersion).substring(0, 12) : ''}

    ${translate("walletprofile.wp4")} ${translate("walletprofile.wp2")}

    ${translate("appinfo.blockheight")}: ${this.nodeInfos.height ? this.nodeInfos.height : ''}

    ${translate("appinfo.peers")}: ${this.nodeInfos.numberOfConnections ? this.nodeInfos.numberOfConnections : ''}

    @@ -164,7 +106,7 @@ class CoreSyncStatus extends connect(store)(LitElement) {

    ${translate("walletprofile.wp3")}

    -

    ${translate("appinfo.coreversion")}: ${this.coreInfos.buildVersion ? (this.coreInfos.buildVersion).substring(0,12) : ''}

    +

    ${translate("appinfo.coreversion")}: ${this.coreInfos.buildVersion ? (this.coreInfos.buildVersion).substring(0, 12) : ''}

    ${translate("walletprofile.wp4")} ${translate("walletprofile.wp2")}

    ${translate("appinfo.blockheight")}: ${this.nodeInfos.height ? this.nodeInfos.height : ''}

    ${translate("appinfo.peers")}: ${this.nodeInfos.numberOfConnections ? this.nodeInfos.numberOfConnections : ''}

    @@ -178,7 +120,7 @@ class CoreSyncStatus extends connect(store)(LitElement) {

    ${translate("walletprofile.wp3")}

    -

    ${translate("appinfo.coreversion")}: ${this.coreInfos.buildVersion ? (this.coreInfos.buildVersion).substring(0,12) : ''}

    +

    ${translate("appinfo.coreversion")}: ${this.coreInfos.buildVersion ? (this.coreInfos.buildVersion).substring(0, 12) : ''}

    ${translate("walletprofile.wp4")} ( ${translate("walletprofile.wp1")} )

    ${translate("appinfo.blockheight")}: ${this.nodeInfos.height ? this.nodeInfos.height : ''}

    ${translate("appinfo.peers")}: ${this.nodeInfos.numberOfConnections ? this.nodeInfos.numberOfConnections : ''}

    @@ -192,7 +134,7 @@ class CoreSyncStatus extends connect(store)(LitElement) {

    ${translate("walletprofile.wp3")}

    -

    ${translate("appinfo.coreversion")}: ${this.coreInfos.buildVersion ? (this.coreInfos.buildVersion).substring(0,12) : ''}

    +

    ${translate("appinfo.coreversion")}: ${this.coreInfos.buildVersion ? (this.coreInfos.buildVersion).substring(0, 12) : ''}

    ${translate("walletprofile.wp4")} ( ${translate("walletprofile.wp1")} )

    ${translate("appinfo.blockheight")}: ${this.nodeInfos.height ? this.nodeInfos.height : ''}

    ${translate("appinfo.peers")}: ${this.nodeInfos.numberOfConnections ? this.nodeInfos.numberOfConnections : ''}

    @@ -206,7 +148,7 @@ class CoreSyncStatus extends connect(store)(LitElement) {

    ${translate("walletprofile.wp3")}

    -

    ${translate("appinfo.coreversion")}: ${this.coreInfos.buildVersion ? (this.coreInfos.buildVersion).substring(0,12) : ''}

    +

    ${translate("appinfo.coreversion")}: ${this.coreInfos.buildVersion ? (this.coreInfos.buildVersion).substring(0, 12) : ''}

    ${translate("appinfo.synchronizing")}... ${this.nodeInfos.syncPercent !== undefined ? this.nodeInfos.syncPercent + '%' : ''}

    ${translate("appinfo.blockheight")}: ${this.nodeInfos.height ? this.nodeInfos.height : ''}

    ${translate("appinfo.peers")}: ${this.nodeInfos.numberOfConnections ? this.nodeInfos.numberOfConnections : ''}

    @@ -221,6 +163,20 @@ class CoreSyncStatus extends connect(store)(LitElement) { // ... } + // Standard functions + getApiKey() { + const coreNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node] + return coreNode.apiKey + } + + isEmptyArray(arr) { + if (!arr) { return true } + return arr.length === 0 + } + + round(number) { + return (Math.round(parseFloat(number) * 1e8) / 1e8).toFixed(8) + } } -customElements.define('core-sync-status', CoreSyncStatus) \ No newline at end of file +window.customElements.define('core-sync-status', CoreSyncStatus) \ No newline at end of file diff --git a/core/src/components/friends-view/feed-item.js b/core/src/components/friends-view/feed-item.js index 2410c5ff..07e11d64 100644 --- a/core/src/components/friends-view/feed-item.js +++ b/core/src/components/friends-view/feed-item.js @@ -1,366 +1,282 @@ -import {css, html, LitElement} from 'lit'; -import {translate,} from '../../../translate' +import { html, LitElement } from 'lit' +import { connect } from 'pwa-helpers' +import { store } from '../../store' +import { setNewTab } from '../../redux/app/app-actions' +import { RequestQueueWithPromise } from '../../../../plugins/plugins/utils/classes' +import { translate, } from '../../../translate' +import { feedItemStyles } from '../../styles/core-css' import axios from 'axios' -import '@material/mwc-menu'; -import '@material/mwc-list/mwc-list-item.js' -import {RequestQueueWithPromise} from '../../../../plugins/plugins/utils/queue'; +import ShortUniqueId from 'short-unique-id' import '../../../../plugins/plugins/core/components/TimeAgo' -import {connect} from 'pwa-helpers'; -import {store} from '../../store'; -import {setNewTab} from '../../redux/app/app-actions'; -import ShortUniqueId from 'short-unique-id'; - -const requestQueue = new RequestQueueWithPromise(3); -const requestQueueRawData = new RequestQueueWithPromise(3); -const requestQueueStatus = new RequestQueueWithPromise(3); +import '@material/mwc-menu' +import '@material/mwc-list/mwc-list-item.js' +const requestQueue = new RequestQueueWithPromise(3) +const requestQueueRawData = new RequestQueueWithPromise(3) +const requestQueueStatus = new RequestQueueWithPromise(3) export class FeedItem extends connect(store)(LitElement) { - static get properties() { - return { - resource: { type: Object }, - isReady: { type: Boolean}, - status: {type: Object}, - feedItem: {type: Object}, - appName: {type: String}, - link: {type: String} - }; - } - - static get styles() { - return css` - * { - --mdc-theme-text-primary-on-background: var(--black); - box-sizing: border-box; - } - :host { - width: 100%; - box-sizing: border-box; - } - img { - width:100%; - max-height:30vh; - border-radius: 5px; - cursor: pointer; - position: relative; - } - .smallLoading, - .smallLoading:after { - border-radius: 50%; - width: 2px; - height: 2px; - } - - .smallLoading { - border-width: 0.8em; - border-style: solid; - border-color: rgba(3, 169, 244, 0.2) rgba(3, 169, 244, 0.2) - rgba(3, 169, 244, 0.2) rgb(3, 169, 244); - font-size: 30px; - position: relative; - text-indent: -9999em; - transform: translateZ(0px); - animation: 1.1s linear 0s infinite normal none running loadingAnimation; - } - - .defaultSize { - width: 100%; - height: 160px; - } - .parent-feed-item { - position: relative; - display: flex; - background-color: var(--chat-bubble-bg); - flex-grow: 0; - flex-direction: column; - align-items: flex-start; - justify-content: center; - border-radius: 5px; - padding: 12px 15px 4px 15px; - min-width: 150px; - width: 100%; - box-sizing: border-box; - cursor: pointer; - font-size: 16px; - } - .avatar { - width: 36px; - height: 36px; - border-radius:50%; - overflow: hidden; - display:flex; - align-items:center; - } - .avatarApp { - width: 30px; - height: 30px; - border-radius:50%; - overflow: hidden; - display:flex; - align-items:center; - } - .feed-item-name { - user-select: none; - color: #03a9f4; - margin-bottom: 5px; + static get properties() { + return { + resource: { type: Object }, + isReady: { type: Boolean }, + status: { type: Object }, + feedItem: { type: Object }, + appName: { type: String }, + link: { type: String } + } } - .app-name { - display: flex; - justify-content: space-between; - align-items: center; - width: 100%; - } + static get styles() { + return [feedItemStyles] + } - mwc-menu { - position: absolute; - } + constructor() { + super() + this.resource = { + identifier: "", + name: "", + service: "" + } + this.status = { + status: '' + } + this.isReady = false + this.nodeUrl = this.getNodeUrl() + this.myNode = this.getMyNode() + this.hasCalledWhenDownloaded = false + this.isFetching = false + this.uid = new ShortUniqueId() + this.observer = new IntersectionObserver(entries => { + for (const entry of entries) { + if (entry.isIntersecting && this.status.status !== 'READY') { + this._fetchImage() + // Stop observing after the image has started loading + this.observer.unobserve(this) + } + } + }) + this.feedItem = null + } + render() { + let avatarImg + const avatarUrl = `${this.nodeUrl}/arbitrary/THUMBNAIL/${this.resource.name}/qortal_avatar?async=true` + avatarImg = html`` + let avatarImgApp + const avatarUrl2 = `${this.nodeUrl}/arbitrary/THUMBNAIL/${this.appName}/qortal_avatar?async=true` + avatarImgApp = html`` + return html` +
    + ${this.status.status !== 'READY' ? + html` +
    +
    +

    + ${`${Math.round(this.status.percentLoaded || 0).toFixed(0)}% `}${translate('chatpage.cchange94')} +

    +
    + ` + : '' + } + ${this.status.status === 'READY' && this.feedItem ? + html` +
    +
    +
    ${avatarImg}
    + ${this.resource.name} +
    +
    +

    ${this.feedItem.title}

    +
    +
    +
    ${avatarImgApp}
    + +
    +
    + ` + : '' + } +
    + ` + } - @-webkit-keyframes loadingAnimation { - 0% { - -webkit-transform: rotate(0deg); - transform: rotate(0deg); - } - 100% { - -webkit-transform: rotate(360deg); - transform: rotate(360deg); - } - } + firstUpdated() { + this.observer.observe(this) + } - @keyframes loadingAnimation { - 0% { - -webkit-transform: rotate(0deg); - transform: rotate(0deg); - } - 100% { - -webkit-transform: rotate(360deg); - transform: rotate(360deg); - } - } - `; - } + getNodeUrl() { + const myNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node] + return myNode.protocol + '://' + myNode.domain + ':' + myNode.port + } - constructor() { - super(); - this.resource = { - identifier: "", - name: "", - service: "" - } - this.status = { - status: '' - } - this.isReady = false - this.nodeUrl = this.getNodeUrl() - this.myNode = this.getMyNode() - this.hasCalledWhenDownloaded = false - this.isFetching = false - this.uid = new ShortUniqueId() + getMyNode() { + return store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node] + } - this.observer = new IntersectionObserver(entries => { - for (const entry of entries) { - if (entry.isIntersecting && this.status.status !== 'READY') { - this._fetchImage(); - // Stop observing after the image has started loading - this.observer.unobserve(this); - } - } - }); - this.feedItem = null - } - getNodeUrl(){ - const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] + async fetchResource() { + try { + if (this.isFetching) return + this.isFetching = true + await axios.get(`${this.nodeUrl}/arbitrary/resource/properties/${this.resource.service}/${this.resource.name}/${this.resource.identifier}?apiKey=${this.myNode.apiKey}`) + this.isFetching = false - return myNode.protocol + '://' + myNode.domain + ':' + myNode.port -} -getMyNode(){ - return window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] -} + } catch (error) { + this.isFetching = false + } + } - getApiKey() { - const myNode = - window.parent.reduxStore.getState().app.nodeConfig.knownNodes[ - window.parent.reduxStore.getState().app.nodeConfig.node - ]; - return myNode.apiKey; - } + async fetchVideoUrl() { + await this.fetchResource() + } - async fetchResource() { - try { - if(this.isFetching) return - this.isFetching = true - await axios.get(`${this.nodeUrl}/arbitrary/resource/properties/${this.resource.service}/${this.resource.name}/${this.resource.identifier}?apiKey=${this.myNode.apiKey}`) - this.isFetching = false + async getRawData() { + const url = `${this.nodeUrl}/arbitrary/${this.resource.service}/${this.resource.name}/${this.resource.identifier}?apiKey=${this.myNode.apiKey}` - } catch (error) { - this.isFetching = false - } - } + return await requestQueueRawData.enqueue(() => { + return axios.get(url) + }) + } - async fetchVideoUrl() { + updateDisplayWithPlaceholders(display, resource, rawdata) { + const pattern = /\$\$\{([a-zA-Z0-9_\.]+)\}\$\$/g - await this.fetchResource() + for (const key in display) { + const value = display[key] - } + display[key] = value.replace(pattern, (match, p1) => { + if (p1.startsWith('rawdata.')) { + const dataKey = p1.split('.')[1] + if (rawdata[dataKey] === undefined) { + console.error("rawdata key not found:", dataKey) + } + return rawdata[dataKey] || match + } else if (p1.startsWith('resource.')) { + const resourceKey = p1.split('.')[1] + if (resource[resourceKey] === undefined) { + console.error("resource key not found:", resourceKey) + } + return resource[resourceKey] || match + } + return match + }) + } + } - async getRawData(){ - const url = `${this.nodeUrl}/arbitrary/${this.resource.service}/${this.resource.name}/${this.resource.identifier}?apiKey=${this.myNode.apiKey}` - return await requestQueueRawData.enqueue(()=> { - return axios.get(url) - }) - // const response2 = await fetch(url, { - // method: 'GET', - // headers: { - // 'Content-Type': 'application/json' - // } - // }) + async fetchStatus() { + let isCalling = false + let percentLoaded = 0 + let timer = 24 - // const responseData2 = await response2.json() - // return responseData2 - } + const response = await requestQueueStatus.enqueue(() => { + return axios.get(`${this.nodeUrl}/arbitrary/resource/status/${this.resource.service}/${this.resource.name}/${this.resource.identifier}?apiKey=${this.myNode.apiKey}`) + }) - updateDisplayWithPlaceholders(display, resource, rawdata) { - const pattern = /\$\$\{([a-zA-Z0-9_\.]+)\}\$\$/g; + if (response && response.data && response.data.status === 'READY') { + const rawData = await this.getRawData() - for (const key in display) { - const value = display[key]; + const object = { + ...this.resource.schema.display + } - display[key] = value.replace(pattern, (match, p1) => { - if (p1.startsWith('rawdata.')) { - const dataKey = p1.split('.')[1]; - if (rawdata[dataKey] === undefined) { - console.error("rawdata key not found:", dataKey); - } - return rawdata[dataKey] || match; - } else if (p1.startsWith('resource.')) { - const resourceKey = p1.split('.')[1]; - if (resource[resourceKey] === undefined) { - console.error("resource key not found:", resourceKey); - } - return resource[resourceKey] || match; - } - return match; - }); - } -} + this.updateDisplayWithPlaceholders(object, {}, rawData.data) + this.feedItem = object + this.status = response.data + return + } + const intervalId = setInterval(async () => { + if (isCalling) return + isCalling = true + const data = await requestQueue.enqueue(() => { + return axios.get(`${this.nodeUrl}/arbitrary/resource/status/${this.resource.service}/${this.resource.name}/${this.resource.identifier}?apiKey=${this.myNode.apiKey}`) + }) - async fetchStatus(){ - let isCalling = false - let percentLoaded = 0 - let timer = 24 - const response = await requestQueueStatus.enqueue(()=> { - return axios.get(`${this.nodeUrl}/arbitrary/resource/status/${this.resource.service}/${this.resource.name}/${this.resource.identifier}?apiKey=${this.myNode.apiKey}`) - }) - if(response && response.data && response.data.status === 'READY'){ - const rawData = await this.getRawData() - const object = { - ...this.resource.schema.display - } - this.updateDisplayWithPlaceholders(object, {},rawData.data) - this.feedItem = object - this.status = response.data + const res = data.data - return - } - const intervalId = setInterval(async () => { - if (isCalling) return - isCalling = true + isCalling = false + if (res.localChunkCount) { + if (res.percentLoaded) { + if (res.percentLoaded === percentLoaded && res.percentLoaded !== 100) { + timer = timer - 5 + } else { + timer = 24 + } + if (timer < 0) { + timer = 24 + isCalling = true + this.status = { + ...res, + status: 'REFETCHING' + } - const data = await requestQueue.enqueue(() => { - return axios.get(`${this.nodeUrl}/arbitrary/resource/status/${this.resource.service}/${this.resource.name}/${this.resource.identifier}?apiKey=${this.myNode.apiKey}`) - }); - const res = data.data + setTimeout(() => { + isCalling = false + this.fetchResource() + }, 25000) - isCalling = false - if (res.localChunkCount) { - if (res.percentLoaded) { - if ( - res.percentLoaded === percentLoaded && - res.percentLoaded !== 100 - ) { - timer = timer - 5 - } else { - timer = 24 - } - if (timer < 0) { - timer = 24 - isCalling = true - this.status = { - ...res, - status: 'REFETCHING' - } + return + } + percentLoaded = res.percentLoaded + } - setTimeout(() => { - isCalling = false - this.fetchResource() - }, 25000) - return - } - percentLoaded = res.percentLoaded - } + this.status = res - this.status = res - if(this.status.status === 'DOWNLOADED'){ - await this.fetchResource() - } - } + if (this.status.status === 'DOWNLOADED') { + await this.fetchResource() + } + } - // check if progress is 100% and clear interval if true - if (res.status === 'READY') { - const rawData = await this.getRawData() - const object = { - ...this.resource.schema.display - } - this.updateDisplayWithPlaceholders(object, {},rawData.data) - this.feedItem = object - clearInterval(intervalId) - this.status = res - this.isReady = true - } - }, 5000) // 1 second interval - } + // check if progress is 100% and clear interval if true + if (res.status === 'READY') { + const rawData = await this.getRawData() + const object = { + ...this.resource.schema.display + } + this.updateDisplayWithPlaceholders(object, {}, rawData.data) + this.feedItem = object + clearInterval(intervalId) + this.status = res + this.isReady = true + } + }, 5000) // 5 second interval + } - async _fetchImage() { - try { - await this.fetchVideoUrl() - await this.fetchStatus() - } catch (error) { /* empty */ } - } + async _fetchImage() { + try { + await this.fetchVideoUrl() + await this.fetchStatus() + } catch (error) { /* empty */ } + } - firstUpdated(){ - this.observer.observe(this); + async goToFeedLink() { + try { + let newQuery = this.link + if (newQuery.endsWith('/')) { + newQuery = newQuery.slice(0, -1) + } + const res = await this.extractComponents(newQuery) + if (!res) return + const { service, name, identifier, path } = res + let query = `?service=${service}` + if (name) { + query = query + `&name=${name}` + } + if (identifier) { + query = query + `&identifier=${identifier}` + } + if (path) { + query = query + `&path=${path}` + } - } - - - - async goToFeedLink(){ - try { - let newQuery = this.link - if (newQuery.endsWith('/')) { - newQuery = newQuery.slice(0, -1) - } - const res = await this.extractComponents(newQuery) - if (!res) return - const { service, name, identifier, path } = res - let query = `?service=${service}` - if (name) { - query = query + `&name=${name}` - } - if (identifier) { - query = query + `&identifier=${identifier}` - } - if (path) { - query = query + `&path=${path}` - } - - store.dispatch(setNewTab({ + store.dispatch(setNewTab({ url: `qdn/browser/index.html${query}`, id: this.uid.rnd(), myPlugObj: { @@ -373,137 +289,72 @@ getMyNode(){ "menus": [], "parent": false }, - openExisting: true + openExisting: true })) - } catch (error) { - console.log({error}) - } - } + } catch (error) { + console.log({ error }) + } + } + async extractComponents(url) { + if (!url.startsWith("qortal://")) { + return null + } + url = url.replace(/^(qortal\:\/\/)/, "") - async extractComponents(url) { - if (!url.startsWith("qortal://")) { - return null - } + if (url.includes("/")) { + let parts = url.split("/") + const service = parts[0].toUpperCase() + parts.shift() + const name = parts[0] + parts.shift() + let identifier - url = url.replace(/^(qortal\:\/\/)/, "") - if (url.includes("/")) { - let parts = url.split("/") - const service = parts[0].toUpperCase() - parts.shift() - const name = parts[0] - parts.shift() - let identifier + if (parts.length > 0) { + identifier = parts[0] // Do not shift yet + // Check if a resource exists with this service, name and identifier combination + const myNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node] + const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port + const url = `${nodeUrl}/arbitrary/resource/status/${service}/${name}/${identifier}?apiKey=${myNode.apiKey}}` - if (parts.length > 0) { - identifier = parts[0] // Do not shift yet - // Check if a resource exists with this service, name and identifier combination - const myNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node] - const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port - const url = `${nodeUrl}/arbitrary/resource/status/${service}/${name}/${identifier}?apiKey=${myNode.apiKey}}` + const res = await fetch(url); + const data = await res.json(); + if (data.totalChunkCount > 0) { + // Identifier exists, so don't include it in the path + parts.shift() + } + else { + identifier = null + } + } - const res = await fetch(url); - const data = await res.json(); - if (data.totalChunkCount > 0) { - // Identifier exists, so don't include it in the path - parts.shift() - } - else { - identifier = null - } - } + const path = parts.join("/") - const path = parts.join("/") + const components = {} + components["service"] = service + components["name"] = name + components["identifier"] = identifier + components["path"] = path + return components + } + return null + } - const components = {} - components["service"] = service - components["name"] = name - components["identifier"] = identifier - components["path"] = path - return components - } - return null + // Standard functions + getApiKey() { + const coreNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node] + return coreNode.apiKey + } + + isEmptyArray(arr) { + if (!arr) { return true } + return arr.length === 0 + } + + round(number) { + return (Math.round(parseFloat(number) * 1e8) / 1e8).toFixed(8) + } } - - - - - - - - render() { - let avatarImg - const avatarUrl = `${this.nodeUrl}/arbitrary/THUMBNAIL/${this.resource.name}/qortal_avatar?async=true&apiKey=${this.myNode.apiKey}`; - avatarImg = html``; - let avatarImgApp - const avatarUrl2 = `${this.nodeUrl}/arbitrary/THUMBNAIL/${this.appName}/qortal_avatar?async=true&apiKey=${this.myNode.apiKey}`; - avatarImgApp = html``; - return html` -
    - ${ - this.status.status !== 'READY' - ? html` -
    -
    -

    ${`${Math.round(this.status.percentLoaded || 0 - ).toFixed(0)}% `}${translate('chatpage.cchange94')}

    -
    - ` - : '' - } - ${this.status.status === 'READY' && this.feedItem ? html` -
    -
    -
    - ${avatarImg}
    ${this.resource.name} -
    -
    -

    ${this.feedItem.title}

    -
    -
    -
    - ${avatarImgApp} -
    - -
    -
    - ` : ''} - -
    - - ` - - - } -} - -customElements.define('feed-item', FeedItem); +window.customElements.define('feed-item', FeedItem) \ No newline at end of file diff --git a/core/src/components/friends-view/friend-item-actions.js b/core/src/components/friends-view/friend-item-actions.js index 06b1217a..1f57893c 100644 --- a/core/src/components/friends-view/friend-item-actions.js +++ b/core/src/components/friends-view/friend-item-actions.js @@ -1,146 +1,42 @@ -// popover-component.js -import {css, html, LitElement} from 'lit'; -import {createPopper} from '@popperjs/core'; -import '@material/mwc-icon'; -import {translate} from '../../../translate' -import {store} from '../../store'; -import {connect} from 'pwa-helpers'; -import {setNewTab, setSideEffectAction} from '../../redux/app/app-actions'; -import ShortUniqueId from 'short-unique-id'; +import { html, LitElement } from 'lit' +import { connect } from 'pwa-helpers' +import { store } from '../../store' +import { createPopper } from '@popperjs/core' +import { setNewTab, setSideEffectAction } from '../../redux/app/app-actions' +import { translate } from '../../../translate' +import { friendItemActionsStyles } from '../../styles/core-css' +import ShortUniqueId from 'short-unique-id' +import '@material/mwc-icon' export class FriendItemActions extends connect(store)(LitElement) { - static styles = css` - :host { - display: none; - position: absolute; - background-color: var(--white); - border: 1px solid #ddd; - padding: 8px; - z-index: 10; - box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); - color: var(--black); - max-width: 250px; - } - - .close-icon { - cursor: pointer; - float: right; - margin-left: 10px; - color: var(--black); - } - - .send-message-button { - font-family: Roboto, sans-serif; - letter-spacing: 0.3px; - font-weight: 300; - padding: 8px 5px; - border-radius: 3px; - text-align: center; - color: var(--mdc-theme-primary); - transition: all 0.3s ease-in-out; - display: flex; - align-items: center; - gap: 10px; - } - - .send-message-button:hover { - cursor: pointer; - background-color: #03a8f485; - } - .action-parent { - display: flex; - flex-direction: column; - width: 100%; - } - - div[tabindex='0']:focus { - outline: none; - } - `; - static get properties() { return { for: { type: String, reflect: true }, message: { type: String }, openEditFriend: { attribute: false }, name: { type: String }, - closeSidePanel: { attribute: false, type: Object }, - }; + closeSidePanel: { attribute: false, type: Object } + } + } + + static get styles() { + return [friendItemActionsStyles] } constructor() { - super(); - this.message = ''; - this.nodeUrl = this.getNodeUrl(); - this.uid = new ShortUniqueId(); - this.getUserAddress = this.getUserAddress.bind(this); - } - getNodeUrl() { - const myNode = - store.getState().app.nodeConfig.knownNodes[ - window.parent.reduxStore.getState().app.nodeConfig.node - ] - - return myNode.protocol + '://' + myNode.domain + ':' + myNode.port - } - - firstUpdated() { - // We'll defer the popper attachment to the openPopover() method to ensure target availability - } - - attachToTarget(target) { - if (!this.popperInstance && target) { - this.popperInstance = createPopper(target, this, { - placement: 'bottom', - }); - } - } - - openPopover(target) { - this.attachToTarget(target); - this.style.display = 'block'; - setTimeout(() => { - this.shadowRoot.getElementById('parent-div').focus(); - }, 50); - } - - closePopover() { - this.style.display = 'none'; - if (this.popperInstance) { - this.popperInstance.destroy(); - this.popperInstance = null; - } - this.requestUpdate(); - } - handleBlur() { - setTimeout(() => { - this.closePopover(); - }, 0); - } - - async getUserAddress() { - try { - const url = `${this.nodeUrl}/names/${this.name}`; - const res = await fetch(url); - const result = await res.json(); - if (result.error === 401) { - return ''; - } else { - return result.owner; - } - } catch (error) { - return ''; - } + super() + this.message = '' + this.nodeUrl = this.getNodeUrl() + this.uid = new ShortUniqueId() + this.getUserAddress = this.getUserAddress.bind(this) } render() { return html`
    - close + + close +
    - person + person ${translate('profile.profile18')}
    - `; + ` + } + + firstUpdated() { + // ... + } + + getNodeUrl() { + const myNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node] + return myNode.protocol + '://' + myNode.domain + ':' + myNode.port + } + + attachToTarget(target) { + if (!this.popperInstance && target) { + this.popperInstance = createPopper(target, this, { + placement: 'bottom' + }) + } + } + + openPopover(target) { + this.attachToTarget(target) + this.style.display = 'block' + setTimeout(() => { + this.shadowRoot.getElementById('parent-div').focus() + }, 50) + } + + closePopover() { + this.style.display = 'none' + if (this.popperInstance) { + this.popperInstance.destroy() + this.popperInstance = null + } + this.requestUpdate() + } + + handleBlur() { + setTimeout(() => { + this.closePopover() + }, 0) + } + + async getUserAddress() { + try { + const url = `${this.nodeUrl}/names/${this.name}` + const res = await fetch(url) + const result = await res.json() + if (result.error === 401) { + return '' + } else { + return result.owner + } + } catch (error) { + return '' + } + } + + // Standard functions + getApiKey() { + const coreNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node] + return coreNode.apiKey + } + + isEmptyArray(arr) { + if (!arr) { return true } + return arr.length === 0 + } + + round(number) { + return (Math.round(parseFloat(number) * 1e8) / 1e8).toFixed(8) } } -customElements.define('friend-item-actions', FriendItemActions); +window.customElements.define('friend-item-actions', FriendItemActions) diff --git a/core/src/components/friends-view/friends-feed.js b/core/src/components/friends-view/friends-feed.js index 597fa8e1..b20a18e2 100644 --- a/core/src/components/friends-view/friends-feed.js +++ b/core/src/components/friends-view/friends-feed.js @@ -1,476 +1,461 @@ -import {html, LitElement} from 'lit'; -import '@material/mwc-icon'; -import './friends-view' -import {friendsViewStyles} from './friends-view-css'; -import {connect} from 'pwa-helpers'; -import {store} from '../../store'; +import { html, LitElement } from 'lit' +import { store } from '../../store' +import { connect } from 'pwa-helpers' +import { translate } from '../../../translate' +import { friendsViewStyles } from '../../styles/core-css' import './feed-item' -import {translate} from '../../../translate' - +import './friends-view' +import '@material/mwc-icon' import '@polymer/paper-spinner/paper-spinner-lite.js' +const perEndpointCount = 20 +const totalDesiredCount = 100 +const maxResultsInMemory = 300 -const perEndpointCount = 20; -const totalDesiredCount = 100; -const maxResultsInMemory = 300; class FriendsFeed extends connect(store)(LitElement) { - static get properties() { + static get properties() { return { - feed: {type: Array}, - setHasNewFeed: {attribute:false}, - isLoading: {type: Boolean}, - hasFetched: {type: Boolean}, - mySelectedFeeds: {type: Array} - }; - } - constructor(){ - super() - this.feed = [] - this.feedToRender = [] - this.nodeUrl = this.getNodeUrl(); - this.myNode = this.getMyNode(); - this.endpoints = [] - this.endpointOffsets = [] // Initialize offsets for each endpoint to 0 - - this.loadAndMergeData = this.loadAndMergeData.bind(this) - this.hasInitialFetch = false - this.observerHandler = this.observerHandler.bind(this); - this.elementObserver = this.elementObserver.bind(this) - this.mySelectedFeeds = [] - this.getSchemas = this.getSchemas.bind(this) - this.hasFetched = false - this._updateFeeds = this._updateFeeds.bind(this) - + feed: { type: Array }, + setHasNewFeed: { attribute: false }, + isLoading: { type: Boolean }, + hasFetched: { type: Boolean }, + mySelectedFeeds: { type: Array } + } } static get styles() { - return [friendsViewStyles]; + return [friendsViewStyles] + } + + constructor() { + super() + this.feed = [] + this.feedToRender = [] + this.nodeUrl = this.getNodeUrl() + this.myNode = this.getMyNode() + this.endpoints = [] + this.endpointOffsets = [] // Initialize offsets for each endpoint to 0 + this.loadAndMergeData = this.loadAndMergeData.bind(this) + this.hasInitialFetch = false + this.observerHandler = this.observerHandler.bind(this) + this.elementObserver = this.elementObserver.bind(this) + this.mySelectedFeeds = [] + this.getSchemas = this.getSchemas.bind(this) + this.hasFetched = false + this._updateFeeds = this._updateFeeds.bind(this) + } + + render() { + return html` +
    +
    + ${this.isLoading ? html` +
    + +
    + ` : ''} + ${this.hasFetched && !this.isLoading && this.feed.length === 0 ? html` +
    +

    ${translate('friends.friend17')}

    +
    + ` : ''} + ${this.feedToRender.map((item) => { + return html` + + + ` + })} +
    +
    +
    + ` } + async firstUpdated() { + this.viewElement = this.shadowRoot.getElementById('viewElement') + this.downObserverElement = this.shadowRoot.getElementById('downObserver') + this.elementObserver() + + try { + await new Promise((res) => { + setTimeout(() => { + res() + }, 5000) + }) + + if (this.mySelectedFeeds.length === 0) { + await this.getEndpoints() + await this.loadAndMergeData() + } + + this.getFeedOnInterval() + } catch (error) { + console.log(error) + } + } getNodeUrl() { - const myNode = - store.getState().app.nodeConfig.knownNodes[ - window.parent.reduxStore.getState().app.nodeConfig.node - ] - + const myNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node] return myNode.protocol + '://' + myNode.domain + ':' + myNode.port } + getMyNode() { - return store.getState().app.nodeConfig.knownNodes[ - window.parent.reduxStore.getState().app.nodeConfig.node - ] + return store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node] } - _updateFeeds(event) { + _updateFeeds(event) { this.mySelectedFeeds = event.detail - this.reFetchFeedData() - this.requestUpdate() + this.reFetchFeedData() + this.requestUpdate() } connectedCallback() { super.connectedCallback() - window.addEventListener('friends-my-selected-feeds-event', this._updateFeeds) } + window.addEventListener('friends-my-selected-feeds-event', this._updateFeeds) + } disconnectedCallback() { window.removeEventListener('friends-my-selected-feeds-event', this._updateFeeds) super.disconnectedCallback() } - async getSchemas(){ - this.mySelectedFeeds = JSON.parse(localStorage.getItem('friends-my-selected-feeds') || "[]") - const schemas = this.mySelectedFeeds - const getAllSchemas = (schemas || []).map( - async (schema) => { - try { - const url = `${this.nodeUrl}/arbitrary/${schema.service}/${schema.name}/${schema.identifier}`; - const res = await fetch(url) - const data = await res.json() - if(data.error) return false - return data - } catch (error) { - console.log(error); - return false - } - } - ); - const res = await Promise.all(getAllSchemas); - return res.filter((item)=> !!item) - } + async getSchemas() { + this.mySelectedFeeds = JSON.parse(localStorage.getItem('friends-my-selected-feeds') || "[]") + const schemas = this.mySelectedFeeds - getFeedOnInterval(){ - let interval = null; - let stop = false; - const getAnswer = async () => { - - if (!stop) { - stop = true; + const getAllSchemas = (schemas || []).map( + async (schema) => { try { - await this.reFetchFeedData() - } catch (error) {} - stop = false; + const url = `${this.nodeUrl}/arbitrary/${schema.service}/${schema.name}/${schema.identifier}` + const res = await fetch(url) + const data = await res.json() + if (data.error) return false + return data + } catch (error) { + console.log(error) + return false + } } - }; - interval = setInterval(getAnswer, 900000); + ) - } - - async getEndpoints(){ - const dynamicVars = { - - } - const schemas = await this.getSchemas() - const friendList = JSON.parse(localStorage.getItem('friends-my-friend-list') || "[]") - const names = friendList.map(friend => `name=${friend.name}`).join('&'); - if(names.length === 0){ - this.endpoints= [] - this.endpointOffsets = Array(this.endpoints.length).fill(0); - return - } - const baseurl = `${this.nodeUrl}/arbitrary/resources/search?reverse=true&mode=ALL&exactmatchnames=true&${names}` - let formEndpoints = [] - schemas.forEach((schema)=> { - const feedData = schema.feed[0] - if(feedData){ - const copyFeedData = {...feedData} - const fullUrl = constructUrl(baseurl, copyFeedData.search, dynamicVars); - if(fullUrl){ - formEndpoints.push({ - url: fullUrl, schemaName: schema.name, schema: copyFeedData - }) - } - } - - - }) - this.endpoints= formEndpoints - this.endpointOffsets = Array(this.endpoints.length).fill(0); - } - - async firstUpdated(){ - this.viewElement = this.shadowRoot.getElementById('viewElement'); - this.downObserverElement = - this.shadowRoot.getElementById('downObserver'); - this.elementObserver(); - - - try { - await new Promise((res)=> { - setTimeout(() => { - res() - }, 5000); - }) - if(this.mySelectedFeeds.length === 0){ - await this.getEndpoints() - -await this.loadAndMergeData(); - } - -this.getFeedOnInterval() - - } catch (error) { - console.log(error) - } + const res = await Promise.all(getAllSchemas) + return res.filter((item) => !!item) } - getMoreFeed(){ - if(!this.hasInitialFetch) return - if(this.feedToRender.length === this.feed.length ) return - this.feedToRender = this.feed.slice(0, this.feedToRender.length + 20) - this.requestUpdate() - } + getFeedOnInterval() { + let interval = null + let stop = false - async refresh(){ - try { - await this.getEndpoints() - await this.reFetchFeedData() - } catch (error) { + const getAnswer = async () => { + if (!stop) { + stop = true + try { + await this.reFetchFeedData() + } catch (error) { } + stop = false + } + } - } - } + interval = setInterval(getAnswer, 900000) + } + async getEndpoints() { + const dynamicVars = { } + const schemas = await this.getSchemas() + const friendList = JSON.parse(localStorage.getItem('friends-my-friend-list') || "[]") + const names = friendList.map(friend => `name=${friend.name}`).join('&') + + if (names.length === 0) { + this.endpoints = [] + this.endpointOffsets = Array(this.endpoints.length).fill(0) + return + } + + const baseurl = `${this.nodeUrl}/arbitrary/resources/search?reverse=true&mode=ALL&exactmatchnames=true&${names}` + let formEndpoints = [] + + schemas.forEach((schema) => { + const feedData = schema.feed[0] + if (feedData) { + const copyFeedData = { ...feedData } + const fullUrl = constructUrl(baseurl, copyFeedData.search, dynamicVars) + if (fullUrl) { + formEndpoints.push({ + url: fullUrl, schemaName: schema.name, schema: copyFeedData + }) + } + } + }) + + this.endpoints = formEndpoints + this.endpointOffsets = Array(this.endpoints.length).fill(0) + } + + getMoreFeed() { + if (!this.hasInitialFetch) return + if (this.feedToRender.length === this.feed.length) return + this.feedToRender = this.feed.slice(0, this.feedToRender.length + 20) + this.requestUpdate() + } + + async refresh() { + try { + await this.getEndpoints() + await this.reFetchFeedData() + } catch (error) { + + } + } elementObserver() { const options = { rootMargin: '0px', - threshold: 1, - }; + threshold: 1 + } + // identify an element to observe - const elementToObserve = this.downObserverElement; + const elementToObserve = this.downObserverElement + // passing it a callback function const observer = new IntersectionObserver( this.observerHandler, options - ); + ) + // call `observe()` on that MutationObserver instance, // passing it the element to observe, and the options object - observer.observe(elementToObserve); + observer.observe(elementToObserve) } observerHandler(entries) { if (!entries[0].isIntersecting) { - } else { if (this.feedToRender.length < 20) { - return; + return } - this.getMoreFeed(); + this.getMoreFeed() } } - async fetchDataFromEndpoint(endpointIndex, count) { - const offset = this.endpointOffsets[endpointIndex]; - const url = `${this.endpoints[endpointIndex].url}&limit=${count}&offset=${offset}`; - const res = await fetch(url) - const data = await res.json() - return data.map((i)=> { - return { - ...this.endpoints[endpointIndex], - ...i - } - }) + async fetchDataFromEndpoint(endpointIndex, count) { + const offset = this.endpointOffsets[endpointIndex] + const url = `${this.endpoints[endpointIndex].url}&limit=${count}&offset=${offset}` + const res = await fetch(url) + const data = await res.json() - } + return data.map((i) => { + return { + ...this.endpoints[endpointIndex], + ...i + } + }) + } + async initialLoad() { + let results = [] + let totalFetched = 0 + let i = 0 + let madeProgress = true + let exhaustedEndpoints = new Set() - async initialLoad() { - let results = []; - let totalFetched = 0; - let i = 0; - let madeProgress = true; - let exhaustedEndpoints = new Set(); + while (totalFetched < totalDesiredCount && madeProgress) { + madeProgress = false + this.isLoading = true + for (i = 0; i < this.endpoints.length; i++) { + if (exhaustedEndpoints.has(i)) { + continue + } - while (totalFetched < totalDesiredCount && madeProgress) { - madeProgress = false; - this.isLoading = true - for (i = 0; i < this.endpoints.length; i++) { - if (exhaustedEndpoints.has(i)) { - continue; - } + const remainingCount = totalDesiredCount - totalFetched - const remainingCount = totalDesiredCount - totalFetched; + // If we've already reached the desired count, break + if (remainingCount <= 0) { + break; + } - // If we've already reached the desired count, break - if (remainingCount <= 0) { - break; - } + let fetchCount = Math.min(perEndpointCount, remainingCount) + let data = await this.fetchDataFromEndpoint(i, fetchCount) - let fetchCount = Math.min(perEndpointCount, remainingCount); - let data = await this.fetchDataFromEndpoint(i, fetchCount); + // Increment the offset for this endpoint by the number of items fetched + this.endpointOffsets[i] += data.length - // Increment the offset for this endpoint by the number of items fetched - this.endpointOffsets[i] += data.length; + if (data.length > 0) { + madeProgress = true + } - if (data.length > 0) { - madeProgress = true; - } + if (data.length < fetchCount) { + exhaustedEndpoints.add(i) + } - if (data.length < fetchCount) { - exhaustedEndpoints.add(i); - } + results = results.concat(data) + totalFetched += data.length + } - results = results.concat(data); - totalFetched += data.length; - } + if (exhaustedEndpoints.size === this.endpoints.length) { + break + } + } - if (exhaustedEndpoints.size === this.endpoints.length) { - break; - } - } - this.isLoading = false - this.hasFetched = true; - // Trim the results if somehow they are over the totalDesiredCount - return results.slice(0, totalDesiredCount); - } + this.isLoading = false + this.hasFetched = true + // Trim the results if somehow they are over the totalDesiredCount + return results.slice(0, totalDesiredCount) + } + trimDataToLimit(data, limit) { + return data.slice(0, limit) + } + mergeData(newData, existingData) { + const existingIds = new Set(existingData.map(item => item.identifier)) // Assume each item has a unique 'id' + const uniqueNewData = newData.filter(item => !existingIds.has(item.identifier)) + return uniqueNewData.concat(existingData) + } + async addExtraData(data) { + let newData = [] + for (let item of data) { + let newItem = { + ...item, + schema: { + ...item.schema, + customParams: { ...item.schema.customParams } - trimDataToLimit(data, limit) { - return data.slice(0, limit); - } + } + } - mergeData(newData, existingData) { - const existingIds = new Set(existingData.map(item => item.identifier)); // Assume each item has a unique 'id' - const uniqueNewData = newData.filter(item => !existingIds.has(item.identifier)); - return uniqueNewData.concat(existingData); - } + let newResource = { + identifier: newItem.identifier, + service: newItem.service, + name: newItem.name + } + if (newItem.schema) { + const resource = newItem - async addExtraData(data){ - let newData = [] - for (let item of data) { - let newItem = { - ...item, - schema: { - ...item.schema, - customParams: {...item.schema.customParams} - - } - } - let newResource = { - identifier: newItem.identifier, - service: newItem.service, - name: newItem.name - } - if(newItem.schema){ - const resource = newItem - - let clickValue1 = newItem.schema.click; + let clickValue1 = newItem.schema.click; newItem.link = replacePlaceholders(clickValue1, resource, newItem.schema.customParams) - newData.push(newItem) - } - } - return newData + newData.push(newItem) + } + } + return newData + } - } - async reFetchFeedData() { - // Resetting offsets to start fresh. - this.endpointOffsets = Array(this.endpoints.length).fill(0); - await this.getEndpoints() - const oldIdentifiers = new Set(this.feed.map(item => item.identifier)); - const newData = await this.initialLoad(); + async reFetchFeedData() { + // Resetting offsets to start fresh. + this.endpointOffsets = Array(this.endpoints.length).fill(0) + await this.getEndpoints() + const oldIdentifiers = new Set(this.feed.map(item => item.identifier)) + const newData = await this.initialLoad() - // Filter out items that are already in the feed - const trulyNewData = newData.filter(item => !oldIdentifiers.has(item.identifier)); + // Filter out items that are already in the feed + const trulyNewData = newData.filter(item => !oldIdentifiers.has(item.identifier)) - if (trulyNewData.length > 0) { - // Adding extra data and merging with old data - const enhancedNewData = await this.addExtraData(trulyNewData); + if (trulyNewData.length > 0) { + // Adding extra data and merging with old data + const enhancedNewData = await this.addExtraData(trulyNewData) - // Merge new data with old data immutably - this.feed = [...enhancedNewData, ...this.feed]; - this.feed = this.removeDuplicates(this.feed) - this.feed.sort((a, b) => new Date(b.created) - new Date(a.created)); // Sort by timestamp, most recent first - this.feed = this.trimDataToLimit(this.feed, maxResultsInMemory); // Trim to the maximum allowed in memory - this.feedToRender = this.feed.slice(0, 20); - this.hasInitialFetch = true; + // Merge new data with old data immutably + this.feed = [...enhancedNewData, ...this.feed] + this.feed = this.removeDuplicates(this.feed) + this.feed.sort((a, b) => new Date(b.created) - new Date(a.created)) // Sort by timestamp, most recent first + this.feed = this.trimDataToLimit(this.feed, maxResultsInMemory) // Trim to the maximum allowed in memory + this.feedToRender = this.feed.slice(0, 20) + this.hasInitialFetch = true - const created = trulyNewData[0].created; - let value = localStorage.getItem('lastSeenFeed'); - if (((+value || 0) < created)) { - this.setHasNewFeed(true); - } - } - } - - - removeDuplicates(array) { - const seenIds = new Set(); - return array.filter(item => { - if (!seenIds.has(item.identifier)) { - seenIds.add(item.identifier); - return true; - } - return false; - }); - } - - - async loadAndMergeData() { - let allData = this.feed - const newData = await this.initialLoad(); - allData = await this.addExtraData(newData) - allData = this.mergeData(newData, allData); - allData.sort((a, b) => new Date(b.created) - new Date(a.created)); // Sort by timestamp, most recent first - allData = this.trimDataToLimit(allData, maxResultsInMemory); // Trim to the maximum allowed in memory - allData = this.removeDuplicates(allData) - this.feed = [...allData] - this.feedToRender = this.feed.slice(0,20) - this.hasInitialFetch = true - if(allData.length > 0){ - const created = allData[0].created - let value = localStorage.getItem('lastSeenFeed') + const created = trulyNewData[0].created + let value = localStorage.getItem('lastSeenFeed') if (((+value || 0) < created)) { this.setHasNewFeed(true) } - } - } - - - - - - render() { - return html` -
    -
    - ${this.isLoading ? html` -
    - -
    - ` : ''} - ${this.hasFetched && !this.isLoading && this.feed.length === 0 ? html` -
    -

    ${translate('friends.friend17')}

    -
    - ` : ''} - ${this.feedToRender.map((item) => { - return html``; - })} -
    -
    -
    - `; + } } + removeDuplicates(array) { + const seenIds = new Set() + return array.filter(item => { + if (!seenIds.has(item.identifier)) { + seenIds.add(item.identifier) + return true + } + return false + }) + } + + async loadAndMergeData() { + let allData = this.feed + const newData = await this.initialLoad(); + allData = await this.addExtraData(newData) + allData = this.mergeData(newData, allData); + allData.sort((a, b) => new Date(b.created) - new Date(a.created)); // Sort by timestamp, most recent first + allData = this.trimDataToLimit(allData, maxResultsInMemory); // Trim to the maximum allowed in memory + allData = this.removeDuplicates(allData) + this.feed = [...allData] + this.feedToRender = this.feed.slice(0, 20) + this.hasInitialFetch = true + if (allData.length > 0) { + const created = allData[0].created + let value = localStorage.getItem('lastSeenFeed') + if (((+value || 0) < created)) { + this.setHasNewFeed(true) + } + } + } + + // Standard functions + getApiKey() { + const coreNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node] + return coreNode.apiKey + } + + isEmptyArray(arr) { + if (!arr) { return true } + return arr.length === 0 + } + + round(number) { + return (Math.round(parseFloat(number) * 1e8) / 1e8).toFixed(8) + } } -customElements.define('friends-feed', FriendsFeed); +window.customElements.define('friends-feed', FriendsFeed) export function substituteDynamicVar(value, dynamicVars) { - if (typeof value !== 'string') return value; - - const pattern = /\$\$\{([a-zA-Z0-9_]+)\}\$\$/g; // Adjusted pattern to capture $${name}$$ with curly braces - - return value.replace(pattern, (match, p1) => { - return dynamicVars[p1] !== undefined ? dynamicVars[p1] : match; - }); + if (typeof value !== 'string') return value + const pattern = /\$\$\{([a-zA-Z0-9_]+)\}\$\$/g // Adjusted pattern to capture $${name}$$ with curly braces + return value.replace(pattern, (match, p1) => { + return dynamicVars[p1] !== undefined ? dynamicVars[p1] : match + }) } export function constructUrl(base, search, dynamicVars) { - let queryStrings = []; - - for (const [key, value] of Object.entries(search)) { - const substitutedValue = substituteDynamicVar(value, dynamicVars); - queryStrings.push(`${key}=${encodeURIComponent(substitutedValue)}`); - } - - return queryStrings.length > 0 ? `${base}&${queryStrings.join('&')}` : base; + let queryStrings = [] + for (const [key, value] of Object.entries(search)) { + const substitutedValue = substituteDynamicVar(value, dynamicVars) + queryStrings.push(`${key}=${encodeURIComponent(substitutedValue)}`) + } + return queryStrings.length > 0 ? `${base}&${queryStrings.join('&')}` : base } - - - - - - - export function replacePlaceholders(template, resource, customParams) { - const dataSource = { resource, customParams }; - - return template.replace(/\$\$\{(.*?)\}\$\$/g, (match, p1) => { - const keys = p1.split('.'); - let value = dataSource; - - for (let key of keys) { - if (value[key] !== undefined) { - value = value[key]; - } else { - return match; // Return placeholder unchanged - } - } - return value; - }); -} - - - - + const dataSource = { resource, customParams } + return template.replace(/\$\$\{(.*?)\}\$\$/g, (match, p1) => { + const keys = p1.split('.') + let value = dataSource + for (let key of keys) { + if (value[key] !== undefined) { + value = value[key] + } else { + return match // Return placeholder unchanged + } + } + return value + }) +} \ No newline at end of file diff --git a/core/src/components/friends-view/friends-side-panel-parent.js b/core/src/components/friends-view/friends-side-panel-parent.js index 42984e65..1af1c69e 100644 --- a/core/src/components/friends-view/friends-side-panel-parent.js +++ b/core/src/components/friends-view/friends-side-panel-parent.js @@ -1,68 +1,43 @@ -import {css, html, LitElement} from 'lit' +import { html, LitElement } from 'lit' +import { connect } from 'pwa-helpers' +import { store } from '../../store' +import { translate } from '../../../translate' +import { friendsSidePanelParentStyles } from '../../styles/core-css' +import './friends-side-panel' import '@material/mwc-icon' -import './friends-side-panel.js' import '@vaadin/tooltip' -import {translate} from '../../../translate' -class FriendsSidePanelParent extends LitElement { +class FriendsSidePanelParent extends connect(store)(LitElement) { static get properties() { return { - isOpen: {type: Boolean}, - hasNewFeed: {type: Boolean} + isOpen: { type: Boolean }, + hasNewFeed: { type: Boolean } } } + static get styles() { + return [friendsSidePanelParentStyles] + } + constructor() { super() this.isOpen = false this.hasNewFeed = false } - static styles = css` - .header { - display: flex; - align-items: center; - justify-content: space-between; - padding: 16px; - border-bottom: 1px solid #e0e0e0; - } - - .content { - padding: 16px; - } - .close { - visibility: hidden; - position: fixed; - z-index: -100; - right: -1000px; - } - - .parent-side-panel { - transform: translateX(100%); /* start from outside the right edge */ - transition: transform 0.3s ease-in-out; - } - .parent-side-panel.open { - transform: translateX(0); /* slide in to its original position */ - - } - ` - - setHasNewFeed(val){ - this.hasNewFeed = val - } - render() { return html` { + @click=${() => { this.isOpen = !this.isOpen - if(this.isOpen && this.hasNewFeed) { + if (this.isOpen && this.hasNewFeed) { localStorage.setItem('lastSeenFeed', Date.now()) this.hasNewFeed = false this.shadowRoot.querySelector("friends-side-panel").selected = 'feed' } - }} style="color: ${this.hasNewFeed ? 'green' : 'var(--black)'}; cursor:pointer;user-select:none" + }} + style="color: ${this.hasNewFeed ? 'green' : 'var(--black)'}; cursor:pointer;user-select:none" > group @@ -72,12 +47,33 @@ class FriendsSidePanelParent extends LitElement { hover-delay=${400} hide-delay=${1} text=${translate('friends.friend12')} - > - - this.setHasNewFeed(val)} ?isOpen=${this.isOpen} .setIsOpen=${(val)=> this.isOpen = val}> - + > + this.setHasNewFeed(val)} ?isOpen=${this.isOpen} .setIsOpen=${(val) => this.isOpen = val}> ` } + + firstUpdated() { + // ... + } + + setHasNewFeed(val) { + this.hasNewFeed = val + } + + // Standard functions + getApiKey() { + const coreNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node] + return coreNode.apiKey + } + + isEmptyArray(arr) { + if (!arr) { return true } + return arr.length === 0 + } + + round(number) { + return (Math.round(parseFloat(number) * 1e8) / 1e8).toFixed(8) + } } -customElements.define('friends-side-panel-parent', FriendsSidePanelParent) +window.customElements.define('friends-side-panel-parent', FriendsSidePanelParent) \ No newline at end of file diff --git a/core/src/components/friends-view/friends-side-panel.js b/core/src/components/friends-view/friends-side-panel.js index 3e4a0370..11485887 100644 --- a/core/src/components/friends-view/friends-side-panel.js +++ b/core/src/components/friends-view/friends-side-panel.js @@ -1,158 +1,94 @@ -import {css, html, LitElement} from 'lit'; -import '@material/mwc-icon'; +import { html, LitElement } from 'lit' +import { connect } from 'pwa-helpers' +import { store } from '../../store' +import { translate } from '../../../translate' +import { friendsSidePanelStyles } from '../../styles/core-css' import './friends-view' import './friends-feed' -import {translate} from '../../../translate' +import '@material/mwc-icon' -class FriendsSidePanel extends LitElement { - static get properties() { +class FriendsSidePanel extends connect(store)(LitElement) { + static get properties() { return { - setIsOpen: { attribute: false}, - isOpen: {type: Boolean}, - selected: {type: String}, - setHasNewFeed: {attribute: false}, - closeSidePanel: {attribute: false, type: Object}, - openSidePanel: {attribute: false, type: Object} - }; + setIsOpen: { attribute: false }, + isOpen: { type: Boolean }, + selected: { type: String }, + setHasNewFeed: { attribute: false }, + closeSidePanel: { attribute: false, type: Object }, + openSidePanel: { attribute: false, type: Object } + } } - constructor(){ + static get styles() { + return [friendsSidePanelStyles] + } + + constructor() { super() this.selected = 'friends' this.closeSidePanel = this.closeSidePanel.bind(this) this.openSidePanel = this.openSidePanel.bind(this) - - } - - static styles = css` - :host { - display: block; - position: fixed; - top: 55px; - right: 0px; - width: 420px; - max-width: 95%; - height: calc(100vh - 55px); - background-color: var(--white); - border-left: 1px solid rgb(224, 224, 224); - z-index: 1; - transform: translateX(100%); /* start from outside the right edge */ - transition: transform 0.3s ease-in-out; - } - :host([isOpen]) { - transform: unset; /* slide in to its original position */ - } - - .header { - display: flex; - align-items: center; - justify-content: space-between; - padding: 16px; - border-bottom: 1px solid #e0e0e0; - } - - .content { - padding: 16px; - display: flex; - flex-direction: column; - flex-grow: 1; - overflow: auto; - } - .content::-webkit-scrollbar-track { - background-color: whitesmoke; - border-radius: 7px; - } - - .content::-webkit-scrollbar { - width: 12px; - border-radius: 7px; - background-color: whitesmoke; - } - - .content::-webkit-scrollbar-thumb { - background-color: rgb(180, 176, 176); - border-radius: 7px; - transition: all 0.3s ease-in-out; - } - .parent { - display: flex; - flex-direction: column; - height: 100%; - } - - .active { - font-size: 16px; - background: var(--black); - color: var(--white); - padding: 5px; - border-radius: 2px; - cursor: pointer; - } - - .default { - font-size: 16px; - color: var(--black); - padding: 5px; - border-radius: 2px; - cursor: pointer; - } - - .default-content { - visibility: hidden; - position: absolute; - z-index: -50; - } - - `; - - refreshFeed(){ - - this.shadowRoot.querySelector('friends-feed').refresh() - - - } - - closeSidePanel(){ - this.setIsOpen(false) - } - openSidePanel(){ - this.setIsOpen(true) } render() { return html`
    -
    -
    - this.selected = 'friends'} class="${this.selected === 'friends' ? 'active' : 'default'}">${translate('friends.friend12')} - this.selected = 'feed'} class="${this.selected === 'feed' ? 'active' : 'default'}">${translate('friends.friend13')} -
    -
    - { - this.refreshFeed() - }} style="color: var(--black); cursor:pointer;">refresh - { - this.setIsOpen(false) - }}>close -
    - -
    -
    -
    - this.refreshFeed()}> +
    +
    + this.selected = 'friends'} class="${this.selected === 'friends' ? 'active' : 'default'}">${translate('friends.friend12')} + this.selected = 'feed'} class="${this.selected === 'feed' ? 'active' : 'default'}">${translate('friends.friend13')} +
    +
    + { this.refreshFeed(); }} style="color: var(--black); cursor:pointer;"> + refresh + + { this.setIsOpen(false); }}> + close + +
    -
    - this.setHasNewFeed(val)}> +
    +
    + this.refreshFeed()}> +
    +
    + this.setHasNewFeed(val)}> +
    - - - -
    -
    - `; + ` } + firstUpdated() { + // ... + } + + refreshFeed() { + this.shadowRoot.querySelector('friends-feed').refresh() + } + + closeSidePanel() { + this.setIsOpen(false) + } + + openSidePanel() { + this.setIsOpen(true) + } + + // Standard functions + getApiKey() { + const coreNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node] + return coreNode.apiKey + } + + isEmptyArray(arr) { + if (!arr) { return true } + return arr.length === 0 + } + + round(number) { + return (Math.round(parseFloat(number) * 1e8) / 1e8).toFixed(8) + } } -customElements.define('friends-side-panel', FriendsSidePanel); +window.customElements.define('friends-side-panel', FriendsSidePanel) \ No newline at end of file diff --git a/core/src/components/friends-view/friends-view-css.js b/core/src/components/friends-view/friends-view-css.js deleted file mode 100644 index aa3aa5be..00000000 --- a/core/src/components/friends-view/friends-view-css.js +++ /dev/null @@ -1,182 +0,0 @@ -import {css} from 'lit' - -export const friendsViewStyles = css` -* { - box-sizing: border-box; -} - .top-bar-icon { - cursor: pointer; - height: 18px; - width: 18px; - transition: 0.2s all; - } - - .top-bar-icon:hover { - color: var(--black); - } - - .modal-button { - font-family: Roboto, sans-serif; - font-size: 16px; - color: var(--mdc-theme-primary); - background-color: transparent; - padding: 8px 10px; - border-radius: 5px; - border: none; - transition: all 0.3s ease-in-out; - } - - .close-row { - width: 100%; - display: flex; - justify-content: flex-end; - height: 50px; - flex:0 - - } - - .container-body { - width: 100%; - display: flex; - flex-direction: column; - flex-grow: 1; - margin-top: 5px; - padding: 0px 6px; - box-sizing: border-box; - align-items: center; - gap: 10px; - } - - .container-body::-webkit-scrollbar-track { - background-color: whitesmoke; - border-radius: 7px; - } - - .container-body::-webkit-scrollbar { - width: 6px; - border-radius: 7px; - background-color: whitesmoke; - } - - .container-body::-webkit-scrollbar-thumb { - background-color: rgb(180, 176, 176); - border-radius: 7px; - transition: all 0.3s ease-in-out; - } - - .container-body::-webkit-scrollbar-thumb:hover { - background-color: rgb(148, 146, 146); - cursor: pointer; - } - - p { - color: var(--black); - margin: 0px; - padding: 0px; - word-break: break-all; - } - - .container { - display: flex; - width: 100%; - flex-direction: column; - height: 100%; - } - - .chat-right-panel-label { - font-family: Montserrat, sans-serif; - color: var(--group-header); - padding: 5px; - font-size: 13px; - user-select: none; - } - - .group-info { - display: flex; - flex-direction: column; - justify-content: flex-start; - gap: 10px; - } - - .group-name { - font-family: Raleway, sans-serif; - font-size: 20px; - color: var(--chat-bubble-msg-color); - text-align: center; - user-select: none; - } - - .group-description { - font-family: Roboto, sans-serif; - color: var(--chat-bubble-msg-color); - letter-spacing: 0.3px; - font-weight: 300; - font-size: 14px; - margin-top: 15px; - word-break: break-word; - user-select: none; - } - - .group-subheader { - font-family: Montserrat, sans-serif; - font-size: 14px; - color: var(--chat-bubble-msg-color); - } - - .group-data { - font-family: Roboto, sans-serif; - letter-spacing: 0.3px; - font-weight: 300; - font-size: 14px; - color: var(--chat-bubble-msg-color); - } - .search-results-div { - position: absolute; - top: 25px; - right: 25px; - } - - .name-input { - width: 100%; - outline: 0; - border-width: 0 0 2px; - border-color: var(--mdc-theme-primary); - background-color: transparent; - padding: 10px; - font-family: Roboto, sans-serif; - font-size: 15px; - color: var(--chat-bubble-msg-color); - box-sizing: border-box; - } - - .name-input::selection { - background-color: var(--mdc-theme-primary); - color: white; - } - - .name-input::placeholder { - opacity: 0.9; - color: var(--black); - } - - .search-field { - width: 100%; - position: relative; - } - - .search-icon { - position: absolute; - right: 3px; - color: var(--chat-bubble-msg-color); - transition: hover 0.3s ease-in-out; - background: none; - border-radius: 50%; - padding: 6px 3px; - font-size: 21px; - } - - .search-icon:hover { - cursor: pointer; - background: #d7d7d75c; - } -` diff --git a/core/src/components/friends-view/friends-view.js b/core/src/components/friends-view/friends-view.js index 94e4b128..6d320f39 100644 --- a/core/src/components/friends-view/friends-view.js +++ b/core/src/components/friends-view/friends-view.js @@ -1,22 +1,20 @@ -import {html, LitElement} from 'lit'; -import {connect} from 'pwa-helpers'; - -import '@material/mwc-button'; -import '@material/mwc-dialog'; -import '@polymer/paper-spinner/paper-spinner-lite.js'; -import '@polymer/paper-progress/paper-progress.js'; -import '@material/mwc-icon'; +import { html, LitElement } from 'lit' +import { store } from '../../store' +import { connect } from 'pwa-helpers' +import { parentEpml } from '../show-plugin' +import { translate } from '../../../translate' +import { friendsViewStyles } from '../../styles/core-css' +import './add-friends-modal' +import './ChatSideNavHeads' +import '../../../../plugins/plugins/core/components/ChatSearchResults' +import '@material/mwc-button' +import '@material/mwc-dialog' +import '@material/mwc-icon' +import '@polymer/paper-spinner/paper-spinner-lite.js' +import '@polymer/paper-progress/paper-progress.js' import '@vaadin/icon' import '@vaadin/icons' -import '@vaadin/button'; -import './ChatSideNavHeads'; -import '../../../../plugins/plugins/core/components/ChatSearchResults' -import './add-friends-modal' - -import {translate,} from '../../../translate' -import {store} from '../../store'; -import {friendsViewStyles} from './friends-view-css'; -import {parentEpml} from '../show-plugin'; +import '@vaadin/button' class FriendsView extends connect(store)(LitElement) { static get properties() { @@ -29,94 +27,159 @@ class FriendsView extends connect(store)(LitElement) { setUserName: { attribute: false }, friendList: { type: Array }, userSelected: { type: Object }, - isLoading: {type: Boolean}, - userFoundModalOpen: {type: Boolean}, - userFound: { type: Array}, - isOpenAddFriendsModal: {type: Boolean}, - editContent: {type: Object}, - mySelectedFeeds: {type: Array}, - refreshFeed: {attribute: false}, - closeSidePanel: {attribute: false, type: Object}, - openSidePanel: {attribute:false, type: Object} - }; + isLoading: { type: Boolean }, + userFoundModalOpen: { type: Boolean }, + userFound: { type: Array }, + isOpenAddFriendsModal: { type: Boolean }, + editContent: { type: Object }, + mySelectedFeeds: { type: Array }, + refreshFeed: { attribute: false }, + closeSidePanel: { attribute: false, type: Object }, + openSidePanel: { attribute: false, type: Object } + } } + static get styles() { - return [friendsViewStyles]; + return [friendsViewStyles] } constructor() { - super(); - this.error = false; - this.observerHandler = this.observerHandler.bind(this); - this.viewElement = ''; - this.downObserverElement = ''; - this.myAddress = - window.parent.reduxStore.getState().app.selectedAddress.address; - this.errorMessage = ''; - this.successMessage = ''; - this.friendList = []; - this.userSelected = {}; - this.isLoading = false; + super() + this.error = false + this.observerHandler = this.observerHandler.bind(this) + this.viewElement = '' + this.downObserverElement = '' + this.myAddress = store.getState().app.selectedAddress.address + this.errorMessage = '' + this.successMessage = '' + this.friendList = [] + this.userSelected = {} + this.isLoading = false this.userFoundModalOpen = false - this.userFound = []; - this.nodeUrl = this.getNodeUrl(); - this.myNode = this.getMyNode(); + this.userFound = [] + this.nodeUrl = this.getNodeUrl() + this.myNode = this.getMyNode() this.isOpenAddFriendsModal = false this.editContent = null this.addToFriendList = this.addToFriendList.bind(this) this._updateFriends = this._updateFriends.bind(this) this._updateFeed = this._updateFeed.bind(this) this._addFriend = this._addFriend.bind(this) + } + render() { + return html` +
    +
    +

    My Friends

    +
    + { + if (e.key === 'Enter') { + this.userSearch() + } + }} + > + + +
    +
    + { + this.userSelected = result; + this.isOpenAddFriendsModal = true + this.userFound = []; + this.userFoundModalOpen = false; + }} + .closeFunc=${() => { + this.userFoundModalOpen = false; + this.userFound = []; + }} + .searchResults=${this.userFound} + ?isOpen=${this.userFoundModalOpen} + ?loading=${this.isLoading} + > + +
    + ${this.friendList.map((item) => { + return html` + { }} + .chatInfo=${item} + .openEditFriend=${(val) => this.openEditFriend(val)} + .closeSidePanel=${this.closeSidePanel} + > + + ` + })} +
    +
    +
    + { + this.isOpenAddFriendsModal = val + }} + .userSelected=${this.userSelected} + .onSubmit=${(val, isRemove) => this.addToFriendList(val, isRemove)} + .editContent=${this.editContent} + .onClose=${() => this.onClose()} + .mySelectedFeeds=${this.mySelectedFeeds} + > + + ` + } + + firstUpdated() { + this.viewElement = this.shadowRoot.getElementById('viewElement') + this.downObserverElement = this.shadowRoot.getElementById('downObserver') + this.elementObserver() + this.mySelectedFeeds = JSON.parse(localStorage.getItem('friends-my-selected-feeds') || "[]") + this.friendList = JSON.parse(localStorage.getItem('friends-my-friend-list') || "[]") } getNodeUrl() { - const myNode = - store.getState().app.nodeConfig.knownNodes[ - window.parent.reduxStore.getState().app.nodeConfig.node - ] - + const myNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node] return myNode.protocol + '://' + myNode.domain + ':' + myNode.port } + getMyNode() { - return store.getState().app.nodeConfig.knownNodes[ - window.parent.reduxStore.getState().app.nodeConfig.node - ] + return store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node] } - getMoreFriends() {} - - firstUpdated() { - this.viewElement = this.shadowRoot.getElementById('viewElement'); - this.downObserverElement = - this.shadowRoot.getElementById('downObserver'); - this.elementObserver(); - this.mySelectedFeeds = JSON.parse(localStorage.getItem('friends-my-selected-feeds') || "[]") - this.friendList = JSON.parse(localStorage.getItem('friends-my-friend-list') || "[]") - - - - - } + getMoreFriends() { } _updateFriends(event) { this.friendList = event.detail } + _updateFeed(event) { this.mySelectedFeeds = event.detail this.requestUpdate() } - _addFriend(event){ - const name = event.detail; - const findFriend = this.friendList.find((friend)=> friend.name === name) - if(findFriend){ - this.editContent = {...findFriend, mySelectedFeeds: this.mySelectedFeeds} - this.userSelected = findFriend; + _addFriend(event) { + const name = event.detail; + const findFriend = this.friendList.find((friend) => friend.name === name) + if (findFriend) { + this.editContent = { ...findFriend, mySelectedFeeds: this.mySelectedFeeds } + this.userSelected = findFriend } else { this.userSelected = { name - }; + } } this.isOpenAddFriendsModal = true @@ -134,7 +197,6 @@ class FriendsView extends connect(store)(LitElement) { window.removeEventListener('friends-my-friend-list-event', this._updateFriends) window.removeEventListener('friends-my-selected-feeds-event', this._updateFeed) window.removeEventListener('add-friend', this._addFriend) - super.disconnectedCallback() } @@ -142,18 +204,21 @@ class FriendsView extends connect(store)(LitElement) { const options = { root: this.viewElement, rootMargin: '0px', - threshold: 1, - }; + threshold: 1 + } + // identify an element to observe - const elementToObserve = this.downObserverElement; + const elementToObserve = this.downObserverElement + // passing it a callback function const observer = new IntersectionObserver( this.observerHandler, options - ); + ) + // call `observe()` on that MutationObserver instance, // passing it the element to observe, and the options object - observer.observe(elementToObserve); + observer.observe(elementToObserve) } observerHandler(entries) { @@ -163,112 +228,121 @@ class FriendsView extends connect(store)(LitElement) { if (this.friendList.length < 20) { return; } - this.getMoreFriends(); + + this.getMoreFriends() } } async userSearch() { const nameValue = this.shadowRoot.getElementById('sendTo').value - if(!nameValue) { + + if (!nameValue) { + this.userFound = [] + this.userFoundModalOpen = true + return; + } + + try { + const url = `${this.nodeUrl}/names/${nameValue}` + const res = await fetch(url) + const result = await res.json() + + if (result.error === 401) { this.userFound = [] - this.userFoundModalOpen = true - return; - } - try { - const url = `${this.nodeUrl}/names/${nameValue}` - const res = await fetch(url) - const result = await res.json() - if (result.error === 401) { - this.userFound = [] - } else { - this.userFound = [ - result - ]; - } - this.userFoundModalOpen = true; - } catch (error) { - // let err4string = get("chatpage.cchange35"); - // parentEpml.request('showSnackBar', `${err4string}`) + } else { + this.userFound = [ + result + ] } + + this.userFoundModalOpen = true; + } catch (error) { + // let err4string = get("chatpage.cchange35") + // parentEpml.request('showSnackBar', `${err4string}`) } + } - getApiKey() { - const apiNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] - return apiNode.apiKey - } + async myFollowName(name) { + let items = [ + name + ] - async myFollowName(name) { - let items = [ - name - ] - let namesJsonString = JSON.stringify({ "items": items }) + let namesJsonString = JSON.stringify({ "items": items }) - return await parentEpml.request('apiCall', { - url: `/lists/followedNames?apiKey=${this.getApiKey()}`, - method: 'POST', - headers: { - 'Content-Type': 'application/json' - }, - body: `${namesJsonString}` - }) - } + return await parentEpml.request('apiCall', { + url: `/lists/followedNames?apiKey=${this.getApiKey()}`, + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: `${namesJsonString}` + }) + } - async unFollowName(name) { - let items = [ - name - ] - let namesJsonString = JSON.stringify({ "items": items }) + async unFollowName(name) { + let items = [ + name + ] - return await parentEpml.request('apiCall', { - url: `/lists/followedNames?apiKey=${this.getApiKey()}`, - method: 'DELETE', - headers: { - 'Content-Type': 'application/json' - }, - body: `${namesJsonString}` - }) - } - async addToFriendList(val, isRemove){ - const copyVal = {...val} + let namesJsonString = JSON.stringify({ "items": items }) + + return await parentEpml.request('apiCall', { + url: `/lists/followedNames?apiKey=${this.getApiKey()}`, + method: 'DELETE', + headers: { + 'Content-Type': 'application/json' + }, + body: `${namesJsonString}` + }) + } + + async addToFriendList(val, isRemove) { + const copyVal = { ...val } delete copyVal.mySelectedFeeds - if(isRemove){ - this.friendList = this.friendList.filter((item)=> item.name !== copyVal.name) - }else if(this.editContent){ - const findFriend = this.friendList.findIndex(item=> item.name === copyVal.name) - if(findFriend !== -1){ + + if (isRemove) { + this.friendList = this.friendList.filter((item) => item.name !== copyVal.name) + } else if (this.editContent) { + const findFriend = this.friendList.findIndex(item => item.name === copyVal.name) + if (findFriend !== -1) { const copyList = [...this.friendList] copyList[findFriend] = copyVal this.friendList = copyList } - } else { this.friendList = [...this.friendList, copyVal] } - if(!copyVal.willFollow || isRemove) { + + if (!copyVal.willFollow || isRemove) { await this.unFollowName(copyVal.name) - } else if(copyVal.willFollow){ + } else if (copyVal.willFollow) { await this.myFollowName(copyVal.name) } + this.setMySelectedFeeds(val.mySelectedFeeds) - await new Promise((res)=> { - setTimeout(()=> { + + await new Promise((res) => { + setTimeout(() => { res() - },50) + }, 50) }) - this.userSelected = {}; + + this.userSelected = {} this.shadowRoot.getElementById('sendTo').value = '' - this.isLoading = false; + this.isLoading = false this.isOpenAddFriendsModal = false this.editContent = null this.setMyFriends(this.friendList) - if(!isRemove && this.friendList.length === 1){ + + if (!isRemove && this.friendList.length === 1) { this.refreshFeed() } } - setMyFriends(friendList){ + + setMyFriends(friendList) { localStorage.setItem('friends-my-friend-list', JSON.stringify(friendList)); - const tempSettingsData= JSON.parse(localStorage.getItem('temp-settings-data') || "{}") + const tempSettingsData = JSON.parse(localStorage.getItem('temp-settings-data') || "{}") const newTemp = { ...tempSettingsData, userLists: { @@ -277,18 +351,20 @@ class FriendsView extends connect(store)(LitElement) { } } - localStorage.setItem('temp-settings-data', JSON.stringify(newTemp)); + localStorage.setItem('temp-settings-data', JSON.stringify(newTemp)) + this.dispatchEvent( new CustomEvent('temp-settings-data-event', { - bubbles: true, - composed: true - }), - ); - + bubbles: true, + composed: true + }) + ) } - setMySelectedFeeds(mySelectedFeeds){ + + setMySelectedFeeds(mySelectedFeeds) { this.mySelectedFeeds = mySelectedFeeds - const tempSettingsData= JSON.parse(localStorage.getItem('temp-settings-data') || "{}") + const tempSettingsData = JSON.parse(localStorage.getItem('temp-settings-data') || "{}") + const newTemp = { ...tempSettingsData, friendsFeed: { @@ -297,98 +373,37 @@ class FriendsView extends connect(store)(LitElement) { } } - localStorage.setItem('temp-settings-data', JSON.stringify(newTemp)); - localStorage.setItem('friends-my-selected-feeds', JSON.stringify(mySelectedFeeds)); - } - openEditFriend(val){ - this.isOpenAddFriendsModal = true - this.userSelected = val - this.editContent = {...val, mySelectedFeeds: this.mySelectedFeeds} + localStorage.setItem('temp-settings-data', JSON.stringify(newTemp)) + localStorage.setItem('friends-my-selected-feeds', JSON.stringify(mySelectedFeeds)) } - onClose(){ + openEditFriend(val) { + this.isOpenAddFriendsModal = true + this.userSelected = val + this.editContent = { ...val, mySelectedFeeds: this.mySelectedFeeds } + } + + onClose() { this.isLoading = false; this.isOpenAddFriendsModal = false this.editContent = null this.userSelected = {} } - render() { - return html` -
    -
    -

    My Friends

    -
    - { - if(e.key === 'Enter'){ - this.userSearch() - } - }} - /> + // Standard functions + getApiKey() { + const coreNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node] + return coreNode.apiKey + } - - + isEmptyArray(arr) { + if (!arr) { return true } + return arr.length === 0 + } -
    -
    - { - this.userSelected = result; - this.isOpenAddFriendsModal = true - - this.userFound = []; - this.userFoundModalOpen = false; - }} - .closeFunc=${() => { - this.userFoundModalOpen = false; - this.userFound = []; - }} - .searchResults=${this.userFound} - ?isOpen=${this.userFoundModalOpen} - ?loading=${this.isLoading}> - -
    - - - ${this.friendList.map((item) => { - return html` { - - }} - .chatInfo=${item} - .openEditFriend=${(val)=> this.openEditFriend(val)} - .closeSidePanel=${this.closeSidePanel} - >`; - })} -
    -
    -
    - { - this.isOpenAddFriendsModal = val - }} - .userSelected=${this.userSelected} - .onSubmit=${(val, isRemove)=> this.addToFriendList(val, isRemove)} - .editContent=${this.editContent} - .onClose=${()=> this.onClose()} - .mySelectedFeeds=${this.mySelectedFeeds} - > - - `; + round(number) { + return (Math.round(parseFloat(number) * 1e8) / 1e8).toFixed(8) } } -customElements.define('friends-view', FriendsView); +window.customElements.define('friends-view', FriendsView) \ No newline at end of file diff --git a/core/src/components/friends-view/profile-modal-update.js b/core/src/components/friends-view/profile-modal-update.js index 8e1418bf..9f84c738 100644 --- a/core/src/components/friends-view/profile-modal-update.js +++ b/core/src/components/friends-view/profile-modal-update.js @@ -1,14 +1,15 @@ -import {css, html, LitElement} from 'lit'; -import {get, translate} from '../../../translate' -import '@material/mwc-button'; -import '@material/mwc-icon'; -import '@vaadin/tooltip'; -import '@material/mwc-dialog'; -import '@material/mwc-checkbox'; -import {connect} from 'pwa-helpers'; -import {store} from '../../store'; -import '@polymer/paper-spinner/paper-spinner-lite.js'; -import {parentEpml} from '../show-plugin'; +import { html, LitElement } from 'lit' +import { connect } from 'pwa-helpers' +import { store } from '../../store' +import { parentEpml } from '../show-plugin' +import { get, translate } from '../../../translate' +import { profileModalUpdateStyles } from '../../styles/core-css' +import '@material/mwc-button' +import '@material/mwc-checkbox' +import '@material/mwc-dialog' +import '@material/mwc-icon' +import '@polymer/paper-spinner/paper-spinner-lite.js' +import '@vaadin/tooltip' class ProfileModalUpdate extends connect(store)(LitElement) { static get properties() { @@ -25,420 +26,57 @@ class ProfileModalUpdate extends connect(store)(LitElement) { hasFetchedArrr: { type: Boolean }, isOpenCustomDataModal: { type: Boolean }, customData: { type: Object }, - newCustomDataField: {type: Object}, - newFieldName: {type: String}, - qortalRequestCustomData: {type: Object}, - newCustomDataKey: {type: String}, - newCustomDataValue: {type: String}, - isSaving: {type: Boolean} - }; + newCustomDataField: { type: Object }, + newFieldName: { type: String }, + qortalRequestCustomData: { type: Object }, + newCustomDataKey: { type: String }, + newCustomDataValue: { type: String }, + isSaving: { type: Boolean } + } + } + + static get styles() { + return [profileModalUpdateStyles] } constructor() { super(); - this.isOpen = false; - this.isLoading = false; - this.nodeUrl = this.getNodeUrl(); - this.myNode = this.getMyNode(); - this.tagline = ''; - this.bio = ''; - this.walletList = ['btc', 'ltc', 'doge', 'dgb', 'rvn', 'arrr']; - let wallets = {}; + this.isOpen = false + this.isLoading = false + this.nodeUrl = this.getNodeUrl() + this.myNode = this.getMyNode() + this.tagline = '' + this.bio = '' + this.walletList = ['btc', 'ltc', 'doge', 'dgb', 'rvn', 'arrr'] + let wallets = {} this.walletList.forEach((item) => { - wallets[item] = ''; - }); - this.wallets = wallets; - this.walletsUi = new Map(); + wallets[item] = '' + }) + this.wallets = wallets + this.walletsUi = new Map() let coinProp = { - wallet: null, - }; - + wallet: null + } this.walletList.forEach((c, i) => { - this.walletsUi.set(c, { ...coinProp }); - }); - this.walletsUi.get('btc').wallet = - window.parent.reduxStore.getState().app.selectedAddress.btcWallet; - this.walletsUi.get('ltc').wallet = - window.parent.reduxStore.getState().app.selectedAddress.ltcWallet; - this.walletsUi.get('doge').wallet = - window.parent.reduxStore.getState().app.selectedAddress.dogeWallet; - this.walletsUi.get('dgb').wallet = - window.parent.reduxStore.getState().app.selectedAddress.dgbWallet; - this.walletsUi.get('rvn').wallet = - window.parent.reduxStore.getState().app.selectedAddress.rvnWallet; - this.hasFetchedArrr = false; - this.isOpenCustomDataModal = false; - this.customData = {}; - this.newCustomDataKey = ""; - this.newCustomDataValue = ""; - this.newCustomDataField = {}; - this.newFieldName = ''; - this.isSaving = false; - this.addPrivate = this.addPrivate.bind(this); - this.checkForPrivate = this.checkForPrivate.bind(this); - } - - static get styles() { - return css` - * { - --mdc-theme-primary: rgb(3, 169, 244); - --mdc-theme-secondary: var(--mdc-theme-primary); - --mdc-theme-surface: var(--white); - --mdc-dialog-content-ink-color: var(--black); - --mdc-dialog-min-width: 400px; - --mdc-dialog-max-width: 1024px; - box-sizing: border-box; - } - .input { - width: 90%; - outline: 0; - border-width: 0 0 2px; - border-color: var(--mdc-theme-primary); - background-color: transparent; - padding: 10px; - font-family: Roboto, sans-serif; - font-size: 15px; - color: var(--chat-bubble-msg-color); - box-sizing: border-box; - } - .input::selection { - background-color: var(--mdc-theme-primary); - color: white; - } - - .input::placeholder { - opacity: 0.6; - color: var(--black); - } - - .modal-button { - font-family: Roboto, sans-serif; - font-size: 16px; - color: var(--mdc-theme-primary); - background-color: transparent; - padding: 8px 10px; - border-radius: 5px; - border: none; - transition: all 0.3s ease-in-out; - } - - .modal-button-red { - font-family: Roboto, sans-serif; - font-size: 16px; - color: #f44336; - background-color: transparent; - padding: 8px 10px; - border-radius: 5px; - border: none; - transition: all 0.3s ease-in-out; - } - - .modal-button-red:hover { - cursor: pointer; - background-color: #f4433663; - } - - .modal-button:hover { - cursor: pointer; - background-color: #03a8f475; - } - .checkbox-row { - position: relative; - display: flex; - align-items: center; - align-content: center; - font-family: Montserrat, sans-serif; - font-weight: 600; - color: var(--black); - } - .modal-overlay { - display: block; - position: fixed; - top: 0; - left: 0; - width: 100vw; - height: 100vh; - background-color: rgba( - 0, - 0, - 0, - 0.5 - ); /* Semi-transparent backdrop */ - z-index: 1000; - } - - .modal-content { - position: fixed; - top: 50vh; - left: 50vw; - transform: translate(-50%, -50%); - background-color: var(--mdc-theme-surface); - width: 80vw; - padding: 20px; - box-shadow: rgba(0, 0, 0, 0.1) 0px 4px 6px; - z-index: 1001; - border-radius: 5px; - display: flex; - flex-direction: column; - } - - .modal-overlay.hidden { - display: none; - } - - .avatar { - width: 36px; - height: 36px; - display: flex; - align-items: center; - } - - .app-name { - display: flex; - gap: 20px; - align-items: center; - width: 100%; - cursor: pointer; - padding: 5px; - border-radius: 5px; - margin-bottom: 10px; - } - .inner-content { - display: flex; - flex-direction: column; - max-height: 75vh; - flex-grow: 1; - overflow: auto; - } - - .inner-content::-webkit-scrollbar-track { - background-color: whitesmoke; - border-radius: 7px; - } - - .inner-content::-webkit-scrollbar { - width: 12px; - border-radius: 7px; - background-color: whitesmoke; - } - - .inner-content::-webkit-scrollbar-thumb { - background-color: rgb(180, 176, 176); - border-radius: 7px; - transition: all 0.3s ease-in-out; - } - - .checkbox-row { - position: relative; - display: flex; - align-items: center; - align-content: center; - font-family: Montserrat, sans-serif; - font-weight: 600; - color: var(--black); - } - `; - } - - async updated(changedProperties) { - if ( - changedProperties && - changedProperties.has('editContent') && - this.editContent - ) { - const {bio, tagline, wallets, customData} = this.editContent - this.bio = bio ?? ''; - this.tagline = tagline ?? ''; - let formWallets = {...this.wallets} - if(wallets && Object.keys(wallets).length){ - Object.keys(formWallets).forEach((key)=> { - if(wallets[key]){ - formWallets[key] = wallets[key] - } - }) - } - this.wallets = formWallets - - this.customData = {...customData} - this.requestUpdate(); - } - if ( - changedProperties && - changedProperties.has('qortalRequestCustomData') && - this.qortalRequestCustomData - ) { - this.isOpenCustomDataModal = true - this.newCustomDataField = {...this.qortalRequestCustomData.payload.customData} - this.newCustomDataKey = this.qortalRequestCustomData.property - this.requestUpdate(); - } - - - } - - async firstUpdated() { - try { - await this.fetchWalletAddress('arrr'); - } catch (error) { - console.log({ error }); - } finally { - } - } - - async fetchWalletAddress(coin) { - switch (coin) { - case 'arrr': - const arrrWalletName = `${coin}Wallet`; - - let res = await parentEpml.request('apiCall', { - url: `/crosschain/${coin}/walletaddress?apiKey=${this.myNode.apiKey}`, - method: 'POST', - body: `${ - window.parent.reduxStore.getState().app.selectedAddress[ - arrrWalletName - ].seed58 - }`, - }); - if (res != null && res.error != 1201 && res.length === 78) { - this.arrrWalletAddress = res; - this.hasFetchedArrr = true; - } - break; - - default: - // Not used for other coins yet - break; - } - } - - async getSelectedWalletAddress(wallet) { - switch (wallet) { - case 'arrr': - if(!this.arrrWalletAddress){ - try { - await this.fetchWalletAddress('arrr'); - } catch (error) { - console.log({error}) - } - } - // Use address returned by core API - return this.arrrWalletAddress; - - default: - // Use locally derived address - return this.walletsUi.get(wallet).wallet.address; - } - } - - getNodeUrl() { - const myNode = - store.getState().app.nodeConfig.knownNodes[ - window.parent.reduxStore.getState().app.nodeConfig.node - ] - - return myNode.protocol + '://' + myNode.domain + ':' + myNode.port - } - getMyNode() { - return store.getState().app.nodeConfig.knownNodes[ - window.parent.reduxStore.getState().app.nodeConfig.node - ] - } - - clearFields() { - this.bio = ''; - this.tagline = ''; - } - - async fillAddress(coin) { - const address = await this.getSelectedWalletAddress(coin); - if (address) { - this.wallets = { - ...this.wallets, - [coin]: address, - }; - } - } - - async saveProfile() { - try { - const data = { - version: 1, - tagline: this.tagline, - bio: this.bio, - wallets: this.wallets, - customData: this.customData - }; - this.isSaving = true - await this.onSubmit(data); - this.setIsOpen(false); - this.clearFields(); - this.onClose('success'); - } catch (error) {} finally { - this.isSaving = false - } - } - - removeField(key){ - const copyObj = {...this.newCustomDataField} - delete copyObj[key] - this.newCustomDataField = copyObj - } - - addField(){ - if (!this.newFieldName || !this.newCustomDataValue) { - let snack5string = get("profile.profile24"); - parentEpml.request('showSnackBar', `${snack5string}`); - return; - } - const copyObj = {...this.newCustomDataField} - copyObj[this.newFieldName] = this.newCustomDataValue - this.newCustomDataField = copyObj - this.newFieldName = "" - this.newCustomDataValue = "" - } - - addCustomData(){ - const copyObj = {...this.customData} - copyObj[this.newCustomDataKey] = this.newCustomDataField - this.customData = copyObj + this.walletsUi.set(c, { ...coinProp }) + }) + this.walletsUi.get('btc').wallet = store.getState().app.selectedAddress.btcWallet + this.walletsUi.get('ltc').wallet = store.getState().app.selectedAddress.ltcWallet + this.walletsUi.get('doge').wallet = store.getState().app.selectedAddress.dogeWallet + this.walletsUi.get('dgb').wallet = store.getState().app.selectedAddress.dgbWallet + this.walletsUi.get('rvn').wallet = store.getState().app.selectedAddress.rvnWallet + this.hasFetchedArrr = false + this.isOpenCustomDataModal = false + this.customData = {} this.newCustomDataKey = "" - this.newCustomDataField = {}; + this.newCustomDataValue = "" + this.newCustomDataField = {} this.newFieldName = '' - this.newCustomDataValue = '' - this.isOpenCustomDataModal = false; + this.isSaving = false + this.addPrivate = this.addPrivate.bind(this) + this.checkForPrivate = this.checkForPrivate.bind(this) } - updateCustomData(key, data){ - this.isOpenCustomDataModal = true - this.newCustomDataField = data - this.newCustomDataKey = key - - } - - removeCustomData(key){ - const copyObj = {...this.customData} - delete copyObj[key] - this.customData = copyObj - } - - checkForPrivate(){ - let isPrivate = false - if(this.newCustomDataKey.includes('-private')) isPrivate = true - return isPrivate - } - - addPrivate(e){ - if (e.target.checked) { - if(this.newCustomDataKey.includes('-private')){ - - } else { - this.newCustomDataKey = this.newCustomDataKey + '-private' - } - } else { - this.newCustomDataKey = this.newCustomDataKey.replace('-private', ''); - } - } - render() { return html` @@ -277,13 +165,14 @@ class Chat extends LitElement { { - this.resetChatEditor() - this.openPrivateMessage = false - this.shadowRoot.getElementById('sendTo').value = "" + this.resetChatEditor(); + this.openPrivateMessage = false; + this.shadowRoot.getElementById('sendTo').value = ''; this.userFoundModalOpen = false; - this.userFound = [] + this.userFound = []; }} - style=${this.openPrivateMessage ? "visibility:visible;z-index:50" : "visibility: hidden;z-index:-100;position: relative"}> + style=${this.openPrivateMessage ? "visibility:visible;z-index:50" : "visibility: hidden;z-index:-100;position: relative"} + >
    @@ -298,32 +187,24 @@ class Chat extends LitElement { ?disabled=${this.isLoading} id="sendTo" placeholder="${translate("chatpage.cchange7")}" - value=${this.userSelected.name ? this.userSelected.name: ''} + value=${this.userSelected.name ? this.userSelected.name : ''} @keypress=${() => { - this.userSelected = {} + this.userSelected = {}; this.requestUpdate() }} /> - ${this.userSelected.name ? ( - html` + ${this.userSelected.name ? + (html`
    -

    ${translate("chatpage.cchange38")}

    +

    ${translate("chatpage.cchange38")}

    - ` - ) : ( - html` - - - ` - )} + `) + : (html` + + `) + }
    - this.updatePlaceholder(editor, value)} + .updatePlaceholder=${(editor, value) => this.updatePlaceholder(editor, value)} > - @@ -365,13 +245,13 @@ class Chat extends LitElement {
    { - this.userSelected = result + this.userSelected = result; this.userFound = []; - this.userFoundModalOpen = false + this.userFoundModalOpen = false; }} .closeFunc=${() => { - this.userFoundModalOpen = false - this.userFound = [] + this.userFoundModalOpen = false; + this.userFound = []; }} .searchResults=${this.userFound} ?isOpen=${this.userFoundModalOpen} @@ -381,7 +261,6 @@ class Chat extends LitElement {
    -
    @@ -392,26 +271,20 @@ class Chat extends LitElement { { if (data.item.name === "No registered name") { - render(html`${translate("chatpage.cchange15")}`, root) + render(html`${translate("chatpage.cchange15")}`, root); } else { - render(html`${data.item.name}`, root) + render(html`${data.item.name}`, root); } }}> { - render(html`${this.renderUnblockButton(data.item)}`, root) + render(html`${this.renderUnblockButton(data.item)}`, root); }}> - ${this.isEmptyArray(this.blockedUserList) ? html` - ${translate("chatpage.cchange14")} - `: ''} - + ${this.isEmptyArray(this.blockedUserList) ? html`${translate("chatpage.cchange14")}`: ''} + ${translate("general.close")} @@ -425,9 +298,12 @@ class Chat extends LitElement { this.getLocalBlockedList() const getBlockedUsers = async () => { - this.blockedUsers = await parentEpml.request('apiCall', { + let blockedUsers = await parentEpml.request('apiCall', { url: `/lists/blockedAddresses?apiKey=${this.getApiKey()}` }) + + this.blockedUsers = blockedUsers + setTimeout(getBlockedUsers, 60000) } @@ -442,14 +318,12 @@ class Chat extends LitElement { this.shadowRoot.getElementById('messageBox').addEventListener('keydown', stopKeyEventPropagation) - const runFunctionsAfterPageLoad = () => { + const runFunctionsAfterPageLoad = async () => { // Functions to exec after render while waiting for page info... - // getDataFromURL() - try { let key = `${window.parent.reduxStore.getState().app.selectedAddress.address.substr(0, 10)}_chat-heads` let localChatHeads = localStorage.getItem(key) - this.setChatHeads(JSON.parse(localChatHeads)) + await this.setChatHeads(JSON.parse(localChatHeads)) } catch (e) { // TODO: Could add error handling in case there's a weird one... (-_-) return @@ -458,6 +332,7 @@ class Chat extends LitElement { // Clear Interval... if (this.selectedAddress.address !== undefined) { clearInterval(runFunctionsAfterPageLoadInterval) + return } } @@ -471,13 +346,17 @@ class Chat extends LitElement { } else { this.theme = 'light' } + document.querySelector('html').setAttribute('theme', this.theme) }) - if (!isElectron()) { /* empty */ } else { + if (!isElectron()) { + // ... + } else { window.addEventListener('contextmenu', (event) => { // Check if the clicked element has the class let target = event.target + while (target !== null) { if (target.classList && target.classList.contains('customContextMenuDiv')) { // Your custom context menu logic @@ -496,7 +375,6 @@ class Chat extends LitElement { let configLoaded = false parentEpml.ready().then(() => { - parentEpml.subscribe('config', c => { if (!configLoaded) { setTimeout(getBlockedUsers, 1) @@ -504,18 +382,20 @@ class Chat extends LitElement { } this.config = JSON.parse(c) }) + parentEpml.subscribe('chat_heads', chatHeads => { chatHeads = JSON.parse(chatHeads) this.getChatHeadFromState(chatHeads) }) + parentEpml.subscribe('side_effect_action', async sideEffectActionParam => { const sideEffectAction = JSON.parse(sideEffectActionParam) - if(sideEffectAction && sideEffectAction.type === 'openPrivateChat') { + if (sideEffectAction && sideEffectAction.type === 'openPrivateChat') { const name = sideEffectAction.data.name const address = sideEffectAction.data.address - if(this.chatHeadsObj.direct && this.chatHeadsObj.direct.find(item=> item.address === address)){ - await this.setActiveChatHeadUrl(`direct/${address}`) + if (this.chatHeadsObj.direct && this.chatHeadsObj.direct.find(item => item.address === address)) { + this.setActiveChatHeadUrl(`direct/${address}`) window.parent.reduxStore.dispatch( window.parent.reduxAction.setSideEffectAction(null)) } else { @@ -526,9 +406,9 @@ class Chat extends LitElement { window.parent.reduxStore.dispatch( window.parent.reduxAction.setSideEffectAction(null)) } - } }) + parentEpml.request('apiCall', { url: `/addresses/balance/${window.parent.reduxStore.getState().app.selectedAddress.address}` }).then(res => { @@ -536,48 +416,174 @@ class Chat extends LitElement { this.requestUpdate() }) }) + parentEpml.imReady() + this.clearConsole() + setInterval(() => { this.clearConsole() }, 60000) } + async setActiveChatHeadUrl(url) { + this.activeChatHeadUrl = url + this.requestUpdate() + } + + resetChatEditor() { + this.editor.commands.setContent('') + } + + async getUpdateCompleteTextEditor() { + await super.getUpdateComplete() + const marginElements = Array.from(this.shadowRoot.querySelectorAll('chat-text-editor')) + await Promise.all(marginElements.map(el => el.updateComplete)) + const marginElements2 = Array.from(this.shadowRoot.querySelectorAll('wrapper-modal')) + await Promise.all(marginElements2.map(el => el.updateComplete)) + return true + } + + async connectedCallback() { + super.connectedCallback() + + await this.getUpdateCompleteTextEditor() + + const elementChatId = this.shadowRoot.getElementById('messageBox').shadowRoot.getElementById('privateMessage') + this.editor = new Editor({ + onUpdate: () => { + this.shadowRoot.getElementById('messageBox').getMessageSize(this.editor.getJSON()) + }, + element: elementChatId, + extensions: [ + StarterKit, + Underline, + Highlight, + Placeholder.configure({ + placeholder: 'Write something …' + }), + Extension.create({ + addKeyboardShortcuts: () => { + return { + 'Enter': () => { + const chatTextEditor = this.shadowRoot.getElementById('messageBox') + chatTextEditor.sendMessageFunc({ }) + return true + } + } + } + }) + ] + }) + + this.unsubscribeStore = window.parent.reduxStore.subscribe(() => { + try { + const currentState = window.parent.reduxStore.getState() + + if (window.parent.location && window.parent.location.search) { + const queryString = window.parent.location.search + const params = new URLSearchParams(queryString) + const chat = params.get("chat") + if (chat && chat !== this.activeChatHeadUrl) { + let url = window.parent.location.href + let newUrl = url.split("?")[0] + window.parent.history.pushState({}, "", newUrl) + this.setActiveChatHeadUrl(chat) + } + } + + if (currentState.app.accountInfo && currentState.app.accountInfo.names && currentState.app.accountInfo.names.length > 0 && this.loggedInUserName !== currentState.app.accountInfo.names[0].name) { + this.loggedInUserName = currentState.app.accountInfo.names[0].name + } + + if (currentState.app.accountInfo && currentState.app.accountInfo.addressInfo && currentState.app.accountInfo.addressInfo.address && this.loggedInUserAddress !== currentState.app.accountInfo.addressInfo.address) { + this.loggedInUserAddress = currentState.app.accountInfo.addressInfo.address + } + } catch (error) { /* empty */ } + }) + } + + disconnectedCallback() { + super.disconnectedCallback() + this.editor.destroy() + this.unsubscribeStore() + } + + updatePlaceholder(editor, text) { + editor.extensionManager.extensions.forEach((extension) => { + if (extension.name === 'placeholder') { + extension.options['placeholder'] = text + editor.commands.focus('end') + } + }) + } + + setOpenDialogGroupsModal(val) { + this.openDialogGroupsModal = val + } + + openTabToGroupManagement() { + window.parent.reduxStore.dispatch( + window.parent.reduxAction.setNewTab({ + url: `group-management`, + id: this.uid.rnd(), + myPlugObj: { + 'url': 'group-management', + 'domain': 'core', + 'page': 'group-management/index.html', + 'title': 'Group Management', + 'icon': 'vaadin:group', + 'mwcicon': 'group', + 'pluginNumber': 'plugin-fJZNpyLGTl', + 'menus': [], + 'parent': false + }, + openExisting: true + }) + ) + } + clearConsole() { - if (!isElectron()) { /* empty */ } else { + if (!isElectron()) { + // ... + } else { console.clear() window.parent.electronAPI.clearCache() } } setOpenPrivateMessage(props) { - this.openPrivateMessage = props.open; - this.shadowRoot.getElementById("sendTo").value = props.name + this.openPrivateMessage = props.open + this.shadowRoot.getElementById('sendTo').value = props.name } async userSearch() { const nameValue = this.shadowRoot.getElementById('sendTo').value - if(!nameValue) { + + if (!nameValue) { this.userFound = [] this.userFoundModalOpen = true return } + try { const result = await parentEpml.request('apiCall', { type: 'api', url: `/names/${nameValue}` }) + if (result.error === 401) { this.userFound = [] } else { this.userFound = [ ...this.userFound, - result, - ]; + result + ] } - this.userFoundModalOpen = true; + + this.userFoundModalOpen = true } catch (error) { - let err4string = get("chatpage.cchange35"); + let err4string = get('chatpage.cchange35') parentEpml.request('showSnackBar', `${err4string}`) } } @@ -587,9 +593,10 @@ class Chat extends LitElement { } async _sendMessage(outSideMsg, msg) { - this.isLoading = true; + this.isLoading = true const trimmedMessage = msg + if (/^\s*$/.test(trimmedMessage)) { this.isLoading = false } else { @@ -600,7 +607,7 @@ class Chat extends LitElement { version: 3 } const stringifyMessageObject = JSON.stringify(messageObject) - await this.sendMessage(stringifyMessageObject) + this.sendMessage(stringifyMessageObject) } } @@ -617,19 +624,22 @@ class Chat extends LitElement { let myNameRes = await parentEpml.request('apiCall', { type: 'api', url: `/names/${receiverName}` - }); + }) + if (myNameRes.error === 401) { - myRes = false; + myRes = false } else { myRes = myNameRes } - return myRes; + + return myRes } catch (error) { - return "" + return '' } } const myNameRes = await validateName(_recipient) + if (!myNameRes) { recipient = _recipient } else { @@ -637,8 +647,8 @@ class Chat extends LitElement { } const getAddressPublicKey = async () => { - let isEncrypted; - let _publicKey; + let isEncrypted + let _publicKey let addressPublicKey = await parentEpml.request('apiCall', { type: 'api', @@ -647,22 +657,26 @@ class Chat extends LitElement { if (addressPublicKey.error === 102) { _publicKey = false - let err4string = get("chatpage.cchange19") + let err4string = get('chatpage.cchange19') parentEpml.request('showSnackBar', `${err4string}`) this.isLoading = false } else if (addressPublicKey !== false) { isEncrypted = 1 _publicKey = addressPublicKey - await sendMessageRequest(isEncrypted, _publicKey) + sendMessageRequest(isEncrypted, _publicKey) } else { - let err4string = get("chatpage.cchange39") + let err4string = get('chatpage.cchange39') parentEpml.request('showSnackBar', `${err4string}`) this.isLoading = false } } + let _reference = new Uint8Array(64) - window.crypto.getRandomValues(_reference); + + window.crypto.getRandomValues(_reference) + let reference = window.parent.Base58.encode(_reference) + const sendMessageRequest = async (isEncrypted, _publicKey) => { let chatResponse = await parentEpml.request('chat', { type: 18, @@ -679,17 +693,20 @@ class Chat extends LitElement { isText: 1 } }) - await _computePow(chatResponse) + + _computePow(chatResponse) } const _computePow = async (chatBytes) => { const difficulty = this.balance < 4 ? 18 : 8 const path = window.parent.location.origin + '/memory-pow/memory-pow.wasm.full' const worker = new WebWorker() + let nonce = null let chatBytesArray = null + await new Promise((res) => { - worker.postMessage({chatBytes, path, difficulty}) + worker.postMessage({ chatBytes, path, difficulty }) worker.onmessage = e => { worker.terminate() chatBytesArray = e.data.chatBytesArray @@ -703,26 +720,27 @@ class Chat extends LitElement { chatBytesArray: chatBytesArray, chatNonce: nonce }) + getSendChatResponse(_response) } const getSendChatResponse = (response) => { if (response === true) { this.setActiveChatHeadUrl(`direct/${recipient}`) - this.shadowRoot.getElementById('sendTo').value = "" + this.shadowRoot.getElementById('sendTo').value = '' this.openPrivateMessage = false - this.resetChatEditor(); + this.resetChatEditor() } else if (response.error) { parentEpml.request('showSnackBar', response.message) } else { - let err2string = get("chatpage.cchange21") + let err2string = get('chatpage.cchange21') parentEpml.request('showSnackBar', `${err2string}`) } this.isLoading = false } - // Exec.. - await getAddressPublicKey() + + getAddressPublicKey() } insertImage(file) { @@ -730,7 +748,8 @@ class Chat extends LitElement { this.imageFile = file return } - parentEpml.request('showSnackBar', get("chatpage.cchange28")) + + parentEpml.request('showSnackBar', get('chatpage.cchange28')) } renderLoadingText() { @@ -738,12 +757,12 @@ class Chat extends LitElement { } renderSendText() { - return html`${translate("chatpage.cchange9")}` + return html`${translate('chatpage.cchange9')}` } relMessages() { setTimeout(() => { - window.location.href = window.location.href.split( '#' )[0] + window.location.href = window.location.href.split('#')[0] }, 500) } @@ -752,7 +771,7 @@ class Chat extends LitElement { const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port const blockedAddressesUrl = `${nodeUrl}/lists/blockedAddresses?apiKey=${this.getApiKey()}` - localStorage.removeItem("MessageBlockedAddresses") + localStorage.removeItem('MessageBlockedAddresses') var hidelist = [] @@ -762,7 +781,8 @@ class Chat extends LitElement { data.map(item => { hidelist.push(item) }) - localStorage.setItem("MessageBlockedAddresses", JSON.stringify(hidelist)) + + localStorage.setItem('MessageBlockedAddresses', JSON.stringify(hidelist)) this.blockedUserList = hidelist }) @@ -774,7 +794,7 @@ class Chat extends LitElement { const blockedAddressesUrl = `${nodeUrl}/lists/blockedAddresses?apiKey=${this.getApiKey()}` const err1string = 'No registered name' - localStorage.removeItem("ChatBlockedAddresses") + localStorage.removeItem('ChatBlockedAddresses') var obj = [] @@ -786,18 +806,21 @@ class Chat extends LitElement { name: err1string, owner: item } + fetch(`${nodeUrl}/names/address/${item}?limit=0&reverse=true`).then(res => { return res.json() }).then(jsonRes => { - if(jsonRes.length) { - jsonRes.map (item => { + if (jsonRes.length) { + jsonRes.map(item => { obj.push(item) }) } else { obj.push(noName) } - localStorage.setItem("ChatBlockedAddresses", JSON.stringify(obj)) - this.blockedUserList = JSON.parse(localStorage.getItem("ChatBlockedAddresses") || "[]") + + localStorage.setItem('ChatBlockedAddresses', JSON.stringify(obj)) + + this.blockedUserList = JSON.parse(localStorage.getItem('ChatBlockedAddresses') || '[]') }) }) }) @@ -805,12 +828,14 @@ class Chat extends LitElement { async getPendingGroupInvites() { const myAddress = window.parent.reduxStore.getState().app.selectedAddress.address + try { - this.groupInvites = await parentEpml.request('apiCall', { + let pendingGroupInvites = await parentEpml.request('apiCall', { url: `/groups/invites/${myAddress}` - }); + }) + this.groupInvites = pendingGroupInvites } catch (error) { - let err4string = get("chatpage.cchange61"); + let err4string = get('chatpage.cchange61') parentEpml.request('showSnackBar', `${err4string}`) } } @@ -822,7 +847,7 @@ class Chat extends LitElement { owner ] - let ownersJsonString = JSON.stringify({ "items": items }) + let ownersJsonString = JSON.stringify({ 'items': items }) let ret = await parentEpml.request('apiCall', { url: `/lists/blockedAddresses?apiKey=${this.getApiKey()}`, @@ -836,26 +861,26 @@ class Chat extends LitElement { if (ret === true) { this.blockedUsers = this.blockedUsers.filter(item => item != owner) this.getChatBlockedList() - this.blockedUserList = JSON.parse(localStorage.getItem("ChatBlockedAddresses") || "[]") - let err2string = get("chatpage.cchange16") + this.blockedUserList = JSON.parse(localStorage.getItem('ChatBlockedAddresses') || '[]') + let err2string = get('chatpage.cchange16') snackbar.add({ labelText: `${err2string}`, dismiss: true }) this.relMessages() - } - else { - let err3string = get("chatpage.cchange17") + } else { + let err3string = get('chatpage.cchange17') snackbar.add({ labelText: `${err3string}`, dismiss: true }) } + return ret } renderUnblockButton(websiteObj) { - return html`` + return html`` } changeTheme() { @@ -874,20 +899,21 @@ class Chat extends LitElement { myAddress=${JSON.stringify(this.selectedAddress)} .setOpenPrivateMessage=${(val) => this.setOpenPrivateMessage(val)} > - ` + + ` } renderChatHead(chatHeadArr) { return chatHeadArr.map(eachChatHead => { - return html` this.setActiveChatHeadUrl(val)} chatInfo=${JSON.stringify(eachChatHead)}>` + return html` this.setActiveChatHeadUrl(val)} chatInfo=${JSON.stringify(eachChatHead)}>` }) } renderChatPage() { // Check for the chat ID from and render chat messages // Else render Welcome to Q-CHat - // TODO: DONE: Do the above in the ChatPage + return html` this.setOpenPrivateMessage(val)} - .setActiveChatHeadUrl=${(val)=> this.setActiveChatHeadUrl(val)} + .setActiveChatHeadUrl=${(val) => this.setActiveChatHeadUrl(val)} balance=${this.balance} loggedInUserName=${this.loggedInUserName} loggedInUserAddress=${this.loggedInUserAddress} @@ -905,16 +931,48 @@ class Chat extends LitElement { ` } - setChatHeads(chatObj) { - const chatObjGroups = Array.isArray(chatObj.groups) ? chatObj.groups : [] + async getOwnerName(newGroupId) { + try { + const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] + const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port + + const response = await fetch(`${nodeUrl}/groups/${newGroupId}`) + const data = await response.json() + + const res = await fetch(`${nodeUrl}/names/address/${data.owner}?limit=0&reverse=true`) + const jsonRes = await res.json() + + let goName = 'undefined' + + if (jsonRes.length) { + jsonRes.forEach(item => { + goName = item.name + }) + } + + return goName + } catch (error) { + console.error('Error fetching name', error) + throw error + } + } + + async setChatHeads(chatObj) { + const chatObjGroups = Array.isArray(chatObj.groups) ? chatObj.groups : [] const chatObjDirect = Array.isArray(chatObj.direct) ? chatObj.direct : [] - let groupList = chatObjGroups.map(group => group.groupId === 0 ? { - groupId: group.groupId, url: `group/${group.groupId}`, - groupName: "Qortal General Chat", + let groupList = await Promise.all(chatObjGroups.map(async group => group.groupId === 0 ? { + groupId: group.groupId, + url: `group/${group.groupId}`, + groupName: 'Qortal General Chat', timestamp: group.timestamp === undefined ? 2 : group.timestamp, - sender: group.sender } : { ...group, timestamp: group.timestamp === undefined ? 1 : group.timestamp, url: `group/${group.groupId}` - }) + sender: group.sender + } : { + ...group, + timestamp: group.timestamp === undefined ? 1 : group.timestamp, + url: `group/${group.groupId}`, + ownerName: group.ownerName === undefined ? await this.getOwnerName(group.groupId) : 'undefined' + })) let directList = chatObjDirect.map(dc => { return { ...dc, url: `direct/${dc.address}` } @@ -925,6 +983,7 @@ class Chat extends LitElement { } groupList.sort(compareNames) + let chatHeadMasterList = [...groupList, ...directList] const compareArgs = (a, b) => { @@ -934,12 +993,12 @@ class Chat extends LitElement { this.chatHeads = chatHeadMasterList.sort(compareArgs) } - getChatHeadFromState(chatObj) { + async getChatHeadFromState(chatObj) { if (chatObj === undefined) { - + return } else { this.chatHeadsObj = chatObj - this.setChatHeads(chatObj) + await this.setChatHeads(chatObj) } } @@ -951,23 +1010,13 @@ class Chat extends LitElement { parentEpml.request('setPageUrl', pageUrl) } - isEmptyArray(arr) { - if (!arr) { return true } - return arr.length === 0 - } - - getApiKey() { - const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] - return myNode.apiKey - } - scrollToBottom() { const viewElement = this.shadowRoot.querySelector('chat-page').shadowRoot.querySelector('chat-scroller').shadowRoot.getElementById('viewElement') - const chatScrollerElement = this.shadowRoot.querySelector('chat-page').shadowRoot.querySelector('chat-scroller') + if (chatScrollerElement && chatScrollerElement.disableAddingNewMessages) { const chatPageElement = this.shadowRoot.querySelector('chat-page') - if(chatPageElement && chatPageElement.getLastestMessages) + if (chatPageElement && chatPageElement.getLastestMessages) chatPageElement.getLastestMessages() } else { viewElement.scroll({ top: viewElement.scrollHeight, left: 0, behavior: 'smooth' }) @@ -981,6 +1030,21 @@ class Chat extends LitElement { hideNewMessageBar() { this.shadowRoot.getElementById('newMessageBar').classList.add('hide-new-message-bar') } + + // Standard functions + getApiKey() { + const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] + return myNode.apiKey + } + + isEmptyArray(arr) { + if (!arr) { return true } + return arr.length === 0 + } + + round(number) { + return (Math.round(parseFloat(number) * 1e8) / 1e8).toFixed(8) + } } -window.customElements.define('q-chat', Chat) +window.customElements.define('q-chat', Chat) \ No newline at end of file diff --git a/plugins/plugins/core/qdn/index.html b/plugins/plugins/core/q-website/index.html similarity index 94% rename from plugins/plugins/core/qdn/index.html rename to plugins/plugins/core/q-website/index.html index da9c4777..e1ef8b98 100644 --- a/plugins/plugins/core/qdn/index.html +++ b/plugins/plugins/core/q-website/index.html @@ -48,8 +48,8 @@ - - + + diff --git a/plugins/plugins/core/q-website/q-websites.src.js b/plugins/plugins/core/q-website/q-websites.src.js new file mode 100644 index 00000000..0bb07ed9 --- /dev/null +++ b/plugins/plugins/core/q-website/q-websites.src.js @@ -0,0 +1,976 @@ +import { html, LitElement } from 'lit' +import { render } from 'lit/html.js' +import { Epml } from '../../../epml' +import { qWebsitesStyles } from '../components/plugins-css' +import isElectron from 'is-electron' +import '@material/mwc-dialog' +import '@material/mwc-icon' +import '@material/mwc-button' +import '@material/mwc-tab-bar' +import '@material/mwc-textfield' +import '@vaadin/button' +import '@vaadin/grid' +import '@vaadin/icon' +import '@vaadin/icons' +import '@vaadin/text-field' + +// Multi language support +import { get, registerTranslateConfig, translate, use } from '../../../../core/translate' +registerTranslateConfig({ + loader: lang => fetch(`/language/${lang}.json`).then(res => res.json()) +}) + +const parentEpml = new Epml({ type: 'WINDOW', source: window.parent }) + +class QWebsites extends LitElement { + static get properties() { + return { + identifier: { type: String }, + loading: { type: Boolean }, + resources: { type: Array }, + pageRes: { type: Array }, + followedNames: { type: Array }, + blockedNames: { type: Array }, + relayMode: { type: Boolean }, + selectedAddress: { type: Object }, + searchName: { type: String }, + searchResources: { type: Array }, + followedResources: { type: Array }, + blockedResources: { type: Array }, + theme: { type: String, reflect: true } + } + } + + static get styles() { + return [qWebsitesStyles] + } + + constructor() { + super() + this.identifier = '' + this.selectedAddress = {} + this.resources = [] + this.pageRes = [] + this.followedNames = [] + this.blockedNames = [] + this.relayMode = false + this.isLoading = false + this.searchName = '' + this.searchResources = [] + this.followedResources = [] + this.blockedResources = [] + this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light' + } + + render() { + return html` +
    + + + + + +
    +
    +
    +

    ${translate("websitespage.schange1")}

    +

    ${this.renderSearchButton()}

    +

    ${this.renderPublishButton()}

    +
    +

    ${translate("websitespage.schange9")}

    + + { + render(html`${this.renderAvatar(data.item)}`, root) + }}> + + { + render(html`${this.renderInfo(data.item)}`, root) + }}> + + { + render(html`${this.renderPublishedBy(data.item)}`, root) + }}> + + { + render(html`${this.renderFollowUnfollowButton(data.item)}`, root); + }}> + + { + render(html`${this.renderBlockUnblockButton(data.item)}`, root); + }}> + + +
    + ${this.pageRes == null ? html` + Loading... + ` : ''} + ${this.isEmptyArray(this.pageRes) ? html` + ${translate("websitespage.schange10")} + ` : ''} + ${this.renderRelayModeText()} +
    +
    +
    +

    ${translate("websitespage.schange11")}

    +

    ${this.renderSearchButton()}

    +

    ${this.renderPublishButton()}

    +
    +

    ${translate("websitespage.schange12")}

    + + { + render(html`${this.renderAvatar(data.item)}`, root) + }}> + + { + render(html`${this.renderInfo(data.item)}`, root) + }}> + + { + render(html`${this.renderPublishedBy(data.item)}`, root) + }}> + + { + render(html`${this.renderFollowUnfollowButtonTab(data.item)}`, root); + }}> + + + ${this.followedResources == null ? html` + Loading... + ` : ''} + ${this.isEmptyArray(this.followedResources) ? html` + ${translate("websitespage.schange13")} + ` : ''} + ${this.renderRelayModeText()} +
    +
    +
    +

    ${translate("websitespage.schange14")}

    +

    ${this.renderSearchButton()}

    +

    ${this.renderPublishButton()}

    +
    +

    ${translate("websitespage.schange15")}

    + + { + render(html`${this.renderAvatar(data.item)}`, root) + }}> + + { + render(html`${this.renderInfo(data.item)}`, root) + }}> + + { + render(html`${this.renderPublishedBy(data.item)}`, root) + }}> + + { + render(html`${this.renderBlockUnblockButtonTab(data.item)}`, root); + }}> + + + ${this.blockedResources == null ? html` + Loading... + ` : ''} + ${this.isEmptyArray(this.blockedResources) ? html` + ${translate("websitespage.schange16")} + ` : ''} + ${this.renderRelayModeText()} +
    +
    +
    + +

    ${translate("websitespage.schange4")}

    + +
    + + { + render(html`${this.renderAvatar(data.item)}`, root) + }}> + + { + render(html`${this.renderPublishedBy(data.item)}`, root) + }}> + + { + render(html`${this.renderFollowUnfollowButton(data.item)}`, root); + }}> + + { + render(html`${this.renderBlockUnblockButton(data.item)}`, root); + }}> + + +
    + ` + } + + firstUpdated() { + this.changeTheme() + this.changeLanguage() + this.showWebsites() + + setTimeout(() => { + this.displayTabContent('browse') + }, 0) + + const getFollowedNames = async () => { + this.followedNames = await parentEpml.request('apiCall', { + url: `/lists/followedNames?apiKey=${this.getApiKey()}` + }) + setTimeout(getFollowedNames, 60000) + } + + const getBlockedNames = async () => { + this.blockedNames = await parentEpml.request('apiCall', { + url: `/lists/blockedNames?apiKey=${this.getApiKey()}` + }) + setTimeout(getBlockedNames, 60000) + } + + const getRelayMode = async () => { + this.relayMode = await parentEpml.request('apiCall', { + url: `/arbitrary/relaymode?apiKey=${this.getApiKey()}` + }) + setTimeout(getRelayMode, 600000) + } + + window.addEventListener('storage', () => { + const checkLanguage = localStorage.getItem('qortalLanguage') + const checkTheme = localStorage.getItem('qortalTheme') + + use(checkLanguage) + + if (checkTheme === 'dark') { + this.theme = 'dark' + } else { + this.theme = 'light' + } + document.querySelector('html').setAttribute('theme', this.theme) + }) + + if (!isElectron()) { + } else { + window.addEventListener('contextmenu', (event) => { + event.preventDefault() + window.parent.electronAPI.showMyMenu() + }) + } + + let configLoaded = false + + parentEpml.ready().then(() => { + parentEpml.subscribe('selected_address', async selectedAddress => { + this.selectedAddress = {} + selectedAddress = JSON.parse(selectedAddress) + if (!selectedAddress || Object.entries(selectedAddress).length === 0) return + this.selectedAddress = selectedAddress + }) + + parentEpml.subscribe('config', c => { + if (!configLoaded) { + setTimeout(getFollowedNames, 1) + setTimeout(getBlockedNames, 1) + setTimeout(getRelayMode, 1) + setTimeout(this.getFollowedNamesResource, 1) + setTimeout(this.getBlockedNamesResource, 1) + setInterval(this.getArbitraryResources, 900000) + configLoaded = true + } + + this.config = JSON.parse(c) + }) + }) + + parentEpml.imReady() + + this.clearConsole() + + setInterval(() => { + this.clearConsole() + }, 60000) + } + + clearConsole() { + if (!isElectron()) { + } else { + console.clear() + window.parent.electronAPI.clearCache() + } + } + + changeTheme() { + const checkTheme = localStorage.getItem('qortalTheme') + + if (checkTheme === 'dark') { + this.theme = 'dark' + } else { + this.theme = 'light' + } + document.querySelector('html').setAttribute('theme', this.theme) + } + + changeLanguage() { + const checkLanguage = localStorage.getItem('qortalLanguage') + + if (checkLanguage === null || checkLanguage.length === 0) { + localStorage.setItem('qortalLanguage', 'us') + use('us') + } else { + use(checkLanguage) + } + } + + renderCatText() { + return html`${translate('websitespage.schange26')}` + } + + async displayTabContent(tab) { + const tabBrowseContent = this.shadowRoot.getElementById('tab-browse-content') + const tabFollowedContent = this.shadowRoot.getElementById('tab-followed-content') + const tabBlockedContent = this.shadowRoot.getElementById('tab-blocked-content') + + if (tab === 'browse') { + tabBrowseContent.style.display = 'block' + tabFollowedContent.style.display = 'none' + tabBlockedContent.style.display = 'none' + await this.refreshWebsites() + } else if (tab === 'followed') { + tabBrowseContent.style.display = 'none' + tabFollowedContent.style.display = 'block' + tabBlockedContent.style.display = 'none' + await this.getFollowedNamesRefresh() + await this.getFollowedNamesResource() + } else if (tab === 'blocked') { + tabBrowseContent.style.display = 'none' + tabFollowedContent.style.display = 'none' + tabBlockedContent.style.display = 'block' + await this.getBlockedNamesRefresh() + await this.getBlockedNamesResource() + } + } + + searchListener(e) { + if (e.key === 'Enter') { + this.doSearch(e) + } + } + + async getResourcesGrid() { + this.resourcesGrid = this.shadowRoot.querySelector('#resourcesGrid') + this.pagesControl = this.shadowRoot.querySelector('#pages') + this.pages = undefined + } + + async getArbitraryResources() { + this.resources = await parentEpml.request('apiCall', { + url: `/arbitrary/resources?service=WEBSITE&default=true&limit=0&reverse=false&includestatus=false&includemetadata=false&excludeblocked=true` + }) + } + + async getFollowedNamesResource() { + this.followedResources = await parentEpml.request('apiCall', { + url: `/arbitrary/resources?service=WEBSITE&default=true&limit=0&reverse=false&includestatus=true&includemetadata=true&namefilter=followedNames` + }) + } + + async getFollowedNamesRefresh() { + this.followedNames = await parentEpml.request('apiCall', { + url: `/lists/followedNames?apiKey=${this.getApiKey()}` + }) + } + + async getBlockedNamesResource() { + this.blockedResources = await parentEpml.request('apiCall', { + url: `/arbitrary/resources?service=WEBSITE&default=true&limit=0&reverse=false&includestatus=true&includemetadata=true&namefilter=blockedNames` + }) + } + + async getBlockedNamesRefresh() { + this.blockedNames = await parentEpml.request('apiCall', { + url: `/lists/blockedNames?apiKey=${this.getApiKey()}` + }) + } + + async getData(offset) { + const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] + const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port + + let jsonOffsetUrl = `${nodeUrl}/arbitrary/resources?service=WEBSITE&default=true&limit=20&offset=${offset}&reverse=false&includestatus=true&includemetadata=true&excludeblocked=true` + + const jsonOffsetRes = await fetch(jsonOffsetUrl) + + this.pageRes = await jsonOffsetRes.json() + } + + async updateItemsFromPage(page) { + if (page === undefined) { + return + } + + if (!this.pages) { + this.pages = Array.apply(null, { length: Math.ceil(this.resources.length / 20) }).map((item, index) => { + return index + 1 + }) + + let offset = 0 + + const prevBtn = document.createElement('button') + prevBtn.textContent = '<' + prevBtn.addEventListener('click', () => { + if (parseInt(this.pagesControl.querySelector('[selected]').textContent) > 1) { + offset = (parseInt(this.pagesControl.querySelector('[selected]').textContent) - 2) * 20 + } else { + offset = 0 + } + this.getData(offset) + const selectedPage = parseInt(this.pagesControl.querySelector('[selected]').textContent) + this.updateItemsFromPage(selectedPage - 1) + }) + this.pagesControl.appendChild(prevBtn) + + this.pages.forEach((pageNumber) => { + const pageBtn = document.createElement('button') + pageBtn.textContent = pageNumber + let offset = 0 + pageBtn.addEventListener('click', (e) => { + if (parseInt(e.target.textContent) > 1) { + offset = (parseInt(e.target.textContent) - 1) * 20 + } else { + offset = 0 + } + this.getData(offset) + this.updateItemsFromPage(parseInt(e.target.textContent)) + }) + if (pageNumber === page) { + pageBtn.setAttribute('selected', true) + } + this.pagesControl.appendChild(pageBtn) + }) + + const nextBtn = window.document.createElement('button') + nextBtn.textContent = '>' + nextBtn.addEventListener('click', () => { + if (parseInt(this.pagesControl.querySelector('[selected]').textContent) >= 1) { + offset = ((parseInt(this.pagesControl.querySelector('[selected]').textContent) + 1) * 20) - 20 + } else { + offset = 0 + } + + this.getData(offset) + const selectedPage = parseInt(this.pagesControl.querySelector('[selected]').textContent) + this.updateItemsFromPage(selectedPage + 1) + }) + + this.pagesControl.appendChild(nextBtn) + } + + const buttons = Array.from(this.pagesControl.children) + buttons.forEach((btn, index) => { + if (parseInt(btn.textContent) === page) { + btn.setAttribute('selected', true) + } else { + btn.removeAttribute('selected') + } + + if (index === 0) { + if (page === 1) { + btn.setAttribute('disabled', '') + } else { + btn.removeAttribute('disabled') + } + } + + if (index === buttons.length - 1) { + if (page === this.pages.length) { + btn.setAttribute('disabled', '') + } else { + btn.removeAttribute('disabled') + } + } + }) + } + + async showWebsites() { + await this.getData(0) + await this.getArbitraryResources() + await this.getResourcesGrid() + await this.updateItemsFromPage(1, true) + } + + async refreshWebsites() { + await this.getData(0) + await this.getArbitraryResources() + await this.updateItemsFromPage(1, true) + } + + doSearch(e) { + this.searchResult() + } + + async searchResult() { + let searchName = this.shadowRoot.getElementById('searchName').value + + if (searchName.length === 0) { + let err1string = get('websitespage.schange34') + parentEpml.request('showSnackBar', `${err1string}`) + } else { + let searchResources = await parentEpml.request('apiCall', { + url: `/arbitrary/resources/search?service=WEBSITE&query=${searchName}&default=true&limit=5&reverse=false&includestatus=true&includemetadata=true` + }) + if (this.isEmptyArray(searchResources)) { + let err2string = get('websitespage.schange17') + parentEpml.request('showSnackBar', `${err2string}`) + } else { + this.searchResources = searchResources + } + } + } + + renderAvatar(websiteObj) { + let name = websiteObj.name + const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] + const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port + const url = `${nodeUrl}/arbitrary/THUMBNAIL/${name}/qortal_avatar?async=true}` + return html`` + } + + renderRelayModeText() { + if (this.relayMode === true) { + return html`
    ${translate('websitespage.schange18')} "relayModeEnabled": false ${translate('websitespage.schange19')} settings.json
    ` + } else if (this.relayMode === false) { + return html`
    ${translate('websitespage.schange20')} "relayModeEnabled": true ${translate('websitespage.schange19')} settings.json
    ` + } else { + return html`` + } + } + + renderPublishButton() { + // Only show the publish button if we have admin permissions on this node + // We can check the followed names array to achieve this + if (this.followedNames == null || !Array.isArray(this.followedNames)) { + return html`` + } else { + return html` this.publishWebsite()}>add${translate('websitespage.schange21')}` + } + } + + renderSearchButton() { + return html` this.openSearchDialog()}>search${translate('websitespage.schange4')}` + } + + openSearchDialog() { + this.searchResources = [] + this.shadowRoot.getElementById('searchName').value = '' + this.shadowRoot.getElementById('searchWebsiteDialog').show() + } + + publishWebsite() { + window.location.href = `../qdn/publish/index.html?service=WEBSITE&identifier=${this.identifier}&uploadType=zip&category=Website&showName=true&showService=false&showIdentifier=false&showMetadata=true` + } + + async followName(websiteObj) { + let name = websiteObj.name + + let items = [ + name + ] + + let namesJsonString = JSON.stringify({ 'items': items }) + + let ret = await parentEpml.request('apiCall', { + url: `/lists/followedNames?apiKey=${this.getApiKey()}`, + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: `${namesJsonString}` + }) + + if (ret === true) { + // Successfully followed - add to local list + // Remove it first by filtering the list - doing it this way ensures the UI updates + // immediately, as apposed to only adding if it doesn't already exist + this.followedNames = this.followedNames.filter(item => item != name) + this.followedNames.push(name) + } else { + let err3string = get('websitespage.schange22') + parentEpml.request('showSnackBar', `${err3string}`) + } + + return ret + } + + async followNameTab(websiteObj) { + let name = websiteObj.name + + let items = [ + name + ] + + let namesJsonString = JSON.stringify({ 'items': items }) + + let ret = await parentEpml.request('apiCall', { + url: `/lists/followedNames?apiKey=${this.getApiKey()}`, + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: `${namesJsonString}` + }) + + if (ret === true) { + // Successfully followed - add to local list + // Remove it first by filtering the list - doing it this way ensures the UI updates + // immediately, as apposed to only adding if it doesn't already exist + this.followedNames = this.followedNames.filter(item => item != name) + this.followedNames.push(name) + await this.getFollowedNamesRefresh() + await this.getFollowedNamesResource() + } else { + let err3string = get('websitespage.schange22') + parentEpml.request('showSnackBar', `${err3string}`) + } + + return ret + } + + async unfollowName(websiteObj) { + let name = websiteObj.name + + let items = [ + name + ] + + let namesJsonString = JSON.stringify({ 'items': items }) + + let ret = await parentEpml.request('apiCall', { + url: `/lists/followedNames?apiKey=${this.getApiKey()}`, + method: 'DELETE', + headers: { + 'Content-Type': 'application/json' + }, + body: `${namesJsonString}` + }) + + if (ret === true) { + // Successfully unfollowed - remove from local list + this.followedNames = this.followedNames.filter(item => item != name) + } else { + let err4string = get('websitespage.schange23') + parentEpml.request('showSnackBar', `${err4string}`) + } + + return ret + } + + async unfollowNameTab(websiteObj) { + let name = websiteObj.name + + let items = [ + name + ] + + let namesJsonString = JSON.stringify({ 'items': items }) + + let ret = await parentEpml.request('apiCall', { + url: `/lists/followedNames?apiKey=${this.getApiKey()}`, + method: 'DELETE', + headers: { + 'Content-Type': 'application/json' + }, + body: `${namesJsonString}` + }) + + if (ret === true) { + // Successfully unfollowed - remove from local list + this.followedNames = this.followedNames.filter(item => item != name) + await this.getFollowedNamesRefresh() + await this.getFollowedNamesResource() + } else { + let err4string = get('websitespage.schange23') + parentEpml.request('showSnackBar', `${err4string}`) + } + + return ret + } + + async blockName(websiteObj) { + let name = websiteObj.name + + let items = [ + name + ] + + let namesJsonString = JSON.stringify({ 'items': items }) + + let ret = await parentEpml.request('apiCall', { + url: `/lists/blockedNames?apiKey=${this.getApiKey()}`, + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: `${namesJsonString}` + }) + + if (ret === true) { + // Successfully blocked - add to local list + // Remove it first by filtering the list - doing it this way ensures the UI updates + // immediately, as apposed to only adding if it doesn't already exist + this.blockedNames = this.blockedNames.filter(item => item != name) + this.blockedNames.push(name) + } else { + let err5string = get('websitespage.schange24') + parentEpml.request('showSnackBar', `${err5string}`) + } + + return ret + } + + async blockNameTab(websiteObj) { + let name = websiteObj.name + + let items = [ + name + ] + + let namesJsonString = JSON.stringify({ 'items': items }) + + let ret = await parentEpml.request('apiCall', { + url: `/lists/blockedNames?apiKey=${this.getApiKey()}`, + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: `${namesJsonString}` + }) + + if (ret === true) { + // Successfully blocked - add to local list + // Remove it first by filtering the list - doing it this way ensures the UI updates + // immediately, as apposed to only adding if it doesn't already exist + this.blockedNames = this.blockedNames.filter(item => item != name) + this.blockedNames.push(name) + await this.getBlockedNamesRefresh() + await this.getBlockedNamesResource() + } else { + let err5string = get('websitespage.schange24') + parentEpml.request('showSnackBar', `${err5string}`) + } + + return ret + } + + async unblockName(websiteObj) { + let name = websiteObj.name + + let items = [ + name + ] + + let namesJsonString = JSON.stringify({ 'items': items }) + + let ret = await parentEpml.request('apiCall', { + url: `/lists/blockedNames?apiKey=${this.getApiKey()}`, + method: 'DELETE', + headers: { + 'Content-Type': 'application/json' + }, + body: `${namesJsonString}` + }) + + if (ret === true) { + // Successfully unblocked - remove from local list + this.blockedNames = this.blockedNames.filter(item => item != name) + } else { + let err6string = get('websitespage.schange25') + parentEpml.request('showSnackBar', `${err6string}`) + } + + return ret + } + + async unblockNameTab(websiteObj) { + let name = websiteObj.name + + let items = [ + name + ] + + let namesJsonString = JSON.stringify({ 'items': items }) + + let ret = await parentEpml.request('apiCall', { + url: `/lists/blockedNames?apiKey=${this.getApiKey()}`, + method: 'DELETE', + headers: { + 'Content-Type': 'application/json' + }, + body: `${namesJsonString}` + }) + + if (ret === true) { + // Successfully unblocked - remove from local list + this.blockedNames = this.blockedNames.filter(item => item != name) + await this.getBlockedNamesRefresh() + await this.getBlockedNamesResource() + } else { + let err6string = get('websitespage.schange25') + parentEpml.request('showSnackBar', `${err6string}`) + } + + return ret + } + + renderInfo(websiteObj) { + let name = websiteObj.name + let title = name + let description = '' + let categoryName = this.renderCatText() + let tags = '' + let sizeReadable = '' + + if (websiteObj.metadata != null) { + title = websiteObj.metadata.title + description = websiteObj.metadata.description + categoryName = websiteObj.metadata.categoryName + if (websiteObj.metadata.tags != null && websiteObj.metadata.tags.length > 0) { + tags = 'Tags: ' + websiteObj.metadata.tags.join(', ') + } + } + + if (websiteObj.size != null) { + sizeReadable = this.bytesToSize(websiteObj.size) + } + + return html` +
    + ${title} +
    +
    ${description}
    +
    + ${categoryName}  + ${tags.length > 0 ? " | " : ""}  + ${tags}  + ${sizeReadable.length > 0 ? " | " : ""}  + ${translate("websitespage.schange27")}: ${sizeReadable} +
    + ` + } + + renderPublishedBy(websiteObj) { + return html` +
    ${websiteObj.name}
    +
    + ${translate('websitespage.schange28')}: ${websiteObj.status.title} +
    + ` + } + + renderSize(websiteObj) { + if (websiteObj.size === null) { + return html`` + } + + let sizeReadable = this.bytesToSize(websiteObj.size) + + return html`${sizeReadable}` + } + + renderFollowUnfollowButton(websiteObj) { + let name = websiteObj.name + + // Only show the follow/unfollow button if we have permission to modify the list on this node + if (this.followedNames == null || !Array.isArray(this.followedNames)) { + return html`` + } + + if (this.followedNames.indexOf(name) === -1) { + // render follow button + return html` this.followName(websiteObj)}>add_to_queue ${translate('websitespage.schange29')}` + } else { + // render unfollow button + return html` this.unfollowName(websiteObj)}>remove_from_queue ${translate('websitespage.schange30')}` + } + } + + renderFollowUnfollowButtonTab(websiteObj) { + let name = websiteObj.name + + // Only show the follow/unfollow button if we have permission to modify the list on this node + if (this.followedNames == null || !Array.isArray(this.followedNames)) { + return html`` + } + + if (this.followedNames.indexOf(name) === -1) { + // render follow button + return html` this.followNameTab(websiteObj)}>add_to_queue ${translate('websitespage.schange29')}` + } else { + // render unfollow button + return html` this.unfollowNameTab(websiteObj)}>remove_from_queue ${translate('websitespage.schange30')}` + } + } + + renderBlockUnblockButton(websiteObj) { + let name = websiteObj.name + + // Only show the block/unblock button if we have permission to modify the list on this node + if (this.blockedNames == null || !Array.isArray(this.blockedNames)) { + return html`` + } + + if (this.blockedNames.indexOf(name) === -1) { + // render block button + return html` this.blockName(websiteObj)}>block ${translate('websitespage.schange31')}` + } else { + // render unblock button + return html` this.unblockName(websiteObj)}>radio_button_unchecked ${translate('websitespage.schange32')}` + } + } + + renderBlockUnblockButtonTab(websiteObj) { + let name = websiteObj.name + + // Only show the block/unblock button if we have permission to modify the list on this node + if (this.blockedNames == null || !Array.isArray(this.blockedNames)) { + return html`` + } + + if (this.blockedNames.indexOf(name) === -1) { + // render block button + return html` this.blockNameTab(websiteObj)}>block ${translate('websitespage.schange31')}` + } else { + // render unblock button + return html` this.unblockNameTab(websiteObj)}>radio_button_unchecked ${translate('websitespage.schange32')}` + } + } + + bytesToSize(bytes) { + var sizes = ['bytes', 'KB', 'MB', 'GB', 'TB'] + if (bytes == 0) return '0 bytes' + var i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024))) + return Math.round(bytes / Math.pow(1024, i), 2) + ' ' + sizes[i] + } + + // Standard functions + getApiKey() { + const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] + return myNode.apiKey + } + + isEmptyArray(arr) { + if (!arr) { return true } + return arr.length === 0 + } + + round(number) { + return (Math.round(parseFloat(number) * 1e8) / 1e8).toFixed(8) + } +} + +window.customElements.define('q-websites', QWebsites) \ No newline at end of file diff --git a/plugins/plugins/core/qdn/browser/browser.src.js b/plugins/plugins/core/qdn/browser/browser.src.js index 8d0c5ad5..60fb6e53 100644 --- a/plugins/plugins/core/qdn/browser/browser.src.js +++ b/plugins/plugins/core/qdn/browser/browser.src.js @@ -1,19 +1,8 @@ -import {css, html, LitElement} from 'lit' -import {Epml} from '../../../../epml' -import isElectron from 'is-electron' -import {get, registerTranslateConfig, translate, use} from '../../../../../core/translate' -import ShortUniqueId from 'short-unique-id'; -import FileSaver from 'file-saver' -import * as actions from '../../components/qdn-action-types' -import '@material/mwc-button' -import '@material/mwc-icon' -import '@material/mwc-checkbox' -import WebWorker from 'web-worker:./computePowWorkerFile.src.js' -import WebWorkerChat from 'web-worker:./computePowWorker.src.js' -import {publishData} from '../../../utils/publish-image.js' -import {Loader} from '../../../utils/loader.js'; -import {QORT_DECIMALS} from '../../../../../crypto/api/constants' -import {mimeToExtensionMap} from '../../components/qdn-action-constants'; +import { html, LitElement } from 'lit' +import { Epml } from '../../../../epml' +import { Loader, publishData } from '../../../utils/classes' +import { QORT_DECIMALS } from '../../../../../crypto/api/constants' +import { mimeToExtensionMap } from '../../components/qdn-action-constants' import { base64ToUint8Array, decryptDeprecatedSingle, @@ -22,13 +11,25 @@ import { fileToBase64, uint8ArrayStartsWith, uint8ArrayToBase64 -} from '../../components/qdn-action-encryption'; +} from '../../components/qdn-action-encryption' +import { webBrowserStyles, webBrowserModalStyles } from '../../components/plugins-css' +import * as actions from '../../components/qdn-action-types' +import isElectron from 'is-electron' +import ShortUniqueId from 'short-unique-id' +import FileSaver from 'file-saver' +import WebWorker from 'web-worker:./computePowWorkerFile.js' +import WebWorkerChat from 'web-worker:./computePowWorker.js' +import '@material/mwc-button' +import '@material/mwc-icon' +import '@material/mwc-checkbox' +// Multi language support +import { get, registerTranslateConfig, translate, use } from '../../../../../core/translate' registerTranslateConfig({ - loader: (lang) => fetch(`/language/${lang}.json`).then((res) => res.json()) + loader: lang => fetch(`/language/${lang}.json`).then(res => res.json()) }) -const parentEpml = new Epml({ type: 'WINDOW', source: window.parent }); +const parentEpml = new Epml({ type: 'WINDOW', source: window.parent }) class WebBrowser extends LitElement { static get properties() { @@ -60,77 +61,7 @@ class WebBrowser extends LitElement { } static get styles() { - return css` - * { - --mdc-theme-primary: rgb(3, 169, 244); - --mdc-theme-secondary: var(--mdc-theme-primary); - --paper-input-container-focus-color: var(--mdc-theme-primary); - --mdc-checkbox-unchecked-color: var(--black); - --mdc-theme-on-surface: var(--black); - --mdc-checkbox-disabled-color: var(--black); - --mdc-checkbox-ink-color: var(--black); - } - - #websitesWrapper paper-button { - float: right; - } - - #websitesWrapper .buttons { - width: auto !important; - } - - .address-bar { - position: absolute; - top: 0; - left: 0; - right: 0; - height: 100px; - background-color: var(--white); - height: 36px; - } - - .address-bar-button mwc-icon { - width: 20px; - } - - .iframe-container { - position: absolute; - top: 36px; - left: 0; - right: 0; - bottom: 0; - border-top: 1px solid var(--black); - } - - .iframe-container iframe { - display: block; - width: 100%; - height: 100%; - border: none; - background-color: var(--white); - } - - input[type='text'] { - margin: 0; - padding: 2px 0 0 20px; - border: 0; - height: 34px; - font-size: 16px; - background-color: var(--white); - } - input { - outline: none - } - - - paper-progress { - --paper-progress-active-color: var(--mdc-theme-primary); - } - - .float-right { - float: right; - } - `; + return [webBrowserStyles] } constructor() { @@ -142,15 +73,8 @@ class WebBrowser extends LitElement { const urlParams = new URLSearchParams(window.location.search) this.name = urlParams.get('name') this.service = urlParams.get('service') - this.identifier = - urlParams.get('identifier') != null - ? urlParams.get('identifier') - : null - this.path = - urlParams.get('path') != null - ? (urlParams.get('path').startsWith('/') ? '' : '/') + - urlParams.get('path') - : '' + this.identifier = urlParams.get('identifier') != null ? urlParams.get('identifier') : null + this.path = urlParams.get('path') != null ? (urlParams.get('path').startsWith('/') ? '' : '/') + urlParams.get('path') : '' this.preview = urlParams.get('preview') this.link = urlParams.get('link') this.dev = urlParams.get('dev') @@ -166,9 +90,11 @@ class WebBrowser extends LitElement { displayUrl = 'qortal://app/development' } else { displayUrl = 'qortal://' + this.service + '/' + this.name + if (this.identifier && this.identifier != 'null' && this.identifier != 'default') { displayUrl = displayUrl.concat('/' + this.identifier) } + if (this.path != null && this.path != '/') { displayUrl = displayUrl.concat(this.path) } @@ -178,8 +104,9 @@ class WebBrowser extends LitElement { const getFollowedNames = async () => { this.followedNames = await parentEpml.request('apiCall', { - url: `/lists/followedNames?apiKey=${this.getApiKey()}`, + url: `/lists/followedNames?apiKey=${this.getApiKey()}` }) + setTimeout( getFollowedNames, this.config.user.nodeSettings.pingInterval @@ -188,8 +115,9 @@ class WebBrowser extends LitElement { const getBlockedNames = async () => { this.blockedNames = await parentEpml.request('apiCall', { - url: `/lists/blockedNames?apiKey=${this.getApiKey()}`, + url: `/lists/blockedNames?apiKey=${this.getApiKey()}` }) + setTimeout( getBlockedNames, this.config.user.nodeSettings.pingInterval @@ -197,12 +125,8 @@ class WebBrowser extends LitElement { } const render = () => { - const myNode = - window.parent.reduxStore.getState().app.nodeConfig.knownNodes[ - window.parent.reduxStore.getState().app.nodeConfig.node - ] - const nodeUrl = - myNode.protocol + '://' + myNode.domain + ':' + myNode.port + const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] + const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port if (this.preview != null && this.preview.length > 0) { // In preview mode we access the preview URL path directly @@ -211,10 +135,7 @@ class WebBrowser extends LitElement { this.url = `${this.link}` } else { // Normal mode - - this.url = `${nodeUrl}/render/${this.service}/${this.name}${this.path != null ? this.path : '' - }?theme=${this.theme}&identifier=${(this.identifier != null && this.identifier != 'null') ? this.identifier : '' - }` + this.url = `${nodeUrl}/render/${this.service}/${this.name}${this.path != null ? this.path : ''}?theme=${this.theme}&identifier=${(this.identifier != null && this.identifier != 'null') ? this.identifier : ''}` } } @@ -231,7 +152,10 @@ class WebBrowser extends LitElement { parentEpml.ready().then(() => { parentEpml.subscribe('selected_address', async (selectedAddress) => { selectedAddress = JSON.parse(selectedAddress) - if (!selectedAddress || Object.entries(selectedAddress).length === 0) return + + if (!selectedAddress || Object.entries(selectedAddress).length === 0) { + return + } this.selectedAddress = selectedAddress this.btcWallet = window.parent.reduxStore.getState().app.selectedAddress.btcWallet @@ -241,6 +165,7 @@ class WebBrowser extends LitElement { this.rvnWallet = window.parent.reduxStore.getState().app.selectedAddress.rvnWallet this.arrrWallet = window.parent.reduxStore.getState().app.selectedAddress.arrrWallet }) + parentEpml.subscribe('config', (c) => { this.config = JSON.parse(c) if (!configLoaded) { @@ -253,119 +178,28 @@ class WebBrowser extends LitElement { }) } - async extractComponents(url) { - if (!url.startsWith("qortal://")) { - return null - } - - url = url.replace(/^(qortal\:\/\/)/, "") - if (url.includes("/")) { - let parts = url.split("/") - const service = parts[0].toUpperCase() - parts.shift() - const name = parts[0] - parts.shift() - let identifier - if (parts.length > 0) { - identifier = parts[0] // Do not shift yet - // Check if a resource exists with this service, name and identifier combination - let responseObj = await parentEpml.request('apiCall', { - url: `/arbitrary/resource/status/${service}/${name}/${identifier}?apiKey=${this.getApiKey()}` - }) - - if (responseObj.totalChunkCount > 0) { - // Identifier exists, so don't include it in the path - parts.shift() - } - else { - identifier = null - } - } - const path = parts.join("/") - const components = {} - components["service"] = service - components["name"] = name - components["identifier"] = identifier - components["path"] = path - return components - } - - return null - } - - async _handleKeyDown(e) { - if (e.key === 'Enter') { - let newQuery = e.target.value - if (newQuery.endsWith('/')) { - newQuery = newQuery.slice(0, -1) - } - const res = await this.extractComponents(newQuery) - if (!res) return - const { service, name, identifier, path } = res - let query = `?service=${service}` - if (name) { - query = query + `&name=${name}` - } - if (identifier) { - query = query + `&identifier=${identifier}` - } - if (path) { - query = query + `&path=${path}` - } - window.location = window.location.origin + window.location.pathname + query - } - } - - async linkOpenNewTab(link) { - - let newQuery = link - if (newQuery.endsWith('/')) { - newQuery = newQuery.slice(0, -1) - } - const res = await this.extractComponents(newQuery) - if (!res) return - const { service, name, identifier, path } = res - let query = `?service=${service}` - if (name) { - query = query + `&name=${name}` - } - if (identifier) { - query = query + `&identifier=${identifier}` - } - if (path) { - query = query + `&path=${path}` - } - - window.parent.reduxStore.dispatch(window.parent.reduxAction.setNewTab({ - url: `qdn/browser/index.html${query}`, - id: this.uid.rnd(), - myPlugObj: { - "url": service === 'WEBSITE' ? "websites" : "qapps", - "domain": "core", - "page": `qdn/browser/index.html${query}`, - "title": name, - "icon": service === 'WEBSITE' ? 'vaadin:desktop' : 'vaadin:external-browser', - "mwcicon": service === 'WEBSITE' ? 'desktop_mac' : 'open_in_browser', - "menus": [], - "parent": false - } - })) - - } - render() { - return html`
    - this.goBack()} title="${translate('general.back')}" class="address-bar-button">arrow_back_ios - this.goForward()} title="${translate('browserpage.bchange1')}" class="address-bar-button">arrow_forward_ios - this.refresh()} title="${translate('browserpage.bchange2')}" class="address-bar-button">refresh - this.goBackToList()} title="${translate('browserpage.bchange3')}" class="address-bar-button">home + this.goBack()} title="${translate('general.back')}" class="address-bar-button"> + arrow_back_ios + + this.goForward()} title="${translate('browserpage.bchange1')}" class="address-bar-button"> + arrow_forward_ios + + this.refresh()} title="${translate('browserpage.bchange2')}" class="address-bar-button"> + refresh + + this.goBackToList()} title="${translate('browserpage.bchange3')}" class="address-bar-button"> + home + ${this.renderFullScreen()} - this.delete()} title="${translate('browserpage.bchange4')} ${this.service} ${this.name} ${translate('browserpage.bchange5')}" class="address-bar-button float-right">delete + this.delete()} title="${translate('browserpage.bchange4')} ${this.service} ${this.name} ${translate('browserpage.bchange5')}" class="address-bar-button float-right"> + delete + ${this.renderBlockUnblockButton()} ${this.renderFollowUnfollowButton()}
    @@ -376,358 +210,7 @@ class WebBrowser extends LitElement {
    - `; - } - - renderFullScreen() { - if (window.innerHeight == screen.height) { - return html` - this.exitFullScreen()} - title="${translate('browserpage.bchange38')}" - class="address-bar-button float-right" - > - fullscreen_exit - - ` - } else { - return html` - this.goFullScreen()} - title="${translate('browserpage.bchange37')}" - class="address-bar-button float-right" - > - fullscreen - - ` - } - } - - goFullScreen() { - var elem = this.shadowRoot.getElementById('websitesWrapper') - - if (elem.requestFullscreen) { - elem.requestFullscreen() - } else if (elem.mozRequestFullScreen) { - elem.mozRequestFullScreen() - } else if (elem.webkitRequestFullscreen) { - elem.webkitRequestFullscreen() - } else if (elem.msRequestFullscreen) { - elem.msRequestFullscreen() - } - - this.renderFullScreen() - } - - exitFullScreen() { - if (document.exitFullscreen) { - document.exitFullscreen() - } else if (document.mozCancelFullScreen) { - document.mozCancelFullScreen() - } else if (document.webkitExitFullscreen) { - document.webkitExitFullscreen() - } else if (document.msExitFullscreen) { - document.msExitFullscreen() - } - - this.renderFullScreen() - } - - async unitJoinFee() { - const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] - const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port - const url = `${nodeUrl}/transactions/unitfee?txType=JOIN_GROUP` - const response = await fetch(url) - if (!response.ok) { - throw new Error('Error when fetching join fee') - } - - const data = await response.json() - return (Number(data) / 1e8).toFixed(8) - } - - async deployAtFee() { - const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] - const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port - const url = `${nodeUrl}/transactions/unitfee?txType=DEPLOY_AT` - const response = await fetch(url) - if (!response.ok) { - throw new Error('Error when fetching join fee') - } - - const data = await response.json() - return (Number(data) / 1e8).toFixed(8) - } - - async getArbitraryFee() { - const timestamp = Date.now() - const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] - const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port - const url = `${nodeUrl}/transactions/unitfee?txType=ARBITRARY×tamp=${timestamp}` - const response = await fetch(url) - if (!response.ok) { - throw new Error('Error when fetching arbitrary fee') - } - const data = await response.json() - const arbitraryFee = (Number(data) / 1e8).toFixed(8) - return { - timestamp, - fee: Number(data), - feeToShow: arbitraryFee - } - } - async sendQortFee() { - const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] - const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port - const url = `${nodeUrl}/transactions/unitfee?txType=PAYMENT` - const response = await fetch(url) - if (!response.ok) { - throw new Error('Error when fetching join fee') - } - - const data = await response.json() - return (Number(data) / 1e8).toFixed(8) - } - - async unitVoteFee() { - const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] - const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port - const url = `${nodeUrl}/transactions/unitfee?txType=VOTE_ON_POLL` - const response = await fetch(url) - if (!response.ok) { - throw new Error('Error when fetching vote fee') - } - - const data = await response.json() - return (Number(data) / 1e8).toFixed(8) - } - - async unitCreatePollFee() { - const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] - const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port - const url = `${nodeUrl}/transactions/unitfee?txType=CREATE_POLL` - const response = await fetch(url) - if (!response.ok) { - throw new Error('Error when fetching vote fee') - } - - const data = await response.json() - return (Number(data) / 1e8).toFixed(8) - } - - async _joinGroup(groupId, groupName) { - const joinFeeInput = await this.unitJoinFee() - const getLastRef = async () => { - return await parentEpml.request('apiCall', { - type: 'api', - url: `/addresses/lastreference/${this.selectedAddress.address}` - }) - } - - const validateReceiver = async () => { - let lastRef = await getLastRef() - let myTransaction = await makeTransactionRequest(lastRef) - return getTxnRequestResponse(myTransaction) - } - - const makeTransactionRequest = async (lastRef) => { - let groupdialog1 = get("transactions.groupdialog1") - let groupdialog2 = get("transactions.groupdialog2") - return await parentEpml.request('transaction', { - type: 31, - nonce: this.selectedAddress.nonce, - params: { - fee: joinFeeInput, - registrantAddress: this.selectedAddress.address, - rGroupName: groupName, - rGroupId: groupId, - lastReference: lastRef, - groupdialog1: groupdialog1, - groupdialog2: groupdialog2 - }, - apiVersion: 2 - }) - } - - const getTxnRequestResponse = (txnResponse) => { - if (txnResponse.success === false && txnResponse.message) { - throw new Error(txnResponse.message) - } else if (txnResponse.success === true && !txnResponse.data.error) { - return txnResponse.data - } else if (txnResponse.data && txnResponse.data.message) { - throw new Error(txnResponse.data.message) - } else { - throw new Error('Server error. Could not perform action.') - } - } - return await validateReceiver() - - } - - async _deployAt(name, description, tags, creationBytes, amount, assetId, atType) { - const deployAtFee = await this.deployAtFee() - const getLastRef = async () => { - return await parentEpml.request('apiCall', { - type: 'api', - url: `/addresses/lastreference/${this.selectedAddress.address}` - }) - } - - const validateReceiver = async () => { - let lastRef = await getLastRef() - let myTransaction = await makeTransactionRequest(lastRef) - return getTxnRequestResponse(myTransaction) - } - - const makeTransactionRequest = async (lastRef) => { - let deployAtdialog1 = get("transactions.deployAtdialog1") - let deployAtdialog2 = get("transactions.deployAtdialog2") - let deployAtdialog3 = get("transactions.deployAtdialog3") - let deployAtdialog4 = get("walletpage.wchange12") - return await parentEpml.request('transaction', { - type: 16, - nonce: this.selectedAddress.nonce, - params: { - fee: deployAtFee, - rName: name, - rDescription: description, - rTags: tags, - rAmount: amount, - rAssetId: assetId, - rCreationBytes: creationBytes, - atType: atType, - lastReference: lastRef, - atDeployDialog1: deployAtdialog1, - atDeployDialog2: deployAtdialog2, - atDeployDialog3: deployAtdialog3, - atDeployDialog4: deployAtdialog4 - }, - apiVersion: 2 - }) - } - - const getTxnRequestResponse = (txnResponse) => { - if (txnResponse.success === false && txnResponse.message) { - throw new Error(txnResponse.message) - } else if (txnResponse.success === true && !txnResponse.data.error) { - return txnResponse.data - } else if (txnResponse.data && txnResponse.data.message) { - throw new Error(txnResponse.data.message) - } else { - throw new Error('Server error. Could not perform action.') - } - } - return await validateReceiver() - - } - - async _voteOnPoll(pollName, optionIndex) { - const voteFeeInput = await this.unitVoteFee() - const getLastRef = async () => { - return await parentEpml.request('apiCall', { - type: 'api', - url: `/addresses/lastreference/${this.selectedAddress.address}` - }) - } - - const validateReceiver = async () => { - let lastRef = await getLastRef() - let myTransaction = await makeTransactionRequest(lastRef) - return getTxnRequestResponse(myTransaction) - } - - const makeTransactionRequest = async (lastRef) => { - let votedialog1 = get("transactions.votedialog1") - let votedialog2 = get("transactions.votedialog2") - let feeDialog = get("walletpage.wchange12") - - return await parentEpml.request('transaction', { - type: 9, - nonce: this.selectedAddress.nonce, - params: { - fee: voteFeeInput, - voterAddress: this.selectedAddress.address, - rPollName: pollName, - rOptionIndex: optionIndex, - lastReference: lastRef, - votedialog1: votedialog1, - votedialog2: votedialog2, - feeDialog - }, - apiVersion: 2 - }) - } - - const getTxnRequestResponse = (txnResponse) => { - if (txnResponse.success === false && txnResponse.message) { - throw new Error(txnResponse.message) - } else if (txnResponse.success === true && !txnResponse.data.error) { - return txnResponse.data - } else if (txnResponse.data && txnResponse.data.message) { - throw new Error(txnResponse.data.message) - } else { - throw new Error('Server error. Could not perform action.') - } - } - return await validateReceiver() - - } - - async _createPoll(pollName, pollDescription, options, pollOwnerAddress) { - const voteFeeInput = await this.unitCreatePollFee() - const getLastRef = async () => { - return await parentEpml.request('apiCall', { - type: 'api', - url: `/addresses/lastreference/${this.selectedAddress.address}` - }) - } - - const validateReceiver = async () => { - let lastRef = await getLastRef() - let myTransaction = await makeTransactionRequest(lastRef) - return getTxnRequestResponse(myTransaction) - } - - const makeTransactionRequest = async (lastRef) => { - let votedialog3 = get("transactions.votedialog3") - let votedialog4 = get("transactions.votedialog4") - let votedialog5 = get("transactions.votedialog5") - let votedialog6 = get("transactions.votedialog6") - let feeDialog = get("walletpage.wchange12") - - return await parentEpml.request('transaction', { - type: 8, - nonce: this.selectedAddress.nonce, - params: { - fee: voteFeeInput, - ownerAddress: pollOwnerAddress, - rPollName: pollName, - rPollDesc: pollDescription, - rOptions: options, - lastReference: lastRef, - votedialog3: votedialog3, - votedialog4: votedialog4, - votedialog5: votedialog5, - votedialog6: votedialog6, - feeDialog - }, - apiVersion: 2 - }) - } - - const getTxnRequestResponse = (txnResponse) => { - if (txnResponse.success === false && txnResponse.message) { - throw new Error(txnResponse.message) - } else if (txnResponse.success === true && !txnResponse.data.error) { - return txnResponse.data - } else if (txnResponse.data && txnResponse.data.message) { - throw new Error(txnResponse.data.message) - } else { - throw new Error('Server error. Could not perform action.') - } - } - return await validateReceiver() - + ` } firstUpdated() { @@ -752,6 +235,7 @@ class WebBrowser extends LitElement { } else { this.theme = 'light' } + document.querySelector('html').setAttribute('theme', this.theme) }) @@ -764,12 +248,7 @@ class WebBrowser extends LitElement { } window.addEventListener('message', async (event) => { - if ( - event == null || - event.data == null || - event.data.length == 0 || - event.data.action == null - ) { + if (event == null || event.data == null || event.data.length == 0 || event.data.action == null) { return } @@ -778,7 +257,6 @@ class WebBrowser extends LitElement { switch (data.action) { case actions.GET_USER_ACCOUNT: { - let skip = false if (window.parent.reduxStore.getState().app.qAPPAutoAuth) { skip = true @@ -829,16 +307,14 @@ class WebBrowser extends LitElement { if (encryptDataResponse) { data64 = encryptDataResponse response = JSON.stringify(encryptDataResponse) - break; + break } else { dataSentBack['error'] = "Unable to encrypt" response = JSON.stringify(dataSentBack) break } - } catch (error) { - const data = {} data['error'] = error.message || "Error in encrypting data" response = JSON.stringify(data) @@ -847,9 +323,7 @@ class WebBrowser extends LitElement { } case actions.DECRYPT_DATA: { - const { encryptedData, publicKey } = data - try { let data = {} if (!encryptedData) { @@ -861,19 +335,14 @@ class WebBrowser extends LitElement { const uint8Array = base64ToUint8Array(encryptedData) const startsWithQortalEncryptedData = uint8ArrayStartsWith(uint8Array, "qortalEncryptedData") if (startsWithQortalEncryptedData) { - if (!publicKey) { data['error'] = `Missing fields: publicKey` response = JSON.stringify(data) break } - - const decryptedDataToBase64 = decryptDeprecatedSingle(uint8Array, publicKey) response = JSON.stringify(decryptedDataToBase64) break - - } const startsWithQortalGroupEncryptedData = uint8ArrayStartsWith(uint8Array, "qortalGroupEncryptedData") if (startsWithQortalGroupEncryptedData) { @@ -884,12 +353,10 @@ class WebBrowser extends LitElement { break } - data['error'] = "Unable to decrypt" response = JSON.stringify(data) break } catch (error) { - const data = {} data['error'] = error.message || "Error in decrypting data" response = JSON.stringify(data) @@ -900,13 +367,11 @@ class WebBrowser extends LitElement { case actions.GET_LIST_ITEMS: { const requiredFields = ['list_name'] const missingFields = [] - requiredFields.forEach((field) => { if (!data[field]) { missingFields.push(field) } }) - if (missingFields.length > 0) { const missingFieldsString = missingFields.join(', ') const errorMsg = `Missing fields: ${missingFieldsString}` @@ -928,14 +393,11 @@ class WebBrowser extends LitElement { } ) } - - if (res1 && res1.action === 'accept' || skip) { - try { const list = await parentEpml.request('apiCall', { type: 'api', - url: `/lists/${data.list_name}?apiKey=${this.getApiKey()}`, + url: `/lists/${data.list_name}?apiKey=${this.getApiKey()}` }) response = JSON.stringify(list) @@ -946,7 +408,6 @@ class WebBrowser extends LitElement { } finally { break } - } else { const data = {} data['error'] = "User declined to share list" @@ -958,13 +419,11 @@ class WebBrowser extends LitElement { case actions.ADD_LIST_ITEMS: { const requiredFields = ['list_name', 'items'] const missingFields = [] - requiredFields.forEach((field) => { if (!data[field]) { missingFields.push(field) } }) - if (missingFields.length > 0) { const missingFieldsString = missingFields.join(', ') const errorMsg = `Missing fields: ${missingFieldsString}` @@ -982,14 +441,11 @@ class WebBrowser extends LitElement { items: items } ) - if (res && res.action === 'accept') { - try { const body = { items: items, } - const bodyToString = JSON.stringify(body) response = await parentEpml.request('apiCall', { type: 'api', @@ -997,8 +453,8 @@ class WebBrowser extends LitElement { url: `/lists/${list_name}?apiKey=${this.getApiKey()}`, body: bodyToString, headers: { - 'Content-Type': 'application/json', - }, + 'Content-Type': 'application/json' + } }) } catch (error) { const data = {} @@ -1007,7 +463,6 @@ class WebBrowser extends LitElement { } finally { break } - } else { const data = {} data['error'] = "User declined add to list" @@ -1019,13 +474,11 @@ class WebBrowser extends LitElement { case actions.DELETE_LIST_ITEM: { const requiredFields = ['list_name', 'item'] const missingFields = [] - requiredFields.forEach((field) => { if (!data[field]) { missingFields.push(field) } }) - if (missingFields.length > 0) { const missingFieldsString = missingFields.join(', ') const errorMsg = `Missing fields: ${missingFieldsString}` @@ -1043,24 +496,20 @@ class WebBrowser extends LitElement { item: item } ) - if (res && res.action === 'accept') { - try { const body = { - items: [item], + items: [item] } - const bodyToString = JSON.stringify(body) - response = await parentEpml.request('apiCall', { type: 'api', method: 'DELETE', url: `/lists/${list_name}?apiKey=${this.getApiKey()}`, body: bodyToString, headers: { - 'Content-Type': 'application/json', - }, + 'Content-Type': 'application/json' + } }) } catch (error) { const data = {} @@ -1069,7 +518,6 @@ class WebBrowser extends LitElement { } finally { break } - } else { const data = {} data['error'] = "User declined add to list" @@ -1089,13 +537,9 @@ class WebBrowser extends LitElement { actions.GET_FRIENDS_LIST ) } - - if (res1 && res1.action === 'accept' || skip) { - try { let list = JSON.parse(localStorage.getItem('friends-my-friend-list') || "[]") - list = list.map((friend) => friend.name || "") response = JSON.stringify(list) } catch (error) { @@ -1103,9 +547,7 @@ class WebBrowser extends LitElement { data['error'] = "Error in retrieving friends list" response = JSON.stringify(data) } - break - } else { const data = {} data['error'] = "User declined to share friends list" @@ -1122,39 +564,30 @@ class WebBrowser extends LitElement { this.displayUrl = translate("appspage.schange40") return } - let url = 'qortal://' + data.service + '/' + data.name - this.path = - data.path != null - ? (data.path.startsWith('/') ? '' : '/') + data.path - : null - if ( - data.identifier != null && - data.identifier != '' && - data.identifier != 'default' - ) + this.path = data.path != null ? (data.path.startsWith('/') ? '' : '/') + data.path : null + if (data.identifier != null && data.identifier != '' && data.identifier != 'default') { url = url.concat('/' + data.identifier) - if (this.path != null && this.path != '/') + } + if (this.path != null && this.path != '/') { url = url.concat(this.path) + } this.name = data.name this.service = data.service this.identifier = data.identifier this.displayUrl = url - const frame = window.frameElement - let tabId = "" + let tabId = '' if (frame && frame.dataset.id) { tabId = frame.dataset.id } - if (data.name === 'Q-Mail') { localStorage.setItem("Q-Mail-last-visited", Date.now()) - } window.parent.reduxStore.dispatch(window.parent.reduxAction.addTabInfo({ name: data.name, service: data.service, - id: tabId ? tabId : "" + id: tabId ? tabId : '' })) return @@ -1168,27 +601,23 @@ class WebBrowser extends LitElement { response['error'] = 'missing count' break } - window.parent.reduxStore.dispatch(window.parent.reduxAction.setTabNotifications({ name: this.name, count: count })) response = true break - } case actions.PUBLISH_QDN_RESOURCE: { // optional fields: encrypt:boolean recipientPublicKey:string const requiredFields = ['service', 'name'] const missingFields = [] - requiredFields.forEach((field) => { if (!data[field]) { missingFields.push(field) } }) - if (missingFields.length > 0) { const missingFieldsString = missingFields.join(', ') const errorMsg = `Missing fields: ${missingFieldsString}` @@ -1221,7 +650,6 @@ class WebBrowser extends LitElement { if (data.identifier == null) { identifier = 'default' } - if (data.encrypt && (!data.publicKeys || (Array.isArray(data.publicKeys) && data.publicKeys.length === 0))) { let data = {} data['error'] = "Encrypting data requires public keys" @@ -1239,7 +667,6 @@ class WebBrowser extends LitElement { } const getArbitraryFee = await this.getArbitraryFee() feeAmount = getArbitraryFee.fee - if (data.encrypt) { try { const encryptDataResponse = encryptDataGroup({ @@ -1248,7 +675,6 @@ class WebBrowser extends LitElement { if (encryptDataResponse) { data64 = encryptDataResponse } - } catch (error) { const obj = {} obj['error'] = error.message || 'Upload failed due to failed encryption' @@ -1257,7 +683,6 @@ class WebBrowser extends LitElement { } } - const res2 = await showModalAndWait( actions.PUBLISH_QDN_RESOURCE, { @@ -1298,7 +723,6 @@ class WebBrowser extends LitElement { withFee: res2.userData.isWithFee === true, feeAmount: feeAmount }) - response = JSON.stringify(resPublish) worker.terminate() } catch (error) { @@ -1330,7 +754,6 @@ class WebBrowser extends LitElement { missingFields.push(field) } }) - if (missingFields.length > 0) { const missingFieldsString = missingFields.join(', ') const errorMsg = `Missing fields: ${missingFieldsString}` @@ -1368,7 +791,6 @@ class WebBrowser extends LitElement { feeAmount: getArbitraryFee.feeToShow } ) - if (res2.action === 'reject') { response = '{"error": "User declined request"}' break @@ -1380,13 +802,11 @@ class WebBrowser extends LitElement { try { const requiredFields = ['service', 'name'] const missingFields = [] - requiredFields.forEach((field) => { if (!resource[field]) { missingFields.push(field) } }) - if (missingFields.length > 0) { const missingFieldsString = missingFields.join(', ') const errorMsg = `Missing fields: ${missingFieldsString}` @@ -1396,7 +816,6 @@ class WebBrowser extends LitElement { }) continue } - if (!resource.file && !resource.data64) { const errorMsg = 'No data or file was submitted' failedPublishesIdentifiers.push({ @@ -1405,7 +824,6 @@ class WebBrowser extends LitElement { }) continue } - const service = resource.service const name = resource.name let identifier = resource.identifier @@ -1422,7 +840,6 @@ class WebBrowser extends LitElement { if (resource.identifier == null) { identifier = 'default' } - if (!data.encrypt && service.endsWith("_PRIVATE")) { const errorMsg = "Only encrypted data can go into private services" failedPublishesIdentifiers.push({ @@ -1434,18 +851,14 @@ class WebBrowser extends LitElement { if (data.file) { data64 = await fileToBase64(data.file) } - - if (data.encrypt) { try { - const encryptDataResponse = encryptDataGroup({ data64, publicKeys: data.publicKeys }) if (encryptDataResponse) { data64 = encryptDataResponse } - } catch (error) { const errorMsg = error.message || 'Upload failed due to failed encryption' failedPublishesIdentifiers.push({ @@ -1454,15 +867,12 @@ class WebBrowser extends LitElement { }) continue } - } if (resource.file && !data.encrypt) { data64 = await fileToBase64(resource.file) } - const worker = new WebWorker() try { - await publishData({ registeredName: encodeURIComponent(name), file: data64, @@ -1486,12 +896,11 @@ class WebBrowser extends LitElement { withFee: res2.userData.isWithFee === true, feeAmount: feeAmount }) - worker.terminate() await new Promise((res) => { setTimeout(() => { res() - }, 1000); + }, 1000) }) } catch (error) { worker.terminate() @@ -1501,16 +910,12 @@ class WebBrowser extends LitElement { identifier: resource.identifier }) } - } catch (error) { failedPublishesIdentifiers.push({ reason: "Unknown error", identifier: resource.identifier }) } - - - } this.loader.hide() if (failedPublishesIdentifiers.length > 0) { @@ -1523,23 +928,18 @@ class WebBrowser extends LitElement { this.loader.hide() break } - response = true break - - } case actions.VOTE_ON_POLL: { const requiredFields = ['pollName', 'optionIndex'] const missingFields = [] - requiredFields.forEach((field) => { if (!data[field] && data[field] !== 0) { missingFields.push(field) } }) - if (missingFields.length > 0) { const missingFieldsString = missingFields.join(', ') const errorMsg = `Missing fields: ${missingFieldsString}` @@ -1548,15 +948,13 @@ class WebBrowser extends LitElement { response = JSON.stringify(data) break } - const pollName = data.pollName const optionIndex = data.optionIndex - let pollInfo = null try { pollInfo = await parentEpml.request("apiCall", { type: "api", - url: `/polls/${encodeURIComponent(pollName)}`, + url: `/polls/${encodeURIComponent(pollName)}` }) } catch (error) { const errorMsg = (error && error.message) || 'Poll not found' @@ -1565,7 +963,6 @@ class WebBrowser extends LitElement { response = JSON.stringify(obj) break } - if (!pollInfo || pollInfo.error) { const errorMsg = (pollInfo && pollInfo.message) || 'Poll not found' let obj = {} @@ -1573,7 +970,6 @@ class WebBrowser extends LitElement { response = JSON.stringify(obj) break } - try { this.loader.show() const resVoteOnPoll = await this._voteOnPoll(pollName, optionIndex) @@ -1585,20 +981,17 @@ class WebBrowser extends LitElement { } finally { this.loader.hide() } - break } case actions.CREATE_POLL: { const requiredFields = ['pollName', 'pollDescription', 'pollOptions', 'pollOwnerAddress'] const missingFields = [] - requiredFields.forEach((field) => { if (!data[field]) { missingFields.push(field) } }) - if (missingFields.length > 0) { const missingFieldsString = missingFields.join(', ') const errorMsg = `Missing fields: ${missingFieldsString}` @@ -1607,12 +1000,10 @@ class WebBrowser extends LitElement { response = JSON.stringify(data) break } - const pollName = data.pollName const pollDescription = data.pollDescription const pollOptions = data.pollOptions const pollOwnerAddress = data.pollOwnerAddress - try { this.loader.show() const resCreatePoll = await this._createPoll(pollName, pollDescription, pollOptions, pollOwnerAddress) @@ -1624,7 +1015,6 @@ class WebBrowser extends LitElement { } finally { this.loader.hide() } - break } @@ -1635,7 +1025,6 @@ class WebBrowser extends LitElement { response = JSON.stringify(obj) break } - try { await this.linkOpenNewTab(data.qortalLink) response = true @@ -1647,12 +1036,10 @@ class WebBrowser extends LitElement { response = JSON.stringify(obj) break } - } case actions.NOTIFICATIONS_PERMISSION: { try { - const res = await showModalAndWait( actions.NOTIFICATIONS_PERMISSION, { @@ -1667,11 +1054,9 @@ class WebBrowser extends LitElement { response = false break } - } catch (error) { break } - } case actions.SEND_LOCAL_NOTIFICATION: { @@ -1685,7 +1070,6 @@ class WebBrowser extends LitElement { const interval = appInfo.interval if (lastNotification && interval) { const timeDifference = Date.now() - lastNotification - if (timeDifference > interval) { parentEpml.request('showNotification', { title, type: "qapp-local-notification", sound: '', url, options: { body: message, icon, badge: icon } @@ -1706,29 +1090,25 @@ class WebBrowser extends LitElement { } else { throw new Error(`invalid data`) } - } catch (error) { const obj = {} obj['error'] = error.message || "error in pushing notification" response = JSON.stringify(obj) break - } - } + case actions.SEND_CHAT_MESSAGE: { const message = data.message const recipient = data.destinationAddress const groupId = data.groupId const isRecipient = !groupId const sendMessage = async (messageText, chatReference) => { - let _reference = new Uint8Array(64) window.crypto.getRandomValues(_reference) let reference = window.parent.Base58.encode(_reference) const sendMessageRequest = async () => { let chatResponse - if (isRecipient) { chatResponse = await parentEpml.request('chat', { type: 18, @@ -1746,10 +1126,7 @@ class WebBrowser extends LitElement { isText: 1 } }) - - } - if (!isRecipient) { chatResponse = await parentEpml.request('chat', { type: 181, @@ -1767,20 +1144,15 @@ class WebBrowser extends LitElement { isText: 1 } }) - - } - return await _computePow(chatResponse) } - const _computePow = async (chatBytes) => { const difficulty = 8 const path = window.parent.location.origin + '/memory-pow/memory-pow.wasm.full' const worker = new WebWorkerChat() let nonce = null let chatBytesArray = null - await new Promise((res) => { worker.postMessage({ chatBytes, path, difficulty }) worker.onmessage = e => { @@ -1789,17 +1161,14 @@ class WebBrowser extends LitElement { res() } }) - let _response = await parentEpml.request('sign_chat', { nonce: this.selectedAddress.nonce, chatBytesArray: chatBytesArray, chatNonce: nonce, apiVersion: 2 }) - return getSendChatResponse(_response) } - const getSendChatResponse = (res) => { if (res.signature) { return res @@ -1809,22 +1178,18 @@ class WebBrowser extends LitElement { throw new Error('ERROR: Could not send message') } } - return await sendMessageRequest() } - const result = await showModalAndWait( actions.SEND_CHAT_MESSAGE ) if (result.action === "accept") { let hasPublicKey = true - if (isRecipient) { const res = await parentEpml.request('apiCall', { type: 'api', url: `/addresses/publickey/${recipient}` }) - if (res.error === 102) { this._publicKey.key = '' this._publicKey.hasPubKey = false @@ -1838,46 +1203,27 @@ class WebBrowser extends LitElement { hasPublicKey = false } } - - if (!hasPublicKey && isRecipient) { response = '{"error": "Cannot send an encrypted message to this user since they do not have their publickey on chain."}' break } - - - const tiptapJson = { type: 'doc', - content: [ - { - type: 'paragraph', - content: [ - { - type: 'text', - text: message, - }, - - ], - }, - ], + content: [{ + type: 'paragraph', + content: [{ + type: 'text', + text: message + }] + }] } - const messageObject = { messageText: tiptapJson, images: [''], repliedTo: '', version: 3 } - const stringifyMessageObject = JSON.stringify(messageObject) - // if (this.balance < 4) { - // this.myTrimmedMeassage = '' - // this.myTrimmedMeassage = stringifyMessageObject - // this.shadowRoot.getElementById('confirmDialog').open() - // } else { - // this.sendMessage(stringifyMessageObject, typeMessage) - // } try { this.loader.show() response = await sendMessage(stringifyMessageObject) @@ -1892,9 +1238,7 @@ class WebBrowser extends LitElement { response = '{"error": "Request could not be fulfilled"}' } finally { this.loader.hide() - } - } else { response = '{"error": "User declined request"}' } @@ -1909,13 +1253,11 @@ class WebBrowser extends LitElement { case actions.JOIN_GROUP: { const requiredFields = ['groupId'] const missingFields = [] - requiredFields.forEach((field) => { if (!data[field]) { missingFields.push(field) } }) - if (missingFields.length > 0) { const missingFieldsString = missingFields.join(', ') const errorMsg = `Missing fields: ${missingFieldsString}` @@ -1925,13 +1267,11 @@ class WebBrowser extends LitElement { break } const groupId = data.groupId - - let groupInfo = null try { groupInfo = await parentEpml.request("apiCall", { type: "api", - url: `/groups/${groupId}`, + url: `/groups/${groupId}` }) } catch (error) { const errorMsg = (error && error.message) || 'Group not found' @@ -1940,7 +1280,6 @@ class WebBrowser extends LitElement { response = JSON.stringify(obj) break } - if (!groupInfo || groupInfo.error) { const errorMsg = (groupInfo && groupInfo.message) || 'Group not found' let obj = {} @@ -1948,7 +1287,6 @@ class WebBrowser extends LitElement { response = JSON.stringify(obj) break } - try { this.loader.show() const resJoinGroup = await this._joinGroup(groupId, groupInfo.groupName) @@ -1960,7 +1298,6 @@ class WebBrowser extends LitElement { } finally { this.loader.hide() } - // Params: data.groupId // TODO: prompt user to join group. If they confirm, sign+process a JOIN_GROUP transaction // then set the response string from the core to the `response` variable (defined above) @@ -1970,16 +1307,13 @@ class WebBrowser extends LitElement { case actions.SAVE_FILE: { try { - const requiredFields = ['filename', 'blob'] const missingFields = [] - requiredFields.forEach((field) => { if (!data[field]) { missingFields.push(field) } }) - if (missingFields.length > 0) { const missingFieldsString = missingFields.join(', ') const errorMsg = `Missing fields: ${missingFieldsString}` @@ -1988,25 +1322,18 @@ class WebBrowser extends LitElement { response = JSON.stringify(data) break } - - - const filename = data.filename const blob = data.blob - const res = await showModalAndWait( actions.SAVE_FILE, { filename } ) - if (res.action === 'reject') { response = '{"error": "User declined request"}' break - } - const mimeType = blob.type || data.mimeType let backupExention = filename.split('.').pop() if (backupExention) { @@ -2033,7 +1360,6 @@ class WebBrowser extends LitElement { } } } - try { const fileHandle = await self.showSaveFilePicker({ suggestedName: filename, @@ -2041,10 +1367,8 @@ class WebBrowser extends LitElement { { description: mimeType, ...fileHandleOptions - }, + } ] - - }) const writeFile = async (fileHandle, contents) => { const writable = await fileHandle.createWritable() @@ -2061,7 +1385,6 @@ class WebBrowser extends LitElement { } FileSaver.saveAs(blob, filename) } - response = JSON.stringify(true) } catch (error) { const obj = {} @@ -2071,16 +1394,14 @@ class WebBrowser extends LitElement { break } - case 'DEPLOY_AT': { + case actions.DEPLOY_AT: { const requiredFields = ['name', 'description', 'tags', 'creationBytes', 'amount', 'assetId', 'type'] const missingFields = [] - requiredFields.forEach((field) => { if (!data[field] && data[field] !== 0) { missingFields.push(field) } }) - if (missingFields.length > 0) { const missingFieldsString = missingFields.join(', ') const errorMsg = `Missing fields: ${missingFieldsString}` @@ -2089,11 +1410,8 @@ class WebBrowser extends LitElement { response = JSON.stringify(data) break } - - try { this.loader.show() - const resDeployAt = await this._deployAt(data.name, data.description, data.tags, data.creationBytes, data.amount, data.assetId, data.type) response = JSON.stringify(resDeployAt) } catch (error) { @@ -2106,27 +1424,23 @@ class WebBrowser extends LitElement { break } - case 'GET_PROFILE_DATA': { + case actions.GET_PROFILE_DATA: { const defaultProperties = ['tagline', 'bio', 'wallets'] - const requiredFields = ['property']; - const missingFields = []; - + const requiredFields = ['property'] + const missingFields = [] requiredFields.forEach((field) => { if (!data[field] && data[field] !== 0) { - missingFields.push(field); + missingFields.push(field) } - }); - + }) if (missingFields.length > 0) { - const missingFieldsString = missingFields.join(', '); + const missingFieldsString = missingFields.join(', ') const errorMsg = `Missing fields: ${missingFieldsString}` - let data = {}; - data['error'] = errorMsg; - response = JSON.stringify(data); + let data = {} + data['error'] = errorMsg + response = JSON.stringify(data) break } - - try { const profileData = window.parent.reduxStore.getState().app.profileData if (!profileData) { @@ -2137,25 +1451,22 @@ class WebBrowser extends LitElement { if (propertyIndex !== -1) { const requestedData = profileData[property] if (requestedData) { - response = JSON.stringify(requestedData); + response = JSON.stringify(requestedData) break } else { throw new Error('Cannot find requested data') } } - if (property.includes('-private')) { const resPrivateProperty = await showModalAndWait( actions.GET_PROFILE_DATA, { - property - } - ); - + property + } + ) if (resPrivateProperty.action === 'accept') { - const requestedData = profileData.customData[property] if (requestedData) { - response = JSON.stringify(requestedData); + response = JSON.stringify(requestedData) break } else { throw new Error('Cannot find requested data') @@ -2166,42 +1477,38 @@ class WebBrowser extends LitElement { } else { const requestedData = profileData.customData[property] if (requestedData) { - response = JSON.stringify(requestedData); + response = JSON.stringify(requestedData) break } else { throw new Error('Cannot find requested data') } } - } catch (error) { - const obj = {}; - obj['error'] = error.message || 'Failed to join the group.'; - response = JSON.stringify(obj); + const obj = {} + obj['error'] = error.message || 'Failed to join the group.' + response = JSON.stringify(obj) } finally { - this.loader.hide(); + this.loader.hide() } - break; + break } - case 'SET_PROFILE_DATA': { - const requiredFields = ['property', 'data']; - const missingFields = []; + case actions.SET_PROFILE_DATA: { + const requiredFields = ['property', 'data'] + const missingFields = [] requiredFields.forEach((field) => { if (!data[field] && data[field] !== 0) { - missingFields.push(field); + missingFields.push(field) } - }); - + }) if (missingFields.length > 0) { - const missingFieldsString = missingFields.join(', '); + const missingFieldsString = missingFields.join(', ') const errorMsg = `Missing fields: ${missingFieldsString}` - let data = {}; - data['error'] = errorMsg; - response = JSON.stringify(data); + let data = {} + data['error'] = errorMsg + response = JSON.stringify(data) break } - - try { const property = data.property const payload = data.data @@ -2209,16 +1516,12 @@ class WebBrowser extends LitElement { const fee = await this.getArbitraryFee() const resSetPrivateProperty = await showModalAndWait( actions.SET_PROFILE_DATA, { - property, - fee: fee.feeToShow - } - ); - - + property, + fee: fee.feeToShow + } + ) if (resSetPrivateProperty.action !== 'accept') throw new Error('User declined permission') - //dispatch event and wait until I get a response to continue - // Create and dispatch custom event const customEvent = new CustomEvent('qortal-request-set-profile-data', { detail: { @@ -2226,102 +1529,91 @@ class WebBrowser extends LitElement { payload, uniqueId } - }); - window.parent.dispatchEvent(customEvent); - + }) + window.parent.dispatchEvent(customEvent) // Wait for response event const res = await new Promise((resolve, reject) => { function handleResponseEvent(event) { // Handle the data from the event, if any - const responseData = event.detail; + const responseData = event.detail if (responseData && responseData.uniqueId !== uniqueId) return // Clean up by removing the event listener once we've received the response - window.removeEventListener('qortal-request-set-profile-data-response', handleResponseEvent); + window.removeEventListener('qortal-request-set-profile-data-response', handleResponseEvent) if (responseData.response === 'saved') { - resolve(responseData); + resolve(responseData) } else { - reject(new Error('not saved')); + reject(new Error('not saved')) } } - // Set up an event listener to wait for the response - window.addEventListener('qortal-request-set-profile-data-response', handleResponseEvent); - }); + window.addEventListener('qortal-request-set-profile-data-response', handleResponseEvent) + }) if (!res.response) throw new Error('Failed to set property') - response = JSON.stringify(res.response); - + response = JSON.stringify(res.response) } catch (error) { - const obj = {}; - obj['error'] = error.message || 'Failed to set property.'; - response = JSON.stringify(obj); + const obj = {} + obj['error'] = error.message || 'Failed to set property.' + response = JSON.stringify(obj) } finally { - this.loader.hide(); + this.loader.hide() } - break; + break } - case 'OPEN_PROFILE': { - const requiredFields = ['name']; - const missingFields = []; - + case actions.OPEN_PROFILE: { + const requiredFields = ['name'] + const missingFields = [] requiredFields.forEach((field) => { if (!data[field] && data[field] !== 0) { - missingFields.push(field); + missingFields.push(field) } - }); - + }) if (missingFields.length > 0) { - const missingFieldsString = missingFields.join(', '); + const missingFieldsString = missingFields.join(', ') const errorMsg = `Missing fields: ${missingFieldsString}` - let data = {}; - data['error'] = errorMsg; - response = JSON.stringify(data); + let data = {} + data['error'] = errorMsg + response = JSON.stringify(data) break } - - try { const customEvent = new CustomEvent('open-visiting-profile', { detail: data.name - }); - window.parent.dispatchEvent(customEvent); - response = JSON.stringify(true); + }) + window.parent.dispatchEvent(customEvent) + response = JSON.stringify(true) } catch (error) { - const obj = {}; - obj['error'] = error.message || 'Failed to open profile'; - response = JSON.stringify(obj); + const obj = {} + obj['error'] = error.message || 'Failed to open profile' + response = JSON.stringify(obj) } - break; + break } - case actions.GET_USER_WALLET: { - const requiredFields = ['coin']; - const missingFields = []; - + const requiredFields = ['coin'] + const missingFields = [] requiredFields.forEach((field) => { if (!data[field]) { - missingFields.push(field); + missingFields.push(field) } - }); - + }) if (missingFields.length > 0) { - const missingFieldsString = missingFields.join(', '); + const missingFieldsString = missingFields.join(', ') const errorMsg = `Missing fields: ${missingFieldsString}` - let data = {}; - data['error'] = errorMsg; - response = JSON.stringify(data); + let data = {} + data['error'] = errorMsg + response = JSON.stringify(data) break } const res3 = await showModalAndWait( actions.GET_USER_WALLET - ); - + ) if (res3.action === 'accept') { - let coin = data.coin; - let userWallet = {}; - let arrrAddress = ""; + let coin = data.coin + let userWallet = {} + let arrrAddress = "" if (coin === "ARRR") { arrrAddress = await parentEpml.request('apiCall', { url: `/crosschain/arrr/walletaddress?apiKey=${this.getApiKey()}`, @@ -2360,24 +1652,22 @@ class WebBrowser extends LitElement { default: break } - response = JSON.stringify(userWallet); - break; + response = JSON.stringify(userWallet) + break } else if (res3.action === 'reject') { - response = '{"error": "User declined request"}'; + response = '{"error": "User declined request"}' } - break; + break } case actions.GET_WALLET_BALANCE: { const requiredFields = ['coin'] const missingFields = [] - requiredFields.forEach((field) => { if (!data[field]) { missingFields.push(field) } }) - if (missingFields.length > 0) { const missingFieldsString = missingFields.join(', ') const errorMsg = `Missing fields: ${missingFieldsString}` @@ -2393,7 +1683,6 @@ class WebBrowser extends LitElement { const res3 = await showModalAndWait( actions.GET_WALLET_BALANCE ) - if (res3.action === 'accept') { let coin = data.coin if (coin === "QORT") { @@ -2401,7 +1690,7 @@ class WebBrowser extends LitElement { try { this.loader.show() response = await parentEpml.request('apiCall', { - url: `/addresses/balance/${qortAddress}?apiKey=${this.getApiKey()}`, + url: `/addresses/balance/${qortAddress}?apiKey=${this.getApiKey()}` }) @@ -2417,7 +1706,6 @@ class WebBrowser extends LitElement { } else { let _url = `` let _body = null - switch (coin) { case 'BTC': _url = `/crosschain/btc/walletbalance?apiKey=${this.getApiKey()}` @@ -2451,7 +1739,7 @@ class WebBrowser extends LitElement { const res = await parentEpml.request('apiCall', { url: _url, method: 'POST', - body: _body, + body: _body }) if (isNaN(Number(res))) { const data = {} @@ -2474,19 +1762,17 @@ class WebBrowser extends LitElement { } else if (res3.action === 'reject') { response = '{"error": "User declined request"}' } - break } + case actions.GET_USER_WALLET_INFO: { const requiredFields = ['coin'] const missingFields = [] - requiredFields.forEach((field) => { if (!data[field]) { missingFields.push(field) } }) - if (missingFields.length > 0) { const missingFieldsString = missingFields.join(', ') const errorMsg = `Missing fields: ${missingFieldsString}` @@ -2495,23 +1781,17 @@ class WebBrowser extends LitElement { response = JSON.stringify(data) break } - const userWallet = await showModalAndWait( actions.GET_USER_WALLET ) - if (userWallet.action === 'accept') { - let coin = data.coin; - let walletKeys = this.getUserWallet(coin); - + let coin = data.coin + let walletKeys = this.getUserWallet(coin) let _url = `/crosschain/` + data.coin.toLowerCase() + `/addressinfos?apiKey=${this.getApiKey()}` - let _body = { - xpub58: walletKeys['publickey'] - } - + let _body = { xpub58: walletKeys['publickey'] } try { this.loader.show() - const bodyToString = JSON.stringify(_body); + const bodyToString = JSON.stringify(_body) const res = await parentEpml.request('apiCall', { url: _url, method: 'POST', @@ -2519,9 +1799,9 @@ class WebBrowser extends LitElement { 'Accept': '*/*', 'Content-Type': 'application/json' }, - body: bodyToString, + body: bodyToString }) - response = JSON.stringify(res); + response = JSON.stringify(res) } catch (error) { console.error(error) const data = {} @@ -2534,20 +1814,16 @@ class WebBrowser extends LitElement { } else if (userWallet.action === 'reject') { response = '{"error": "User declined request"}' } - break } - case actions.GET_CROSSCHAIN_SERVER_INFO: { const requiredFields = ['coin'] const missingFields = [] - requiredFields.forEach((field) => { if (!data[field]) { missingFields.push(field) } }) - if (missingFields.length > 0) { const missingFieldsString = missingFields.join(', ') const errorMsg = `Missing fields: ${missingFieldsString}` @@ -2556,7 +1832,6 @@ class WebBrowser extends LitElement { response = JSON.stringify(data) break } - let _url = `/crosschain/` + data.coin.toLowerCase() + `/serverinfos` try { this.loader.show() @@ -2567,30 +1842,27 @@ class WebBrowser extends LitElement { 'Accept': '*/*' } }) - response = JSON.stringify(res.servers); + response = JSON.stringify(res.servers) } catch (error) { - console.error(error) - const data = {} + console.error(error) + const data = {} data['error'] = error.message || 'Error in retrieving server info' - response = JSON.stringify(data) - return - } finally { - this.loader.hide() - } - + response = JSON.stringify(data) + return + } finally { + this.loader.hide() + } break } case actions.GET_TX_ACTIVITY_SUMMARY: { const requiredFields = ['coin'] const missingFields = [] - requiredFields.forEach((field) => { if (!data[field]) { missingFields.push(field) } }) - if (missingFields.length > 0) { const missingFieldsString = missingFields.join(', ') const errorMsg = `Missing fields: ${missingFieldsString}` @@ -2599,9 +1871,8 @@ class WebBrowser extends LitElement { response = JSON.stringify(data) break } - try { - let coin = data.coin; + let coin = data.coin response = await parentEpml.request('apiCall', { type: 'api', method: 'POST', @@ -2609,7 +1880,7 @@ class WebBrowser extends LitElement { headers: { 'Accept': '*/*', 'Content-Type': 'application/json' - }, + } }) } catch (error) { const data = {} @@ -2620,11 +1891,87 @@ class WebBrowser extends LitElement { } } + case actions.GET_FOREIGN_FEE: { + const requiredFields = ['coin','type'] + const missingFields = [] + requiredFields.forEach((field) => { + if (!data[field]) { + missingFields.push(field) + } + }) + if (missingFields.length > 0) { + const missingFieldsString = missingFields.join(', ') + const errorMsg = `Missing fields: ${missingFieldsString}` + let data = {} + data['error'] = errorMsg + response = JSON.stringify(data) + break + } + try { + let coin = data.coin; + let type = data.type; + response = await parentEpml.request('apiCall', { + type: 'api', + method: 'GET', + url: `/crosschain/${coin}/${type}?apiKey=${this.getApiKey()}`, + headers: { + 'Accept': '*/*', + 'Content-Type': 'application/json' + }, + }) + } catch (error) { + const data = {} + data['error'] = "Error in get foreign fee" + response = JSON.stringify(data) + } finally { + break + } + } + + case actions.UPDATE_FOREIGN_FEE: { + const requiredFields = ['coin','type'] + const missingFields = [] + requiredFields.forEach((field) => { + if (!data[field]) { + missingFields.push(field) + } + }) + if (missingFields.length > 0) { + const missingFieldsString = missingFields.join(', ') + const errorMsg = `Missing fields: ${missingFieldsString}` + let data = {} + data['error'] = errorMsg + response = JSON.stringify(data) + break + } + try { + let coin = data.coin; + let type = data.type; + let value = data.value; + response = await parentEpml.request('apiCall', { + type: 'api', + method: 'POST', + url: `/crosschain/${coin}/update${type}?apiKey=${this.getApiKey()}`, + headers: { + 'Accept': '*/*', + 'Content-Type': 'application/json' + }, + body: `${value}` + }) + } catch (error) { + const data = {} + data['error'] = "Error in update foreign fee" + response = JSON.stringify(data) + } finally { + break + } + } + case actions.GET_DAY_SUMMARY: { try { response = await parentEpml.request('apiCall', { type: 'api', - url: `/admin/summary?apiKey=${this.getApiKey()}`, + url: `/admin/summary?apiKey=${this.getApiKey()}` }) } catch (error) { const data = {} @@ -2638,13 +1985,11 @@ class WebBrowser extends LitElement { case actions.SEND_COIN: { const requiredFields = ['coin', 'destinationAddress', 'amount'] const missingFields = [] - requiredFields.forEach((field) => { if (!data[field]) { missingFields.push(field) } }) - if (missingFields.length > 0) { const missingFieldsString = missingFields.join(', ') const errorMsg = `Missing fields: ${missingFieldsString}` @@ -2654,9 +1999,7 @@ class WebBrowser extends LitElement { response = JSON.stringify(data) break } - let checkCoin = data.coin - if (checkCoin === "QORT") { // Params: data.coin, data.destinationAddress, data.amount, data.fee // TODO: prompt user to send. If they confirm, call `POST /crosschain/:coin/send`, or for QORT, broadcast a PAYMENT transaction @@ -2665,11 +2008,9 @@ class WebBrowser extends LitElement { const amount = Number(data.amount) const recipient = data.destinationAddress const coin = data.coin - const walletBalance = await parentEpml.request('apiCall', { - url: `/addresses/balance/${this.myAddress.address}`, + url: `/addresses/balance/${this.myAddress.address}` }) - if (isNaN(Number(walletBalance))) { let errorMsg = "Failed to Fetch QORT Balance. Try again!" let failedMsg = get("walletpage.wchange33") + " QORT " + get("general.balance") @@ -2680,18 +2021,15 @@ class WebBrowser extends LitElement { response = JSON.stringify(obj) break } - const myRef = await parentEpml.request("apiCall", { type: "api", - url: `/addresses/lastreference/${this.myAddress.address}`, + url: `/addresses/lastreference/${this.myAddress.address}` }) - const transformDecimals = (Number(walletBalance) * QORT_DECIMALS).toFixed(0) const walletBalanceDecimals = Number(transformDecimals) const amountDecimals = Number(amount) * QORT_DECIMALS const balance = (Number(transformDecimals) / 1e8).toFixed(8) const fee = await this.sendQortFee() - if (amountDecimals + (fee * QORT_DECIMALS) > walletBalanceDecimals) { let errorMsg = "Insufficient Funds!" let failedMsg = get("walletpage.wchange26") @@ -2702,7 +2040,6 @@ class WebBrowser extends LitElement { response = JSON.stringify(obj) break } - if (amount <= 0) { let errorMsg = "Invalid Amount!" await showErrorAndWait("INVALID_AMOUNT", errorMsg) @@ -2711,7 +2048,6 @@ class WebBrowser extends LitElement { response = JSON.stringify(obj) break } - if (recipient.length === 0) { let errorMsg = "Receiver cannot be empty!" await showErrorAndWait("NO_RECEIVER", errorMsg) @@ -2720,7 +2056,6 @@ class WebBrowser extends LitElement { response = JSON.stringify(obj) break } - const processPayment = await showModalAndWait( actions.SEND_COIN, { @@ -2731,7 +2066,6 @@ class WebBrowser extends LitElement { fee } ) - if (processPayment.action === 'reject') { let errorMsg = "User declined request" let myMsg1 = get("transactions.declined") @@ -2740,14 +2074,12 @@ class WebBrowser extends LitElement { response = '{"error": "User declined request"}' break } - const validateName = async (receiverName) => { let myRes let myNameRes = await parentEpml.request('apiCall', { type: 'api', - url: `/names/${receiverName}`, + url: `/names/${receiverName}` }) - if (myNameRes.error === 401) { myRes = false } else { @@ -2755,21 +2087,17 @@ class WebBrowser extends LitElement { } return myRes } - const validateAddress = async (receiverAddress) => { return await window.parent.validateAddress(receiverAddress) } - const validateReceiver = async (recipient) => { let lastRef = myRef let isAddress - try { isAddress = await validateAddress(recipient) } catch (err) { isAddress = false } - if (isAddress) { let myTransaction = await makeTransactionRequest(recipient, lastRef) return getTxnRequestResponse(myTransaction) @@ -2787,26 +2115,22 @@ class WebBrowser extends LitElement { } } } - const getName = async (recipient) => { try { const getNames = await parentEpml.request("apiCall", { type: "api", url: `/names/address/${recipient}` }) - if (getNames.length > 0) { return getNames[0].name } else { return '' } } catch (error) { - return "" + return '' } } - this.loader.show() - const makeTransactionRequest = async (receiver, lastRef) => { let myReceiver = receiver let mylastRef = lastRef @@ -2832,7 +2156,6 @@ class WebBrowser extends LitElement { apiVersion: 2 }) } - const getTxnRequestResponse = (txnResponse) => { if (txnResponse.success === false && txnResponse.message) { this.loader.hide() @@ -2844,9 +2167,7 @@ class WebBrowser extends LitElement { this.loader.hide() throw new Error('Error: could not send coin') } - } - try { response = await validateReceiver(recipient) } catch (error) { @@ -2863,13 +2184,11 @@ class WebBrowser extends LitElement { const coin = data.coin const xprv58 = this.btcWallet.derivedMasterPrivateKey const feePerByte = data.fee ? data.fee : this.btcFeePerByte - const btcWalletBalance = await parentEpml.request('apiCall', { url: `/crosschain/btc/walletbalance?apiKey=${this.getApiKey()}`, method: 'POST', body: `${this.btcWallet.derivedMasterPublicKey}` }) - if (isNaN(Number(btcWalletBalance))) { this.loader.hide() let errorMsg = "Failed to Fetch BTC Balance. Try again!" @@ -2881,12 +2200,10 @@ class WebBrowser extends LitElement { response = JSON.stringify(obj) break } - const btcWalletBalanceDecimals = Number(btcWalletBalance) const btcAmountDecimals = Number(amount) * QORT_DECIMALS const balance = (Number(btcWalletBalance) / 1e8).toFixed(8) const fee = feePerByte * 500 // default 0.00050000 - if (btcAmountDecimals + (fee * QORT_DECIMALS) > btcWalletBalanceDecimals) { this.loader.hide() let errorMsg = "Insufficient Funds!" @@ -2898,9 +2215,7 @@ class WebBrowser extends LitElement { response = JSON.stringify(obj) break } - this.loader.hide() - const processPayment = await showModalAndWait( actions.SEND_COIN, { @@ -2911,7 +2226,6 @@ class WebBrowser extends LitElement { fee } ) - if (processPayment.action === 'reject') { let errorMsg = "User declined request" let myMsg1 = get("transactions.declined") @@ -2920,9 +2234,7 @@ class WebBrowser extends LitElement { response = '{"error": "User declined request"}' break } - this.loader.show() - const makeRequest = async () => { const opts = { xprv58: xprv58, @@ -2932,7 +2244,6 @@ class WebBrowser extends LitElement { } return await parentEpml.request('sendBtc', opts) } - const manageResponse = (response) => { if (response.length === 64) { this.loader.hide() @@ -2953,7 +2264,6 @@ class WebBrowser extends LitElement { throw new Error(response) } } - try { const res = await makeRequest() manageResponse(res) @@ -2972,13 +2282,11 @@ class WebBrowser extends LitElement { const coin = data.coin const xprv58 = this.ltcWallet.derivedMasterPrivateKey const feePerByte = data.fee ? data.fee : this.ltcFeePerByte - const ltcWalletBalance = await parentEpml.request('apiCall', { url: `/crosschain/ltc/walletbalance?apiKey=${this.getApiKey()}`, method: 'POST', body: `${this.ltcWallet.derivedMasterPublicKey}` }) - if (isNaN(Number(ltcWalletBalance))) { this.loader.hide() let errorMsg = "Failed to Fetch LTC Balance. Try again!" @@ -2990,12 +2298,10 @@ class WebBrowser extends LitElement { response = JSON.stringify(obj) break } - const ltcWalletBalanceDecimals = Number(ltcWalletBalance) const ltcAmountDecimals = Number(amount) * QORT_DECIMALS const balance = (Number(ltcWalletBalance) / 1e8).toFixed(8) const fee = feePerByte * 1000 // default 0.00030000 - if (ltcAmountDecimals + (fee * QORT_DECIMALS) > ltcWalletBalanceDecimals) { this.loader.hide() let errorMsg = "Insufficient Funds!" @@ -3007,9 +2313,7 @@ class WebBrowser extends LitElement { response = JSON.stringify(obj) break } - this.loader.hide() - const processPayment = await showModalAndWait( actions.SEND_COIN, { @@ -3020,7 +2324,6 @@ class WebBrowser extends LitElement { fee } ) - if (processPayment.action === 'reject') { let errorMsg = "User declined request" let myMsg1 = get("transactions.declined") @@ -3029,9 +2332,7 @@ class WebBrowser extends LitElement { response = '{"error": "User declined request"}' break } - this.loader.show() - const makeRequest = async () => { const opts = { xprv58: xprv58, @@ -3041,7 +2342,6 @@ class WebBrowser extends LitElement { } return await parentEpml.request('sendLtc', opts) } - const manageResponse = (response) => { if (response.length === 64) { this.loader.hide() @@ -3062,7 +2362,6 @@ class WebBrowser extends LitElement { throw new Error(response) } } - try { const res = await makeRequest() manageResponse(res) @@ -3081,13 +2380,11 @@ class WebBrowser extends LitElement { const coin = data.coin const xprv58 = this.dogeWallet.derivedMasterPrivateKey const feePerByte = data.fee ? data.fee : this.dogeFeePerByte - const dogeWalletBalance = await parentEpml.request('apiCall', { url: `/crosschain/doge/walletbalance?apiKey=${this.getApiKey()}`, method: 'POST', body: `${this.dogeWallet.derivedMasterPublicKey}` }) - if (isNaN(Number(dogeWalletBalance))) { this.loader.hide() let errorMsg = "Failed to Fetch DOGE Balance. Try again!" @@ -3099,12 +2396,10 @@ class WebBrowser extends LitElement { response = JSON.stringify(obj) break } - const dogeWalletBalanceDecimals = Number(dogeWalletBalance) const dogeAmountDecimals = Number(amount) * QORT_DECIMALS const balance = (Number(dogeWalletBalance) / 1e8).toFixed(8) const fee = feePerByte * 5000 // default 0.05000000 - if (dogeAmountDecimals + (fee * QORT_DECIMALS) > dogeWalletBalanceDecimals) { this.loader.hide() let errorMsg = "Insufficient Funds!" @@ -3116,9 +2411,7 @@ class WebBrowser extends LitElement { response = JSON.stringify(obj) break } - this.loader.hide() - const processPayment = await showModalAndWait( actions.SEND_COIN, { @@ -3129,7 +2422,6 @@ class WebBrowser extends LitElement { fee } ) - if (processPayment.action === 'reject') { let errorMsg = "User declined request" let myMsg1 = get("transactions.declined") @@ -3138,9 +2430,7 @@ class WebBrowser extends LitElement { response = '{"error": "User declined request"}' break } - this.loader.show() - const makeRequest = async () => { const opts = { xprv58: xprv58, @@ -3150,7 +2440,6 @@ class WebBrowser extends LitElement { } return await parentEpml.request('sendDoge', opts) } - const manageResponse = (response) => { if (response.length === 64) { this.loader.hide() @@ -3171,7 +2460,6 @@ class WebBrowser extends LitElement { throw new Error(response) } } - try { const res = await makeRequest() manageResponse(res) @@ -3190,13 +2478,11 @@ class WebBrowser extends LitElement { const coin = data.coin const xprv58 = this.dgbWallet.derivedMasterPrivateKey const feePerByte = data.fee ? data.fee : this.dgbFeePerByte - const dgbWalletBalance = await parentEpml.request('apiCall', { url: `/crosschain/dgb/walletbalance?apiKey=${this.getApiKey()}`, method: 'POST', body: `${this.dgbWallet.derivedMasterPublicKey}` }) - if (isNaN(Number(dgbWalletBalance))) { this.loader.hide() let errorMsg = "Failed to Fetch DGB Balance. Try again!" @@ -3208,12 +2494,10 @@ class WebBrowser extends LitElement { response = JSON.stringify(obj) break } - const dgbWalletBalanceDecimals = Number(dgbWalletBalance) const dgbAmountDecimals = Number(amount) * QORT_DECIMALS const balance = (Number(dgbWalletBalance) / 1e8).toFixed(8) const fee = feePerByte * 500 // default 0.00005000 - if (dgbAmountDecimals + (fee * QORT_DECIMALS) > dgbWalletBalanceDecimals) { this.loader.hide() let errorMsg = "Insufficient Funds!" @@ -3225,9 +2509,7 @@ class WebBrowser extends LitElement { response = JSON.stringify(obj) break } - this.loader.hide() - const processPayment = await showModalAndWait( actions.SEND_COIN, { @@ -3238,7 +2520,6 @@ class WebBrowser extends LitElement { fee } ) - if (processPayment.action === 'reject') { let errorMsg = "User declined request" let myMsg1 = get("transactions.declined") @@ -3247,9 +2528,7 @@ class WebBrowser extends LitElement { response = '{"error": "User declined request"}' break } - this.loader.show() - const makeRequest = async () => { const opts = { xprv58: xprv58, @@ -3259,7 +2538,6 @@ class WebBrowser extends LitElement { } return await parentEpml.request('sendDgb', opts) } - const manageResponse = (response) => { if (response.length === 64) { this.loader.hide() @@ -3280,7 +2558,6 @@ class WebBrowser extends LitElement { throw new Error(response) } } - try { const res = await makeRequest() manageResponse(res) @@ -3299,13 +2576,11 @@ class WebBrowser extends LitElement { const coin = data.coin const xprv58 = this.rvnWallet.derivedMasterPrivateKey const feePerByte = data.fee ? data.fee : this.rvnFeePerByte - const rvnWalletBalance = await parentEpml.request('apiCall', { url: `/crosschain/rvn/walletbalance?apiKey=${this.getApiKey()}`, method: 'POST', body: `${this.rvnWallet.derivedMasterPublicKey}` }) - if (isNaN(Number(rvnWalletBalance))) { this.loader.hide() let errorMsg = "Failed to Fetch RVN Balance. Try again!" @@ -3317,12 +2592,10 @@ class WebBrowser extends LitElement { response = JSON.stringify(obj) break } - const rvnWalletBalanceDecimals = Number(rvnWalletBalance) const rvnAmountDecimals = Number(amount) * QORT_DECIMALS const balance = (Number(rvnWalletBalance) / 1e8).toFixed(8) const fee = feePerByte * 500 // default 0.00562500 - if (rvnAmountDecimals + (fee * QORT_DECIMALS) > rvnWalletBalanceDecimals) { this.loader.hide() let errorMsg = "Insufficient Funds!" @@ -3334,9 +2607,7 @@ class WebBrowser extends LitElement { response = JSON.stringify(obj) break } - this.loader.hide() - const processPayment = await showModalAndWait( actions.SEND_COIN, { @@ -3347,7 +2618,6 @@ class WebBrowser extends LitElement { fee } ) - if (processPayment.action === 'reject') { let errorMsg = "User declined request" let myMsg1 = get("transactions.declined") @@ -3356,9 +2626,7 @@ class WebBrowser extends LitElement { response = '{"error": "User declined request"}' break } - this.loader.show() - const makeRequest = async () => { const opts = { xprv58: xprv58, @@ -3368,7 +2636,6 @@ class WebBrowser extends LitElement { } return await parentEpml.request('sendRvn', opts) } - const manageResponse = (response) => { if (response.length === 64) { this.loader.hide() @@ -3389,7 +2656,6 @@ class WebBrowser extends LitElement { throw new Error(response) } } - try { const res = await makeRequest() manageResponse(res) @@ -3408,13 +2674,11 @@ class WebBrowser extends LitElement { const coin = data.coin const memo = data.memo const seed58 = this.arrrWallet.seed58 - const arrrWalletBalance = await parentEpml.request('apiCall', { url: `/crosschain/arrr/walletbalance?apiKey=${this.getApiKey()}`, method: 'POST', body: `${this.arrrWallet.seed58}` }) - if (isNaN(Number(arrrWalletBalance))) { this.loader.hide() let errorMsg = "Failed to Fetch ARRR Balance. Try again!" @@ -3426,12 +2690,10 @@ class WebBrowser extends LitElement { response = JSON.stringify(obj) break } - const arrrWalletBalanceDecimals = Number(arrrWalletBalance) const arrrAmountDecimals = Number(amount) * QORT_DECIMALS const balance = (Number(arrrWalletBalance) / 1e8).toFixed(8) const fee = 0.00010000 - if (arrrAmountDecimals + (fee * QORT_DECIMALS) > arrrWalletBalanceDecimals) { this.loader.hide() let errorMsg = "Insufficient Funds!" @@ -3443,9 +2705,7 @@ class WebBrowser extends LitElement { response = JSON.stringify(obj) break } - this.loader.hide() - const processPayment = await showModalAndWait( actions.SEND_COIN, { @@ -3456,7 +2716,6 @@ class WebBrowser extends LitElement { fee } ) - if (processPayment.action === 'reject') { let errorMsg = "User declined request" let myMsg1 = get("transactions.declined") @@ -3465,9 +2724,7 @@ class WebBrowser extends LitElement { response = '{"error": "User declined request"}' break } - this.loader.show() - const makeRequest = async () => { const opts = { entropy58: seed58, @@ -3477,7 +2734,6 @@ class WebBrowser extends LitElement { } return await parentEpml.request('sendArrr', opts) } - const manageResponse = (response) => { if (response.length === 64) { this.loader.hide() @@ -3498,7 +2754,6 @@ class WebBrowser extends LitElement { throw new Error(response) } } - try { const res = await makeRequest() manageResponse(res) @@ -3513,7 +2768,7 @@ class WebBrowser extends LitElement { break } } - break; + break default: console.log('Unhandled message: ' + JSON.stringify(data)) return @@ -3531,24 +2786,446 @@ class WebBrowser extends LitElement { if (responseObj.error != null) { event.ports[0].postMessage({ result: null, - error: responseObj, + error: responseObj }) } else { event.ports[0].postMessage({ result: responseObj, - error: null, + error: null }) } }) + this.clearConsole() + setInterval(() => { this.clearConsole() }, 60000) } - getUserWallet(coin) { - let userWallet = {}; + renderFullScreen() { + if (window.innerHeight == screen.height) { + return html` + this.exitFullScreen()} + title="${translate('browserpage.bchange38')}" + class="address-bar-button float-right" + > + fullscreen_exit + + ` + } else { + return html` + this.goFullScreen()} + title="${translate('browserpage.bchange37')}" + class="address-bar-button float-right" + > + fullscreen + + ` + } + } + goFullScreen() { + var elem = this.shadowRoot.getElementById('websitesWrapper') + if (elem.requestFullscreen) { + elem.requestFullscreen() + } else if (elem.mozRequestFullScreen) { + elem.mozRequestFullScreen() + } else if (elem.webkitRequestFullscreen) { + elem.webkitRequestFullscreen() + } else if (elem.msRequestFullscreen) { + elem.msRequestFullscreen() + } + this.renderFullScreen() + } + + exitFullScreen() { + if (document.exitFullscreen) { + document.exitFullscreen() + } else if (document.mozCancelFullScreen) { + document.mozCancelFullScreen() + } else if (document.webkitExitFullscreen) { + document.webkitExitFullscreen() + } else if (document.msExitFullscreen) { + document.msExitFullscreen() + } + this.renderFullScreen() + } + + async unitJoinFee() { + const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] + const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port + const url = `${nodeUrl}/transactions/unitfee?txType=JOIN_GROUP` + const response = await fetch(url) + if (!response.ok) { + throw new Error('Error when fetching join fee') + } + const data = await response.json() + return (Number(data) / 1e8).toFixed(8) + } + + async deployAtFee() { + const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] + const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port + const url = `${nodeUrl}/transactions/unitfee?txType=DEPLOY_AT` + const response = await fetch(url) + if (!response.ok) { + throw new Error('Error when fetching join fee') + } + const data = await response.json() + return (Number(data) / 1e8).toFixed(8) + } + + async getArbitraryFee() { + const timestamp = Date.now() + const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] + const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port + const url = `${nodeUrl}/transactions/unitfee?txType=ARBITRARY×tamp=${timestamp}` + const response = await fetch(url) + if (!response.ok) { + throw new Error('Error when fetching arbitrary fee') + } + const data = await response.json() + const arbitraryFee = (Number(data) / 1e8).toFixed(8) + return { + timestamp, + fee: Number(data), + feeToShow: arbitraryFee + } + } + async sendQortFee() { + const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] + const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port + const url = `${nodeUrl}/transactions/unitfee?txType=PAYMENT` + const response = await fetch(url) + if (!response.ok) { + throw new Error('Error when fetching join fee') + } + const data = await response.json() + return (Number(data) / 1e8).toFixed(8) + } + + async unitVoteFee() { + const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] + const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port + const url = `${nodeUrl}/transactions/unitfee?txType=VOTE_ON_POLL` + const response = await fetch(url) + if (!response.ok) { + throw new Error('Error when fetching vote fee') + } + const data = await response.json() + return (Number(data) / 1e8).toFixed(8) + } + + async unitCreatePollFee() { + const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] + const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port + const url = `${nodeUrl}/transactions/unitfee?txType=CREATE_POLL` + const response = await fetch(url) + if (!response.ok) { + throw new Error('Error when fetching vote fee') + } + const data = await response.json() + return (Number(data) / 1e8).toFixed(8) + } + + async _joinGroup(groupId, groupName) { + const joinFeeInput = await this.unitJoinFee() + const getLastRef = async () => { + return await parentEpml.request('apiCall', { + type: 'api', + url: `/addresses/lastreference/${this.selectedAddress.address}` + }) + } + const validateReceiver = async () => { + let lastRef = await getLastRef() + let myTransaction = await makeTransactionRequest(lastRef) + return getTxnRequestResponse(myTransaction) + } + const makeTransactionRequest = async (lastRef) => { + let groupdialog1 = get("transactions.groupdialog1") + let groupdialog2 = get("transactions.groupdialog2") + return await parentEpml.request('transaction', { + type: 31, + nonce: this.selectedAddress.nonce, + params: { + fee: joinFeeInput, + registrantAddress: this.selectedAddress.address, + rGroupName: groupName, + rGroupId: groupId, + lastReference: lastRef, + groupdialog1: groupdialog1, + groupdialog2: groupdialog2 + }, + apiVersion: 2 + }) + } + const getTxnRequestResponse = (txnResponse) => { + if (txnResponse.success === false && txnResponse.message) { + throw new Error(txnResponse.message) + } else if (txnResponse.success === true && !txnResponse.data.error) { + return txnResponse.data + } else if (txnResponse.data && txnResponse.data.message) { + throw new Error(txnResponse.data.message) + } else { + throw new Error('Server error. Could not perform action.') + } + } + return await validateReceiver() + } + + async _deployAt(name, description, tags, creationBytes, amount, assetId, atType) { + const deployAtFee = await this.deployAtFee() + const getLastRef = async () => { + return await parentEpml.request('apiCall', { + type: 'api', + url: `/addresses/lastreference/${this.selectedAddress.address}` + }) + } + const validateReceiver = async () => { + let lastRef = await getLastRef() + let myTransaction = await makeTransactionRequest(lastRef) + return getTxnRequestResponse(myTransaction) + } + const makeTransactionRequest = async (lastRef) => { + let deployAtdialog1 = get("transactions.deployAtdialog1") + let deployAtdialog2 = get("transactions.deployAtdialog2") + let deployAtdialog3 = get("transactions.deployAtdialog3") + let deployAtdialog4 = get("walletpage.wchange12") + return await parentEpml.request('transaction', { + type: 16, + nonce: this.selectedAddress.nonce, + params: { + fee: deployAtFee, + rName: name, + rDescription: description, + rTags: tags, + rAmount: amount, + rAssetId: assetId, + rCreationBytes: creationBytes, + atType: atType, + lastReference: lastRef, + atDeployDialog1: deployAtdialog1, + atDeployDialog2: deployAtdialog2, + atDeployDialog3: deployAtdialog3, + atDeployDialog4: deployAtdialog4 + }, + apiVersion: 2 + }) + } + const getTxnRequestResponse = (txnResponse) => { + if (txnResponse.success === false && txnResponse.message) { + throw new Error(txnResponse.message) + } else if (txnResponse.success === true && !txnResponse.data.error) { + return txnResponse.data + } else if (txnResponse.data && txnResponse.data.message) { + throw new Error(txnResponse.data.message) + } else { + throw new Error('Server error. Could not perform action.') + } + } + return await validateReceiver() + } + + async _voteOnPoll(pollName, optionIndex) { + const voteFeeInput = await this.unitVoteFee() + const getLastRef = async () => { + return await parentEpml.request('apiCall', { + type: 'api', + url: `/addresses/lastreference/${this.selectedAddress.address}` + }) + } + const validateReceiver = async () => { + let lastRef = await getLastRef() + let myTransaction = await makeTransactionRequest(lastRef) + return getTxnRequestResponse(myTransaction) + } + const makeTransactionRequest = async (lastRef) => { + let votedialog1 = get("transactions.votedialog1") + let votedialog2 = get("transactions.votedialog2") + let feeDialog = get("walletpage.wchange12") + + return await parentEpml.request('transaction', { + type: 9, + nonce: this.selectedAddress.nonce, + params: { + fee: voteFeeInput, + voterAddress: this.selectedAddress.address, + rPollName: pollName, + rOptionIndex: optionIndex, + lastReference: lastRef, + votedialog1: votedialog1, + votedialog2: votedialog2, + feeDialog + }, + apiVersion: 2 + }) + } + const getTxnRequestResponse = (txnResponse) => { + if (txnResponse.success === false && txnResponse.message) { + throw new Error(txnResponse.message) + } else if (txnResponse.success === true && !txnResponse.data.error) { + return txnResponse.data + } else if (txnResponse.data && txnResponse.data.message) { + throw new Error(txnResponse.data.message) + } else { + throw new Error('Server error. Could not perform action.') + } + } + return await validateReceiver() + } + + async _createPoll(pollName, pollDescription, options, pollOwnerAddress) { + const voteFeeInput = await this.unitCreatePollFee() + const getLastRef = async () => { + return await parentEpml.request('apiCall', { + type: 'api', + url: `/addresses/lastreference/${this.selectedAddress.address}` + }) + } + const validateReceiver = async () => { + let lastRef = await getLastRef() + let myTransaction = await makeTransactionRequest(lastRef) + return getTxnRequestResponse(myTransaction) + } + const makeTransactionRequest = async (lastRef) => { + let votedialog3 = get("transactions.votedialog3") + let votedialog4 = get("transactions.votedialog4") + let votedialog5 = get("transactions.votedialog5") + let votedialog6 = get("transactions.votedialog6") + let feeDialog = get("walletpage.wchange12") + return await parentEpml.request('transaction', { + type: 8, + nonce: this.selectedAddress.nonce, + params: { + fee: voteFeeInput, + ownerAddress: pollOwnerAddress, + rPollName: pollName, + rPollDesc: pollDescription, + rOptions: options, + lastReference: lastRef, + votedialog3: votedialog3, + votedialog4: votedialog4, + votedialog5: votedialog5, + votedialog6: votedialog6, + feeDialog + }, + apiVersion: 2 + }) + } + const getTxnRequestResponse = (txnResponse) => { + if (txnResponse.success === false && txnResponse.message) { + throw new Error(txnResponse.message) + } else if (txnResponse.success === true && !txnResponse.data.error) { + return txnResponse.data + } else if (txnResponse.data && txnResponse.data.message) { + throw new Error(txnResponse.data.message) + } else { + throw new Error('Server error. Could not perform action.') + } + } + return await validateReceiver() + } + + async extractComponents(url) { + if (!url.startsWith("qortal://")) { + return null + } + url = url.replace(/^(qortal\:\/\/)/, "") + if (url.includes("/")) { + let parts = url.split("/") + const service = parts[0].toUpperCase() + parts.shift() + const name = parts[0] + parts.shift() + let identifier + if (parts.length > 0) { + identifier = parts[0] // Do not shift yet + // Check if a resource exists with this service, name and identifier combination + let responseObj = await parentEpml.request('apiCall', { + url: `/arbitrary/resource/status/${service}/${name}/${identifier}?apiKey=${this.getApiKey()}` + }) + + if (responseObj.totalChunkCount > 0) { + // Identifier exists, so don't include it in the path + parts.shift() + } + else { + identifier = null + } + } + const path = parts.join("/") + const components = {} + components["service"] = service + components["name"] = name + components["identifier"] = identifier + components["path"] = path + return components + } + return null + } + + async _handleKeyDown(e) { + if (e.key === 'Enter') { + let newQuery = e.target.value + if (newQuery.endsWith('/')) { + newQuery = newQuery.slice(0, -1) + } + const res = await this.extractComponents(newQuery) + if (!res) return + const { service, name, identifier, path } = res + let query = `?service=${service}` + if (name) { + query = query + `&name=${name}` + } + if (identifier) { + query = query + `&identifier=${identifier}` + } + if (path) { + query = query + `&path=${path}` + } + window.location = window.location.origin + window.location.pathname + query + } + } + + async linkOpenNewTab(link) { + let newQuery = link + if (newQuery.endsWith('/')) { + newQuery = newQuery.slice(0, -1) + } + const res = await this.extractComponents(newQuery) + if (!res) return + const { service, name, identifier, path } = res + let query = `?service=${service}` + if (name) { + query = query + `&name=${name}` + } + if (identifier) { + query = query + `&identifier=${identifier}` + } + if (path) { + query = query + `&path=${path}` + } + window.parent.reduxStore.dispatch(window.parent.reduxAction.setNewTab({ + url: `qdn/browser/index.html${query}`, + id: this.uid.rnd(), + myPlugObj: { + "url": service === 'WEBSITE' ? "websites" : "qapps", + "domain": "core", + "page": `qdn/browser/index.html${query}`, + "title": name, + "icon": service === 'WEBSITE' ? 'vaadin:desktop' : 'vaadin:external-browser', + "mwcicon": service === 'WEBSITE' ? 'desktop_mac' : 'open_in_browser', + "menus": [], + "parent": false + } + })) + } + + getUserWallet(coin) { + let userWallet = {} switch (coin) { case 'QORT': userWallet['address'] = window.parent.reduxStore.getState().app.selectedAddress.address @@ -3579,7 +3256,7 @@ class WebBrowser extends LitElement { default: break } - return userWallet; + return userWallet } clearConsole() { @@ -3602,7 +3279,6 @@ class WebBrowser extends LitElement { changeLanguage() { const checkLanguage = localStorage.getItem('qortalLanguage') - if (checkLanguage === null || checkLanguage.length === 0) { localStorage.setItem('qortalLanguage', 'us') use('us') @@ -3615,20 +3291,19 @@ class WebBrowser extends LitElement { if (!appName) throw new Error('unknown app name') const id = `appNotificationList-${this.selectedAddress.address}` const checkData = localStorage.getItem(id) ? JSON.parse(localStorage.getItem(id)) : null - if (!checkData) { const newData = { [appName]: { interval: 900000, // 15mins in milliseconds - lastNotification: null, - }, + lastNotification: null + } } localStorage.setItem(id, JSON.stringify(newData)) } else { const copyData = { ...checkData } copyData[appName] = { interval: 900000, // 15mins in milliseconds - lastNotification: null, + lastNotification: null } localStorage.setItem(id, JSON.stringify(copyData)) } @@ -3636,7 +3311,6 @@ class WebBrowser extends LitElement { updateLastNotification(id, appName) { const checkData = localStorage.getItem(id) ? JSON.parse(localStorage.getItem(id)) : null - if (checkData) { const copyData = { ...checkData } if (copyData[appName]) { @@ -3644,7 +3318,7 @@ class WebBrowser extends LitElement { } else { copyData[appName] = { interval: 900000, // 15mins in milliseconds - lastNotification: Date.now(), + lastNotification: Date.now() } } localStorage.setItem(id, JSON.stringify(copyData)) @@ -3657,23 +3331,28 @@ class WebBrowser extends LitElement { if (this.followedNames == null || !Array.isArray(this.followedNames)) { return html`` } - if (this.followedNames.indexOf(this.name) === -1) { // render follow button - return html` this.follow()} - title="${translate('browserpage.bchange7')} ${this.name}" - class="address-bar-button float-right" - >add_to_queue` + return html` + this.follow()} + title="${translate('browserpage.bchange7')} ${this.name}" + class="address-bar-button float-right" + > + add_to_queue + + ` } else { // render unfollow button - return html` this.unfollow()} - title="${translate('browserpage.bchange8')} ${this.name}" - class="address-bar-button float-right" - >remove_from_queue` + return html` + this.unfollow()} + title="${translate('browserpage.bchange8')} ${this.name}" + class="address-bar-button float-right" + > + remove_from_queue + + ` } } @@ -3682,28 +3361,32 @@ class WebBrowser extends LitElement { if (this.blockedNames == null || !Array.isArray(this.blockedNames)) { return html`` } - if (this.blockedNames.indexOf(this.name) === -1) { // render block button - return html` this.block()} - title="${translate('browserpage.bchange9')} ${this.name}" - class="address-bar-button float-right" - >block` + return html` + this.block()} + title="${translate('browserpage.bchange9')} ${this.name}" + class="address-bar-button float-right" + > + block + + ` } else { // render unblock button - return html` this.unblock()} - title="${translate('browserpage.bchange10')} ${this.name}" - class="address-bar-button float-right" - >radio_button_unchecked` + return html` + this.unblock()} + title="${translate('browserpage.bchange10')} ${this.name}" + class="address-bar-button float-right" + > + radio_button_unchecked + + ` } } // Navigation - goBack() { window.history.back() } @@ -3718,9 +3401,7 @@ class WebBrowser extends LitElement { if (this.dev === 'FRAMEWORK') { this.url = `${this.link}?time=${new Date().getMilliseconds()}` } else { - this.url = `${nodeUrl}/render/${this.service}/${this.name}${this.path != null ? this.path : '' - }?theme=${this.theme}&identifier=${this.identifier != null ? this.identifier : '' - }&time=${new Date().getMilliseconds()}` + this.url = `${nodeUrl}/render/${this.service}/${this.name}${this.path != null ? this.path : ''}?theme=${this.theme}&identifier=${this.identifier != null ? this.identifier : ''}&time=${new Date().getMilliseconds()}` } } @@ -3731,7 +3412,7 @@ class WebBrowser extends LitElement { } else { // Default to websites list this.exitFullScreen() - window.location = '../index.html' + window.location = '../../q-website/index.html' } } @@ -3758,16 +3439,14 @@ class WebBrowser extends LitElement { async followName(name) { let items = [name] let namesJsonString = JSON.stringify({ items: items }) - let ret = await parentEpml.request('apiCall', { url: `/lists/followedNames?apiKey=${this.getApiKey()}`, method: 'POST', headers: { - 'Content-Type': 'application/json', + 'Content-Type': 'application/json' }, - body: `${namesJsonString}`, + body: `${namesJsonString}` }) - if (ret === true) { // Successfully followed - add to local list // Remove it first by filtering the list - doing it this way ensures the UI updates @@ -3780,23 +3459,20 @@ class WebBrowser extends LitElement { let err1string = get('browserpage.bchange11') parentEpml.request('showSnackBar', `${err1string}`) } - return ret } async unfollowName(name) { let items = [name] let namesJsonString = JSON.stringify({ items: items }) - let ret = await parentEpml.request('apiCall', { url: `/lists/followedNames?apiKey=${this.getApiKey()}`, method: 'DELETE', headers: { - 'Content-Type': 'application/json', + 'Content-Type': 'application/json' }, - body: `${namesJsonString}`, + body: `${namesJsonString}` }) - if (ret === true) { // Successfully unfollowed - remove from local list this.followedNames = this.followedNames.filter( @@ -3806,23 +3482,20 @@ class WebBrowser extends LitElement { let err2string = get('browserpage.bchange12') parentEpml.request('showSnackBar', `${err2string}`) } - return ret } async blockName(name) { let items = [name] let namesJsonString = JSON.stringify({ items: items }) - let ret = await parentEpml.request('apiCall', { url: `/lists/blockedNames?apiKey=${this.getApiKey()}`, method: 'POST', headers: { - 'Content-Type': 'application/json', + 'Content-Type': 'application/json' }, - body: `${namesJsonString}`, + body: `${namesJsonString}` }) - if (ret === true) { // Successfully blocked - add to local list // Remove it first by filtering the list - doing it this way ensures the UI updates @@ -3835,33 +3508,27 @@ class WebBrowser extends LitElement { let err3string = get('browserpage.bchange13') parentEpml.request('showSnackBar', `${err3string}`) } - return ret } async unblockName(name) { let items = [name] let namesJsonString = JSON.stringify({ items: items }) - let ret = await parentEpml.request('apiCall', { url: `/lists/blockedNames?apiKey=${this.getApiKey()}`, method: 'DELETE', headers: { - 'Content-Type': 'application/json', + 'Content-Type': 'application/json' }, - body: `${namesJsonString}`, + body: `${namesJsonString}` }) - if (ret === true) { // Successfully unblocked - remove from local list - this.blockedNames = this.blockedNames.filter( - (item) => item != name - ) + this.blockedNames = this.blockedNames.filter((item) => item != name) } else { let err4string = get('browserpage.bchange14') parentEpml.request('showSnackBar', `${err4string}`) } - return ret } @@ -3872,32 +3539,34 @@ class WebBrowser extends LitElement { parentEpml.request('showSnackBar', `${err5string}`) return } - let identifier = (this.identifier == null || this.identifier.length == 0) ? 'default' : this.identifier - let ret = await parentEpml.request('apiCall', { - url: `/arbitrary/resource/${this.service}/${this.name - }/${identifier}?apiKey=${this.getApiKey()}`, - method: 'DELETE', + url: `/arbitrary/resource/${this.service}/${this.name}/${identifier}?apiKey=${this.getApiKey()}`, + method: 'DELETE' }) - if (ret === true) { this.goBackToList() } else { let err6string = get('browserpage.bchange16') parentEpml.request('showSnackBar', `${err6string}`) } - return ret } + // Standard functions getApiKey() { - const myNode = - window.parent.reduxStore.getState().app.nodeConfig.knownNodes[ - window.parent.reduxStore.getState().app.nodeConfig.node - ] + const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] return myNode.apiKey } + + isEmptyArray(arr) { + if (!arr) { return true } + return arr.length === 0 + } + + round(number) { + return (Math.round(parseFloat(number) * 1e8) / 1e8).toFixed(8) + } } window.customElements.define('web-browser', WebBrowser) @@ -3913,7 +3582,6 @@ async function showModalAndWait(type, data) {
    -

    ${translate('sponsorshipspage.schange6')}

    @@ -236,10 +235,9 @@ class SponsorshipList extends LitElement { dialogAction='cancel' class='red' > - ${translate('general.close')} + ${translate('general.close')} -
    @@ -303,7 +301,7 @@ class SponsorshipList extends LitElement { `}
    { this.openDialogRewardShare = false this.errorMessage = '' @@ -311,12 +309,11 @@ class SponsorshipList extends LitElement { this.privateRewardShareKey = '' this.atMount() }} - class='red' - > - ${translate('general.close')} + class='red' + > + ${translate('general.close')} -

    ${translate('sponsorshipspage.schange10')}

    @@ -345,13 +342,13 @@ class SponsorshipList extends LitElement { this.lookUpPublicAddressFunc() }}' > - ${translate('sponsorshipspage.schange10')} + ${translate('sponsorshipspage.schange10')}
    ${this.lookupPublicAddressValue ? html`
    ${this.lookupPublicAddressValue} -
    +
    - ${translate('general.close')} + ${translate('general.close')}
    @@ -409,11 +406,12 @@ class SponsorshipList extends LitElement { }) } + this.clearConsole() + setInterval(() => { this.atMount() }, 180000) - this.clearConsole() setInterval(() => { this.clearConsole() }, 60000) @@ -480,11 +478,6 @@ class SponsorshipList extends LitElement { this.saveToClipboard(this.privateRewardShareKey, `${copystring1}`) } - getApiKey() { - const apiNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] - return apiNode.apiKey - } - async atMount() { this.addressInfo = window.parent.reduxStore.getState().app.accountInfo.addressInfo this.isPageLoading = true @@ -505,7 +498,9 @@ class SponsorshipList extends LitElement { type: 'api', url: `/names/address/${rs.recipient}` }) + let url = '' + if(getNames.length > 0 ) { const avatarNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] const avatarUrl = avatarNode.protocol + '://' + avatarNode.domain + ':' + avatarNode.port @@ -519,7 +514,7 @@ class SponsorshipList extends LitElement { ...rs, name: getNames.length > 0 ? getNames[0].name : '', url, - blocksRemaining: blocksRemaining, + blocksRemaining: blocksRemaining } }) @@ -562,7 +557,6 @@ class SponsorshipList extends LitElement { } async removeRewardShare(rewardShareObject) { - const selectedAddress = window.parent.reduxStore.getState().app.selectedAddress const myPercentageShare = -1 @@ -601,8 +595,8 @@ class SponsorshipList extends LitElement { percentageShare: myPercentageShare, lastReference: mylastRef, rewarddialog5: rewarddialog5, - rewarddialog6: rewarddialog6, - }, + rewarddialog6: rewarddialog6 + } }) } @@ -611,10 +605,7 @@ class SponsorshipList extends LitElement { this.removeRewardShareLoading = false parentEpml.request('showSnackBar', txnResponse.message) throw new Error(txnResponse) - } else if ( - txnResponse.success === true && - !txnResponse.data.error - ) { + } else if (txnResponse.success === true && !txnResponse.data.error) { let err7tring = get('rewardsharepage.rchange22') this.removeRewardShareLoading = false parentEpml.request('showSnackBar', `${err7tring}`) @@ -625,6 +616,7 @@ class SponsorshipList extends LitElement { throw new Error(txnResponse) } } + await removeReceiver() } @@ -704,38 +696,37 @@ class SponsorshipList extends LitElement { rewarddialog1: rewarddialog1, rewarddialog2: rewarddialog2, rewarddialog3: rewarddialog3, - rewarddialog4: rewarddialog4, + rewarddialog4: rewarddialog4 }, disableModal: true }) } const getTxnRequestResponse = (txnResponse) => { + const extraData = txnResponse && txnResponse.extraData + const data = txnResponse && txnResponse.data + const dataMessage = data && data.message + const extraDataPrivateKey = extraData && extraData.rewardSharePrivateKey + const txnSuccess = txnResponse && txnResponse.success - const extraData = txnResponse && txnResponse.extraData; - const data = txnResponse && txnResponse.data; - const dataMessage = data && data.message; - const extraDataPrivateKey = extraData && extraData.rewardSharePrivateKey; - const txnSuccess = txnResponse && txnResponse.success; - - if (extraDataPrivateKey && typeof dataMessage === 'string' && - (dataMessage.includes('multiple') || dataMessage.includes('SELF_SHARE_EXISTS'))) { - this.privateRewardShareKey = extraDataPrivateKey; - this.confirmRelationship(publicKeyValue, isCopy); + if (extraDataPrivateKey && typeof dataMessage === 'string' && (dataMessage.includes('multiple') || dataMessage.includes('SELF_SHARE_EXISTS'))) { + this.privateRewardShareKey = extraDataPrivateKey + this.confirmRelationship(publicKeyValue, isCopy) } else if (txnSuccess === false && txnResponse.message) { - this.errorMessage = txnResponse.message; - this.isLoadingCreateSponsorship = false; - throw new Error(txnResponse.message); + this.errorMessage = txnResponse.message + this.isLoadingCreateSponsorship = false + throw new Error(txnResponse.message) } else if (txnSuccess === true && !(data && data.error)) { - this.privateRewardShareKey = extraDataPrivateKey; - this.confirmRelationship(publicKeyValue, isCopy); + this.privateRewardShareKey = extraDataPrivateKey + this.confirmRelationship(publicKeyValue, isCopy) } else { - const defaultErrorMessage = 'An unknown error occurred.'; - this.errorMessage = dataMessage || txnResponse.message || defaultErrorMessage; - this.isLoadingCreateSponsorship = false; - throw new Error(dataMessage || txnResponse.message || defaultErrorMessage); + const defaultErrorMessage = 'An unknown error occurred.' + this.errorMessage = dataMessage || txnResponse.message || defaultErrorMessage + this.isLoadingCreateSponsorship = false + throw new Error(dataMessage || txnResponse.message || defaultErrorMessage) } } + await validateReceiver() } @@ -745,13 +736,13 @@ class SponsorshipList extends LitElement { let stop = false const getAnswer = async () => { - if (!stop) { stop= true try { const recipientAddress = window.parent.base58PublicKeyToAddress(recipientPublicKey) const minterAddress = window.parent.reduxStore.getState().app.selectedAddress.address + const myRewardShareArray = await parentEpml.request('apiCall', { type: 'api', url: `/addresses/rewardshares?minters=${minterAddress}&recipients=${recipientAddress}` @@ -767,16 +758,19 @@ class SponsorshipList extends LitElement { stop = false } } + interval = setInterval(getAnswer, 5000) } async lookUpPublicAddressFunc() { this.errorLookup = '' + try { const response = await parentEpml.request('apiCall', { type: 'api', url: `/addresses/publickey/${this.lookupAddressValue}` }) + if(response.error) { throw(response.message) } @@ -785,6 +779,21 @@ class SponsorshipList extends LitElement { this.errorLookup = error } } + + // Standard functions + getApiKey() { + const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] + return myNode.apiKey + } + + isEmptyArray(arr) { + if (!arr) { return true } + return arr.length === 0 + } + + round(number) { + return (Math.round(parseFloat(number) * 1e8) / 1e8).toFixed(8) + } } -window.customElements.define('sponsorship-list', SponsorshipList) +window.customElements.define('sponsorship-list', SponsorshipList) \ No newline at end of file diff --git a/plugins/plugins/core/streams/AddressWatcher.js b/plugins/plugins/core/streams/AddressWatcher.js index c2411aa6..771b5f5b 100644 --- a/plugins/plugins/core/streams/AddressWatcher.js +++ b/plugins/plugins/core/streams/AddressWatcher.js @@ -1,4 +1,4 @@ -import {parentEpml} from '../connect.js' +import { parentEpml } from '../connect' // Tests to see if a block or transaction should trigger an address reload...but we're not doing that yet, because of no time for good testing const transactionTests = [] @@ -7,73 +7,73 @@ const blockTests = [] const DEFAULT_ADDRESS_INFO = {} transactionTests.push((tx, addr) => { - return tx.recipient === addr || tx.sender === addr + return tx.recipient === addr || tx.sender === addr }) blockTests.push((block, addr) => { - return block.generator === addr + return block.generator === addr }) export class AddressWatcher { - constructor(addresses) { - addresses = addresses || [] - this.reset() + constructor(addresses) { + addresses = addresses || [] + this.reset() - addresses.forEach(addr => this.addAddress(addr)) - } + addresses.forEach(addr => this.addAddress(addr)) + } - reset() { - this._addresses = {} - this._addressStreams = {} - } + reset() { + this._addresses = {} + this._addressStreams = {} + } - // Adds an address to watch - addAddress(address) { - const addr = address.address - this._addresses[addr] = address + // Adds an address to watch + addAddress(address) { + const addr = address.address + this._addresses[addr] = address - this._addressStreams[addr] = new EpmlStream(`address/${addr}`, () => this._addresses[addr]) + this._addressStreams[addr] = new EpmlStream(`address/${addr}`, () => this._addresses[addr]) - this.updateAddress(addr) - } + this.updateAddress(addr) + } - async testBlock(block) { - const pendingUpdateAddresses = [] - const transactions = await parentEpml.request('apiCall', { url: `/transactions/block/${block.signature}` }) - transactions.forEach(transaction => { - // Guess the block needs transactions - for (const addr of Object.keys(this._addresses)) { - const addrChanged = true // Just update it every block...for now - if (!addrChanged) return + async testBlock(block) { + const pendingUpdateAddresses = [] + const transactions = await parentEpml.request('apiCall', { url: `/transactions/block/${block.signature}` }) + transactions.forEach(transaction => { + // Guess the block needs transactions + for (const addr of Object.keys(this._addresses)) { + const addrChanged = true // Just update it every block...for now + if (!addrChanged) return - if (!(addr in pendingUpdateAddresses)) pendingUpdateAddresses.push(addr) - /** - * In the future transactions are potentially stored from here...and address is updated excluding transactions...and also somehow manage tx pages... - * Probably will just make wallet etc. listen for address change and then do the api call itself. If tx. page is on, say, page 3...and there's a new transaction... - * it will refresh, changing the "page" to have 1 extra transaction at the top and losing 1 at the bottom (pushed to next page) - */ - } - }) - pendingUpdateAddresses.forEach(addr => this.updateAddress(addr)) - } + if (!(addr in pendingUpdateAddresses)) pendingUpdateAddresses.push(addr) + /** + * In the future transactions are potentially stored from here...and address is updated excluding transactions...and also somehow manage tx pages... + * Probably will just make wallet etc. listen for address change and then do the api call itself. If tx. page is on, say, page 3...and there's a new transaction... + * it will refresh, changing the "page" to have 1 extra transaction at the top and losing 1 at the bottom (pushed to next page) + */ + } + }) + pendingUpdateAddresses.forEach(addr => this.updateAddress(addr)) + } - async updateAddress(addr) { - let addressRequest = await parentEpml.request('apiCall', { - type: 'explorer', - data: { - addr: addr, - txOnPage: 10 - } - }) - const addressInfo = addressRequest.success ? addressRequest.data : DEFAULT_ADDRESS_INFO - addressInfo.transactions = [] + async updateAddress(addr) { + let addressRequest = await parentEpml.request('apiCall', { + type: 'explorer', + data: { + addr: addr, + txOnPage: 10 + } + }) + const addressInfo = addressRequest.success ? addressRequest.data : DEFAULT_ADDRESS_INFO + addressInfo.transactions = [] - for (let i = addressInfo.start; i >= addressInfo.end; i--) { - addressInfo.transactions.push(addressInfo[i]) - delete addressInfo[i] - } - if (!(addr in this._addresses)) return - this._addresses[addr] = addressInfo - this._addressStreams[addr].emit(addressInfo) - } -} + for (let i = addressInfo.start; i >= addressInfo.end; i--) { + addressInfo.transactions.push(addressInfo[i]) + delete addressInfo[i] + } + if (!(addr in this._addresses)) return + this._addresses[addr] = addressInfo + this._addressStreams[addr].emit(addressInfo) + } +} \ No newline at end of file diff --git a/plugins/plugins/core/streams/UnconfirmedTransactionWatcher.js b/plugins/plugins/core/streams/UnconfirmedTransactionWatcher.js index 528ada42..59181c2e 100644 --- a/plugins/plugins/core/streams/UnconfirmedTransactionWatcher.js +++ b/plugins/plugins/core/streams/UnconfirmedTransactionWatcher.js @@ -1,46 +1,46 @@ -import {parentEpml} from '../connect.js' +import { parentEpml } from '../connect' export class UnconfirmedTransactionWatcher { - constructor() { - this._unconfirmedTransactionStreams = {} - this.reset() // Sets defaults + constructor() { + this._unconfirmedTransactionStreams = {} + this.reset() // Sets defaults - setInterval(() => { - Object.entries(this._addresses).forEach((addr) => this._addressTransactionCheck(addr[0])) - }, 10 * 1000) - } + setInterval(() => { + Object.entries(this._addresses).forEach((addr) => this._addressTransactionCheck(addr[0])) + }, 10 * 1000) + } - reset() { - this._addresses = {} - this._addressesUnconfirmedTransactions = {} - } + reset() { + this._addresses = {} + this._addressesUnconfirmedTransactions = {} + } - // Adds an address to watch - addAddress(address) { - const addr = address.address - this._addresses[addr] = address - this._addressesUnconfirmedTransactions[addr] = [] - if (this._unconfirmedTransactionStreams[addr]) return - this._unconfirmedTransactionStreams[addr] = new EpmlStream(`unconfirmedOfAddress/${addr}`, () => this._addressesUnconfirmedTransactions[addr]) - } + // Adds an address to watch + addAddress(address) { + const addr = address.address + this._addresses[addr] = address + this._addressesUnconfirmedTransactions[addr] = [] + if (this._unconfirmedTransactionStreams[addr]) return + this._unconfirmedTransactionStreams[addr] = new EpmlStream(`unconfirmedOfAddress/${addr}`, () => this._addressesUnconfirmedTransactions[addr]) + } - check() { - const c = this._addressTransactionCheck() - .then(() => setTimeout(() => this.check(), 5000)) - .catch(() => setTimeout(() => this.check(), 5000)) - } + check() { + const c = this._addressTransactionCheck() + .then(() => setTimeout(() => this.check(), 5000)) + .catch(() => setTimeout(() => this.check(), 5000)) + } - async _addressTransactionCheck() { - return Promise.all(Object.keys(this._addresses).map(addr => { - return parentEpml.request('apiCall', { - type: 'api', - url: `/transactions/unconfirmed` - }).then(unconfirmedTransactions => { - unconfirmedTransactions.filter(tx => { - tx.creatorAddress === addr || tx.recipient === addr - }) - this._unconfirmedTransactionStreams[addr].emit(unconfirmedTransactions) - }) - })) - } -} + async _addressTransactionCheck() { + return Promise.all(Object.keys(this._addresses).map(addr => { + return parentEpml.request('apiCall', { + type: 'api', + url: `/transactions/unconfirmed` + }).then(unconfirmedTransactions => { + unconfirmedTransactions.filter(tx => { + tx.creatorAddress === addr || tx.recipient === addr + }) + this._unconfirmedTransactionStreams[addr].emit(unconfirmedTransactions) + }) + })) + } +} \ No newline at end of file diff --git a/plugins/plugins/core/streams/onNewBlock.js b/plugins/plugins/core/streams/onNewBlock.js index 70b4068d..dda6e70f 100644 --- a/plugins/plugins/core/streams/onNewBlock.js +++ b/plugins/plugins/core/streams/onNewBlock.js @@ -1,6 +1,7 @@ -import {parentEpml} from '../connect.js' -const MIN_RECONNECT_INTERVAL = 1000; // 1 second -const MAX_RECONNECT_INTERVAL = 60000; // 1 minute +import { parentEpml } from '../connect' + +const MIN_RECONNECT_INTERVAL = 1000 // 1 second +const MAX_RECONNECT_INTERVAL = 60000 // 1 minute let socketObject let activeBlockSocketTimeout @@ -15,227 +16,242 @@ let nodeStatusRetryOnClose = false let nodeStateCall = false let isLoggedIn = false let oldAccountInfo -let blockSocketReconnectInterval = MIN_RECONNECT_INTERVAL; -let nodeStatusSocketReconnectInterval = MIN_RECONNECT_INTERVAL; +let blockSocketReconnectInterval = MIN_RECONNECT_INTERVAL +let nodeStatusSocketReconnectInterval = MIN_RECONNECT_INTERVAL parentEpml.subscribe('logged_in', loggedIn => { - isLoggedIn = loggedIn === 'true'; + isLoggedIn = loggedIn === 'true' }) - const setAccountInfo = async (addr) => { - const names = await parentEpml.request('apiCall', { - url: `/names/address/${addr}` - }) - const addressInfo = await parentEpml.request('apiCall', { - url: `/addresses/${addr}` - }) - let accountInfo = { - names: names, - addressInfo: addressInfo - } - if (window.parent._.isEqual(oldAccountInfo, accountInfo) === true) { + const names = await parentEpml.request('apiCall', { + url: `/names/address/${addr}` + }) - } else { - parentEpml.request('setAccountInfo', accountInfo) - oldAccountInfo = accountInfo - } + const addressInfo = await parentEpml.request('apiCall', { + url: `/addresses/${addr}` + }) + + let accountInfo = { + names: names, + addressInfo: addressInfo + } + + if (window.parent._.isEqual(oldAccountInfo, accountInfo) === true) { + } else { + parentEpml.request('setAccountInfo', accountInfo) + oldAccountInfo = accountInfo + } } const doNodeInfo = async () => { - const nodeInfo = await parentEpml.request('apiCall', { - url: '/admin/info' - }) - parentEpml.request('updateNodeInfo', nodeInfo) + const nodeInfo = await parentEpml.request('apiCall', { + url: '/admin/info' + }) + + parentEpml.request('updateNodeInfo', nodeInfo) } let initStateCount = 0 let oldState const closeSockets = () => { - socketObject.close() - closeGracefully = true - nodeStatusSocketObject.close() - nodeStatusSocketcloseGracefully = true + socketObject.close() + closeGracefully = true + nodeStatusSocketObject.close() + nodeStatusSocketcloseGracefully = true } export const startConfigWatcher = () => { - parentEpml.ready().then(() => { - parentEpml.subscribe('node_config', c => { - if (initStateCount === 0) { - let _oldState = JSON.parse(c) - oldState = { node: _oldState.node, knownNodes: _oldState.knownNodes } - initStateCount = initStateCount + 1 - nodeStateCall = true - isCalled = true - socketObject !== undefined ? closeSockets() : undefined - nodeStatusSocketObject !== undefined ? closeSockets() : undefined - initNodeStatusCall(oldState) - pingactiveBlockSocket() - // Call doNodeInfo - doNodeInfo() - } - let _newState = JSON.parse(c) - let newState = { node: _newState.node, knownNodes: _newState.knownNodes } - if (window.parent._.isEqual(oldState, newState) === true) { + parentEpml.ready().then(() => { + parentEpml.subscribe('node_config', c => { + if (initStateCount === 0) { + let _oldState = JSON.parse(c) + oldState = { node: _oldState.node, knownNodes: _oldState.knownNodes } + initStateCount = initStateCount + 1 + nodeStateCall = true + isCalled = true + socketObject !== undefined ? closeSockets() : undefined + nodeStatusSocketObject !== undefined ? closeSockets() : undefined + initNodeStatusCall(oldState) + pingactiveBlockSocket() + // Call doNodeInfo + doNodeInfo() + } - } else { - oldState = newState - nodeStateCall = true - isCalled = true - socketObject !== undefined ? closeSockets() : undefined - nodeStatusSocketObject !== undefined ? closeSockets() : undefined - initNodeStatusCall(newState) - pingactiveBlockSocket() - // Call doNodeInfo - doNodeInfo() - } - }) - }) - parentEpml.imReady() + let _newState = JSON.parse(c) + let newState = { node: _newState.node, knownNodes: _newState.knownNodes } + + if (window.parent._.isEqual(oldState, newState) === true) { + } else { + oldState = newState + nodeStateCall = true + isCalled = true + socketObject !== undefined ? closeSockets() : undefined + nodeStatusSocketObject !== undefined ? closeSockets() : undefined + initNodeStatusCall(newState) + pingactiveBlockSocket() + // Call doNodeInfo + doNodeInfo() + } + }) + }) + + parentEpml.imReady() } const processBlock = (blockObject) => { - parentEpml.request('updateBlockInfo', blockObject) + parentEpml.request('updateBlockInfo', blockObject) } const doNodeStatus = async (nodeStatusObject) => { - parentEpml.request('updateNodeStatus', nodeStatusObject) + parentEpml.request('updateNodeStatus', nodeStatusObject) } const initNodeStatusCall = (nodeConfig) => { - if (nodeConfig.node >= 0) { - pingNodeStatusSocket() - } else if (nodeStatusSocketObject !== undefined) { - nodeStatusSocketObject.close() - nodeStatusSocketcloseGracefully = true - } else { - // ... - } + if (nodeConfig.node >= 0) { + pingNodeStatusSocket() + } else if (nodeStatusSocketObject !== undefined) { + nodeStatusSocketObject.close() + nodeStatusSocketcloseGracefully = true + } else { + // ... + } } function attemptReconnectBlockSocket() { - setTimeout(() => { - initBlockSocket(); - blockSocketReconnectInterval = Math.min(blockSocketReconnectInterval * 2, MAX_RECONNECT_INTERVAL); - }, blockSocketReconnectInterval); + setTimeout(() => { + initBlockSocket() + blockSocketReconnectInterval = Math.min(blockSocketReconnectInterval * 2, MAX_RECONNECT_INTERVAL) + }, blockSocketReconnectInterval) } function attemptReconnectNodeStatusSocket() { - setTimeout(() => { - initNodeStatusSocket(); - nodeStatusSocketReconnectInterval = Math.min(nodeStatusSocketReconnectInterval * 2, MAX_RECONNECT_INTERVAL); - }, nodeStatusSocketReconnectInterval); + setTimeout(() => { + initNodeStatusSocket() + nodeStatusSocketReconnectInterval = Math.min(nodeStatusSocketReconnectInterval * 2, MAX_RECONNECT_INTERVAL) + }, nodeStatusSocketReconnectInterval) } - const initBlockSocket = () => { - let myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] - let nodeUrl = myNode.domain + ":" + myNode.port - let activeBlockSocketLink - if (window.parent.location.protocol === "https:") { - activeBlockSocketLink = `wss://${nodeUrl}/websockets/blocks` - } else { - activeBlockSocketLink = `ws://${nodeUrl}/websockets/blocks` - } - const activeBlockSocket = new WebSocket(activeBlockSocketLink) - // Open Connection - activeBlockSocket.onopen = (e) => { - blockSocketReconnectInterval = MIN_RECONNECT_INTERVAL; - closeGracefully = false - socketObject = activeBlockSocket - } - // Message Event - activeBlockSocket.onmessage = (e) => { - processBlock(JSON.parse(e.data)) - if (isLoggedIn) { - // Call Set Account Info... - setAccountInfo(window.parent.reduxStore.getState().app.selectedAddress.address) - } - } - // Closed Event - activeBlockSocket.onclose = () => { - processBlock({}); - blockFirstCall = true; - attemptReconnectBlockSocket(); - }; - // Error Event - activeBlockSocket.onerror = (e) => { - blockFirstCall = true - processBlock({}) - } - if (blockFirstCall) { - parentEpml.request('apiCall', { - url: '/blocks/last' - }).then(res => { - processBlock(res) - blockFirstCall = false - }) - } + let myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] + let nodeUrl = myNode.domain + ":" + myNode.port + let activeBlockSocketLink + + if (window.parent.location.protocol === "https:") { + activeBlockSocketLink = `wss://${nodeUrl}/websockets/blocks` + } else { + activeBlockSocketLink = `ws://${nodeUrl}/websockets/blocks` + } + + const activeBlockSocket = new WebSocket(activeBlockSocketLink) + + // Open Connection + activeBlockSocket.onopen = (e) => { + blockSocketReconnectInterval = MIN_RECONNECT_INTERVAL + closeGracefully = false + socketObject = activeBlockSocket + } + + // Message Event + activeBlockSocket.onmessage = (e) => { + processBlock(JSON.parse(e.data)) + if (isLoggedIn) { + // Call Set Account Info... + setAccountInfo(window.parent.reduxStore.getState().app.selectedAddress.address) + } + } + + // Closed Event + activeBlockSocket.onclose = () => { + processBlock({}) + blockFirstCall = true + attemptReconnectBlockSocket() + } + + // Error Event + activeBlockSocket.onerror = (e) => { + blockFirstCall = true + processBlock({}) + } + + if (blockFirstCall) { + parentEpml.request('apiCall', { + url: '/blocks/last' + }).then(res => { + processBlock(res) + blockFirstCall = false + }) + } } const pingactiveBlockSocket = () => { - if (isCalled) { - isCalled = false - initBlockSocket() - activeBlockSocketTimeout = setTimeout(pingactiveBlockSocket, 295000) - } else if (retryOnClose) { - retryOnClose = false - clearTimeout(activeBlockSocketTimeout) - initBlockSocket() - isCalled = true - activeBlockSocketTimeout = setTimeout(pingactiveBlockSocket, 295000) - } else { - socketObject.send("non-integer ping") - activeBlockSocketTimeout = setTimeout(pingactiveBlockSocket, 295000) - } + if (isCalled) { + isCalled = false + initBlockSocket() + activeBlockSocketTimeout = setTimeout(pingactiveBlockSocket, 295000) + } else if (retryOnClose) { + retryOnClose = false + clearTimeout(activeBlockSocketTimeout) + initBlockSocket() + isCalled = true + activeBlockSocketTimeout = setTimeout(pingactiveBlockSocket, 295000) + } else { + socketObject.send("non-integer ping") + activeBlockSocketTimeout = setTimeout(pingactiveBlockSocket, 295000) + } } const initNodeStatusSocket = () => { - let myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] - let nodeUrl = myNode.domain + ":" + myNode.port - let activeNodeStatusSocketLink - if (window.parent.location.protocol === "https:") { - activeNodeStatusSocketLink = `wss://${nodeUrl}/websockets/admin/status` - } else { - activeNodeStatusSocketLink = `ws://${nodeUrl}/websockets/admin/status` - } - const activeNodeStatusSocket = new WebSocket(activeNodeStatusSocketLink) - // Open Connection - activeNodeStatusSocket.onopen = (e) => { - nodeStatusSocketReconnectInterval = MIN_RECONNECT_INTERVAL; + let myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] + let nodeUrl = myNode.domain + ":" + myNode.port + let activeNodeStatusSocketLink - nodeStatusSocketcloseGracefully = false - nodeStatusSocketObject = activeNodeStatusSocket - } - // Message Event - activeNodeStatusSocket.onmessage = (e) => { - doNodeStatus(JSON.parse(e.data)) - } - // Closed Event - activeNodeStatusSocket.onclose = () => { - doNodeStatus({}); - attemptReconnectNodeStatusSocket(); - }; - // Error Event - activeNodeStatusSocket.onerror = (e) => { - doNodeStatus({}) - } + if (window.parent.location.protocol === "https:") { + activeNodeStatusSocketLink = `wss://${nodeUrl}/websockets/admin/status` + } else { + activeNodeStatusSocketLink = `ws://${nodeUrl}/websockets/admin/status` + } + + const activeNodeStatusSocket = new WebSocket(activeNodeStatusSocketLink) + + // Open Connection + activeNodeStatusSocket.onopen = (e) => { + nodeStatusSocketReconnectInterval = MIN_RECONNECT_INTERVAL + nodeStatusSocketcloseGracefully = false + nodeStatusSocketObject = activeNodeStatusSocket + } + + // Message Event + activeNodeStatusSocket.onmessage = (e) => { + doNodeStatus(JSON.parse(e.data)) + } + + // Closed Event + activeNodeStatusSocket.onclose = () => { + doNodeStatus({}) + attemptReconnectNodeStatusSocket() + } + + // Error Event + activeNodeStatusSocket.onerror = (e) => { + doNodeStatus({}) + } } const pingNodeStatusSocket = () => { - if (nodeStateCall) { - clearTimeout(nodeStatusSocketTimeout) - initNodeStatusSocket() - nodeStateCall = false - nodeStatusSocketTimeout = setTimeout(pingNodeStatusSocket, 295000) - } else if (nodeStatusRetryOnClose) { - nodeStatusRetryOnClose = false - clearTimeout(nodeStatusSocketTimeout) - initNodeStatusSocket() - nodeStatusSocketTimeout = setTimeout(pingNodeStatusSocket, 295000) - } else { - nodeStatusSocketObject.send("non-integer ping") - nodeStatusSocketTimeout = setTimeout(pingNodeStatusSocket, 295000) - } -} + if (nodeStateCall) { + clearTimeout(nodeStatusSocketTimeout) + initNodeStatusSocket() + nodeStateCall = false + nodeStatusSocketTimeout = setTimeout(pingNodeStatusSocket, 295000) + } else if (nodeStatusRetryOnClose) { + nodeStatusRetryOnClose = false + clearTimeout(nodeStatusSocketTimeout) + initNodeStatusSocket() + nodeStatusSocketTimeout = setTimeout(pingNodeStatusSocket, 295000) + } else { + nodeStatusSocketObject.send("non-integer ping") + nodeStatusSocketTimeout = setTimeout(pingNodeStatusSocket, 295000) + } +} \ No newline at end of file diff --git a/plugins/plugins/core/streams/streams.js b/plugins/plugins/core/streams/streams.js index 7b382a63..30a5ea3f 100644 --- a/plugins/plugins/core/streams/streams.js +++ b/plugins/plugins/core/streams/streams.js @@ -1,107 +1,102 @@ -import {parentEpml} from '../connect.js' +import { parentEpml } from '../connect' -import {startConfigWatcher} from './onNewBlock.js' +import { startConfigWatcher } from './onNewBlock' const setAccountInfo = async (addr) => { + const names = await parentEpml.request('apiCall', { + url: `/names/address/${addr}` + }) - const names = await parentEpml.request('apiCall', { - url: `/names/address/${addr}` - }) - const addressInfo = await parentEpml.request('apiCall', { - url: `/addresses/${addr}` - }) + const addressInfo = await parentEpml.request('apiCall', { + url: `/addresses/${addr}` + }) - let accountInfo = { - names: names, - addressInfo: addressInfo - } + let accountInfo = { + names: names, + addressInfo: addressInfo + } - parentEpml.request('setAccountInfo', accountInfo) + parentEpml.request('setAccountInfo', accountInfo) } - const objectToArray = (object) => { + let groupList = object.groups.map(group => group.groupId === 0 ? { + groupId: group.groupId, + url: `group/${group.groupId}`, + groupName: "Qortal General Chat", + sender: group.sender, + senderName: group.senderName, + timestamp: group.timestamp === undefined ? 2 : group.timestamp + } : { + ...group, url: `group/${group.groupId}` + }) + + let directList = object.direct.map(dc => { + return { ...dc, url: `direct/${dc.address}` } + }) - let groupList = object.groups.map(group => group.groupId === 0 ? { groupId: group.groupId, url: `group/${group.groupId}`, groupName: "Qortal General Chat", sender: group.sender, senderName: group.senderName, timestamp: group.timestamp === undefined ? 1 : group.timestamp } : { ...group, url: `group/${group.groupId}` }) - let directList = object.direct.map(dc => { - return { ...dc, url: `direct/${dc.address}` } - }) return [...groupList, ...directList] } const sortActiveChat = (activeChatObject, localChatHeads) => { + let oldChatHeads = JSON.parse(localChatHeads) - let oldChatHeads = JSON.parse(localChatHeads) + if (window.parent._.isEqual(oldChatHeads, activeChatObject) === true) { + } else { + let oldActiveChats = objectToArray(oldChatHeads) + let newActiveChats = objectToArray(activeChatObject) - if (window.parent._.isEqual(oldChatHeads, activeChatObject) === true) { - - } else { - - let oldActiveChats = objectToArray(oldChatHeads) - let newActiveChats = objectToArray(activeChatObject) - - let results = newActiveChats.filter(newChat => { - let value = oldActiveChats.some(oldChat => newChat.timestamp === oldChat.timestamp) - return !value - }) - - results.forEach(chat => { - - if (chat.sender !== window.parent.reduxStore.getState().app.selectedAddress.address) { - - if (chat.sender !== undefined) parentEpml.request('showNotification', chat) - } else { - // ... - } - }) - - } + let results = newActiveChats.filter(newChat => { + let value = oldActiveChats.some(oldChat => newChat.timestamp === oldChat.timestamp) + return !value + }) + results.forEach(chat => { + if (chat.sender !== window.parent.reduxStore.getState().app.selectedAddress.address) { + if (chat.sender !== undefined) parentEpml.request('showNotification', chat) + } else { + // ... + } + }) + } } - let initialChatWatch = 0 const chatHeadWatcher = (activeChats) => { + let addr = window.parent.reduxStore.getState().app.selectedAddress.address + let key = `${addr.substr(0, 10)}_chat-heads` - let addr = window.parent.reduxStore.getState().app.selectedAddress.address + try { + let localChatHeads = localStorage.getItem(key) - let key = `${addr.substr(0, 10)}_chat-heads` + if (localChatHeads === null) { + parentEpml.request('setLocalStorage', { + key: key, + dataObj: activeChats + }).then(ms => { + parentEpml.request('setChatHeads', activeChats).then(ret => { + // ... + }) + }) + } else { + parentEpml.request('setLocalStorage', { + key: key, + dataObj: activeChats + }).then(ms => { + parentEpml.request('setChatHeads', activeChats).then(ret => { + // ... + }) + }) - try { - let localChatHeads = localStorage.getItem(key) - - if (localChatHeads === null) { - parentEpml.request('setLocalStorage', { - key: key, - dataObj: activeChats - }).then(ms => { - parentEpml.request('setChatHeads', activeChats).then(ret => { - // ... - }) - }) - } else { - - parentEpml.request('setLocalStorage', { - key: key, - dataObj: activeChats - }).then(ms => { - parentEpml.request('setChatHeads', activeChats).then(ret => { - // ... - }) - }) - - if (initialChatWatch >= 1) { - - sortActiveChat(activeChats, localChatHeads) - } else { - - initialChatWatch = initialChatWatch + 1 - } - } - - } catch (e) { - } + if (initialChatWatch >= 1) { + sortActiveChat(activeChats, localChatHeads) + } else { + initialChatWatch = initialChatWatch + 1 + } + } + } catch (e) { + } } let socketObject @@ -114,120 +109,102 @@ let canPing = false let timeoutId parentEpml.subscribe('logged_in', async isLoggedIn => { + const initChatHeadSocket = () => { + let myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] + let nodeUrl = myNode.domain + ":" + myNode.port + let activeChatSocketLink - const initChatHeadSocket = () => { + if (window.parent.location.protocol === "https:") { + activeChatSocketLink = `wss://${nodeUrl}/websockets/chat/active/${window.parent.reduxStore.getState().app.selectedAddress.address}?encoding=BASE64` + } else { + activeChatSocketLink = `ws://${nodeUrl}/websockets/chat/active/${window.parent.reduxStore.getState().app.selectedAddress.address}?encoding=BASE64` + } - let myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] - let nodeUrl = myNode.domain + ":" + myNode.port + const activeChatSocket = new WebSocket(activeChatSocketLink) - let activeChatSocketLink + // Open Connection + activeChatSocket.onopen = () => { + socketObject = activeChatSocket + initial = initial + 1 + canPing = true + } - if (window.parent.location.protocol === "https:") { + // Message Event + activeChatSocket.onmessage = (e) => { + if (e.data === 'pong') { + clearTimeout(timeoutId) + activeChatSocketTimeout = setTimeout(pingActiveChatSocket, 45000) + return + } - activeChatSocketLink = `wss://${nodeUrl}/websockets/chat/active/${window.parent.reduxStore.getState().app.selectedAddress.address}?encoding=BASE64` - } else { + try { + chatHeadWatcher(JSON.parse(e.data)) + } catch (error) { + } + } - activeChatSocketLink = `ws://${nodeUrl}/websockets/chat/active/${window.parent.reduxStore.getState().app.selectedAddress.address}?encoding=BASE64` - } + // Closed Event + activeChatSocket.onclose = () => { + clearInterval(activeChatSocketTimeout) - const activeChatSocket = new WebSocket(activeChatSocketLink) + if (closeGracefully === false) { + retryOnClose = true + setTimeout(pingActiveChatSocket, 10000) + } + } - // Open Connection - activeChatSocket.onopen = () => { - socketObject = activeChatSocket + // Error Event + activeChatSocket.onerror = (e) => { + } + } - initial = initial + 1 - canPing = true - } + const pingActiveChatSocket = () => { + if (window.parent.reduxStore.getState().app.loggedIn === true) { + if (!onceLoggedIn) { + initChatHeadSocket() + onceLoggedIn = true + activeChatSocketTimeout = setTimeout(pingActiveChatSocket, 45000) + } else if (retryOnClose) { + retryOnClose = false + clearTimeout(activeChatSocketTimeout) + initChatHeadSocket() + onceLoggedIn = true + activeChatSocketTimeout = setTimeout(pingActiveChatSocket, 45000) + } else if (canPing) { + socketObject.send('ping') + timeoutId = setTimeout(() => { + socketObject.close() + clearTimeout(activeChatSocketTimeout) + }, 5000) + } + } else { + if (onceLoggedIn && !closeGracefully) { + closeGracefully = true + socketObject.close() + clearTimeout(activeChatSocketTimeout) + onceLoggedIn = false + canPing = false + } + } + } - // Message Event - activeChatSocket.onmessage = (e) => { - if (e.data === 'pong') { - clearTimeout(timeoutId) - activeChatSocketTimeout = setTimeout(pingActiveChatSocket, 45000) - return - } - try { - chatHeadWatcher(JSON.parse(e.data)) - } catch (error) { - } - } + if (isLoggedIn === 'true') { + // Call Set Account Info... + await setAccountInfo(window.parent.reduxStore.getState().app.selectedAddress.address) - // Closed Event - activeChatSocket.onclose = () => { - clearInterval(activeChatSocketTimeout) + // Start Chat Watcher Socket + pingActiveChatSocket() + } else { + if (onceLoggedIn) { + closeGracefully = true + socketObject.close() + clearTimeout(activeChatSocketTimeout) + onceLoggedIn = false + canPing = false + } - if (closeGracefully === false) { - retryOnClose = true - setTimeout(pingActiveChatSocket, 10000) - } - } - - // Error Event - activeChatSocket.onerror = (e) => { - } - } - - - const pingActiveChatSocket = () => { - - if (window.parent.reduxStore.getState().app.loggedIn === true) { - - if (!onceLoggedIn) { - - initChatHeadSocket() - onceLoggedIn = true - activeChatSocketTimeout = setTimeout(pingActiveChatSocket, 45000) - } else if (retryOnClose) { - - retryOnClose = false - clearTimeout(activeChatSocketTimeout) - initChatHeadSocket() - onceLoggedIn = true - activeChatSocketTimeout = setTimeout(pingActiveChatSocket, 45000) - } else if (canPing) { - - socketObject.send('ping') - timeoutId = setTimeout(() => { - socketObject.close() - clearTimeout(activeChatSocketTimeout) - }, 5000) - } - - } else { - - if (onceLoggedIn && !closeGracefully) { - - closeGracefully = true - socketObject.close() - clearTimeout(activeChatSocketTimeout) - onceLoggedIn = false - canPing = false - } - } - } - - - if (isLoggedIn === 'true') { - - // Call Set Account Info... - await setAccountInfo(window.parent.reduxStore.getState().app.selectedAddress.address) - - // Start Chat Watcher Socket - pingActiveChatSocket() - } else { - - if (onceLoggedIn) { - - closeGracefully = true - socketObject.close() - clearTimeout(activeChatSocketTimeout) - onceLoggedIn = false - canPing = false - } - - initialChatWatch = 0 - } + initialChatWatch = 0 + } }) -startConfigWatcher() +startConfigWatcher() \ No newline at end of file diff --git a/plugins/plugins/core/trade-bot/trade-bot-portal-css.js b/plugins/plugins/core/trade-bot/trade-bot-portal-css.js deleted file mode 100644 index d769c8fb..00000000 --- a/plugins/plugins/core/trade-bot/trade-bot-portal-css.js +++ /dev/null @@ -1,679 +0,0 @@ -import {css} from 'lit' - -export const tradebotStyles = css` - * { - --mdc-theme-primary: rgb(3, 169, 244); - --mdc-theme-secondary: var(--mdc-theme-primary); - --mdc-theme-error: rgb(255, 89, 89); - --mdc-text-field-outlined-idle-border-color: var(--txtfieldborder); - --mdc-text-field-outlined-hover-border-color: var(--txtfieldhoverborder); - --mdc-text-field-label-ink-color: var(--black); - --mdc-text-field-ink-color: var(--black); - --mdc-select-outlined-idle-border-color: var(--txtfieldborder); - --mdc-select-outlined-hover-border-color: var(--txtfieldhoverborder); - --mdc-select-label-ink-color: var(--black); - --mdc-select-ink-color: var(--black); - --mdc-theme-surface: var(--white); - --mdc-dialog-content-ink-color: var(--black); - --mdc-dialog-shape-radius: 25px; - --paper-input-container-focus-color: var(--mdc-theme-primary); - --lumo-primary-text-color: rgb(0, 167, 245); - --lumo-primary-color-50pct: rgba(0, 167, 245, 0.5); - --lumo-primary-color-10pct: rgba(0, 167, 245, 0.1); - --lumo-primary-color: hsl(199, 100%, 48%); - --lumo-base-color: var(--white); - --lumo-body-text-color: var(--black); - --lumo-secondary-text-color: var(--sectxt); - --lumo-contrast-60pct: var(--vdicon); - --_lumo-grid-border-color: var(--border); - --_lumo-grid-secondary-border-color: var(--border2); - } - - paper-spinner-lite { - height: 30px; - width: 30px; - --paper-spinner-color: var(--mdc-theme-primary); - --paper-spinner-stroke-width: 3px; - } - - mwc-tab-bar { - --mdc-text-transform: none; - --mdc-tab-color-default: var(--black); - --mdc-tab-text-label-color-default: var(--black); - } - - #tabs-1 { - --mdc-tab-height: 42px; - border-left: 1px solid var(--tradeborder); - border-top: 1px solid var(--tradeborder); - border-right: 1px solid var(--tradeborder); - color: var(--black); - } - - #tab-buy[active] { - --mdc-theme-primary: rgba(55, 160, 51, 0.9); - } - - #tabs-1-content { - height: 100%; - padding-bottom: 10px; - } - - #tabs-1-content>div { - height: 100%; - border: 1px solid var(--tradeborder); - } - - #tabs-1-content .card { - border: none; - } - - #tabs-1-content .btn-clear { - --mdc-icon-button-size: 32px; - color: var(--black); - } - - .btn-clear-bot { - --mdc-icon-button-size: 32px; - color: var(--black); - float: right; - } - - .btn-info { - color: #03a9f4; - --mdc-icon-size: 16px; - padding-top: 3px; - } - - #tab-sell[active] { - --mdc-theme-primary: rgb(255, 89, 89); - } - - #trade-portal-page { - background: var(--white); - padding: 12px 24px; - } - - .divCard { - border: 1px solid var(--black); - padding: 1em; - box-shadow: 0 0.3px 1px 0 rgba(0, 0, 0, 0.14), 0 1px 1px -1px rgba(0, 0, 0, 0.12), 0 1px 2px 0 rgba(0, 0, 0, 0.2); - } - - h2 { - margin: 10px 0; - } - - h4 { - margin: 5px 0; - } - - p { - font-size: 14px; - line-height: 21px; - } - - .card-body { - background-color: var(--white); - display: flex; - align-items: center; - justify-content: center; - flex-direction: column; - min-height: 100vh; - margin: 0; - } - - .card-container { - background-color: var(--white); - border-radius: 5px; - color: var(--black); - padding-top: 30px; - position: relative; - width: 350px; - max-width: 100%; - text-align: center; - } - - .card-container .level { - color: #ffffff; - background-color: #03a9f4; - border-radius: 3px; - font-size: 14px; - font-weight: bold; - padding: 3px 7px; - position: absolute; - top: 30px; - left: 30px; - } - - .card-container .founder { - color: #ffffff; - background-color: #03a9f4; - border-radius: 3px; - font-size: 14px; - font-weight: bold; - padding: 3px 7px; - position: absolute; - top: 30px; - right: 30px; - } - - .card-container .round { - width: 96px; - height: 96px; - border: 1px solid #03a9f4; - border-radius: 50%; - padding: 2px; - } - - .card-container .badge { - width: 200px; - height: 135px; - border: 1px solid transparent; - border-radius: 10%; - padding: 2px; - } - - .userdata { - background-color: #1F1A36; - text-align: left; - padding: 15px; - margin-top: 30px; - } - - .userdata ul { - list-style-type: none; - margin: 0; - padding: 0; - } - - .userdata ul li { - border: 1px solid #2D2747; - border-radius: 2px; - display: inline-block; - font-size: 12px; - margin: 0 7px 7px 0; - padding: 7px; - } - - h2, - h3, - h4, - h5 { - color: var(--black); - font-weight: 400; - } - - header { - display: flex; - flex: 0 1 auto; - align-items: center; - justify-content: center; - padding: 0px 10px; - font-size: 16px; - color: var(--white); - background-color: var(--tradehead); - border-left: 1px solid var(--tradeborder); - border-top: 1px solid var(--tradeborder); - border-right: 1px solid var(--tradeborder); - min-height: 40px; - } - - p { - margin-bottom: 12px; - } - - #trade-portal { - max-width: 100vw; - margin-left: auto; - margin-right: auto; - } - - .box { - margin: 0; - padding: 0; - display: flex; - flex-flow: column; - height: 100%; - } - - .box-bot { - margin: 0; - padding: 0; - display: flex; - flex-flow: column; - height: 150px; - } - - #first-trade-section { - margin-bottom: 10px; - } - - #first-trade-section>div {} - - #second-trade-section { - margin-bottom: 10px; - } - - #second-trade-section>div {} - - #third-trade-section { - margin-bottom: 10px; - } - - #third-trade-section>div {} - - .trade-chart { - background-color: var(--white); - border: 2px #ddd solid; - text-align: center; - } - - .open-trades { - text-align: center; - } - - .open-market-container { - text-align: center; - } - - .trade-bot-container { - text-align: center; - } - - .no-last-seen { - background: rgb(255, 89, 89); - padding: 9px 1.3px; - border-radius: 50%; - width: 1rem; - margin: 0 auto; - } - - .card { - padding: 1em; - border: 1px var(--tradeborder) solid; - flex: 1 1 auto; - display: flex; - flex-flow: column; - justify-content: space-evenly; - min-height: inherit; - } - - .card-bot { - padding: 1em; - flex: 1 1 auto; - display: flex; - flex-flow: column; - justify-content: space-evenly; - width: 350px; - min-height: inherit; - } - - .cancel { - --mdc-theme-primary: rgb(255, 89, 89); - } - - .border-wrapper { - border: 1px var(--tradeborder) solid; - overflow: hidden; - } - - .amt-text { - color: var(--tradehave); - font-size: 15px; - margin-top: 5px; - margin-bottom: 12px; - } - - .exchange { - color: var(--black); - font-size: 18px; - font-weight: bold; - margin-top: 5px; - margin-bottom: 10px; - } - - .clear-button { - display: inline; - float: right; - margin-bottom: 5px; - } - - .exhcnage-text { - display: inline; - float: left; - margin-bottom: 5px; - } - - .balance-text { - display: inline; - float: right; - margin-bottom: 5px; - } - - .fee-text { - display: inline; - float: left; - margin-bottom: 5px; - } - - .tab-text { - color: var(--tradehave); - font-size: 12px; - text-align: left; - margin-top: 2px; - margin-bottom: -12px; - } - - .historic-trades { - text-align: center; - } - - .my-open-orders { - text-align: center; - } - - .my-historic-trades { - text-align: center; - } - - .buttons { - width: auto !important; - } - - .buy-button { - --mdc-theme-primary: rgba(55, 160, 51, 0.9); - } - - .sell-button { - --mdc-theme-primary: rgb(255, 89, 89); - } - - .trade-bot-button { - margin-top: 20px; - margin-bottom: 20px; - --mdc-theme-primary: rgba(55, 160, 51, 0.9); - } - - .full-width { - background-color: var(--white); - border: 2px var(--black); - height: 200px; - text-align: center; - } - - vaading-grid { - font-size: .8em; - } - - vaadin-grid-column { - flex-grow: 1; - } - - .loadingContainer { - height: 100%; - width: 100%; - } - - .loading, - .loading:after { - border-radius: 50%; - width: 5em; - height: 5em; - } - - .loading { - margin: 10px auto; - border-width: .6em; - border-style: solid; - border-color: rgba(3, 169, 244, 0.2) rgba(3, 169, 244, 0.2) rgba(3, 169, 244, 0.2) rgb(3, 169, 244); - font-size: 10px; - position: relative; - text-indent: -9999em; - transform: translateZ(0px); - animation: 1.1s linear 0s infinite normal none running loadingAnimation; - } - - mwc-select#coinSelectionMenu { - font-size: 24px; - width: 220px; - } - - mwc-select#coinSelectionMenu mwc-list-item { - line-height: 30px; - } - - .coinName::before { - content: ""; - display: inline-block; - height: 26px; - width: 45px; - position: absolute; - background-repeat: no-repeat; - background-size: cover; - left: 10px; - top: 10px; - } - - .btc.coinName:before { - background-image: url('/img/qortbtc.png'); - } - - .ltc.coinName:before { - background-image: url('/img/qortltc.png'); - } - - .doge.coinName:before { - background-image: url('/img/qortdoge.png'); - } - - .dgb.coinName:before { - background-image: url('/img/qortdgb.png'); - } - - .rvn.coinName:before { - background-image: url('/img/qortrvn.png'); - } - - .arrr.coinName:before { - background-image: url('/img/qortarrr.png'); - } - - .coinName { - display: inline-block; - height: 26px; - padding-left: 45px; - } - - .warning-text { - animation: blinker 1.5s linear infinite; - display: inline; - float: left; - margin-bottom: 5px; - color: rgb(255, 89, 89); - } - - .warning-bot-text { - animation: blinker 1.5s linear infinite; - display: inline; - text-align: center; - color: rgb(255, 89, 89); - } - - .red { - --mdc-theme-primary: #F44336; - } - - @-webkit-keyframes loadingAnimation { - 0% { - -webkit-transform: rotate(0deg); - transform: rotate(0deg); - } - - 100% { - -webkit-transform: rotate(360deg); - transform: rotate(360deg); - } - } - - @keyframes loadingAnimation { - 0% { - -webkit-transform: rotate(0deg); - transform: rotate(0deg); - } - - 100% { - -webkit-transform: rotate(360deg); - transform: rotate(360deg); - } - } - - @keyframes blinker { - 50% { - opacity: 0; - } - } - - paper-dialog.info { - width: 75%; - max-width: 75vw; - height: 50%; - max-height: 50vh; - background-color: var(--white); - color: var(--black); - border: 1px solid var(--black); - border-radius: 15px; - line-height: 1.6; - overflow-y: auto; - } - - .actions { - display: flex; - justify-content: space-between; - padding: 0 1em; - margin: 12px 0 -6px 0; - } - - .close-icon { - font-size: 36px; - } - - .close-icon:hover { - cursor: pointer; - opacity: .6; - } - - .setpass-wrapper { - width: 100%; - min-width: 400px; - max-width: 450px; - text-align: center; - background: var(--white); - border: 1px solid var(--black); - border-radius: 15px; - padding: 10px 10px 0px; - box-shadow: 0px 10px 15px rgba(0, 0, 0, 0.1); - } - - .lock-wrapper { - width: 100%; - height: 100%; - min-width: 600px; - max-width: 600px; - min-height: 400px; - max-height: 400px; - text-align: center; - background: url("/img/qortal-lock.jpg"); - border: 1px solid var(--black); - border-radius: 25px; - padding: 10px 10px 0px; - } - - .text-wrapper { - width: 100%; - height: 100%; - min-width: 280px; - max-width: 280px; - min-height: 64px; - max-height: 64px; - text-align: center; - margin-left: 35px; - margin-top: 125px; - overflow: hidden; - } - - .lock-title-white { - font-family: 'magistralbold'; - font-weight: 700; - font-size: 26px; - line-height: 32px; - color: #ffffff; - } - - .lock-title-red { - font-family: 'magistralbold'; - font-weight: 700; - font-size: 26px; - line-height: 32px; - color: #df3636; - } - - @media (min-width: 701px) { - * {} - - #trade-bot-portal { - display: grid; - grid-template-columns: 2fr 4fr 2fr; - grid-auto-rows: max(80px); - column-gap: 0.5em; - row-gap: 0.4em; - justify-items: stretch; - align-items: stretch; - margin-bottom: 20px; - } - - #first-trade-section { - display: grid; - grid-template-columns: 1fr 4fr 1fr; - grid-auto-rows: max(250px); - column-gap: 0.5em; - row-gap: 0.4em; - justify-items: stretch; - align-items: stretch; - margin-bottom: 10px; - } - - #second-trade-section { - display: grid; - grid-template-columns: 1fr 4fr 1fr; - grid-auto-rows: max(250px); - column-gap: 0.5em; - row-gap: 0.4em; - justify-items: stretch; - align-items: stretch; - margin-bottom: 10px; - } - - #third-trade-section { - display: grid; - grid-template-columns: 1fr 4fr 1fr; - grid-auto-rows: max(150px); - column-gap: 0.5em; - row-gap: 0.4em; - justify-items: stretch; - align-items: stretch; - margin-bottom: 10px; - } - - #fourth-trade-section { - display: grid; - grid-template-columns: 1fr 4fr 1fr; - grid-auto-rows: max(150px); - column-gap: 0.5em; - row-gap: 0.4em; - justify-items: stretch; - align-items: stretch; - margin-bottom: 10px; - } - } -` \ No newline at end of file diff --git a/plugins/plugins/core/trade-bot/trade-bot-portal.src.js b/plugins/plugins/core/trade-bot/trade-bot-portal.src.js index d8296e49..909a40e5 100644 --- a/plugins/plugins/core/trade-bot/trade-bot-portal.src.js +++ b/plugins/plugins/core/trade-bot/trade-bot-portal.src.js @@ -1,11 +1,10 @@ -import {html, LitElement} from 'lit' -import {render} from 'lit/html.js' -import {Epml} from '../../../epml.js' +import { html, LitElement } from 'lit' +import { render } from 'lit/html.js' +import { Epml } from '../../../epml' +import { decryptData, encryptData } from '../../../../core/src/lockScreen' +import { tradeBotStyles } from '../components/plugins-css' import isElectron from 'is-electron' -import {get, registerTranslateConfig, translate, use} from '../../../../core/translate' -import Base58 from '../../../../crypto/api/deps/Base58.js' -import {decryptData, encryptData} from '../../../../core/src/lockScreen.js' -import {tradebotStyles} from './trade-bot-portal-css.js' +import Base58 from '../../../../crypto/api/deps/Base58' import '@material/mwc-button' import '@material/mwc-textfield' import '@material/mwc-icon' @@ -24,8 +23,10 @@ import '@vaadin/grid' import '@vaadin/grid/vaadin-grid-sorter' import '@vaadin/password-field' +// Multi language support +import { get, registerTranslateConfig, translate, use } from '../../../../core/translate' registerTranslateConfig({ - loader: lang => fetch(`/language/${lang}.json`).then(res => res.json()) + loader: lang => fetch(`/language/${lang}.json`).then(res => res.json()) }) const parentEpml = new Epml({ type: 'WINDOW', source: window.parent }) @@ -33,3283 +34,3331 @@ const parentEpml = new Epml({ type: 'WINDOW', source: window.parent }) let workers = new Map() class TradeBotPortal extends LitElement { - static get properties() { - return { - selectedAddress: { type: Object }, - config: { type: Object }, - listedCoins: { type: Map }, - blockedTradesList: { type: Array }, - tradesPresenceCleaned: { type: Array }, - sellBtnDisable: { type: Boolean }, - isSellLoading: { type: Boolean }, - isBuyLoading: { type: Boolean }, - buyBtnDisable: { type: Boolean }, - autoBuyWarning: { type: Boolean }, - autoBuyBtnDisable: { type: Boolean }, - autoBuyBotDisable: { type: Boolean }, - initialAmount: { type: Number }, - cancelBtnDisable: { type: Boolean }, - cancelStuckOfferBtnDisable: { type: Boolean }, - selectedCoin: { type: String }, - isLoadingHistoricTrades: { type: Boolean }, - isLoadingOpenTrades: { type: Boolean }, - isLoadingMyOpenOrders: { type: Boolean }, - showGetWalletBance: { type: Boolean }, - showAddAutoBuy: { type: Boolean }, - theme: { type: String, reflect: true }, - btcWallet: { type: String }, - ltcWallet: { type: String }, - dogeWallet: { type: String }, - dgbWallet: { type: String }, - rvnWallet: { type: String }, - arrrWallet: { type: String }, - arrrWalletAddress: { type: String }, - qortbtc: { type: Number }, - qortltc: { type: Number }, - qortdoge: { type: Number }, - qortdgb: { type: Number }, - qortrvn: { type: Number }, - qortarrr: { type: Number }, - btcqort: { type: Number }, - ltcqort: { type: Number }, - dogeqort: { type: Number }, - dgbqort: { type: Number }, - rvnqort: { type: Number }, - arrrqort: { type: Number }, - tradeBotBtcBook: { type: Array }, - tradeBotLtcBook: { type: Array }, - tradeBotDogeBook: { type: Array }, - tradeBotDgbBook: { type: Array }, - tradeBotRvnBook: { type: Array }, - tradeBotArrrBook: { type: Array }, - autoSalt: { type: String }, - autoStorageData: { type: String }, - autoLockScreenPass: { type: String }, - autoLockScreenSet: { type: String }, - autoLockPass: { type: String }, - autoLockSet: { type: String }, - myAutoLockScreenPass: { type: String }, - myAutoLockScreenSet: { type: String }, - autoHelperMessage: { type: String } - } - } + static get properties() { + return { + selectedAddress: { type: Object }, + config: { type: Object }, + listedCoins: { type: Map }, + blockedTradesList: { type: Array }, + tradesPresenceCleaned: { type: Array }, + sellBtnDisable: { type: Boolean }, + isSellLoading: { type: Boolean }, + isBuyLoading: { type: Boolean }, + buyBtnDisable: { type: Boolean }, + autoBuyWarning: { type: Boolean }, + autoBuyBtnDisable: { type: Boolean }, + autoBuyBotDisable: { type: Boolean }, + initialAmount: { type: Number }, + cancelBtnDisable: { type: Boolean }, + cancelStuckOfferBtnDisable: { type: Boolean }, + selectedCoin: { type: String }, + isLoadingHistoricTrades: { type: Boolean }, + isLoadingOpenTrades: { type: Boolean }, + isLoadingMyOpenOrders: { type: Boolean }, + showGetWalletBance: { type: Boolean }, + showAddAutoBuy: { type: Boolean }, + theme: { type: String, reflect: true }, + btcWallet: { type: String }, + ltcWallet: { type: String }, + dogeWallet: { type: String }, + dgbWallet: { type: String }, + rvnWallet: { type: String }, + arrrWallet: { type: String }, + arrrWalletAddress: { type: String }, + qortbtc: { type: Number }, + qortltc: { type: Number }, + qortdoge: { type: Number }, + qortdgb: { type: Number }, + qortrvn: { type: Number }, + qortarrr: { type: Number }, + btcqort: { type: Number }, + ltcqort: { type: Number }, + dogeqort: { type: Number }, + dgbqort: { type: Number }, + rvnqort: { type: Number }, + arrrqort: { type: Number }, + tradeBotBtcBook: { type: Array }, + tradeBotLtcBook: { type: Array }, + tradeBotDogeBook: { type: Array }, + tradeBotDgbBook: { type: Array }, + tradeBotRvnBook: { type: Array }, + tradeBotArrrBook: { type: Array }, + autoSalt: { type: String }, + autoStorageData: { type: String }, + autoLockScreenPass: { type: String }, + autoLockScreenSet: { type: String }, + autoLockPass: { type: String }, + autoLockSet: { type: String }, + myAutoLockScreenPass: { type: String }, + myAutoLockScreenSet: { type: String }, + autoHelperMessage: { type: String } + } + } - static get styles() { - return [tradebotStyles] - } + static get styles() { + return [tradeBotStyles] + } - constructor() { - super() - let qortal = { - name: "QORTAL", - balance: "0", - coinCode: "QORT", - coinAmount: this.amountString, - tradeFee: "0.002" - } + constructor() { + super() + let qortal = { + name: "QORTAL", + balance: "0", + coinCode: "QORT", + coinAmount: this.amountString, + tradeFee: "0.002" + } - let bitcoin = { - name: "BITCOIN", - balance: "0", - coinCode: "BTC", - openOrders: [], - openFilteredOrders: [], - historicTrades: [], - myOrders: [], - myHistoricTrades: [], - myOfferingOrders: [], - myGridBoughtItems: [], - openTradeOrders: null, - tradeOffersSocketCounter: 1, - coinAmount: this.amountString, - tradeFee: "~0.0001" - } + let bitcoin = { + name: "BITCOIN", + balance: "0", + coinCode: "BTC", + openOrders: [], + openFilteredOrders: [], + historicTrades: [], + myOrders: [], + myHistoricTrades: [], + myOfferingOrders: [], + myGridBoughtItems: [], + openTradeOrders: null, + tradeOffersSocketCounter: 1, + coinAmount: this.amountString, + tradeFee: "~0.0001" + } - let litecoin = { - name: "LITECOIN", - balance: "0", - coinCode: "LTC", - openOrders: [], - openFilteredOrders: [], - historicTrades: [], - myOrders: [], - myHistoricTrades: [], - myOfferingOrders: [], - myGridBoughtItems: [], - openTradeOrders: null, - tradeOffersSocketCounter: 1, - coinAmount: this.amountString, - tradeFee: "~0.00005" - } + let litecoin = { + name: "LITECOIN", + balance: "0", + coinCode: "LTC", + openOrders: [], + openFilteredOrders: [], + historicTrades: [], + myOrders: [], + myHistoricTrades: [], + myOfferingOrders: [], + myGridBoughtItems: [], + openTradeOrders: null, + tradeOffersSocketCounter: 1, + coinAmount: this.amountString, + tradeFee: "~0.00005" + } - let dogecoin = { - name: "DOGECOIN", - balance: "0", - coinCode: "DOGE", - openOrders: [], - openFilteredOrders: [], - historicTrades: [], - myOrders: [], - myHistoricTrades: [], - myOfferingOrders: [], - myGridBoughtItems: [], - openTradeOrders: null, - tradeOffersSocketCounter: 1, - coinAmount: this.amountString, - tradeFee: "~0.005" - } + let dogecoin = { + name: "DOGECOIN", + balance: "0", + coinCode: "DOGE", + openOrders: [], + openFilteredOrders: [], + historicTrades: [], + myOrders: [], + myHistoricTrades: [], + myOfferingOrders: [], + myGridBoughtItems: [], + openTradeOrders: null, + tradeOffersSocketCounter: 1, + coinAmount: this.amountString, + tradeFee: "~0.005" + } - let digibyte = { - name: "DIGIBYTE", - balance: "0", - coinCode: "DGB", - openOrders: [], - openFilteredOrders: [], - historicTrades: [], - myOrders: [], - myHistoricTrades: [], - myOfferingOrders: [], - myGridBoughtItems: [], - openTradeOrders: null, - tradeOffersSocketCounter: 1, - coinAmount: this.amountString, - tradeFee: "~0.0005" - } + let digibyte = { + name: "DIGIBYTE", + balance: "0", + coinCode: "DGB", + openOrders: [], + openFilteredOrders: [], + historicTrades: [], + myOrders: [], + myHistoricTrades: [], + myOfferingOrders: [], + myGridBoughtItems: [], + openTradeOrders: null, + tradeOffersSocketCounter: 1, + coinAmount: this.amountString, + tradeFee: "~0.0005" + } - let ravencoin = { - name: "RAVENCOIN", - balance: "0", - coinCode: "RVN", - openOrders: [], - openFilteredOrders: [], - historicTrades: [], - myOrders: [], - myHistoricTrades: [], - myOfferingOrders: [], - myGridBoughtItems: [], - openTradeOrders: null, - tradeOffersSocketCounter: 1, - coinAmount: this.amountString, - tradeFee: "~0.006" - } + let ravencoin = { + name: "RAVENCOIN", + balance: "0", + coinCode: "RVN", + openOrders: [], + openFilteredOrders: [], + historicTrades: [], + myOrders: [], + myHistoricTrades: [], + myOfferingOrders: [], + myGridBoughtItems: [], + openTradeOrders: null, + tradeOffersSocketCounter: 1, + coinAmount: this.amountString, + tradeFee: "~0.006" + } - let piratechain = { - name: "PIRATECHAIN", - balance: "0", - coinCode: "ARRR", - openOrders: [], - openFilteredOrders: [], - historicTrades: [], - myOrders: [], - myHistoricTrades: [], - myOfferingOrders: [], - myGridBoughtItems: [], - openTradeOrders: null, - tradeOffersSocketCounter: 1, - coinAmount: this.amountString, - tradeFee: "~0.0002" - } + let piratechain = { + name: "PIRATECHAIN", + balance: "0", + coinCode: "ARRR", + openOrders: [], + openFilteredOrders: [], + historicTrades: [], + myOrders: [], + myHistoricTrades: [], + myOfferingOrders: [], + myGridBoughtItems: [], + openTradeOrders: null, + tradeOffersSocketCounter: 1, + coinAmount: this.amountString, + tradeFee: "~0.0002" + } - this.listedCoins = new Map() - this.listedCoins.set("QORTAL", qortal) - this.listedCoins.set("BITCOIN", bitcoin) - this.listedCoins.set("LITECOIN", litecoin) - this.listedCoins.set("DOGECOIN", dogecoin) - this.listedCoins.set("DIGIBYTE", digibyte) - this.listedCoins.set("RAVENCOIN", ravencoin) - this.listedCoins.set("PIRATECHAIN", piratechain) + this.listedCoins = new Map() + this.listedCoins.set("QORTAL", qortal) + this.listedCoins.set("BITCOIN", bitcoin) + this.listedCoins.set("LITECOIN", litecoin) + this.listedCoins.set("DOGECOIN", dogecoin) + this.listedCoins.set("DIGIBYTE", digibyte) + this.listedCoins.set("RAVENCOIN", ravencoin) + this.listedCoins.set("PIRATECHAIN", piratechain) - workers.set("QORTAL", { - tradesConnectedWorker: null, - handleStuckTradesConnectedWorker: null - }) + workers.set("QORTAL", { + tradesConnectedWorker: null, + handleStuckTradesConnectedWorker: null + }) - workers.set("BITCOIN", { - tradesConnectedWorker: null, - handleStuckTradesConnectedWorker: null - }) + workers.set("BITCOIN", { + tradesConnectedWorker: null, + handleStuckTradesConnectedWorker: null + }) - workers.set("LITECOIN", { - tradesConnectedWorker: null, - handleStuckTradesConnectedWorker: null - }) + workers.set("LITECOIN", { + tradesConnectedWorker: null, + handleStuckTradesConnectedWorker: null + }) - workers.set("DOGECOIN", { - tradesConnectedWorker: null, - handleStuckTradesConnectedWorker: null - }) + workers.set("DOGECOIN", { + tradesConnectedWorker: null, + handleStuckTradesConnectedWorker: null + }) - workers.set("DIGIBYTE", { - tradesConnectedWorker: null, - handleStuckTradesConnectedWorker: null - }) + workers.set("DIGIBYTE", { + tradesConnectedWorker: null, + handleStuckTradesConnectedWorker: null + }) - workers.set("RAVENCOIN", { - tradesConnectedWorker: null, - handleStuckTradesConnectedWorker: null - }) + workers.set("RAVENCOIN", { + tradesConnectedWorker: null, + handleStuckTradesConnectedWorker: null + }) - workers.set("PIRATECHAIN", { - tradesConnectedWorker: null, - handleStuckTradesConnectedWorker: null - }) + workers.set("PIRATECHAIN", { + tradesConnectedWorker: null, + handleStuckTradesConnectedWorker: null + }) - this.selectedCoin = "LITECOIN" - this.selectedAddress = {} - this.config = {} - this.blockedTradesList = [] - this.tradesPresenceCleaned = [] - this.sellBtnDisable = false - this.isSellLoading = false - this.buyBtnDisable = true - this.autoBuyWarning = false - this.autoBuyBtnDisable = true - this.autoBuyBotDisable = false - this.isBuyLoading = false - this.initialAmount = 0 - this.cancelBtnDisable = false - this.cancelStuckOfferBtnDisable = false - this.isLoadingHistoricTrades = true - this.isLoadingOpenTrades = true - this.isLoadingMyOpenOrders = false - this.showGetWalletBance = true - this.showAddAutoBuy = false - this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light' - this.btcWallet = '' - this.ltcWallet = '' - this.dogeWallet = '' - this.dgbWallet = '' - this.rvnWallet = '' - this.arrrWallet = '' - this.arrrWalletAddress = '' - this.qortbtc = 0 - this.qortltc = 0 - this.qortdoge = 0 - this.qortdgb = 0 - this.qortrvn = 0 - this.qortarrr = 0 - this.btcqort = 0 - this.ltcqort = 0 - this.dogeqort = 0 - this.dgbqort = 0 - this.rvnqort = 0 - this.arrrqort = 0 - this.tradeBotBtcBook = [] - this.tradeBotLtcBook = [] - this.tradeBotDogeBook = [] - this.tradeBotDgbBook = [] - this.tradeBotRvnBook = [] - this.tradeBotArrrBook = [] - this.autoSalt = '' - this.autoStorageData = '' - this.autoLockScreenPass = '' - this.autoLockScreenSet = '' - this.autoLockPass = '' - this.autoLockSet = '' - this.myAutoLockScreenPass = '' - this.myAutoLockScreenSet = '' - this.autoHelperMessage = '' - } + this.selectedCoin = "LITECOIN" + this.selectedAddress = {} + this.config = {} + this.blockedTradesList = [] + this.tradesPresenceCleaned = [] + this.sellBtnDisable = false + this.isSellLoading = false + this.buyBtnDisable = true + this.autoBuyWarning = false + this.autoBuyBtnDisable = true + this.autoBuyBotDisable = false + this.isBuyLoading = false + this.initialAmount = 0 + this.cancelBtnDisable = false + this.cancelStuckOfferBtnDisable = false + this.isLoadingHistoricTrades = true + this.isLoadingOpenTrades = true + this.isLoadingMyOpenOrders = false + this.showGetWalletBance = true + this.showAddAutoBuy = false + this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light' + this.btcWallet = '' + this.ltcWallet = '' + this.dogeWallet = '' + this.dgbWallet = '' + this.rvnWallet = '' + this.arrrWallet = '' + this.arrrWalletAddress = '' + this.qortbtc = 0 + this.qortltc = 0 + this.qortdoge = 0 + this.qortdgb = 0 + this.qortrvn = 0 + this.qortarrr = 0 + this.btcqort = 0 + this.ltcqort = 0 + this.dogeqort = 0 + this.dgbqort = 0 + this.rvnqort = 0 + this.arrrqort = 0 + this.tradeBotBtcBook = [] + this.tradeBotLtcBook = [] + this.tradeBotDogeBook = [] + this.tradeBotDgbBook = [] + this.tradeBotRvnBook = [] + this.tradeBotArrrBook = [] + this.autoSalt = '' + this.autoStorageData = '' + this.autoLockScreenPass = '' + this.autoLockScreenSet = '' + this.autoLockPass = '' + this.autoLockSet = '' + this.myAutoLockScreenPass = '' + this.myAutoLockScreenSet = '' + this.autoHelperMessage = '' + } - openTradesTemplate() { - return html` -
    -
    -
    ${this.listedCoins.get(this.selectedCoin).coinCode} ${translate("tradepage.tchange42")}
    -
    -
    ${translate("login.loading")}
    - - { - render(html`${this.round(data.item.qortAmount)}`, root) - }} - > - - { - render(html`${this.round(data.item.price)}`, root) - }} - > - - { - render(html`${data.item.foreignAmount}`, root) - }} - > - - { - render(html`${data.item.qortalCreator}`, root) - }} - > - - + render() { + return html` +
    +
    +
    +
    +

    ${translate("info.inf13")} QORT ${translate("info.inf14")} ${this.listedCoins.get(this.selectedCoin).coinCode} -  

    + + BTC / QORT + LTC / QORT + DOGE / QORT + DGB / QORT + RVN / QORT + ARRR / QORT + +
    + this.shadowRoot.getElementById('buyInfoDialog').open()}> +
    +
    + ${this.renderAutoLockButton()} +
    +
    +
    +
    +
    +
    +
    + ${this.openTradesTemplate()} +
    +
    +
    +
    + ${this.myDoneTradesTemplate()} +
    +
    +
    +
    + ${this.myOpenOrdersTemplate()} +
    +
    +
    +
    + ${this.showAutoBuyGrid()} +
    +
    +
    +

    ${translate("tradepage.tchange33")} ${this.listedCoins.get(this.selectedCoin).coinCode} ${translate("tradepage.tchange40")}

    +

    1 QORT = ${this.exchangeRateQort()} ${this.listedCoins.get(this.selectedCoin).coinCode}

    +
    -
    - ` - } + +
    +

    + ${this.renderFetchText()} + +

    +
    +
    +
    +

    ${this.listedCoins.get(this.selectedCoin).coinCode} ==> QORT

    +
    +
    +
    +
    ${this.renderWarning()}
    + +
    + ${translate("tradepage.tchange8")} (QORT)* +

    + + +

    + ${translate("tradepage.tchange14")} (${this.listedCoins.get(this.selectedCoin).coinCode})* +

    + + +

    + ${translate("tradepage.tchange10")} (${this.listedCoins.get(this.selectedCoin).coinCode})* +

    + + +

    + + ${translate("tradepage.tchange16")}: ${this.listedCoins.get(this.selectedCoin).balance} ${this.listedCoins.get(this.selectedCoin).coinCode} + +
    +
    + + ${translate("tradepage.tchange38")} ${this.listedCoins.get(this.selectedCoin).coinCode} ${translate("tradepage.tchange39")} + +
    +
    +
    + ${translate("general.close")} +
    + +
    +

    + ${this.renderFetchText()} + +

    +
    +
    +
    +

    ${this.listedCoins.get(this.selectedCoin).coinCode} ==> QORT

    +
    +
    +
    +
    ${this.renderWarning()}
    + +
    + ${translate("tradepage.tchange8")} (QORT)* +

    + + +

    + ${translate("tradepage.tchange14")} (${this.listedCoins.get(this.selectedCoin).coinCode})* +

    + + +

    + ${translate("tradepage.tchange10")} (${this.listedCoins.get(this.selectedCoin).coinCode})* +

    + + +

    + + ${translate("tradepage.tchange16")}: ${this.listedCoins.get(this.selectedCoin).balance} ${this.listedCoins.get(this.selectedCoin).coinCode} + +
    +
    + + ${translate("tradepage.tchange38")} ${this.listedCoins.get(this.selectedCoin).coinCode} ${translate("tradepage.tchange39")} + +
    +
    +
    + ${translate("general.close")} +
    + +
    +

    + ${this.renderFetchText()} + +

    +
    +
    +
    +

    ${this.listedCoins.get(this.selectedCoin).coinCode} ==> QORT

    +
    +
    +
    +
    ${this.renderWarning()}
    + +
    + ${translate("tradepage.tchange8")} (QORT)* +

    + + +

    + ${translate("tradepage.tchange14")} (${this.listedCoins.get(this.selectedCoin).coinCode})* +

    + + +

    + ${translate("tradepage.tchange10")} (${this.listedCoins.get(this.selectedCoin).coinCode})* +

    + + +

    + + ${translate("tradepage.tchange16")}: ${this.listedCoins.get(this.selectedCoin).balance} ${this.listedCoins.get(this.selectedCoin).coinCode} + +
    +
    + + ${translate("tradepage.tchange38")} ${this.listedCoins.get(this.selectedCoin).coinCode} ${translate("tradepage.tchange39")} + +
    +
    +
    + ${translate("general.close")} +
    + +
    +

    + ${this.renderFetchText()} + +

    +
    +
    +
    +

    ${this.listedCoins.get(this.selectedCoin).coinCode} ==> QORT

    +
    +
    +
    +
    ${this.renderWarning()}
    + +
    + ${translate("tradepage.tchange8")} (QORT)* +

    + + +

    + ${translate("tradepage.tchange14")} (${this.listedCoins.get(this.selectedCoin).coinCode})* +

    + + +

    + ${translate("tradepage.tchange10")} (${this.listedCoins.get(this.selectedCoin).coinCode})* +

    + + +

    + + ${translate("tradepage.tchange16")}: ${this.listedCoins.get(this.selectedCoin).balance} ${this.listedCoins.get(this.selectedCoin).coinCode} + +
    +
    + + ${translate("tradepage.tchange38")} ${this.listedCoins.get(this.selectedCoin).coinCode} ${translate("tradepage.tchange39")} + +
    +
    +
    + ${translate("general.close")} +
    + +
    +

    + ${this.renderFetchText()} + +

    +
    +
    +
    +

    ${this.listedCoins.get(this.selectedCoin).coinCode} ==> QORT

    +
    +
    +
    +
    ${this.renderWarning()}
    + +
    + ${translate("tradepage.tchange8")} (QORT)* +

    + + +

    + ${translate("tradepage.tchange14")} (${this.listedCoins.get(this.selectedCoin).coinCode})* +

    + + +

    + ${translate("tradepage.tchange10")} (${this.listedCoins.get(this.selectedCoin).coinCode})* +

    + + +

    + + ${translate("tradepage.tchange16")}: ${this.listedCoins.get(this.selectedCoin).balance} ${this.listedCoins.get(this.selectedCoin).coinCode} + +
    +
    + + ${translate("tradepage.tchange38")} ${this.listedCoins.get(this.selectedCoin).coinCode} ${translate("tradepage.tchange39")} + +
    +
    +
    + ${translate("general.close")} +
    + +
    +

    + ${this.renderFetchText()} + +

    +
    +
    +
    +

    ${this.listedCoins.get(this.selectedCoin).coinCode} ==> QORT

    +
    +
    +
    +
    ${this.renderWarning()}
    + +
    + ${translate("tradepage.tchange8")} (QORT)* +

    + + +

    + ${translate("tradepage.tchange14")} (${this.listedCoins.get(this.selectedCoin).coinCode})* +

    + + +

    + ${translate("tradepage.tchange10")} (${this.listedCoins.get(this.selectedCoin).coinCode})* +

    + + +

    + + ${translate("tradepage.tchange16")}: ${this.listedCoins.get(this.selectedCoin).balance} ${this.listedCoins.get(this.selectedCoin).coinCode} + +
    +
    + + ${translate("tradepage.tchange38")} ${this.listedCoins.get(this.selectedCoin).coinCode} ${translate("tradepage.tchange39")} + +
    +
    +
    + ${translate("general.close")} +
    + +
    +

    + this.shadowRoot.getElementById('buyInfoDialog').close()} title="${translate("info.inf8")}">highlight_off +
    +
    +

    ${translate("info.inf7")}

    +

    ${translate("info.inf9")}

    +

    ${translate("info.inf10")}

    +

    ${translate("info.inf11")}

    +

    ${translate("info.inf12")}

    +
    +
    + +
    +

    Qortal ${translate("tabmenu.tm6")} ${translate("login.lp1")}

    +
    +
    +
    +

    ${translate("login.lp2")}

    +

    ${translate("login.lp3")}

    +
    +
    + password + +
    +
    + password + +
    +
    + ${translate("login.lp4")} + ${translate("login.lp5")} +
    +
    + +
    +

    Qortal ${translate("tabmenu.tm6")} ${translate("login.lp1")}

    +
    +
    +
    +

    ${translate("login.lessthen8")}

    +
    +
    + ${translate("login.lp4")} + ${translate("login.lp5")} +
    +
    + +
    + ${translate("tradepage.tchange46")}
    + ${translate("login.lp9")} + ${translate("login.lp10")} +
    +
    + password + +
    + ${this.autoHelperMessage} +
    +
    +
    +
    + +
    +
    + ` + } - myOpenOrdersTemplate() { - return html` -
    -
    -
    ${translate("info.inf15")}
    -
    -
    ${translate("login.loading")}
    - - { - const dateString = new Date(data.item.timestamp).toLocaleString() - render(html`${dateString}`, root) - }} - > - - { - render(html` ${data.item._tradeState} `, root) - }} - > - - { - const price = this.round(parseFloat(data.item.foreignAmount) / parseFloat(data.item.qortAmount)) - render(html`${price}`, root) - }} - > - - - - - - + async firstUpdated() { + let _this = this + + this.changeTheme() + this.changeLanguage() + + await this.tradeFee() + await this.getNewBlockedTrades() + + this.autoHelperMessage = this.renderAutoHelperPass() + + this.autoSalt = '' + this.autoSalt = Base58.encode(window.parent.reduxStore.getState().app.wallet._addresses[0].keyPair.privateKey) + + this.autoStorageData = '' + this.autoStorageData = window.parent.reduxStore.getState().app.selectedAddress.address + + this.autoLockScreenPass = '' + this.autoLockScreenPass = 'autoLockScreenPass-' + this.autoStorageData + + this.autoLockScreenSet = '' + this.autoLockScreenSet = 'autoLockScreenSet-' + this.autoStorageData + + this.autoLockPass = '' + this.autoLockPass = encryptData(false, this.autoSalt) + + this.autoLockSet = '' + this.autoLockSet = encryptData(false, this.autoSalt) + + if (localStorage.getItem(this.autoLockScreenPass) === null && localStorage.getItem(this.autoLockScreenSet) === null) { + localStorage.setItem(this.autoLockScreenPass, this.autoLockPass) + localStorage.setItem(this.autoLockScreenSet, this.autoLockSet) + this.myAutoLockScreenPass = '' + this.myAutoLockScreenPass = decryptData(localStorage.getItem(this.autoLockScreenPass), this.autoSalt) + this.myAutoLockScreenSet = '' + this.myAutoLockScreenSet = decryptData(localStorage.getItem(this.autoLockScreenSet), this.autoSalt) + } else { + this.myAutoLockScreenPass = '' + this.myAutoLockScreenPass = decryptData(localStorage.getItem(this.autoLockScreenPass), this.autoSalt) + this.myAutoLockScreenSet = '' + this.myAutoLockScreenSet = decryptData(localStorage.getItem(this.autoLockScreenSet), this.autoSalt) + } + + if (this.myAutoLockScreenSet === true) { + this.shadowRoot.getElementById('autoLockScreenActive').open() + } + + await this.updateWalletBalance() + await this.fetchWalletAddress(this.selectedCoin) + + this.blockedTradesList = JSON.parse(localStorage.getItem('failedTrades') || '[]') + this._openOrdersGrid = this.shadowRoot.getElementById('openOrdersGrid') + + this._openOrdersGrid.querySelector('#priceColumn').headerRenderer = function (root) { + const priceString = get("tradepage.tchange9") + root.innerHTML = '' + priceString + ' (' + _this.listedCoins.get(_this.selectedCoin).coinCode + ')' + } + + this._openOrdersGrid.querySelector('#qortAmountColumn').headerRenderer = function (root) { + const amountString = get("tradepage.tchange8") + root.innerHTML = '' + amountString + ' (QORT)' + } + + this._myOrdersGrid = this.shadowRoot.getElementById('myOrdersGrid') + + const getQortBtcPrice = () => { + parentEpml.request("apiCall", { url: `/crosschain/price/BITCOIN?inverse=true` }).then((res) => { + setTimeout(() => { this.qortbtc = (Number(res) / 1e8).toFixed(8) }, 1) + }) + setTimeout(getQortBtcPrice, 300000) + } + + const getQortLtcPrice = () => { + parentEpml.request("apiCall", { url: `/crosschain/price/LITECOIN?inverse=true` }).then((res) => { + setTimeout(() => { this.qortltc = (Number(res) / 1e8).toFixed(8) }, 1) + }) + setTimeout(getQortLtcPrice, 300000) + } + + const getQortDogePrice = () => { + parentEpml.request("apiCall", { url: `/crosschain/price/DOGECOIN?inverse=true` }).then((res) => { + setTimeout(() => { this.qortdoge = (Number(res) / 1e8).toFixed(8) }, 1) + }) + setTimeout(getQortDogePrice, 300000) + } + + const getQortDgbPrice = () => { + parentEpml.request("apiCall", { url: `/crosschain/price/DIGIBYTE?inverse=true` }).then((res) => { + setTimeout(() => { this.qortdgb = (Number(res) / 1e8).toFixed(8) }, 1) + }) + setTimeout(getQortDgbPrice, 300000) + } + + const getQortRvnPrice = () => { + parentEpml.request("apiCall", { url: `/crosschain/price/RAVENCOIN?inverse=true` }).then((res) => { + setTimeout(() => { this.qortrvn = (Number(res) / 1e8).toFixed(8) }, 1) + }) + setTimeout(getQortRvnPrice, 300000) + } + + const getQortArrrPrice = () => { + parentEpml.request("apiCall", { url: `/crosschain/price/PIRATECHAIN?inverse=true` }).then((res) => { + setTimeout(() => { this.qortarrr = (Number(res) / 1e8).toFixed(8) }, 1) + }) + setTimeout(getQortArrrPrice, 300000) + } + + window.addEventListener('storage', () => { + this.blockedTradesList = JSON.parse(localStorage.getItem('failedTrades') || '[]') + this.tradeBotBtcBook = JSON.parse(localStorage.getItem(this.btcWallet) || "[]") + this.tradeBotLtcBook = JSON.parse(localStorage.getItem(this.ltcWallet) || "[]") + this.tradeBotDogeBook = JSON.parse(localStorage.getItem(this.dogeWallet) || "[]") + this.tradeBotDgbBook = JSON.parse(localStorage.getItem(this.dgbWallet) || "[]") + this.tradeBotRvnBook = JSON.parse(localStorage.getItem(this.rvnWallet) || "[]") + this.tradeBotArrrBook = JSON.parse(localStorage.getItem(this.arrrWallet) || "[]") + const checkLanguage = localStorage.getItem('qortalLanguage') + const checkTheme = localStorage.getItem('qortalTheme') + + use(checkLanguage) + + this.theme = (checkTheme === 'dark') ? 'dark' : 'light' + document.querySelector('html').setAttribute('theme', this.theme) + }) + + if (!isElectron()) { + } else { + window.addEventListener('contextmenu', (event) => { + event.preventDefault() + window.parent.electronAPI.showMyMenu() + }) + } + + this.btcWallet = window.parent.reduxStore.getState().app.selectedAddress.btcWallet.address + this.ltcWallet = window.parent.reduxStore.getState().app.selectedAddress.ltcWallet.address + this.dogeWallet = window.parent.reduxStore.getState().app.selectedAddress.dogeWallet.address + this.dgbWallet = window.parent.reduxStore.getState().app.selectedAddress.dgbWallet.address + this.rvnWallet = window.parent.reduxStore.getState().app.selectedAddress.rvnWallet.address + this.arrrWallet = window.parent.reduxStore.getState().app.selectedAddress.arrrWallet.address + + let configLoaded = false + + parentEpml.ready().then(() => { + parentEpml.subscribe('selected_address', async (selectedAddress) => { + this.selectedAddress = {} + selectedAddress = JSON.parse(selectedAddress) + if (!selectedAddress || Object.entries(selectedAddress).length === 0) return + this.selectedAddress = selectedAddress + + this.btcWallet = window.parent.reduxStore.getState().app.selectedAddress.btcWallet.address + this.ltcWwallet = window.parent.reduxStore.getState().app.selectedAddress.ltcWallet.address + this.dogeWallet = window.parent.reduxStore.getState().app.selectedAddress.dogeWallet.address + this.dgbWallet = window.parent.reduxStore.getState().app.selectedAddress.dgbWallet.address + this.rvnWallet = window.parent.reduxStore.getState().app.selectedAddress.rvnWallet.address + this.arrrWallet = window.parent.reduxStore.getState().app.selectedAddress.arrrWallet.address + + this.updateAccountBalance() + }) + + parentEpml.subscribe('config', (c) => { + if (!configLoaded) { + setTimeout(getQortBtcPrice, 1) + setTimeout(getQortLtcPrice, 1) + setTimeout(getQortDogePrice, 1) + setTimeout(getQortDgbPrice, 1) + setTimeout(getQortRvnPrice, 1) + setTimeout(getQortArrrPrice, 1) + configLoaded = true + } + this.config = JSON.parse(c) + }) + + let coinSelectionMenu = this.shadowRoot.getElementById("coinSelectionMenu") + + coinSelectionMenu.addEventListener('change', function () { + _this.setForeignCoin(coinSelectionMenu.value, false) + }) + + _this.setForeignCoin(coinSelectionMenu.value, true) + }) + parentEpml.imReady() + + this.btcTradebook() + this.ltcTradebook() + this.dogeTradebook() + this.dgbTradebook() + this.rvnTradebook() + this.arrrTradebook() + + this.clearConsole() + + setInterval(() => { + this.clearConsole() + }, 60000) + + setInterval(() => { + this.getNewBlockedTrades() + }, 300000) + } + + openTradesTemplate() { + return html` +
    +
    +
    ${this.listedCoins.get(this.selectedCoin).coinCode} ${translate("tradepage.tchange42")}
    +
    +
    +
    + ${translate("login.loading")} +
    + + { + render(html`${this.round(data.item.qortAmount)}`, root) + }} + > + + { + render(html`${this.round(data.item.price)}`, root) + }} + > + + { + render(html`${data.item.foreignAmount}`, root) + }} + > + + { + render(html`${data.item.qortalCreator}`, root) + }} + > + + +
    -
    - ` - } + ` + } - myDoneTradesTemplate() { - return html` -
    -
    -
    ${translate("tradepage.tchange43")} (${this.listedCoins.get(this.selectedCoin).coinCode})
    -
    -
    ${translate("login.loading")}
    - - { - const dateString = new Date(data.item.timestamp).toLocaleString() - render(html`${dateString}`, root) - }} - > - - { - return render(html` ${translate("tradepage.tchange32")} `, root) - }} - > - - { - const price = this.round(parseFloat(data.item.foreignAmount) / parseFloat(data.item.qortAmount)) - render(html`${price}`, root) - }} - > - - - - { + myOpenOrdersTemplate() { + return html` +
    +
    +
    ${translate("info.inf15")}
    +
    +
    +
    + ${translate("login.loading")} +
    + + { + const dateString = new Date(data.item.timestamp).toLocaleString() + render(html`${dateString}`, root) + }} + > + + { + render(html` ${data.item._tradeState} `, root) + }} + > + + { + const price = this.round(parseFloat(data.item.foreignAmount) / parseFloat(data.item.qortAmount)) + render(html`${price}`, root) + }} + > + + + + + + +
    +
    +
    + ` + } + + myDoneTradesTemplate() { + return html` +
    +
    +
    ${translate("tradepage.tchange43")} (${this.listedCoins.get(this.selectedCoin).coinCode})
    +
    +
    +
    + ${translate("login.loading")} +
    + + { + const dateString = new Date(data.item.timestamp).toLocaleString() + render(html`${dateString}`, root) + }} + > + + { + return render(html` ${translate("tradepage.tchange32")} `, root) + }} + > + + { + const price = this.round(parseFloat(data.item.foreignAmount) / parseFloat(data.item.qortAmount)) + render(html`${price}`, root) + }} + > + + + + { + render(html` ${data.item.foreignAmount} `, root) + }} + > + + +
    +
    +
    + ` + } + + myHistoricTradesTemplate() { + return html` +
    +
    +
    ${translate("tradepage.tchange4")}
    +
    + + { + const dateString = new Date(data.item.timestamp).toLocaleString() + render(html`${dateString}`, root) + }} + > + + { + if (data.item.mode === 'SOLD') return render(html` ${translate("tradepage.tchange31")} `, root) + if (data.item.mode === 'BOUGHT') return render(html` ${translate("tradepage.tchange32")} `, root) + return render(html` ${data.item.mode} `, root) + }} + > + + { + const price = this.round(parseFloat(data.item.foreignAmount) / parseFloat(data.item.qortAmount)) + render(html`${price}`, root) + }} + > + + + + { render(html` ${data.item.foreignAmount} `, root) - }} - > - - -
    -
    -
    - ` - } - - myHistoricTradesTemplate() { - return html` -
    -
    -
    ${translate("tradepage.tchange4")}
    -
    - - { - const dateString = new Date(data.item.timestamp).toLocaleString() - render(html`${dateString}`, root) - }} - > - - { - if (data.item.mode === 'SOLD') return render(html` ${translate("tradepage.tchange31")} `, root) - if (data.item.mode === 'BOUGHT') return render(html` ${translate("tradepage.tchange32")} `, root) - return render(html` ${data.item.mode} `, root) - }} - > - - { - const price = this.round(parseFloat(data.item.foreignAmount) / parseFloat(data.item.qortAmount)) - render(html`${price}`, root) - }} - > - - - - { - render(html` ${data.item.foreignAmount} `, root) - }} - > - - -
    -
    -
    - ` - } - - tradeBotBTCTemplate() { - return html` -
    -
    -
    ${translate("info.inf16")} QORT ${translate("info.inf14")} ${this.listedCoins.get(this.selectedCoin).coinCode}
    -
    - - { - render(html`${data.item.botBtcQortAmount}`, root) - }} - > - - { - render(html`${data.item.botBtcPrice}`, root) - }} - > - - { - const totalCoins = this.round(parseFloat(data.item.botBtcQortAmount) * parseFloat(data.item.botBtcPrice)) - const myBotFunds = this.round(parseFloat(this.listedCoins.get(this.selectedCoin).balance)) - if (Number(myBotFunds) > Number(totalCoins)) { - this.autoBuyBotDisable = false - render(html`${totalCoins}`, root) - } else { - this.autoBuyBotDisable = true - render(html`${totalCoins}`, root) - } - }} - > - - { - render(html` this.removeBTCTradebook()}>delete ${translate("nodepage.nchange12")}`, root) - }} - > - - - ${this.isEmptyArray(this.tradeBotBtcBook) ? html` - - ${translate("tradepage.tchange38")} ${translate("tradepage.tchange39")} - - `: ''} -
    - ${this.autoBuyBotDisable ? html` -
    ${this.renderBotWarning()}
    - `: ''} -
    -
    - ` - } - - tradeBotLTCTemplate() { - return html` -
    -
    -
    ${translate("info.inf16")} QORT ${translate("info.inf14")} ${this.listedCoins.get(this.selectedCoin).coinCode}
    -
    - - { - render(html`${data.item.botLtcQortAmount}`, root) - }} - > - - { - render(html`${data.item.botLtcPrice}`, root) - }} - > - - { - const totalCoins = this.round(parseFloat(data.item.botLtcQortAmount) * parseFloat(data.item.botLtcPrice)) - const myBotFunds = this.round(parseFloat(this.listedCoins.get(this.selectedCoin).balance)) - if (Number(myBotFunds) > Number(totalCoins)) { - this.autoBuyBotDisable = false - render(html`${totalCoins}`, root) - } else { - this.autoBuyBotDisable = true - render(html`${totalCoins}`, root) - } - }} - > - - { - render(html` this.removeLTCTradebook()}>delete ${translate("nodepage.nchange12")}`, root) - }} - > - - - ${this.isEmptyArray(this.tradeBotLtcBook) ? html` - - ${translate("tradepage.tchange38")} ${translate("tradepage.tchange39")} - - `: ''} -
    - ${this.autoBuyBotDisable ? html` -
    ${this.renderBotWarning()}
    - `: ''} -
    -
    - ` - } - - tradeBotDOGETemplate() { - return html` -
    -
    -
    ${translate("info.inf16")} QORT ${translate("info.inf14")} ${this.listedCoins.get(this.selectedCoin).coinCode}
    -
    - - { - render(html`${data.item.botDogeQortAmount}`, root) - }} - > - - { - render(html`${data.item.botDogePrice}`, root) - }} - > - - { - const totalCoins = this.round(parseFloat(data.item.botDogeQortAmount) * parseFloat(data.item.botDogePrice)) - const myBotFunds = this.round(parseFloat(this.listedCoins.get(this.selectedCoin).balance)) - if (Number(myBotFunds) > Number(totalCoins)) { - this.autoBuyBotDisable = false - render(html`${totalCoins}`, root) - } else { - this.autoBuyBotDisable = true - render(html`${totalCoins}`, root) - } - }} - > - - { - render(html` this.removeDOGETradebook()}>delete ${translate("nodepage.nchange12")}`, root) - }} - > - - - ${this.isEmptyArray(this.tradeBotDogeBook) ? html` - - ${translate("tradepage.tchange38")} ${translate("tradepage.tchange39")} - - `: ''} -
    - ${this.autoBuyBotDisable ? html` -
    ${this.renderBotWarning()}
    - `: ''} -
    -
    - ` - } - - tradeBotDGBTemplate() { - return html` -
    -
    -
    ${translate("info.inf16")} QORT ${translate("info.inf14")} ${this.listedCoins.get(this.selectedCoin).coinCode}
    -
    - - { - render(html`${data.item.botDgbQortAmount}`, root) - }} - > - - { - render(html`${data.item.botDgbPrice}`, root) - }} - > - - { - const totalCoins = this.round(parseFloat(data.item.botDgbQortAmount) * parseFloat(data.item.botDgbPrice)) - const myBotFunds = this.round(parseFloat(this.listedCoins.get(this.selectedCoin).balance)) - if (Number(myBotFunds) > Number(totalCoins)) { - this.autoBuyBotDisable = false - render(html`${totalCoins}`, root) - } else { - this.autoBuyBotDisable = true - render(html`${totalCoins}`, root) - } - }} - > - - { - render(html` this.removeDGBTradebook()}>delete ${translate("nodepage.nchange12")}`, root) - }} - > - - - ${this.isEmptyArray(this.tradeBotDgbBook) ? html` - - ${translate("tradepage.tchange38")} ${translate("tradepage.tchange39")} - - `: ''} -
    - ${this.autoBuyBotDisable ? html` -
    ${this.renderBotWarning()}
    - `: ''} -
    -
    - ` - } - - tradeBotRVNTemplate() { - return html` -
    -
    -
    ${translate("info.inf16")} QORT ${translate("info.inf14")} ${this.listedCoins.get(this.selectedCoin).coinCode}
    -
    - - { - render(html`${data.item.botRvnQortAmount}`, root) - }} - > - - { - render(html`${data.item.botRvnPrice}`, root) - }} - > - - { - const totalCoins = this.round(parseFloat(data.item.botRvnQortAmount) * parseFloat(data.item.botRvnPrice)) - const myBotFunds = this.round(parseFloat(this.listedCoins.get(this.selectedCoin).balance)) - if (Number(myBotFunds) > Number(totalCoins)) { - this.autoBuyBotDisable = false - render(html`${totalCoins}`, root) - } else { - this.autoBuyBotDisable = true - render(html`${totalCoins}`, root) - } - }} - > - - { - render(html` this.removeRVNTradebook()}>delete ${translate("nodepage.nchange12")}`, root) - }} - > - - - ${this.isEmptyArray(this.tradeBotRvnBook) ? html` - - ${translate("tradepage.tchange38")} ${translate("tradepage.tchange39")} - - `: ''} -
    - ${this.autoBuyBotDisable ? html` -
    ${this.renderBotWarning()}
    - `: ''} -
    -
    - ` - } - - tradeBotARRRTemplate() { - return html` -
    -
    -
    ${translate("info.inf16")} QORT ${translate("info.inf14")} ${this.listedCoins.get(this.selectedCoin).coinCode}
    -
    - - { - render(html`${data.item.botArrrQortAmount}`, root) - }} - > - - { - render(html`${data.item.botArrrPrice}`, root) - }} - > - - { - const totalCoins = this.round(parseFloat(data.item.botArrrQortAmount) * parseFloat(data.item.botArrrPrice)) - const myBotFunds = this.round(parseFloat(this.listedCoins.get(this.selectedCoin).balance)) - if (Number(myBotFunds) > Number(totalCoins)) { - this.autoBuyBotDisable = false - render(html`${totalCoins}`, root) - } else { - this.autoBuyBotDisable = true - render(html`${totalCoins}`, root) - } - }} - > - - { - render(html` this.removeARRRTradebook()}>delete ${translate("nodepage.nchange12")}`, root) - }} - > - - - ${this.isEmptyArray(this.tradeBotArrrBook) ? html` - - ${translate("tradepage.tchange38")} ${translate("tradepage.tchange39")} - - `: ''} -
    - ${this.autoBuyBotDisable ? html` -
    ${this.renderBotWarning()}
    - `: ''} -
    -
    - ` - } - - render() { - return html` -
    -
    -
    -
    -

    ${translate("info.inf13")} QORT ${translate("info.inf14")} ${this.listedCoins.get(this.selectedCoin).coinCode} -  

    - - BTC / QORT - LTC / QORT - DOGE / QORT - DGB / QORT - RVN / QORT - ARRR / QORT - -
    - this.shadowRoot.getElementById('buyInfoDialog').open()}> -
    -
    - ${this.renderAutoLockButton()} -
    -
    -
    -
    -
    -
    -
    - ${this.openTradesTemplate()} -
    -
    -
    -
    - ${this.myDoneTradesTemplate()} -
    -
    -
    -
    - ${this.myOpenOrdersTemplate()} -
    -
    -
    -
    - ${this.showAutoBuyGrid()} -
    -
    -
    -

    ${translate("tradepage.tchange33")} ${this.listedCoins.get(this.selectedCoin).coinCode} ${translate("tradepage.tchange40")}

    -

    1 QORT = ${this.exchangeRateQort()} ${this.listedCoins.get(this.selectedCoin).coinCode}

    -
    -
    -
    - - -
    -

    ${this.renderFetchText()}

    -
    -
    -
    -

    ${this.listedCoins.get(this.selectedCoin).coinCode} ==> QORT

    -
    -
    -
    -
    ${this.renderWarning()}
    - -
    - ${translate("tradepage.tchange8")} (QORT)* -

    - - -

    - ${translate("tradepage.tchange14")} (${this.listedCoins.get(this.selectedCoin).coinCode})* -

    - - -

    - ${translate("tradepage.tchange10")} (${this.listedCoins.get(this.selectedCoin).coinCode})* -

    - - -

    - - ${translate("tradepage.tchange16")}: ${this.listedCoins.get(this.selectedCoin).balance} ${this.listedCoins.get(this.selectedCoin).coinCode} - -
    -
    - - ${translate("tradepage.tchange38")} ${this.listedCoins.get(this.selectedCoin).coinCode} ${translate("tradepage.tchange39")} - + }} + > + +
    - ${translate("general.close")} -
    + ` + } - -
    -

    ${this.renderFetchText()}

    -
    -
    -
    -

    ${this.listedCoins.get(this.selectedCoin).coinCode} ==> QORT

    -
    -
    -
    -
    ${this.renderWarning()}
    - -
    - ${translate("tradepage.tchange8")} (QORT)* -

    - - -

    - ${translate("tradepage.tchange14")} (${this.listedCoins.get(this.selectedCoin).coinCode})* -

    - - -

    - ${translate("tradepage.tchange10")} (${this.listedCoins.get(this.selectedCoin).coinCode})* -

    - - -

    - - ${translate("tradepage.tchange16")}: ${this.listedCoins.get(this.selectedCoin).balance} ${this.listedCoins.get(this.selectedCoin).coinCode} - -
    -
    - - ${translate("tradepage.tchange38")} ${this.listedCoins.get(this.selectedCoin).coinCode} ${translate("tradepage.tchange39")} - + tradeBotBTCTemplate() { + return html` +
    +
    +
    ${translate("info.inf16")} QORT ${translate("info.inf14")} ${this.listedCoins.get(this.selectedCoin).coinCode}
    +
    + + { + render(html`${data.item.botBtcQortAmount}`, root) + }} + > + + { + render(html`${data.item.botBtcPrice}`, root) + }} + > + + { + const totalCoins = this.round(parseFloat(data.item.botBtcQortAmount) * parseFloat(data.item.botBtcPrice)) + const myBotFunds = this.round(parseFloat(this.listedCoins.get(this.selectedCoin).balance)) + if (Number(myBotFunds) > Number(totalCoins)) { + this.autoBuyBotDisable = false + render(html`${totalCoins}`, root) + } else { + this.autoBuyBotDisable = true + render(html`${totalCoins}`, root) + } + }} + > + + { + render(html` + this.removeBTCTradebook()}> + delete ${translate("nodepage.nchange12")} + + `, root) + }} + > + + + ${this.isEmptyArray(this.tradeBotBtcBook) ? html` + + ${translate("tradepage.tchange38")} ${translate("tradepage.tchange39")} + + `: ''}
    + ${this.autoBuyBotDisable ? html` +
    ${this.renderBotWarning()}
    + `: ''}
    - ${translate("general.close")} - + ` + } - -
    -

    ${this.renderFetchText()}

    -
    -
    -
    -

    ${this.listedCoins.get(this.selectedCoin).coinCode} ==> QORT

    -
    -
    -
    -
    ${this.renderWarning()}
    - -
    - ${translate("tradepage.tchange8")} (QORT)* -

    - - -

    - ${translate("tradepage.tchange14")} (${this.listedCoins.get(this.selectedCoin).coinCode})* -

    - - -

    - ${translate("tradepage.tchange10")} (${this.listedCoins.get(this.selectedCoin).coinCode})* -

    - - -

    - - ${translate("tradepage.tchange16")}: ${this.listedCoins.get(this.selectedCoin).balance} ${this.listedCoins.get(this.selectedCoin).coinCode} - -
    -
    - - ${translate("tradepage.tchange38")} ${this.listedCoins.get(this.selectedCoin).coinCode} ${translate("tradepage.tchange39")} - + tradeBotLTCTemplate() { + return html` +
    +
    +
    ${translate("info.inf16")} QORT ${translate("info.inf14")} ${this.listedCoins.get(this.selectedCoin).coinCode}
    +
    + + { + render(html`${data.item.botLtcQortAmount}`, root) + }} + > + + { + render(html`${data.item.botLtcPrice}`, root) + }} + > + + { + const totalCoins = this.round(parseFloat(data.item.botLtcQortAmount) * parseFloat(data.item.botLtcPrice)) + const myBotFunds = this.round(parseFloat(this.listedCoins.get(this.selectedCoin).balance)) + if (Number(myBotFunds) > Number(totalCoins)) { + this.autoBuyBotDisable = false + render(html`${totalCoins}`, root) + } else { + this.autoBuyBotDisable = true + render(html`${totalCoins}`, root) + } + }} + > + + { + render(html` + this.removeLTCTradebook()}> + delete ${translate("nodepage.nchange12")} + + `, root) + }} + > + + + ${this.isEmptyArray(this.tradeBotLtcBook) ? html` + + ${translate("tradepage.tchange38")} ${translate("tradepage.tchange39")} + + `: ''}
    + ${this.autoBuyBotDisable ? html` +
    ${this.renderBotWarning()}
    + `: ''}
    - ${translate("general.close")} - + ` + } - -
    -

    ${this.renderFetchText()}

    -
    -
    -
    -

    ${this.listedCoins.get(this.selectedCoin).coinCode} ==> QORT

    -
    -
    -
    -
    ${this.renderWarning()}
    - -
    - ${translate("tradepage.tchange8")} (QORT)* -

    - - -

    - ${translate("tradepage.tchange14")} (${this.listedCoins.get(this.selectedCoin).coinCode})* -

    - - -

    - ${translate("tradepage.tchange10")} (${this.listedCoins.get(this.selectedCoin).coinCode})* -

    - - -

    - - ${translate("tradepage.tchange16")}: ${this.listedCoins.get(this.selectedCoin).balance} ${this.listedCoins.get(this.selectedCoin).coinCode} - -
    -
    - - ${translate("tradepage.tchange38")} ${this.listedCoins.get(this.selectedCoin).coinCode} ${translate("tradepage.tchange39")} - + tradeBotDOGETemplate() { + return html` +
    +
    +
    ${translate("info.inf16")} QORT ${translate("info.inf14")} ${this.listedCoins.get(this.selectedCoin).coinCode}
    +
    + + { + render(html`${data.item.botDogeQortAmount}`, root) + }} + > + + { + render(html`${data.item.botDogePrice}`, root) + }} + > + + { + const totalCoins = this.round(parseFloat(data.item.botDogeQortAmount) * parseFloat(data.item.botDogePrice)) + const myBotFunds = this.round(parseFloat(this.listedCoins.get(this.selectedCoin).balance)) + if (Number(myBotFunds) > Number(totalCoins)) { + this.autoBuyBotDisable = false + render(html`${totalCoins}`, root) + } else { + this.autoBuyBotDisable = true + render(html`${totalCoins}`, root) + } + }} + > + + { + render(html` + this.removeDOGETradebook()}> + delete ${translate("nodepage.nchange12")} + + `, root) + }} + > + + + ${this.isEmptyArray(this.tradeBotDogeBook) ? html` + + ${translate("tradepage.tchange38")} ${translate("tradepage.tchange39")} + + `: ''}
    + ${this.autoBuyBotDisable ? html` +
    ${this.renderBotWarning()}
    + `: ''}
    - ${translate("general.close")} - + ` + } - -
    -

    ${this.renderFetchText()}

    -
    -
    -
    -

    ${this.listedCoins.get(this.selectedCoin).coinCode} ==> QORT

    -
    -
    -
    -
    ${this.renderWarning()}
    - -
    - ${translate("tradepage.tchange8")} (QORT)* -

    - - -

    - ${translate("tradepage.tchange14")} (${this.listedCoins.get(this.selectedCoin).coinCode})* -

    - - -

    - ${translate("tradepage.tchange10")} (${this.listedCoins.get(this.selectedCoin).coinCode})* -

    - - -

    - - ${translate("tradepage.tchange16")}: ${this.listedCoins.get(this.selectedCoin).balance} ${this.listedCoins.get(this.selectedCoin).coinCode} - -
    -
    - - ${translate("tradepage.tchange38")} ${this.listedCoins.get(this.selectedCoin).coinCode} ${translate("tradepage.tchange39")} - + tradeBotDGBTemplate() { + return html` +
    +
    +
    ${translate("info.inf16")} QORT ${translate("info.inf14")} ${this.listedCoins.get(this.selectedCoin).coinCode}
    +
    + + { + render(html`${data.item.botDgbQortAmount}`, root) + }} + > + + { + render(html`${data.item.botDgbPrice}`, root) + }} + > + + { + const totalCoins = this.round(parseFloat(data.item.botDgbQortAmount) * parseFloat(data.item.botDgbPrice)) + const myBotFunds = this.round(parseFloat(this.listedCoins.get(this.selectedCoin).balance)) + if (Number(myBotFunds) > Number(totalCoins)) { + this.autoBuyBotDisable = false + render(html`${totalCoins}`, root) + } else { + this.autoBuyBotDisable = true + render(html`${totalCoins}`, root) + } + }} + > + + { + render(html` + this.removeDGBTradebook()}> + delete ${translate("nodepage.nchange12")} + + `, root) + }} + > + + + ${this.isEmptyArray(this.tradeBotDgbBook) ? html` + + ${translate("tradepage.tchange38")} ${translate("tradepage.tchange39")} + + `: ''}
    + ${this.autoBuyBotDisable ? html` +
    ${this.renderBotWarning()}
    + `: ''}
    - ${translate("general.close")} - + ` + } - -
    -

    ${this.renderFetchText()}

    -
    -
    -
    -

    ${this.listedCoins.get(this.selectedCoin).coinCode} ==> QORT

    -
    -
    -
    -
    ${this.renderWarning()}
    - -
    - ${translate("tradepage.tchange8")} (QORT)* -

    - - -

    - ${translate("tradepage.tchange14")} (${this.listedCoins.get(this.selectedCoin).coinCode})* -

    - - -

    - ${translate("tradepage.tchange10")} (${this.listedCoins.get(this.selectedCoin).coinCode})* -

    - - -

    - - ${translate("tradepage.tchange16")}: ${this.listedCoins.get(this.selectedCoin).balance} ${this.listedCoins.get(this.selectedCoin).coinCode} - -
    -
    - - ${translate("tradepage.tchange38")} ${this.listedCoins.get(this.selectedCoin).coinCode} ${translate("tradepage.tchange39")} - + tradeBotRVNTemplate() { + return html` +
    +
    +
    ${translate("info.inf16")} QORT ${translate("info.inf14")} ${this.listedCoins.get(this.selectedCoin).coinCode}
    +
    + + { + render(html`${data.item.botRvnQortAmount}`, root) + }} + > + + { + render(html`${data.item.botRvnPrice}`, root) + }} + > + + { + const totalCoins = this.round(parseFloat(data.item.botRvnQortAmount) * parseFloat(data.item.botRvnPrice)) + const myBotFunds = this.round(parseFloat(this.listedCoins.get(this.selectedCoin).balance)) + if (Number(myBotFunds) > Number(totalCoins)) { + this.autoBuyBotDisable = false + render(html`${totalCoins}`, root) + } else { + this.autoBuyBotDisable = true + render(html`${totalCoins}`, root) + } + }} + > + + { + render(html` + this.removeRVNTradebook()}> + delete ${translate("nodepage.nchange12")} + + `, root) + }} + > + + + ${this.isEmptyArray(this.tradeBotRvnBook) ? html` + + ${translate("tradepage.tchange38")} ${translate("tradepage.tchange39")} + + `: ''}
    + ${this.autoBuyBotDisable ? html` +
    ${this.renderBotWarning()}
    + `: ''}
    - ${translate("general.close")} - - - -
    -

    - this.shadowRoot.getElementById('buyInfoDialog').close()} title="${translate("info.inf8")}">highlight_off -
    -
    -

    ${translate("info.inf7")}

    -

    ${translate("info.inf9")}

    -

    ${translate("info.inf10")}

    -

    ${translate("info.inf11")}

    -

    ${translate("info.inf12")}

    -
    -
    - -
    -

    Qortal ${translate("tabmenu.tm6")} ${translate("login.lp1")}

    -
    -
    -
    -

    ${translate("login.lp2")}

    -

    ${translate("login.lp3")}

    -
    -
    - password - -
    -
    - password - -
    -
    - ${translate("login.lp4")} - ${translate("login.lp5")} -
    -
    - -
    -

    Qortal ${translate("tabmenu.tm6")} ${translate("login.lp1")}

    -
    -
    -
    -

    ${translate("login.lessthen8")}

    -
    -
    - ${translate("login.lp4")} - ${translate("login.lp5")} -
    -
    - -
    - ${translate("tradepage.tchange46")}
    - ${translate("login.lp9")} - ${translate("login.lp10")} -
    -
    - password - -
    - ${this.autoHelperMessage} -
    -
    -
    -
    - -
    -
    - ` - } - - async firstUpdated() { - let _this = this - - this.changeTheme() - this.changeLanguage() - await this.tradeFee() - await this.getNewBlockedTrades() - - this.autoHelperMessage = this.renderAutoHelperPass() - - this.autoSalt = '' - this.autoSalt = Base58.encode(window.parent.reduxStore.getState().app.wallet._addresses[0].keyPair.privateKey) - - this.autoStorageData = '' - this.autoStorageData = window.parent.reduxStore.getState().app.selectedAddress.address - - this.autoLockScreenPass = '' - this.autoLockScreenPass = 'autoLockScreenPass-' + this.autoStorageData - - this.autoLockScreenSet = '' - this.autoLockScreenSet = 'autoLockScreenSet-' + this.autoStorageData - - this.autoLockPass = '' - this.autoLockPass = encryptData(false, this.autoSalt) - - this.autoLockSet = '' - this.autoLockSet = encryptData(false, this.autoSalt) - - if (localStorage.getItem(this.autoLockScreenPass) === null && localStorage.getItem(this.autoLockScreenSet) === null) { - localStorage.setItem(this.autoLockScreenPass, this.autoLockPass) - localStorage.setItem(this.autoLockScreenSet, this.autoLockSet) - this.myAutoLockScreenPass = '' - this.myAutoLockScreenPass = decryptData(localStorage.getItem(this.autoLockScreenPass), this.autoSalt) - this.myAutoLockScreenSet = '' - this.myAutoLockScreenSet = decryptData(localStorage.getItem(this.autoLockScreenSet), this.autoSalt) - } else { - this.myAutoLockScreenPass = '' - this.myAutoLockScreenPass = decryptData(localStorage.getItem(this.autoLockScreenPass), this.autoSalt) - this.myAutoLockScreenSet = '' - this.myAutoLockScreenSet = decryptData(localStorage.getItem(this.autoLockScreenSet), this.autoSalt) - } - - if (this.myAutoLockScreenSet === true) { - this.shadowRoot.getElementById('autoLockScreenActive').open() - } - - await this.updateWalletBalance() - await this.fetchWalletAddress(this.selectedCoin) - this.blockedTradesList = JSON.parse(localStorage.getItem('failedTrades') || '[]') - this._openOrdersGrid = this.shadowRoot.getElementById('openOrdersGrid') - - this._openOrdersGrid.querySelector('#priceColumn').headerRenderer = function (root) { - const priceString = get("tradepage.tchange9") - root.innerHTML = '' + priceString + ' (' + _this.listedCoins.get(_this.selectedCoin).coinCode + ')' - } - - this._openOrdersGrid.querySelector('#qortAmountColumn').headerRenderer = function (root) { - const amountString = get("tradepage.tchange8") - root.innerHTML = '' + amountString + ' (QORT)' - } - - this._myOrdersGrid = this.shadowRoot.getElementById('myOrdersGrid') - - const getQortBtcPrice = () => { - parentEpml.request("apiCall", { url: `/crosschain/price/BITCOIN?inverse=true` }).then((res) => { - setTimeout(() => { this.qortbtc = (Number(res) / 1e8).toFixed(8) }, 1) - }) - setTimeout(getQortBtcPrice, 300000) - } - - const getQortLtcPrice = () => { - parentEpml.request("apiCall", { url: `/crosschain/price/LITECOIN?inverse=true` }).then((res) => { - setTimeout(() => { this.qortltc = (Number(res) / 1e8).toFixed(8) }, 1) - }) - setTimeout(getQortLtcPrice, 300000) - } - - const getQortDogePrice = () => { - parentEpml.request("apiCall", { url: `/crosschain/price/DOGECOIN?inverse=true` }).then((res) => { - setTimeout(() => { this.qortdoge = (Number(res) / 1e8).toFixed(8) }, 1) - }) - setTimeout(getQortDogePrice, 300000) - } - - const getQortDgbPrice = () => { - parentEpml.request("apiCall", { url: `/crosschain/price/DIGIBYTE?inverse=true` }).then((res) => { - setTimeout(() => { this.qortdgb = (Number(res) / 1e8).toFixed(8) }, 1) - }) - setTimeout(getQortDgbPrice, 300000) - } - - const getQortRvnPrice = () => { - parentEpml.request("apiCall", { url: `/crosschain/price/RAVENCOIN?inverse=true` }).then((res) => { - setTimeout(() => { this.qortrvn = (Number(res) / 1e8).toFixed(8) }, 1) - }) - setTimeout(getQortRvnPrice, 300000) - } - - const getQortArrrPrice = () => { - parentEpml.request("apiCall", { url: `/crosschain/price/PIRATECHAIN?inverse=true` }).then((res) => { - setTimeout(() => { this.qortarrr = (Number(res) / 1e8).toFixed(8) }, 1) - }) - setTimeout(getQortArrrPrice, 300000) - } - - window.addEventListener('storage', () => { - this.blockedTradesList = JSON.parse(localStorage.getItem('failedTrades') || '[]') - this.tradeBotBtcBook = JSON.parse(localStorage.getItem(this.btcWallet) || "[]") - this.tradeBotLtcBook = JSON.parse(localStorage.getItem(this.ltcWallet) || "[]") - this.tradeBotDogeBook = JSON.parse(localStorage.getItem(this.dogeWallet) || "[]") - this.tradeBotDgbBook = JSON.parse(localStorage.getItem(this.dgbWallet) || "[]") - this.tradeBotRvnBook = JSON.parse(localStorage.getItem(this.rvnWallet) || "[]") - this.tradeBotArrrBook = JSON.parse(localStorage.getItem(this.arrrWallet) || "[]") - const checkLanguage = localStorage.getItem('qortalLanguage') - const checkTheme = localStorage.getItem('qortalTheme') - - use(checkLanguage) - - this.theme = (checkTheme === 'dark') ? 'dark' : 'light' - document.querySelector('html').setAttribute('theme', this.theme) - }) - - if (!isElectron()) { - } else { - window.addEventListener('contextmenu', (event) => { - event.preventDefault() - window.parent.electronAPI.showMyMenu() - }) - } - - this.btcWallet = window.parent.reduxStore.getState().app.selectedAddress.btcWallet.address - this.ltcWallet = window.parent.reduxStore.getState().app.selectedAddress.ltcWallet.address - this.dogeWallet = window.parent.reduxStore.getState().app.selectedAddress.dogeWallet.address - this.dgbWallet = window.parent.reduxStore.getState().app.selectedAddress.dgbWallet.address - this.rvnWallet = window.parent.reduxStore.getState().app.selectedAddress.rvnWallet.address - this.arrrWallet = window.parent.reduxStore.getState().app.selectedAddress.arrrWallet.address - - let configLoaded = false - - parentEpml.ready().then(() => { - parentEpml.subscribe('selected_address', async (selectedAddress) => { - this.selectedAddress = {} - selectedAddress = JSON.parse(selectedAddress) - if (!selectedAddress || Object.entries(selectedAddress).length === 0) return - this.selectedAddress = selectedAddress - - this.btcWallet = window.parent.reduxStore.getState().app.selectedAddress.btcWallet.address - this.ltcWwallet = window.parent.reduxStore.getState().app.selectedAddress.ltcWallet.address - this.dogeWallet = window.parent.reduxStore.getState().app.selectedAddress.dogeWallet.address - this.dgbWallet = window.parent.reduxStore.getState().app.selectedAddress.dgbWallet.address - this.rvnWallet = window.parent.reduxStore.getState().app.selectedAddress.rvnWallet.address - this.arrrWallet = window.parent.reduxStore.getState().app.selectedAddress.arrrWallet.address - - this.updateAccountBalance() - }) - - parentEpml.subscribe('config', (c) => { - if (!configLoaded) { - setTimeout(getQortBtcPrice, 1) - setTimeout(getQortLtcPrice, 1) - setTimeout(getQortDogePrice, 1) - setTimeout(getQortDgbPrice, 1) - setTimeout(getQortRvnPrice, 1) - setTimeout(getQortArrrPrice, 1) - configLoaded = true - } - this.config = JSON.parse(c) - }) - - let coinSelectionMenu = this.shadowRoot.getElementById("coinSelectionMenu") - - coinSelectionMenu.addEventListener('change', function () { - _this.setForeignCoin(coinSelectionMenu.value,false) - }) - - _this.setForeignCoin(coinSelectionMenu.value,true) - }) - parentEpml.imReady() - this.btcTradebook() - this.ltcTradebook() - this.dogeTradebook() - this.dgbTradebook() - this.rvnTradebook() - this.arrrTradebook() - this.clearConsole() - setInterval(() => { - this.clearConsole() - }, 60000) - setInterval(() => { - this.getNewBlockedTrades() - }, 300000) - } - - clearConsole() { - if (!isElectron()) { - } else { - console.clear() - window.parent.electronAPI.clearCache() - } - } - - renderAutoLockButton() { - if (this.myAutoLockScreenPass === false && this.myAutoLockScreenSet === false) { - return html` -
    - this.openAutoSetScreenLockPass()} title="${translate("login.lp11")}"> -
    - ` - } else if (this.myAutoLockScreenSet === false) { - return html` -
    - this.setAutoLockQortal()} title="${translate("login.lp11")}"> -
    - ` - } else if (this.myAutoLockScreenSet === true) { - return html` -
    - -
    - ` - } - } - - openAutoSetScreenLockPass() { - this.shadowRoot.getElementById('autoLockPassword').value = '' - this.shadowRoot.getElementById('autoLockPasswordConfirm').value = '' - this.shadowRoot.getElementById('setAutoLockScreenPass').open() - } - - closewAutoSetScreenLockPass() { - this.shadowRoot.getElementById('setAutoLockScreenPass').close() - } - - autoCheckPass() { - const autoPassword = this.shadowRoot.getElementById('autoLockPassword').value - const autoRePassword = this.shadowRoot.getElementById('autoLockPasswordConfirm').value - - if (autoPassword === '') { - let snackbar1string = get("login.pleaseenter") - parentEpml.request('showSnackBar', `${snackbar1string}`) - return - } - - if (autoPassword != autoRePassword) { - let snackbar2string = get("login.notmatch") - parentEpml.request('showSnackBar', `${snackbar2string}`) - return - } - - if (autoPassword.length < 8) { - let snackbar3string = get("login.lessthen8") - parentEpml.request('showSnackBar', `${snackbar3string}`) - this.autoExtraConfirm() - } - - if (autoPassword.length >= 8) { - this.setAutoNewScreenPass() - let snackbar4string = get("login.lp6") - parentEpml.request('showSnackBar', `${snackbar4string}`) - } - } - - autoExtraConfirm() { - this.shadowRoot.getElementById('setAutoLockScreenPass').close() - this.shadowRoot.getElementById('autoExtraConfirmPass').open() - } - - closAutoExtraConfirmPass() { - this.shadowRoot.getElementById('autoExtraConfirmPass').close() - this.shadowRoot.getElementById('autoLockPassword').value = '' - this.shadowRoot.getElementById('autoLockPasswordConfirm').value = '' - } - - setAutoNewScreenPass() { - const autoRawPassword = this.shadowRoot.getElementById('autoLockPassword').value - const autoCryptPassword = encryptData(autoRawPassword, this.autoSalt) - localStorage.setItem(this.autoLockScreenPass, autoCryptPassword) - this.myAutoLockScreenPass = '' - this.myAutoLockScreenPass = decryptData(localStorage.getItem(this.autoLockScreenPass), this.autoSalt) - this.shadowRoot.getElementById('setAutoLockScreenPass').close() - this.shadowRoot.getElementById('autoExtraConfirmPass').close() - this.shadowRoot.getElementById('autoLockPassword').value = '' - this.shadowRoot.getElementById('autoLockPasswordConfirm').value = '' - } - - setAutoLockQortal() { - this.autoHelperMessage = this.renderAutoHelperPass() - this.autoLockSet = '' - this.autoLockSet = encryptData(true, this.autoSalt) - localStorage.setItem(this.autoLockScreenSet, this.autoLockSet) - this.myAutoLockScreenSet = '' - this.myAutoLockScreenSet = decryptData(localStorage.getItem(this.autoLockScreenSet), this.autoSalt) - this.shadowRoot.getElementById('autoLockScreenActive').open() - } - - autoPassKeyListener(e) { - if (e.key === 'Enter') { - this.closeAutoLockScreenActive() - } - } - - async closeAutoLockScreenActive() { - const myAutoPass = decryptData(localStorage.getItem(this.autoLockScreenPass), this.autoSalt) - const autoCheckPass = this.shadowRoot.getElementById('autoUnlockPassword').value - const errDelay = ms => new Promise(res => setTimeout(res, ms)) - - if (autoCheckPass === myAutoPass) { - this.autoLockSet = '' - this.autoLockSet = encryptData(false, this.autoSalt) - localStorage.setItem(this.autoLockScreenSet, this.autoLockSet) - this.myAutoLockScreenSet = '' - this.myAutoLockScreenSet = decryptData(localStorage.getItem(this.autoLockScreenSet), this.autoSalt) - this.shadowRoot.getElementById('autoLockScreenActive').close() - this.shadowRoot.getElementById('autoUnlockPassword').value = '' - this.autoHelperMessage = this.renderAutoHelperPass() - } else { - this.shadowRoot.getElementById('autoUnlockPassword').value = '' - this.autoHelperMessage = this.renderAutoHelperErr() - await errDelay(3000) - this.autoHelperMessage = this.renderAutoHelperPass() - - } - } - - renderAutoHelperPass() { - return html`${translate("login.pleaseenter")}` - } - - renderAutoHelperErr() { - return html`${translate("login.lp8")}` - } - - changeTheme() { - const checkTheme = localStorage.getItem('qortalTheme') - this.theme = (checkTheme === 'dark') ? 'dark' : 'light' - document.querySelector('html').setAttribute('theme', this.theme); - } - - changeLanguage() { - const checkLanguage = localStorage.getItem('qortalLanguage') - - if (checkLanguage === null || checkLanguage.length === 0) { - localStorage.setItem('qortalLanguage', 'us') - use('us') - } else { - use(checkLanguage) - } - } - - renderFetchText() { - return html`${translate("walletpage.wchange1")}` - } - - renderWarning() { - return html`${translate("tradepage.tchange48")} ${this.listedCoins.get(this.selectedCoin).coinCode}` - } - - renderBotWarning() { - return html`${translate("walletpage.wchange1")}` - } - - showAutoBuyGrid() { - switch(this.listedCoins.get(this.selectedCoin).coinCode) { - case "BTC": - return html`${this.tradeBotBTCTemplate()}` - break - case "LTC": - return html`${this.tradeBotLTCTemplate()}` - break - case "DOGE": - return html`${this.tradeBotDOGETemplate()}` - break - case "DGB": - return html`${this.tradeBotDGBTemplate()}` - break - case "RVN": - return html`${this.tradeBotRVNTemplate()}` - break - case "ARRR": - return html`${this.tradeBotARRRTemplate()}` - break - default: - break - } - } - - exchangeRateQort() { - switch(this.listedCoins.get(this.selectedCoin).coinCode) { - case "BTC": - this.qortRatio = this.qortbtc - break - case "LTC": - this.qortRatio = this.qortltc - break - case "DOGE": - this.qortRatio = this.qortdoge - break - case "DGB": - this.qortRatio = this.qortdgb - break - case "RVN": - this.qortRatio = this.qortrvn - break - case "ARRR": - this.qortRatio = this.qortarrr - break - default: - break - } - return html`${this.qortRatio}` - } - - exchangeRateForeign() { - if (this.listedCoins.get(this.selectedCoin).coinCode === "BTC") { - parentEpml.request('apiCall', { - url: `/crosschain/price/BITCOIN?inverse=false` - }).then((res) => { - this.btcqort = (Number(res) / 1e8).toFixed(8) - }) - return html`${this.btcqort}` - } else if (this.listedCoins.get(this.selectedCoin).coinCode === "LTC") { - parentEpml.request('apiCall', { - url: `/crosschain/price/LITECOIN?inverse=false` - }).then((res) => { - this.ltcqort = (Number(res) / 1e8).toFixed(8) - }) - return html`${this.ltcqort}` - } else if (this.listedCoins.get(this.selectedCoin).coinCode === "DOGE") { - parentEpml.request('apiCall', { - url: `/crosschain/price/DOGECOIN?inverse=false` - }).then((res) => { - this.dogeqort = (Number(res) / 1e8).toFixed(8) - }) - return html`${this.dogeqort}` - } else if (this.listedCoins.get(this.selectedCoin).coinCode === "DGB") { - parentEpml.request('apiCall', { - url: `/crosschain/price/DIGIBYTE?inverse=false` - }).then((res) => { - this.dgbqort = (Number(res) / 1e8).toFixed(8) - }) - return html`${this.dgbqort}` - } else if (this.listedCoins.get(this.selectedCoin).coinCode === "RVN") { - parentEpml.request('apiCall', { - url: `/crosschain/price/RAVENCOIN?inverse=false` - }).then((res) => { - this.rvnqort = (Number(res) / 1e8).toFixed(8) - }) - return html`${this.rvnqort}` - } else if (this.listedCoins.get(this.selectedCoin).coinCode === "ARRR") { - parentEpml.request('apiCall', { - url: `/crosschain/price/PIRATECHAIN?inverse=false` - }).then((res) => { - this.arrrqort = (Number(res) / 1e8).toFixed(8) - }) - return html`${this.arrrqort}` - } - } - - async updateWalletBalance() { - let _url = `` - let _body = null - - switch (this.selectedCoin) { - case 'BITCOIN': - _url = `/crosschain/btc/walletbalance?apiKey=${this.getApiKey()}` - _body = window.parent.reduxStore.getState().app.selectedAddress.btcWallet.derivedMasterPublicKey - break - case 'LITECOIN': - _url = `/crosschain/ltc/walletbalance?apiKey=${this.getApiKey()}` - _body = window.parent.reduxStore.getState().app.selectedAddress.ltcWallet.derivedMasterPublicKey - break - case 'DOGECOIN': - _url = `/crosschain/doge/walletbalance?apiKey=${this.getApiKey()}` - _body = window.parent.reduxStore.getState().app.selectedAddress.dogeWallet.derivedMasterPublicKey - break - case 'DIGIBYTE': - _url = `/crosschain/dgb/walletbalance?apiKey=${this.getApiKey()}` - _body = window.parent.reduxStore.getState().app.selectedAddress.dgbWallet.derivedMasterPublicKey - break - case 'RAVENCOIN': - _url = `/crosschain/rvn/walletbalance?apiKey=${this.getApiKey()}` - _body = window.parent.reduxStore.getState().app.selectedAddress.rvnWallet.derivedMasterPublicKey - break - case 'PIRATECHAIN': - _url = `/crosschain/arrr/walletbalance?apiKey=${this.getApiKey()}` - _body = window.parent.reduxStore.getState().app.selectedAddress.arrrWallet.seed58 - break - default: - break - } - - this.showGetWalletBance = true - this.showAddAutoBuy = false - - await parentEpml.request('apiCall', { - url: _url, - method: 'POST', - body: _body, - }).then((res) => { - if (isNaN(Number(res))) { - //... - } else { - this.listedCoins.get(this.selectedCoin).balance = (Number(res) / 1e8).toFixed(8) - } - }) - - this.showGetWalletBance = false - this.showAddAutoBuy = true - } - - async fetchWalletAddress(coin) { - switch (coin) { - case 'PIRATECHAIN': - let res = await parentEpml.request('apiCall', { - url: `/crosschain/arrr/walletaddress?apiKey=${this.getApiKey()}`, - method: 'POST', - body: `${window.parent.reduxStore.getState().app.selectedAddress.arrrWallet.seed58}`, - }) - if (res != null && res.error != 1201) { - this.arrrWalletAddress = res - } - break - - default: - // Not used for other coins yet - break - } - } - - async getDoneTrades() { - let tradesUrl = `` - clearTimeout(this.updateDoneTradesTimeout) - const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] - const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port - const myAddress = window.parent.reduxStore.getState().app.selectedAddress.address - - switch (this.selectedCoin) { - case 'BITCOIN': - tradesUrl = `${nodeUrl}/crosschain/trades?foreignBlockchain=BITCOIN&minimumTimestamp=1597310000000&limit=0&reverse=true` - break - case 'LITECOIN': - tradesUrl = `${nodeUrl}/crosschain/trades?foreignBlockchain=LITECOIN&minimumTimestamp=1597310000000&limit=0&reverse=true` - break - case 'DOGECOIN': - tradesUrl = `${nodeUrl}/crosschain/trades?foreignBlockchain=DOGECOIN&minimumTimestamp=1597310000000&limit=0&reverse=true` - break - case 'DIGIBYTE': - tradesUrl = `${nodeUrl}/crosschain/trades?foreignBlockchain=DIGIBYTE&minimumTimestamp=1597310000000&limit=0&reverse=true` - break - case 'RAVENCOIN': - tradesUrl = `${nodeUrl}/crosschain/trades?foreignBlockchain=RAVENCOIN&minimumTimestamp=1597310000000&limit=0&reverse=true` - break - case 'PIRATECHAIN': - tradesUrl = `${nodeUrl}/crosschain/trades?foreignBlockchain=PIRATECHAIN&minimumTimestamp=1597310000000&limit=0&reverse=true` - break - default: - break - } - - this.isLoadingDoneTrades = true - - const doneTradesAll = await fetch(tradesUrl).then(response => { - return response.json() - }) - - this.listedCoins.get(this.selectedCoin).myGridBoughtItems = doneTradesAll.map(item => { - const searchAddress = item.buyerReceivingAddress - if (searchAddress == myAddress) { - return { - timestamp: item.tradeTimestamp, - foreignAmount: item.foreignAmount, - qortAmount: item.qortAmount - } - } - }).filter(item => !!item) - - this.isLoadingDoneTrades = false - this.updateDoneTradesTimeout = setTimeout(() => this.getDoneTrades(), 300000) - } - - btcTradebook() { - if (localStorage.getItem(this.btcWallet) === null) { - localStorage.setItem(this.btcWallet, "") - } else { - this.tradeBotBtcBook = JSON.parse(localStorage.getItem(this.btcWallet) || "[]") - } - } - - addToBTCTradebook() { - const addBotBtcQortAmount = this.shadowRoot.getElementById('autoBuyBTCQortAmountInput').value - const addBotBtcPrice = this.shadowRoot.getElementById('autoBuyBTCPriceInput').value - const addBtcQortAmount = this.round(parseFloat(addBotBtcQortAmount)) - const addBtcPrice = this.round(parseFloat(addBotBtcPrice)) - - var oldBtcTradebook = JSON.parse(localStorage.getItem(this.btcWallet) || "[]") - - const newBtcTradebookItem = { - botBtcQortAmount: addBtcQortAmount, - botBtcPrice: addBtcPrice - } - - oldBtcTradebook.push(newBtcTradebookItem) - - localStorage.setItem(this.btcWallet, JSON.stringify(oldBtcTradebook)) - - let btctradebookstring = get("tradepage.tchange44") - parentEpml.request('showSnackBar', `${btctradebookstring}`) - - this.closeBTCTradebookDialog() - this.tradeBotBtcBook = JSON.parse(localStorage.getItem(this.btcWallet) || "[]") - } - - closeBTCTradebookDialog() { - this.shadowRoot.querySelector('#tradeBotBTCAddDialog').close() - this.clearTradeBotForm() - } - - removeBTCTradebook() { - localStorage.removeItem(this.btcWallet) - localStorage.setItem(this.btcWallet, "") - this.tradeBotBtcBook = JSON.parse(localStorage.getItem(this.btcWallet) || "[]") - - this.autoBuyBotDisable = false - - let btcstring = get("tradepage.tchange41") - parentEpml.request('showSnackBar', `${btcstring}`) - } - - ltcTradebook() { - if (localStorage.getItem(this.ltcWallet) === null) { - localStorage.setItem(this.ltcWallet, "") - } else { - this.tradeBotLtcBook = JSON.parse(localStorage.getItem(this.ltcWallet) || "[]") - } - } - - addToLTCTradebook() { - const addBotLtcQortAmount = this.shadowRoot.getElementById('autoBuyLTCQortAmountInput').value - const addBotLtcPrice = this.shadowRoot.getElementById('autoBuyLTCPriceInput').value - const addLtcQortAmount = this.round(parseFloat(addBotLtcQortAmount)) - const addLtcPrice = this.round(parseFloat(addBotLtcPrice)) - - var oldLtcTradebook = JSON.parse(localStorage.getItem(this.ltcWallet) || "[]") - - const newLtcTradebookItem = { - botLtcQortAmount: addLtcQortAmount, - botLtcPrice: addLtcPrice - } - - oldLtcTradebook.push(newLtcTradebookItem) - - localStorage.setItem(this.ltcWallet, JSON.stringify(oldLtcTradebook)) - - let ltctradebookstring = get("tradepage.tchange44") - parentEpml.request('showSnackBar', `${ltctradebookstring}`) - - this.closeLTCTradebookDialog() - this.tradeBotLtcBook = JSON.parse(localStorage.getItem(this.ltcWallet) || "[]") - } - - closeLTCTradebookDialog() { - this.shadowRoot.querySelector('#tradeBotLTCAddDialog').close() - this.clearTradeBotForm() - } - - removeLTCTradebook() { - localStorage.removeItem(this.ltcWallet) - localStorage.setItem(this.ltcWallet, "") - this.tradeBotLtcBook = JSON.parse(localStorage.getItem(this.ltcWallet) || "[]") - - this.autoBuyBotDisable = false + ` + } + + tradeBotARRRTemplate() { + return html` +
    +
    +
    ${translate("info.inf16")} QORT ${translate("info.inf14")} ${this.listedCoins.get(this.selectedCoin).coinCode}
    +
    + + { + render(html`${data.item.botArrrQortAmount}`, root) + }} + > + + { + render(html`${data.item.botArrrPrice}`, root) + }} + > + + { + const totalCoins = this.round(parseFloat(data.item.botArrrQortAmount) * parseFloat(data.item.botArrrPrice)) + const myBotFunds = this.round(parseFloat(this.listedCoins.get(this.selectedCoin).balance)) + if (Number(myBotFunds) > Number(totalCoins)) { + this.autoBuyBotDisable = false + render(html`${totalCoins}`, root) + } else { + this.autoBuyBotDisable = true + render(html`${totalCoins}`, root) + } + }} + > + + { + render(html` + this.removeARRRTradebook()}> + delete  ${translate("nodepage.nchange12")} + + `, root) + }} + > + + + ${this.isEmptyArray(this.tradeBotArrrBook) ? html` + + ${translate("tradepage.tchange38")} ${translate("tradepage.tchange39")} + + `: ''} +
    + ${this.autoBuyBotDisable ? html` +
    ${this.renderBotWarning()}
    + `: ''} +
    +
    + ` + } + + clearConsole() { + if (!isElectron()) { + } else { + console.clear() + window.parent.electronAPI.clearCache() + } + } + + renderAutoLockButton() { + if (this.myAutoLockScreenPass === false && this.myAutoLockScreenSet === false) { + return html` +
    + this.openAutoSetScreenLockPass()} title="${translate("login.lp11")}"> +
    + ` + } else if (this.myAutoLockScreenSet === false) { + return html` +
    + this.setAutoLockQortal()} title="${translate("login.lp11")}"> +
    + ` + } else if (this.myAutoLockScreenSet === true) { + return html` +
    + +
    + ` + } + } + + openAutoSetScreenLockPass() { + this.shadowRoot.getElementById('autoLockPassword').value = '' + this.shadowRoot.getElementById('autoLockPasswordConfirm').value = '' + this.shadowRoot.getElementById('setAutoLockScreenPass').open() + } + + closewAutoSetScreenLockPass() { + this.shadowRoot.getElementById('setAutoLockScreenPass').close() + } + + autoCheckPass() { + const autoPassword = this.shadowRoot.getElementById('autoLockPassword').value + const autoRePassword = this.shadowRoot.getElementById('autoLockPasswordConfirm').value + + if (autoPassword === '') { + let snackbar1string = get("login.pleaseenter") + parentEpml.request('showSnackBar', `${snackbar1string}`) + return + } + + if (autoPassword != autoRePassword) { + let snackbar2string = get("login.notmatch") + parentEpml.request('showSnackBar', `${snackbar2string}`) + return + } + + if (autoPassword.length < 8) { + let snackbar3string = get("login.lessthen8") + parentEpml.request('showSnackBar', `${snackbar3string}`) + this.autoExtraConfirm() + } + + if (autoPassword.length >= 8) { + this.setAutoNewScreenPass() + let snackbar4string = get("login.lp6") + parentEpml.request('showSnackBar', `${snackbar4string}`) + } + } + + autoExtraConfirm() { + this.shadowRoot.getElementById('setAutoLockScreenPass').close() + this.shadowRoot.getElementById('autoExtraConfirmPass').open() + } + + closAutoExtraConfirmPass() { + this.shadowRoot.getElementById('autoExtraConfirmPass').close() + this.shadowRoot.getElementById('autoLockPassword').value = '' + this.shadowRoot.getElementById('autoLockPasswordConfirm').value = '' + } + + setAutoNewScreenPass() { + const autoRawPassword = this.shadowRoot.getElementById('autoLockPassword').value + const autoCryptPassword = encryptData(autoRawPassword, this.autoSalt) + localStorage.setItem(this.autoLockScreenPass, autoCryptPassword) + this.myAutoLockScreenPass = '' + this.myAutoLockScreenPass = decryptData(localStorage.getItem(this.autoLockScreenPass), this.autoSalt) + this.shadowRoot.getElementById('setAutoLockScreenPass').close() + this.shadowRoot.getElementById('autoExtraConfirmPass').close() + this.shadowRoot.getElementById('autoLockPassword').value = '' + this.shadowRoot.getElementById('autoLockPasswordConfirm').value = '' + } + + setAutoLockQortal() { + this.autoHelperMessage = this.renderAutoHelperPass() + this.autoLockSet = '' + this.autoLockSet = encryptData(true, this.autoSalt) + localStorage.setItem(this.autoLockScreenSet, this.autoLockSet) + this.myAutoLockScreenSet = '' + this.myAutoLockScreenSet = decryptData(localStorage.getItem(this.autoLockScreenSet), this.autoSalt) + this.shadowRoot.getElementById('autoLockScreenActive').open() + } + + autoPassKeyListener(e) { + if (e.key === 'Enter') { + this.closeAutoLockScreenActive() + } + } + + async closeAutoLockScreenActive() { + const myAutoPass = decryptData(localStorage.getItem(this.autoLockScreenPass), this.autoSalt) + const autoCheckPass = this.shadowRoot.getElementById('autoUnlockPassword').value + const errDelay = ms => new Promise(res => setTimeout(res, ms)) + + if (autoCheckPass === myAutoPass) { + this.autoLockSet = '' + this.autoLockSet = encryptData(false, this.autoSalt) + localStorage.setItem(this.autoLockScreenSet, this.autoLockSet) + this.myAutoLockScreenSet = '' + this.myAutoLockScreenSet = decryptData(localStorage.getItem(this.autoLockScreenSet), this.autoSalt) + this.shadowRoot.getElementById('autoLockScreenActive').close() + this.shadowRoot.getElementById('autoUnlockPassword').value = '' + this.autoHelperMessage = this.renderAutoHelperPass() + } else { + this.shadowRoot.getElementById('autoUnlockPassword').value = '' + this.autoHelperMessage = this.renderAutoHelperErr() + await errDelay(3000) + this.autoHelperMessage = this.renderAutoHelperPass() + + } + } + + renderAutoHelperPass() { + return html`${translate("login.pleaseenter")}` + } + + renderAutoHelperErr() { + return html`${translate("login.lp8")}` + } + + changeTheme() { + const checkTheme = localStorage.getItem('qortalTheme') + this.theme = (checkTheme === 'dark') ? 'dark' : 'light' + document.querySelector('html').setAttribute('theme', this.theme); + } + + changeLanguage() { + const checkLanguage = localStorage.getItem('qortalLanguage') + if (checkLanguage === null || checkLanguage.length === 0) { + localStorage.setItem('qortalLanguage', 'us') + use('us') + } else { + use(checkLanguage) + } + } + + renderFetchText() { + return html`${translate("walletpage.wchange1")}` + } + + renderWarning() { + return html`${translate("tradepage.tchange48")} ${this.listedCoins.get(this.selectedCoin).coinCode}` + } + + renderBotWarning() { + return html`${translate("walletpage.wchange1")}` + } + + showAutoBuyGrid() { + switch (this.listedCoins.get(this.selectedCoin).coinCode) { + case "BTC": + return html`${this.tradeBotBTCTemplate()}` + break + case "LTC": + return html`${this.tradeBotLTCTemplate()}` + break + case "DOGE": + return html`${this.tradeBotDOGETemplate()}` + break + case "DGB": + return html`${this.tradeBotDGBTemplate()}` + break + case "RVN": + return html`${this.tradeBotRVNTemplate()}` + break + case "ARRR": + return html`${this.tradeBotARRRTemplate()}` + break + default: + break + } + } + + exchangeRateQort() { + switch (this.listedCoins.get(this.selectedCoin).coinCode) { + case "BTC": + this.qortRatio = this.qortbtc + break + case "LTC": + this.qortRatio = this.qortltc + break + case "DOGE": + this.qortRatio = this.qortdoge + break + case "DGB": + this.qortRatio = this.qortdgb + break + case "RVN": + this.qortRatio = this.qortrvn + break + case "ARRR": + this.qortRatio = this.qortarrr + break + default: + break + } + return html`${this.qortRatio}` + } + + exchangeRateForeign() { + if (this.listedCoins.get(this.selectedCoin).coinCode === "BTC") { + parentEpml.request('apiCall', { + url: `/crosschain/price/BITCOIN?inverse=false` + }).then((res) => { + this.btcqort = (Number(res) / 1e8).toFixed(8) + }) + return html`${this.btcqort}` + } else if (this.listedCoins.get(this.selectedCoin).coinCode === "LTC") { + parentEpml.request('apiCall', { + url: `/crosschain/price/LITECOIN?inverse=false` + }).then((res) => { + this.ltcqort = (Number(res) / 1e8).toFixed(8) + }) + return html`${this.ltcqort}` + } else if (this.listedCoins.get(this.selectedCoin).coinCode === "DOGE") { + parentEpml.request('apiCall', { + url: `/crosschain/price/DOGECOIN?inverse=false` + }).then((res) => { + this.dogeqort = (Number(res) / 1e8).toFixed(8) + }) + return html`${this.dogeqort}` + } else if (this.listedCoins.get(this.selectedCoin).coinCode === "DGB") { + parentEpml.request('apiCall', { + url: `/crosschain/price/DIGIBYTE?inverse=false` + }).then((res) => { + this.dgbqort = (Number(res) / 1e8).toFixed(8) + }) + return html`${this.dgbqort}` + } else if (this.listedCoins.get(this.selectedCoin).coinCode === "RVN") { + parentEpml.request('apiCall', { + url: `/crosschain/price/RAVENCOIN?inverse=false` + }).then((res) => { + this.rvnqort = (Number(res) / 1e8).toFixed(8) + }) + return html`${this.rvnqort}` + } else if (this.listedCoins.get(this.selectedCoin).coinCode === "ARRR") { + parentEpml.request('apiCall', { + url: `/crosschain/price/PIRATECHAIN?inverse=false` + }).then((res) => { + this.arrrqort = (Number(res) / 1e8).toFixed(8) + }) + return html`${this.arrrqort}` + } + } + + async updateWalletBalance() { + let _url = `` + let _body = null + + switch (this.selectedCoin) { + case 'BITCOIN': + _url = `/crosschain/btc/walletbalance?apiKey=${this.getApiKey()}` + _body = window.parent.reduxStore.getState().app.selectedAddress.btcWallet.derivedMasterPublicKey + break + case 'LITECOIN': + _url = `/crosschain/ltc/walletbalance?apiKey=${this.getApiKey()}` + _body = window.parent.reduxStore.getState().app.selectedAddress.ltcWallet.derivedMasterPublicKey + break + case 'DOGECOIN': + _url = `/crosschain/doge/walletbalance?apiKey=${this.getApiKey()}` + _body = window.parent.reduxStore.getState().app.selectedAddress.dogeWallet.derivedMasterPublicKey + break + case 'DIGIBYTE': + _url = `/crosschain/dgb/walletbalance?apiKey=${this.getApiKey()}` + _body = window.parent.reduxStore.getState().app.selectedAddress.dgbWallet.derivedMasterPublicKey + break + case 'RAVENCOIN': + _url = `/crosschain/rvn/walletbalance?apiKey=${this.getApiKey()}` + _body = window.parent.reduxStore.getState().app.selectedAddress.rvnWallet.derivedMasterPublicKey + break + case 'PIRATECHAIN': + _url = `/crosschain/arrr/walletbalance?apiKey=${this.getApiKey()}` + _body = window.parent.reduxStore.getState().app.selectedAddress.arrrWallet.seed58 + break + default: + break + } + + this.showGetWalletBance = true + this.showAddAutoBuy = false + + await parentEpml.request('apiCall', { + url: _url, + method: 'POST', + body: _body + }).then((res) => { + if (isNaN(Number(res))) { + //... + } else { + this.listedCoins.get(this.selectedCoin).balance = (Number(res) / 1e8).toFixed(8) + } + }) + + this.showGetWalletBance = false + this.showAddAutoBuy = true + } + + async fetchWalletAddress(coin) { + switch (coin) { + case 'PIRATECHAIN': + let res = await parentEpml.request('apiCall', { + url: `/crosschain/arrr/walletaddress?apiKey=${this.getApiKey()}`, + method: 'POST', + body: `${window.parent.reduxStore.getState().app.selectedAddress.arrrWallet.seed58}` + }) + if (res != null && res.error != 1201) { + this.arrrWalletAddress = res + } + break + + default: + // Not used for other coins yet + break + } + } + + async getDoneTrades() { + let tradesUrl = `` + clearTimeout(this.updateDoneTradesTimeout) + const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] + const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port + const myAddress = window.parent.reduxStore.getState().app.selectedAddress.address + + switch (this.selectedCoin) { + case 'BITCOIN': + tradesUrl = `${nodeUrl}/crosschain/trades?foreignBlockchain=BITCOIN&minimumTimestamp=1597310000000&limit=0&reverse=true` + break + case 'LITECOIN': + tradesUrl = `${nodeUrl}/crosschain/trades?foreignBlockchain=LITECOIN&minimumTimestamp=1597310000000&limit=0&reverse=true` + break + case 'DOGECOIN': + tradesUrl = `${nodeUrl}/crosschain/trades?foreignBlockchain=DOGECOIN&minimumTimestamp=1597310000000&limit=0&reverse=true` + break + case 'DIGIBYTE': + tradesUrl = `${nodeUrl}/crosschain/trades?foreignBlockchain=DIGIBYTE&minimumTimestamp=1597310000000&limit=0&reverse=true` + break + case 'RAVENCOIN': + tradesUrl = `${nodeUrl}/crosschain/trades?foreignBlockchain=RAVENCOIN&minimumTimestamp=1597310000000&limit=0&reverse=true` + break + case 'PIRATECHAIN': + tradesUrl = `${nodeUrl}/crosschain/trades?foreignBlockchain=PIRATECHAIN&minimumTimestamp=1597310000000&limit=0&reverse=true` + break + default: + break + } + + this.isLoadingDoneTrades = true + + const doneTradesAll = await fetch(tradesUrl).then(response => { + return response.json() + }) + + this.listedCoins.get(this.selectedCoin).myGridBoughtItems = doneTradesAll.map(item => { + const searchAddress = item.buyerReceivingAddress + if (searchAddress == myAddress) { + return { + timestamp: item.tradeTimestamp, + foreignAmount: item.foreignAmount, + qortAmount: item.qortAmount + } + } + }).filter(item => !!item) + + this.isLoadingDoneTrades = false + this.updateDoneTradesTimeout = setTimeout(() => this.getDoneTrades(), 300000) + } + + btcTradebook() { + if (localStorage.getItem(this.btcWallet) === null) { + localStorage.setItem(this.btcWallet, "") + } else { + this.tradeBotBtcBook = JSON.parse(localStorage.getItem(this.btcWallet) || "[]") + } + } + + addToBTCTradebook() { + const addBotBtcQortAmount = this.shadowRoot.getElementById('autoBuyBTCQortAmountInput').value + const addBotBtcPrice = this.shadowRoot.getElementById('autoBuyBTCPriceInput').value + const addBtcQortAmount = this.round(parseFloat(addBotBtcQortAmount)) + const addBtcPrice = this.round(parseFloat(addBotBtcPrice)) + + var oldBtcTradebook = JSON.parse(localStorage.getItem(this.btcWallet) || "[]") + + const newBtcTradebookItem = { + botBtcQortAmount: addBtcQortAmount, + botBtcPrice: addBtcPrice + } + + oldBtcTradebook.push(newBtcTradebookItem) + + localStorage.setItem(this.btcWallet, JSON.stringify(oldBtcTradebook)) + + let btctradebookstring = get("tradepage.tchange44") + parentEpml.request('showSnackBar', `${btctradebookstring}`) + + this.closeBTCTradebookDialog() + this.tradeBotBtcBook = JSON.parse(localStorage.getItem(this.btcWallet) || "[]") + } + + closeBTCTradebookDialog() { + this.shadowRoot.querySelector('#tradeBotBTCAddDialog').close() + this.clearTradeBotForm() + } + + removeBTCTradebook() { + localStorage.removeItem(this.btcWallet) + localStorage.setItem(this.btcWallet, "") + this.tradeBotBtcBook = JSON.parse(localStorage.getItem(this.btcWallet) || "[]") + + this.autoBuyBotDisable = false + + let btcstring = get("tradepage.tchange41") + parentEpml.request('showSnackBar', `${btcstring}`) + } + + ltcTradebook() { + if (localStorage.getItem(this.ltcWallet) === null) { + localStorage.setItem(this.ltcWallet, "") + } else { + this.tradeBotLtcBook = JSON.parse(localStorage.getItem(this.ltcWallet) || "[]") + } + } + + addToLTCTradebook() { + const addBotLtcQortAmount = this.shadowRoot.getElementById('autoBuyLTCQortAmountInput').value + const addBotLtcPrice = this.shadowRoot.getElementById('autoBuyLTCPriceInput').value + const addLtcQortAmount = this.round(parseFloat(addBotLtcQortAmount)) + const addLtcPrice = this.round(parseFloat(addBotLtcPrice)) + + var oldLtcTradebook = JSON.parse(localStorage.getItem(this.ltcWallet) || "[]") + + const newLtcTradebookItem = { + botLtcQortAmount: addLtcQortAmount, + botLtcPrice: addLtcPrice + } + + oldLtcTradebook.push(newLtcTradebookItem) + + localStorage.setItem(this.ltcWallet, JSON.stringify(oldLtcTradebook)) + + let ltctradebookstring = get("tradepage.tchange44") + parentEpml.request('showSnackBar', `${ltctradebookstring}`) + + this.closeLTCTradebookDialog() + this.tradeBotLtcBook = JSON.parse(localStorage.getItem(this.ltcWallet) || "[]") + } + + closeLTCTradebookDialog() { + this.shadowRoot.querySelector('#tradeBotLTCAddDialog').close() + this.clearTradeBotForm() + } + + removeLTCTradebook() { + localStorage.removeItem(this.ltcWallet) + localStorage.setItem(this.ltcWallet, "") + this.tradeBotLtcBook = JSON.parse(localStorage.getItem(this.ltcWallet) || "[]") + + this.autoBuyBotDisable = false - let ltcstring = get("tradepage.tchange41") - parentEpml.request('showSnackBar', `${ltcstring}`) - } + let ltcstring = get("tradepage.tchange41") + parentEpml.request('showSnackBar', `${ltcstring}`) + } - dogeTradebook() { - if (localStorage.getItem(this.dogeWallet) === null) { - localStorage.setItem(this.dogeWallet, "") - } else { - this.tradeBotDogeBook = JSON.parse(localStorage.getItem(this.dogeWallet) || "[]") - } - } - - addToDOGETradebook() { - const addBotDogeQortAmount = this.shadowRoot.getElementById('autoBuyDOGEQortAmountInput').value - const addBotDogePrice = this.shadowRoot.getElementById('autoBuyDOGEPriceInput').value - const addDogeQortAmount = this.round(parseFloat(addBotDogeQortAmount)) - const addDogePrice = this.round(parseFloat(addBotDogePrice)) + dogeTradebook() { + if (localStorage.getItem(this.dogeWallet) === null) { + localStorage.setItem(this.dogeWallet, "") + } else { + this.tradeBotDogeBook = JSON.parse(localStorage.getItem(this.dogeWallet) || "[]") + } + } + + addToDOGETradebook() { + const addBotDogeQortAmount = this.shadowRoot.getElementById('autoBuyDOGEQortAmountInput').value + const addBotDogePrice = this.shadowRoot.getElementById('autoBuyDOGEPriceInput').value + const addDogeQortAmount = this.round(parseFloat(addBotDogeQortAmount)) + const addDogePrice = this.round(parseFloat(addBotDogePrice)) - var oldDogeTradebook = JSON.parse(localStorage.getItem(this.dogeWallet) || "[]") + var oldDogeTradebook = JSON.parse(localStorage.getItem(this.dogeWallet) || "[]") - const newDogeTradebookItem = { - botDogeQortAmount: addDogeQortAmount, - botDogePrice: addDogePrice - } + const newDogeTradebookItem = { + botDogeQortAmount: addDogeQortAmount, + botDogePrice: addDogePrice + } - oldDogeTradebook.push(newDogeTradebookItem) + oldDogeTradebook.push(newDogeTradebookItem) - localStorage.setItem(this.dogeWallet, JSON.stringify(oldDogeTradebook)) + localStorage.setItem(this.dogeWallet, JSON.stringify(oldDogeTradebook)) - let dogetradebookstring = get("tradepage.tchange44") - parentEpml.request('showSnackBar', `${dogetradebookstring}`) + let dogetradebookstring = get("tradepage.tchange44") + parentEpml.request('showSnackBar', `${dogetradebookstring}`) - this.closeDOGETradebookDialog() - this.tradeBotDogeBook = JSON.parse(localStorage.getItem(this.dogeWallet) || "[]") - } + this.closeDOGETradebookDialog() + this.tradeBotDogeBook = JSON.parse(localStorage.getItem(this.dogeWallet) || "[]") + } - closeDOGETradebookDialog() { - this.shadowRoot.querySelector('#tradeBotDOGEAddDialog').close() - this.clearTradeBotForm() - } - - removeDOGETradebook() { - localStorage.removeItem(this.dogeWallet) - localStorage.setItem(this.dogeWallet, "") - this.tradeBotDogeBook = JSON.parse(localStorage.getItem(this.dogeWallet) || "[]") + closeDOGETradebookDialog() { + this.shadowRoot.querySelector('#tradeBotDOGEAddDialog').close() + this.clearTradeBotForm() + } + + removeDOGETradebook() { + localStorage.removeItem(this.dogeWallet) + localStorage.setItem(this.dogeWallet, "") + this.tradeBotDogeBook = JSON.parse(localStorage.getItem(this.dogeWallet) || "[]") - this.autoBuyBotDisable = false + this.autoBuyBotDisable = false - let dogestring = get("tradepage.tchange41") - parentEpml.request('showSnackBar', `${dogestring}`) - } + let dogestring = get("tradepage.tchange41") + parentEpml.request('showSnackBar', `${dogestring}`) + } - dgbTradebook() { - if (localStorage.getItem(this.dgbWallet) === null) { - localStorage.setItem(this.dgbWallet, "") - } else { - this.tradeBotDgbBook = JSON.parse(localStorage.getItem(this.dgbWallet) || "[]") - } - } - - addToDGBTradebook() { - const addBotDgbQortAmount = this.shadowRoot.getElementById('autoBuyDGBQortAmountInput').value - const addBotDgbPrice = this.shadowRoot.getElementById('autoBuyDGBPriceInput').value - const addDgbQortAmount = this.round(parseFloat(addBotDgbQortAmount)) - const addDgbPrice = this.round(parseFloat(addBotDgbPrice)) + dgbTradebook() { + if (localStorage.getItem(this.dgbWallet) === null) { + localStorage.setItem(this.dgbWallet, "") + } else { + this.tradeBotDgbBook = JSON.parse(localStorage.getItem(this.dgbWallet) || "[]") + } + } + + addToDGBTradebook() { + const addBotDgbQortAmount = this.shadowRoot.getElementById('autoBuyDGBQortAmountInput').value + const addBotDgbPrice = this.shadowRoot.getElementById('autoBuyDGBPriceInput').value + const addDgbQortAmount = this.round(parseFloat(addBotDgbQortAmount)) + const addDgbPrice = this.round(parseFloat(addBotDgbPrice)) - var oldDgbTradebook = JSON.parse(localStorage.getItem(this.dgbWallet) || "[]") + var oldDgbTradebook = JSON.parse(localStorage.getItem(this.dgbWallet) || "[]") - const newDgbTradebookItem = { - botDgbQortAmount: addDgbQortAmount, - botDgbPrice: addDgbPrice - } + const newDgbTradebookItem = { + botDgbQortAmount: addDgbQortAmount, + botDgbPrice: addDgbPrice + } - oldDgbTradebook.push(newDgbTradebookItem) + oldDgbTradebook.push(newDgbTradebookItem) - localStorage.setItem(this.dgbWallet, JSON.stringify(oldDgbTradebook)) + localStorage.setItem(this.dgbWallet, JSON.stringify(oldDgbTradebook)) - let dgbtradebookstring = get("tradepage.tchange44") - parentEpml.request('showSnackBar', `${dgbtradebookstring}`) + let dgbtradebookstring = get("tradepage.tchange44") + parentEpml.request('showSnackBar', `${dgbtradebookstring}`) - this.closeDGBTradebookDialog() - this.tradeBotDgbBook = JSON.parse(localStorage.getItem(this.dgbWallet) || "[]") - } + this.closeDGBTradebookDialog() + this.tradeBotDgbBook = JSON.parse(localStorage.getItem(this.dgbWallet) || "[]") + } - closeDGBTradebookDialog() { - this.shadowRoot.querySelector('#tradeBotDGBAddDialog').close() - this.clearTradeBotForm() - } - - removeDGBTradebook() { - localStorage.removeItem(this.dgbWallet) - localStorage.setItem(this.dgbWallet, "") - this.tradeBotDgbBook = JSON.parse(localStorage.getItem(this.dgbWallet) || "[]") + closeDGBTradebookDialog() { + this.shadowRoot.querySelector('#tradeBotDGBAddDialog').close() + this.clearTradeBotForm() + } + + removeDGBTradebook() { + localStorage.removeItem(this.dgbWallet) + localStorage.setItem(this.dgbWallet, "") + this.tradeBotDgbBook = JSON.parse(localStorage.getItem(this.dgbWallet) || "[]") - this.autoBuyBotDisable = false + this.autoBuyBotDisable = false - let dgbstring = get("tradepage.tchange41") - parentEpml.request('showSnackBar', `${dgbstring}`) - } + let dgbstring = get("tradepage.tchange41") + parentEpml.request('showSnackBar', `${dgbstring}`) + } - rvnTradebook() { - if (localStorage.getItem(this.rvnWallet) === null) { - localStorage.setItem(this.rvnWallet, "") - } else { - this.tradeBotRvnBook = JSON.parse(localStorage.getItem(this.rvnWallet) || "[]") - } - } + rvnTradebook() { + if (localStorage.getItem(this.rvnWallet) === null) { + localStorage.setItem(this.rvnWallet, "") + } else { + this.tradeBotRvnBook = JSON.parse(localStorage.getItem(this.rvnWallet) || "[]") + } + } - addToRVNTradebook() { - const addBotRvnQortAmount = this.shadowRoot.getElementById('autoBuyRVNQortAmountInput').value - const addBotRvnPrice = this.shadowRoot.getElementById('autoBuyRVNPriceInput').value - const addRvnQortAmount = this.round(parseFloat(addBotRvnQortAmount)) - const addRvnPrice = this.round(parseFloat(addBotRvnPrice)) - - var oldRvnTradebook = JSON.parse(localStorage.getItem(this.rvnWallet) || "[]") + addToRVNTradebook() { + const addBotRvnQortAmount = this.shadowRoot.getElementById('autoBuyRVNQortAmountInput').value + const addBotRvnPrice = this.shadowRoot.getElementById('autoBuyRVNPriceInput').value + const addRvnQortAmount = this.round(parseFloat(addBotRvnQortAmount)) + const addRvnPrice = this.round(parseFloat(addBotRvnPrice)) + + var oldRvnTradebook = JSON.parse(localStorage.getItem(this.rvnWallet) || "[]") - const newRvnTradebookItem = { - botRvnQortAmount: addRvnQortAmount, - botRvnPrice: addRvnPrice - } - - oldRvnTradebook.push(newRvnTradebookItem) - - localStorage.setItem(this.rvnWallet, JSON.stringify(oldRvnTradebook)) - - let rvntradebookstring = get("tradepage.tchange44") - parentEpml.request('showSnackBar', `${rvntradebookstring}`) - - this.closeRVNTradebookDialog() - this.tradeBotRvnBook = JSON.parse(localStorage.getItem(this.rvnWallet) || "[]") - } - - closeRVNTradebookDialog() { - this.shadowRoot.querySelector('#tradeBotRVNAddDialog').close() - this.clearTradeBotForm() - } - - removeRVNTradebook() { - localStorage.removeItem(this.rvnWallet) - localStorage.setItem(this.rvnWallet, "") - this.tradeBotRvnBook = JSON.parse(localStorage.getItem(this.rvnWallet) || "[]") - - this.autoBuyBotDisable = false - - let rvnstring = get("tradepage.tchange41") - parentEpml.request('showSnackBar', `${rvnstring}`) - } - - arrrTradebook() { - if (localStorage.getItem(this.arrrWallet) === null) { - localStorage.setItem(this.arrrWallet, "") - } else { - this.tradeBotArrrBook = JSON.parse(localStorage.getItem(this.arrrWallet) || "[]") - } - } - - addToARRRTradebook() { - const addBotArrrQortAmount = this.shadowRoot.getElementById('autoBuyARRRQortAmountInput').value - const addBotArrrPrice = this.shadowRoot.getElementById('autoBuyARRRPriceInput').value - const addArrrQortAmount = this.round(parseFloat(addBotArrrQortAmount)) - const addArrrPrice = this.round(parseFloat(addBotArrrPrice)) - - var oldArrrTradebook = JSON.parse(localStorage.getItem(this.arrrWallet) || "[]") - - const newArrrTradebookItem = { - botArrrQortAmount: addArrrQortAmount, - botArrrPrice: addArrrPrice - } - - oldArrrTradebook.push(newArrrTradebookItem) - - localStorage.setItem(this.arrrWallet, JSON.stringify(oldArrrTradebook)) - - let arrrtradebookstring = get("tradepage.tchange44") - parentEpml.request('showSnackBar', `${arrrtradebookstring}`) - - this.closeARRRTradebookDialog() - this.tradeBotArrrBook = JSON.parse(localStorage.getItem(this.arrrWallet) || "[]") - } - - closeARRRTradebookDialog() { - this.shadowRoot.querySelector('#tradeBotARRRAddDialog').close() - this.clearTradeBotForm() - } - - removeARRRTradebook() { - localStorage.removeItem(this.arrrWallet) - localStorage.setItem(this.arrrWallet, "") - this.tradeBotArrrBook = JSON.parse(localStorage.getItem(this.arrrWallet) || "[]") - - this.autoBuyBotDisable = false - - let arrrstring = get("tradepage.tchange41") - parentEpml.request('showSnackBar', `${arrrstring}`) - } - - async setForeignCoin(coin,beingInitialized) { - let _this = this - this.selectedCoin = coin - - let coinSelectionMenu=this.shadowRoot.getElementById("coinSelectionMenu") - - if(beingInitialized){ - coinSelectionMenu.shadowRoot.querySelector('.mdc-select--outlined .mdc-select__anchor').setAttribute('style', 'padding-left: 60px;') - let pairIconContainer = document.createElement("span") - let pairicon = (_this.listedCoins.get(_this.selectedCoin).coinCode).toLowerCase() - pairIconContainer.setAttribute("class","pairIconContainer") - pairIconContainer.setAttribute('style', 'left: 10px;top: 50%;transform: translate(0, -50%);height: 26px;width: 45px;position: absolute;background-repeat: no-repeat;background-size: cover;background-image: url(/img/qort'+pairicon+'.png);') - coinSelectionMenu.shadowRoot.querySelector('.mdc-select--outlined .mdc-select__anchor').appendChild(pairIconContainer) - }else{ - let pairIconContainer = coinSelectionMenu.shadowRoot.querySelector(".mdc-select--outlined .mdc-select__anchor span.pairIconContainer") - let pairicon = (_this.listedCoins.get(_this.selectedCoin).coinCode).toLowerCase() - pairIconContainer.style.backgroundImage='url(/img/qort'+pairicon+'.png)' - } - - this.isLoadingOpenTrades = true - this.createConnection() - this._openOrdersGrid.querySelector('#priceColumn').headerRenderer = function (root) { - const priceString2 = get("tradepage.tchange9") - root.innerHTML = '' + priceString2 + ' (' + _this.listedCoins.get(_this.selectedCoin).coinCode + ')' - } - this.clearTradeBotForm() - clearTimeout(this.updateDoneTradesTimeout) - await this.getDoneTrades() - this.updateDoneTradesTimeout = setTimeout(() => this.getDoneTrades(), 180000) - await this.updateWalletBalance() - await this.fetchWalletAddress(coin) - - } - - async reRenderOpenFilteredOrders() { - this.requestUpdate() - await this.updateComplete - this.isLoadingOpenTrades = false - } - - async reRenderMyOpenOrders() { - this.requestUpdate() - await this.updateComplete - this.isLoadingMyOpenOrders = false - } - - addAutoBuyAction() { - this.autoBuyWarning = false - this.clearTradeBotForm() - this.shadowRoot.querySelector('#tradeBot' + this.listedCoins.get(this.selectedCoin).coinCode + 'AddDialog').show() - } - - checkTradeBotValues() { - const checkTradeBotAmountInput = this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'QortAmountInput').value - const checkTradeBotPriceInput = this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'PriceInput').value - const checkTradeBotTotalInput = this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'TotalInput').value - const checkAmount = this.round(parseFloat(checkTradeBotAmountInput)) - const checkPrice = this.round(parseFloat(checkTradeBotPriceInput)) - const checkTotal = this.round(parseFloat(checkTradeBotTotalInput)) - - if (Number(checkAmount) === 0) { - let amountString = get("tradepage.tchange34") - parentEpml.request('showSnackBar', `${amountString}`) - } else if (Number(checkPrice) === 0) { - let priceString = get("tradepage.tchange35") - parentEpml.request('showSnackBar', `${priceString}`) - } else if (Number(checkTotal) === 0) { - let totalString = get("tradepage.tchange35") - parentEpml.request('showSnackBar', `${totalString}`) - } else { - this.showAddToAutoBuyStore() - } - } - - showAddToAutoBuyStore() { - switch(this.listedCoins.get(this.selectedCoin).coinCode) { - case "BTC": - this.addToBTCTradebook() - break - case "LTC": - this.addToLTCTradebook() - break - case "DOGE": - this.addToDOGETradebook() - break - case "DGB": - this.addToDGBTradebook() - break - case "RVN": - this.addToRVNTradebook() - break - case "ARRR": - this.addToARRRTradebook() - break - default: - break - } - } - - processOfferingTrade(offer) { - try { - if(this.listedCoins.get(offer.foreignBlockchain).name!='') { - const offerItem = { - ...offer, - qortAmount: parseFloat(offer.qortAmount), - price: parseFloat(offer.foreignAmount) / parseFloat(offer.qortAmount), - } - const addOffer = () => { - this.listedCoins.get(offer.foreignBlockchain).openOrders.unshift(offerItem) - } - const initOffer = () => { - this.listedCoins.get(offer.foreignBlockchain).openOrders.push(offerItem) - } - this.listedCoins.get(offer.foreignBlockchain).openOrders.length === 0 ? initOffer() : addOffer() - this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1 ? this._openOrdersGrid.clearCache() : null - } - } catch(e) { - console.log("Error adding offer from "+offer.foreignBlockchain) - } - } - - processRedeemedTrade(offer) { - try { - if (this.listedCoins.get(offer.foreignBlockchain).name!='') { - - if (offer.qortalCreator === this.selectedAddress.address) { - if (this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1) { - this.updateWalletBalance() - } - const offerItem = { - ...offer, - mode: 'SOLD', - } - this._myHistoricTradesGrid.items.unshift(offerItem) - this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1 ? this._myHistoricTradesGrid.clearCache() : null - } else if (offer.partnerQortalReceivingAddress === this.selectedAddress.address) { - if (this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1) { - this.updateWalletBalance() - } - const offerItem = { - ...offer, - mode: 'BOUGHT', - } - this._myHistoricTradesGrid.items.unshift(offerItem) - this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1 ? this._myHistoricTradesGrid.clearCache() : null - } - const addNewHistoricTrade = () => { - this._historicTradesGrid.items.unshift(offer) - this._historicTradesGrid.clearCache() - } - this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1 ? addNewHistoricTrade() : null - - } - } catch(e) { - console.log("Error processing redeemed trade offer from "+offer.foreignBlockchain) - } - } - - processTradingTrade(offer) { - try { - if (this.listedCoins.get(offer.foreignBlockchain).name!='') { - - if (offer.qortalCreator === this.selectedAddress.address && this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1) { - this.updateWalletBalance() - } - this._openOrdersGrid.items.forEach((item, index) => { - if (item.qortalAtAddress === offer.qortalAtAddress) { - this._openOrdersGrid.items.splice(index, 1) - this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1 ? this._openOrdersGrid.clearCache() : null - } - }) - this.listedCoins.get(offer.foreignBlockchain).openOrders = this.listedCoins.get(offer.foreignBlockchain).openOrders.filter((order) => order.qortalAtAddress !== offer.qortalAtAddress) - } - } catch(e) { - console.log("Error processing trading trade offer from "+offer.foreignBlockchain) - } - } - - processRefundedTrade(offer) { - try { - if (this.listedCoins.get(offer.foreignBlockchain).name!='') { - - if (offer.qortalCreator === this.selectedAddress.address) { - if (this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1) { - this.updateWalletBalance() - } - this._myHistoricTradesGrid.items.unshift(offer) - this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1 ? this._myHistoricTradesGrid.clearCache() : null - } - - } - } catch(e) { - console.log("Error processing refunded trade offer from "+offer.foreignBlockchain) - } - } - - processCancelledTrade(offer) { - try { - if (this.listedCoins.get(offer.foreignBlockchain).name!='') { - - if (offer.qortalCreator === this.selectedAddress.address) { - if (this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1) { - this.updateWalletBalance() - } - this._myHistoricTradesGrid.items.unshift(offer) - this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1 ? this._myHistoricTradesGrid.clearCache() : null - } - this._openOrdersGrid.items.forEach((item, index) => { - if (item.qortalAtAddress === offer.qortalAtAddress) { - this._openOrdersGrid.items.splice(index, 1) - this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1 ? this._openOrdersGrid.clearCache() : null - } - }) - this.listedCoins.get(offer.foreignBlockchain).openOrders = this.listedCoins.get(offer.foreignBlockchain).openOrders.filter((order) => order.qortalAtAddress !== offer.qortalAtAddress) - this._stuckOrdersGrid.items.forEach((item, index) => { - if (item.qortalAtAddress === offer.qortalAtAddress) { - this._stuckOrdersGrid.items.splice(index, 1) - this._stuckOrdersGrid.clearCache() - } - }) - } - } catch(e) { - console.log("Error processing cancelled trade offer from "+offer.foreignBlockchain) - } - } - - processTradeOffers(offers) { - offers.forEach((offer) => { - if (offer.mode === 'OFFERING') { - this.processOfferingTrade(offer) - } - }) - } - - processTradeBotStates(tradeStates) { - - const BitcoinACCTv1 = (states) => { - states.reverse() - states.forEach((state) => { - if (state.creatorAddress === this.selectedAddress.address) { - if (state.tradeState == 'ALICE_WAITING_FOR_AT_LOCK') { - this.changeTradeBotState(state, 'BUYING') - } else if (state.tradeState == 'ALICE_DONE') { - this.handleCompletedState(state) - } else if (state.tradeState == 'ALICE_REFUNDING_A') { - this.changeTradeBotState(state, 'REFUNDING') - } else if (state.tradeState == 'ALICE_REFUNDED') { - this.handleCompletedState(state) - } - } - }) - } - - const LitecoinACCTv1 = (states) => { - states.reverse() - states.forEach((state) => { - if (state.creatorAddress === this.selectedAddress.address) { - if (state.tradeState == 'ALICE_WAITING_FOR_AT_LOCK') { - this.changeTradeBotState(state, 'BUYING') - } else if (state.tradeState == 'ALICE_DONE') { - this.handleCompletedState(state) - } else if (state.tradeState == 'ALICE_REFUNDING_A') { - this.changeTradeBotState(state, 'REFUNDING') - } else if (state.tradeState == 'ALICE_REFUNDED') { - this.handleCompletedState(state) - } - } - }) - } - - const DogecoinACCTv1 = (states) => { - states.reverse() - states.forEach((state) => { - if (state.creatorAddress === this.selectedAddress.address) { - if (state.tradeState == 'ALICE_WAITING_FOR_AT_LOCK') { - this.changeTradeBotState(state, 'BUYING') - } else if (state.tradeState == 'ALICE_DONE') { - this.handleCompletedState(state) - } else if (state.tradeState == 'ALICE_REFUNDING_A') { - this.changeTradeBotState(state, 'REFUNDING') - } else if (state.tradeState == 'ALICE_REFUNDED') { - this.handleCompletedState(state) - } - } - }) - } - - const DigibyteACCTv1 = (states) => { - states.reverse() - states.forEach((state) => { - if (state.creatorAddress === this.selectedAddress.address) { - if (state.tradeState == 'ALICE_WAITING_FOR_AT_LOCK') { - this.changeTradeBotState(state, 'BUYING') - } else if (state.tradeState == 'ALICE_DONE') { - this.handleCompletedState(state) - } else if (state.tradeState == 'ALICE_REFUNDING_A') { - this.changeTradeBotState(state, 'REFUNDING') - } else if (state.tradeState == 'ALICE_REFUNDED') { - this.handleCompletedState(state) - } - } - }) - } - - const RavencoinACCTv1 = (states) => { - states.reverse() - states.forEach((state) => { - if (state.creatorAddress === this.selectedAddress.address) { - if (state.tradeState == 'ALICE_WAITING_FOR_AT_LOCK') { - this.changeTradeBotState(state, 'BUYING') - } else if (state.tradeState == 'ALICE_DONE') { - this.handleCompletedState(state) - } else if (state.tradeState == 'ALICE_REFUNDING_A') { - this.changeTradeBotState(state, 'REFUNDING') - } else if (state.tradeState == 'ALICE_REFUNDED') { - this.handleCompletedState(state) - } - } - }) - } - - const PirateChainACCTv1 = (states) => { - states.reverse() - states.forEach((state) => { - if (state.creatorAddress === this.selectedAddress.address) { - if (state.tradeState == 'ALICE_WAITING_FOR_AT_LOCK') { - this.changeTradeBotState(state, 'BUYING') - } else if (state.tradeState == 'ALICE_DONE') { - this.handleCompletedState(state) - } else if (state.tradeState == 'ALICE_REFUNDING_A') { - this.changeTradeBotState(state, 'REFUNDING') - } else if (state.tradeState == 'ALICE_REFUNDED') { - this.handleCompletedState(state) - } - } - }) - } - - switch (this.selectedCoin) { - case 'BITCOIN': - BitcoinACCTv1(tradeStates) - break - case 'LITECOIN': - LitecoinACCTv1(tradeStates) - break - case 'DOGECOIN': - DogecoinACCTv1(tradeStates) - break - case 'DIGIBYTE': - DigibyteACCTv1(tradeStates) - break - case 'RAVENCOIN': - RavencoinACCTv1(tradeStates) - break - case 'PIRATECHAIN': - PirateChainACCTv1(tradeStates) - break - default: - break - } - } - - changeTradeBotState(state, tradeState) { - this.isLoadingMyOpenOrders = true - const stateItem = { - ...state, - _tradeState: tradeState, - } - const item = this._myOrdersGrid.querySelector(`#${state.atAddress}`) - const addStateItem = () => { - this.reRenderMyOpenOrders() - this._myOrdersGrid.items.unshift(stateItem) - this._myOrdersGrid.clearCache() - } - const updateStateItem = () => { - this._myOrdersGrid.items.forEach((item, index) => { - if (item.atAddress === state.atAddress) { - this.reRenderMyOpenOrders() - this._myOrdersGrid.items.splice(index, 1) - this._myOrdersGrid.items.unshift(stateItem) - this._myOrdersGrid.clearCache() - } - }) - } - item ? updateStateItem() : addStateItem() - } - - handleCompletedState(state) { - this._myOrdersGrid.items.forEach((item, index) => { - if (item.atAddress === state.atAddress) { - this.reRenderMyOpenOrders() - this._myOrdersGrid.items.splice(index, 1) - this._myOrdersGrid.clearCache() - } - }) - } - - initSocket() { - let _relatedCoin = "" - let tradePresenceTxns = null - let offeringTrades = null - - self.addEventListener('message', function (event) { - switch (event.data.type) { - case 'open_orders': - offeringTrades = event.data.content - processOffersWithPresence() - break - case 'set_coin': - _relatedCoin = event.data.content - break - default: - break - } - }) - - const lessThanThirtyMinsAgo = (timestamp) => { - const THIRTYMINS = 1000 * 60 * 30 - const thirtyMinsAgo = Date.now() - THIRTYMINS - return timestamp > thirtyMinsAgo - } - - const filterOffersUsingTradePresence = (offeringTrade) => { - return offeringTrade.tradePresenceExpiry > Date.now(); - } - - const processOffersWithPresence = () => { - if (offeringTrades === null) return - - async function asyncForEach(array, callback) { - for (let index = 0; index < array.length; index++) { - await callback(array[index], index, array) - } - } - - const startOfferPresenceMapping = async () => { - - if (tradePresenceTxns !== null) { - await asyncForEach(tradePresenceTxns, async (tradePresence) => { - let offerIndex = offeringTrades.findIndex((offeringTrade) => offeringTrade.qortalCreatorTradeAddress === tradePresence.tradeAddress) - offerIndex !== -1 ? (offeringTrades[offerIndex].tradePresenceExpiry = tradePresence.timestamp) : null - }) - } - - let filteredOffers = offeringTrades.filter((offeringTrade) => filterOffersUsingTradePresence(offeringTrade)) - self.postMessage({ type: 'PRESENCE', data: { offers: offeringTrades, filteredOffers: filteredOffers, relatedCoin: _relatedCoin } }) - } - - startOfferPresenceMapping() - } - - const initTradeOffersWebSocket = (restarted = false) => { - let tradeOffersSocketCounter = 0 - let socketTimeout - let socketLink = `ws://NODEURL/websockets/crosschain/tradeoffers?foreignBlockchain=FOREIGN_BLOCKCHAIN&includeHistoric=true` - const socket = new WebSocket(socketLink) - socket.onopen = () => { - setTimeout(pingSocket, 50) - tradeOffersSocketCounter += 1 - } - socket.onmessage = (e) => { - e.relatedCoin = _relatedCoin - self.postMessage({ - type: 'TRADE_OFFERS', - data: e.data, - counter: tradeOffersSocketCounter, - isRestarted: restarted, - }) - tradeOffersSocketCounter += 1 - restarted = false - } - socket.onclose = () => { - clearTimeout(socketTimeout) - restartTradeOffersWebSocket() - } - socket.onerror = (e) => { - clearTimeout(socketTimeout) - } - const pingSocket = () => { - socket.send('ping') - socketTimeout = setTimeout(pingSocket, 295000) - } - } - - const initTradeBotWebSocket = (restarted = false) => { - let socketTimeout - let socketLink = `ws://NODEURL/websockets/crosschain/tradebot?foreignBlockchain=FOREIGN_BLOCKCHAIN` - const socket = new WebSocket(socketLink) - socket.onopen = () => { - setTimeout(pingSocket, 50) - } - socket.onmessage = (e) => { - e.relatedCoin = _relatedCoin - self.postMessage({ - type: 'TRADE_BOT', - data: e.data, - isRestarted: restarted, - }) - restarted = false - } - socket.onclose = () => { - clearTimeout(socketTimeout) - restartTradeBotWebSocket() - } - socket.onerror = (e) => { - clearTimeout(socketTimeout) - } - const pingSocket = () => { - socket.send('ping') - socketTimeout = setTimeout(pingSocket, 295000) - } - } - - const initTradePresenceWebSocket = (restarted = false) => { - let socketTimeout - let socketLink = `ws://NODEURL/websockets/crosschain/tradepresence` - const socket = new WebSocket(socketLink) - socket.onopen = () => { - setTimeout(pingSocket, 50) - } - socket.onmessage = (e) => { - tradePresenceTxns = JSON.parse(e.data) - processOffersWithPresence() - restarted = false - } - socket.onclose = () => { - clearTimeout(socketTimeout) - restartTradePresenceWebSocket() - } - socket.onerror = (e) => { - clearTimeout(socketTimeout) - } - const pingSocket = () => { - socket.send('ping') - socketTimeout = setTimeout(pingSocket, 295000) - } - } - - const restartTradePresenceWebSocket = () => { - setTimeout(() => initTradePresenceWebSocket(true), 50) - } - - const restartTradeOffersWebSocket = () => { - setTimeout(() => initTradeOffersWebSocket(true), 50) - } - - const restartTradeBotWebSocket = () => { - setTimeout(() => initTradeBotWebSocket(true), 50) - } - - initTradeOffersWebSocket() - initTradePresenceWebSocket() - initTradeBotWebSocket() - } - - updateAccountBalance() { - clearTimeout(this.updateAccountBalanceTimeout) - parentEpml.request('apiCall', { - url: `/addresses/balance/${this.selectedAddress.address}?apiKey=${this.getApiKey()}`, - }) - .then((res) => { - this.listedCoins.get("QORTAL").balance = res - this.updateAccountBalanceTimeout = setTimeout(() => this.updateAccountBalance(), 10000) - }) - } - - _checkBuyAmount(e) { - const targetAmount = e.target.value - const target = e.target - - if (targetAmount.length === 0) { - this.isValidAmount = false - this.sellBtnDisable = true - e.target.blur() - e.target.focus() - e.target.invalid = true - } else { - this.buyBtnDisable = false - } - - e.target.blur() - e.target.focus() - - e.target.validityTransform = (newValue, nativeValidity) => { - if (newValue.includes('-') === true) { - this.buyBtnDisable = true - return { - valid: false, - } - } else if (!nativeValidity.valid) { - if (newValue.includes('.') === true) { - let myAmount = newValue.split('.') - if (myAmount[1].length > 8) { - this.buyBtnDisable = true - } else { - this.buyBtnDisable = false - return { - valid: true, - } - } - } - } else { - this.buyBtnDisable = false - } - } - } - - checkTradeBotAmount(e) { - const targetAmount = e.target.value - const target = e.target - this.autoBuyWarning = false - - if (targetAmount.length === 0) { - this.isValidAmount = false - this.autoBuyBtnDisable = true - this.autoBuyWarning = false - e.target.blur() - e.target.focus() - e.target.invalid = true - } else { - const buyTradeBotAmountInput = this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'QortAmountInput').value - const buyTradeBotPriceInput = this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'PriceInput').value - const buyTradeBotTotalInput = this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'TotalInput').value - const checkFunds = this.round(parseFloat(buyTradeBotAmountInput) * parseFloat(buyTradeBotPriceInput)) - const myFunds = this.round(parseFloat(this.listedCoins.get(this.selectedCoin).balance)) - if (Number(myFunds) > Number(checkFunds)) { - this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'TotalInput').value = this.round(parseFloat(buyTradeBotAmountInput) * parseFloat(buyTradeBotPriceInput)) - this.autoBuyBtnDisable = false - this.autoBuyWarning = false - } else { - this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'TotalInput').value = this.round(parseFloat(buyTradeBotAmountInput) * parseFloat(buyTradeBotPriceInput)) - this.autoBuyBtnDisable = true - this.autoBuyWarning = true - } - } - - e.target.blur() - e.target.focus() - - e.target.validityTransform = (newValue, nativeValidity) => { - if (newValue.includes('-') === true) { - this.autoBuyBtnDisable = true - this.autoBuyWarning = false - return { - valid: false, - } - } else if (!nativeValidity.valid) { - if (newValue.includes('.') === true) { - let myAmount = newValue.split('.') - if (myAmount[1].length > 8) { - this.autoBuyBtnDisable = true - this.autoBuyWarning = false - } else { - const buyTradeBotAmountInput = this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'QortAmountInput').value - const buyTradeBotPriceInput = this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'PriceInput').value - const buyTradeBotTotalInput = this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'TotalInput').value - const checkFunds = this.round(parseFloat(buyTradeBotAmountInput) * parseFloat(buyTradeBotPriceInput)) - const myFunds = this.round(parseFloat(this.listedCoins.get(this.selectedCoin).balance)) - if (Number(myFunds) > Number(checkFunds)) { - this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'TotalInput').value = this.round(parseFloat(buyTradeBotAmountInput) * parseFloat(buyTradeBotPriceInput)) - this.autoBuyBtnDisable = false - this.autoBuyWarning = false - } else { - this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'TotalInput').value = this.round(parseFloat(buyTradeBotAmountInput) * parseFloat(buyTradeBotPriceInput)) - this.autoBuyBtnDisable = true - this.autoBuyWarning = true - } - return { - valid: true, - } - } - } - } else { - const buyTradeBotAmountInput = this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'QortAmountInput').value - const buyTradeBotPriceInput = this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'PriceInput').value - const buyTradeBotTotalInput = this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'TotalInput').value - const checkFunds = this.round(parseFloat(buyTradeBotAmountInput) * parseFloat(buyTradeBotPriceInput)) - const myFunds = this.round(parseFloat(this.listedCoins.get(this.selectedCoin).balance)) - if (Number(myFunds) > Number(checkFunds)) { - this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'TotalInput').value = this.round(parseFloat(buyTradeBotAmountInput) * parseFloat(buyTradeBotPriceInput)) - this.autoBuyBtnDisable = false - this.autoBuyWarning = false - } else { - this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'TotalInput').value = this.round(parseFloat(buyTradeBotAmountInput) * parseFloat(buyTradeBotPriceInput)) - this.autoBuyBtnDisable = true - this.autoBuyWarning = true - } - } - } - } - - checkTradeBotTotalAmount(e) { - const targetAmount = e.target.value - const target = e.target - this.autoBuyWarning = false - - if (targetAmount.length === 0) { - this.isValidAmount = false - this.autoBuyBtnDisable = true - this.autoBuyWarning = false - e.target.blur() - e.target.focus() - e.target.invalid = true - } else { - const buyTradeBotAmountInput = this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'QortAmountInput').value - const buyTradeBotPriceInput = this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'PriceInput').value - const buyTradeBotTotalInput = this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'TotalInput').value - const checkFunds = this.round(parseFloat(buyTradeBotAmountInput) * parseFloat(buyTradeBotPriceInput)) - const myFunds = this.round(parseFloat(this.listedCoins.get(this.selectedCoin).balance)) - if (Number(myFunds) > Number(checkFunds)) { - this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'QortAmountInput').value = this.round(parseFloat(buyTradeBotTotalInput) / parseFloat(buyTradeBotPriceInput)) - this.autoBuyBtnDisable = false - this.autoBuyWarning = false - } else { - this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'QortAmountInput').value = this.round(parseFloat(buyTradeBotTotalInput) / parseFloat(buyTradeBotPriceInput)) - this.autoBuyBtnDisable = true - this.autoBuyWarning = true - } - } - - e.target.blur() - e.target.focus() - - e.target.validityTransform = (newValue, nativeValidity) => { - if (newValue.includes('-') === true) { - this.autoBuyBtnDisable = true - this.autoBuyWarning = false - return { - valid: false, - } - } else if (!nativeValidity.valid) { - if (newValue.includes('.') === true) { - let myAmount = newValue.split('.') - if (myAmount[1].length > 8) { - this.autoBuyBtnDisable = true - this.autoBuyWarning = false - } else { - const buyTradeBotAmountInput = this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'QortAmountInput').value - const buyTradeBotPriceInput = this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'PriceInput').value - const buyTradeBotTotalInput = this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'TotalInput').value - const checkFunds = this.round(parseFloat(buyTradeBotAmountInput) * parseFloat(buyTradeBotPriceInput)) - const myFunds = this.round(parseFloat(this.listedCoins.get(this.selectedCoin).balance)) - if (Number(myFunds) > Number(checkFunds)) { - this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'QortAmountInput').value = this.round(parseFloat(buyTradeBotTotalInput) / parseFloat(buyTradeBotPriceInput)) - this.autoBuyBtnDisable = false - this.autoBuyWarning = false - } else { - this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'QortAmountInput').value = this.round(parseFloat(buyTradeBotTotalInput) / parseFloat(buyTradeBotPriceInput)) - this.autoBuyBtnDisable = true - this.autoBuyWarning = true - } - return { - valid: true, - } - } - } - } else { - const buyTradeBotAmountInput = this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'QortAmountInput').value - const buyTradeBotPriceInput = this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'PriceInput').value - const buyTradeBotTotalInput = this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'TotalInput').value - const checkFunds = this.round(parseFloat(buyTradeBotAmountInput) * parseFloat(buyTradeBotPriceInput)) - const myFunds = this.round(parseFloat(this.listedCoins.get(this.selectedCoin).balance)) - if (Number(myFunds) > Number(checkFunds)) { - this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'QortAmountInput').value = this.round(parseFloat(buyTradeBotTotalInput) / parseFloat(buyTradeBotPriceInput)) - this.autoBuyBtnDisable = false - this.autoBuyWarning = false - } else { - this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'QortAmountInput').value = this.round(parseFloat(buyTradeBotTotalInput) / parseFloat(buyTradeBotPriceInput)) - this.autoBuyBtnDisable = true - this.autoBuyWarning = true - } - } - } - } - - async tradeFee() { - const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] - const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port - const url = `${nodeUrl}/transactions/unitfee?txType=DEPLOY_AT` - await fetch(url).then((response) => { - if (response.ok) { - return response.json() - } - return Promise.reject(response) - }).then((json) => { - this.listedCoins.get("QORTAL").tradeFee = (Number(json) + 100000) / 1e8 - }) - } - - getApiKey() { - const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] + const newRvnTradebookItem = { + botRvnQortAmount: addRvnQortAmount, + botRvnPrice: addRvnPrice + } + + oldRvnTradebook.push(newRvnTradebookItem) + + localStorage.setItem(this.rvnWallet, JSON.stringify(oldRvnTradebook)) + + let rvntradebookstring = get("tradepage.tchange44") + parentEpml.request('showSnackBar', `${rvntradebookstring}`) + + this.closeRVNTradebookDialog() + this.tradeBotRvnBook = JSON.parse(localStorage.getItem(this.rvnWallet) || "[]") + } + + closeRVNTradebookDialog() { + this.shadowRoot.querySelector('#tradeBotRVNAddDialog').close() + this.clearTradeBotForm() + } + + removeRVNTradebook() { + localStorage.removeItem(this.rvnWallet) + localStorage.setItem(this.rvnWallet, "") + this.tradeBotRvnBook = JSON.parse(localStorage.getItem(this.rvnWallet) || "[]") + + this.autoBuyBotDisable = false + + let rvnstring = get("tradepage.tchange41") + parentEpml.request('showSnackBar', `${rvnstring}`) + } + + arrrTradebook() { + if (localStorage.getItem(this.arrrWallet) === null) { + localStorage.setItem(this.arrrWallet, "") + } else { + this.tradeBotArrrBook = JSON.parse(localStorage.getItem(this.arrrWallet) || "[]") + } + } + + addToARRRTradebook() { + const addBotArrrQortAmount = this.shadowRoot.getElementById('autoBuyARRRQortAmountInput').value + const addBotArrrPrice = this.shadowRoot.getElementById('autoBuyARRRPriceInput').value + const addArrrQortAmount = this.round(parseFloat(addBotArrrQortAmount)) + const addArrrPrice = this.round(parseFloat(addBotArrrPrice)) + + var oldArrrTradebook = JSON.parse(localStorage.getItem(this.arrrWallet) || "[]") + + const newArrrTradebookItem = { + botArrrQortAmount: addArrrQortAmount, + botArrrPrice: addArrrPrice + } + + oldArrrTradebook.push(newArrrTradebookItem) + + localStorage.setItem(this.arrrWallet, JSON.stringify(oldArrrTradebook)) + + let arrrtradebookstring = get("tradepage.tchange44") + parentEpml.request('showSnackBar', `${arrrtradebookstring}`) + + this.closeARRRTradebookDialog() + this.tradeBotArrrBook = JSON.parse(localStorage.getItem(this.arrrWallet) || "[]") + } + + closeARRRTradebookDialog() { + this.shadowRoot.querySelector('#tradeBotARRRAddDialog').close() + this.clearTradeBotForm() + } + + removeARRRTradebook() { + localStorage.removeItem(this.arrrWallet) + localStorage.setItem(this.arrrWallet, "") + this.tradeBotArrrBook = JSON.parse(localStorage.getItem(this.arrrWallet) || "[]") + + this.autoBuyBotDisable = false + + let arrrstring = get("tradepage.tchange41") + parentEpml.request('showSnackBar', `${arrrstring}`) + } + + async setForeignCoin(coin, beingInitialized) { + let _this = this + this.selectedCoin = coin + + let coinSelectionMenu = this.shadowRoot.getElementById("coinSelectionMenu") + + if (beingInitialized) { + coinSelectionMenu.shadowRoot.querySelector('.mdc-select--outlined .mdc-select__anchor').setAttribute('style', 'padding-left: 60px;') + let pairIconContainer = document.createElement("span") + let pairicon = (_this.listedCoins.get(_this.selectedCoin).coinCode).toLowerCase() + pairIconContainer.setAttribute("class", "pairIconContainer") + pairIconContainer.setAttribute('style', 'left: 10px;top: 50%;transform: translate(0, -50%);height: 26px;width: 45px;position: absolute;background-repeat: no-repeat;background-size: cover;background-image: url(/img/qort' + pairicon + '.png);') + coinSelectionMenu.shadowRoot.querySelector('.mdc-select--outlined .mdc-select__anchor').appendChild(pairIconContainer) + } else { + let pairIconContainer = coinSelectionMenu.shadowRoot.querySelector(".mdc-select--outlined .mdc-select__anchor span.pairIconContainer") + let pairicon = (_this.listedCoins.get(_this.selectedCoin).coinCode).toLowerCase() + pairIconContainer.style.backgroundImage = 'url(/img/qort' + pairicon + '.png)' + } + + this.isLoadingOpenTrades = true + this.createConnection() + this._openOrdersGrid.querySelector('#priceColumn').headerRenderer = function (root) { + const priceString2 = get("tradepage.tchange9") + root.innerHTML = '' + priceString2 + ' (' + _this.listedCoins.get(_this.selectedCoin).coinCode + ')' + } + this.clearTradeBotForm() + clearTimeout(this.updateDoneTradesTimeout) + await this.getDoneTrades() + this.updateDoneTradesTimeout = setTimeout(() => this.getDoneTrades(), 180000) + await this.updateWalletBalance() + await this.fetchWalletAddress(coin) + + } + + async reRenderOpenFilteredOrders() { + this.requestUpdate() + await this.updateComplete + this.isLoadingOpenTrades = false + } + + async reRenderMyOpenOrders() { + this.requestUpdate() + await this.updateComplete + this.isLoadingMyOpenOrders = false + } + + addAutoBuyAction() { + this.autoBuyWarning = false + this.clearTradeBotForm() + this.shadowRoot.querySelector('#tradeBot' + this.listedCoins.get(this.selectedCoin).coinCode + 'AddDialog').show() + } + + checkTradeBotValues() { + const checkTradeBotAmountInput = this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'QortAmountInput').value + const checkTradeBotPriceInput = this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'PriceInput').value + const checkTradeBotTotalInput = this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'TotalInput').value + const checkAmount = this.round(parseFloat(checkTradeBotAmountInput)) + const checkPrice = this.round(parseFloat(checkTradeBotPriceInput)) + const checkTotal = this.round(parseFloat(checkTradeBotTotalInput)) + + if (Number(checkAmount) === 0) { + let amountString = get("tradepage.tchange34") + parentEpml.request('showSnackBar', `${amountString}`) + } else if (Number(checkPrice) === 0) { + let priceString = get("tradepage.tchange35") + parentEpml.request('showSnackBar', `${priceString}`) + } else if (Number(checkTotal) === 0) { + let totalString = get("tradepage.tchange35") + parentEpml.request('showSnackBar', `${totalString}`) + } else { + this.showAddToAutoBuyStore() + } + } + + showAddToAutoBuyStore() { + switch (this.listedCoins.get(this.selectedCoin).coinCode) { + case "BTC": + this.addToBTCTradebook() + break + case "LTC": + this.addToLTCTradebook() + break + case "DOGE": + this.addToDOGETradebook() + break + case "DGB": + this.addToDGBTradebook() + break + case "RVN": + this.addToRVNTradebook() + break + case "ARRR": + this.addToARRRTradebook() + break + default: + break + } + } + + processOfferingTrade(offer) { + try { + if (this.listedCoins.get(offer.foreignBlockchain).name != '') { + const offerItem = { + ...offer, + qortAmount: parseFloat(offer.qortAmount), + price: parseFloat(offer.foreignAmount) / parseFloat(offer.qortAmount), + } + const addOffer = () => { + this.listedCoins.get(offer.foreignBlockchain).openOrders.unshift(offerItem) + } + const initOffer = () => { + this.listedCoins.get(offer.foreignBlockchain).openOrders.push(offerItem) + } + this.listedCoins.get(offer.foreignBlockchain).openOrders.length === 0 ? initOffer() : addOffer() + this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1 ? this._openOrdersGrid.clearCache() : null + } + } catch (e) { + console.log("Error adding offer from " + offer.foreignBlockchain) + } + } + + processRedeemedTrade(offer) { + try { + if (this.listedCoins.get(offer.foreignBlockchain).name != '') { + + if (offer.qortalCreator === this.selectedAddress.address) { + if (this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1) { + this.updateWalletBalance() + } + const offerItem = { + ...offer, + mode: 'SOLD', + } + this._myHistoricTradesGrid.items.unshift(offerItem) + this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1 ? this._myHistoricTradesGrid.clearCache() : null + } else if (offer.partnerQortalReceivingAddress === this.selectedAddress.address) { + if (this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1) { + this.updateWalletBalance() + } + const offerItem = { + ...offer, + mode: 'BOUGHT', + } + this._myHistoricTradesGrid.items.unshift(offerItem) + this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1 ? this._myHistoricTradesGrid.clearCache() : null + } + const addNewHistoricTrade = () => { + this._historicTradesGrid.items.unshift(offer) + this._historicTradesGrid.clearCache() + } + this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1 ? addNewHistoricTrade() : null + + } + } catch (e) { + console.log("Error processing redeemed trade offer from " + offer.foreignBlockchain) + } + } + + processTradingTrade(offer) { + try { + if (this.listedCoins.get(offer.foreignBlockchain).name != '') { + + if (offer.qortalCreator === this.selectedAddress.address && this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1) { + this.updateWalletBalance() + } + this._openOrdersGrid.items.forEach((item, index) => { + if (item.qortalAtAddress === offer.qortalAtAddress) { + this._openOrdersGrid.items.splice(index, 1) + this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1 ? this._openOrdersGrid.clearCache() : null + } + }) + this.listedCoins.get(offer.foreignBlockchain).openOrders = this.listedCoins.get(offer.foreignBlockchain).openOrders.filter((order) => order.qortalAtAddress !== offer.qortalAtAddress) + } + } catch (e) { + console.log("Error processing trading trade offer from " + offer.foreignBlockchain) + } + } + + processRefundedTrade(offer) { + try { + if (this.listedCoins.get(offer.foreignBlockchain).name != '') { + + if (offer.qortalCreator === this.selectedAddress.address) { + if (this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1) { + this.updateWalletBalance() + } + this._myHistoricTradesGrid.items.unshift(offer) + this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1 ? this._myHistoricTradesGrid.clearCache() : null + } + + } + } catch (e) { + console.log("Error processing refunded trade offer from " + offer.foreignBlockchain) + } + } + + processCancelledTrade(offer) { + try { + if (this.listedCoins.get(offer.foreignBlockchain).name != '') { + + if (offer.qortalCreator === this.selectedAddress.address) { + if (this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1) { + this.updateWalletBalance() + } + this._myHistoricTradesGrid.items.unshift(offer) + this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1 ? this._myHistoricTradesGrid.clearCache() : null + } + this._openOrdersGrid.items.forEach((item, index) => { + if (item.qortalAtAddress === offer.qortalAtAddress) { + this._openOrdersGrid.items.splice(index, 1) + this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1 ? this._openOrdersGrid.clearCache() : null + } + }) + this.listedCoins.get(offer.foreignBlockchain).openOrders = this.listedCoins.get(offer.foreignBlockchain).openOrders.filter((order) => order.qortalAtAddress !== offer.qortalAtAddress) + this._stuckOrdersGrid.items.forEach((item, index) => { + if (item.qortalAtAddress === offer.qortalAtAddress) { + this._stuckOrdersGrid.items.splice(index, 1) + this._stuckOrdersGrid.clearCache() + } + }) + } + } catch (e) { + console.log("Error processing cancelled trade offer from " + offer.foreignBlockchain) + } + } + + processTradeOffers(offers) { + offers.forEach((offer) => { + if (offer.mode === 'OFFERING') { + this.processOfferingTrade(offer) + } + }) + } + + processTradeBotStates(tradeStates) { + + const BitcoinACCTv1 = (states) => { + states.reverse() + states.forEach((state) => { + if (state.creatorAddress === this.selectedAddress.address) { + if (state.tradeState == 'ALICE_WAITING_FOR_AT_LOCK') { + this.changeTradeBotState(state, 'BUYING') + } else if (state.tradeState == 'ALICE_DONE') { + this.handleCompletedState(state) + } else if (state.tradeState == 'ALICE_REFUNDING_A') { + this.changeTradeBotState(state, 'REFUNDING') + } else if (state.tradeState == 'ALICE_REFUNDED') { + this.handleCompletedState(state) + } + } + }) + } + + const LitecoinACCTv1 = (states) => { + states.reverse() + states.forEach((state) => { + if (state.creatorAddress === this.selectedAddress.address) { + if (state.tradeState == 'ALICE_WAITING_FOR_AT_LOCK') { + this.changeTradeBotState(state, 'BUYING') + } else if (state.tradeState == 'ALICE_DONE') { + this.handleCompletedState(state) + } else if (state.tradeState == 'ALICE_REFUNDING_A') { + this.changeTradeBotState(state, 'REFUNDING') + } else if (state.tradeState == 'ALICE_REFUNDED') { + this.handleCompletedState(state) + } + } + }) + } + + const DogecoinACCTv1 = (states) => { + states.reverse() + states.forEach((state) => { + if (state.creatorAddress === this.selectedAddress.address) { + if (state.tradeState == 'ALICE_WAITING_FOR_AT_LOCK') { + this.changeTradeBotState(state, 'BUYING') + } else if (state.tradeState == 'ALICE_DONE') { + this.handleCompletedState(state) + } else if (state.tradeState == 'ALICE_REFUNDING_A') { + this.changeTradeBotState(state, 'REFUNDING') + } else if (state.tradeState == 'ALICE_REFUNDED') { + this.handleCompletedState(state) + } + } + }) + } + + const DigibyteACCTv1 = (states) => { + states.reverse() + states.forEach((state) => { + if (state.creatorAddress === this.selectedAddress.address) { + if (state.tradeState == 'ALICE_WAITING_FOR_AT_LOCK') { + this.changeTradeBotState(state, 'BUYING') + } else if (state.tradeState == 'ALICE_DONE') { + this.handleCompletedState(state) + } else if (state.tradeState == 'ALICE_REFUNDING_A') { + this.changeTradeBotState(state, 'REFUNDING') + } else if (state.tradeState == 'ALICE_REFUNDED') { + this.handleCompletedState(state) + } + } + }) + } + + const RavencoinACCTv1 = (states) => { + states.reverse() + states.forEach((state) => { + if (state.creatorAddress === this.selectedAddress.address) { + if (state.tradeState == 'ALICE_WAITING_FOR_AT_LOCK') { + this.changeTradeBotState(state, 'BUYING') + } else if (state.tradeState == 'ALICE_DONE') { + this.handleCompletedState(state) + } else if (state.tradeState == 'ALICE_REFUNDING_A') { + this.changeTradeBotState(state, 'REFUNDING') + } else if (state.tradeState == 'ALICE_REFUNDED') { + this.handleCompletedState(state) + } + } + }) + } + + const PirateChainACCTv1 = (states) => { + states.reverse() + states.forEach((state) => { + if (state.creatorAddress === this.selectedAddress.address) { + if (state.tradeState == 'ALICE_WAITING_FOR_AT_LOCK') { + this.changeTradeBotState(state, 'BUYING') + } else if (state.tradeState == 'ALICE_DONE') { + this.handleCompletedState(state) + } else if (state.tradeState == 'ALICE_REFUNDING_A') { + this.changeTradeBotState(state, 'REFUNDING') + } else if (state.tradeState == 'ALICE_REFUNDED') { + this.handleCompletedState(state) + } + } + }) + } + + switch (this.selectedCoin) { + case 'BITCOIN': + BitcoinACCTv1(tradeStates) + break + case 'LITECOIN': + LitecoinACCTv1(tradeStates) + break + case 'DOGECOIN': + DogecoinACCTv1(tradeStates) + break + case 'DIGIBYTE': + DigibyteACCTv1(tradeStates) + break + case 'RAVENCOIN': + RavencoinACCTv1(tradeStates) + break + case 'PIRATECHAIN': + PirateChainACCTv1(tradeStates) + break + default: + break + } + } + + changeTradeBotState(state, tradeState) { + this.isLoadingMyOpenOrders = true + const stateItem = { + ...state, + _tradeState: tradeState, + } + const item = this._myOrdersGrid.querySelector(`#${state.atAddress}`) + const addStateItem = () => { + this.reRenderMyOpenOrders() + this._myOrdersGrid.items.unshift(stateItem) + this._myOrdersGrid.clearCache() + } + const updateStateItem = () => { + this._myOrdersGrid.items.forEach((item, index) => { + if (item.atAddress === state.atAddress) { + this.reRenderMyOpenOrders() + this._myOrdersGrid.items.splice(index, 1) + this._myOrdersGrid.items.unshift(stateItem) + this._myOrdersGrid.clearCache() + } + }) + } + item ? updateStateItem() : addStateItem() + } + + handleCompletedState(state) { + this._myOrdersGrid.items.forEach((item, index) => { + if (item.atAddress === state.atAddress) { + this.reRenderMyOpenOrders() + this._myOrdersGrid.items.splice(index, 1) + this._myOrdersGrid.clearCache() + } + }) + } + + initSocket() { + let _relatedCoin = "" + let tradePresenceTxns = null + let offeringTrades = null + + self.addEventListener('message', function (event) { + switch (event.data.type) { + case 'open_orders': + offeringTrades = event.data.content + processOffersWithPresence() + break + case 'set_coin': + _relatedCoin = event.data.content + break + default: + break + } + }) + + const lessThanThirtyMinsAgo = (timestamp) => { + const THIRTYMINS = 1000 * 60 * 30 + const thirtyMinsAgo = Date.now() - THIRTYMINS + return timestamp > thirtyMinsAgo + } + + const filterOffersUsingTradePresence = (offeringTrade) => { + return offeringTrade.tradePresenceExpiry > Date.now(); + } + + const processOffersWithPresence = () => { + if (offeringTrades === null) return + + async function asyncForEach(array, callback) { + for (let index = 0; index < array.length; index++) { + await callback(array[index], index, array) + } + } + + const startOfferPresenceMapping = async () => { + + if (tradePresenceTxns !== null) { + await asyncForEach(tradePresenceTxns, async (tradePresence) => { + let offerIndex = offeringTrades.findIndex((offeringTrade) => offeringTrade.qortalCreatorTradeAddress === tradePresence.tradeAddress) + offerIndex !== -1 ? (offeringTrades[offerIndex].tradePresenceExpiry = tradePresence.timestamp) : null + }) + } + + let filteredOffers = offeringTrades.filter((offeringTrade) => filterOffersUsingTradePresence(offeringTrade)) + self.postMessage({ type: 'PRESENCE', data: { offers: offeringTrades, filteredOffers: filteredOffers, relatedCoin: _relatedCoin } }) + } + + startOfferPresenceMapping() + } + + const initTradeOffersWebSocket = (restarted = false) => { + let tradeOffersSocketCounter = 0 + let socketTimeout + let socketLink = `ws://NODEURL/websockets/crosschain/tradeoffers?foreignBlockchain=FOREIGN_BLOCKCHAIN&includeHistoric=true` + const socket = new WebSocket(socketLink) + socket.onopen = () => { + setTimeout(pingSocket, 50) + tradeOffersSocketCounter += 1 + } + socket.onmessage = (e) => { + e.relatedCoin = _relatedCoin + self.postMessage({ + type: 'TRADE_OFFERS', + data: e.data, + counter: tradeOffersSocketCounter, + isRestarted: restarted, + }) + tradeOffersSocketCounter += 1 + restarted = false + } + socket.onclose = () => { + clearTimeout(socketTimeout) + restartTradeOffersWebSocket() + } + socket.onerror = (e) => { + clearTimeout(socketTimeout) + } + const pingSocket = () => { + socket.send('ping') + socketTimeout = setTimeout(pingSocket, 295000) + } + } + + const initTradeBotWebSocket = (restarted = false) => { + let socketTimeout + let socketLink = `ws://NODEURL/websockets/crosschain/tradebot?foreignBlockchain=FOREIGN_BLOCKCHAIN` + const socket = new WebSocket(socketLink) + socket.onopen = () => { + setTimeout(pingSocket, 50) + } + socket.onmessage = (e) => { + e.relatedCoin = _relatedCoin + self.postMessage({ + type: 'TRADE_BOT', + data: e.data, + isRestarted: restarted, + }) + restarted = false + } + socket.onclose = () => { + clearTimeout(socketTimeout) + restartTradeBotWebSocket() + } + socket.onerror = (e) => { + clearTimeout(socketTimeout) + } + const pingSocket = () => { + socket.send('ping') + socketTimeout = setTimeout(pingSocket, 295000) + } + } + + const initTradePresenceWebSocket = (restarted = false) => { + let socketTimeout + let socketLink = `ws://NODEURL/websockets/crosschain/tradepresence` + const socket = new WebSocket(socketLink) + socket.onopen = () => { + setTimeout(pingSocket, 50) + } + socket.onmessage = (e) => { + tradePresenceTxns = JSON.parse(e.data) + processOffersWithPresence() + restarted = false + } + socket.onclose = () => { + clearTimeout(socketTimeout) + restartTradePresenceWebSocket() + } + socket.onerror = (e) => { + clearTimeout(socketTimeout) + } + const pingSocket = () => { + socket.send('ping') + socketTimeout = setTimeout(pingSocket, 295000) + } + } + + const restartTradePresenceWebSocket = () => { + setTimeout(() => initTradePresenceWebSocket(true), 50) + } + + const restartTradeOffersWebSocket = () => { + setTimeout(() => initTradeOffersWebSocket(true), 50) + } + + const restartTradeBotWebSocket = () => { + setTimeout(() => initTradeBotWebSocket(true), 50) + } + + initTradeOffersWebSocket() + initTradePresenceWebSocket() + initTradeBotWebSocket() + } + + updateAccountBalance() { + clearTimeout(this.updateAccountBalanceTimeout) + parentEpml.request('apiCall', { + url: `/addresses/balance/${this.selectedAddress.address}?apiKey=${this.getApiKey()}`, + }) + .then((res) => { + this.listedCoins.get("QORTAL").balance = res + this.updateAccountBalanceTimeout = setTimeout(() => this.updateAccountBalance(), 10000) + }) + } + + _checkBuyAmount(e) { + const targetAmount = e.target.value + const target = e.target + + if (targetAmount.length === 0) { + this.isValidAmount = false + this.sellBtnDisable = true + e.target.blur() + e.target.focus() + e.target.invalid = true + } else { + this.buyBtnDisable = false + } + + e.target.blur() + e.target.focus() + + e.target.validityTransform = (newValue, nativeValidity) => { + if (newValue.includes('-') === true) { + this.buyBtnDisable = true + return { + valid: false, + } + } else if (!nativeValidity.valid) { + if (newValue.includes('.') === true) { + let myAmount = newValue.split('.') + if (myAmount[1].length > 8) { + this.buyBtnDisable = true + } else { + this.buyBtnDisable = false + return { + valid: true, + } + } + } + } else { + this.buyBtnDisable = false + } + } + } + + checkTradeBotAmount(e) { + const targetAmount = e.target.value + const target = e.target + this.autoBuyWarning = false + + if (targetAmount.length === 0) { + this.isValidAmount = false + this.autoBuyBtnDisable = true + this.autoBuyWarning = false + e.target.blur() + e.target.focus() + e.target.invalid = true + } else { + const buyTradeBotAmountInput = this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'QortAmountInput').value + const buyTradeBotPriceInput = this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'PriceInput').value + const buyTradeBotTotalInput = this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'TotalInput').value + const checkFunds = this.round(parseFloat(buyTradeBotAmountInput) * parseFloat(buyTradeBotPriceInput)) + const myFunds = this.round(parseFloat(this.listedCoins.get(this.selectedCoin).balance)) + if (Number(myFunds) > Number(checkFunds)) { + this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'TotalInput').value = this.round(parseFloat(buyTradeBotAmountInput) * parseFloat(buyTradeBotPriceInput)) + this.autoBuyBtnDisable = false + this.autoBuyWarning = false + } else { + this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'TotalInput').value = this.round(parseFloat(buyTradeBotAmountInput) * parseFloat(buyTradeBotPriceInput)) + this.autoBuyBtnDisable = true + this.autoBuyWarning = true + } + } + + e.target.blur() + e.target.focus() + + e.target.validityTransform = (newValue, nativeValidity) => { + if (newValue.includes('-') === true) { + this.autoBuyBtnDisable = true + this.autoBuyWarning = false + return { + valid: false, + } + } else if (!nativeValidity.valid) { + if (newValue.includes('.') === true) { + let myAmount = newValue.split('.') + if (myAmount[1].length > 8) { + this.autoBuyBtnDisable = true + this.autoBuyWarning = false + } else { + const buyTradeBotAmountInput = this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'QortAmountInput').value + const buyTradeBotPriceInput = this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'PriceInput').value + const buyTradeBotTotalInput = this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'TotalInput').value + const checkFunds = this.round(parseFloat(buyTradeBotAmountInput) * parseFloat(buyTradeBotPriceInput)) + const myFunds = this.round(parseFloat(this.listedCoins.get(this.selectedCoin).balance)) + if (Number(myFunds) > Number(checkFunds)) { + this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'TotalInput').value = this.round(parseFloat(buyTradeBotAmountInput) * parseFloat(buyTradeBotPriceInput)) + this.autoBuyBtnDisable = false + this.autoBuyWarning = false + } else { + this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'TotalInput').value = this.round(parseFloat(buyTradeBotAmountInput) * parseFloat(buyTradeBotPriceInput)) + this.autoBuyBtnDisable = true + this.autoBuyWarning = true + } + return { + valid: true, + } + } + } + } else { + const buyTradeBotAmountInput = this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'QortAmountInput').value + const buyTradeBotPriceInput = this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'PriceInput').value + const buyTradeBotTotalInput = this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'TotalInput').value + const checkFunds = this.round(parseFloat(buyTradeBotAmountInput) * parseFloat(buyTradeBotPriceInput)) + const myFunds = this.round(parseFloat(this.listedCoins.get(this.selectedCoin).balance)) + if (Number(myFunds) > Number(checkFunds)) { + this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'TotalInput').value = this.round(parseFloat(buyTradeBotAmountInput) * parseFloat(buyTradeBotPriceInput)) + this.autoBuyBtnDisable = false + this.autoBuyWarning = false + } else { + this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'TotalInput').value = this.round(parseFloat(buyTradeBotAmountInput) * parseFloat(buyTradeBotPriceInput)) + this.autoBuyBtnDisable = true + this.autoBuyWarning = true + } + } + } + } + + checkTradeBotTotalAmount(e) { + const targetAmount = e.target.value + const target = e.target + this.autoBuyWarning = false + + if (targetAmount.length === 0) { + this.isValidAmount = false + this.autoBuyBtnDisable = true + this.autoBuyWarning = false + e.target.blur() + e.target.focus() + e.target.invalid = true + } else { + const buyTradeBotAmountInput = this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'QortAmountInput').value + const buyTradeBotPriceInput = this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'PriceInput').value + const buyTradeBotTotalInput = this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'TotalInput').value + const checkFunds = this.round(parseFloat(buyTradeBotAmountInput) * parseFloat(buyTradeBotPriceInput)) + const myFunds = this.round(parseFloat(this.listedCoins.get(this.selectedCoin).balance)) + if (Number(myFunds) > Number(checkFunds)) { + this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'QortAmountInput').value = this.round(parseFloat(buyTradeBotTotalInput) / parseFloat(buyTradeBotPriceInput)) + this.autoBuyBtnDisable = false + this.autoBuyWarning = false + } else { + this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'QortAmountInput').value = this.round(parseFloat(buyTradeBotTotalInput) / parseFloat(buyTradeBotPriceInput)) + this.autoBuyBtnDisable = true + this.autoBuyWarning = true + } + } + + e.target.blur() + e.target.focus() + + e.target.validityTransform = (newValue, nativeValidity) => { + if (newValue.includes('-') === true) { + this.autoBuyBtnDisable = true + this.autoBuyWarning = false + return { + valid: false, + } + } else if (!nativeValidity.valid) { + if (newValue.includes('.') === true) { + let myAmount = newValue.split('.') + if (myAmount[1].length > 8) { + this.autoBuyBtnDisable = true + this.autoBuyWarning = false + } else { + const buyTradeBotAmountInput = this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'QortAmountInput').value + const buyTradeBotPriceInput = this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'PriceInput').value + const buyTradeBotTotalInput = this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'TotalInput').value + const checkFunds = this.round(parseFloat(buyTradeBotAmountInput) * parseFloat(buyTradeBotPriceInput)) + const myFunds = this.round(parseFloat(this.listedCoins.get(this.selectedCoin).balance)) + if (Number(myFunds) > Number(checkFunds)) { + this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'QortAmountInput').value = this.round(parseFloat(buyTradeBotTotalInput) / parseFloat(buyTradeBotPriceInput)) + this.autoBuyBtnDisable = false + this.autoBuyWarning = false + } else { + this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'QortAmountInput').value = this.round(parseFloat(buyTradeBotTotalInput) / parseFloat(buyTradeBotPriceInput)) + this.autoBuyBtnDisable = true + this.autoBuyWarning = true + } + return { + valid: true, + } + } + } + } else { + const buyTradeBotAmountInput = this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'QortAmountInput').value + const buyTradeBotPriceInput = this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'PriceInput').value + const buyTradeBotTotalInput = this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'TotalInput').value + const checkFunds = this.round(parseFloat(buyTradeBotAmountInput) * parseFloat(buyTradeBotPriceInput)) + const myFunds = this.round(parseFloat(this.listedCoins.get(this.selectedCoin).balance)) + if (Number(myFunds) > Number(checkFunds)) { + this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'QortAmountInput').value = this.round(parseFloat(buyTradeBotTotalInput) / parseFloat(buyTradeBotPriceInput)) + this.autoBuyBtnDisable = false + this.autoBuyWarning = false + } else { + this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'QortAmountInput').value = this.round(parseFloat(buyTradeBotTotalInput) / parseFloat(buyTradeBotPriceInput)) + this.autoBuyBtnDisable = true + this.autoBuyWarning = true + } + } + } + } + + async tradeFee() { + const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] + const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port + const url = `${nodeUrl}/transactions/unitfee?txType=DEPLOY_AT` + await fetch(url).then((response) => { + if (response.ok) { + return response.json() + } + return Promise.reject(response) + }).then((json) => { + this.listedCoins.get("QORTAL").tradeFee = (Number(json) + 100000) / 1e8 + }) + } + + clearTradeBotForm() { + this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'QortAmountInput').value = this.initialAmount + this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'PriceInput').value = this.initialAmount + this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'TotalInput').value = this.initialAmount + this.autoBuyBtnDisable = true + } + + inlineWorker(passedFunction, modifiers) { + let parsedFunction = `` + + modifiers.forEach((modifier) => { + let regex = new RegExp(modifier.searchValue, 'g') + parsedFunction = parsedFunction.length === 0 ? `(function ${passedFunction.toString().trim().replace(regex, modifier.replaceValue)})()` : parsedFunction.toString().trim().replace(regex, modifier.replaceValue) + }) + + const workerUrl = URL.createObjectURL(new Blob([parsedFunction], { type: 'text/javascript' })) + const worker = new Worker(workerUrl) + URL.revokeObjectURL(workerUrl) + return worker + } + + clearPaneCache() { + this._openOrdersGrid.clearCache() + this._myOrdersGrid.clearCache() + } + + createConnection() { + if (workers.get(this.selectedCoin).tradesConnectedWorker !== null) { + this.isLoadingHistoricTrades = false + this.isLoadingOpenTrades = false + return + } + + const handleMessage = (message) => { + switch (message.type) { + case 'TRADE_OFFERS': + if (!message.isRestarted) { + this.listedCoins.get(this.selectedCoin).tradeOffersSocketCounter = message.counter + this.processTradeOffers(JSON.parse(message.data)) + this.listedCoins.get(this.selectedCoin).tradeOffersSocketCounter === 1 ? this.clearPaneCache() : null + workers.get(this.selectedCoin).tradesConnectedWorker.postMessage(this.listedCoins.get(this.selectedCoin).openOrders) + workers.get(this.selectedCoin).tradesConnectedWorker.postMessage({ type: "open_orders", content: this.listedCoins.get(this.selectedCoin).openOrders }) + } + return null + case 'TRADE_BOT': + if (!message.isRestarted) this.processTradeBotStates(JSON.parse(message.data)) + return null + case 'PRESENCE': + this.tradesPresenceCleaned = [] + this.listedCoins.get(message.data.relatedCoin).openOrders = message.data.offers + this.tradesPresenceCleaned = message.data.filteredOffers + + const filterPresenceList = () => { + this.blockedTradesList.forEach(item => { + const toDelete = item.recipient + this.tradesPresenceCleaned = this.tradesPresenceCleaned.filter(el => { + return el.qortalCreatorTradeAddress !== toDelete + }) + }) + } + + filterPresenceList() + this.listedCoins.get(message.data.relatedCoin).openFilteredOrders = this.tradesPresenceCleaned + this.reRenderOpenFilteredOrders() + return null + default: + break + } + } + + let myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] + let nodeUrl = myNode.domain + ':' + myNode.port + + const modifiers = [ + { searchValue: 'NODEURL', replaceValue: nodeUrl }, + { searchValue: 'FOREIGN_BLOCKCHAIN', replaceValue: this.selectedCoin }, + ] + + workers.get(this.selectedCoin).tradesConnectedWorker = this.inlineWorker(this.initSocket, modifiers) + + workers.get(this.selectedCoin).tradesConnectedWorker.addEventListener('message', function (event) { handleMessage(event.data) }, { passive: true }) + + workers.get(this.selectedCoin).tradesConnectedWorker.postMessage({ type: "set_coin", content: this.selectedCoin }) + } + + async getNewBlockedTrades() { + const unconfirmedTransactionsList = async () => { + const myNodeInf = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] + const myNodeUrl = myNodeInf.protocol + '://' + myNodeInf.domain + ':' + myNodeInf.port + const unconfirmedTransactionslUrl = `${myNodeUrl}/transactions/unconfirmed?txType=MESSAGE&limit=0&reverse=true` + + var addBlockedTrades = JSON.parse(localStorage.getItem('failedTrades') || '[]') + + await fetch(unconfirmedTransactionslUrl).then(response => { + return response.json() + }).then(data => { + data.map(item => { + const unconfirmedNessageTimeDiff = Date.now() - item.timestamp + const timeOneHour = 60 * 60 * 1000 + if (Number(unconfirmedNessageTimeDiff) > Number(timeOneHour)) { + const addBlocked = { + timestamp: item.timestamp, + recipient: item.recipient + } + addBlockedTrades.push(addBlocked) + } + }) + localStorage.setItem("failedTrades", JSON.stringify(addBlockedTrades)) + this.blockedTradesList = JSON.parse(localStorage.getItem('failedTrades') || '[]') + }) + } + + await unconfirmedTransactionsList() + + const filterUnconfirmedTransactionsList = async () => { + let cleanBlockedTrades = this.blockedTradesList.reduce((newArray, cut) => { + if (!newArray.some(obj => obj.recipient === cut.recipient)) { + newArray.push(cut) + } + return newArray + }, []) + localStorage.setItem("failedTrades", JSON.stringify(cleanBlockedTrades)) + this.blockedTradesList = JSON.parse(localStorage.getItem("failedTrades") || "[]") + } + + await filterUnconfirmedTransactionsList() + } + + // Standard functions + getApiKey() { + const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] return myNode.apiKey - } + } - clearTradeBotForm() { - this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'QortAmountInput').value = this.initialAmount - this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'PriceInput').value = this.initialAmount - this.shadowRoot.getElementById('autoBuy' + this.listedCoins.get(this.selectedCoin).coinCode + 'TotalInput').value = this.initialAmount - this.autoBuyBtnDisable = true - } + isEmptyArray(arr) { + if (!arr) { return true } + return arr.length === 0 + } - isEmptyArray(arr) { - if (!arr) { - return true - } - return arr.length === 0 - } - - round(number) { + round(number) { return (Math.round(parseFloat(number) * 1e8) / 1e8).toFixed(8) - } - - inlineWorker(passedFunction, modifiers) { - let parsedFunction = `` - - modifiers.forEach((modifier) => { - let regex = new RegExp(modifier.searchValue, 'g') - parsedFunction = parsedFunction.length === 0 ? `(function ${passedFunction.toString().trim().replace(regex, modifier.replaceValue)})()` : parsedFunction.toString().trim().replace(regex, modifier.replaceValue) - }) - - const workerUrl = URL.createObjectURL(new Blob([parsedFunction], { type: 'text/javascript' })) - const worker = new Worker(workerUrl) - URL.revokeObjectURL(workerUrl) - return worker - } - - clearPaneCache() { - this._openOrdersGrid.clearCache() - this._myOrdersGrid.clearCache() - } - - createConnection() { - if (workers.get(this.selectedCoin).tradesConnectedWorker !== null) { - this.isLoadingHistoricTrades = false - this.isLoadingOpenTrades = false - return - } - - const handleMessage = (message) => { - switch (message.type) { - case 'TRADE_OFFERS': - if (!message.isRestarted) { - this.listedCoins.get(this.selectedCoin).tradeOffersSocketCounter = message.counter - this.processTradeOffers(JSON.parse(message.data)) - this.listedCoins.get(this.selectedCoin).tradeOffersSocketCounter === 1 ? this.clearPaneCache() : null - workers.get(this.selectedCoin).tradesConnectedWorker.postMessage(this.listedCoins.get(this.selectedCoin).openOrders) - workers.get(this.selectedCoin).tradesConnectedWorker.postMessage({ type: "open_orders", content: this.listedCoins.get(this.selectedCoin).openOrders }) - } - return null - case 'TRADE_BOT': - if (!message.isRestarted) this.processTradeBotStates(JSON.parse(message.data)) - return null - case 'PRESENCE': - this.tradesPresenceCleaned = [] - this.listedCoins.get(message.data.relatedCoin).openOrders = message.data.offers - this.tradesPresenceCleaned = message.data.filteredOffers - - const filterPresenceList = () => { - this.blockedTradesList.forEach(item => { - const toDelete = item.recipient - this.tradesPresenceCleaned = this.tradesPresenceCleaned.filter(el => { - return el.qortalCreatorTradeAddress !== toDelete - }) - }) - } - - filterPresenceList() - this.listedCoins.get(message.data.relatedCoin).openFilteredOrders = this.tradesPresenceCleaned - this.reRenderOpenFilteredOrders() - return null - default: - break - } - } - - let myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] - let nodeUrl = myNode.domain + ':' + myNode.port - - const modifiers = [ - { searchValue: 'NODEURL', replaceValue: nodeUrl }, - { searchValue: 'FOREIGN_BLOCKCHAIN', replaceValue: this.selectedCoin }, - ] - - workers.get(this.selectedCoin).tradesConnectedWorker = this.inlineWorker(this.initSocket, modifiers) - - workers.get(this.selectedCoin).tradesConnectedWorker.addEventListener('message', function (event) { handleMessage(event.data) }, { passive: true }) - - workers.get(this.selectedCoin).tradesConnectedWorker.postMessage({ type: "set_coin", content: this.selectedCoin }) - } - - async getNewBlockedTrades() { - const unconfirmedTransactionsList = async () => { - const myNodeInf = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] - const myNodeUrl = myNodeInf.protocol + '://' + myNodeInf.domain + ':' + myNodeInf.port - const unconfirmedTransactionslUrl = `${myNodeUrl}/transactions/unconfirmed?txType=MESSAGE&limit=0&reverse=true` - - var addBlockedTrades = JSON.parse(localStorage.getItem('failedTrades') || '[]') - - await fetch(unconfirmedTransactionslUrl).then(response => { - return response.json() - }).then(data => { - data.map(item => { - const unconfirmedNessageTimeDiff = Date.now() - item.timestamp - const timeOneHour = 60 * 60 * 1000 - if (Number(unconfirmedNessageTimeDiff) > Number(timeOneHour)) { - const addBlocked = { - timestamp: item.timestamp, - recipient: item.recipient - } - addBlockedTrades.push(addBlocked) - } - }) - localStorage.setItem("failedTrades", JSON.stringify(addBlockedTrades)) - this.blockedTradesList = JSON.parse(localStorage.getItem('failedTrades') || '[]') - }) - } - - await unconfirmedTransactionsList() - - const filterUnconfirmedTransactionsList = async () => { - let cleanBlockedTrades = this.blockedTradesList.reduce((newArray, cut) => { - if(!newArray.some(obj => obj.recipient === cut.recipient)) { - newArray.push(cut) - } - return newArray - },[]) - localStorage.setItem("failedTrades", JSON.stringify(cleanBlockedTrades)) - this.blockedTradesList = JSON.parse(localStorage.getItem("failedTrades") || "[]") - } - - await filterUnconfirmedTransactionsList() - } + } } -window.customElements.define('trade-bot-portal', TradeBotPortal) +window.customElements.define('trade-bot-portal', TradeBotPortal) \ No newline at end of file diff --git a/plugins/plugins/core/trade-portal/charts/arrr-charts.js b/plugins/plugins/core/trade-portal/charts/arrr-charts.js index 68c0e618..20f16fed 100644 --- a/plugins/plugins/core/trade-portal/charts/arrr-charts.js +++ b/plugins/plugins/core/trade-portal/charts/arrr-charts.js @@ -1,7 +1,6 @@ -import {css, html, LitElement} from 'lit' -import {Epml} from '../../../../epml.js' -import {get, registerTranslateConfig, translate, use} from '../../../../../core/translate' -import '@polymer/paper-dialog/paper-dialog.js' +import { html, LitElement } from 'lit' +import { Epml } from '../../../../epml' +import { highChartStyles } from '../../components/plugins-css' import * as Highcharts from 'highcharts' import Exporting from 'highcharts/modules/exporting' import StockChart from 'highcharts/modules/stock' @@ -11,18 +10,21 @@ import 'highcharts/modules/boost.js' import 'highcharts/modules/data.js' import 'highcharts/modules/export-data.js' import 'highcharts/modules/offline-exporting.js' +import '@polymer/paper-dialog/paper-dialog.js' +// Multi language support +import { get, registerTranslateConfig, translate, use } from '../../../../../core/translate' registerTranslateConfig({ - loader: lang => fetch(`/language/${lang}.json`).then(res => res.json()) + loader: lang => fetch(`/language/${lang}.json`).then(res => res.json()) }) +const parentEpml = new Epml({ type: 'WINDOW', source: window.parent }) + Exporting(Highcharts) StockChart(Highcharts) let arrrChartDialog -const parentEpml = new Epml({ type: 'WINDOW', source: window.parent }) - class ArrrCharts extends LitElement { static get properties() { return { @@ -33,43 +35,7 @@ class ArrrCharts extends LitElement { } static get styles() { - return css` - .loadingContainer { - height: 100%; - width: 100%; - } - - .trades-chart { - color: var(--black); - background: var(--white); - border: 1px solid var(--black); - border-radius: 25px; - padding: 15px; - } - - .chart-container { - margin: auto; - color: var(--black); - text-align: center; - padding: 15px; - height: 30vh; - width: 80vw; - } - - .chart-info-wrapper { - background: transparent; - height: 38vh; - width: 83vw; - overflow: auto; - } - - .chart-loading-wrapper { - color: var(--black); - background: var(--white); - border: 1px solid var(--black); - border-radius: 15px; - } - ` + return [highChartStyles] } constructor() { @@ -199,6 +165,17 @@ class ArrrCharts extends LitElement { } } + // Standard functions + getApiKey() { + const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] + return myNode.apiKey + } + + isEmptyArray(arr) { + if (!arr) { return true } + return arr.length === 0 + } + round(number) { return (Math.round(parseFloat(number) * 1e8) / 1e8).toFixed(8) } @@ -208,5 +185,4 @@ window.customElements.define('arrr-charts', ArrrCharts) const chartsarrr = document.createElement('arrr-charts') arrrChartDialog = document.body.appendChild(chartsarrr) - -export default arrrChartDialog +export default arrrChartDialog \ No newline at end of file diff --git a/plugins/plugins/core/trade-portal/charts/btc-charts.js b/plugins/plugins/core/trade-portal/charts/btc-charts.js index 1ec4136c..19f2a121 100644 --- a/plugins/plugins/core/trade-portal/charts/btc-charts.js +++ b/plugins/plugins/core/trade-portal/charts/btc-charts.js @@ -1,7 +1,6 @@ -import {css, html, LitElement} from 'lit' -import {Epml} from '../../../../epml.js' -import {get, registerTranslateConfig, translate, use} from '../../../../../core/translate' -import '@polymer/paper-dialog/paper-dialog.js' +import { html, LitElement } from 'lit' +import { Epml } from '../../../../epml' +import { highChartStyles } from '../../components/plugins-css' import * as Highcharts from 'highcharts' import Exporting from 'highcharts/modules/exporting' import StockChart from 'highcharts/modules/stock' @@ -11,18 +10,21 @@ import 'highcharts/modules/boost.js' import 'highcharts/modules/data.js' import 'highcharts/modules/export-data.js' import 'highcharts/modules/offline-exporting.js' +import '@polymer/paper-dialog/paper-dialog.js' +// Multi language support +import { get, registerTranslateConfig, translate, use } from '../../../../../core/translate' registerTranslateConfig({ - loader: lang => fetch(`/language/${lang}.json`).then(res => res.json()) + loader: lang => fetch(`/language/${lang}.json`).then(res => res.json()) }) +const parentEpml = new Epml({ type: 'WINDOW', source: window.parent }) + Exporting(Highcharts) StockChart(Highcharts) let btcChartDialog -const parentEpml = new Epml({ type: 'WINDOW', source: window.parent }) - class BtcCharts extends LitElement { static get properties() { return { @@ -33,43 +35,7 @@ class BtcCharts extends LitElement { } static get styles() { - return css` - .loadingContainer { - height: 100%; - width: 100%; - } - - .trades-chart { - color: var(--black); - background: var(--white); - border: 1px solid var(--black); - border-radius: 25px; - padding: 15px; - } - - .chart-container { - margin: auto; - color: var(--black); - text-align: center; - padding: 15px; - height: 30vh; - width: 80vw; - } - - .chart-info-wrapper { - background: transparent; - height: 38vh; - width: 83vw; - overflow: auto; - } - - .chart-loading-wrapper { - color: var(--black); - background: var(--white); - border: 1px solid var(--black); - border-radius: 15px; - } - ` + return [highChartStyles] } constructor() { @@ -200,6 +166,17 @@ class BtcCharts extends LitElement { } } + // Standard functions + getApiKey() { + const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] + return myNode.apiKey + } + + isEmptyArray(arr) { + if (!arr) { return true } + return arr.length === 0 + } + round(number) { return (Math.round(parseFloat(number) * 1e8) / 1e8).toFixed(8) } @@ -209,5 +186,4 @@ window.customElements.define('btc-charts', BtcCharts) const chartsbtc = document.createElement('btc-charts') btcChartDialog = document.body.appendChild(chartsbtc) - -export default btcChartDialog +export default btcChartDialog \ No newline at end of file diff --git a/plugins/plugins/core/trade-portal/charts/dgb-charts.js b/plugins/plugins/core/trade-portal/charts/dgb-charts.js index a78b51fe..eac814de 100644 --- a/plugins/plugins/core/trade-portal/charts/dgb-charts.js +++ b/plugins/plugins/core/trade-portal/charts/dgb-charts.js @@ -1,7 +1,6 @@ -import {css, html, LitElement} from 'lit' -import {Epml} from '../../../../epml.js' -import {get, registerTranslateConfig, translate, use} from '../../../../../core/translate' -import '@polymer/paper-dialog/paper-dialog.js' +import { html, LitElement } from 'lit' +import { Epml } from '../../../../epml' +import { highChartStyles } from '../../components/plugins-css' import * as Highcharts from 'highcharts' import Exporting from 'highcharts/modules/exporting' import StockChart from 'highcharts/modules/stock' @@ -11,18 +10,21 @@ import 'highcharts/modules/boost.js' import 'highcharts/modules/data.js' import 'highcharts/modules/export-data.js' import 'highcharts/modules/offline-exporting.js' +import '@polymer/paper-dialog/paper-dialog.js' +// Multi language support +import { get, registerTranslateConfig, translate, use } from '../../../../../core/translate' registerTranslateConfig({ - loader: lang => fetch(`/language/${lang}.json`).then(res => res.json()) + loader: lang => fetch(`/language/${lang}.json`).then(res => res.json()) }) +const parentEpml = new Epml({ type: 'WINDOW', source: window.parent }) + Exporting(Highcharts) StockChart(Highcharts) let dgbChartDialog -const parentEpml = new Epml({ type: 'WINDOW', source: window.parent }) - class DgbCharts extends LitElement { static get properties() { return { @@ -33,43 +35,7 @@ class DgbCharts extends LitElement { } static get styles() { - return css` - .loadingContainer { - height: 100%; - width: 100%; - } - - .trades-chart { - color: var(--black); - background: var(--white); - border: 1px solid var(--black); - border-radius: 25px; - padding: 15px; - } - - .chart-container { - margin: auto; - color: var(--black); - text-align: center; - padding: 15px; - height: 30vh; - width: 80vw; - } - - .chart-info-wrapper { - background: transparent; - height: 38vh; - width: 83vw; - overflow: auto; - } - - .chart-loading-wrapper { - color: var(--black); - background: var(--white); - border: 1px solid var(--black); - border-radius: 15px; - } - ` + return [highChartStyles] } constructor() { @@ -199,6 +165,17 @@ class DgbCharts extends LitElement { } } + // Standard functions + getApiKey() { + const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] + return myNode.apiKey + } + + isEmptyArray(arr) { + if (!arr) { return true } + return arr.length === 0 + } + round(number) { return (Math.round(parseFloat(number) * 1e8) / 1e8).toFixed(8) } @@ -208,5 +185,4 @@ window.customElements.define('dgb-charts', DgbCharts) const chartsdgb = document.createElement('dgb-charts') dgbChartDialog = document.body.appendChild(chartsdgb) - -export default dgbChartDialog +export default dgbChartDialog \ No newline at end of file diff --git a/plugins/plugins/core/trade-portal/charts/doge-charts.js b/plugins/plugins/core/trade-portal/charts/doge-charts.js index 01f1eecb..da008dcd 100644 --- a/plugins/plugins/core/trade-portal/charts/doge-charts.js +++ b/plugins/plugins/core/trade-portal/charts/doge-charts.js @@ -1,7 +1,6 @@ -import {css, html, LitElement} from 'lit' -import {Epml} from '../../../../epml.js' -import {get, registerTranslateConfig, translate, use} from '../../../../../core/translate' -import '@polymer/paper-dialog/paper-dialog.js' +import { html, LitElement } from 'lit' +import { Epml } from '../../../../epml' +import { highChartStyles } from '../../components/plugins-css' import * as Highcharts from 'highcharts' import Exporting from 'highcharts/modules/exporting' import StockChart from 'highcharts/modules/stock' @@ -11,18 +10,21 @@ import 'highcharts/modules/boost.js' import 'highcharts/modules/data.js' import 'highcharts/modules/export-data.js' import 'highcharts/modules/offline-exporting.js' +import '@polymer/paper-dialog/paper-dialog.js' +// Multi language support +import { get, registerTranslateConfig, translate, use } from '../../../../../core/translate' registerTranslateConfig({ - loader: lang => fetch(`/language/${lang}.json`).then(res => res.json()) + loader: lang => fetch(`/language/${lang}.json`).then(res => res.json()) }) +const parentEpml = new Epml({ type: 'WINDOW', source: window.parent }) + Exporting(Highcharts) StockChart(Highcharts) let dogeChartDialog -const parentEpml = new Epml({ type: 'WINDOW', source: window.parent }) - class DogeCharts extends LitElement { static get properties() { return { @@ -33,43 +35,7 @@ class DogeCharts extends LitElement { } static get styles() { - return css` - .loadingContainer { - height: 100%; - width: 100%; - } - - .trades-chart { - color: var(--black); - background: var(--white); - border: 1px solid var(--black); - border-radius: 25px; - padding: 15px; - } - - .chart-container { - margin: auto; - color: var(--black); - text-align: center; - padding: 15px; - height: 30vh; - width: 80vw; - } - - .chart-info-wrapper { - background: transparent; - height: 38vh; - width: 83vw; - overflow: auto; - } - - .chart-loading-wrapper { - color: var(--black); - background: var(--white); - border: 1px solid var(--black); - border-radius: 15px; - } - ` + return [highChartStyles] } constructor() { @@ -199,6 +165,17 @@ class DogeCharts extends LitElement { } } + // Standard functions + getApiKey() { + const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] + return myNode.apiKey + } + + isEmptyArray(arr) { + if (!arr) { return true } + return arr.length === 0 + } + round(number) { return (Math.round(parseFloat(number) * 1e8) / 1e8).toFixed(8) } @@ -208,5 +185,4 @@ window.customElements.define('doge-charts', DogeCharts) const chartsdoge = document.createElement('doge-charts') dogeChartDialog = document.body.appendChild(chartsdoge) - -export default dogeChartDialog +export default dogeChartDialog \ No newline at end of file diff --git a/plugins/plugins/core/trade-portal/charts/ltc-charts.js b/plugins/plugins/core/trade-portal/charts/ltc-charts.js index 6c880abc..23186b62 100644 --- a/plugins/plugins/core/trade-portal/charts/ltc-charts.js +++ b/plugins/plugins/core/trade-portal/charts/ltc-charts.js @@ -1,7 +1,6 @@ -import {css, html, LitElement} from 'lit' -import {Epml} from '../../../../epml.js' -import {get, registerTranslateConfig, translate, use} from '../../../../../core/translate' -import '@polymer/paper-dialog/paper-dialog.js' +import { html, LitElement } from 'lit' +import { Epml } from '../../../../epml' +import { highChartStyles } from '../../components/plugins-css' import * as Highcharts from 'highcharts' import Exporting from 'highcharts/modules/exporting' import StockChart from 'highcharts/modules/stock' @@ -11,18 +10,21 @@ import 'highcharts/modules/boost.js' import 'highcharts/modules/data.js' import 'highcharts/modules/export-data.js' import 'highcharts/modules/offline-exporting.js' +import '@polymer/paper-dialog/paper-dialog.js' +// Multi language support +import { get, registerTranslateConfig, translate, use } from '../../../../../core/translate' registerTranslateConfig({ - loader: lang => fetch(`/language/${lang}.json`).then(res => res.json()) + loader: lang => fetch(`/language/${lang}.json`).then(res => res.json()) }) +const parentEpml = new Epml({ type: 'WINDOW', source: window.parent }) + Exporting(Highcharts) StockChart(Highcharts) let ltcChartDialog -const parentEpml = new Epml({ type: 'WINDOW', source: window.parent }) - class LtcCharts extends LitElement { static get properties() { return { @@ -33,43 +35,7 @@ class LtcCharts extends LitElement { } static get styles() { - return css` - .loadingContainer { - height: 100%; - width: 100%; - } - - .trades-chart { - color: var(--black); - background: var(--white); - border: 1px solid var(--black); - border-radius: 25px; - padding: 15px; - } - - .chart-container { - margin: auto; - color: var(--black); - text-align: center; - padding: 15px; - height: 30vh; - width: 80vw; - } - - .chart-info-wrapper { - background: transparent; - height: 38vh; - width: 83vw; - overflow: auto; - } - - .chart-loading-wrapper { - color: var(--black); - background: var(--white); - border: 1px solid var(--black); - border-radius: 15px; - } - ` + return [highChartStyles] } constructor() { @@ -199,6 +165,17 @@ class LtcCharts extends LitElement { } } + // Standard functions + getApiKey() { + const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] + return myNode.apiKey + } + + isEmptyArray(arr) { + if (!arr) { return true } + return arr.length === 0 + } + round(number) { return (Math.round(parseFloat(number) * 1e8) / 1e8).toFixed(8) } @@ -208,5 +185,4 @@ window.customElements.define('ltc-charts', LtcCharts) const chartsltc = document.createElement('ltc-charts') ltcChartDialog = document.body.appendChild(chartsltc) - -export default ltcChartDialog +export default ltcChartDialog \ No newline at end of file diff --git a/plugins/plugins/core/trade-portal/charts/rvn-charts.js b/plugins/plugins/core/trade-portal/charts/rvn-charts.js index c878aece..d8dd4144 100644 --- a/plugins/plugins/core/trade-portal/charts/rvn-charts.js +++ b/plugins/plugins/core/trade-portal/charts/rvn-charts.js @@ -1,7 +1,6 @@ -import {css, html, LitElement} from 'lit' -import {Epml} from '../../../../epml.js' -import {get, registerTranslateConfig, translate, use} from '../../../../../core/translate' -import '@polymer/paper-dialog/paper-dialog.js' +import { html, LitElement } from 'lit' +import { Epml } from '../../../../epml' +import { highChartStyles } from '../../components/plugins-css' import * as Highcharts from 'highcharts' import Exporting from 'highcharts/modules/exporting' import StockChart from 'highcharts/modules/stock' @@ -11,18 +10,21 @@ import 'highcharts/modules/boost.js' import 'highcharts/modules/data.js' import 'highcharts/modules/export-data.js' import 'highcharts/modules/offline-exporting.js' +import '@polymer/paper-dialog/paper-dialog.js' +// Multi language support +import { get, registerTranslateConfig, translate, use } from '../../../../../core/translate' registerTranslateConfig({ - loader: lang => fetch(`/language/${lang}.json`).then(res => res.json()) + loader: lang => fetch(`/language/${lang}.json`).then(res => res.json()) }) +const parentEpml = new Epml({ type: 'WINDOW', source: window.parent }) + Exporting(Highcharts) StockChart(Highcharts) let rvnChartDialog -const parentEpml = new Epml({ type: 'WINDOW', source: window.parent }) - class RvnCharts extends LitElement { static get properties() { return { @@ -33,43 +35,7 @@ class RvnCharts extends LitElement { } static get styles() { - return css` - .loadingContainer { - height: 100%; - width: 100%; - } - - .trades-chart { - color: var(--black); - background: var(--white); - border: 1px solid var(--black); - border-radius: 25px; - padding: 15px; - } - - .chart-container { - margin: auto; - color: var(--black); - text-align: center; - padding: 15px; - height: 30vh; - width: 80vw; - } - - .chart-info-wrapper { - background: transparent; - height: 38vh; - width: 83vw; - overflow: auto; - } - - .chart-loading-wrapper { - color: var(--black); - background: var(--white); - border: 1px solid var(--black); - border-radius: 15px; - } - ` + return [highChartStyles] } constructor() { @@ -199,6 +165,17 @@ class RvnCharts extends LitElement { } } + // Standard functions + getApiKey() { + const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] + return myNode.apiKey + } + + isEmptyArray(arr) { + if (!arr) { return true } + return arr.length === 0 + } + round(number) { return (Math.round(parseFloat(number) * 1e8) / 1e8).toFixed(8) } @@ -208,5 +185,4 @@ window.customElements.define('rvn-charts', RvnCharts) const chartsrvn = document.createElement('rvn-charts') rvnChartDialog = document.body.appendChild(chartsrvn) - -export default rvnChartDialog +export default rvnChartDialog \ No newline at end of file diff --git a/plugins/plugins/core/trade-portal/trade-portal-css.js b/plugins/plugins/core/trade-portal/trade-portal-css.js deleted file mode 100644 index 31a4f6f8..00000000 --- a/plugins/plugins/core/trade-portal/trade-portal-css.js +++ /dev/null @@ -1,687 +0,0 @@ -import {css} from 'lit' - -export const tradeStyles = css` - * { - --mdc-theme-primary: rgb(3, 169, 244); - --mdc-theme-secondary: var(--mdc-theme-primary); - --mdc-theme-error: rgb(255, 89, 89); - --mdc-text-field-outlined-idle-border-color: var(--txtfieldborder); - --mdc-text-field-outlined-hover-border-color: var(--txtfieldhoverborder); - --mdc-text-field-label-ink-color: var(--black); - --mdc-text-field-ink-color: var(--black); - --mdc-select-outlined-idle-border-color: var(--txtfieldborder); - --mdc-select-outlined-hover-border-color: var(--txtfieldhoverborder); - --mdc-select-label-ink-color: var(--black); - --mdc-select-ink-color: var(--black); - --mdc-theme-surface: var(--white); - --mdc-dialog-content-ink-color: var(--black); - --mdc-dialog-shape-radius: 25px; - --paper-input-container-focus-color: var(--mdc-theme-primary); - --lumo-primary-text-color: rgb(0, 167, 245); - --lumo-primary-color-50pct: rgba(0, 167, 245, 0.5); - --lumo-primary-color-10pct: rgba(0, 167, 245, 0.1); - --lumo-primary-color: hsl(199, 100%, 48%); - --lumo-base-color: var(--white); - --lumo-body-text-color: var(--black); - --lumo-secondary-text-color: var(--sectxt); - --lumo-contrast-60pct: var(--vdicon); - --_lumo-grid-border-color: var(--border); - --_lumo-grid-secondary-border-color: var(--border2); - } - - .myhover vaadin-grid-cell-content { - cursor: pointer; - } - - .myhover vaadin-grid::part(selected-row) { - color: green; - cursor: pointer; - } - - .myhover vaadin-grid::part(focused-selected-row) { - color: green; - cursor: pointer; - } - - .myhover vaadin-grid::part(cell):hover { - cursor: pointer; - } - - .myhover vaadin-grid::part(row):hover { - color: green; - cursor: pointer; - } - - .myhover vaadin-grid::part(selected-row-cell) { - color: green; - cursor: pointer; - } - - paper-spinner-lite { - height: 30px; - width: 30px; - --paper-spinner-color: var(--mdc-theme-primary); - --paper-spinner-stroke-width: 3px; - } - - mwc-tab-bar { - --mdc-text-transform: none; - --mdc-tab-color-default: var(--black); - --mdc-tab-text-label-color-default: var(--black); - } - - #tabs-1 { - --mdc-tab-height: 42px; - border-left: 1px solid var(--tradeborder); - border-top: 1px solid var(--tradeborder); - border-right: 1px solid var(--tradeborder); - color: var(--black); - } - - #tab-buy[active] { - --mdc-theme-primary: rgba(55, 160, 51, 0.9); - } - - #tabs-1-content { - height: 100%; - padding-bottom: 10px; - } - - #tabs-1-content>div { - height: 100%; - border: 1px solid var(--tradeborder); - } - - #tabs-1-content .card { - border: none; - } - - #tabs-1-content .btn-clear { - --mdc-icon-button-size: 32px; - color: var(--black); - } - - .btn-clear-bot { - --mdc-icon-button-size: 32px; - color: var(--black); - float: right; - } - - .btn-info { - color: #03a9f4; - --mdc-icon-size: 16px; - padding-top: 3px; - } - - #tab-sell[active] { - --mdc-theme-primary: rgb(255, 89, 89); - } - - #trade-portal-page { - background: var(--white); - padding: 12px 24px; - } - - .divCard { - border: 1px solid var(--black); - padding: 1em; - box-shadow: 0 0.3px 1px 0 rgba(0, 0, 0, 0.14), 0 1px 1px -1px rgba(0, 0, 0, 0.12), 0 1px 2px 0 rgba(0, 0, 0, 0.2); - } - - h2 { - margin: 10px 0; - } - - h4 { - margin: 5px 0; - } - - p { - font-size: 14px; - line-height: 21px; - } - - .card-body { - background-color: var(--white); - display: flex; - align-items: center; - justify-content: center; - flex-direction: column; - min-height: 100vh; - margin: 0; - } - - .card-container { - background-color: var(--white); - border-radius: 5px; - color: var(--black); - padding-top: 30px; - position: relative; - width: 350px; - max-width: 100%; - text-align: center; - } - - .card-container .level { - color: #ffffff; - background-color: #03a9f4; - border-radius: 3px; - font-size: 14px; - font-weight: bold; - padding: 3px 7px; - position: absolute; - top: 30px; - left: 30px; - } - - .card-container .founder { - color: #ffffff; - background-color: #03a9f4; - border-radius: 3px; - font-size: 14px; - font-weight: bold; - padding: 3px 7px; - position: absolute; - top: 30px; - right: 30px; - } - - .card-container .round { - width: 96px; - height: 96px; - border: 1px solid #03a9f4; - border-radius: 50%; - padding: 2px; - } - - .card-container .badge { - width: 200px; - height: 135px; - border: 1px solid transparent; - border-radius: 10%; - padding: 2px; - } - - .userdata { - background-color: #1F1A36; - text-align: left; - padding: 15px; - margin-top: 30px; - } - - .userdata ul { - list-style-type: none; - margin: 0; - padding: 0; - } - - .userdata ul li { - border: 1px solid #2D2747; - border-radius: 2px; - display: inline-block; - font-size: 12px; - margin: 0 7px 7px 0; - padding: 7px; - } - - h2, - h3, - h4, - h5 { - color: var(--black); - font-weight: 400; - } - - header { - display: flex; - flex: 0 1 auto; - align-items: center; - justify-content: center; - padding: 0px 10px; - font-size: 16px; - color: var(--white); - background-color: var(--tradehead); - border-left: 1px solid var(--tradeborder); - border-top: 1px solid var(--tradeborder); - border-right: 1px solid var(--tradeborder); - min-height: 40px; - } - - p { - margin-bottom: 12px; - } - - #trade-portal { - max-width: 100vw; - margin-left: auto; - margin-right: auto; - } - - .box { - margin: 0; - padding: 0; - display: flex; - flex-flow: column; - height: 100%; - } - - .box-bot { - margin: 0; - padding: 0; - display: flex; - flex-flow: column; - height: 150px; - } - - #first-trade-section { - margin-bottom: 10px; - } - - #first-trade-section>div {} - - #second-trade-section { - margin-bottom: 10px; - } - - #second-trade-section>div {} - - #third-trade-section { - margin-bottom: 10px; - } - - #third-trade-section>div {} - - .trade-chart { - background-color: var(--white); - border: 2px #ddd solid; - text-align: center; - } - - .open-trades { - text-align: center; - } - - .open-market-container { - text-align: center; - } - - .trade-bot-container { - text-align: center; - } - - .no-last-seen { - background: rgb(255, 89, 89); - padding: 9px 1.3px; - border-radius: 50%; - width: 1rem; - margin: 0 auto; - } - - .card { - padding: 1em; - border: 1px var(--tradeborder) solid; - flex: 1 1 auto; - display: flex; - flex-flow: column; - justify-content: space-evenly; - min-height: inherit; - } - - .card-bot { - padding: 1em; - flex: 1 1 auto; - display: flex; - flex-flow: column; - justify-content: space-evenly; - width: 350px; - min-height: inherit; - } - - .cancel { - --mdc-theme-primary: rgb(255, 89, 89); - } - - .border-wrapper { - border: 1px var(--tradeborder) solid; - overflow: hidden; - } - - .amt-text { - color: var(--tradehave); - font-size: 15px; - margin-top: 5px; - margin-bottom: 12px; - } - - .exchange { - color: var(--black); - font-size: 18px; - font-weight: bold; - margin-top: 5px; - margin-bottom: 10px; - } - - .clear-button { - display: inline; - float: right; - margin-bottom: 5px; - } - - .exhcnage-text { - display: inline; - float: left; - margin-bottom: 5px; - } - - .balance-text { - display: inline; - float: right; - margin-bottom: 5px; - } - - .fee-text { - display: inline; - float: left; - margin-bottom: 5px; - } - - .tab-text { - color: var(--tradehave); - font-size: 12px; - text-align: left; - margin-top: 2px; - margin-bottom: -12px; - } - - .historic-trades { - text-align: center; - } - - .my-open-orders { - text-align: center; - } - - .my-historic-trades { - text-align: center; - } - - .buttons { - width: auto !important; - } - - .buy-button { - --mdc-theme-primary: rgba(55, 160, 51, 0.9); - } - - .sell-button { - --mdc-theme-primary: rgb(255, 89, 89); - } - - .trade-bot-button { - margin-top: 20px; - margin-bottom: 20px; - --mdc-theme-primary: rgba(55, 160, 51, 0.9); - } - - .full-width { - background-color: var(--white); - border: 2px var(--black); - height: 200px; - text-align: center; - } - - vaading-grid { - font-size: .8em; - } - - vaadin-grid-column { - flex-grow: 1; - } - - .loadingContainer { - height: 100%; - width: 100%; - } - - .loading, - .loading:after { - border-radius: 50%; - width: 5em; - height: 5em; - } - - .loading { - margin: 10px auto; - border-width: .6em; - border-style: solid; - border-color: rgba(3, 169, 244, 0.2) rgba(3, 169, 244, 0.2) rgba(3, 169, 244, 0.2) rgb(3, 169, 244); - font-size: 10px; - position: relative; - text-indent: -9999em; - transform: translateZ(0px); - animation: 1.1s linear 0s infinite normal none running loadingAnimation; - } - - mwc-select#coinSelectionMenu { - font-size: 24px; - width: 220px; - } - - mwc-select#coinSelectionMenu mwc-list-item { - line-height: 30px; - } - - .coinName::before { - content: ""; - display: inline-block; - height: 26px; - width: 45px; - position: absolute; - background-repeat: no-repeat; - background-size: cover; - left: 10px; - top: 10px; - } - - .btc.coinName:before { - background-image: url('/img/qortbtc.png'); - } - - .ltc.coinName:before { - background-image: url('/img/qortltc.png'); - } - - .doge.coinName:before { - background-image: url('/img/qortdoge.png'); - } - - .dgb.coinName:before { - background-image: url('/img/qortdgb.png'); - } - - .rvn.coinName:before { - background-image: url('/img/qortrvn.png'); - } - - .arrr.coinName:before { - background-image: url('/img/qortarrr.png'); - } - - .coinName { - display: inline-block; - height: 26px; - padding-left: 45px; - } - - .warning-text { - animation: blinker 1.5s linear infinite; - display: inline; - float: left; - margin-bottom: 5px; - color: rgb(255, 89, 89); - } - - .warning-bot-text { - animation: blinker 1.5s linear infinite; - display: inline; - text-align: center; - color: rgb(255, 89, 89); - } - - .red { - --mdc-theme-primary: #F44336; - } - - @-webkit-keyframes loadingAnimation { - 0% { - -webkit-transform: rotate(0deg); - transform: rotate(0deg); - } - - 100% { - -webkit-transform: rotate(360deg); - transform: rotate(360deg); - } - } - - @keyframes loadingAnimation { - 0% { - -webkit-transform: rotate(0deg); - transform: rotate(0deg); - } - - 100% { - -webkit-transform: rotate(360deg); - transform: rotate(360deg); - } - } - - @keyframes blinker { - 50% { - opacity: 0; - } - } - - paper-dialog.info { - width: 100%; - max-width: 75vw; - height: 100%; - max-height: 50vh; - background-color: var(--white); - color: var(--black); - border: 1px solid var(--black); - border-radius: 15px; - line-height: 1.6; - overflow-y: auto; - } - - .actions { - display: flex; - justify-content: space-between; - padding: 0 1em; - margin: 12px 0 -6px 0; - } - - .close-icon { - font-size: 36px; - } - - .close-icon:hover { - cursor: pointer; - opacity: .6; - } - - .setpass-wrapper { - width: 100%; - min-width: 400px; - max-width: 450px; - text-align: center; - background: var(--white); - border: 1px solid var(--black); - border-radius: 15px; - padding: 10px 10px 0px; - box-shadow: 0px 10px 15px rgba(0, 0, 0, 0.1); - } - - .lock-wrapper { - width: 100%; - height: 100%; - min-width: 600px; - max-width: 600px; - min-height: 400px; - max-height: 400px; - text-align: center; - background: url("/img/qortal-lock.jpg"); - border: 1px solid var(--black); - border-radius: 25px; - padding: 10px 10px 0px; - } - - .text-wrapper { - width: 100%; - height: 100%; - min-width: 280px; - max-width: 280px; - min-height: 64px; - max-height: 64px; - text-align: center; - margin-left: 35px; - margin-top: 125px; - overflow: hidden; - } - - .lock-title-white { - font-family: 'magistralbold'; - font-weight: 700; - font-size: 26px; - line-height: 32px; - color: #ffffff; - } - - .lock-title-red { - font-family: 'magistralbold'; - font-weight: 700; - font-size: 26px; - line-height: 32px; - color: #df3636; - } - - @media (min-width: 701px) { - * {} - - #trade-portal {} - - #first-trade-section { - display: grid; - grid-template-columns: 1fr 1fr 2fr; - grid-auto-rows: max(450px); - column-gap: 0.5em; - row-gap: 0.4em; - justify-items: stretch; - align-items: stretch; - margin-bottom: 10px; - } - - #second-trade-section { - display: grid; - grid-template-columns: 2fr 1fr; - grid-auto-rows: max(450px); - column-gap: 0.5em; - row-gap: 0.4em; - justify-items: stretch; - align-items: stretch; - margin-bottom: 10px; - } - - #third-trade-section { - display: grid; - grid-template-columns: 1fr 2fr 1fr; - grid-auto-rows: max(200px); - column-gap: 0.5em; - row-gap: 0.4em; - justify-items: stretch; - align-items: stretch; - margin-bottom: 10px; - } - } -` \ No newline at end of file diff --git a/plugins/plugins/core/trade-portal/trade-portal.src.js b/plugins/plugins/core/trade-portal/trade-portal.src.js index a8405c55..d122b0df 100644 --- a/plugins/plugins/core/trade-portal/trade-portal.src.js +++ b/plugins/plugins/core/trade-portal/trade-portal.src.js @@ -1,11 +1,18 @@ -import {html, LitElement} from 'lit' -import {render} from 'lit/html.js' -import {Epml} from '../../../epml.js' +import { html, LitElement } from 'lit' +import { render } from 'lit/html.js' +import { Epml } from '../../../epml' +import { decryptData, encryptData } from '../../../../core/src/lockScreen' +import { tradePortalStyles } from '../components/plugins-css' import isElectron from 'is-electron' -import {get, registerTranslateConfig, translate, use} from '../../../../core/translate' -import Base58 from '../../../../crypto/api/deps/Base58.js' -import {decryptData, encryptData} from '../../../../core/src/lockScreen.js' -import {tradeStyles} from './trade-portal-css.js' +import chartsbtc from './charts/btc-charts' +import chartsltc from './charts/ltc-charts' +import chartsdoge from './charts/doge-charts' +import chartsdgb from './charts/dgb-charts' +import chartsrvn from './charts/rvn-charts' +import chartsarrr from './charts/arrr-charts' +import Base58 from '../../../../crypto/api/deps/Base58' +import '../components/TradeInfoView' +import '../components/TraderInfoView' import '@material/mwc-button' import '@material/mwc-textfield' import '@material/mwc-icon' @@ -23,17 +30,11 @@ import '@polymer/paper-spinner/paper-spinner-lite.js' import '@vaadin/grid' import '@vaadin/grid/vaadin-grid-sorter' import '@vaadin/password-field' -import chartsbtc from './charts/btc-charts.js' -import chartsltc from './charts/ltc-charts.js' -import chartsdoge from './charts/doge-charts.js' -import chartsdgb from './charts/dgb-charts.js' -import chartsrvn from './charts/rvn-charts.js' -import chartsarrr from './charts/arrr-charts.js' -import '../components/TraderInfoView.js' -import '../components/TradeInfoView.js' +// Multi language support +import { get, registerTranslateConfig, translate, use } from '../../../../core/translate' registerTranslateConfig({ - loader: lang => fetch(`/language/${lang}.json`).then(res => res.json()) + loader: lang => fetch(`/language/${lang}.json`).then(res => res.json()) }) const parentEpml = new Epml({ type: 'WINDOW', source: window.parent }) @@ -41,2205 +42,2221 @@ const parentEpml = new Epml({ type: 'WINDOW', source: window.parent }) let workers = new Map() class TradePortal extends LitElement { - static get properties() { - return { - selectedAddress: { type: Object }, - config: { type: Object }, - listedCoins: { type: Map }, - nodeInfo: { type: Array }, - blockedTradesList: { type: Array }, - tradesPresenceCleaned: { type: Array }, - sellBtnDisable: { type: Boolean }, - isSellLoading: { type: Boolean }, - isBuyLoading: { type: Boolean }, - buyBtnDisable: { type: Boolean }, - autoBuyWarning: { type: Boolean }, - autoBuyBtnDisable: { type: Boolean }, - autoBuyBotDisable: { type: Boolean }, - initialAmount: { type: Number }, - cancelBtnDisable: { type: Boolean }, - cancelStuckOfferBtnDisable: { type: Boolean }, - selectedCoin: { type: String }, - isLoadingHistoricTrades: { type: Boolean }, - isLoadingOpenTrades: { type: Boolean }, - isLoadingMyOpenOrders: { type: Boolean }, - showGetWalletBance: { type: Boolean }, - theme: { type: String, reflect: true }, - btcWallet: { type: String }, - ltcWallet: { type: String }, - dogeWallet: { type: String }, - dgbWallet: { type: String }, - rvnWallet: { type: String }, - arrrWallet: { type: String }, - arrrWalletAddress: { type: String }, - qortbtc: { type: Number }, - qortltc: { type: Number }, - qortdoge: { type: Number }, - qortdgb: { type: Number }, - qortrvn: { type: Number }, - qortarrr: { type: Number }, - btcqort: { type: Number }, - ltcqort: { type: Number }, - dogeqort: { type: Number }, - dgbqort: { type: Number }, - rvnqort: { type: Number }, - arrrqort: { type: Number }, - qortRatio: {type: Number}, - tradeSalt: { type: String }, - tradeStorageData: { type: String }, - tradeLockScreenPass: { type: String }, - tradeLockScreenSet: { type: String }, - tradeLockPass: { type: String }, - tradeLockSet: { type: String }, - myTradeLockScreenPass: { type: String }, - myTradeLockScreenSet: { type: String }, - tradeHelperMessage: { type: String } - } - } + static get properties() { + return { + selectedAddress: { type: Object }, + config: { type: Object }, + listedCoins: { type: Map }, + nodeInfo: { type: Array }, + blockedTradesList: { type: Array }, + tradesPresenceCleaned: { type: Array }, + sellBtnDisable: { type: Boolean }, + isSellLoading: { type: Boolean }, + isBuyLoading: { type: Boolean }, + buyBtnDisable: { type: Boolean }, + autoBuyWarning: { type: Boolean }, + autoBuyBtnDisable: { type: Boolean }, + autoBuyBotDisable: { type: Boolean }, + initialAmount: { type: Number }, + cancelBtnDisable: { type: Boolean }, + cancelStuckOfferBtnDisable: { type: Boolean }, + selectedCoin: { type: String }, + isLoadingHistoricTrades: { type: Boolean }, + isLoadingOpenTrades: { type: Boolean }, + isLoadingMyOpenOrders: { type: Boolean }, + showGetWalletBance: { type: Boolean }, + theme: { type: String, reflect: true }, + btcWallet: { type: String }, + ltcWallet: { type: String }, + dogeWallet: { type: String }, + dgbWallet: { type: String }, + rvnWallet: { type: String }, + arrrWallet: { type: String }, + arrrWalletAddress: { type: String }, + qortbtc: { type: Number }, + qortltc: { type: Number }, + qortdoge: { type: Number }, + qortdgb: { type: Number }, + qortrvn: { type: Number }, + qortarrr: { type: Number }, + btcqort: { type: Number }, + ltcqort: { type: Number }, + dogeqort: { type: Number }, + dgbqort: { type: Number }, + rvnqort: { type: Number }, + arrrqort: { type: Number }, + qortRatio: { type: Number }, + tradeSalt: { type: String }, + tradeStorageData: { type: String }, + tradeLockScreenPass: { type: String }, + tradeLockScreenSet: { type: String }, + tradeLockPass: { type: String }, + tradeLockSet: { type: String }, + myTradeLockScreenPass: { type: String }, + myTradeLockScreenSet: { type: String }, + tradeHelperMessage: { type: String } + } + } - static get styles() { - return [tradeStyles] - } + static get styles() { + return [tradePortalStyles] + } - constructor() { - super() - let qortal = { - name: "QORTAL", - balance: "0", - coinCode: "QORT", - coinAmount: this.amountString, - tradeFee: "0.02" - } + constructor() { + super() + let qortal = { + name: "QORTAL", + balance: "0", + coinCode: "QORT", + coinAmount: this.amountString, + tradeFee: "0.02" + } - let bitcoin = { - name: "BITCOIN", - balance: "0", - coinCode: "BTC", - openOrders: [], - openFilteredOrders: [], - historicTrades: [], - myOrders: [], - myHistoricTrades: [], - myOfferingOrders: [], - openTradeOrders: null, - tradeOffersSocketCounter: 1, - coinAmount: this.amountString, - tradeFee: "~0.0001" - } + let bitcoin = { + name: "BITCOIN", + balance: "0", + coinCode: "BTC", + openOrders: [], + openFilteredOrders: [], + historicTrades: [], + myOrders: [], + myHistoricTrades: [], + myOfferingOrders: [], + openTradeOrders: null, + tradeOffersSocketCounter: 1, + coinAmount: this.amountString, + tradeFee: "~0.0001" + } - let litecoin = { - name: "LITECOIN", - balance: "0", - coinCode: "LTC", - openOrders: [], - openFilteredOrders: [], - historicTrades: [], - myOrders: [], - myHistoricTrades: [], - myOfferingOrders: [], - openTradeOrders: null, - tradeOffersSocketCounter: 1, - coinAmount: this.amountString, - tradeFee: "~0.00005" - } + let litecoin = { + name: "LITECOIN", + balance: "0", + coinCode: "LTC", + openOrders: [], + openFilteredOrders: [], + historicTrades: [], + myOrders: [], + myHistoricTrades: [], + myOfferingOrders: [], + openTradeOrders: null, + tradeOffersSocketCounter: 1, + coinAmount: this.amountString, + tradeFee: "~0.00005" + } - let dogecoin = { - name: "DOGECOIN", - balance: "0", - coinCode: "DOGE", - openOrders: [], - openFilteredOrders: [], - historicTrades: [], - myOrders: [], - myHistoricTrades: [], - myOfferingOrders: [], - openTradeOrders: null, - tradeOffersSocketCounter: 1, - coinAmount: this.amountString, - tradeFee: "~0.005" - } + let dogecoin = { + name: "DOGECOIN", + balance: "0", + coinCode: "DOGE", + openOrders: [], + openFilteredOrders: [], + historicTrades: [], + myOrders: [], + myHistoricTrades: [], + myOfferingOrders: [], + openTradeOrders: null, + tradeOffersSocketCounter: 1, + coinAmount: this.amountString, + tradeFee: "~0.005" + } - let digibyte = { - name: "DIGIBYTE", - balance: "0", - coinCode: "DGB", - openOrders: [], - openFilteredOrders: [], - historicTrades: [], - myOrders: [], - myHistoricTrades: [], - myOfferingOrders: [], - openTradeOrders: null, - tradeOffersSocketCounter: 1, - coinAmount: this.amountString, - tradeFee: "~0.0005" - } + let digibyte = { + name: "DIGIBYTE", + balance: "0", + coinCode: "DGB", + openOrders: [], + openFilteredOrders: [], + historicTrades: [], + myOrders: [], + myHistoricTrades: [], + myOfferingOrders: [], + openTradeOrders: null, + tradeOffersSocketCounter: 1, + coinAmount: this.amountString, + tradeFee: "~0.0005" + } - let ravencoin = { - name: "RAVENCOIN", - balance: "0", - coinCode: "RVN", - openOrders: [], - openFilteredOrders: [], - historicTrades: [], - myOrders: [], - myHistoricTrades: [], - myOfferingOrders: [], - openTradeOrders: null, - tradeOffersSocketCounter: 1, - coinAmount: this.amountString, - tradeFee: "~0.006" - } + let ravencoin = { + name: "RAVENCOIN", + balance: "0", + coinCode: "RVN", + openOrders: [], + openFilteredOrders: [], + historicTrades: [], + myOrders: [], + myHistoricTrades: [], + myOfferingOrders: [], + openTradeOrders: null, + tradeOffersSocketCounter: 1, + coinAmount: this.amountString, + tradeFee: "~0.006" + } - let piratechain = { - name: "PIRATECHAIN", - balance: "0", - coinCode: "ARRR", - openOrders: [], - openFilteredOrders: [], - historicTrades: [], - myOrders: [], - myHistoricTrades: [], - myOfferingOrders: [], - openTradeOrders: null, - tradeOffersSocketCounter: 1, - coinAmount: this.amountString, - tradeFee: "~0.0002" - } + let piratechain = { + name: "PIRATECHAIN", + balance: "0", + coinCode: "ARRR", + openOrders: [], + openFilteredOrders: [], + historicTrades: [], + myOrders: [], + myHistoricTrades: [], + myOfferingOrders: [], + openTradeOrders: null, + tradeOffersSocketCounter: 1, + coinAmount: this.amountString, + tradeFee: "~0.0002" + } - this.listedCoins = new Map() - this.listedCoins.set("QORTAL", qortal) - this.listedCoins.set("BITCOIN", bitcoin) - this.listedCoins.set("LITECOIN", litecoin) - this.listedCoins.set("DOGECOIN", dogecoin) - this.listedCoins.set("DIGIBYTE", digibyte) - this.listedCoins.set("RAVENCOIN", ravencoin) - this.listedCoins.set("PIRATECHAIN", piratechain) + this.listedCoins = new Map() + this.listedCoins.set("QORTAL", qortal) + this.listedCoins.set("BITCOIN", bitcoin) + this.listedCoins.set("LITECOIN", litecoin) + this.listedCoins.set("DOGECOIN", dogecoin) + this.listedCoins.set("DIGIBYTE", digibyte) + this.listedCoins.set("RAVENCOIN", ravencoin) + this.listedCoins.set("PIRATECHAIN", piratechain) - workers.set("QORTAL", { - tradesConnectedWorker: null, - handleStuckTradesConnectedWorker: null - }) + workers.set("QORTAL", { + tradesConnectedWorker: null, + handleStuckTradesConnectedWorker: null + }) - workers.set("BITCOIN", { - tradesConnectedWorker: null, - handleStuckTradesConnectedWorker: null - }) + workers.set("BITCOIN", { + tradesConnectedWorker: null, + handleStuckTradesConnectedWorker: null + }) - workers.set("LITECOIN", { - tradesConnectedWorker: null, - handleStuckTradesConnectedWorker: null - }) + workers.set("LITECOIN", { + tradesConnectedWorker: null, + handleStuckTradesConnectedWorker: null + }) - workers.set("DOGECOIN", { - tradesConnectedWorker: null, - handleStuckTradesConnectedWorker: null - }) + workers.set("DOGECOIN", { + tradesConnectedWorker: null, + handleStuckTradesConnectedWorker: null + }) - workers.set("DIGIBYTE", { - tradesConnectedWorker: null, - handleStuckTradesConnectedWorker: null - }) + workers.set("DIGIBYTE", { + tradesConnectedWorker: null, + handleStuckTradesConnectedWorker: null + }) - workers.set("RAVENCOIN", { - tradesConnectedWorker: null, - handleStuckTradesConnectedWorker: null - }) + workers.set("RAVENCOIN", { + tradesConnectedWorker: null, + handleStuckTradesConnectedWorker: null + }) - workers.set("PIRATECHAIN", { - tradesConnectedWorker: null, - handleStuckTradesConnectedWorker: null - }) + workers.set("PIRATECHAIN", { + tradesConnectedWorker: null, + handleStuckTradesConnectedWorker: null + }) - this.selectedCoin = "LITECOIN" - this.selectedAddress = {} - this.nodeInfo = [] - this.blockedTradesList = [] - this.preparedPresence = [] - this.tradesPresenceCleaned = [] - this.config = {} - this.sellBtnDisable = false - this.isSellLoading = false - this.buyBtnDisable = true - this.autoBuyWarning = false - this.autoBuyBtnDisable = true - this.autoBuyBotDisable = false - this.isBuyLoading = false - this.initialAmount = 0 - this.cancelBtnDisable = false - this.cancelStuckOfferBtnDisable = false - this.isLoadingHistoricTrades = true - this.isLoadingOpenTrades = true - this.isLoadingMyOpenOrders = false - this.showGetWalletBance = true - this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light' - this.btcWallet = '' - this.ltcWallet = '' - this.dogeWallet = '' - this.dgbWallet = '' - this.rvnWallet = '' - this.arrrWallet = '' - this.arrrWalletAddress = '' - this.qortbtc = 0 - this.qortltc = 0 - this.qortdoge = 0 - this.qortdgb = 0 - this.qortrvn = 0 - this.qortarrr = 0 - this.btcqort = 0 - this.ltcqort = 0 - this.dogeqort = 0 - this.dgbqort = 0 - this.rvnqort = 0 - this.arrrqort = 0 - this.tradeInfoAccountName = '' - this.tradeImageUrl = '' - this.tradeAddressResult = [] - this.displayTradeAddress = '' - this.displayTradeLevel = '' - this.displayTradeBalance = '' - this.tradeSalt = '' - this.tradeStorageData = '' - this.tradeLockScreenPass = '' - this.tradeLockScreenSet = '' - this.tradeLockPass = '' - this.tradeLockSet = '' - this.myTradeLockScreenPass = '' - this.myTradeLockScreenSet = '' - this.tradeHelperMessage = '' - this.pingCoinBalancesController = this.pingCoinBalancesController.bind(this) - } + this.selectedCoin = "LITECOIN" + this.selectedAddress = {} + this.nodeInfo = [] + this.blockedTradesList = [] + this.preparedPresence = [] + this.tradesPresenceCleaned = [] + this.config = {} + this.sellBtnDisable = false + this.isSellLoading = false + this.buyBtnDisable = true + this.autoBuyWarning = false + this.autoBuyBtnDisable = true + this.autoBuyBotDisable = false + this.isBuyLoading = false + this.initialAmount = 0 + this.cancelBtnDisable = false + this.cancelStuckOfferBtnDisable = false + this.isLoadingHistoricTrades = true + this.isLoadingOpenTrades = true + this.isLoadingMyOpenOrders = false + this.showGetWalletBance = true + this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light' + this.btcWallet = '' + this.ltcWallet = '' + this.dogeWallet = '' + this.dgbWallet = '' + this.rvnWallet = '' + this.arrrWallet = '' + this.arrrWalletAddress = '' + this.qortbtc = 0 + this.qortltc = 0 + this.qortdoge = 0 + this.qortdgb = 0 + this.qortrvn = 0 + this.qortarrr = 0 + this.btcqort = 0 + this.ltcqort = 0 + this.dogeqort = 0 + this.dgbqort = 0 + this.rvnqort = 0 + this.arrrqort = 0 + this.tradeInfoAccountName = '' + this.tradeImageUrl = '' + this.tradeAddressResult = [] + this.displayTradeAddress = '' + this.displayTradeLevel = '' + this.displayTradeBalance = '' + this.tradeSalt = '' + this.tradeStorageData = '' + this.tradeLockScreenPass = '' + this.tradeLockScreenSet = '' + this.tradeLockPass = '' + this.tradeLockSet = '' + this.myTradeLockScreenPass = '' + this.myTradeLockScreenSet = '' + this.tradeHelperMessage = '' + this.pingCoinBalancesController = this.pingCoinBalancesController.bind(this) + } - historicTradesTemplate() { - return html` -
    -
    -
    ${translate("tradepage.tchange3")}
    -
    -
    ${translate("login.loading")}
    - - { - render(html`${data.item.qortAmount}`, root) - }} - > - - { - const price = this.round(parseFloat(data.item.foreignAmount) / parseFloat(data.item.qortAmount)) - render(html`${price}`, root) - }} - > - - { - render(html`${data.item.foreignAmount}`, root) - }} - > - - + render() { + return html` +
    +
    +

    Qortal ${translate("tradepage.tchange1")} -  

    + + QORT / LTC + QORT / BTC + QORT / DOGE + QORT / DGB + QORT / RVN + QORT / ARRR + +
    + this.shadowRoot.getElementById('tradeInfoDialog').open()}> +
    +
    + ${this.chartShowCoin()} +
    +
    + ${this.renderTradeLockButton()} +
    +
    +
    +
    + ${this.historicTradesTemplate()} + ${this.myHistoricTradesTemplate()} + ${this.openTradesTemplate()} +
    +
    + ${this.myOpenOrdersTemplate()} + ${this.openMarketTemplate()} +
    +
    +
    +
    +

    ${translate("tradepage.tchange33")} ${this.listedCoins.get(this.selectedCoin).coinCode} ${translate("tradepage.tchange40")}

    +

    1 QORT = ${this.exchangeRateQort()} ${this.listedCoins.get(this.selectedCoin).coinCode}

    + this.setDefaultSellPrice()}> +
    +
    +
    -
    - ` - } - - openTradesTemplate() { - return html` -
    -
    -
    ${translate("tradepage.tchange5")}
    -
    -
    ${translate("login.loading")}
    - - { - render(html`${this.round(data.item.qortAmount)}`, root) - }} - > - - { - render(html`${this.round(data.item.price)}`, root) - }} - > - - { - render(html`${data.item.foreignAmount}`, root) - }} - > - - { - render(html`${data.item.qortalCreator}`, root) - }} - > - - { - render(html`info`, root) - }} - > - + + +
    +

    ${translate("tradepage.tchange7")}

    +
    +
    +
    + + + + + { render(html`${this.renderCancelStuckOfferButton(data.item)}`, root) }}>
    -
    -
    - ` - } + ${translate("general.close")} + + +
    +

    + this.shadowRoot.getElementById('tradeInfoDialog').close()} title="${translate("info.inf2")}">highlight_off +
    +
    +

    ${translate("info.inf1")}

    +

    ${translate("info.inf3")} ${this.listedCoins.get(this.selectedCoin).coinCode} ${translate("info.inf4")}

    +

    ${translate("info.inf5")} ${this.listedCoins.get(this.selectedCoin).coinCode}

    +

    ${translate("info.inf6")}

    +
    +
    + +
    +

    Qortal ${translate("tabmenu.tm4")} ${translate("login.lp1")}

    +
    +
    +
    +

    ${translate("login.lp2")}

    +

    ${translate("login.lp3")}

    +
    +
    + password + +
    +
    + password + +
    +
    + ${translate("login.lp4")} + ${translate("login.lp5")} +
    +
    + +
    +

    Qortal ${translate("tabmenu.tm4")} ${translate("login.lp1")}

    +
    +
    +
    +

    ${translate("login.lessthen8")}

    +
    +
    + ${translate("login.lp4")} + ${translate("login.lp5")} +
    +
    + +
    + ${translate("sidemenu.tradeportal")}
    + ${translate("login.lp9")} + ${translate("login.lp10")} +
    +
    + password + +
    + ${this.tradeHelperMessage} +
    +
    +
    +
    + +
    +
    + + + ` + } - openMarketTemplate() { - return html` -
    -
    - - - - - -
    -
    -
    - -
    - ${translate("tradepage.tchange8")} (QORT)* -

    - - -

    - ${translate("tradepage.tchange14")} (${this.listedCoins.get(this.selectedCoin).coinCode})* -

    - - -

    - ${translate("tradepage.tchange10")} (${this.listedCoins.get(this.selectedCoin).coinCode})* -

    - - - -

    - - ${translate("tradepage.tchange16")}: ${this.listedCoins.get(this.selectedCoin).balance} ${this.listedCoins.get(this.selectedCoin).coinCode} - ${translate("walletpage.wchange12")}: ${this.listedCoins.get(this.selectedCoin).tradeFee} ${this.listedCoins.get(this.selectedCoin).coinCode} - -
    -
    - - ${this.isBuyLoading === false ? html`${translate("tradepage.tchange18")}` : html``} - + async firstUpdated() { + let _this = this + + this.changeTheme() + this.changeLanguage() + + this.tradeFee() + this.getNewBlockedTrades() + + this.tradeHelperMessage = this.renderTradeHelperPass() + + this.tradeSalt = '' + this.tradeSalt = Base58.encode(window.parent.reduxStore.getState().app.wallet._addresses[0].keyPair.privateKey) + + this.tradeStorageData = '' + this.tradeStorageData = window.parent.reduxStore.getState().app.selectedAddress.address + + this.tradeLockScreenPass = '' + this.tradeLockScreenPass = 'tradeLockScreenPass-' + this.tradeStorageData + + this.tradeLockScreenSet = '' + this.tradeLockScreenSet = 'tradeLockScreenSet-' + this.tradeStorageData + + this.tradeLockPass = '' + this.tradeLockPass = encryptData(false, this.tradeSalt) + + this.tradeLockSet = '' + this.tradeLockSet = encryptData(false, this.tradeSalt) + + if (localStorage.getItem(this.tradeLockScreenPass) === null && localStorage.getItem(this.tradeLockScreenSet) === null) { + localStorage.setItem(this.tradeLockScreenPass, this.tradeLockPass) + localStorage.setItem(this.tradeLockScreenSet, this.tradeLockSet) + this.myTradeLockScreenPass = '' + this.myTradeLockScreenPass = decryptData(localStorage.getItem(this.tradeLockScreenPass), this.tradeSalt) + this.myTradeLockScreenSet = '' + this.myTradeLockScreenSet = decryptData(localStorage.getItem(this.tradeLockScreenSet), this.tradeSalt) + } else { + this.myTradeLockScreenPass = '' + this.myTradeLockScreenPass = decryptData(localStorage.getItem(this.tradeLockScreenPass), this.tradeSalt) + this.myTradeLockScreenSet = '' + this.myTradeLockScreenSet = decryptData(localStorage.getItem(this.tradeLockScreenSet), this.tradeSalt) + } + + if (this.myTradeLockScreenSet === true) { + this.shadowRoot.getElementById('tradeLockScreenActive').open() + } + + this.updateWalletBalance() + this.fetchWalletAddress(this.selectedCoin) + this.blockedTradesList = JSON.parse(localStorage.getItem('failedTrades') || '[]') + + setTimeout(() => { + this.displayTabContent('buy') + }, 0) + + this._openOrdersGrid = this.shadowRoot.getElementById('openOrdersGrid') + + this._openOrdersGrid.querySelector('#priceColumn').headerRenderer = function (root) { + const priceString = get("tradepage.tchange9") + root.innerHTML = '' + priceString + ' (' + _this.listedCoins.get(_this.selectedCoin).coinCode + ')' + } + + this._openOrdersGrid.querySelector('#qortAmountColumn').headerRenderer = function (root) { + const amountString = get("tradepage.tchange8") + root.innerHTML = '' + amountString + ' (QORT)' + } + + this._myOrdersGrid = this.shadowRoot.getElementById('myOrdersGrid') + this._historicTradesGrid = this.shadowRoot.getElementById('historicTradesGrid') + this._myHistoricTradesGrid = this.shadowRoot.getElementById('myHistoricTradesGrid') + this._stuckOrdersGrid = this.shadowRoot.getElementById('stuckOrdersGrid') + + const getNodeInfo = () => { + parentEpml.request("apiCall", { url: `/admin/status` }).then((res) => { + this.nodeInfo = res + getSellButtonStatus() + }) + setTimeout(getNodeInfo, 30000) + } + + const getSellButtonStatus = () => { + if (this.nodeInfo.isSynchronizing === true) { + this.sellBtnDisable = true + } else this.sellBtnDisable = this.nodeInfo.isSynchronizing !== false; + } + + const getQortBtcPrice = () => { + parentEpml.request("apiCall", { url: `/crosschain/price/BITCOIN?inverse=true` }).then((res) => { + this.qortbtc = (Number(res) / 1e8).toFixed(8) + }) + setTimeout(getQortBtcPrice, 300000) + } + + const getQortLtcPrice = () => { + parentEpml.request("apiCall", { url: `/crosschain/price/LITECOIN?inverse=true` }).then((res) => { + this.qortltc = (Number(res) / 1e8).toFixed(8) + }) + setTimeout(getQortLtcPrice, 300000) + } + + const getQortDogePrice = () => { + parentEpml.request("apiCall", { url: `/crosschain/price/DOGECOIN?inverse=true` }).then((res) => { + this.qortdoge = (Number(res) / 1e8).toFixed(8) + }) + setTimeout(getQortDogePrice, 300000) + } + + const getQortDgbPrice = () => { + parentEpml.request("apiCall", { url: `/crosschain/price/DIGIBYTE?inverse=true` }).then((res) => { + this.qortdgb = (Number(res) / 1e8).toFixed(8) + }) + setTimeout(getQortDgbPrice, 300000) + } + + const getQortRvnPrice = () => { + parentEpml.request("apiCall", { url: `/crosschain/price/RAVENCOIN?inverse=true` }).then((res) => { + this.qortrvn = (Number(res) / 1e8).toFixed(8) + }) + setTimeout(getQortRvnPrice, 300000) + } + + const getQortArrrPrice = () => { + parentEpml.request("apiCall", { url: `/crosschain/price/PIRATECHAIN?inverse=true` }).then((res) => { + this.qortarrr = (Number(res) / 1e8).toFixed(8) + }) + setTimeout(getQortArrrPrice, 300000) + } + + window.addEventListener('storage', () => { + this.blockedTradesList = JSON.parse(localStorage.getItem('failedTrades') || '[]') + const checkLanguage = localStorage.getItem('qortalLanguage') + const checkTheme = localStorage.getItem('qortalTheme') + + use(checkLanguage) + + this.theme = (checkTheme === 'dark') ? 'dark' : 'light' + document.querySelector('html').setAttribute('theme', this.theme) + }) + + if (!isElectron()) { + } else { + window.addEventListener('contextmenu', (event) => { + event.preventDefault() + window.parent.electronAPI.showMyMenu() + }) + } + + this.btcWallet = window.parent.reduxStore.getState().app.selectedAddress.btcWallet.address + this.ltcWallet = window.parent.reduxStore.getState().app.selectedAddress.ltcWallet.address + this.dogeWallet = window.parent.reduxStore.getState().app.selectedAddress.dogeWallet.address + this.dgbWallet = window.parent.reduxStore.getState().app.selectedAddress.dgbWallet.address + this.rvnWallet = window.parent.reduxStore.getState().app.selectedAddress.rvnWallet.address + this.arrrWallet = window.parent.reduxStore.getState().app.selectedAddress.arrrWallet.address + + let configLoaded = false + + parentEpml.ready().then(() => { + parentEpml.subscribe('selected_address', async (selectedAddress) => { + this.selectedAddress = {} + selectedAddress = JSON.parse(selectedAddress) + if (!selectedAddress || Object.entries(selectedAddress).length === 0) return + this.selectedAddress = selectedAddress + + this.btcWallet = window.parent.reduxStore.getState().app.selectedAddress.btcWallet.address + this.ltcWallet = window.parent.reduxStore.getState().app.selectedAddress.ltcWallet.address + this.dogeWallet = window.parent.reduxStore.getState().app.selectedAddress.dogeWallet.address + this.dgbWallet = window.parent.reduxStore.getState().app.selectedAddress.dgbWallet.address + this.rvnWallet = window.parent.reduxStore.getState().app.selectedAddress.rvnWallet.address + this.arrrWallet = window.parent.reduxStore.getState().app.selectedAddress.arrrWallet.address + this.updateAccountBalance() + }) + + parentEpml.subscribe('config', (c) => { + if (!configLoaded) { + setTimeout(getNodeInfo, 1) + setTimeout(getQortBtcPrice, 1) + setTimeout(getQortLtcPrice, 1) + setTimeout(getQortDogePrice, 1) + setTimeout(getQortDgbPrice, 1) + setTimeout(getQortRvnPrice, 1) + setTimeout(getQortArrrPrice, 1) + configLoaded = true + } + this.config = JSON.parse(c) + }) + + parentEpml.subscribe('coin_balances', async (payload) => { + const coinBalances = JSON.parse(payload) + let coin = '' + switch (this.selectedCoin) { + case 'BITCOIN': + coin = 'btc' + break + case 'LITECOIN': + coin = 'ltc' + break + case 'DOGECOIN': + coin = 'doge' + break + case 'DIGIBYTE': + coin = 'dgb' + break + case 'RAVENCOIN': + coin = 'rvn' + break + case 'PIRATECHAIN': + coin = 'arrr' + break + default: + break + } + if (coinBalances[coin]) { + const res = coinBalances[coin].fullValue + let value = (Number(res) / 1e8).toFixed(8) + if (coin !== 'qort') { + value = (Number(res) / 1e8).toFixed(8) + } + this.listedCoins.get(this.selectedCoin).balance = value + this.requestUpdate() + } + }) + + let coinSelectionMenu = this.shadowRoot.getElementById("coinSelectionMenu") + + coinSelectionMenu.addEventListener('change', function () { + _this.setForeignCoin(coinSelectionMenu.value, false) + }) + + _this.setForeignCoin(coinSelectionMenu.value, true) + }) + + parentEpml.imReady() + + setTimeout(() => this.shadowRoot.querySelector('[slot="vaadin-grid-cell-content-3"]').setAttribute('title', 'Last Seen'), 3000) + + this.clearConsole() + + setInterval(() => { + this.clearConsole() + }, 60000) + + setInterval(() => { + this.getNewBlockedTrades() + }, 150000) + } + + historicTradesTemplate() { + return html` +
    +
    +
    ${translate("tradepage.tchange3")}
    +
    +
    +
    + ${translate("login.loading")} +
    + + { + render(html`${data.item.qortAmount}`, root) + }} + > + + { + const price = this.round(parseFloat(data.item.foreignAmount) / parseFloat(data.item.qortAmount)) + render(html`${price}`, root) + }} + > + + { + render(html`${data.item.foreignAmount}`, root) + }} + > + + +
    +
    +
    + ` + } + + openTradesTemplate() { + return html` +
    +
    +
    ${translate("tradepage.tchange5")}
    +
    +
    +
    + ${translate("login.loading")} +
    + + { + render(html`${this.round(data.item.qortAmount)}`, root) + }} + > + + { + render(html`${this.round(data.item.price)}`, root) + }} + > + + { + render(html`${data.item.foreignAmount}`, root) + }} + > + + { + render(html`${data.item.qortalCreator}`, root) + }} + > + + { + render(html` + + info + + `, root) + }} + > + + +
    +
    +
    + ` + } + + openMarketTemplate() { + return html` +
    +
    + + + + +
    +
    +
    +
    + +
    + ${translate("tradepage.tchange8")} (QORT)* +

    + + +

    + ${translate("tradepage.tchange14")} (${this.listedCoins.get(this.selectedCoin).coinCode})* +

    + + +

    + ${translate("tradepage.tchange10")} (${this.listedCoins.get(this.selectedCoin).coinCode})* +

    + + + +

    + + ${translate("tradepage.tchange16")}: ${this.listedCoins.get(this.selectedCoin).balance} ${this.listedCoins.get(this.selectedCoin).coinCode} + ${translate("walletpage.wchange12")}: ${this.listedCoins.get(this.selectedCoin).tradeFee} ${this.listedCoins.get(this.selectedCoin).coinCode} + +
    +
    + + ${this.isBuyLoading === false ? html`${translate("tradepage.tchange18")}` : html` + + `} + +
    -
    -
    -
    -
    - -
    - ${translate("tradepage.tchange8")} (QORT)* -

    - - -

    - ${translate("tradepage.tchange14")} (${this.listedCoins.get(this.selectedCoin).coinCode})* -

    - - -

    - ${translate("tradepage.tchange10")} (${this.listedCoins.get(this.selectedCoin).coinCode})* -

    - - -

    - - ${translate("tradepage.tchange16")}: ${this.listedCoins.get("QORTAL").balance} QORT - ${translate("walletpage.wchange12")}: ${this.listedCoins.get("QORTAL").tradeFee} QORT - -
    -
    - - ${this.isSellLoading === false ? html`${translate("tradepage.tchange19")}` : html``} - +
    +
    +
    + +
    + ${translate("tradepage.tchange8")} (QORT)* +

    + + +

    + ${translate("tradepage.tchange14")} (${this.listedCoins.get(this.selectedCoin).coinCode})* +

    + + +

    + ${translate("tradepage.tchange10")} (${this.listedCoins.get(this.selectedCoin).coinCode})* +

    + + +

    + + ${translate("tradepage.tchange16")}: ${this.listedCoins.get("QORTAL").balance} QORT + ${translate("walletpage.wchange12")}: ${this.listedCoins.get("QORTAL").tradeFee} QORT + +
    +
    + + ${this.isSellLoading === false ? html`${translate("tradepage.tchange19")}` : html` + + `} + +
    -
    - ` - } + ` + } - myOpenOrdersTemplate() { - return html` -
    -
    -
    ${translate("tradepage.tchange6")} this.showStuckOrdersDialog()}>
    -
    -
    ${translate("login.loading")}
    - - { - const dateString = new Date(data.item.timestamp).toLocaleString() - render(html`${dateString}`, root) - }} - > - - { - render(html` ${data.item._tradeState} `, root) - }} - > - - { - const price = this.round(parseFloat(data.item.foreignAmount) / parseFloat(data.item.qortAmount)) - render(html`${price}`, root) - }} - > - - - - - - { - render(html`${this.renderCancelButton(data.item)}`, root) - }} - > - - -
    -
    -
    - ` - } - - myHistoricTradesTemplate() { - return html` -
    -
    -
    ${translate("tradepage.tchange4")}
    -
    - - { - const dateString = new Date(data.item.timestamp).toLocaleString() - render(html`${dateString}`, root) - }} - > - - { - if (data.item.mode === 'SOLD') return render(html` ${translate("tradepage.tchange31")} `, root) - if (data.item.mode === 'BOUGHT') return render(html` ${translate("tradepage.tchange32")} `, root) - return render(html` ${data.item.mode} `, root) - }} - > - - { - const price = this.round(parseFloat(data.item.foreignAmount) / parseFloat(data.item.qortAmount)) - render(html`${price}`, root) - }} - > - - - - { - render(html` ${data.item.foreignAmount} `, root) - }} - > - - -
    -
    -
    - ` - } - - render() { - return html` -
    -
    -

    Qortal ${translate("tradepage.tchange1")} -  

    - - QORT / LTC - QORT / BTC - QORT / DOGE - QORT / DGB - QORT / RVN - QORT / ARRR - -
    - this.shadowRoot.getElementById('tradeInfoDialog').open()}> -
    -
    - ${this.chartShowCoin()} -
    -
    - ${this.renderTradeLockButton()} -
    - -
    -
    -
    - ${this.historicTradesTemplate()} - ${this.myHistoricTradesTemplate()} - ${this.openTradesTemplate()} -
    -
    - ${this.myOpenOrdersTemplate()} - ${this.openMarketTemplate()} -
    -
    -
    -
    -

    ${translate("tradepage.tchange33")} ${this.listedCoins.get(this.selectedCoin).coinCode} ${translate("tradepage.tchange40")}

    -

    1 QORT = ${this.exchangeRateQort()} ${this.listedCoins.get(this.selectedCoin).coinCode}

    - this.setDefaultSellPrice()}> + myOpenOrdersTemplate() { + return html` +
    +
    +
    ${translate("tradepage.tchange6")} this.showStuckOrdersDialog()}>
    +
    +
    +
    + ${translate("login.loading")} +
    + + { + const dateString = new Date(data.item.timestamp).toLocaleString() + render(html`${dateString}`, root) + }} + > + + { + render(html` ${data.item._tradeState} `, root) + }} + > + + { + const price = this.round(parseFloat(data.item.foreignAmount) / parseFloat(data.item.qortAmount)) + render(html`${price}`, root) + }} + > + + + + + + { + render(html`${this.renderCancelButton(data.item)}`, root) + }} + > + +
    -
    -
    - - -
    -

    ${translate("tradepage.tchange7")}

    -
    + ` + } + + myHistoricTradesTemplate() { + return html` +
    +
    +
    ${translate("tradepage.tchange4")}
    +
    + + { + const dateString = new Date(data.item.timestamp).toLocaleString() + render(html`${dateString}`, root) + }} + > + + { + if (data.item.mode === 'SOLD') return render(html` ${translate("tradepage.tchange31")} `, root) + if (data.item.mode === 'BOUGHT') return render(html` ${translate("tradepage.tchange32")} `, root) + return render(html` ${data.item.mode} `, root) + }} + > + + { + const price = this.round(parseFloat(data.item.foreignAmount) / parseFloat(data.item.qortAmount)) + render(html`${price}`, root) + }} + > + + + + { + render(html` ${data.item.foreignAmount} `, root) + }} + > + + +
    +
    -
    - - - - - { render(html`${this.renderCancelStuckOfferButton(data.item)}`, root) }}> - -
    - ${translate("general.close")} - - - -
    -

    - this.shadowRoot.getElementById('tradeInfoDialog').close()} title="${translate("info.inf2")}">highlight_off -
    -
    -

    ${translate("info.inf1")}

    -

    ${translate("info.inf3")} ${this.listedCoins.get(this.selectedCoin).coinCode} ${translate("info.inf4")}

    -

    ${translate("info.inf5")} ${this.listedCoins.get(this.selectedCoin).coinCode}

    -

    ${translate("info.inf6")}

    -
    -
    - -
    -

    Qortal ${translate("tabmenu.tm4")} ${translate("login.lp1")}

    -
    -
    -
    -

    ${translate("login.lp2")}

    -

    ${translate("login.lp3")}

    -
    -
    - password - -
    -
    - password - -
    -
    - ${translate("login.lp4")} - ${translate("login.lp5")} -
    -
    - -
    -

    Qortal ${translate("tabmenu.tm4")} ${translate("login.lp1")}

    -
    -
    -
    -

    ${translate("login.lessthen8")}

    -
    -
    - ${translate("login.lp4")} - ${translate("login.lp5")} -
    -
    - -
    - ${translate("sidemenu.tradeportal")}
    - ${translate("login.lp9")} - ${translate("login.lp10")} -
    -
    - password - -
    - ${this.tradeHelperMessage} -
    -
    -
    -
    - -
    -
    - - - ` - } - - pingCoinBalancesController() { - if(!this.selectedCoin) return - let coin = '' - switch (this.selectedCoin) { - case 'BITCOIN': - coin ='btc' - break - case 'LITECOIN': - coin = 'ltc' - break - case 'DOGECOIN': - coin = 'doge' - break - case 'DIGIBYTE': - coin = 'dgb' - break - case 'RAVENCOIN': - coin = 'rvn' - break - case 'PIRATECHAIN': - coin = 'arrr' - break - default: - break - } - const customEvent = new CustomEvent('ping-coin-controller-with-coin', { - detail: coin - }) - window.parent.dispatchEvent(customEvent) - } - - connectedCallback() { - super.connectedCallback() - this.intervalID = setInterval(this.pingCoinBalancesController, 30000) - } - - disconnectedCallback() { - super.disconnectedCallback() - if (this.intervalID) { - clearInterval(this.intervalID) - } - } - - async firstUpdated() { - let _this = this - - this.changeTheme() - this.changeLanguage() - await this.tradeFee() - await this.getNewBlockedTrades() - - this.tradeHelperMessage = this.renderTradeHelperPass() - - this.tradeSalt = '' - this.tradeSalt = Base58.encode(window.parent.reduxStore.getState().app.wallet._addresses[0].keyPair.privateKey) - - this.tradeStorageData = '' - this.tradeStorageData = window.parent.reduxStore.getState().app.selectedAddress.address - - this.tradeLockScreenPass = '' - this.tradeLockScreenPass = 'tradeLockScreenPass-' + this.tradeStorageData - - this.tradeLockScreenSet = '' - this.tradeLockScreenSet = 'tradeLockScreenSet-' + this.tradeStorageData - - this.tradeLockPass = '' - this.tradeLockPass = encryptData(false, this.tradeSalt) - - this.tradeLockSet = '' - this.tradeLockSet = encryptData(false, this.tradeSalt) - - if (localStorage.getItem(this.tradeLockScreenPass) === null && localStorage.getItem(this.tradeLockScreenSet) === null) { - localStorage.setItem(this.tradeLockScreenPass, this.tradeLockPass) - localStorage.setItem(this.tradeLockScreenSet, this.tradeLockSet) - this.myTradeLockScreenPass = '' - this.myTradeLockScreenPass = decryptData(localStorage.getItem(this.tradeLockScreenPass), this.tradeSalt) - this.myTradeLockScreenSet = '' - this.myTradeLockScreenSet = decryptData(localStorage.getItem(this.tradeLockScreenSet), this.tradeSalt) - } else { - this.myTradeLockScreenPass = '' - this.myTradeLockScreenPass = decryptData(localStorage.getItem(this.tradeLockScreenPass), this.tradeSalt) - this.myTradeLockScreenSet = '' - this.myTradeLockScreenSet = decryptData(localStorage.getItem(this.tradeLockScreenSet), this.tradeSalt) - } - - if (this.myTradeLockScreenSet === true) { - this.shadowRoot.getElementById('tradeLockScreenActive').open() - } - - await this.updateWalletBalance() - await this.fetchWalletAddress(this.selectedCoin) - this.blockedTradesList = JSON.parse(localStorage.getItem('failedTrades') || '[]') - - setTimeout(() => { - this.displayTabContent('buy') - }, 0) - - this._openOrdersGrid = this.shadowRoot.getElementById('openOrdersGrid') - - this._openOrdersGrid.querySelector('#priceColumn').headerRenderer = function (root) { - const priceString = get("tradepage.tchange9") - root.innerHTML = '' + priceString + ' (' + _this.listedCoins.get(_this.selectedCoin).coinCode + ')' - } - - this._openOrdersGrid.querySelector('#qortAmountColumn').headerRenderer = function (root) { - const amountString = get("tradepage.tchange8") - root.innerHTML = '' + amountString + ' (QORT)' - } - - this._myOrdersGrid = this.shadowRoot.getElementById('myOrdersGrid') - this._historicTradesGrid = this.shadowRoot.getElementById('historicTradesGrid') - this._myHistoricTradesGrid = this.shadowRoot.getElementById('myHistoricTradesGrid') - this._stuckOrdersGrid = this.shadowRoot.getElementById('stuckOrdersGrid') - - const getNodeInfo = () => { - parentEpml.request("apiCall", { url: `/admin/status` }).then((res) => { - this.nodeInfo = res - getSellButtonStatus() - }) - setTimeout(getNodeInfo, 30000) - } - - const getSellButtonStatus = () => { - if (this.nodeInfo.isSynchronizing === true) { - this.sellBtnDisable = true - } else this.sellBtnDisable = this.nodeInfo.isSynchronizing !== false; - } - - const getQortBtcPrice = () => { - parentEpml.request("apiCall", { url: `/crosschain/price/BITCOIN?inverse=true` }).then((res) => { - this.qortbtc = (Number(res) / 1e8).toFixed(8) - }) - setTimeout(getQortBtcPrice, 300000) - } - - const getQortLtcPrice = () => { - parentEpml.request("apiCall", { url: `/crosschain/price/LITECOIN?inverse=true` }).then((res) => { - this.qortltc = (Number(res) / 1e8).toFixed(8) - }) - setTimeout(getQortLtcPrice, 300000) - } - - const getQortDogePrice = () => { - parentEpml.request("apiCall", { url: `/crosschain/price/DOGECOIN?inverse=true` }).then((res) => { - this.qortdoge = (Number(res) / 1e8).toFixed(8) - }) - setTimeout(getQortDogePrice, 300000) - } - - const getQortDgbPrice = () => { - parentEpml.request("apiCall", { url: `/crosschain/price/DIGIBYTE?inverse=true` }).then((res) => { - this.qortdgb = (Number(res) / 1e8).toFixed(8) - }) - setTimeout(getQortDgbPrice, 300000) - } - - const getQortRvnPrice = () => { - parentEpml.request("apiCall", { url: `/crosschain/price/RAVENCOIN?inverse=true` }).then((res) => { - this.qortrvn = (Number(res) / 1e8).toFixed(8) - }) - setTimeout(getQortRvnPrice, 300000) - } - - const getQortArrrPrice = () => { - parentEpml.request("apiCall", { url: `/crosschain/price/PIRATECHAIN?inverse=true` }).then((res) => { - this.qortarrr = (Number(res) / 1e8).toFixed(8) - }) - setTimeout(getQortArrrPrice, 300000) - } - - window.addEventListener('storage', () => { - this.blockedTradesList = JSON.parse(localStorage.getItem('failedTrades') || '[]') - const checkLanguage = localStorage.getItem('qortalLanguage') - const checkTheme = localStorage.getItem('qortalTheme') - - use(checkLanguage) - - this.theme = (checkTheme === 'dark') ? 'dark' : 'light' - document.querySelector('html').setAttribute('theme', this.theme) - }) - - if (!isElectron()) { - } else { - window.addEventListener('contextmenu', (event) => { - event.preventDefault() - window.parent.electronAPI.showMyMenu() - }) - } - - this.btcWallet = window.parent.reduxStore.getState().app.selectedAddress.btcWallet.address - this.ltcWallet = window.parent.reduxStore.getState().app.selectedAddress.ltcWallet.address - this.dogeWallet = window.parent.reduxStore.getState().app.selectedAddress.dogeWallet.address - this.dgbWallet = window.parent.reduxStore.getState().app.selectedAddress.dgbWallet.address - this.rvnWallet = window.parent.reduxStore.getState().app.selectedAddress.rvnWallet.address - this.arrrWallet = window.parent.reduxStore.getState().app.selectedAddress.arrrWallet.address - - let configLoaded = false - - parentEpml.ready().then(() => { - parentEpml.subscribe('selected_address', async (selectedAddress) => { - this.selectedAddress = {} - selectedAddress = JSON.parse(selectedAddress) - if (!selectedAddress || Object.entries(selectedAddress).length === 0) return - this.selectedAddress = selectedAddress - - this.btcWallet = window.parent.reduxStore.getState().app.selectedAddress.btcWallet.address - this.ltcWallet = window.parent.reduxStore.getState().app.selectedAddress.ltcWallet.address - this.dogeWallet = window.parent.reduxStore.getState().app.selectedAddress.dogeWallet.address - this.dgbWallet = window.parent.reduxStore.getState().app.selectedAddress.dgbWallet.address - this.rvnWallet = window.parent.reduxStore.getState().app.selectedAddress.rvnWallet.address - this.arrrWallet = window.parent.reduxStore.getState().app.selectedAddress.arrrWallet.address - this.updateAccountBalance() - }) - - parentEpml.subscribe('config', (c) => { - if (!configLoaded) { - setTimeout(getNodeInfo, 1) - setTimeout(getQortBtcPrice, 1) - setTimeout(getQortLtcPrice, 1) - setTimeout(getQortDogePrice, 1) - setTimeout(getQortDgbPrice, 1) - setTimeout(getQortRvnPrice, 1) - setTimeout(getQortArrrPrice, 1) - configLoaded = true - } - this.config = JSON.parse(c) - }) - parentEpml.subscribe('coin_balances', async (payload) => { - const coinBalances = JSON.parse(payload) - let coin = '' - switch (this.selectedCoin) { - case 'BITCOIN': - coin ='btc' - break - case 'LITECOIN': - coin = 'ltc' - break - case 'DOGECOIN': - coin = 'doge' - break - case 'DIGIBYTE': - coin = 'dgb' - break - case 'RAVENCOIN': - coin = 'rvn' - break - case 'PIRATECHAIN': - coin = 'arrr' - break - default: - break - } - if(coinBalances[coin]){ - const res = coinBalances[coin].fullValue - let value = (Number(res) / 1e8).toFixed(8) - if(coin !== 'qort'){ - value = (Number(res) / 1e8).toFixed(8) - } - this.listedCoins.get(this.selectedCoin).balance = value - this.requestUpdate() - } - }) - - let coinSelectionMenu = this.shadowRoot.getElementById("coinSelectionMenu") - - coinSelectionMenu.addEventListener('change', function () { - _this.setForeignCoin(coinSelectionMenu.value,false) - }) - - _this.setForeignCoin(coinSelectionMenu.value,true) - }) - parentEpml.imReady() - - setTimeout(() => this.shadowRoot.querySelector('[slot="vaadin-grid-cell-content-3"]').setAttribute('title', 'Last Seen'), 3000) - - this.clearConsole() - setInterval(() => { - this.clearConsole() - }, 60000) - - setInterval(() => { - this.getNewBlockedTrades() - }, 150000) - } - - clearConsole() { - if (!isElectron()) { - } else { - console.clear() - window.parent.electronAPI.clearCache() - } - } - - renderTradeLockButton() { - if (this.myTradeLockScreenPass === false && this.myTradeLockScreenSet === false) { - return html` -
    - this.openTradeSetScreenLockPass()} title="${translate("login.lp11")}"> -
    - ` - } else if (this.myTradeLockScreenSet === false) { - return html` -
    - this.setTradeLockQortal()} title="${translate("login.lp11")}"> -
    - ` - } else if (this.myTradeLockScreenSet === true) { - return html` -
    - -
    - ` - } - } - - openTradeSetScreenLockPass() { - this.shadowRoot.getElementById('tradeLockPassword').value = '' - this.shadowRoot.getElementById('tradeLockPasswordConfirm').value = '' - this.shadowRoot.getElementById('setTradeLockScreenPass').open() - } - - closewTradeSetScreenLockPass() { - this.shadowRoot.getElementById('setTradeLockScreenPass').close() - } - - tradeCheckPass() { - const tradePassword = this.shadowRoot.getElementById('tradeLockPassword').value - const tradeRePassword = this.shadowRoot.getElementById('tradeLockPasswordConfirm').value - - if (tradePassword === '') { - let snackbar1string = get("login.pleaseenter") - parentEpml.request('showSnackBar', `${snackbar1string}`) - return - } - - if (tradePassword != tradeRePassword) { - let snackbar2string = get("login.notmatch") - parentEpml.request('showSnackBar', `${snackbar2string}`) - return - } - - if (tradePassword.length < 8) { - let snackbar3string = get("login.lessthen8") - parentEpml.request('showSnackBar', `${snackbar3string}`) - this.tradeExtraConfirm() - } - - if (tradePassword.length >= 8) { - this.setTradeNewScreenPass() - let snackbar4string = get("login.lp6") - parentEpml.request('showSnackBar', `${snackbar4string}`) - } - } - - tradeExtraConfirm() { - this.shadowRoot.getElementById('setTradeLockScreenPass').close() - this.shadowRoot.getElementById('tradeExtraConfirmPass').open() - } - - closTradeExtraConfirmPass() { - this.shadowRoot.getElementById('tradeExtraConfirmPass').close() - this.shadowRoot.getElementById('tradeLockPassword').value = '' - this.shadowRoot.getElementById('tradeLockPasswordConfirm').value = '' - } - - setTradeNewScreenPass() { - const tradeRawPassword = this.shadowRoot.getElementById('tradeLockPassword').value - const tradeCryptPassword = encryptData(tradeRawPassword, this.tradeSalt) - localStorage.setItem(this.tradeLockScreenPass, tradeCryptPassword) - this.myTradeLockScreenPass = '' - this.myTradeLockScreenPass = decryptData(localStorage.getItem(this.tradeLockScreenPass), this.tradeSalt) - this.shadowRoot.getElementById('setTradeLockScreenPass').close() - this.shadowRoot.getElementById('tradeExtraConfirmPass').close() - this.shadowRoot.getElementById('tradeLockPassword').value = '' - this.shadowRoot.getElementById('tradeLockPasswordConfirm').value = '' - } - - setTradeLockQortal() { - this.tradeHelperMessage = this.renderTradeHelperPass() - this.tradeLockSet = '' - this.tradeLockSet = encryptData(true, this.tradeSalt) - localStorage.setItem(this.tradeLockScreenSet, this.tradeLockSet) - this.myTradeLockScreenSet = '' - this.myTradeLockScreenSet = decryptData(localStorage.getItem(this.tradeLockScreenSet), this.tradeSalt) - this.shadowRoot.getElementById('tradeLockScreenActive').open() - } - - tradePassKeyListener(e) { - if (e.key === 'Enter') { - this.closeTradeLockScreenActive() - } - } - - async closeTradeLockScreenActive() { - const myTradePass = decryptData(localStorage.getItem(this.tradeLockScreenPass), this.tradeSalt) - const tradeCheckPass = this.shadowRoot.getElementById('tradeUnlockPassword').value - const errDelay = ms => new Promise(res => setTimeout(res, ms)) - - if (tradeCheckPass === myTradePass) { - this.tradeLockSet = '' - this.tradeLockSet = encryptData(false, this.tradeSalt) - localStorage.setItem(this.tradeLockScreenSet, this.tradeLockSet) - this.myTradeLockScreenSet = '' - this.myTradeLockScreenSet = decryptData(localStorage.getItem(this.tradeLockScreenSet), this.tradeSalt) - this.shadowRoot.getElementById('tradeLockScreenActive').close() - this.shadowRoot.getElementById('tradeUnlockPassword').value = '' - this.tradeHelperMessage = this.renderTradeHelperPass() - } else { - this.shadowRoot.getElementById('tradeUnlockPassword').value = '' - this.tradeHelperMessage = this.renderTradeHelperErr() - await errDelay(3000) - this.tradeHelperMessage = this.renderTradeHelperPass() - - } - } - - renderTradeHelperPass() { - return html`${translate("login.pleaseenter")}` - } - - renderTradeHelperErr() { - return html`${translate("login.lp8")}` - } - - requestTraderInfo(traderAddress) { - let getAddress = traderAddress - const theInfoView = this.shadowRoot.querySelector('trader-info-view') - theInfoView.openTraderInfo(getAddress) - } - - requestTradeInfo(tradeObj) { - let seller = '' - let buyer = '' - let qortAmount = 0 - let foreignAmount = 0 - let ata = '' - let time = 0 - let coin = '' - seller = tradeObj.item.sellerAddress - buyer = tradeObj.item.buyerReceivingAddress - qortAmount = tradeObj.item.qortAmount - foreignAmount = tradeObj.item.foreignAmount - ata = tradeObj.item.atAddress - time = tradeObj.item.tradeTimestamp - coin = this.listedCoins.get(this.selectedCoin).coinCode - const theTradeInfoView = this.shadowRoot.querySelector('trade-info-view') - theTradeInfoView.openTradeInfo(seller, buyer, qortAmount, foreignAmount, ata, time, coin) - } - - changeTheme() { - const checkTheme = localStorage.getItem('qortalTheme') - this.theme = (checkTheme === 'dark') ? 'dark' : 'light' - document.querySelector('html').setAttribute('theme', this.theme); - } - - changeLanguage() { - const checkLanguage = localStorage.getItem('qortalLanguage') - - if (checkLanguage === null || checkLanguage.length === 0) { - localStorage.setItem('qortalLanguage', 'us') - use('us') - } else { - use(checkLanguage) - } - } - - renderFetchText() { - return html`${translate("walletpage.wchange1")}` - } - - renderWarning() { - return html`NOT ENOUGH ${this.listedCoins.get(this.selectedCoin).coinCode}` - } - - chartShowCoin() { - switch(this.listedCoins.get(this.selectedCoin).coinCode) { - case "BTC": - return html` chartsbtc.open()}>` - break - case "LTC": - return html` chartsltc.open()}>` - break - case "DOGE": - return html` chartsdoge.open()}>` - break - case "DGB": - return html` chartsdgb.open()}>` - break - case "RVN": - return html` chartsrvn.open()}>` - break - case "ARRR": - return html` chartsarrr.open()}>` - break - default: - break - } - } - - exchangeRateQort() { - switch(this.listedCoins.get(this.selectedCoin).coinCode) { - case "BTC": - this.qortRatio = this.qortbtc - break - case "LTC": - this.qortRatio = this.qortltc - break - case "DOGE": - this.qortRatio = this.qortdoge - break - case "DGB": - this.qortRatio = this.qortdgb - break - case "RVN": - this.qortRatio = this.qortrvn - break - case "ARRR": - this.qortRatio = this.qortarrr - break - default: - break - } - return html`${this.qortRatio}` - } - - exchangeRateForeign() { - if (this.listedCoins.get(this.selectedCoin).coinCode === "BTC") { - parentEpml.request('apiCall', { - url: `/crosschain/price/BITCOIN?inverse=false` - }).then((res) => { - this.btcqort = (Number(res) / 1e8).toFixed(8) - }) - return html`${this.btcqort}` - } else if (this.listedCoins.get(this.selectedCoin).coinCode === "LTC") { - parentEpml.request('apiCall', { - url: `/crosschain/price/LITECOIN?inverse=false` - }).then((res) => { - this.ltcqort = (Number(res) / 1e8).toFixed(8) - }) - return html`${this.ltcqort}` - } else if (this.listedCoins.get(this.selectedCoin).coinCode === "DOGE") { - parentEpml.request('apiCall', { - url: `/crosschain/price/DOGECOIN?inverse=false` - }).then((res) => { - this.dogeqort = (Number(res) / 1e8).toFixed(8) - }) - return html`${this.dogeqort}` - } else if (this.listedCoins.get(this.selectedCoin).coinCode === "DGB") { - parentEpml.request('apiCall', { - url: `/crosschain/price/DIGIBYTE?inverse=false` - }).then((res) => { - this.dgbqort = (Number(res) / 1e8).toFixed(8) - }) - return html`${this.dgbqort}` - } else if (this.listedCoins.get(this.selectedCoin).coinCode === "RVN") { - parentEpml.request('apiCall', { - url: `/crosschain/price/RAVENCOIN?inverse=false` - }).then((res) => { - this.rvnqort = (Number(res) / 1e8).toFixed(8) - }) - return html`${this.rvnqort}` - } else if (this.listedCoins.get(this.selectedCoin).coinCode === "ARRR") { - parentEpml.request('apiCall', { - url: `/crosschain/price/PIRATECHAIN?inverse=false` - }).then((res) => { - this.arrrqort = (Number(res) / 1e8).toFixed(8) - }) - return html`${this.arrrqort}` - } - } - - async updateWalletBalance() { - let _url = `` - let _body = null - - switch (this.selectedCoin) { - case 'BITCOIN': - _url = `/crosschain/btc/walletbalance?apiKey=${this.getApiKey()}` - _body = window.parent.reduxStore.getState().app.selectedAddress.btcWallet.derivedMasterPublicKey - break - case 'LITECOIN': - _url = `/crosschain/ltc/walletbalance?apiKey=${this.getApiKey()}` - _body = window.parent.reduxStore.getState().app.selectedAddress.ltcWallet.derivedMasterPublicKey - break - case 'DOGECOIN': - _url = `/crosschain/doge/walletbalance?apiKey=${this.getApiKey()}` - _body = window.parent.reduxStore.getState().app.selectedAddress.dogeWallet.derivedMasterPublicKey - break - case 'DIGIBYTE': - _url = `/crosschain/dgb/walletbalance?apiKey=${this.getApiKey()}` - _body = window.parent.reduxStore.getState().app.selectedAddress.dgbWallet.derivedMasterPublicKey - break - case 'RAVENCOIN': - _url = `/crosschain/rvn/walletbalance?apiKey=${this.getApiKey()}` - _body = window.parent.reduxStore.getState().app.selectedAddress.rvnWallet.derivedMasterPublicKey - break - case 'PIRATECHAIN': - _url = `/crosschain/arrr/walletbalance?apiKey=${this.getApiKey()}` - _body = window.parent.reduxStore.getState().app.selectedAddress.arrrWallet.seed58 - break - default: - break - } - - this.showGetWalletBance = true - - await parentEpml.request('apiCall', { - url: _url, - method: 'POST', - body: _body, - }).then((res) => { - if (isNaN(Number(res))) { - //... - } else { - this.listedCoins.get(this.selectedCoin).balance = (Number(res) / 1e8).toFixed(8) - } - }) - - this.showGetWalletBance = false - } - - async fetchWalletAddress(coin) { - switch (coin) { - case 'PIRATECHAIN': - let res = await parentEpml.request('apiCall', { - url: `/crosschain/arrr/walletaddress?apiKey=${this.getApiKey()}`, - method: 'POST', - body: `${window.parent.reduxStore.getState().app.selectedAddress.arrrWallet.seed58}`, - }) - if (res != null && res.error != 1201) { - this.arrrWalletAddress = res - } - break - - default: - // Not used for other coins yet - break - } - } - - async setForeignCoin(coin,beingInitialized) { - let _this = this - this.selectedCoin = coin - - let coinSelectionMenu=this.shadowRoot.getElementById("coinSelectionMenu") - - if(beingInitialized){ - coinSelectionMenu.shadowRoot.querySelector('.mdc-select--outlined .mdc-select__anchor').setAttribute('style', 'padding-left: 60px;') - let pairIconContainer = document.createElement("span") - let pairicon = (_this.listedCoins.get(_this.selectedCoin).coinCode).toLowerCase() - pairIconContainer.setAttribute("class","pairIconContainer") - pairIconContainer.setAttribute('style', 'left: 10px;top: 50%;transform: translate(0, -50%);height: 26px;width: 45px;position: absolute;background-repeat: no-repeat;background-size: cover;background-image: url(/img/qort'+pairicon+'.png);') - coinSelectionMenu.shadowRoot.querySelector('.mdc-select--outlined .mdc-select__anchor').appendChild(pairIconContainer) - }else{ - let pairIconContainer = coinSelectionMenu.shadowRoot.querySelector(".mdc-select--outlined .mdc-select__anchor span.pairIconContainer") - let pairicon = (_this.listedCoins.get(_this.selectedCoin).coinCode).toLowerCase() - pairIconContainer.style.backgroundImage='url(/img/qort'+pairicon+'.png)' - } - - this.isLoadingHistoricTrades = true - this.isLoadingOpenTrades = true - this.createConnection() - this._openOrdersGrid.querySelector('#priceColumn').headerRenderer = function (root) { - const priceString2 = get("tradepage.tchange9") - root.innerHTML = '' + priceString2 + ' (' + _this.listedCoins.get(_this.selectedCoin).coinCode + ')' - } - this.clearSellForm() - this.clearBuyForm() - await this.updateWalletBalance() - await this.fetchWalletAddress(coin) - } - - displayTabContent(tab) { - const tabPane = this.shadowRoot.getElementById("tabs-1") - tabPane.setAttribute("activeIndex", (tab === 'buy') ? '0': '1') - - const tabBuyContent = this.shadowRoot.getElementById('tab-buy-content') - tabBuyContent.style.display = (tab === 'buy') ? 'block' : 'none' - - const tabSellContent = this.shadowRoot.getElementById('tab-sell-content') - tabSellContent.style.display = (tab === 'sell') ? 'block' : 'none' - } - - setDefaultSellPrice() { - this.displayTabContent('sell') - const tabSellPrice = this.shadowRoot.getElementById('sellPriceInput') - tabSellPrice.value = this.qortRatio.isNaN ? 0 : this.qortRatio - } - - async reRenderHistoricTrades() { - this.requestUpdate() - await this.updateComplete - this.isLoadingHistoricTrades = false - } - - async reRenderOpenFilteredOrders() { - this.requestUpdate() - await this.updateComplete - this.isLoadingOpenTrades = false - } - - async reRenderMyOpenOrders() { - this.requestUpdate() - await this.updateComplete - this.isLoadingMyOpenOrders = false - } - - fillBuyForm(sellerRequest) { - this.shadowRoot.getElementById('buyAmountInput').value = parseFloat(sellerRequest.item.qortAmount) - this.shadowRoot.getElementById('buyPriceInput').value = this.round(parseFloat(sellerRequest.item.foreignAmount) / parseFloat(sellerRequest.item.qortAmount)) - this.shadowRoot.getElementById('buyTotalInput').value = parseFloat(sellerRequest.item.foreignAmount) - this.shadowRoot.getElementById('qortalAtAddress').value = sellerRequest.item.qortalAtAddress - const buyFunds = this.round(parseFloat(sellerRequest.item.foreignAmount)) - const haveFunds = this.round(parseFloat(this.listedCoins.get(this.selectedCoin).balance)) - if (Number(haveFunds) > Number(buyFunds)) { - this.buyBtnDisable = false - this.autoBuyWarning = false - this.displayTabContent('buy') - } else { - this.buyBtnDisable = true - this.autoBuyWarning = true - this.displayTabContent('buy') - } - - } - - processOfferingTrade(offer) { - try { - if(this.listedCoins.get(offer.foreignBlockchain).name!='') { - const offerItem = { - ...offer, - qortAmount: parseFloat(offer.qortAmount), - price: parseFloat(offer.foreignAmount) / parseFloat(offer.qortAmount), - } - const addOffer = () => { - this.listedCoins.get(offer.foreignBlockchain).openOrders.unshift(offerItem) - } - const initOffer = () => { - this.listedCoins.get(offer.foreignBlockchain).openOrders.push(offerItem) - } - this.listedCoins.get(offer.foreignBlockchain).openOrders.length === 0 ? initOffer() : addOffer() - this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1 ? this._openOrdersGrid.clearCache() : null - } - } catch(e) { - console.log("Error adding offer from "+offer.foreignBlockchain) - } - } - - processRedeemedTrade(offer) { - try { - if (this.listedCoins.get(offer.foreignBlockchain).name!='') { - - if (offer.qortalCreator === this.selectedAddress.address) { - if (this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1) { - this.updateWalletBalance() - } - const offerItem = { - ...offer, - mode: 'SOLD', - } - this._myHistoricTradesGrid.items.unshift(offerItem) - this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1 ? this._myHistoricTradesGrid.clearCache() : null - } else if (offer.partnerQortalReceivingAddress === this.selectedAddress.address) { - if (this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1) { - this.updateWalletBalance() - } - const offerItem = { - ...offer, - mode: 'BOUGHT', - } - this._myHistoricTradesGrid.items.unshift(offerItem) - this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1 ? this._myHistoricTradesGrid.clearCache() : null - } - const addNewHistoricTrade = () => { - this._historicTradesGrid.items.unshift(offer) - this._historicTradesGrid.clearCache() - } - this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1 ? addNewHistoricTrade() : null - - } - } catch(e) { - console.log("Error processing redeemed trade offer from "+offer.foreignBlockchain) - } - } - - processTradingTrade(offer) { - try { - if (this.listedCoins.get(offer.foreignBlockchain).name!='') { - - if (offer.qortalCreator === this.selectedAddress.address && this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1) { - this.updateWalletBalance() - } - this._openOrdersGrid.items.forEach((item, index) => { - if (item.qortalAtAddress === offer.qortalAtAddress) { - this._openOrdersGrid.items.splice(index, 1) - this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1 ? this._openOrdersGrid.clearCache() : null - } - }) - this.listedCoins.get(offer.foreignBlockchain).openOrders = this.listedCoins.get(offer.foreignBlockchain).openOrders.filter((order) => order.qortalAtAddress !== offer.qortalAtAddress) - } - } catch(e) { - console.log("Error processing trading trade offer from "+offer.foreignBlockchain) - } - } - - processRefundedTrade(offer) { - try { - if (this.listedCoins.get(offer.foreignBlockchain).name!='') { - - if (offer.qortalCreator === this.selectedAddress.address) { - if (this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1) { - this.updateWalletBalance() - } - this._myHistoricTradesGrid.items.unshift(offer) - this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1 ? this._myHistoricTradesGrid.clearCache() : null - } - - } - } catch(e) { - console.log("Error processing refunded trade offer from "+offer.foreignBlockchain) - } - } - - processCancelledTrade(offer) { - try { - if (this.listedCoins.get(offer.foreignBlockchain).name!='') { - - if (offer.qortalCreator === this.selectedAddress.address) { - if (this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1) { - this.updateWalletBalance() - } - this._myHistoricTradesGrid.items.unshift(offer) - this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1 ? this._myHistoricTradesGrid.clearCache() : null - } - this._openOrdersGrid.items.forEach((item, index) => { - if (item.qortalAtAddress === offer.qortalAtAddress) { - this._openOrdersGrid.items.splice(index, 1) - this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1 ? this._openOrdersGrid.clearCache() : null - } - }) - this.listedCoins.get(offer.foreignBlockchain).openOrders = this.listedCoins.get(offer.foreignBlockchain).openOrders.filter((order) => order.qortalAtAddress !== offer.qortalAtAddress) - this._stuckOrdersGrid.items.forEach((item, index) => { - if (item.qortalAtAddress === offer.qortalAtAddress) { - this._stuckOrdersGrid.items.splice(index, 1) - this._stuckOrdersGrid.clearCache() - } - }) - } - } catch(e) { - console.log("Error processing cancelled trade offer from "+offer.foreignBlockchain) - } - } - - /** - * TRADE OFFER STATES or MODE - * - OFFERING - * - REDEEMED - * - TRADING - * - REFUNDED - * - CANCELLED - */ - - processTradeOffers(offers) { - offers.forEach((offer) => { - if (offer.mode === 'OFFERING') { - this.processOfferingTrade(offer) - } else if (offer.mode === 'REDEEMED') { - this.processRedeemedTrade(offer) - } else if (offer.mode === 'TRADING') { - this.processTradingTrade(offer) - } else if (offer.mode === 'REFUNDED') { - this.processRefundedTrade(offer) - } else if (offer.mode === 'CANCELLED') { - this.processCancelledTrade(offer) - } - }) - } - - /** - * TradeBot Note by cat - * - * trade-bot entry states: - * - when you do /crosschain/tradebot/create, - * - it returns unsigned DEPLOY_AT for you to sign & broadcast - * - so initial trade-bot state is BOB_WAITING_FOR_AT_CONFIRM, because trade-bot is waiting for UI to sign & broadcast txn and for that txn to be confirmed into a block - * - once that happens & Bob's trade-bot notices that DEPLOY_AT has confirmed (and hence AT created and running), then it switches to BOB_WAITING_FOR_MESSAGE - * - which is Bob's trade-bot waiting for a message from Alice's trade-bot telling it (Bob's trade-bot) that Alice's trade-bot has funded P2SH-A and some other details - * - when that message is sent, Bob's trade-bot processes that message and sends its own message to the AT (which switches it to TRADING mode) - * - but the next state for Bob's trade-bot is to wait for Alice to spot AT is locked to her and for her to fund P2SH-B, hence BOB_WAITING_FOR_P2SH_B - * - at this point, Bob's trade-bot finds P2SH-B on the litecoin blockchain and can send secret-B to P2SH-B - * - when this happens, Alice uses secret-B and secret-A to redeem the QORT from the AT, so until Alice does this, Bob's trade-bot state is BOB_WAITING_FOR_AT_REDEEM - * - after Alice redeems QORT from AT, Bob can extract secret-A and capture the actual LTC funds from P2SH-A to his own litecoin account and hence his trade-bot moves to BOB_DONE - * - if anything goes wrong then refunds occur and Bob's trade-bot ends up at BOB_REFUNDED instead - * - I think you can probably guess the corresponding meaning of states for Alice's point of view, but if not I can go through those too? - * - Alice calls /crosschain/tradebot/respond which funds P2SH-A - * - so her trade-bot waits for that to appear in litecoin blockchain, so until then is ALICE_WAITING_FOR_P2SH_A - * - once the P2SH-A funding confirms, Alice's trade-bot can MESSAGE Bob's trade-bot with the details and changes to ALICE_WAITING_FOR_AT_LOCK - * - Bob's AT should then lock to trading with Alice (via those MESSAGEs above) and Alice's trade-bot notices this, (minimally) funds P2SH-B and waits until Bob 'spends' P2SH-B, hence ALICE_WATCH_P2SH_B - * - if Bob spends P2SH-B, then Alice can send secret-B and secret-A to the AT, claim the QORT and she's ALICE_DONE - * - if something goes wrong then her trade-bot needs to refund P2SH-B (if applicable) first (ALICE_REFUNDING_B) - * - and when that's done refund P2SH-A (ALICE_REFUNDING_A) - * - and when that's done her trade-bot ends up at ALICE_REFUNDED - * - * (PHEW) - */ - - processTradeBotStates(tradeStates) { - - /** - * BitcoinACCTv1 TRADEBOT STATES - * - BOB_WAITING_FOR_AT_CONFIRM - * - BOB_WAITING_FOR_MESSAGE - * - BOB_WAITING_FOR_AT_REDEEM - * - BOB_DONE - * - BOB_REFUNDED - * - ALICE_WAITING_FOR_AT_LOCK - * - ALICE_DONE - * - ALICE_REFUNDING_A - * - ALICE_REFUNDED - * - * @param {[{}]} states - */ - - const BitcoinACCTv1 = (states) => { - states.reverse() - states.forEach((state) => { - if (state.creatorAddress === this.selectedAddress.address) { - if (state.tradeState == 'BOB_WAITING_FOR_AT_CONFIRM') { - this.changeTradeBotState(state, 'PENDING') - } else if (state.tradeState == 'BOB_WAITING_FOR_MESSAGE') { - this.changeTradeBotState(state, 'LISTED') - } else if (state.tradeState == 'BOB_WAITING_FOR_AT_REDEEM') { - this.changeTradeBotState(state, 'TRADING') - } else if (state.tradeState == 'BOB_DONE') { - this.handleCompletedState(state) - } else if (state.tradeState == 'BOB_REFUNDED') { - this.handleCompletedState(state) - } else if (state.tradeState == 'ALICE_WAITING_FOR_AT_LOCK') { - this.changeTradeBotState(state, 'BUYING') - } else if (state.tradeState == 'ALICE_DONE') { - this.handleCompletedState(state) - } else if (state.tradeState == 'ALICE_REFUNDING_A') { - this.changeTradeBotState(state, 'REFUNDING') - } else if (state.tradeState == 'ALICE_REFUNDED') { - this.handleCompletedState(state) - } - } - }) - } - - /** - * LitecoinACCTv1 TRADEBOT STATES - * - BOB_WAITING_FOR_AT_CONFIRM - * - BOB_WAITING_FOR_MESSAGE - * - BOB_WAITING_FOR_AT_REDEEM - * - BOB_DONE - * - BOB_REFUNDED - * - ALICE_WAITING_FOR_AT_LOCK - * - ALICE_DONE - * - ALICE_REFUNDING_A - * - ALICE_REFUNDED - * - * @param {[{}]} states - */ - - const LitecoinACCTv1 = (states) => { - states.reverse() - states.forEach((state) => { - if (state.creatorAddress === this.selectedAddress.address) { - if (state.tradeState == 'BOB_WAITING_FOR_AT_CONFIRM') { - this.changeTradeBotState(state, 'PENDING') - } else if (state.tradeState == 'BOB_WAITING_FOR_MESSAGE') { - this.changeTradeBotState(state, 'LISTED') - } else if (state.tradeState == 'BOB_WAITING_FOR_AT_REDEEM') { - this.changeTradeBotState(state, 'TRADING') - } else if (state.tradeState == 'BOB_DONE') { - this.handleCompletedState(state) - } else if (state.tradeState == 'BOB_REFUNDED') { - this.handleCompletedState(state) - } else if (state.tradeState == 'ALICE_WAITING_FOR_AT_LOCK') { - this.changeTradeBotState(state, 'BUYING') - } else if (state.tradeState == 'ALICE_DONE') { - this.handleCompletedState(state) - } else if (state.tradeState == 'ALICE_REFUNDING_A') { - this.changeTradeBotState(state, 'REFUNDING') - } else if (state.tradeState == 'ALICE_REFUNDED') { - this.handleCompletedState(state) - } - } - }) - } - - /** - * DogecoinACCTv1 TRADEBOT STATES - * - BOB_WAITING_FOR_AT_CONFIRM - * - BOB_WAITING_FOR_MESSAGE - * - BOB_WAITING_FOR_AT_REDEEM - * - BOB_DONE - * - BOB_REFUNDED - * - ALICE_WAITING_FOR_AT_LOCK - * - ALICE_DONE - * - ALICE_REFUNDING_A - * - ALICE_REFUNDED - * - * @param {[{}]} states - */ - - const DogecoinACCTv1 = (states) => { - states.reverse() - states.forEach((state) => { - if (state.creatorAddress === this.selectedAddress.address) { - if (state.tradeState == 'BOB_WAITING_FOR_AT_CONFIRM') { - this.changeTradeBotState(state, 'PENDING') - } else if (state.tradeState == 'BOB_WAITING_FOR_MESSAGE') { - this.changeTradeBotState(state, 'LISTED') - } else if (state.tradeState == 'BOB_WAITING_FOR_AT_REDEEM') { - this.changeTradeBotState(state, 'TRADING') - } else if (state.tradeState == 'BOB_DONE') { - this.handleCompletedState(state) - } else if (state.tradeState == 'BOB_REFUNDED') { - this.handleCompletedState(state) - } else if (state.tradeState == 'ALICE_WAITING_FOR_AT_LOCK') { - this.changeTradeBotState(state, 'BUYING') - } else if (state.tradeState == 'ALICE_DONE') { - this.handleCompletedState(state) - } else if (state.tradeState == 'ALICE_REFUNDING_A') { - this.changeTradeBotState(state, 'REFUNDING') - } else if (state.tradeState == 'ALICE_REFUNDED') { - this.handleCompletedState(state) - } - } - }) - } - - /** - * DigibyteACCTv1 TRADEBOT STATES - * - BOB_WAITING_FOR_AT_CONFIRM - * - BOB_WAITING_FOR_MESSAGE - * - BOB_WAITING_FOR_AT_REDEEM - * - BOB_DONE - * - BOB_REFUNDED - * - ALICE_WAITING_FOR_AT_LOCK - * - ALICE_DONE - * - ALICE_REFUNDING_A - * - ALICE_REFUNDED - * - * @param {[{}]} states - */ - - const DigibyteACCTv1 = (states) => { - states.reverse() - states.forEach((state) => { - if (state.creatorAddress === this.selectedAddress.address) { - if (state.tradeState == 'BOB_WAITING_FOR_AT_CONFIRM') { - this.changeTradeBotState(state, 'PENDING') - } else if (state.tradeState == 'BOB_WAITING_FOR_MESSAGE') { - this.changeTradeBotState(state, 'LISTED') - } else if (state.tradeState == 'BOB_WAITING_FOR_AT_REDEEM') { - this.changeTradeBotState(state, 'TRADING') - } else if (state.tradeState == 'BOB_DONE') { - this.handleCompletedState(state) - } else if (state.tradeState == 'BOB_REFUNDED') { - this.handleCompletedState(state) - } else if (state.tradeState == 'ALICE_WAITING_FOR_AT_LOCK') { - this.changeTradeBotState(state, 'BUYING') - } else if (state.tradeState == 'ALICE_DONE') { - this.handleCompletedState(state) - } else if (state.tradeState == 'ALICE_REFUNDING_A') { - this.changeTradeBotState(state, 'REFUNDING') - } else if (state.tradeState == 'ALICE_REFUNDED') { - this.handleCompletedState(state) - } - } - }) - } - - /** - * RavencoinACCTv1 TRADEBOT STATES - * - BOB_WAITING_FOR_AT_CONFIRM - * - BOB_WAITING_FOR_MESSAGE - * - BOB_WAITING_FOR_AT_REDEEM - * - BOB_DONE - * - BOB_REFUNDED - * - ALICE_WAITING_FOR_AT_LOCK - * - ALICE_DONE - * - ALICE_REFUNDING_A - * - ALICE_REFUNDED - * - * @param {[{}]} states - */ - - const RavencoinACCTv1 = (states) => { - states.reverse() - states.forEach((state) => { - if (state.creatorAddress === this.selectedAddress.address) { - if (state.tradeState == 'BOB_WAITING_FOR_AT_CONFIRM') { - this.changeTradeBotState(state, 'PENDING') - } else if (state.tradeState == 'BOB_WAITING_FOR_MESSAGE') { - this.changeTradeBotState(state, 'LISTED') - } else if (state.tradeState == 'BOB_WAITING_FOR_AT_REDEEM') { - this.changeTradeBotState(state, 'TRADING') - } else if (state.tradeState == 'BOB_DONE') { - this.handleCompletedState(state) - } else if (state.tradeState == 'BOB_REFUNDED') { - this.handleCompletedState(state) - } else if (state.tradeState == 'ALICE_WAITING_FOR_AT_LOCK') { - this.changeTradeBotState(state, 'BUYING') - } else if (state.tradeState == 'ALICE_DONE') { - this.handleCompletedState(state) - } else if (state.tradeState == 'ALICE_REFUNDING_A') { - this.changeTradeBotState(state, 'REFUNDING') - } else if (state.tradeState == 'ALICE_REFUNDED') { - this.handleCompletedState(state) - } - } - }) - } - - /** - * PirateChainACCTv1 TRADEBOT STATES - * - BOB_WAITING_FOR_AT_CONFIRM - * - BOB_WAITING_FOR_MESSAGE - * - BOB_WAITING_FOR_AT_REDEEM - * - BOB_DONE - * - BOB_REFUNDED - * - ALICE_WAITING_FOR_AT_LOCK - * - ALICE_DONE - * - ALICE_REFUNDING_A - * - ALICE_REFUNDED - * - * @param {[{}]} states - */ - - const PirateChainACCTv1 = (states) => { - states.reverse() - states.forEach((state) => { - if (state.creatorAddress === this.selectedAddress.address) { - if (state.tradeState == 'BOB_WAITING_FOR_AT_CONFIRM') { - this.changeTradeBotState(state, 'PENDING') - } else if (state.tradeState == 'BOB_WAITING_FOR_MESSAGE') { - this.changeTradeBotState(state, 'LISTED') - } else if (state.tradeState == 'BOB_WAITING_FOR_AT_REDEEM') { - this.changeTradeBotState(state, 'TRADING') - } else if (state.tradeState == 'BOB_DONE') { - this.handleCompletedState(state) - } else if (state.tradeState == 'BOB_REFUNDED') { - this.handleCompletedState(state) - } else if (state.tradeState == 'ALICE_WAITING_FOR_AT_LOCK') { - this.changeTradeBotState(state, 'BUYING') - } else if (state.tradeState == 'ALICE_DONE') { - this.handleCompletedState(state) - } else if (state.tradeState == 'ALICE_REFUNDING_A') { - this.changeTradeBotState(state, 'REFUNDING') - } else if (state.tradeState == 'ALICE_REFUNDED') { - this.handleCompletedState(state) - } - } - }) - } - - switch (this.selectedCoin) { - case 'BITCOIN': - BitcoinACCTv1(tradeStates) - break - case 'LITECOIN': - LitecoinACCTv1(tradeStates) - break - case 'DOGECOIN': - DogecoinACCTv1(tradeStates) - break - case 'DIGIBYTE': - DigibyteACCTv1(tradeStates) - break - case 'RAVENCOIN': - RavencoinACCTv1(tradeStates) - break - case 'PIRATECHAIN': - PirateChainACCTv1(tradeStates) - break - default: - break - } - if (this.listedCoins.get(this.selectedCoin).tradeOffersSocketCounter === 1) { - setTimeout(() => this.filterStuckTrades(tradeStates), 250) - } - } - - changeTradeBotState(state, tradeState) { - this.isLoadingMyOpenOrders = true - const stateItem = { - ...state, - _tradeState: tradeState, - } - const item = this._myOrdersGrid.querySelector(`#${state.atAddress}`) - const addStateItem = () => { - this.reRenderMyOpenOrders() - this._myOrdersGrid.items.unshift(stateItem) - this._myOrdersGrid.clearCache() - } - const updateStateItem = () => { - this._myOrdersGrid.items.forEach((item, index) => { - if (item.atAddress === state.atAddress) { - this.reRenderMyOpenOrders() - this._myOrdersGrid.items.splice(index, 1) - this._myOrdersGrid.items.unshift(stateItem) - this._myOrdersGrid.clearCache() - } - }) - } - item ? updateStateItem() : addStateItem() - } - - handleCompletedState(state) { - this._myOrdersGrid.items.forEach((item, index) => { - if (item.atAddress === state.atAddress) { - this.reRenderMyOpenOrders() - this._myOrdersGrid.items.splice(index, 1) - this._myOrdersGrid.clearCache() - } - }) - } - - initSocket() { - let _relatedCoin = "" - let tradePresenceTxns = null - let offeringTrades = null - - self.addEventListener('message', function (event) { - switch (event.data.type) { - case 'open_orders': - offeringTrades = event.data.content - processOffersWithPresence() - break - case 'set_coin': - _relatedCoin = event.data.content - break - default: - break - } - }) - - const lessThanThirtyMinsAgo = (timestamp) => { - const THIRTYMINS = 1000 * 60 * 30 - const thirtyMinsAgo = Date.now() - THIRTYMINS - return timestamp > thirtyMinsAgo - } - - const filterOffersUsingTradePresence = (offeringTrade) => { - return offeringTrade.tradePresenceExpiry > Date.now(); - } - - const processOffersWithPresence = () => { - if (offeringTrades === null) return - - async function asyncForEach(array, callback) { - for (let index = 0; index < array.length; index++) { - await callback(array[index], index, array) - } - } - - const startOfferPresenceMapping = async () => { - - if (tradePresenceTxns !== null) { - await asyncForEach(tradePresenceTxns, async (tradePresence) => { - let offerIndex = offeringTrades.findIndex((offeringTrade) => offeringTrade.qortalCreatorTradeAddress === tradePresence.tradeAddress) - offerIndex !== -1 ? (offeringTrades[offerIndex].tradePresenceExpiry = tradePresence.timestamp) : null - }) - } - - let filteredOffers = offeringTrades.filter((offeringTrade) => filterOffersUsingTradePresence(offeringTrade)) - self.postMessage({ type: 'PRESENCE', data: { offers: offeringTrades, filteredOffers: filteredOffers, relatedCoin: _relatedCoin } }) - } - - startOfferPresenceMapping() - } - - const initTradeOffersWebSocket = (restarted = false) => { - let tradeOffersSocketCounter = 0 - let socketTimeout - let socketLink = `ws://NODEURL/websockets/crosschain/tradeoffers?foreignBlockchain=FOREIGN_BLOCKCHAIN&includeHistoric=true` - const socket = new WebSocket(socketLink) - socket.onopen = () => { - setTimeout(pingSocket, 50) - tradeOffersSocketCounter += 1 - } - socket.onmessage = (e) => { - e.relatedCoin = _relatedCoin - self.postMessage({ - type: 'TRADE_OFFERS', - data: e.data, - counter: tradeOffersSocketCounter, - isRestarted: restarted, - }) - tradeOffersSocketCounter += 1 - restarted = false - } - socket.onclose = () => { - clearTimeout(socketTimeout) - restartTradeOffersWebSocket() - } - socket.onerror = (e) => { - clearTimeout(socketTimeout) - } - const pingSocket = () => { - socket.send('ping') - socketTimeout = setTimeout(pingSocket, 295000) - } - } - - const initTradeBotWebSocket = (restarted = false) => { - let socketTimeout - let socketLink = `ws://NODEURL/websockets/crosschain/tradebot?foreignBlockchain=FOREIGN_BLOCKCHAIN` - const socket = new WebSocket(socketLink) - socket.onopen = () => { - setTimeout(pingSocket, 50) - } - socket.onmessage = (e) => { - e.relatedCoin = _relatedCoin - self.postMessage({ - type: 'TRADE_BOT', - data: e.data, - isRestarted: restarted, - }) - restarted = false - } - socket.onclose = () => { - clearTimeout(socketTimeout) - restartTradeBotWebSocket() - } - socket.onerror = (e) => { - clearTimeout(socketTimeout) - } - const pingSocket = () => { - socket.send('ping') - socketTimeout = setTimeout(pingSocket, 295000) - } - } - - const initTradePresenceWebSocket = (restarted = false) => { - let socketTimeout - let socketLink = `ws://NODEURL/websockets/crosschain/tradepresence` - const socket = new WebSocket(socketLink) - socket.onopen = () => { - setTimeout(pingSocket, 50) - } - socket.onmessage = (e) => { - tradePresenceTxns = JSON.parse(e.data) - processOffersWithPresence() - restarted = false - } - socket.onclose = () => { - clearTimeout(socketTimeout) - restartTradePresenceWebSocket() - } - socket.onerror = (e) => { - clearTimeout(socketTimeout) - } - const pingSocket = () => { - socket.send('ping') - socketTimeout = setTimeout(pingSocket, 295000) - } - } - - const restartTradePresenceWebSocket = () => { - setTimeout(() => initTradePresenceWebSocket(true), 50) - } - - const restartTradeOffersWebSocket = () => { - setTimeout(() => initTradeOffersWebSocket(true), 50) - } - - const restartTradeBotWebSocket = () => { - setTimeout(() => initTradeBotWebSocket(true), 50) - } - - initTradeOffersWebSocket() - initTradePresenceWebSocket() - initTradeBotWebSocket() - } - - async sellAction() { - this.isSellLoading = true - this.sellBtnDisable = true - await this.tradeFee() - const sellAmountInput = this.shadowRoot.getElementById('sellAmountInput').value - const sellTotalInput = this.shadowRoot.getElementById('sellTotalInput').value - const fundingQortAmount = this.round(parseFloat(sellAmountInput) + 0.001) - - const makeRequest = async () => { - let _receivingAddress = null - switch (this.selectedCoin) { - case 'BITCOIN': - _receivingAddress = this.selectedAddress.btcWallet.address - break - case 'LITECOIN': - _receivingAddress = this.selectedAddress.ltcWallet.address - break - case 'DOGECOIN': - _receivingAddress = this.selectedAddress.dogeWallet.address - break - case 'DIGIBYTE': - _receivingAddress = this.selectedAddress.dgbWallet.address - break - case 'RAVENCOIN': - _receivingAddress = this.selectedAddress.rvnWallet.address - break - case 'PIRATECHAIN': - _receivingAddress = this.arrrWalletAddress - break - default: - break - } + ` + } + + pingCoinBalancesController() { + if (!this.selectedCoin) return + let coin = '' + switch (this.selectedCoin) { + case 'BITCOIN': + coin = 'btc' + break + case 'LITECOIN': + coin = 'ltc' + break + case 'DOGECOIN': + coin = 'doge' + break + case 'DIGIBYTE': + coin = 'dgb' + break + case 'RAVENCOIN': + coin = 'rvn' + break + case 'PIRATECHAIN': + coin = 'arrr' + break + default: + break + } + const customEvent = new CustomEvent('ping-coin-controller-with-coin', { detail: coin }) + window.parent.dispatchEvent(customEvent) + } + + connectedCallback() { + super.connectedCallback() + this.intervalID = setInterval(this.pingCoinBalancesController, 30000) + } + + disconnectedCallback() { + super.disconnectedCallback() + if (this.intervalID) { + clearInterval(this.intervalID) + } + } + + clearConsole() { + if (!isElectron()) { + } else { + console.clear() + window.parent.electronAPI.clearCache() + } + } + + renderTradeLockButton() { + if (this.myTradeLockScreenPass === false && this.myTradeLockScreenSet === false) { + return html` +
    + this.openTradeSetScreenLockPass()} title="${translate("login.lp11")}"> +
    + ` + } else if (this.myTradeLockScreenSet === false) { + return html` +
    + this.setTradeLockQortal()} title="${translate("login.lp11")}"> +
    + ` + } else if (this.myTradeLockScreenSet === true) { + return html` +
    + +
    + ` + } + } + + openTradeSetScreenLockPass() { + this.shadowRoot.getElementById('tradeLockPassword').value = '' + this.shadowRoot.getElementById('tradeLockPasswordConfirm').value = '' + this.shadowRoot.getElementById('setTradeLockScreenPass').open() + } + + closewTradeSetScreenLockPass() { + this.shadowRoot.getElementById('setTradeLockScreenPass').close() + } + + tradeCheckPass() { + const tradePassword = this.shadowRoot.getElementById('tradeLockPassword').value + const tradeRePassword = this.shadowRoot.getElementById('tradeLockPasswordConfirm').value + + if (tradePassword === '') { + let snackbar1string = get("login.pleaseenter") + parentEpml.request('showSnackBar', `${snackbar1string}`) + return + } + + if (tradePassword != tradeRePassword) { + let snackbar2string = get("login.notmatch") + parentEpml.request('showSnackBar', `${snackbar2string}`) + return + } + + if (tradePassword.length < 8) { + let snackbar3string = get("login.lessthen8") + parentEpml.request('showSnackBar', `${snackbar3string}`) + this.tradeExtraConfirm() + } + + if (tradePassword.length >= 8) { + this.setTradeNewScreenPass() + let snackbar4string = get("login.lp6") + parentEpml.request('showSnackBar', `${snackbar4string}`) + } + } + + tradeExtraConfirm() { + this.shadowRoot.getElementById('setTradeLockScreenPass').close() + this.shadowRoot.getElementById('tradeExtraConfirmPass').open() + } + + closTradeExtraConfirmPass() { + this.shadowRoot.getElementById('tradeExtraConfirmPass').close() + this.shadowRoot.getElementById('tradeLockPassword').value = '' + this.shadowRoot.getElementById('tradeLockPasswordConfirm').value = '' + } + + setTradeNewScreenPass() { + const tradeRawPassword = this.shadowRoot.getElementById('tradeLockPassword').value + const tradeCryptPassword = encryptData(tradeRawPassword, this.tradeSalt) + localStorage.setItem(this.tradeLockScreenPass, tradeCryptPassword) + this.myTradeLockScreenPass = '' + this.myTradeLockScreenPass = decryptData(localStorage.getItem(this.tradeLockScreenPass), this.tradeSalt) + this.shadowRoot.getElementById('setTradeLockScreenPass').close() + this.shadowRoot.getElementById('tradeExtraConfirmPass').close() + this.shadowRoot.getElementById('tradeLockPassword').value = '' + this.shadowRoot.getElementById('tradeLockPasswordConfirm').value = '' + } + + setTradeLockQortal() { + this.tradeHelperMessage = this.renderTradeHelperPass() + this.tradeLockSet = '' + this.tradeLockSet = encryptData(true, this.tradeSalt) + localStorage.setItem(this.tradeLockScreenSet, this.tradeLockSet) + this.myTradeLockScreenSet = '' + this.myTradeLockScreenSet = decryptData(localStorage.getItem(this.tradeLockScreenSet), this.tradeSalt) + this.shadowRoot.getElementById('tradeLockScreenActive').open() + } + + tradePassKeyListener(e) { + if (e.key === 'Enter') { + this.closeTradeLockScreenActive() + } + } + + async closeTradeLockScreenActive() { + const myTradePass = decryptData(localStorage.getItem(this.tradeLockScreenPass), this.tradeSalt) + const tradeCheckPass = this.shadowRoot.getElementById('tradeUnlockPassword').value + const errDelay = ms => new Promise(res => setTimeout(res, ms)) + + if (tradeCheckPass === myTradePass) { + this.tradeLockSet = '' + this.tradeLockSet = encryptData(false, this.tradeSalt) + localStorage.setItem(this.tradeLockScreenSet, this.tradeLockSet) + this.myTradeLockScreenSet = '' + this.myTradeLockScreenSet = decryptData(localStorage.getItem(this.tradeLockScreenSet), this.tradeSalt) + this.shadowRoot.getElementById('tradeLockScreenActive').close() + this.shadowRoot.getElementById('tradeUnlockPassword').value = '' + this.tradeHelperMessage = this.renderTradeHelperPass() + } else { + this.shadowRoot.getElementById('tradeUnlockPassword').value = '' + this.tradeHelperMessage = this.renderTradeHelperErr() + await errDelay(3000) + this.tradeHelperMessage = this.renderTradeHelperPass() + + } + } + + renderTradeHelperPass() { + return html`${translate("login.pleaseenter")}` + } + + renderTradeHelperErr() { + return html`${translate("login.lp8")}` + } + + requestTraderInfo(traderAddress) { + let getAddress = traderAddress + const theInfoView = this.shadowRoot.querySelector('trader-info-view') + theInfoView.openTraderInfo(getAddress) + } + + requestTradeInfo(tradeObj) { + let seller = '' + let buyer = '' + let qortAmount = 0 + let foreignAmount = 0 + let ata = '' + let time = 0 + let coin = '' + seller = tradeObj.item.sellerAddress + buyer = tradeObj.item.buyerReceivingAddress + qortAmount = tradeObj.item.qortAmount + foreignAmount = tradeObj.item.foreignAmount + ata = tradeObj.item.atAddress + time = tradeObj.item.tradeTimestamp + coin = this.listedCoins.get(this.selectedCoin).coinCode + const theTradeInfoView = this.shadowRoot.querySelector('trade-info-view') + theTradeInfoView.openTradeInfo(seller, buyer, qortAmount, foreignAmount, ata, time, coin) + } + + changeTheme() { + const checkTheme = localStorage.getItem('qortalTheme') + this.theme = (checkTheme === 'dark') ? 'dark' : 'light' + document.querySelector('html').setAttribute('theme', this.theme); + } + + changeLanguage() { + const checkLanguage = localStorage.getItem('qortalLanguage') + if (checkLanguage === null || checkLanguage.length === 0) { + localStorage.setItem('qortalLanguage', 'us') + use('us') + } else { + use(checkLanguage) + } + } + + renderFetchText() { + return html`${translate("walletpage.wchange1")}` + } + + renderWarning() { + return html`NOT ENOUGH ${this.listedCoins.get(this.selectedCoin).coinCode}` + } + + chartShowCoin() { + switch (this.listedCoins.get(this.selectedCoin).coinCode) { + case "BTC": + return html` chartsbtc.open()}>` + break + case "LTC": + return html` chartsltc.open()}>` + break + case "DOGE": + return html` chartsdoge.open()}>` + break + case "DGB": + return html` chartsdgb.open()}>` + break + case "RVN": + return html` chartsrvn.open()}>` + break + case "ARRR": + return html` chartsarrr.open()}>` + break + default: + break + } + } + + exchangeRateQort() { + switch (this.listedCoins.get(this.selectedCoin).coinCode) { + case "BTC": + this.qortRatio = this.qortbtc + break + case "LTC": + this.qortRatio = this.qortltc + break + case "DOGE": + this.qortRatio = this.qortdoge + break + case "DGB": + this.qortRatio = this.qortdgb + break + case "RVN": + this.qortRatio = this.qortrvn + break + case "ARRR": + this.qortRatio = this.qortarrr + break + default: + break + } + return html`${this.qortRatio}` + } + + exchangeRateForeign() { + if (this.listedCoins.get(this.selectedCoin).coinCode === "BTC") { + parentEpml.request('apiCall', { + url: `/crosschain/price/BITCOIN?inverse=false` + }).then((res) => { + this.btcqort = (Number(res) / 1e8).toFixed(8) + }) + return html`${this.btcqort}` + } else if (this.listedCoins.get(this.selectedCoin).coinCode === "LTC") { + parentEpml.request('apiCall', { + url: `/crosschain/price/LITECOIN?inverse=false` + }).then((res) => { + this.ltcqort = (Number(res) / 1e8).toFixed(8) + }) + return html`${this.ltcqort}` + } else if (this.listedCoins.get(this.selectedCoin).coinCode === "DOGE") { + parentEpml.request('apiCall', { + url: `/crosschain/price/DOGECOIN?inverse=false` + }).then((res) => { + this.dogeqort = (Number(res) / 1e8).toFixed(8) + }) + return html`${this.dogeqort}` + } else if (this.listedCoins.get(this.selectedCoin).coinCode === "DGB") { + parentEpml.request('apiCall', { + url: `/crosschain/price/DIGIBYTE?inverse=false` + }).then((res) => { + this.dgbqort = (Number(res) / 1e8).toFixed(8) + }) + return html`${this.dgbqort}` + } else if (this.listedCoins.get(this.selectedCoin).coinCode === "RVN") { + parentEpml.request('apiCall', { + url: `/crosschain/price/RAVENCOIN?inverse=false` + }).then((res) => { + this.rvnqort = (Number(res) / 1e8).toFixed(8) + }) + return html`${this.rvnqort}` + } else if (this.listedCoins.get(this.selectedCoin).coinCode === "ARRR") { + parentEpml.request('apiCall', { + url: `/crosschain/price/PIRATECHAIN?inverse=false` + }).then((res) => { + this.arrrqort = (Number(res) / 1e8).toFixed(8) + }) + return html`${this.arrrqort}` + } + } + + async updateWalletBalance() { + let _url = `` + let _body = null + + switch (this.selectedCoin) { + case 'BITCOIN': + _url = `/crosschain/btc/walletbalance?apiKey=${this.getApiKey()}` + _body = window.parent.reduxStore.getState().app.selectedAddress.btcWallet.derivedMasterPublicKey + break + case 'LITECOIN': + _url = `/crosschain/ltc/walletbalance?apiKey=${this.getApiKey()}` + _body = window.parent.reduxStore.getState().app.selectedAddress.ltcWallet.derivedMasterPublicKey + break + case 'DOGECOIN': + _url = `/crosschain/doge/walletbalance?apiKey=${this.getApiKey()}` + _body = window.parent.reduxStore.getState().app.selectedAddress.dogeWallet.derivedMasterPublicKey + break + case 'DIGIBYTE': + _url = `/crosschain/dgb/walletbalance?apiKey=${this.getApiKey()}` + _body = window.parent.reduxStore.getState().app.selectedAddress.dgbWallet.derivedMasterPublicKey + break + case 'RAVENCOIN': + _url = `/crosschain/rvn/walletbalance?apiKey=${this.getApiKey()}` + _body = window.parent.reduxStore.getState().app.selectedAddress.rvnWallet.derivedMasterPublicKey + break + case 'PIRATECHAIN': + _url = `/crosschain/arrr/walletbalance?apiKey=${this.getApiKey()}` + _body = window.parent.reduxStore.getState().app.selectedAddress.arrrWallet.seed58 + break + default: + break + } + + this.showGetWalletBance = true + + await parentEpml.request('apiCall', { + url: _url, + method: 'POST', + body: _body + }).then((res) => { + if (isNaN(Number(res))) { + //... + } else { + this.listedCoins.get(this.selectedCoin).balance = (Number(res) / 1e8).toFixed(8) + } + }) + + this.showGetWalletBance = false + } + + async fetchWalletAddress(coin) { + switch (coin) { + case 'PIRATECHAIN': + let res = await parentEpml.request('apiCall', { + url: `/crosschain/arrr/walletaddress?apiKey=${this.getApiKey()}`, + method: 'POST', + body: `${window.parent.reduxStore.getState().app.selectedAddress.arrrWallet.seed58}` + }) + if (res != null && res.error != 1201) { + this.arrrWalletAddress = res + } + break + + default: + // Not used for other coins yet + break + } + } + + async setForeignCoin(coin, beingInitialized) { + let _this = this + this.selectedCoin = coin + + let coinSelectionMenu = this.shadowRoot.getElementById("coinSelectionMenu") + + if (beingInitialized) { + coinSelectionMenu.shadowRoot.querySelector('.mdc-select--outlined .mdc-select__anchor').setAttribute('style', 'padding-left: 60px;') + let pairIconContainer = document.createElement("span") + let pairicon = (_this.listedCoins.get(_this.selectedCoin).coinCode).toLowerCase() + pairIconContainer.setAttribute("class", "pairIconContainer") + pairIconContainer.setAttribute('style', 'left: 10px;top: 50%;transform: translate(0, -50%);height: 26px;width: 45px;position: absolute;background-repeat: no-repeat;background-size: cover;background-image: url(/img/qort' + pairicon + '.png);') + coinSelectionMenu.shadowRoot.querySelector('.mdc-select--outlined .mdc-select__anchor').appendChild(pairIconContainer) + } else { + let pairIconContainer = coinSelectionMenu.shadowRoot.querySelector(".mdc-select--outlined .mdc-select__anchor span.pairIconContainer") + let pairicon = (_this.listedCoins.get(_this.selectedCoin).coinCode).toLowerCase() + pairIconContainer.style.backgroundImage = 'url(/img/qort' + pairicon + '.png)' + } + + this.isLoadingHistoricTrades = true + this.isLoadingOpenTrades = true + this.createConnection() + this._openOrdersGrid.querySelector('#priceColumn').headerRenderer = function (root) { + const priceString2 = get("tradepage.tchange9") + root.innerHTML = '' + priceString2 + ' (' + _this.listedCoins.get(_this.selectedCoin).coinCode + ')' + } + this.clearSellForm() + this.clearBuyForm() + await this.updateWalletBalance() + await this.fetchWalletAddress(coin) + } + + displayTabContent(tab) { + const tabPane = this.shadowRoot.getElementById("tabs-1") + tabPane.setAttribute("activeIndex", (tab === 'buy') ? '0' : '1') + + const tabBuyContent = this.shadowRoot.getElementById('tab-buy-content') + tabBuyContent.style.display = (tab === 'buy') ? 'block' : 'none' + + const tabSellContent = this.shadowRoot.getElementById('tab-sell-content') + tabSellContent.style.display = (tab === 'sell') ? 'block' : 'none' + } + + setDefaultSellPrice() { + this.displayTabContent('sell') + const tabSellPrice = this.shadowRoot.getElementById('sellPriceInput') + tabSellPrice.value = this.qortRatio.isNaN ? 0 : this.qortRatio + } + + async reRenderHistoricTrades() { + this.requestUpdate() + await this.updateComplete + this.isLoadingHistoricTrades = false + } + + async reRenderOpenFilteredOrders() { + this.requestUpdate() + await this.updateComplete + this.isLoadingOpenTrades = false + } + + async reRenderMyOpenOrders() { + this.requestUpdate() + await this.updateComplete + this.isLoadingMyOpenOrders = false + } + + fillBuyForm(sellerRequest) { + this.shadowRoot.getElementById('buyAmountInput').value = parseFloat(sellerRequest.item.qortAmount) + this.shadowRoot.getElementById('buyPriceInput').value = this.round(parseFloat(sellerRequest.item.foreignAmount) / parseFloat(sellerRequest.item.qortAmount)) + this.shadowRoot.getElementById('buyTotalInput').value = parseFloat(sellerRequest.item.foreignAmount) + this.shadowRoot.getElementById('qortalAtAddress').value = sellerRequest.item.qortalAtAddress + const buyFunds = this.round(parseFloat(sellerRequest.item.foreignAmount)) + const haveFunds = this.round(parseFloat(this.listedCoins.get(this.selectedCoin).balance)) + if (Number(haveFunds) > Number(buyFunds)) { + this.buyBtnDisable = false + this.autoBuyWarning = false + this.displayTabContent('buy') + } else { + this.buyBtnDisable = true + this.autoBuyWarning = true + this.displayTabContent('buy') + } + + } + + processOfferingTrade(offer) { + try { + if (this.listedCoins.get(offer.foreignBlockchain).name != '') { + const offerItem = { + ...offer, + qortAmount: parseFloat(offer.qortAmount), + price: parseFloat(offer.foreignAmount) / parseFloat(offer.qortAmount), + } + const addOffer = () => { + this.listedCoins.get(offer.foreignBlockchain).openOrders.unshift(offerItem) + } + const initOffer = () => { + this.listedCoins.get(offer.foreignBlockchain).openOrders.push(offerItem) + } + this.listedCoins.get(offer.foreignBlockchain).openOrders.length === 0 ? initOffer() : addOffer() + this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1 ? this._openOrdersGrid.clearCache() : null + } + } catch (e) { + console.log("Error adding offer from " + offer.foreignBlockchain) + } + } + + processRedeemedTrade(offer) { + try { + if (this.listedCoins.get(offer.foreignBlockchain).name != '') { + + if (offer.qortalCreator === this.selectedAddress.address) { + if (this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1) { + this.updateWalletBalance() + } + const offerItem = { + ...offer, + mode: 'SOLD' + } + this._myHistoricTradesGrid.items.unshift(offerItem) + this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1 ? this._myHistoricTradesGrid.clearCache() : null + } else if (offer.partnerQortalReceivingAddress === this.selectedAddress.address) { + if (this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1) { + this.updateWalletBalance() + } + const offerItem = { + ...offer, + mode: 'BOUGHT' + } + this._myHistoricTradesGrid.items.unshift(offerItem) + this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1 ? this._myHistoricTradesGrid.clearCache() : null + } + const addNewHistoricTrade = () => { + this._historicTradesGrid.items.unshift(offer) + this._historicTradesGrid.clearCache() + } + this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1 ? addNewHistoricTrade() : null + + } + } catch (e) { + console.log("Error processing redeemed trade offer from " + offer.foreignBlockchain) + } + } + + processTradingTrade(offer) { + try { + if (this.listedCoins.get(offer.foreignBlockchain).name != '') { + + if (offer.qortalCreator === this.selectedAddress.address && this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1) { + this.updateWalletBalance() + } + this._openOrdersGrid.items.forEach((item, index) => { + if (item.qortalAtAddress === offer.qortalAtAddress) { + this._openOrdersGrid.items.splice(index, 1) + this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1 ? this._openOrdersGrid.clearCache() : null + } + }) + this.listedCoins.get(offer.foreignBlockchain).openOrders = this.listedCoins.get(offer.foreignBlockchain).openOrders.filter((order) => order.qortalAtAddress !== offer.qortalAtAddress) + } + } catch (e) { + console.log("Error processing trading trade offer from " + offer.foreignBlockchain) + } + } + + processRefundedTrade(offer) { + try { + if (this.listedCoins.get(offer.foreignBlockchain).name != '') { + + if (offer.qortalCreator === this.selectedAddress.address) { + if (this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1) { + this.updateWalletBalance() + } + this._myHistoricTradesGrid.items.unshift(offer) + this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1 ? this._myHistoricTradesGrid.clearCache() : null + } + + } + } catch (e) { + console.log("Error processing refunded trade offer from " + offer.foreignBlockchain) + } + } + + processCancelledTrade(offer) { + try { + if (this.listedCoins.get(offer.foreignBlockchain).name != '') { + + if (offer.qortalCreator === this.selectedAddress.address) { + if (this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1) { + this.updateWalletBalance() + } + this._myHistoricTradesGrid.items.unshift(offer) + this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1 ? this._myHistoricTradesGrid.clearCache() : null + } + this._openOrdersGrid.items.forEach((item, index) => { + if (item.qortalAtAddress === offer.qortalAtAddress) { + this._openOrdersGrid.items.splice(index, 1) + this.listedCoins.get(offer.foreignBlockchain).tradeOffersSocketCounter > 1 ? this._openOrdersGrid.clearCache() : null + } + }) + this.listedCoins.get(offer.foreignBlockchain).openOrders = this.listedCoins.get(offer.foreignBlockchain).openOrders.filter((order) => order.qortalAtAddress !== offer.qortalAtAddress) + this._stuckOrdersGrid.items.forEach((item, index) => { + if (item.qortalAtAddress === offer.qortalAtAddress) { + this._stuckOrdersGrid.items.splice(index, 1) + this._stuckOrdersGrid.clearCache() + } + }) + } + } catch (e) { + console.log("Error processing cancelled trade offer from " + offer.foreignBlockchain) + } + } + + /** + * TRADE OFFER STATES or MODE + * - OFFERING + * - REDEEMED + * - TRADING + * - REFUNDED + * - CANCELLED + */ + + processTradeOffers(offers) { + offers.forEach((offer) => { + if (offer.mode === 'OFFERING') { + this.processOfferingTrade(offer) + } else if (offer.mode === 'REDEEMED') { + this.processRedeemedTrade(offer) + } else if (offer.mode === 'TRADING') { + this.processTradingTrade(offer) + } else if (offer.mode === 'REFUNDED') { + this.processRefundedTrade(offer) + } else if (offer.mode === 'CANCELLED') { + this.processCancelledTrade(offer) + } + }) + } + + /** + * TradeBot Note by cat + * + * trade-bot entry states: + * - when you do /crosschain/tradebot/create, + * - it returns unsigned DEPLOY_AT for you to sign & broadcast + * - so initial trade-bot state is BOB_WAITING_FOR_AT_CONFIRM, because trade-bot is waiting for UI to sign & broadcast txn and for that txn to be confirmed into a block + * - once that happens & Bob's trade-bot notices that DEPLOY_AT has confirmed (and hence AT created and running), then it switches to BOB_WAITING_FOR_MESSAGE + * - which is Bob's trade-bot waiting for a message from Alice's trade-bot telling it (Bob's trade-bot) that Alice's trade-bot has funded P2SH-A and some other details + * - when that message is sent, Bob's trade-bot processes that message and sends its own message to the AT (which switches it to TRADING mode) + * - but the next state for Bob's trade-bot is to wait for Alice to spot AT is locked to her and for her to fund P2SH-B, hence BOB_WAITING_FOR_P2SH_B + * - at this point, Bob's trade-bot finds P2SH-B on the litecoin blockchain and can send secret-B to P2SH-B + * - when this happens, Alice uses secret-B and secret-A to redeem the QORT from the AT, so until Alice does this, Bob's trade-bot state is BOB_WAITING_FOR_AT_REDEEM + * - after Alice redeems QORT from AT, Bob can extract secret-A and capture the actual LTC funds from P2SH-A to his own litecoin account and hence his trade-bot moves to BOB_DONE + * - if anything goes wrong then refunds occur and Bob's trade-bot ends up at BOB_REFUNDED instead + * - I think you can probably guess the corresponding meaning of states for Alice's point of view, but if not I can go through those too? + * - Alice calls /crosschain/tradebot/respond which funds P2SH-A + * - so her trade-bot waits for that to appear in litecoin blockchain, so until then is ALICE_WAITING_FOR_P2SH_A + * - once the P2SH-A funding confirms, Alice's trade-bot can MESSAGE Bob's trade-bot with the details and changes to ALICE_WAITING_FOR_AT_LOCK + * - Bob's AT should then lock to trading with Alice (via those MESSAGEs above) and Alice's trade-bot notices this, (minimally) funds P2SH-B and waits until Bob 'spends' P2SH-B, hence ALICE_WATCH_P2SH_B + * - if Bob spends P2SH-B, then Alice can send secret-B and secret-A to the AT, claim the QORT and she's ALICE_DONE + * - if something goes wrong then her trade-bot needs to refund P2SH-B (if applicable) first (ALICE_REFUNDING_B) + * - and when that's done refund P2SH-A (ALICE_REFUNDING_A) + * - and when that's done her trade-bot ends up at ALICE_REFUNDED + * + * (PHEW) + */ + + processTradeBotStates(tradeStates) { + + /** + * BitcoinACCTv1 TRADEBOT STATES + * - BOB_WAITING_FOR_AT_CONFIRM + * - BOB_WAITING_FOR_MESSAGE + * - BOB_WAITING_FOR_AT_REDEEM + * - BOB_DONE + * - BOB_REFUNDED + * - ALICE_WAITING_FOR_AT_LOCK + * - ALICE_DONE + * - ALICE_REFUNDING_A + * - ALICE_REFUNDED + * + * @param {[{}]} states + */ + + const BitcoinACCTv1 = (states) => { + states.reverse() + states.forEach((state) => { + if (state.creatorAddress === this.selectedAddress.address) { + if (state.tradeState == 'BOB_WAITING_FOR_AT_CONFIRM') { + this.changeTradeBotState(state, 'PENDING') + } else if (state.tradeState == 'BOB_WAITING_FOR_MESSAGE') { + this.changeTradeBotState(state, 'LISTED') + } else if (state.tradeState == 'BOB_WAITING_FOR_AT_REDEEM') { + this.changeTradeBotState(state, 'TRADING') + } else if (state.tradeState == 'BOB_DONE') { + this.handleCompletedState(state) + } else if (state.tradeState == 'BOB_REFUNDED') { + this.handleCompletedState(state) + } else if (state.tradeState == 'ALICE_WAITING_FOR_AT_LOCK') { + this.changeTradeBotState(state, 'BUYING') + } else if (state.tradeState == 'ALICE_DONE') { + this.handleCompletedState(state) + } else if (state.tradeState == 'ALICE_REFUNDING_A') { + this.changeTradeBotState(state, 'REFUNDING') + } else if (state.tradeState == 'ALICE_REFUNDED') { + this.handleCompletedState(state) + } + } + }) + } + + /** + * LitecoinACCTv1 TRADEBOT STATES + * - BOB_WAITING_FOR_AT_CONFIRM + * - BOB_WAITING_FOR_MESSAGE + * - BOB_WAITING_FOR_AT_REDEEM + * - BOB_DONE + * - BOB_REFUNDED + * - ALICE_WAITING_FOR_AT_LOCK + * - ALICE_DONE + * - ALICE_REFUNDING_A + * - ALICE_REFUNDED + * + * @param {[{}]} states + */ + + const LitecoinACCTv1 = (states) => { + states.reverse() + states.forEach((state) => { + if (state.creatorAddress === this.selectedAddress.address) { + if (state.tradeState == 'BOB_WAITING_FOR_AT_CONFIRM') { + this.changeTradeBotState(state, 'PENDING') + } else if (state.tradeState == 'BOB_WAITING_FOR_MESSAGE') { + this.changeTradeBotState(state, 'LISTED') + } else if (state.tradeState == 'BOB_WAITING_FOR_AT_REDEEM') { + this.changeTradeBotState(state, 'TRADING') + } else if (state.tradeState == 'BOB_DONE') { + this.handleCompletedState(state) + } else if (state.tradeState == 'BOB_REFUNDED') { + this.handleCompletedState(state) + } else if (state.tradeState == 'ALICE_WAITING_FOR_AT_LOCK') { + this.changeTradeBotState(state, 'BUYING') + } else if (state.tradeState == 'ALICE_DONE') { + this.handleCompletedState(state) + } else if (state.tradeState == 'ALICE_REFUNDING_A') { + this.changeTradeBotState(state, 'REFUNDING') + } else if (state.tradeState == 'ALICE_REFUNDED') { + this.handleCompletedState(state) + } + } + }) + } + + /** + * DogecoinACCTv1 TRADEBOT STATES + * - BOB_WAITING_FOR_AT_CONFIRM + * - BOB_WAITING_FOR_MESSAGE + * - BOB_WAITING_FOR_AT_REDEEM + * - BOB_DONE + * - BOB_REFUNDED + * - ALICE_WAITING_FOR_AT_LOCK + * - ALICE_DONE + * - ALICE_REFUNDING_A + * - ALICE_REFUNDED + * + * @param {[{}]} states + */ + + const DogecoinACCTv1 = (states) => { + states.reverse() + states.forEach((state) => { + if (state.creatorAddress === this.selectedAddress.address) { + if (state.tradeState == 'BOB_WAITING_FOR_AT_CONFIRM') { + this.changeTradeBotState(state, 'PENDING') + } else if (state.tradeState == 'BOB_WAITING_FOR_MESSAGE') { + this.changeTradeBotState(state, 'LISTED') + } else if (state.tradeState == 'BOB_WAITING_FOR_AT_REDEEM') { + this.changeTradeBotState(state, 'TRADING') + } else if (state.tradeState == 'BOB_DONE') { + this.handleCompletedState(state) + } else if (state.tradeState == 'BOB_REFUNDED') { + this.handleCompletedState(state) + } else if (state.tradeState == 'ALICE_WAITING_FOR_AT_LOCK') { + this.changeTradeBotState(state, 'BUYING') + } else if (state.tradeState == 'ALICE_DONE') { + this.handleCompletedState(state) + } else if (state.tradeState == 'ALICE_REFUNDING_A') { + this.changeTradeBotState(state, 'REFUNDING') + } else if (state.tradeState == 'ALICE_REFUNDED') { + this.handleCompletedState(state) + } + } + }) + } + + /** + * DigibyteACCTv1 TRADEBOT STATES + * - BOB_WAITING_FOR_AT_CONFIRM + * - BOB_WAITING_FOR_MESSAGE + * - BOB_WAITING_FOR_AT_REDEEM + * - BOB_DONE + * - BOB_REFUNDED + * - ALICE_WAITING_FOR_AT_LOCK + * - ALICE_DONE + * - ALICE_REFUNDING_A + * - ALICE_REFUNDED + * + * @param {[{}]} states + */ + + const DigibyteACCTv1 = (states) => { + states.reverse() + states.forEach((state) => { + if (state.creatorAddress === this.selectedAddress.address) { + if (state.tradeState == 'BOB_WAITING_FOR_AT_CONFIRM') { + this.changeTradeBotState(state, 'PENDING') + } else if (state.tradeState == 'BOB_WAITING_FOR_MESSAGE') { + this.changeTradeBotState(state, 'LISTED') + } else if (state.tradeState == 'BOB_WAITING_FOR_AT_REDEEM') { + this.changeTradeBotState(state, 'TRADING') + } else if (state.tradeState == 'BOB_DONE') { + this.handleCompletedState(state) + } else if (state.tradeState == 'BOB_REFUNDED') { + this.handleCompletedState(state) + } else if (state.tradeState == 'ALICE_WAITING_FOR_AT_LOCK') { + this.changeTradeBotState(state, 'BUYING') + } else if (state.tradeState == 'ALICE_DONE') { + this.handleCompletedState(state) + } else if (state.tradeState == 'ALICE_REFUNDING_A') { + this.changeTradeBotState(state, 'REFUNDING') + } else if (state.tradeState == 'ALICE_REFUNDED') { + this.handleCompletedState(state) + } + } + }) + } + + /** + * RavencoinACCTv1 TRADEBOT STATES + * - BOB_WAITING_FOR_AT_CONFIRM + * - BOB_WAITING_FOR_MESSAGE + * - BOB_WAITING_FOR_AT_REDEEM + * - BOB_DONE + * - BOB_REFUNDED + * - ALICE_WAITING_FOR_AT_LOCK + * - ALICE_DONE + * - ALICE_REFUNDING_A + * - ALICE_REFUNDED + * + * @param {[{}]} states + */ + + const RavencoinACCTv1 = (states) => { + states.reverse() + states.forEach((state) => { + if (state.creatorAddress === this.selectedAddress.address) { + if (state.tradeState == 'BOB_WAITING_FOR_AT_CONFIRM') { + this.changeTradeBotState(state, 'PENDING') + } else if (state.tradeState == 'BOB_WAITING_FOR_MESSAGE') { + this.changeTradeBotState(state, 'LISTED') + } else if (state.tradeState == 'BOB_WAITING_FOR_AT_REDEEM') { + this.changeTradeBotState(state, 'TRADING') + } else if (state.tradeState == 'BOB_DONE') { + this.handleCompletedState(state) + } else if (state.tradeState == 'BOB_REFUNDED') { + this.handleCompletedState(state) + } else if (state.tradeState == 'ALICE_WAITING_FOR_AT_LOCK') { + this.changeTradeBotState(state, 'BUYING') + } else if (state.tradeState == 'ALICE_DONE') { + this.handleCompletedState(state) + } else if (state.tradeState == 'ALICE_REFUNDING_A') { + this.changeTradeBotState(state, 'REFUNDING') + } else if (state.tradeState == 'ALICE_REFUNDED') { + this.handleCompletedState(state) + } + } + }) + } + + /** + * PirateChainACCTv1 TRADEBOT STATES + * - BOB_WAITING_FOR_AT_CONFIRM + * - BOB_WAITING_FOR_MESSAGE + * - BOB_WAITING_FOR_AT_REDEEM + * - BOB_DONE + * - BOB_REFUNDED + * - ALICE_WAITING_FOR_AT_LOCK + * - ALICE_DONE + * - ALICE_REFUNDING_A + * - ALICE_REFUNDED + * + * @param {[{}]} states + */ + + const PirateChainACCTv1 = (states) => { + states.reverse() + states.forEach((state) => { + if (state.creatorAddress === this.selectedAddress.address) { + if (state.tradeState == 'BOB_WAITING_FOR_AT_CONFIRM') { + this.changeTradeBotState(state, 'PENDING') + } else if (state.tradeState == 'BOB_WAITING_FOR_MESSAGE') { + this.changeTradeBotState(state, 'LISTED') + } else if (state.tradeState == 'BOB_WAITING_FOR_AT_REDEEM') { + this.changeTradeBotState(state, 'TRADING') + } else if (state.tradeState == 'BOB_DONE') { + this.handleCompletedState(state) + } else if (state.tradeState == 'BOB_REFUNDED') { + this.handleCompletedState(state) + } else if (state.tradeState == 'ALICE_WAITING_FOR_AT_LOCK') { + this.changeTradeBotState(state, 'BUYING') + } else if (state.tradeState == 'ALICE_DONE') { + this.handleCompletedState(state) + } else if (state.tradeState == 'ALICE_REFUNDING_A') { + this.changeTradeBotState(state, 'REFUNDING') + } else if (state.tradeState == 'ALICE_REFUNDED') { + this.handleCompletedState(state) + } + } + }) + } + + switch (this.selectedCoin) { + case 'BITCOIN': + BitcoinACCTv1(tradeStates) + break + case 'LITECOIN': + LitecoinACCTv1(tradeStates) + break + case 'DOGECOIN': + DogecoinACCTv1(tradeStates) + break + case 'DIGIBYTE': + DigibyteACCTv1(tradeStates) + break + case 'RAVENCOIN': + RavencoinACCTv1(tradeStates) + break + case 'PIRATECHAIN': + PirateChainACCTv1(tradeStates) + break + default: + break + } + if (this.listedCoins.get(this.selectedCoin).tradeOffersSocketCounter === 1) { + setTimeout(() => this.filterStuckTrades(tradeStates), 250) + } + } + + changeTradeBotState(state, tradeState) { + this.isLoadingMyOpenOrders = true + const stateItem = { + ...state, + _tradeState: tradeState, + } + const item = this._myOrdersGrid.querySelector(`#${state.atAddress}`) + const addStateItem = () => { + this.reRenderMyOpenOrders() + this._myOrdersGrid.items.unshift(stateItem) + this._myOrdersGrid.clearCache() + } + const updateStateItem = () => { + this._myOrdersGrid.items.forEach((item, index) => { + if (item.atAddress === state.atAddress) { + this.reRenderMyOpenOrders() + this._myOrdersGrid.items.splice(index, 1) + this._myOrdersGrid.items.unshift(stateItem) + this._myOrdersGrid.clearCache() + } + }) + } + item ? updateStateItem() : addStateItem() + } + + handleCompletedState(state) { + this._myOrdersGrid.items.forEach((item, index) => { + if (item.atAddress === state.atAddress) { + this.reRenderMyOpenOrders() + this._myOrdersGrid.items.splice(index, 1) + this._myOrdersGrid.clearCache() + } + }) + } + + initSocket() { + let _relatedCoin = "" + let tradePresenceTxns = null + let offeringTrades = null + + self.addEventListener('message', function (event) { + switch (event.data.type) { + case 'open_orders': + offeringTrades = event.data.content + processOffersWithPresence() + break + case 'set_coin': + _relatedCoin = event.data.content + break + default: + break + } + }) + + const lessThanThirtyMinsAgo = (timestamp) => { + const THIRTYMINS = 1000 * 60 * 30 + const thirtyMinsAgo = Date.now() - THIRTYMINS + return timestamp > thirtyMinsAgo + } + + const filterOffersUsingTradePresence = (offeringTrade) => { + return offeringTrade.tradePresenceExpiry > Date.now(); + } + + const processOffersWithPresence = () => { + if (offeringTrades === null) return + + async function asyncForEach(array, callback) { + for (let index = 0; index < array.length; index++) { + await callback(array[index], index, array) + } + } + + const startOfferPresenceMapping = async () => { + + if (tradePresenceTxns !== null) { + await asyncForEach(tradePresenceTxns, async (tradePresence) => { + let offerIndex = offeringTrades.findIndex((offeringTrade) => offeringTrade.qortalCreatorTradeAddress === tradePresence.tradeAddress) + offerIndex !== -1 ? (offeringTrades[offerIndex].tradePresenceExpiry = tradePresence.timestamp) : null + }) + } + + let filteredOffers = offeringTrades.filter((offeringTrade) => filterOffersUsingTradePresence(offeringTrade)) + self.postMessage({ type: 'PRESENCE', data: { offers: offeringTrades, filteredOffers: filteredOffers, relatedCoin: _relatedCoin } }) + } + + startOfferPresenceMapping() + } + + const initTradeOffersWebSocket = (restarted = false) => { + let tradeOffersSocketCounter = 0 + let socketTimeout + let socketLink = `ws://NODEURL/websockets/crosschain/tradeoffers?foreignBlockchain=FOREIGN_BLOCKCHAIN&includeHistoric=true` + const socket = new WebSocket(socketLink) + socket.onopen = () => { + setTimeout(pingSocket, 50) + tradeOffersSocketCounter += 1 + } + socket.onmessage = (e) => { + e.relatedCoin = _relatedCoin + self.postMessage({ + type: 'TRADE_OFFERS', + data: e.data, + counter: tradeOffersSocketCounter, + isRestarted: restarted, + }) + tradeOffersSocketCounter += 1 + restarted = false + } + socket.onclose = () => { + clearTimeout(socketTimeout) + restartTradeOffersWebSocket() + } + socket.onerror = (e) => { + clearTimeout(socketTimeout) + } + const pingSocket = () => { + socket.send('ping') + socketTimeout = setTimeout(pingSocket, 295000) + } + } + + const initTradeBotWebSocket = (restarted = false) => { + let socketTimeout + let socketLink = `ws://NODEURL/websockets/crosschain/tradebot?foreignBlockchain=FOREIGN_BLOCKCHAIN` + const socket = new WebSocket(socketLink) + socket.onopen = () => { + setTimeout(pingSocket, 50) + } + socket.onmessage = (e) => { + e.relatedCoin = _relatedCoin + self.postMessage({ + type: 'TRADE_BOT', + data: e.data, + isRestarted: restarted, + }) + restarted = false + } + socket.onclose = () => { + clearTimeout(socketTimeout) + restartTradeBotWebSocket() + } + socket.onerror = (e) => { + clearTimeout(socketTimeout) + } + const pingSocket = () => { + socket.send('ping') + socketTimeout = setTimeout(pingSocket, 295000) + } + } + + const initTradePresenceWebSocket = (restarted = false) => { + let socketTimeout + let socketLink = `ws://NODEURL/websockets/crosschain/tradepresence` + const socket = new WebSocket(socketLink) + socket.onopen = () => { + setTimeout(pingSocket, 50) + } + socket.onmessage = (e) => { + tradePresenceTxns = JSON.parse(e.data) + processOffersWithPresence() + restarted = false + } + socket.onclose = () => { + clearTimeout(socketTimeout) + restartTradePresenceWebSocket() + } + socket.onerror = (e) => { + clearTimeout(socketTimeout) + } + const pingSocket = () => { + socket.send('ping') + socketTimeout = setTimeout(pingSocket, 295000) + } + } + + const restartTradePresenceWebSocket = () => { + setTimeout(() => initTradePresenceWebSocket(true), 50) + } + + const restartTradeOffersWebSocket = () => { + setTimeout(() => initTradeOffersWebSocket(true), 50) + } + + const restartTradeBotWebSocket = () => { + setTimeout(() => initTradeBotWebSocket(true), 50) + } + + initTradeOffersWebSocket() + initTradePresenceWebSocket() + initTradeBotWebSocket() + } + + async sellAction() { + this.isSellLoading = true + this.sellBtnDisable = true + await this.tradeFee() + const sellAmountInput = this.shadowRoot.getElementById('sellAmountInput').value + const sellTotalInput = this.shadowRoot.getElementById('sellTotalInput').value + const fundingQortAmount = this.round(parseFloat(sellAmountInput) + 0.001) + + const makeRequest = async () => { + let _receivingAddress = null + switch (this.selectedCoin) { + case 'BITCOIN': + _receivingAddress = this.selectedAddress.btcWallet.address + break + case 'LITECOIN': + _receivingAddress = this.selectedAddress.ltcWallet.address + break + case 'DOGECOIN': + _receivingAddress = this.selectedAddress.dogeWallet.address + break + case 'DIGIBYTE': + _receivingAddress = this.selectedAddress.dgbWallet.address + break + case 'RAVENCOIN': + _receivingAddress = this.selectedAddress.rvnWallet.address + break + case 'PIRATECHAIN': + _receivingAddress = this.arrrWalletAddress + break + default: + break + } return await parentEpml.request('tradeBotCreateRequest', { creatorPublicKey: this.selectedAddress.base58PublicKey, qortAmount: parseFloat(sellAmountInput), @@ -2247,579 +2264,576 @@ class TradePortal extends LitElement { foreignBlockchain: this.selectedCoin, foreignAmount: parseFloat(sellTotalInput), tradeTimeout: 120, - receivingAddress: _receivingAddress, + receivingAddress: _receivingAddress }) - } + } - const manageResponse = (response) => { - if (response === true) { - this.isSellLoading = false - this.sellBtnDisable = false - this.shadowRoot.getElementById('sellAmountInput').value = this.initialAmount - this.shadowRoot.getElementById('sellPriceInput').value = this.initialAmount - this.shadowRoot.getElementById('sellTotalInput').value = this.initialAmount - } else if (response === false) { - this.isSellLoading = false - this.sellBtnDisable = false - let snack2string = get("tradepage.tchange20") - parentEpml.request('showSnackBar', `${snack2string}`) - } else { - this.isSellLoading = false - this.sellBtnDisable = false - let snack3string = get("tradepage.tchange21") - parentEpml.request('showSnackBar', `${snack3string}: ${response.message}`) - } - } + const manageResponse = (response) => { + if (response === true) { + this.isSellLoading = false + this.sellBtnDisable = false + this.shadowRoot.getElementById('sellAmountInput').value = this.initialAmount + this.shadowRoot.getElementById('sellPriceInput').value = this.initialAmount + this.shadowRoot.getElementById('sellTotalInput').value = this.initialAmount + } else if (response === false) { + this.isSellLoading = false + this.sellBtnDisable = false + let snack2string = get("tradepage.tchange20") + parentEpml.request('showSnackBar', `${snack2string}`) + } else { + this.isSellLoading = false + this.sellBtnDisable = false + let snack3string = get("tradepage.tchange21") + parentEpml.request('showSnackBar', `${snack3string}: ${response.message}`) + } + } - if (this.round(parseFloat(fundingQortAmount) + parseFloat(this.listedCoins.get("QORTAL").tradeFee)) > parseFloat(this.listedCoins.get("QORTAL").balance)) { - this.isSellLoading = false - this.sellBtnDisable = false - let snack4string = get("tradepage.tchange22") - parentEpml.request('showSnackBar', `${snack4string}`) - return false - } else { - const res = await makeRequest() - manageResponse(res) - } - } + if (this.round(parseFloat(fundingQortAmount) + parseFloat(this.listedCoins.get("QORTAL").tradeFee)) > parseFloat(this.listedCoins.get("QORTAL").balance)) { + this.isSellLoading = false + this.sellBtnDisable = false + let snack4string = get("tradepage.tchange22") + parentEpml.request('showSnackBar', `${snack4string}`) + return false + } else { + const res = await makeRequest() + manageResponse(res) + } + } - async buyAction() { - this.isBuyLoading = true - this.buyBtnDisable = true - const qortalAtAddress = this.shadowRoot.getElementById('qortalAtAddress').value - let _foreignKey = "" + async buyAction() { + this.isBuyLoading = true + this.buyBtnDisable = true + const qortalAtAddress = this.shadowRoot.getElementById('qortalAtAddress').value + let _foreignKey = "" - switch (this.selectedCoin) { - case 'BITCOIN': - _foreignKey = this.selectedAddress.btcWallet.derivedMasterPrivateKey - break - case 'LITECOIN': - _foreignKey = this.selectedAddress.ltcWallet.derivedMasterPrivateKey - break - case 'DOGECOIN': - _foreignKey = this.selectedAddress.dogeWallet.derivedMasterPrivateKey - break - case 'DIGIBYTE': - _foreignKey = this.selectedAddress.dgbWallet.derivedMasterPrivateKey - break + switch (this.selectedCoin) { + case 'BITCOIN': + _foreignKey = this.selectedAddress.btcWallet.derivedMasterPrivateKey + break + case 'LITECOIN': + _foreignKey = this.selectedAddress.ltcWallet.derivedMasterPrivateKey + break + case 'DOGECOIN': + _foreignKey = this.selectedAddress.dogeWallet.derivedMasterPrivateKey + break + case 'DIGIBYTE': + _foreignKey = this.selectedAddress.dgbWallet.derivedMasterPrivateKey + break case 'RAVENCOIN': - _foreignKey = this.selectedAddress.rvnWallet.derivedMasterPrivateKey - break - case 'PIRATECHAIN': - _foreignKey = this.selectedAddress.arrrWallet.seed58 - break - default: - break - } + _foreignKey = this.selectedAddress.rvnWallet.derivedMasterPrivateKey + break + case 'PIRATECHAIN': + _foreignKey = this.selectedAddress.arrrWallet.seed58 + break + default: + break + } - const makeRequest = async () => { + const makeRequest = async () => { return await parentEpml.request('tradeBotRespondRequest', { atAddress: qortalAtAddress, foreignKey: _foreignKey, - receivingAddress: this.selectedAddress.address, + receivingAddress: this.selectedAddress.address }) - } + } - const manageResponse = (response) => { - if (response === true) { - this.isBuyLoading = false - this.buyBtnDisable = true - this.shadowRoot.getElementById('buyAmountInput').value = this.initialAmount - this.shadowRoot.getElementById('buyPriceInput').value = this.initialAmount - this.shadowRoot.getElementById('buyTotalInput').value = this.initialAmount - this.shadowRoot.getElementById('qortalAtAddress').value = '' - let snack5string = get("tradepage.tchange23") - parentEpml.request('showSnackBar', `${snack5string}`) - } else if (response === false) { - this.isBuyLoading = false - this.buyBtnDisable = false - let snack6string = get("tradepage.tchange24") - parentEpml.request('showSnackBar', `${snack6string}`) - } else { - this.isBuyLoading = false - this.buyBtnDisable = false - let snack7string = get("tradepage.tchange25") - parentEpml.request('showSnackBar', `${snack7string}: ${response.message}`) - } - } - const res = await makeRequest() - manageResponse(res) - } + const manageResponse = (response) => { + if (response === true) { + this.isBuyLoading = false + this.buyBtnDisable = true + this.shadowRoot.getElementById('buyAmountInput').value = this.initialAmount + this.shadowRoot.getElementById('buyPriceInput').value = this.initialAmount + this.shadowRoot.getElementById('buyTotalInput').value = this.initialAmount + this.shadowRoot.getElementById('qortalAtAddress').value = '' + let snack5string = get("tradepage.tchange23") + parentEpml.request('showSnackBar', `${snack5string}`) + } else if (response === false) { + this.isBuyLoading = false + this.buyBtnDisable = false + let snack6string = get("tradepage.tchange24") + parentEpml.request('showSnackBar', `${snack6string}`) + } else { + this.isBuyLoading = false + this.buyBtnDisable = false + let snack7string = get("tradepage.tchange25") + parentEpml.request('showSnackBar', `${snack7string}: ${response.message}`) + } + } + const res = await makeRequest() + manageResponse(res) + } - async cancelAction(state) { - const button = this.shadowRoot.querySelector(`mwc-button#${state.atAddress}`) - button.innerHTML = `` - this.cancelBtnDisable = true + async cancelAction(state) { + const button = this.shadowRoot.querySelector(`mwc-button#${state.atAddress}`) + button.innerHTML = `` + this.cancelBtnDisable = true - const makeRequest = async () => { + const makeRequest = async () => { return await parentEpml.request('deleteTradeOffer', { creatorPublicKey: this.selectedAddress.base58PublicKey, - atAddress: state.atAddress, + atAddress: state.atAddress }) - } + } - const manageResponse = (response) => { - if (response === true) { - button.remove() - this.cancelBtnDisable = false - let snack8string = get("tradepage.tchange26") - parentEpml.request('showSnackBar', `${snack8string}`) - } else if (response === false) { - button.innerHTML = 'CANCEL' - this.cancelBtnDisable = false - let snack9string = get("tradepage.tchange27") - parentEpml.request('showSnackBar', `${snack9string}`) - } else { - button.innerHTML = 'CANCEL' - this.cancelBtnDisable = false - let snack10string = get("tradepage.tchange28") - parentEpml.request('showSnackBar', `${snack10string}: ${response.message}`) - } - } - const res = await makeRequest() - manageResponse(res) - } + const manageResponse = (response) => { + if (response === true) { + button.remove() + this.cancelBtnDisable = false + let snack8string = get("tradepage.tchange26") + parentEpml.request('showSnackBar', `${snack8string}`) + } else if (response === false) { + button.innerHTML = 'CANCEL' + this.cancelBtnDisable = false + let snack9string = get("tradepage.tchange27") + parentEpml.request('showSnackBar', `${snack9string}`) + } else { + button.innerHTML = 'CANCEL' + this.cancelBtnDisable = false + let snack10string = get("tradepage.tchange28") + parentEpml.request('showSnackBar', `${snack10string}: ${response.message}`) + } + } + const res = await makeRequest() + manageResponse(res) + } - updateAccountBalance() { - clearTimeout(this.updateAccountBalanceTimeout) - parentEpml.request('apiCall', { - url: `/addresses/balance/${this.selectedAddress.address}?apiKey=${this.getApiKey()}`, - }) - .then((res) => { - this.listedCoins.get("QORTAL").balance = res - this.updateAccountBalanceTimeout = setTimeout(() => this.updateAccountBalance(), 10000) - }) - } + updateAccountBalance() { + clearTimeout(this.updateAccountBalanceTimeout) + parentEpml.request('apiCall', { + url: `/addresses/balance/${this.selectedAddress.address}?apiKey=${this.getApiKey()}`, + }).then((res) => { + this.listedCoins.get("QORTAL").balance = res + this.updateAccountBalanceTimeout = setTimeout(() => this.updateAccountBalance(), 10000) + }) + } - renderCancelButton(stateItem) { - if (stateItem.tradeState === 'BOB_WAITING_FOR_MESSAGE') { - return html` this.cancelAction(stateItem)}>${translate("tradepage.tchange29")}` - } else { - return '' - } - } + renderCancelButton(stateItem) { + if (stateItem.tradeState === 'BOB_WAITING_FOR_MESSAGE') { + return html` this.cancelAction(stateItem)}>${translate("tradepage.tchange29")}` + } else { + return '' + } + } - showStuckOrdersDialog() { - this.shadowRoot.querySelector('#manageStuckOrdersDialog').show() - } + showStuckOrdersDialog() { + this.shadowRoot.querySelector('#manageStuckOrdersDialog').show() + } - async cancelStuckOfferAction(offer) { - this.cancelStuckOfferBtnDisable = true + async cancelStuckOfferAction(offer) { + this.cancelStuckOfferBtnDisable = true - const makeRequest = async () => { + const makeRequest = async () => { return await parentEpml.request('deleteTradeOffer', { creatorPublicKey: this.selectedAddress.base58PublicKey, - atAddress: offer.qortalAtAddress, + atAddress: offer.qortalAtAddress }) - } + } - const manageResponse = (response) => { - if (response === true) { - this.cancelStuckOfferBtnDisable = false - let snack11string = get("tradepage.tchange26") - parentEpml.request('showSnackBar', `${snack11string}`) - } else if (response === false) { - this.cancelStuckOfferBtnDisable = false - let snack12string = get("tradepage.tchange27") - parentEpml.request('showSnackBar', `${snack12string}`) - } else { - this.cancelStuckOfferBtnDisable = false - let snack13string = get("tradepage.tchange28") - parentEpml.request('showSnackBar', `${snack13string}: ${response.message}`) - } - } - const res = await makeRequest() - manageResponse(res) - } + const manageResponse = (response) => { + if (response === true) { + this.cancelStuckOfferBtnDisable = false + let snack11string = get("tradepage.tchange26") + parentEpml.request('showSnackBar', `${snack11string}`) + } else if (response === false) { + this.cancelStuckOfferBtnDisable = false + let snack12string = get("tradepage.tchange27") + parentEpml.request('showSnackBar', `${snack12string}`) + } else { + this.cancelStuckOfferBtnDisable = false + let snack13string = get("tradepage.tchange28") + parentEpml.request('showSnackBar', `${snack13string}: ${response.message}`) + } + } + const res = await makeRequest() + manageResponse(res) + } - renderCancelStuckOfferButton(offerItem) { - if (offerItem.mode === 'OFFERING' && offerItem.qortalCreator === this.selectedAddress.address) { - return html` this.cancelStuckOfferAction(offerItem)}>CANCEL` - } else { - return '' - } - } + renderCancelStuckOfferButton(offerItem) { + if (offerItem.mode === 'OFFERING' && offerItem.qortalCreator === this.selectedAddress.address) { + return html` this.cancelStuckOfferAction(offerItem)}>CANCEL` + } else { + return '' + } + } - _checkSellAmount(e) { - const targetAmount = e.target.value - const target = e.target + _checkSellAmount(e) { + const targetAmount = e.target.value + const target = e.target - if (targetAmount.length === 0) { - this.isValidAmount = false - this.sellBtnDisable = true - e.target.blur() - e.target.focus() - e.target.invalid = true - } else { - const sellAmountInput = this.shadowRoot.getElementById('sellAmountInput').value - const sellPriceInput = this.shadowRoot.getElementById('sellPriceInput').value - this.shadowRoot.getElementById('sellTotalInput').value = this.round(parseFloat(sellAmountInput) * parseFloat(sellPriceInput)) - this.sellBtnDisable = false - } + if (targetAmount.length === 0) { + this.isValidAmount = false + this.sellBtnDisable = true + e.target.blur() + e.target.focus() + e.target.invalid = true + } else { + const sellAmountInput = this.shadowRoot.getElementById('sellAmountInput').value + const sellPriceInput = this.shadowRoot.getElementById('sellPriceInput').value + this.shadowRoot.getElementById('sellTotalInput').value = this.round(parseFloat(sellAmountInput) * parseFloat(sellPriceInput)) + this.sellBtnDisable = false + } - e.target.blur() - e.target.focus() + e.target.blur() + e.target.focus() - e.target.validityTransform = (newValue, nativeValidity) => { - if (newValue.includes('-') === true) { - this.sellBtnDisable = true - return { - valid: false, - } - } else if (!nativeValidity.valid) { - if (newValue.includes('.') === true) { - let myAmount = newValue.split('.') - if (myAmount[1].length > 8) { - this.sellBtnDisable = true - } else { - const sellAmountInput = this.shadowRoot.getElementById('sellAmountInput').value - const sellPriceInput = this.shadowRoot.getElementById('sellPriceInput').value - this.shadowRoot.getElementById('sellTotalInput').value = this.round(parseFloat(sellAmountInput) * parseFloat(sellPriceInput)) - this.sellBtnDisable = false - return { - valid: true, - } - } - } - } else { - const sellAmountInput = this.shadowRoot.getElementById('sellAmountInput').value - const sellPriceInput = this.shadowRoot.getElementById('sellPriceInput').value - this.shadowRoot.getElementById('sellTotalInput').value = this.round(parseFloat(sellAmountInput) * parseFloat(sellPriceInput)) - this.sellBtnDisable = false - } - } - } + e.target.validityTransform = (newValue, nativeValidity) => { + if (newValue.includes('-') === true) { + this.sellBtnDisable = true + return { + valid: false + } + } else if (!nativeValidity.valid) { + if (newValue.includes('.') === true) { + let myAmount = newValue.split('.') + if (myAmount[1].length > 8) { + this.sellBtnDisable = true + } else { + const sellAmountInput = this.shadowRoot.getElementById('sellAmountInput').value + const sellPriceInput = this.shadowRoot.getElementById('sellPriceInput').value + this.shadowRoot.getElementById('sellTotalInput').value = this.round(parseFloat(sellAmountInput) * parseFloat(sellPriceInput)) + this.sellBtnDisable = false + return { + valid: true + } + } + } + } else { + const sellAmountInput = this.shadowRoot.getElementById('sellAmountInput').value + const sellPriceInput = this.shadowRoot.getElementById('sellPriceInput').value + this.shadowRoot.getElementById('sellTotalInput').value = this.round(parseFloat(sellAmountInput) * parseFloat(sellPriceInput)) + this.sellBtnDisable = false + } + } + } - _checkBuyAmount(e) { - const targetAmount = e.target.value - const target = e.target + _checkBuyAmount(e) { + const targetAmount = e.target.value + const target = e.target - if (targetAmount.length === 0) { - this.isValidAmount = false - this.sellBtnDisable = true - e.target.blur() - e.target.focus() - e.target.invalid = true - } else { - this.buyBtnDisable = false - } + if (targetAmount.length === 0) { + this.isValidAmount = false + this.sellBtnDisable = true + e.target.blur() + e.target.focus() + e.target.invalid = true + } else { + this.buyBtnDisable = false + } - e.target.blur() - e.target.focus() + e.target.blur() + e.target.focus() - e.target.validityTransform = (newValue, nativeValidity) => { - if (newValue.includes('-') === true) { - this.buyBtnDisable = true - return { - valid: false, - } - } else if (!nativeValidity.valid) { - if (newValue.includes('.') === true) { - let myAmount = newValue.split('.') - if (myAmount[1].length > 8) { - this.buyBtnDisable = true - } else { - this.buyBtnDisable = false - return { - valid: true, - } - } - } - } else { - this.buyBtnDisable = false - } - } - } + e.target.validityTransform = (newValue, nativeValidity) => { + if (newValue.includes('-') === true) { + this.buyBtnDisable = true + return { + valid: false + } + } else if (!nativeValidity.valid) { + if (newValue.includes('.') === true) { + let myAmount = newValue.split('.') + if (myAmount[1].length > 8) { + this.buyBtnDisable = true + } else { + this.buyBtnDisable = false + return { + valid: true + } + } + } + } else { + this.buyBtnDisable = false + } + } + } - async tradeFee() { - const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] - const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port - const url = `${nodeUrl}/transactions/unitfee?txType=DEPLOY_AT` - await fetch(url).then((response) => { - if (response.ok) { - return response.json() - } - return Promise.reject(response) - }).then((json) => { - this.listedCoins.get("QORTAL").tradeFee = (Number(json) * 2) / 1e8 - }) - } + async tradeFee() { + const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] + const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port + const url = `${nodeUrl}/transactions/unitfee?txType=DEPLOY_AT` + await fetch(url).then((response) => { + if (response.ok) { + return response.json() + } + return Promise.reject(response) + }).then((json) => { + this.listedCoins.get("QORTAL").tradeFee = (Number(json) * 2) / 1e8 + }) + } + clearBuyForm() { + this.shadowRoot.getElementById('buyAmountInput').value = this.initialAmount + this.shadowRoot.getElementById('buyPriceInput').value = this.initialAmount + this.shadowRoot.getElementById('buyTotalInput').value = this.initialAmount + this.shadowRoot.getElementById('qortalAtAddress').value = '' + this.buyBtnDisable = true + } - getApiKey() { - const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]; - return myNode.apiKey; - } + clearSellForm() { + this.shadowRoot.getElementById('sellAmountInput').value = this.initialAmount + this.shadowRoot.getElementById('sellPriceInput').value = this.initialAmount + this.shadowRoot.getElementById('sellTotalInput').value = this.initialAmount + } - clearBuyForm() { - this.shadowRoot.getElementById('buyAmountInput').value = this.initialAmount - this.shadowRoot.getElementById('buyPriceInput').value = this.initialAmount - this.shadowRoot.getElementById('buyTotalInput').value = this.initialAmount - this.shadowRoot.getElementById('qortalAtAddress').value = '' - this.buyBtnDisable = true - } + /** + * Inline Worker - Takes in a function and a modifier then returns an instance of a Web Worker + * + * - Modifiers are simply an Array of Object containing placeholders (containers for variables used in the passedFunction ) in the and its values. + * These placeholders gets replaced with it value during instantiation of the function to be used by the Worker. + * - Example of modifiers: const modifiers = [ + * { searchValue: 'SELECTED_ADDRESS', replaceValue: this.selectedAddress.address, }, + * ] + * + * @param {Function} passedFunction + * @param {Array} modifiers + * @returns {Worker} Worker + */ - clearSellForm() { - this.shadowRoot.getElementById('sellAmountInput').value = this.initialAmount - this.shadowRoot.getElementById('sellPriceInput').value = this.initialAmount - this.shadowRoot.getElementById('sellTotalInput').value = this.initialAmount - } + inlineWorker(passedFunction, modifiers) { + let parsedFunction = `` - isEmptyArray(arr) { - if (!arr) { - return true - } - return arr.length === 0 - } + modifiers.forEach((modifier) => { + let regex = new RegExp(modifier.searchValue, 'g') + parsedFunction = parsedFunction.length === 0 ? `(function ${passedFunction.toString().trim().replace(regex, modifier.replaceValue)})()` : parsedFunction.toString().trim().replace(regex, modifier.replaceValue) + }) - round(number) { - return (Math.round(parseFloat(number) * 1e8) / 1e8).toFixed(8) - } + const workerUrl = URL.createObjectURL(new Blob([parsedFunction], { type: 'text/javascript' })) + const worker = new Worker(workerUrl) + URL.revokeObjectURL(workerUrl) + return worker + } - /** - * Inline Worker - Takes in a function and a modifier then returns an instance of a Web Worker - * - * - Modifiers are simply an Array of Object containing placeholders (containers for variables used in the passedFunction ) in the and its values. - * These placeholders gets replaced with it value during instantiation of the function to be used by the Worker. - * - Example of modifiers: const modifiers = [ - * { searchValue: 'SELECTED_ADDRESS', replaceValue: this.selectedAddress.address, }, - * ] - * - * @param {Function} passedFunction - * @param {Array} modifiers - * @returns {Worker} Worker - */ + clearPaneCache() { + this._openOrdersGrid.clearCache() + this._myHistoricTradesGrid.clearCache() + this._historicTradesGrid.clearCache() + this._myOrdersGrid.clearCache() + } - inlineWorker(passedFunction, modifiers) { - let parsedFunction = `` + createConnection() { + if (workers.get(this.selectedCoin).tradesConnectedWorker !== null) { + this.isLoadingHistoricTrades = false + this.isLoadingOpenTrades = false + return + } - modifiers.forEach((modifier) => { - let regex = new RegExp(modifier.searchValue, 'g') - parsedFunction = parsedFunction.length === 0 ? `(function ${passedFunction.toString().trim().replace(regex, modifier.replaceValue)})()` : parsedFunction.toString().trim().replace(regex, modifier.replaceValue) - }) + const handleMessage = (message) => { + switch (message.type) { + case 'TRADE_OFFERS': + if (!message.isRestarted) { + this.listedCoins.get(this.selectedCoin).tradeOffersSocketCounter = message.counter + this.processTradeOffers(JSON.parse(message.data)) + this.listedCoins.get(this.selectedCoin).tradeOffersSocketCounter === 1 ? this.clearPaneCache() : null + workers.get(this.selectedCoin).tradesConnectedWorker.postMessage(this.listedCoins.get(this.selectedCoin).openOrders) + workers.get(this.selectedCoin).tradesConnectedWorker.postMessage({ type: "open_orders", content: this.listedCoins.get(this.selectedCoin).openOrders }) + } + return null + case 'TRADE_BOT': + if (!message.isRestarted) this.processTradeBotStates(JSON.parse(message.data)) + return null + case 'PRESENCE': + this.tradesPresenceCleaned = [] + this.listedCoins.get(message.data.relatedCoin).openOrders = message.data.offers + this.tradesPresenceCleaned = message.data.filteredOffers - const workerUrl = URL.createObjectURL(new Blob([parsedFunction], { type: 'text/javascript' })) - const worker = new Worker(workerUrl) - URL.revokeObjectURL(workerUrl) - return worker - } + const filterPresenceList = () => { + this.blockedTradesList.forEach(item => { + const toDelete = item.recipient + this.tradesPresenceCleaned = this.tradesPresenceCleaned.filter(el => { + return el.qortalCreatorTradeAddress !== toDelete + }) + }) + } - clearPaneCache() { - this._openOrdersGrid.clearCache() - this._myHistoricTradesGrid.clearCache() - this._historicTradesGrid.clearCache() - this._myOrdersGrid.clearCache() - } + filterPresenceList() + this.listedCoins.get(message.data.relatedCoin).openFilteredOrders = this.tradesPresenceCleaned + this.reRenderOpenFilteredOrders() + return null + default: + break + } + } - createConnection() { - if (workers.get(this.selectedCoin).tradesConnectedWorker !== null) { - this.isLoadingHistoricTrades = false - this.isLoadingOpenTrades = false - return - } + let myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] + let nodeUrl = myNode.domain + ':' + myNode.port - const handleMessage = (message) => { - switch (message.type) { - case 'TRADE_OFFERS': - if (!message.isRestarted) { - this.listedCoins.get(this.selectedCoin).tradeOffersSocketCounter = message.counter - this.processTradeOffers(JSON.parse(message.data)) - this.listedCoins.get(this.selectedCoin).tradeOffersSocketCounter === 1 ? this.clearPaneCache() : null - workers.get(this.selectedCoin).tradesConnectedWorker.postMessage(this.listedCoins.get(this.selectedCoin).openOrders) - workers.get(this.selectedCoin).tradesConnectedWorker.postMessage({ type: "open_orders", content: this.listedCoins.get(this.selectedCoin).openOrders }) - } - return null - case 'TRADE_BOT': - if (!message.isRestarted) this.processTradeBotStates(JSON.parse(message.data)) - return null - case 'PRESENCE': - this.tradesPresenceCleaned = [] - this.listedCoins.get(message.data.relatedCoin).openOrders = message.data.offers - this.tradesPresenceCleaned = message.data.filteredOffers + const modifiers = [ + { searchValue: 'NODEURL', replaceValue: nodeUrl }, + { searchValue: 'FOREIGN_BLOCKCHAIN', replaceValue: this.selectedCoin }, + ] - const filterPresenceList = () => { - this.blockedTradesList.forEach(item => { - const toDelete = item.recipient - this.tradesPresenceCleaned = this.tradesPresenceCleaned.filter(el => { - return el.qortalCreatorTradeAddress !== toDelete - }) - }) - } + workers.get(this.selectedCoin).tradesConnectedWorker = this.inlineWorker(this.initSocket, modifiers) - filterPresenceList() - this.listedCoins.get(message.data.relatedCoin).openFilteredOrders = this.tradesPresenceCleaned - this.reRenderOpenFilteredOrders() - return null - default: - break - } - } + workers.get(this.selectedCoin).tradesConnectedWorker.addEventListener('message', function (event) { handleMessage(event.data) }, { passive: true }) - let myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] - let nodeUrl = myNode.domain + ':' + myNode.port + workers.get(this.selectedCoin).tradesConnectedWorker.postMessage({ type: "set_coin", content: this.selectedCoin }) - const modifiers = [ - { searchValue: 'NODEURL', replaceValue: nodeUrl }, - { searchValue: 'FOREIGN_BLOCKCHAIN', replaceValue: this.selectedCoin }, - ] + } - workers.get(this.selectedCoin).tradesConnectedWorker = this.inlineWorker(this.initSocket, modifiers) + async getNewBlockedTrades() { + const unconfirmedTransactionsList = async () => { + const myNodeInf = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] + const myNodeUrl = myNodeInf.protocol + '://' + myNodeInf.domain + ':' + myNodeInf.port + const unconfirmedTransactionslUrl = `${myNodeUrl}/transactions/unconfirmed?txType=MESSAGE&limit=0&reverse=true` - workers.get(this.selectedCoin).tradesConnectedWorker.addEventListener('message', function (event) { handleMessage(event.data) }, { passive: true }) + var addBlockedTrades = JSON.parse(localStorage.getItem('failedTrades') || '[]') - workers.get(this.selectedCoin).tradesConnectedWorker.postMessage({ type: "set_coin", content: this.selectedCoin }) + await fetch(unconfirmedTransactionslUrl).then(response => { + return response.json() + }).then(data => { + data.map(item => { + const unconfirmedNessageTimeDiff = Date.now() - item.timestamp + const timeOneHour = 60 * 60 * 1000 + if (Number(unconfirmedNessageTimeDiff) > Number(timeOneHour)) { + const addBlocked = { + timestamp: item.timestamp, + recipient: item.recipient + } + addBlockedTrades.push(addBlocked) + } + }) + localStorage.setItem("failedTrades", JSON.stringify(addBlockedTrades)) + this.blockedTradesList = JSON.parse(localStorage.getItem('failedTrades') || '[]') + }) + } - } + await unconfirmedTransactionsList() - async getNewBlockedTrades() { - const unconfirmedTransactionsList = async () => { - const myNodeInf = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] - const myNodeUrl = myNodeInf.protocol + '://' + myNodeInf.domain + ':' + myNodeInf.port - const unconfirmedTransactionslUrl = `${myNodeUrl}/transactions/unconfirmed?txType=MESSAGE&limit=0&reverse=true` + const filterUnconfirmedTransactionsList = async () => { + let cleanBlockedTrades = this.blockedTradesList.reduce((newArray, cut) => { + if (!newArray.some(obj => obj.recipient === cut.recipient)) { + newArray.push(cut) + } + return newArray + }, []) + localStorage.setItem("failedTrades", JSON.stringify(cleanBlockedTrades)) + this.blockedTradesList = JSON.parse(localStorage.getItem("failedTrades") || "[]") + } - var addBlockedTrades = JSON.parse(localStorage.getItem('failedTrades') || '[]') + await filterUnconfirmedTransactionsList() + } - await fetch(unconfirmedTransactionslUrl).then(response => { - return response.json() - }).then(data => { - data.map(item => { - const unconfirmedNessageTimeDiff = Date.now() - item.timestamp - const timeOneHour = 60 * 60 * 1000 - if (Number(unconfirmedNessageTimeDiff) > Number(timeOneHour)) { - const addBlocked = { - timestamp: item.timestamp, - recipient: item.recipient - } - addBlockedTrades.push(addBlocked) - } - }) - localStorage.setItem("failedTrades", JSON.stringify(addBlockedTrades)) - this.blockedTradesList = JSON.parse(localStorage.getItem('failedTrades') || '[]') - }) - } + handleStuckTrades() { + let tradeBotStates = [] - await unconfirmedTransactionsList() + self.addEventListener('message', function (event) { + tradeBotStates = event.data + }) - const filterUnconfirmedTransactionsList = async () => { - let cleanBlockedTrades = this.blockedTradesList.reduce((newArray, cut) => { - if(!newArray.some(obj => obj.recipient === cut.recipient)) { - newArray.push(cut) - } - return newArray - },[]) - localStorage.setItem("failedTrades", JSON.stringify(cleanBlockedTrades)) - this.blockedTradesList = JSON.parse(localStorage.getItem("failedTrades") || "[]") - } + const getCompletedTrades = async () => { + const url = `http://NODEURL/crosschain/trades?limit=25&reverse=true&foreignBlockchain=FOREIGN_BLOCKCHAIN` + const res = await fetch(url) + const historicTrades = await res.json() + const compareFn = (a, b) => { + return b.tradeTimestamp - a.tradeTimestamp + } + const sortedTrades = historicTrades.sort(compareFn) + self.postMessage({ type: 'HISTORIC_TRADES', data: sortedTrades }) + } - await filterUnconfirmedTransactionsList() - } - - handleStuckTrades() { - let tradeBotStates = [] - - self.addEventListener('message', function (event) { - tradeBotStates = event.data - }) - - const getCompletedTrades = async () => { - const url = `http://NODEURL/crosschain/trades?limit=25&reverse=true&foreignBlockchain=FOREIGN_BLOCKCHAIN` - const res = await fetch(url) - const historicTrades = await res.json() - const compareFn = (a, b) => { - return b.tradeTimestamp - a.tradeTimestamp - } - const sortedTrades = historicTrades.sort(compareFn) - self.postMessage({ type: 'HISTORIC_TRADES', data: sortedTrades }) - } - - const filterStuckOffers = (myOffers) => { - const myTradeBotStates = tradeBotStates.filter((state) => state.creatorAddress === 'SELECTED_ADDRESS') + const filterStuckOffers = (myOffers) => { + const myTradeBotStates = tradeBotStates.filter((state) => state.creatorAddress === 'SELECTED_ADDRESS') return myOffers.filter((myOffer) => { let value = myTradeBotStates.some((myTradeBotState) => myOffer.qortalAtAddress === myTradeBotState.atAddress) return !value }) - } + } - const getOffers = async () => { - const url = `http://NODEURL/crosschain/tradeoffers?foreignBlockchain=FOREIGN_BLOCKCHAIN` - const res = await fetch(url) - const openTradeOrders = await res.json() - const myOpenTradeOrders = await openTradeOrders.filter((order) => order.mode === 'OFFERING' && order.qortalCreator === 'SELECTED_ADDRESS') - const stuckOffers = filterStuckOffers(myOpenTradeOrders) - self.postMessage({ type: 'STUCK_OFFERS', data: stuckOffers }) - } - setTimeout(() => { getOffers() }, 1000) - setTimeout(() => { getCompletedTrades() }, 1000) - } + const getOffers = async () => { + const url = `http://NODEURL/crosschain/tradeoffers?foreignBlockchain=FOREIGN_BLOCKCHAIN` + const res = await fetch(url) + const openTradeOrders = await res.json() + const myOpenTradeOrders = await openTradeOrders.filter((order) => order.mode === 'OFFERING' && order.qortalCreator === 'SELECTED_ADDRESS') + const stuckOffers = filterStuckOffers(myOpenTradeOrders) + self.postMessage({ type: 'STUCK_OFFERS', data: stuckOffers }) + } + setTimeout(() => { getOffers() }, 1000) + setTimeout(() => { getCompletedTrades() }, 1000) + } - filterStuckTrades(states) { - if (workers.get(this.selectedCoin).handleStuckTradesConnectedWorker !== null) { - this.isLoadingOpenTrades = false - return - } + filterStuckTrades(states) { + if (workers.get(this.selectedCoin).handleStuckTradesConnectedWorker !== null) { + this.isLoadingOpenTrades = false + return + } - this.shadowRoot.getElementById('loadingHistoricTrades').style.display = "block"; - let isHandleTradesDone = false - let isHandleStuckOffersDone = false + this.shadowRoot.getElementById('loadingHistoricTrades').style.display = "block"; + let isHandleTradesDone = false + let isHandleStuckOffersDone = false - const handleMessage = (message) => { - switch (message.type) { - case 'HISTORIC_TRADES': - this.listedCoins.get(this.selectedCoin).historicTrades = message.data - this.reRenderHistoricTrades() - isHandleTradesDone = true - break - case 'STUCK_OFFERS': - doStuckOffers(message.data) - isHandleStuckOffersDone = true - break - default: - break - } - if (isHandleTradesDone === true && isHandleStuckOffersDone === true) return workers.get(this.selectedCoin).handleStuckTradesConnectedWorker.terminate() - } + const handleMessage = (message) => { + switch (message.type) { + case 'HISTORIC_TRADES': + this.listedCoins.get(this.selectedCoin).historicTrades = message.data + this.reRenderHistoricTrades() + isHandleTradesDone = true + break + case 'STUCK_OFFERS': + doStuckOffers(message.data) + isHandleStuckOffersDone = true + break + default: + break + } + if (isHandleTradesDone === true && isHandleStuckOffersDone === true) return workers.get(this.selectedCoin).handleStuckTradesConnectedWorker.terminate() + } - const doStuckOffers = (message) => { - const offers = message - const offerItem = (offer) => { - return { - ...offer, - price: this.round(parseFloat(offer.expectedForeignAmount) / parseFloat(offer.qortAmount)), - } - } - const addStuckOrders = (offerItem) => { - if (offerItem.qortalCreator === this.selectedAddress.address) { - this._stuckOrdersGrid.items.unshift(offerItem) - this._stuckOrdersGrid.clearCache() - } - } - const handleOffers = () => { - offers.forEach((offer) => { - addStuckOrders(offerItem(offer)) - }) - } - handleOffers() - } + const doStuckOffers = (message) => { + const offers = message + const offerItem = (offer) => { + return { + ...offer, + price: this.round(parseFloat(offer.expectedForeignAmount) / parseFloat(offer.qortAmount)), + } + } + const addStuckOrders = (offerItem) => { + if (offerItem.qortalCreator === this.selectedAddress.address) { + this._stuckOrdersGrid.items.unshift(offerItem) + this._stuckOrdersGrid.clearCache() + } + } + const handleOffers = () => { + offers.forEach((offer) => { + addStuckOrders(offerItem(offer)) + }) + } + handleOffers() + } - let myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] - let nodeUrl = myNode.domain + ':' + myNode.port + let myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] + let nodeUrl = myNode.domain + ':' + myNode.port - const modifiers = [ - { searchValue: 'NODEURL', replaceValue: nodeUrl }, - { searchValue: 'SELECTED_ADDRESS', replaceValue: this.selectedAddress.address, }, - { searchValue: 'FOREIGN_BLOCKCHAIN', replaceValue: this.selectedCoin, }, - ] + const modifiers = [ + { searchValue: 'NODEURL', replaceValue: nodeUrl }, + { searchValue: 'SELECTED_ADDRESS', replaceValue: this.selectedAddress.address, }, + { searchValue: 'FOREIGN_BLOCKCHAIN', replaceValue: this.selectedCoin, }, + ] - workers.get(this.selectedCoin).handleStuckTradesConnectedWorker = this.inlineWorker(this.handleStuckTrades, modifiers) - workers.get(this.selectedCoin).handleStuckTradesConnectedWorker.postMessage(states) - workers.get(this.selectedCoin).handleStuckTradesConnectedWorker.addEventListener( - 'message', - function (event) { - handleMessage(event.data) - }, - { passive: true } - ) - } + workers.get(this.selectedCoin).handleStuckTradesConnectedWorker = this.inlineWorker(this.handleStuckTrades, modifiers) + workers.get(this.selectedCoin).handleStuckTradesConnectedWorker.postMessage(states) + workers.get(this.selectedCoin).handleStuckTradesConnectedWorker.addEventListener( + 'message', + function (event) { + handleMessage(event.data) + }, + { passive: true } + ) + } + + // Standard functions + getApiKey() { + const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] + return myNode.apiKey + } + + isEmptyArray(arr) { + if (!arr) { return true } + return arr.length === 0 + } + + round(number) { + return (Math.round(parseFloat(number) * 1e8) / 1e8).toFixed(8) + } } -window.customElements.define('trade-portal', TradePortal) +window.customElements.define('trade-portal', TradePortal) \ No newline at end of file diff --git a/plugins/plugins/core/wallet/wallet-app.src.js b/plugins/plugins/core/wallet/wallet-app.src.js index 45b3cd61..a49333d4 100644 --- a/plugins/plugins/core/wallet/wallet-app.src.js +++ b/plugins/plugins/core/wallet/wallet-app.src.js @@ -1,15 +1,15 @@ -import {css, html, LitElement} from 'lit' -import {render} from 'lit/html.js' -import {Epml} from '../../../epml.js' +import { html, LitElement } from 'lit' +import { render } from 'lit/html.js' +import { Epml } from '../../../epml' +import { decryptData, encryptData } from '../../../../core/src/lockScreen' +import { multiWalletStyles } from '../components/plugins-css' import isElectron from 'is-electron' -import {get, registerTranslateConfig, translate, use} from '../../../../core/translate' -import Base58 from '../../../../crypto/api/deps/Base58.js' -import {decryptData, encryptData} from '../../../../core/src/lockScreen.js' import FileSaver from 'file-saver' -import '../components/ButtonIconCopy.js' -import '../components/QortalQrcodeGenerator.js' -import '../components/frag-file-input.js' -import '../components/time-elements/index.js' +import Base58 from '../../../../crypto/api/deps/Base58' +import '../components/ButtonIconCopy' +import '../components/QortalQrcodeGenerator' +import '../components/frag-file-input' +import '../components/time-elements/index' import '@material/mwc-button' import '@material/mwc-checkbox' import '@material/mwc-dialog' @@ -18,20 +18,22 @@ import '@material/mwc-icon' import '@material/mwc-icon-button' import '@material/mwc-tab-bar' import '@material/mwc-textfield' +import '@polymer/iron-icons/iron-icons.js' import '@polymer/paper-dialog/paper-dialog.js' import '@polymer/paper-progress/paper-progress.js' import '@polymer/paper-slider/paper-slider.js' import '@polymer/paper-spinner/paper-spinner-lite.js' import '@polymer/paper-icon-button/paper-icon-button.js' -import '@polymer/iron-icons/iron-icons.js' import '@vaadin/button' import '@vaadin/grid' import '@vaadin/icon' import '@vaadin/icons' import '@vaadin/password-field' +// Multi language support +import { get, registerTranslateConfig, translate, use } from '../../../../core/translate' registerTranslateConfig({ - loader: lang => fetch(`/language/${lang}.json`).then(res => res.json()) + loader: lang => fetch(`/language/${lang}.json`).then(res => res.json()) }) const parentEpml = new Epml({ type: 'WINDOW', source: window.parent }) @@ -39,4031 +41,3503 @@ const parentEpml = new Epml({ type: 'WINDOW', source: window.parent }) const coinsNames = ['qort', 'btc', 'ltc', 'doge', 'dgb', 'rvn', 'arrr'] class MultiWallet extends LitElement { - static get properties() { - return { - loading: { type: Boolean }, - transactions: { type: Object }, - lastBlock: { type: Object }, - selectedTransaction: { type: Object }, - isTextMenuOpen: { type: Boolean }, - wallets: { type: Map }, - _selectedWallet: 'qort', - nodeConfig: { type: Object }, - nodeDomain: { type: String }, - theme: { type: String, reflect: true }, - amount: { type: Number }, - recipient: { type: String }, - btcRecipient: { type: String }, - btcAmount: { type: Number }, - ltcRecipient: { type: String }, - ltcAmount: { type: Number }, - dogeRecipient: { type: String }, - dogeAmount: { type: Number }, - dgbRecipient: { type: String }, - dgbAmount: { type: Number }, - rvnRecipient: { type: String }, - rvnAmount: { type: Number }, - arrrRecipient: { type: String }, - arrrAmount: { type: Number }, - arrrMemo: { type: String }, - errorMessage: { type: String }, - arrrWalletAddress: { type: String }, - unusedWalletAddress: { type: String }, - successMessage: { type: String }, - sendMoneyLoading: { type: Boolean }, - btnDisable: { type: Boolean }, - qortWarning: { type: Boolean }, - isValidAmount: { type: Boolean }, - balance: { type: Number }, - balanceString: { type: String }, - btcServer: { type: Number }, - ltcServer: { type: Number }, - dogeServer: { type: Number }, - dgbServer: { type: Number }, - rvnServer: { type: Number }, - arrrServer: { type: Number }, - qortPaymentFee: { type: Number }, - btcFeePerByte: { type: Number }, - ltcFeePerByte: { type: Number }, - dogeFeePerByte: { type: Number }, - dgbFeePerByte: { type: Number }, - rvnFeePerByte: { type: Number }, - qortBook: { type: Array }, - btcBook: { type: Array }, - ltcBook: { type: Array }, - dogeBook: { type: Array }, - dgbBook: { type: Array }, - rvnBook: { type: Array }, - arrrBook: { type: Array }, - qortBookName: { type: String }, - btcBookName: { type: String }, - ltcBookName: { type: String }, - dogeBookName: { type: String }, - dgbBookName: { type: String }, - rvnBookName: { type: String }, - arrrBookName: { type: String }, - qortBookAddress: { type: String }, - btcBookAddress: { type: String }, - ltcBookAddress: { type: String }, - dogeBookAddress: { type: String }, - dgbBookAddress: { type: String }, - rvnBookAddress: { type: String }, - arrrBookAddress: { type: String }, - myElementId: { type: String }, - walletSalt: { type: String }, - walletStorageData: { type: String }, - walletLockScreenPass: { type: String }, - walletLockScreenSet: { type: String }, - walletLockPass: { type: String }, - walletLockSet: { type: String }, - myWalletLockScreenPass: { type: String }, - myWalletLockScreenSet: { type: String }, - walletHelperMessage: { type: String }, - bookQortalAddress: { type: String }, - bookBitcoinAddress: { type: String }, - bookLitecoinAddress: { type: String }, - bookDogecoinAddress: { type: String }, - bookDigibyteAddress: { type: String }, - bookRavencoinAddress: { type: String }, - bookPiratechainAddress: { type: String } - } - } - - static get observers() { - return ['_kmxKeyUp(amount)'] - } - - static get styles() { - return css` - * { - box-sizing: border-box; - --mdc-theme-primary: rgb(3, 169, 244); - --mdc-theme-secondary: var(--mdc-theme-primary); - --mdc-theme-surface: var(--white); - --mdc-theme-error: rgb(255, 89, 89); - --mdc-dialog-content-ink-color: var(--black); - --mdc-dialog-min-width: 500px; - --mdc-dialog-max-width: 1024px; - --paper-input-container-focus-color: var(--mdc-theme-primary); - --lumo-primary-text-color: rgb(0, 167, 245); - --lumo-primary-color-50pct: rgba(0, 167, 245, 0.5); - --lumo-primary-color-10pct: rgba(0, 167, 245, 0.1); - --lumo-primary-color: hsl(199, 100%, 48%); - --lumo-base-color: var(--white); - --lumo-secondary-text-color: var(--sectxt); - --lumo-contrast-60pct: var(--vdicon); - --lumo-body-text-color: var(--black); - --_lumo-grid-border-color: var(--border); - --_lumo-grid-secondary-border-color: var(--border2); - } - - #pages { - display: flex; - flex-wrap: wrap; - padding: 10px 5px 5px 5px; - margin: 0px 20px 20px 20px; - } - - #pages > button { - user-select: none; - padding: 5px; - margin: 0 5px; - border-radius: 10%; - border: 0; - background: transparent; - font: inherit; - outline: none; - cursor: pointer; - color: var(--black); - } - - #pages > button:not([disabled]):hover, - #pages > button:focus { - color: #ccc; - background-color: #eee; - } - - #pages > button[selected] { - font-weight: bold; - color: var(--white); - background-color: #ccc; - } - - #pages > button[disabled] { - opacity: 0.5; - cursor: default; - } - - #tabs-height { - --mdc-tab-height: 50px; - } - - #tabs-1-content { - height: 100%; - padding-bottom: 10px; - } - - mwc-tab-bar { - --mdc-text-transform: none; - --mdc-tab-color-default: var(--black); - --mdc-tab-text-label-color-default: var(--black); - } - - paper-slider.blue { - --paper-slider-knob-color: var(--paper-light-blue-500); - --paper-slider-active-color: var(--paper-light-blue-500); - --paper-slider-pin-color: var(--paper-light-blue-500); - } - - paper-progress { - --paper-progress-active-color: var(--mdc-theme-primary); - } - - .red { - --mdc-theme-primary: #F44336; - } - - .green { - color: var(--paper-green-500); - } - - paper-spinner-lite { - height: 75px; - width: 75px; - --paper-spinner-color: var(--mdc-theme-primary); - --paper-spinner-stroke-width: 3px; - } - - .unconfirmed { - font-style: italic; - } - - .roboto { - font-family: 'Roboto', sans-serif; - } - - .mono { - font-family: 'Roboto Mono', monospace; - } - - .sans { - font-family: 'Open Sans', sans-serif; - } - - .magistral { - font-family: 'magistralbold'; - } - - .montserrat { - font-family: 'Montserrat', sans-serif; - } - - .maven { - font-family: 'MavenPro', sans-serif; - } - - .weight-100 { - font-weight: 100; - } - - .text-white-primary { - color: var(--white); - } - - .text-white-secondary { - color: var(--white-secondary); - } - - .text-white-disabled { - color: var(--white-disabled); - } - - .text-white-hint { - color: var(--white-divider); - } - - .white-bg { - height: 100vh; - background: var(--white); - } - - span { - font-size: 18px; - word-break: break-all; - } - - .floatleft { - float: left; - } - - .floatright { - float: right; - } - - .title { - font-weight: 600; - font-size: 12px; - line-height: 32px; - opacity: 0.66; - } - - #transactionList { - padding: 0; - } - - .color-in { - color: #02977e; - background-color: rgba(0, 201, 167, 0.2); - font-weight: 700; - font-size: 0.60938rem; - border-radius: 0.25rem !important; - padding: 0.2rem 0.5rem; - margin-left: 4px; - } - - .color-out { - color: #b47d00; - background-color: rgba(219, 154, 4, 0.2); - font-weight: 700; - font-size: 0.60938rem; - border-radius: 0.25rem !important; - padding: 0.2rem 0.5rem; - margin-left: 4px; - } - - body { - margin: 0; - padding: 0; - background: var(--white); - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; - } - - h2 { - margin: 0; - color: var(--black); - font-weight: 400; - font: 24px/24px 'Open Sans', sans-serif; - } - - h3 { - margin: 0 0 5px; - color: var(--black); - font-weight: 600; - font-size: 18px; - line-height: 18px; - } - - .hrstyle { - color: var(--border); - border-radius: 80%; - margin-bottom: 1rem; - } - - .header-title { - display: inlinr; - font-size: 32px; - color: var(--black); - font-weight: 600; - text-align: center; - margin-top: 1rem; - } - - .fullWidth { - width: 100%; - } - - .wrapper { - margin: 0 auto; - height: 100%; - overflow: hidden; - border-radius: 8px; - background-color: var(--white); - } - - .wallet { - width: 200px; - height: 100vh; - border-top-left-radius: inherit; - border-bottom-left-radius: inherit; - border-right: 1px solid var(--border); - } - - .transactions-wrapper { - width: 100%; - padding: 30px 0 0 0; - height: 100%; - } - - .wallet-header { - margin: 0 20px; - color: var(--black); - } - - .wallet-address { - display: flex; - align-items: center; - font-size: 18px; - color: var(--black); - margin: 4px 0 20px; - } - - .wallet-balance { - display: inline-block; - font-weight: 600; - font-size: 32px; - color: var(--black); - } - - #transactions { - margin-top: 30px; - margin-left: 20px; - margin-right: 20px; - border-top: 1px solid var(--border); - padding-top: 0px; - height: 100%; - } - - .show { - animation: fade-in 0.3s 1; - } - - .transaction-item { - display: flex; - justify-content: space-between; - position: relative; - padding-left: 40px; - margin-bottom: 45px; - margin-right: 50px; - } - - .transaction-item::before { - position: absolute; - content: ''; - border: 2px solid #e1e1e1; - border-radius: 50%; - height: 25px; - width: 25px; - left: 0; - top: 10px; - box-sizing: border-box; - vertical-align: middle; - color: #666666; - } - - .credit::before { - content: '+'; - font-size: 25px; - line-height: 19px; - padding: 0 4px 0; - } - - .debit::before { - content: '-'; - font-size: 20px; - line-height: 21px; - padding: 0 5px; - } - - .transaction-item .details { - font-size: 14px; - line-height: 14px; - color: #999; - } - - .transaction-item_details { - width: 270px; - } - - .transaction-item_amount .amount { - font-weight: 600; - font-size: 18px; - line-height: 45px; - position: relative; - margin: 0; - display: inline-block; - } - - .active { - background: var(--menuactive); - } - - .currency-image { - display: inline-block; - height: 42px; - width: 42px; - background-repeat: no-repeat; - background-size: cover; - border-radius: 3px; - filter: grayscale(100%); - } - - .qort .currency-image { - background-image: url('/img/qort.png'); - } - - .btc .currency-image { - background-image: url('/img/btc.png'); - } - - .ltc .currency-image { - background-image: url('/img/ltc.png'); - } - - .doge .currency-image { - background-image: url('/img/doge.png'); - } - - .dgb .currency-image { - background-image: url('/img/dgb.png'); - } - - .rvn .currency-image { - background-image: url('/img/rvn.png'); - } - - .arrr .currency-image { - background-image: url('/img/arrr.png'); - } - - .card-list { - margin-top: 20px; - } - - .card-list .currency-image { - cursor: pointer; - margin-right: 15px; - transition: 0.1s; - } - - .card-list .currency-image:hover { - transform: scale(1.1); - } - - .buttons { - width: auto !important; - } - - .send-coin-dialog { - min-height: 300px; - min-width: 300px; - box-sizing: border-box; - position: relative; - } - - .unused-address-dialog { - min-height: 150px; - min-width: 550px; - box-sizing: border-box; - position: relative; - } - - .btn-clear-success { - --mdc-icon-button-size: 32px; - color: red; - } - - .btn-clear-error { - --mdc-icon-button-size: 32px; - color: green; - } - - @keyframes fade-in { - 0% { - opacity: 0; - } - 100% { - opacity: 1; - } - } - - .successBox { - height: 34px; - min-width: 300px; - width: 100%; - border: 1px solid green; - border-radius: 5px; - background-color: transparent; - margin-top: 15px; - } - - .errorBox { - height: 34px; - min-width: 300px; - width: 100%; - border: 1px solid red; - border-radius: 5px; - background-color: transparent; - margin-top: 15px; - } - - .qrcode-pos { - margin-top: -175px; - float: right; - } - - .send-pos { - margin-top: 20px; - margin-left: 20px; - width: 185px; - } - - .book-pos { - margin-top: -44px; - margin-left: 215px; - width: 185px; - } - - @media (max-width: 863px) { - .wallet { - width: 100%; - height: max-content; - border-top-right-radius: inherit; - padding-bottom: 25px; - } - .cards { - margin-top: 25px; - } - } - - .checkboxLabel:hover{ - cursor: pointer; - } - - .warning-text { - animation: blinker 1.5s linear infinite; - text-align: center; - margin-top: 10px; - color: rgb(255, 89, 89); - } - - @keyframes blinker { - 50% { - opacity: 0; - } - } - - @media (max-width: 764px) { - .wallet { - width: 100%; - height: max-content; - border-top-right-radius: inherit; - padding-bottom: 25px; - } - .cards { - margin-top: 25px; - } - } - - @media (max-width: 530px) { - h3 { - line-height: 24px; - } - .cards { - text-align: center; - } - .wallet-balance { - font-size: 22px; - } - } - - @media (max-width: 390px) { - .wallet { - height: max-content; - padding: 50px 25px; - } - .transactions-wrapper { - padding: 50px 25px; - } - h2 { - font: 18px/24px 'Open Sans', sans-serif; - } - } - - .setpass-wrapper { - width: 100%; - min-width: 400px; - max-width: 450px; - text-align: center; - background: var(--white); - border: 1px solid var(--black); - border-radius: 15px; - padding: 10px 10px 0px; - box-shadow: 0px 10px 15px rgba(0, 0, 0, 0.1); - } - - .lock-wrapper { - width: 100%; - height: 100%; - min-width: 600px; - max-width: 600px; - min-height: 400px; - max-height: 400px; - text-align: center; - background: url("/img/qortal-lock.jpg"); - border: 1px solid var(--black); - border-radius: 25px; - padding: 10px 10px 0px; - } - - .text-wrapper { - width: 100%; - height: 100%; - min-width: 280px; - max-width: 280px; - min-height: 64px; - max-height: 64px; - text-align: center; - margin-left: 35px; - margin-top: 125px; - overflow: hidden; - } - - .lock-title-white { - font-family: 'magistralbold'; - font-weight: 700; - font-size: 26px; - line-height: 32px; - color: #ffffff; - } - - .lock-title-red { - font-family: 'magistralbold'; - font-weight: 700; - font-size: 26px; - line-height: 32px; - color: #df3636; - } - ` - } - - constructor() { - super() - - this.lastBlock = { - height: 0, - } - - this.balanceString = this.renderFetchText() - this.selectedTransaction = {} - this.isTextMenuOpen = false - this.loading = true - - this.nodeConfig = {} - this.nodeDomain = '' - this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light'; - - this.qortBook = [] - this.btcBook = [] - this.ltcBook = [] - this.dogeBook = [] - this.dgbBook = [] - this.rvnBook = [] - this.arrrBook = [] - this.qortBookName = '' - this.btcBookName = '' - this.ltcBookName = '' - this.dogeBookName = '' - this.dgbBookName = '' - this.rvnBookName = '' - this.arrrBookName = '' - this.qortBookAddress = '' - this.btcBookAddress = '' - this.ltcBookAddress = '' - this.dogeBookAddress = '' - this.dgbBookAddress = '' - this.rvnBookAddress = '' - this.arrrBookAddress = '' - this.recipient = '' - this.btcRecipient = '' - this.ltcRecipient = '' - this.dogeRecipient = '' - this.dgbRecipient = '' - this.rvnRecipient = '' - this.arrrRecipient = '' - this.arrrMemo = '' - this.arrrWalletAddress = '' - this.unusedWalletAddress = '' - this.btcServer = '' - this.ltcServer = '' - this.dogeServer = '' - this.dgbServer = '' - this.rvnServer = '' - this.arrrServer = '' - this.errorMessage = '' - this.successMessage = '' - this.myElementId = '' - this.sendMoneyLoading = false - this.isValidAmount = false - this.btnDisable = false - this.qortWarning = false - this.balance = 0 - this.amount = 0 - this.btcAmount = 0 - this.ltcAmount = 0 - this.dogeAmount = 0 - this.dgbAmount = 0 - this.rvnAmount = 0 - this.arrrAmount = 0 - this.qortPaymentFee = 0.001 - this.btcFeePerByte = 100 - this.btcSatMinFee = 20 - this.btcSatMaxFee = 150 - this.ltcFeePerByte = 30 - this.ltcSatMinFee = 10 - this.ltcSatMaxFee = 100 - this.dogeFeePerByte = 1000 - this.dogeSatMinFee = 100 - this.dogeSatMaxFee = 10000 - this.dgbFeePerByte = 10 - this.dgbSatMinFee = 1 - this.dgbSatMaxFee = 100 - this.rvnFeePerByte = 1125 - this.rvnSatMinFee = 1000 - this.rvnSatMaxFee = 10000 - this.walletSalt = '' - this.walletStorageData = '' - this.walletLockScreenPass = '' - this.walletLockScreenSet = '' - this.walletLockPass = '' - this.walletLockSet = '' - this.myWalletLockScreenPass = '' - this.myWalletLockScreenSet = '' - this.walletHelperMessage = '' - this.bookQortalAddress = '' - this.bookBitcoinAddress = '' - this.bookLitecoinAddress = '' - this.bookDogecoinAddress = '' - this.bookDigibyteAddress = '' - this.bookRavencoinAddress = '' - this.bookPiratechainAddress = '' - - this.wallets = new Map() - - let coinProp = { - balance: 0, - wallet: null, - transactions: [], - fetchingWalletBalance: false, - fetchingWalletTransactions: false - } - - coinsNames.forEach((c, i) => { - this.wallets.set(c, { ...coinProp }) - }, this) - - this.wallets.get('qort').wallet = window.parent.reduxStore.getState().app.selectedAddress - this.wallets.get('btc').wallet = window.parent.reduxStore.getState().app.selectedAddress.btcWallet - this.wallets.get('ltc').wallet = window.parent.reduxStore.getState().app.selectedAddress.ltcWallet - this.wallets.get('doge').wallet = window.parent.reduxStore.getState().app.selectedAddress.dogeWallet - this.wallets.get('dgb').wallet = window.parent.reduxStore.getState().app.selectedAddress.dgbWallet - this.wallets.get('rvn').wallet = window.parent.reduxStore.getState().app.selectedAddress.rvnWallet - this.wallets.get('arrr').wallet = window.parent.reduxStore.getState().app.selectedAddress.arrrWallet - - this._selectedWallet = 'qort' - - parentEpml.ready().then(() => { - parentEpml.subscribe('selected_address', async (selectedAddress) => { - selectedAddress = JSON.parse(selectedAddress) - if (!selectedAddress || Object.entries(selectedAddress).length === 0) return - - this.wallets.get('qort').wallet = selectedAddress - this.wallets.get('btc').wallet = window.parent.reduxStore.getState().app.selectedAddress.btcWallet - this.wallets.get('ltc').wallet = window.parent.reduxStore.getState().app.selectedAddress.ltcWallet - this.wallets.get('doge').wallet = window.parent.reduxStore.getState().app.selectedAddress.dogeWallet - this.wallets.get('dgb').wallet = window.parent.reduxStore.getState().app.selectedAddress.dgbWallet - this.wallets.get('rvn').wallet = window.parent.reduxStore.getState().app.selectedAddress.rvnWallet - this.wallets.get('arrr').wallet = window.parent.reduxStore.getState().app.selectedAddress.arrrWallet - }) - parentEpml.subscribe('coin_balances', async (payload) => { - const coinBalances = JSON.parse(payload) - if(coinBalances[this._selectedWallet]){ - const res = coinBalances[this._selectedWallet].fullValue - let value = Number(res).toFixed(8) - if(this._selectedWallet !== 'qort'){ - value = (Number(res) / 1e8).toFixed(8) - } - this.wallets.get(this._selectedWallet).balance = value - this.balanceString = this.wallets.get(this._selectedWallet).balance + " " + this._selectedWallet.toLocaleUpperCase() - this.balance = this.wallets.get(this._selectedWallet).balance - } - }) - }) - - this.pingCoinBalancesController = this.pingCoinBalancesController.bind(this) - } - - refreshWallet(){ - const coin = this._selectedWallet - switch (coin) { - case 'qort': - this.tabWalletQort(); - break - case 'arrr': - this.tabWalletArrr(); - break - case 'btc': - this.tabWalletBtc(); - break; - case 'ltc': - this.tabWalletLtc(); - break; - case 'doge': - this.tabWalletDoge(); - break - case 'dgb': - this.tabWalletDgb() - break; - case 'rvn': - this.tabWalletRvn(); - break - default: - break - } - - } - - render() { - return html` -
    -
    - ${translate("walletpage.wchange22")} ${this.renderWalletLockButton()} -
    - -
    -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - -
    -

    -
    - ${translate("walletpage.wchange2")} - - -
    -
    - ${this.getSelectedWalletAddress()} - - -
    - - ${this.balanceString} - -
    - ${this.getSelectedWalletServer()} -
    -

    -
    - ${this.renderSendButton()} -
    -
    - ${this.renderAddressbookButton()} -
    -
    - -
    -
    - - ${this.loading ? html`` : ''} -
    -
    -
    - - -
    -

    ${translate("walletpage.wchange5")}

    -
    -
    -
    - ${translate("walletpage.wchange6")} -
    -
    - ${this.selectedTransaction.type} - ${this.selectedTransaction.txnFlow === 'OUT' ? html`${translate("walletpage.wchange7")}` : html`${translate("walletpage.wchange8")}`} -
    - ${translate("walletpage.wchange9")} -
    -
    ${this.selectedTransaction.type === 'AT' ? html`${this.selectedTransaction.atAddress}` : html`${this.selectedTransaction.creatorAddress}`}
    - ${translate("walletpage.wchange10")} -
    -
    - ${this.selectedTransaction.type === 'DEPLOY_AT' ? html`${this.renderCAB()}` : html`${this.renderSQB()}`} -
    -
    - ${!this.selectedTransaction.amount ? '' : html` - ${translate("walletpage.wchange11")} -
    -
    ${this.selectedTransaction.amount} QORT
    - `} - ${translate("walletpage.wchange12")} -
    -
    ${this.selectedTransaction.fee}
    - ${translate("walletpage.wchange13")} -
    -
    ${this.selectedTransaction.blockHeight}
    - ${translate("walletpage.wchange14")} -
    -
    ${new Date(this.selectedTransaction.timestamp).toString()}
    - ${translate("walletpage.wchange15")} -
    -
    ${this.selectedTransaction.signature}
    -
    - - ${translate("general.close")} - -
    - - -
    -

    ${translate("walletpage.wchange5")}

    -
    -
    -
    - ${translate("walletpage.wchange6")} -
    -
    - ${translate("walletpage.wchange40")} - ${this.selectedTransaction.btcTxnFlow === 'OUT' ? html`${translate("walletpage.wchange7")}` : html`${translate("walletpage.wchange8")}`} -
    - ${translate("walletpage.wchange9")} -
    -
    - ${this.selectedTransaction.btcSender} -
    - ${translate("walletpage.wchange10")} -
    -
    - ${this.selectedTransaction.btcReceiver} - this.sendToBtcAddress()} title="${translate("walletpage.wchange46")}"> - this.openAddBtcAddressDialog()} title="${translate("walletpage.wchange49")}"> -
    -
    - ${translate("walletpage.wchange12")} -
    -
    - ${(this.selectedTransaction.feeAmount / 1e8).toFixed(8)} BTC -
    - ${translate("walletpage.wchange37")} -
    -
    - ${(this.selectedTransaction.totalAmount / 1e8).toFixed(8)} BTC -
    - ${translate("walletpage.wchange14")} -
    -
    ${new Date(this.selectedTransaction.timestamp).toString()}
    - ${translate("walletpage.wchange16")} -
    -
    - ${this.selectedTransaction.txHash} -
    -
    - - ${translate("general.close")} - -
    - - -
    -

    ${translate("walletpage.wchange5")}

    -
    -
    -
    - ${translate("walletpage.wchange6")}e -
    -
    - ${translate("walletpage.wchange40")} - ${this.selectedTransaction.ltcTxnFlow === 'OUT' ? html`${translate("walletpage.wchange7")}` : html`${translate("walletpage.wchange8")}`} -
    - ${translate("walletpage.wchange9")} -
    -
    - ${this.selectedTransaction.ltcSender} -
    - ${translate("walletpage.wchange10")} -
    -
    - ${this.selectedTransaction.ltcReceiver} - this.sendToLtcAddress()} title="${translate("walletpage.wchange46")}"> - this.openAddLtcAddressDialog()} title="${translate("walletpage.wchange49")}"> -
    -
    - ${translate("walletpage.wchange12")} -
    -
    - ${(this.selectedTransaction.feeAmount / 1e8).toFixed(8)} LTC -
    - ${translate("walletpage.wchange37")} -
    -
    - ${(this.selectedTransaction.totalAmount / 1e8).toFixed(8)} LTC -
    - ${translate("walletpage.wchange14")} -
    -
    ${new Date(this.selectedTransaction.timestamp).toString()}
    - ${translate("walletpage.wchange16")} -
    -
    - ${this.selectedTransaction.txHash} -
    -
    - - ${translate("general.close")} - -
    - - -
    -

    ${translate("walletpage.wchange5")}

    -
    -
    -
    - ${translate("walletpage.wchange6")} -
    -
    - ${translate("walletpage.wchange40")} - ${this.selectedTransaction.dogeTxnFlow === 'OUT' ? html`${translate("walletpage.wchange7")}` : html`${translate("walletpage.wchange8")}`} -
    - ${translate("walletpage.wchange9")} -
    -
    - ${this.selectedTransaction.dogeSender} -
    -
    - ${translate("walletpage.wchange10")} -
    -
    - ${this.selectedTransaction.dogeReceiver} - this.sendToDogeAddress()} title="${translate("walletpage.wchange46")}"> - this.openAddDogeAddressDialog()} title="${translate("walletpage.wchange49")}"> -
    -
    - ${translate("walletpage.wchange12")} -
    -
    - ${(this.selectedTransaction.feeAmount / 1e8).toFixed(8)} DOGE -
    - ${translate("walletpage.wchange37")} -
    -
    - ${(this.selectedTransaction.totalAmount / 1e8).toFixed(8)} DOGE -
    - ${translate("walletpage.wchange14")} -
    -
    ${new Date(this.selectedTransaction.timestamp).toString()}
    - ${translate("walletpage.wchange16")} -
    -
    - ${this.selectedTransaction.txHash} -
    -
    - - ${translate("general.close")} - -
    - - -
    -

    ${translate("walletpage.wchange5")}

    -
    -
    -
    - ${translate("walletpage.wchange6")} -
    -
    - ${translate("walletpage.wchange40")} - ${this.selectedTransaction.dgbTxnFlow === 'OUT' ? html`${translate("walletpage.wchange7")}` : html`${translate("walletpage.wchange8")}`} -
    - ${translate("walletpage.wchange9")} -
    -
    - ${this.selectedTransaction.dgbSender} -
    - ${translate("walletpage.wchange10")} -
    -
    - ${this.selectedTransaction.dgbReceiver} - this.sendToDgbAddress()} title="${translate("walletpage.wchange46")}"> - this.openAddDgbAddressDialog()} title="${translate("walletpage.wchange49")}"> -
    -
    - ${translate("walletpage.wchange12")} -
    -
    - ${(this.selectedTransaction.feeAmount / 1e8).toFixed(8)} DGB -
    - ${translate("walletpage.wchange37")} -
    -
    - ${(this.selectedTransaction.totalAmount / 1e8).toFixed(8)} DGB -
    - ${translate("walletpage.wchange14")} -
    -
    ${new Date(this.selectedTransaction.timestamp).toString()}
    - ${translate("walletpage.wchange16")} -
    -
    - ${this.selectedTransaction.txHash} -
    -
    - - ${translate("general.close")} - -
    - - -
    -

    ${translate("walletpage.wchange5")}

    -
    -
    -
    - ${translate("walletpage.wchange6")} -
    -
    - ${translate("walletpage.wchange40")} - ${this.selectedTransaction.rvnTxnFlow === 'OUT' ? html`${translate("walletpage.wchange7")}` : html`${translate("walletpage.wchange8")}`} -
    - ${translate("walletpage.wchange9")} -
    -
    - ${this.selectedTransaction.rvnSender} -
    - ${translate("walletpage.wchange10")} -
    -
    - ${this.selectedTransaction.rvnReceiver} - this.sendToRvnAddress()} title="${translate("walletpage.wchange46")}"> - this.openAddRvnAddressDialog()} title="${translate("walletpage.wchange49")}"> -
    -
    - ${translate("walletpage.wchange12")} -
    -
    - ${(this.selectedTransaction.feeAmount / 1e8).toFixed(8)} RVN -
    - ${translate("walletpage.wchange37")} -
    -
    - ${(this.selectedTransaction.totalAmount / 1e8).toFixed(8)} RVN -
    - ${translate("walletpage.wchange14")} -
    -
    ${new Date(this.selectedTransaction.timestamp).toString()}
    - ${translate("walletpage.wchange16")} -
    -
    - ${this.selectedTransaction.txHash} -
    -
    - - ${translate("general.close")} - -
    - - -
    -

    ${translate("walletpage.wchange5")}

    -
    -
    -
    - ${translate("walletpage.wchange6")} -
    -
    - ${translate("walletpage.wchange40")} - ${this.selectedTransaction.arrrTxnFlow === 'OUT' ? html`${translate("walletpage.wchange7")}` : html`${translate("walletpage.wchange8")}`} -
    - ${translate("walletpage.wchange9")} -
    -
    - ${this.selectedTransaction.arrrSender} -
    - ${translate("walletpage.wchange10")} -
    -
    - ${this.selectedTransaction.arrrReceiver} - this.sendToArrrAddress()} title="${translate("walletpage.wchange46")}"> - this.openAddArrrAddressDialog()} title="${translate("walletpage.wchange49")}"> -
    -
    - ${translate("walletpage.wchange12")} -
    -
    - ${(this.selectedTransaction.feeAmount / 1e8).toFixed(8)} ARRR -
    - ${translate("walletpage.wchange37")} -
    -
    - ${(this.selectedTransaction.totalAmount / 1e8).toFixed(8)} ARRR -
    - ${translate("walletpage.wchange14")} -
    -
    ${new Date(this.selectedTransaction.timestamp).toString()}
    - ${translate("walletpage.wchange16")} -
    -
    - ${this.selectedTransaction.txHash} -
    -
    - - ${translate("general.close")} - -
    - - -
    -
    - -

    ${translate("walletpage.wchange17")} QORT

    -
    -
    -

    - ${translate("walletpage.wchange18")}:
    - ${this.getSelectedWalletAddress()} -

    -

    - ${translate("walletpage.wchange19")}:
    - ${this.balanceString}
    - - this.calculateQortAll()}> ${translate("walletpage.wchange45")} QORT -
      -

    -

    - - -

    -

    - - -

    -
    -

    ${translate("walletpage.wchange21")} ${this.qortPaymentFee} QORT

    -
    - ${this.renderClearSuccess()} - ${this.renderClearError()} - ${this.sendMoneyLoading ? html` ` : ''} -
    -
    - this.sendQort()}> - - ${translate("walletpage.wchange17")} QORT - -
    ${this.renderWarning()}
    -
    -
    -
    - - ${translate("general.close")} - -
    - - -
    -
    - -

    ${translate("walletpage.wchange17")} BTC

    -
    -
    -

    - From address:
    - ${this.getSelectedWalletAddress()} -

    -

    - Available balance:
    - ${this.balanceString}
    - - this.calculateBtcAll()}> ${translate("walletpage.wchange45")} BTC -
      -

    -

    - - -

    -

    - - -

    -
    -

    ${translate("walletpage.wchange24")}: ${(this.btcFeePerByte / 1e8).toFixed(8)} BTC
    ${translate("walletpage.wchange25")}

    - - -
    - ${this.renderClearSuccess()} - ${this.renderClearError()} - ${this.sendMoneyLoading ? html` ` : ''} -
    -
    - this.sendBtc()}> - - ${translate("walletpage.wchange17")} BTC - -
    -
    -
    - - ${translate("general.close")} - -
    - - -
    -
    - -

    ${translate("walletpage.wchange17")} LTC

    -
    -
    -

    - ${translate("walletpage.wchange18")}:
    - ${this.getSelectedWalletAddress()} -

    -

    - ${translate("walletpage.wchange19")}:
    - ${this.balanceString}
    - - this.calculateLtcAll()}> ${translate("walletpage.wchange45")} LTC -
      -

    -

    - - -

    -

    - - -

    -
    -

    ${translate("walletpage.wchange24")}: ${(this.ltcFeePerByte / 1e8).toFixed(8)} LTC
    ${translate("walletpage.wchange25")}

    - - -
    - ${this.renderClearSuccess()} - ${this.renderClearError()} - ${this.sendMoneyLoading ? html` ` : ''} -
    -
    - this.sendLtc()}> - - ${translate("walletpage.wchange17")} LTC - -
    -
    -
    - - ${translate("general.close")} - -
    - - -
    -
    - -

    ${translate("walletpage.wchange17")} DOGE

    -
    -
    -

    - ${translate("walletpage.wchange18")}:
    - ${this.getSelectedWalletAddress()} -

    -

    - ${translate("walletpage.wchange19")}:
    - ${this.balanceString}
    - - this.calculateDogeAll()}> ${translate("walletpage.wchange45")} DOGE -
      -

    -

    - - -

    -

    - - -

    -
    -

    - ${translate("walletpage.wchange24")}: ${(this.dogeFeePerByte / 1e8).toFixed(8)} DOGE
    ${translate("walletpage.wchange25")} -

    - - -
    - ${this.renderClearSuccess()} - ${this.renderClearError()} - ${this.sendMoneyLoading ? html` ` : ''} -
    -
    - this.sendDoge()}> - - ${translate("walletpage.wchange17")} DOGE - -
    -
    -
    - - ${translate("general.close")} - -
    - - -
    -
    - -

    ${translate("walletpage.wchange17")} DGB

    -
    -
    -

    - ${translate("walletpage.wchange18")}:
    - ${this.getSelectedWalletAddress()} -

    -

    - ${translate("walletpage.wchange19")}:
    - ${this.balanceString}
    - - this.calculateDgbAll()}> ${translate("walletpage.wchange45")} DGB -
      -

    -

    - - -

    -

    - - -

    -
    -

    - ${translate("walletpage.wchange24")}: ${(this.dgbFeePerByte / 1e8).toFixed(8)} DGB
    ${translate("walletpage.wchange25")} -

    - - -
    - ${this.renderClearSuccess()} - ${this.renderClearError()} - ${this.sendMoneyLoading ? html` ` : ''} -
    -
    - this.sendDgb()}> - - ${translate("walletpage.wchange17")} DGB - -
    -
    -
    - - ${translate("general.close")} - -
    - - -
    -
    - -

    ${translate("walletpage.wchange17")} RVN

    -
    -
    -

    - ${translate("walletpage.wchange18")}:
    - ${this.getSelectedWalletAddress()} -

    -

    - ${translate("walletpage.wchange19")}:
    - ${this.balanceString}
    - - this.calculateRvnAll()}> ${translate("walletpage.wchange45")} RVN -
      -

    -

    - - -

    -

    - - -

    -
    -

    - ${translate("walletpage.wchange24")}: ${(this.rvnFeePerByte / 1e8).toFixed(8)} RVN
    ${translate("walletpage.wchange25")} -

    - - -
    - ${this.renderClearSuccess()} - ${this.renderClearError()} - ${this.sendMoneyLoading ? html` ` : ''} -
    -
    - this.sendRvn()}> - - ${translate("walletpage.wchange17")} RVN - -
    -
    -
    - - ${translate("general.close")} - -
    - - -
    -
    - -

    ${translate("walletpage.wchange17")} ARRR

    -
    -
    -

    - ${translate("walletpage.wchange18")}:
    - ${this.getSelectedWalletAddress()} -

    -

    - ${translate("walletpage.wchange19")}:
    - ${this.balanceString}
    - - this.calculateArrrAll()}> ${translate("walletpage.wchange45")} ARRR -
      -

    -

    - - -

    -

    - - -

    -

    - - -

    -

    ${this.errorMessage}

    -

    ${this.successMessage}

    - ${this.sendMoneyLoading ? html` ` : ''} -
    -
    - this.sendArrr()}> - - ${translate("walletpage.wchange17")} ARRR - -
    -
    -
    - - ${translate("general.close")} - -
    - - -
    - -

    Qortal ${translate("walletpage.wchange47")}

    -
    -
    ${this.renderExportAddressbookButton()}
    ${this.renderImportAddressbookButton()}


    -
    -
    - - - - { - render(html`${this.renderSendFromQortAddressbookButton(data.item)}`, root); - }}> - - { - render(html` this.removeQortAddress(data.item.address)}>delete ${translate("nodepage.nchange12")}`, root) - }}> - - - ${this.isEmptyArray(this.qortBook) ? html` - ${translate("walletpage.wchange48")} - `: ''} - - ${translate("general.close")} - - this.openAddToQortAddressbook()} - > - ${translate("rewardsharepage.rchange14")} - -
    - - -
    - -

    Bitcoin ${translate("walletpage.wchange47")}

    -
    -
    ${this.renderExportAddressbookButton()}
    ${this.renderImportAddressbookButton()}


    -
    -
    - - - - { - render(html`${this.renderSendFromBtcAddressbookButton(data.item)}`, root); - }}> - - { - render(html` this.removeBtcAddress(data.item.address)}>delete ${translate("nodepage.nchange12")}`, root) - }}> - - - ${this.isEmptyArray(this.btcBook) ? html` - ${translate("walletpage.wchange48")} - `: ''} - - ${translate("general.close")} - - this.openAddToBtcAddressbook()} - > - ${translate("rewardsharepage.rchange14")} - -
    - - -
    - -

    Litecoin ${translate("walletpage.wchange47")}

    -
    -
    ${this.renderExportAddressbookButton()}
    ${this.renderImportAddressbookButton()}


    -
    -
    - - - - { - render(html`${this.renderSendFromLtcAddressbookButton(data.item)}`, root); - }}> - - { - render(html` this.removeLtcAddress(data.item.address)}>delete ${translate("nodepage.nchange12")}`, root) - }}> - - - ${this.isEmptyArray(this.ltcBook) ? html` - ${translate("walletpage.wchange48")} - `: ''} - - ${translate("general.close")} - - this.openAddToLtcAddressbook()} - > - ${translate("rewardsharepage.rchange14")} - -
    - - -
    - -

    Dogecoin ${translate("walletpage.wchange47")}

    -
    -
    ${this.renderExportAddressbookButton()}
    ${this.renderImportAddressbookButton()}


    -
    -
    - - - - { - render(html`${this.renderSendFromDogeAddressbookButton(data.item)}`, root); - }}> - - { - render(html` this.removeDogeAddress(data.item.address)}>delete ${translate("nodepage.nchange12")}`, root) - }}> - - - ${this.isEmptyArray(this.dogeBook) ? html` - ${translate("walletpage.wchange48")} - `: ''} - - ${translate("general.close")} - - this.openAddToDogeAddressbook()} - > - ${translate("rewardsharepage.rchange14")} - -
    - - -
    - -

    Digibyte ${translate("walletpage.wchange47")}

    -
    -
    ${this.renderExportAddressbookButton()}
    ${this.renderImportAddressbookButton()}


    -
    -
    - - - - { - render(html`${this.renderSendFromDgbAddressbookButton(data.item)}`, root); - }}> - - { - render(html` this.removeDgbAddress(data.item.address)}>delete ${translate("nodepage.nchange12")}`, root) - }}> - - - ${this.isEmptyArray(this.dgbBook) ? html` - ${translate("walletpage.wchange48")} - `: ''} - - ${translate("general.close")} - - this.openAddToDgbAddressbook()} - > - ${translate("rewardsharepage.rchange14")} - -
    - - -
    - -

    Ravencoin ${translate("walletpage.wchange47")}

    -
    -
    ${this.renderExportAddressbookButton()}
    ${this.renderImportAddressbookButton()}


    -
    -
    - - - - { - render(html`${this.renderSendFromRvnAddressbookButton(data.item)}`, root); - }}> - - { - render(html` this.removeRvnAddress(data.item.address)}>delete ${translate("nodepage.nchange12")}`, root) - }}> - - - ${this.isEmptyArray(this.rvnBook) ? html` - ${translate("walletpage.wchange48")} - `: ''} - - ${translate("general.close")} - - this.openAddToRvnAddressbook()} - > - ${translate("rewardsharepage.rchange14")} - -
    - - -
    - -

    Pirate Chain ${translate("walletpage.wchange47")}

    -
    -
    ${this.renderExportAddressbookButton()}
    ${this.renderImportAddressbookButton()}


    -
    -
    - - - - { - render(html`${this.renderSendFromArrrAddressbookButton(data.item)}`, root); - }}> - - { - render(html` this.removeArrrAddress(data.item.address)}>delete ${translate("nodepage.nchange12")}`, root) - }}> - - - ${this.isEmptyArray(this.arrrBook) ? html` - ${translate("walletpage.wchange48")} - `: ''} - - ${translate("general.close")} - - this.openAddToArrrAddressbook()} - > - ${translate("rewardsharepage.rchange14")} - -
    - - -
    - -

    Qortal ${translate("walletpage.wchange47")}


    -

    ${translate("walletpage.wchange49")}

    -
    -
    -
    -
    -

    - - -

    -

    - - -

    -
    -
    -
    - this.addToQortalAddressbook()}> - - ${translate("walletpage.wchange49")} - -
    -
    - - ${translate("general.close")} - -
    - - -
    - -

    Bitcoin ${translate("walletpage.wchange47")}


    -

    ${translate("walletpage.wchange49")}

    -
    -
    -
    -
    -

    - - -

    -

    - - -

    -
    -
    -
    - this.addToBitcoinAddressbook()}> - - ${translate("walletpage.wchange49")} - -
    -
    - - ${translate("general.close")} - -
    - - -
    - -

    Litecoin ${translate("walletpage.wchange47")}


    -

    ${translate("walletpage.wchange49")}

    -
    -
    -
    -
    -

    - - -

    -

    - - -

    -
    -
    -
    - this.addToLitecoinAddressbook()}> - - ${translate("walletpage.wchange49")} - -
    -
    - - ${translate("general.close")} - -
    - - -
    - -

    Dogecoin ${translate("walletpage.wchange47")}


    -

    ${translate("walletpage.wchange49")}

    -
    -
    -
    -
    -

    - - -

    -

    - - -

    -
    -
    -
    - this.addToDogecoinAddressbook()}> - - ${translate("walletpage.wchange49")} - -
    -
    - - ${translate("general.close")} - -
    - - -
    - -

    Digibyte ${translate("walletpage.wchange47")}


    -

    ${translate("walletpage.wchange49")}

    -
    -
    -
    -
    -

    - - -

    -

    - - -

    -
    -
    -
    - this.addToDigibyteAddressbook()}> - - ${translate("walletpage.wchange49")} - -
    -
    - - ${translate("general.close")} - -
    - - -
    - -

    Ravencoin ${translate("walletpage.wchange47")}


    -

    ${translate("walletpage.wchange49")}

    -
    -
    -
    -
    -

    - - -

    -

    - - -

    -
    -
    -
    - this.addToRavencoinAddressbook()}> - - ${translate("walletpage.wchange49")} - -
    -
    - - ${translate("general.close")} - -
    - - -
    - -

    Pirate Chain ${translate("walletpage.wchange47")}


    -

    ${translate("walletpage.wchange49")}

    -
    -
    -
    -
    -

    - - -

    -

    - - -

    -
    -
    -
    - this.addToPiratechainAddressbook()}> - - ${translate("walletpage.wchange49")} - -
    -
    - - ${translate("general.close")} - -
    - - -
    - -

    Qortal ${translate("walletpage.wchange53")}


    -
    -
    -
    -
    - -

    ${translate("walletpage.wchange56")}

    -
    ${translate("walletpage.wchange55")}
    -
    - - ${translate("general.close")} - -
    - - -
    - -

    Bitcoin ${translate("walletpage.wchange53")}


    -
    -
    -
    -
    - -

    ${translate("walletpage.wchange56")}

    -
    ${translate("walletpage.wchange55")}
    -
    - - ${translate("general.close")} - -
    - - -
    - -

    Litecoin ${translate("walletpage.wchange53")}


    -
    -
    -
    -
    - -

    ${translate("walletpage.wchange56")}

    -
    ${translate("walletpage.wchange55")}
    -
    - - ${translate("general.close")} - -
    - - -
    - -

    Dogecoin ${translate("walletpage.wchange53")}


    -
    -
    -
    -
    - -

    ${translate("walletpage.wchange56")}

    -
    ${translate("walletpage.wchange55")}
    -
    - - ${translate("general.close")} - -
    - - -
    - -

    Digibyte ${translate("walletpage.wchange53")}


    -
    -
    -
    -
    - -

    ${translate("walletpage.wchange56")}

    -
    ${translate("walletpage.wchange55")}
    -
    - - ${translate("general.close")} - -
    - - -
    - -

    Litecoin ${translate("walletpage.wchange53")}


    -
    -
    -
    -
    - -

    ${translate("walletpage.wchange56")}

    -
    ${translate("walletpage.wchange55")}
    -
    - - ${translate("general.close")} - -
    - - -
    - -

    Pirate Chain ${translate("walletpage.wchange53")}


    -
    -
    -
    -
    - -

    ${translate("walletpage.wchange56")}

    -
    ${translate("walletpage.wchange55")}
    -
    - - ${translate("general.close")} - -
    -
    - -
    -

    Qortal ${translate("tabmenu.tm5")} ${translate("login.lp1")}

    -
    -
    -
    -

    ${translate("login.lp2")}

    -

    ${translate("login.lp3")}

    -
    -
    - password - -
    -
    - password - -
    -
    - ${translate("login.lp4")} - ${translate("login.lp5")} -
    -
    - -
    -

    Qortal ${translate("tabmenu.tm5")} ${translate("login.lp1")}

    -
    -
    -
    -

    ${translate("login.lessthen8")}

    -
    -
    - ${translate("login.lp4")} - ${translate("login.lp5")} -
    -
    - -
    - ${translate("sidemenu.wallets")}
    - ${translate("login.lp9")} - ${translate("login.lp10")} -
    -
    - password - -
    - ${this.walletHelperMessage} -
    -
    -
    -
    - -
    -
    - ` - } - - firstUpdated() { - - this.changeTheme() - this.changeLanguage() - this.paymentFee() - this.getNodeConfig() - - this.bookQortalAddress = window.parent.reduxStore.getState().app.selectedAddress.address - this.bookBitcoinAddress = window.parent.reduxStore.getState().app.selectedAddress.btcWallet.address - this.bookLitecoinAddress = window.parent.reduxStore.getState().app.selectedAddress.ltcWallet.address - this.bookDogecoinAddress = window.parent.reduxStore.getState().app.selectedAddress.dogeWallet.address - this.bookDigibyteAddress = window.parent.reduxStore.getState().app.selectedAddress.dgbWallet.address - this.bookRavencoinAddress = window.parent.reduxStore.getState().app.selectedAddress.rvnWallet.address - this.bookPiratechainAddress = window.parent.reduxStore.getState().app.selectedAddress.arrrWallet.address - - this.walletHelperMessage = this.renderWalletHelperPass() - - this.walletSalt = '' - this.walletSalt = Base58.encode(window.parent.reduxStore.getState().app.wallet._addresses[0].keyPair.privateKey) - - this.walletStorageData = '' - this.walletStorageData = window.parent.reduxStore.getState().app.selectedAddress.address - - this.walletLockScreenPass = '' - this.walletLockScreenPass = 'walletLockScreenPass-' + this.walletStorageData - - this.walletLockScreenSet = '' - this.walletLockScreenSet = 'walletLockScreenSet-' + this.walletStorageData - - this.walletLockPass = '' - this.walletLockPass = encryptData(false, this.walletSalt) - - this.walletLockSet = '' - this.walletLockSet = encryptData(false, this.walletSalt) - - if (localStorage.getItem(this.walletLockScreenPass) === null && localStorage.getItem(this.walletLockScreenSet) === null) { - localStorage.setItem(this.walletLockScreenPass, this.walletLockPass) - localStorage.setItem(this.walletLockScreenSet, this.walletLockSet) - this.myWalletLockScreenPass = '' - this.myWalletLockScreenPass = decryptData(localStorage.getItem(this.walletLockScreenPass), this.walletSalt) - this.myWalletLockScreenSet = '' - this.myWalletLockScreenSet = decryptData(localStorage.getItem(this.walletLockScreenSet), this.walletSalt) - } else { - this.myWalletLockScreenPass = '' - this.myWalletLockScreenPass = decryptData(localStorage.getItem(this.walletLockScreenPass), this.walletSalt) - this.myWalletLockScreenSet = '' - this.myWalletLockScreenSet = decryptData(localStorage.getItem(this.walletLockScreenSet), this.walletSalt) - } - - if (this.myWalletLockScreenSet === true) { - this.shadowRoot.getElementById('walletLockScreenActive').open() - } - - this.qortAddressbook() - this.btcAddressbook() - this.ltcAddressbook() - this.dogeAddressbook() - this.dgbAddressbook() - this.rvnAddressbook() - this.arrrAddressbook() - - this.transactionsDOM = this.shadowRoot.getElementById('transactionsDOM') - - this.showWallet() - - window.addEventListener('storage', () => { - const checkLanguage = localStorage.getItem('qortalLanguage') - const checkTheme = localStorage.getItem('qortalTheme') - - use(checkLanguage) - - if (checkTheme === 'dark') { - this.theme = 'dark' - } else { - this.theme = 'light' - } - document.querySelector('html').setAttribute('theme', this.theme) - }) - - if (!isElectron()) { - } else { - window.addEventListener('contextmenu', (event) => { - event.preventDefault() - window.parent.electronAPI.showMyMenu() - }) - } - - this.clearConsole() - - setInterval(() => { - this.clearConsole() - this.getNodeConfig() - }, 60000) - - setInterval(() => { - this.paymentFee() - }, 600000) - } - - async paymentFee() { - const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] - const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port - const url = `${nodeUrl}/transactions/unitfee?txType=PAYMENT` - await fetch(url).then((response) => { - if (response.ok) { - return response.json() - } - return Promise.reject(response) - }).then((json) => { - this.qortPaymentFee = (Number(json) / 1e8).toFixed(8) - }) - } - - clearConsole() { - if (!isElectron()) { - } else { - console.clear() - window.parent.electronAPI.clearCache() - } - } - - pingCoinBalancesController(){ - if(!this._selectedWallet) return - const customEvent = new CustomEvent('ping-coin-controller-with-coin', { - detail: this._selectedWallet - }); - window.parent.dispatchEvent(customEvent); - } - - connectedCallback() { - super.connectedCallback() - this.intervalID = setInterval(this.pingCoinBalancesController, 30000) - } - - disconnectedCallback() { - super.disconnectedCallback() - if(this.intervalID) { - clearInterval(this.intervalID) - } - } - - renderWalletLockButton() { - if (this.myWalletLockScreenPass === false && this.myWalletLockScreenSet === false) { - return html` -
    - this.openWalletSetScreenLockPass()} title="${translate("login.lp11")}"> -
    - ` - } else if (this.myWalletLockScreenSet === false) { - return html` -
    - this.setWalletLockQortal()} title="${translate("login.lp11")}"> -
    - ` - } else if (this.myWalletLockScreenSet === true) { - return html` -
    - -
    - ` - } - } - - openWalletSetScreenLockPass() { - this.shadowRoot.getElementById('walletLockPassword').value = '' - this.shadowRoot.getElementById('walletLockPasswordConfirm').value = '' - this.shadowRoot.getElementById('setWalletLockScreenPass').open() - } - - closewWalletSetScreenLockPass() { - this.shadowRoot.getElementById('setWalletLockScreenPass').close() - } - - walletCheckPass() { - const walletPassword = this.shadowRoot.getElementById('walletLockPassword').value - const walletRePassword = this.shadowRoot.getElementById('walletLockPasswordConfirm').value - - if (walletPassword === '') { - let snackbar1string = get("login.pleaseenter") - parentEpml.request('showSnackBar', `${snackbar1string}`) - return - } - - if (walletPassword != walletRePassword) { - let snackbar2string = get("login.notmatch") - parentEpml.request('showSnackBar', `${snackbar2string}`) - return - } - - if (walletPassword.length < 8) { - let snackbar3string = get("login.lessthen8") - parentEpml.request('showSnackBar', `${snackbar3string}`) - this.walletExtraConfirm() - } - - if (walletPassword.length >= 8) { - this.setWalletNewScreenPass() - let snackbar4string = get("login.lp6") - parentEpml.request('showSnackBar', `${snackbar4string}`) - } - } - - walletExtraConfirm() { - this.shadowRoot.getElementById('setWalletLockScreenPass').close() - this.shadowRoot.getElementById('walletExtraConfirmPass').open() - } - - closWalletExtraConfirmPass() { - this.shadowRoot.getElementById('walletExtraConfirmPass').close() - this.shadowRoot.getElementById('walletLockPassword').value = '' - this.shadowRoot.getElementById('walletLockPasswordConfirm').value = '' - } - - setWalletNewScreenPass() { - const walletRawPassword = this.shadowRoot.getElementById('walletLockPassword').value - const walletCryptPassword = encryptData(walletRawPassword, this.walletSalt) - localStorage.setItem(this.walletLockScreenPass, walletCryptPassword) - this.myWalletLockScreenPass = '' - this.myWalletLockScreenPass = decryptData(localStorage.getItem(this.walletLockScreenPass), this.walletSalt) - this.shadowRoot.getElementById('setWalletLockScreenPass').close() - this.shadowRoot.getElementById('walletExtraConfirmPass').close() - this.shadowRoot.getElementById('walletLockPassword').value = '' - this.shadowRoot.getElementById('walletLockPasswordConfirm').value = '' - } - - setWalletLockQortal() { - this.walletHelperMessage = this.renderWalletHelperPass() - this.walletLockSet = '' - this.walletLockSet = encryptData(true, this.walletSalt) - localStorage.setItem(this.walletLockScreenSet, this.walletLockSet) - this.myWalletLockScreenSet = '' - this.myWalletLockScreenSet = decryptData(localStorage.getItem(this.walletLockScreenSet), this.walletSalt) - this.shadowRoot.getElementById('walletLockScreenActive').open() - } - - walletPassKeyListener(e) { - if (e.key === 'Enter') { - this.closeWalletLockScreenActive() - } - } - - async closeWalletLockScreenActive() { - const myWalletPass = decryptData(localStorage.getItem(this.walletLockScreenPass), this.walletSalt) - const walletCheckPass = this.shadowRoot.getElementById('walletUnlockPassword').value - const errDelay = ms => new Promise(res => setTimeout(res, ms)) - - if (walletCheckPass === myWalletPass) { - this.walletLockSet = '' - this.walletLockSet = encryptData(false, this.walletSalt) - localStorage.setItem(this.walletLockScreenSet, this.walletLockSet) - this.myWalletLockScreenSet = '' - this.myWalletLockScreenSet = decryptData(localStorage.getItem(this.walletLockScreenSet), this.walletSalt) - this.shadowRoot.getElementById('walletLockScreenActive').close() - this.shadowRoot.getElementById('walletUnlockPassword').value = '' - this.walletHelperMessage = this.renderWalletHelperPass() - } else { - this.shadowRoot.getElementById('walletUnlockPassword').value = '' - this.walletHelperMessage = this.renderWalletHelperErr() - await errDelay(3000) - this.walletHelperMessage = this.renderWalletHelperPass() - - } - } - - renderWalletHelperPass() { - return html`${translate("login.pleaseenter")}` - } - - renderWalletHelperErr() { - return html`${translate("login.lp8")}` - } - - renderWarning() { - return html`${translate("tradepage.tchange48")} QORT` - } - - renderClearSuccess() { - let strSuccessValue = this.successMessage - if (strSuccessValue === "") { - return html`` - } else { - return html` -
    - ${this.successMessage} - -
    -
    -

    ${translate("walletpage.wchange43")}

    -
    - ` - } - } - - renderClearError() { - let strErrorValue = this.errorMessage - if (strErrorValue === "") { - return html`` - } else { - return html` -
    - ${this.errorMessage} - -
    -
    -

    ${translate("walletpage.wchange44")}

    -
    - ` - } - } - - tabWalletQort() { - this._selectedWallet = 'qort' - this.showWallet() - } - - tabWalletBtc() { - this._selectedWallet = 'btc' - this.showWallet() - } - - tabWalletLtc() { - this._selectedWallet = 'ltc' - this.showWallet() - } - - tabWalletDoge() { - this._selectedWallet = 'doge' - this.showWallet() - } - - tabWalletDgb() { - this._selectedWallet = 'dgb' - this.showWallet() - } - - tabWalletRvn() { - this._selectedWallet = 'rvn' - this.showWallet() - } - - tabWalletArrr() { - this._selectedWallet = 'arrr' - this.showWallet() - } - - qortAddressbook() { - const storedQortalAddressBook = 'addressbookQort-' + this.bookQortalAddress - if (localStorage.getItem(storedQortalAddressBook) === null) { - localStorage.setItem(storedQortalAddressBook, "") - } else { - this.qortBook = JSON.parse(localStorage.getItem(storedQortalAddressBook) || "[]") - } - } - - btcAddressbook() { - const storedBitcoinAddressBook = 'addressbookBtc-' + this.bookBitcoinAddress - if (localStorage.getItem(storedBitcoinAddressBook) === null) { - localStorage.setItem(storedBitcoinAddressBook, "") - } else { - this.btcBook = JSON.parse(localStorage.getItem(storedBitcoinAddressBook) || "[]") - } - } - - ltcAddressbook() { - const storedLitecoinAddressBook = 'addressbookLtc-' + this.bookLitecoinAddress - if (localStorage.getItem(storedLitecoinAddressBook) === null) { - localStorage.setItem(storedLitecoinAddressBook, "") - } else { - this.ltcBook = JSON.parse(localStorage.getItem(storedLitecoinAddressBook) || "[]") - } - } - - dogeAddressbook() { - const storedDogecoinAddressBook = 'addressbookDoge-' + this.bookDogecoinAddress - if (localStorage.getItem(storedDogecoinAddressBook) === null) { - localStorage.setItem(storedDogecoinAddressBook, "") - } else { - this.dogeBook = JSON.parse(localStorage.getItem(storedDogecoinAddressBook) || "[]") - } - } - - dgbAddressbook() { - const storedDigibyteAddressBook = 'addressbookDgb-' + this.bookDigibyteAddress - if (localStorage.getItem(storedDigibyteAddressBook) === null) { - localStorage.setItem(storedDigibyteAddressBook, "") - } else { - this.dgbBook = JSON.parse(localStorage.getItem(storedDigibyteAddressBook) || "[]") - } - } - - rvnAddressbook() { - const storedRavencoinAddressBook = 'addressbookRvn-' + this.bookRavencoinAddress - if (localStorage.getItem(storedRavencoinAddressBook) === null) { - localStorage.setItem(storedRavencoinAddressBook, "") - } else { - this.rvnBook = JSON.parse(localStorage.getItem(storedRavencoinAddressBook) || "[]") - } - } - - arrrAddressbook() { - const storedPiratechainAddressBook = 'addressbookArrr-' + this.bookPiratechainAddress - if (localStorage.getItem(storedPiratechainAddressBook) === null) { - localStorage.setItem(storedPiratechainAddressBook, "") - } else { - this.arrrBook = JSON.parse(localStorage.getItem(storedPiratechainAddressBook) || "[]") - } - } - - openQortAddressbook() { - this.shadowRoot.querySelector("#qortBookDialog").show() - } - - openBtcAddressbook() { - this.shadowRoot.querySelector("#btcBookDialog").show() - } - - openLtcAddressbook() { - this.shadowRoot.querySelector("#ltcBookDialog").show() - } - - openDogeAddressbook() { - this.shadowRoot.querySelector("#dogeBookDialog").show() - } - - openDgbAddressbook() { - this.shadowRoot.querySelector("#dgbBookDialog").show() - } - - openRvnAddressbook() { - this.shadowRoot.querySelector("#rvnBookDialog").show() - } - - openArrrAddressbook() { - this.shadowRoot.querySelector("#arrrBookDialog").show() - } - - openAddQortAddressDialog() { - this.qortBookAddress = this.selectedTransaction.recipient - this.openAddToQortAddressbook() - this.shadowRoot.querySelector('#showTransactionDetailsDialog').close() - } - - openAddBtcAddressDialog() { - this.btcBookAddress = this.selectedTransaction.btcReceiver - this.openAddToBtcAddressbook() - this.shadowRoot.querySelector('#showBtcTransactionDetailsDialog').close() - } - - openAddLtcAddressDialog() { - this.ltcBookAddress = this.selectedTransaction.ltcReceiver - this.openAddToLtcAddressbook() - this.shadowRoot.querySelector('#showLtcTransactionDetailsDialog').close() - } - - openAddDogeAddressDialog() { - this.dogeBookAddress = this.selectedTransaction.dogeReceiver - this.openAddToDogeAddressbook() - this.shadowRoot.querySelector('#showDogeTransactionDetailsDialog').close() - } - - openAddDgbAddressDialog() { - this.dgbBookAddress = this.selectedTransaction.dgbReceiver - this.openAddToDgbAddressbook() - this.shadowRoot.querySelector('#showDgbTransactionDetailsDialog').close() - } - - openAddRvnAddressDialog() { - this.rvnBookAddress = this.selectedTransaction.rvnReceiver - this.openAddToRvnAddressbook() - this.shadowRoot.querySelector('#showRvnTransactionDetailsDialog').close() - } - - openAddArrrAddressDialog() { - this.arrrBookAddress = this.selectedTransaction.arrrReceiver - this.openAddToArrrAddressbook() - this.shadowRoot.querySelector('#showArrrTransactionDetailsDialog').close() - } - - openAddToQortAddressbook() { - this.shadowRoot.querySelector("#addQortAddressDialog").show() - } - - openAddToBtcAddressbook() { - this.shadowRoot.querySelector("#addBtcAddressDialog").show() - } - - openAddToLtcAddressbook() { - this.shadowRoot.querySelector("#addLtcAddressDialog").show() - } - - openAddToDogeAddressbook() { - this.shadowRoot.querySelector("#addDogeAddressDialog").show() - } - - openAddToDgbAddressbook() { - this.shadowRoot.querySelector("#addDgbAddressDialog").show() - } - - openAddToRvnAddressbook() { - this.shadowRoot.querySelector("#addRvnAddressDialog").show() - } - - openAddToArrrAddressbook() { - this.shadowRoot.querySelector("#addArrrAddressDialog").show() - } - - openImportQortAddressbook() { - this.shadowRoot.querySelector("#importQortAddressbookDialog").show() - } - - openImportBtcAddressbook() { - this.shadowRoot.querySelector("#importBtcAddressbookDialog").show() - } - - openImportLtcAddressbook() { - this.shadowRoot.querySelector("#importLtcAddressbookDialog").show() - } - - openImportDogeAddressbook() { - this.shadowRoot.querySelector("#importDogeAddressbookDialog").show() - } - - openImportDgbAddressbook() { - this.shadowRoot.querySelector("#importDgbAddressbookDialog").show() - } - - openImportRvnAddressbook() { - this.shadowRoot.querySelector("#importRvnAddressbookDialog").show() - } - - openImportArrrAddressbook() { - this.shadowRoot.querySelector("#importArrrAddressbookDialog").show() - } - - closeQortAddressDialog() { - this.shadowRoot.querySelector('#addQortAddressDialog').close() - this.shadowRoot.getElementById('qortNameInput').value = '' - this.shadowRoot.getElementById('qortAddressInput').value = '' - this.qortBookName = '' - this.qortBookAddress = '' - } - - closeBtcAddressDialog() { - this.shadowRoot.querySelector('#addBtcAddressDialog').close() - this.shadowRoot.getElementById('btcNameInput').value = '' - this.shadowRoot.getElementById('btcAddressInput').value = '' - this.btcBookName = '' - this.btcBookAddress = '' - } - - closeLtcAddressDialog() { - this.shadowRoot.querySelector('#addLtcAddressDialog').close() - this.shadowRoot.getElementById('ltcNameInput').value = '' - this.shadowRoot.getElementById('ltcAddressInput').value = '' - this.ltcBookName = '' - this.ltcBookAddress = '' - } - - closeDogeAddressDialog() { - this.shadowRoot.querySelector('#addDogeAddressDialog').close() - this.shadowRoot.getElementById('dogeNameInput').value = '' - this.shadowRoot.getElementById('dogeAddressInput').value = '' - this.dogeBookName = '' - this.dogeBookAddress = '' - } - - closeDgbAddressDialog() { - this.shadowRoot.querySelector('#addDgbAddressDialog').close() - this.shadowRoot.getElementById('dgbNameInput').value = '' - this.shadowRoot.getElementById('dgbAddressInput').value = '' - this.dgbBookName = '' - this.dgbBookAddress = '' - } - - closeRvnAddressDialog() { - this.shadowRoot.querySelector('#addRvnAddressDialog').close() - this.shadowRoot.getElementById('rvnNameInput').value = '' - this.shadowRoot.getElementById('rvnAddressInput').value = '' - this.rvnBookName = '' - this.rvnBookAddress = '' - } - - closeArrrAddressDialog() { - this.shadowRoot.querySelector('#addArrrAddressDialog').close() - this.shadowRoot.getElementById('arrrNameInput').value = '' - this.shadowRoot.getElementById('arrrAddressInput').value = '' - this.arrrBookName = '' - this.arrrBookAddress = '' - } - - closeImportQortAddressbookDialog() { - this.shadowRoot.querySelector("#importQortAddressbookDialog").close() - } - - closeImportBtcAddressbookDialog() { - this.shadowRoot.querySelector("#importBtcAddressbookDialog").close() - } - - closeImportLtcAddressbookDialog() { - this.shadowRoot.querySelector("#importLtcAddressbookDialog").close() - } - - closeImportDogeAddressbookDialog() { - this.shadowRoot.querySelector("#importDogeAddressbookDialog").close() - } - - closeImportDgbAddressbookDialog() { - this.shadowRoot.querySelector("#importDgbAddressbookDialog").close() - } - - closeImportRvnAddressbookDialog() { - this.shadowRoot.querySelector("#importRvnAddressbookDialog").close() - } - - closeImportArrrAddressbookDialog() { - this.shadowRoot.querySelector("#importArrrAddressbookDialog").close() - } - - addToQortalAddressbook() { - const myQortalAddressBook = 'addressbookQort-' + this.bookQortalAddress - - let name = this.shadowRoot.getElementById('qortNameInput').value - let address = this.shadowRoot.getElementById('qortAddressInput').value - - var oldQortalBook = JSON.parse(localStorage.getItem(myQortalAddressBook) || "[]") - - if (name.length === 0) { - let qortbookstring1 = get("walletpage.wchange50") - parentEpml.request('showSnackBar', `${qortbookstring1}`) - return false - } - - if (address.length === 0) { - let qortbookstring2 = get("walletpage.wchange51") - parentEpml.request('showSnackBar', `${qortbookstring2}`) - return false - } - - const newQortalBookItem = { - name: name, - address: address - } - - oldQortalBook.push(newQortalBookItem) - - localStorage.setItem(myQortalAddressBook, JSON.stringify(oldQortalBook)) - - let qortbookstring2 = get("walletpage.wchange52") - parentEpml.request('showSnackBar', `${qortbookstring2}`) - - this.closeQortAddressDialog() - this.qortBook = JSON.parse(localStorage.getItem(myQortalAddressBook) || "[]") - } - - addToBitcoinAddressbook() { - const myBitcoinAddressBook = 'addressbookBtc-' + this.bookBitcoinAddress + static get properties() { + return { + loading: { type: Boolean }, + transactions: { type: Object }, + lastBlock: { type: Object }, + selectedTransaction: { type: Object }, + isTextMenuOpen: { type: Boolean }, + wallets: { type: Map }, + _selectedWallet: 'qort', + nodeConfig: { type: Object }, + nodeDomain: { type: String }, + theme: { type: String, reflect: true }, + amount: { type: Number }, + recipient: { type: String }, + btcRecipient: { type: String }, + btcAmount: { type: Number }, + ltcRecipient: { type: String }, + ltcAmount: { type: Number }, + dogeRecipient: { type: String }, + dogeAmount: { type: Number }, + dgbRecipient: { type: String }, + dgbAmount: { type: Number }, + rvnRecipient: { type: String }, + rvnAmount: { type: Number }, + arrrRecipient: { type: String }, + arrrAmount: { type: Number }, + arrrMemo: { type: String }, + errorMessage: { type: String }, + arrrWalletAddress: { type: String }, + unusedWalletAddress: { type: String }, + successMessage: { type: String }, + sendMoneyLoading: { type: Boolean }, + btnDisable: { type: Boolean }, + qortWarning: { type: Boolean }, + isValidAmount: { type: Boolean }, + balance: { type: Number }, + balanceString: { type: String }, + btcServer: { type: Number }, + ltcServer: { type: Number }, + dogeServer: { type: Number }, + dgbServer: { type: Number }, + rvnServer: { type: Number }, + arrrServer: { type: Number }, + qortPaymentFee: { type: Number }, + btcFeePerByte: { type: Number }, + ltcFeePerByte: { type: Number }, + dogeFeePerByte: { type: Number }, + dgbFeePerByte: { type: Number }, + rvnFeePerByte: { type: Number }, + qortBook: { type: Array }, + btcBook: { type: Array }, + ltcBook: { type: Array }, + dogeBook: { type: Array }, + dgbBook: { type: Array }, + rvnBook: { type: Array }, + arrrBook: { type: Array }, + qortBookName: { type: String }, + btcBookName: { type: String }, + ltcBookName: { type: String }, + dogeBookName: { type: String }, + dgbBookName: { type: String }, + rvnBookName: { type: String }, + arrrBookName: { type: String }, + qortBookAddress: { type: String }, + btcBookAddress: { type: String }, + ltcBookAddress: { type: String }, + dogeBookAddress: { type: String }, + dgbBookAddress: { type: String }, + rvnBookAddress: { type: String }, + arrrBookAddress: { type: String }, + myElementId: { type: String }, + walletSalt: { type: String }, + walletStorageData: { type: String }, + walletLockScreenPass: { type: String }, + walletLockScreenSet: { type: String }, + walletLockPass: { type: String }, + walletLockSet: { type: String }, + myWalletLockScreenPass: { type: String }, + myWalletLockScreenSet: { type: String }, + walletHelperMessage: { type: String }, + bookQortalAddress: { type: String }, + bookBitcoinAddress: { type: String }, + bookLitecoinAddress: { type: String }, + bookDogecoinAddress: { type: String }, + bookDigibyteAddress: { type: String }, + bookRavencoinAddress: { type: String }, + bookPiratechainAddress: { type: String } + } + } + + static get styles() { + return [multiWalletStyles] + } + + static get observers() { + return ['_kmxKeyUp(amount)'] + } + + constructor() { + super() + this.lastBlock = { + height: 0 + } + this.balanceString = this.renderFetchText() + this.selectedTransaction = {} + this.isTextMenuOpen = false + this.loading = true + this.nodeConfig = {} + this.nodeDomain = '' + this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light' + this.qortBook = [] + this.btcBook = [] + this.ltcBook = [] + this.dogeBook = [] + this.dgbBook = [] + this.rvnBook = [] + this.arrrBook = [] + this.qortBookName = '' + this.btcBookName = '' + this.ltcBookName = '' + this.dogeBookName = '' + this.dgbBookName = '' + this.rvnBookName = '' + this.arrrBookName = '' + this.qortBookAddress = '' + this.btcBookAddress = '' + this.ltcBookAddress = '' + this.dogeBookAddress = '' + this.dgbBookAddress = '' + this.rvnBookAddress = '' + this.arrrBookAddress = '' + this.recipient = '' + this.btcRecipient = '' + this.ltcRecipient = '' + this.dogeRecipient = '' + this.dgbRecipient = '' + this.rvnRecipient = '' + this.arrrRecipient = '' + this.arrrMemo = '' + this.arrrWalletAddress = '' + this.unusedWalletAddress = '' + this.btcServer = '' + this.ltcServer = '' + this.dogeServer = '' + this.dgbServer = '' + this.rvnServer = '' + this.arrrServer = '' + this.errorMessage = '' + this.successMessage = '' + this.myElementId = '' + this.sendMoneyLoading = false + this.isValidAmount = false + this.btnDisable = false + this.qortWarning = false + this.balance = 0 + this.amount = 0 + this.btcAmount = 0 + this.ltcAmount = 0 + this.dogeAmount = 0 + this.dgbAmount = 0 + this.rvnAmount = 0 + this.arrrAmount = 0 + this.qortPaymentFee = 0.001 + this.btcFeePerByte = 100 + this.btcSatMinFee = 20 + this.btcSatMaxFee = 150 + this.ltcFeePerByte = 30 + this.ltcSatMinFee = 10 + this.ltcSatMaxFee = 100 + this.dogeFeePerByte = 1000 + this.dogeSatMinFee = 100 + this.dogeSatMaxFee = 10000 + this.dgbFeePerByte = 10 + this.dgbSatMinFee = 1 + this.dgbSatMaxFee = 100 + this.rvnFeePerByte = 1125 + this.rvnSatMinFee = 1000 + this.rvnSatMaxFee = 10000 + this.walletSalt = '' + this.walletStorageData = '' + this.walletLockScreenPass = '' + this.walletLockScreenSet = '' + this.walletLockPass = '' + this.walletLockSet = '' + this.myWalletLockScreenPass = '' + this.myWalletLockScreenSet = '' + this.walletHelperMessage = '' + this.bookQortalAddress = '' + this.bookBitcoinAddress = '' + this.bookLitecoinAddress = '' + this.bookDogecoinAddress = '' + this.bookDigibyteAddress = '' + this.bookRavencoinAddress = '' + this.bookPiratechainAddress = '' + this.wallets = new Map() + + let coinProp = { + balance: 0, + wallet: null, + transactions: [], + fetchingWalletBalance: false, + fetchingWalletTransactions: false + } + + coinsNames.forEach((c, i) => { + this.wallets.set(c, { ...coinProp }) + }, this) + + this.wallets.get('qort').wallet = window.parent.reduxStore.getState().app.selectedAddress + this.wallets.get('btc').wallet = window.parent.reduxStore.getState().app.selectedAddress.btcWallet + this.wallets.get('ltc').wallet = window.parent.reduxStore.getState().app.selectedAddress.ltcWallet + this.wallets.get('doge').wallet = window.parent.reduxStore.getState().app.selectedAddress.dogeWallet + this.wallets.get('dgb').wallet = window.parent.reduxStore.getState().app.selectedAddress.dgbWallet + this.wallets.get('rvn').wallet = window.parent.reduxStore.getState().app.selectedAddress.rvnWallet + this.wallets.get('arrr').wallet = window.parent.reduxStore.getState().app.selectedAddress.arrrWallet + + this._selectedWallet = 'qort' + + parentEpml.ready().then(() => { + parentEpml.subscribe('selected_address', async (selectedAddress) => { + selectedAddress = JSON.parse(selectedAddress) + if (!selectedAddress || Object.entries(selectedAddress).length === 0) return + + this.wallets.get('qort').wallet = selectedAddress + this.wallets.get('btc').wallet = window.parent.reduxStore.getState().app.selectedAddress.btcWallet + this.wallets.get('ltc').wallet = window.parent.reduxStore.getState().app.selectedAddress.ltcWallet + this.wallets.get('doge').wallet = window.parent.reduxStore.getState().app.selectedAddress.dogeWallet + this.wallets.get('dgb').wallet = window.parent.reduxStore.getState().app.selectedAddress.dgbWallet + this.wallets.get('rvn').wallet = window.parent.reduxStore.getState().app.selectedAddress.rvnWallet + this.wallets.get('arrr').wallet = window.parent.reduxStore.getState().app.selectedAddress.arrrWallet + }) + parentEpml.subscribe('coin_balances', async (payload) => { + const coinBalances = JSON.parse(payload) + if (coinBalances[this._selectedWallet]) { + const res = coinBalances[this._selectedWallet].fullValue + let value = Number(res).toFixed(8) + if (this._selectedWallet !== 'qort') { + value = (Number(res) / 1e8).toFixed(8) + } + this.wallets.get(this._selectedWallet).balance = value + this.balanceString = this.wallets.get(this._selectedWallet).balance + " " + this._selectedWallet.toLocaleUpperCase() + this.balance = this.wallets.get(this._selectedWallet).balance + } + }) + }) + + this.pingCoinBalancesController = this.pingCoinBalancesController.bind(this) + } + + refreshWallet() { + const coin = this._selectedWallet + switch (coin) { + case 'qort': + this.tabWalletQort() + break + case 'arrr': + this.tabWalletArrr() + break + case 'btc': + this.tabWalletBtc() + break; + case 'ltc': + this.tabWalletLtc() + break; + case 'doge': + this.tabWalletDoge() + break + case 'dgb': + this.tabWalletDgb() + break; + case 'rvn': + this.tabWalletRvn() + break + default: + break + } + } + + render() { + return html` +
    +
    + ${translate("walletpage.wchange22")} ${this.renderWalletLockButton()} +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + +
    +

    +
    + ${translate("walletpage.wchange2")} + +
    +
    + ${this.getSelectedWalletAddress()} + + +
    + + ${this.balanceString} + +
    + ${this.getSelectedWalletServer()} +
    +

    +
    + ${this.renderSendButton()} +
    +
    + ${this.renderAddressbookButton()} +
    +
    + +
    +
    + ${this.loading ? html` + + ` : ''} +
    +
    +
    + +
    +

    ${translate("walletpage.wchange5")}

    +
    +
    +
    + ${translate("walletpage.wchange6")} +
    +
    + ${this.selectedTransaction.type} + ${this.selectedTransaction.txnFlow === 'OUT' ? html`${translate("walletpage.wchange7")}` : html`${translate("walletpage.wchange8")}`} +
    + ${translate("walletpage.wchange9")} +
    +
    ${this.selectedTransaction.type === 'AT' ? html`${this.selectedTransaction.atAddress}` : html`${this.selectedTransaction.creatorAddress}`}
    + ${translate("walletpage.wchange10")} +
    +
    + ${this.selectedTransaction.type === 'DEPLOY_AT' ? html`${this.renderCAB()}` : html`${this.renderSQB()}`} +
    +
    + ${!this.selectedTransaction.amount ? '' : html` + ${translate("walletpage.wchange11")} +
    +
    ${this.selectedTransaction.amount} QORT
    + `} + ${translate("walletpage.wchange12")} +
    +
    ${this.selectedTransaction.fee}
    + ${translate("walletpage.wchange13")} +
    +
    ${this.selectedTransaction.blockHeight}
    + ${translate("walletpage.wchange14")} +
    +
    ${new Date(this.selectedTransaction.timestamp).toString()}
    + ${translate("walletpage.wchange15")} +
    +
    ${this.selectedTransaction.signature}
    +
    + + ${translate("general.close")} + +
    + +
    +

    ${translate("walletpage.wchange5")}

    +
    +
    +
    + ${translate("walletpage.wchange6")} +
    +
    + ${translate("walletpage.wchange40")} + ${this.selectedTransaction.btcTxnFlow === 'OUT' ? html`${translate("walletpage.wchange7")}` : html`${translate("walletpage.wchange8")}`} +
    + ${translate("walletpage.wchange9")} +
    +
    + ${this.selectedTransaction.btcSender} +
    + ${translate("walletpage.wchange10")} +
    +
    + ${this.selectedTransaction.btcReceiver} + this.sendToBtcAddress()} title="${translate("walletpage.wchange46")}"> + this.openAddBtcAddressDialog()} title="${translate("walletpage.wchange49")}"> +
    +
    + ${translate("walletpage.wchange12")} +
    +
    + ${(this.selectedTransaction.feeAmount / 1e8).toFixed(8)} BTC +
    + ${translate("walletpage.wchange37")} +
    +
    + ${(this.selectedTransaction.totalAmount / 1e8).toFixed(8)} BTC +
    + ${translate("walletpage.wchange14")} +
    +
    ${new Date(this.selectedTransaction.timestamp).toString()}
    + ${translate("walletpage.wchange16")} +
    +
    + ${this.selectedTransaction.txHash} +
    +
    + + ${translate("general.close")} + +
    + +
    +

    ${translate("walletpage.wchange5")}

    +
    +
    +
    + ${translate("walletpage.wchange6")}e +
    +
    + ${translate("walletpage.wchange40")} + ${this.selectedTransaction.ltcTxnFlow === 'OUT' ? html`${translate("walletpage.wchange7")}` : html`${translate("walletpage.wchange8")}`} +
    + ${translate("walletpage.wchange9")} +
    +
    + ${this.selectedTransaction.ltcSender} +
    + ${translate("walletpage.wchange10")} +
    +
    + ${this.selectedTransaction.ltcReceiver} + this.sendToLtcAddress()} title="${translate("walletpage.wchange46")}"> + this.openAddLtcAddressDialog()} title="${translate("walletpage.wchange49")}"> +
    +
    + ${translate("walletpage.wchange12")} +
    +
    + ${(this.selectedTransaction.feeAmount / 1e8).toFixed(8)} LTC +
    + ${translate("walletpage.wchange37")} +
    +
    + ${(this.selectedTransaction.totalAmount / 1e8).toFixed(8)} LTC +
    + ${translate("walletpage.wchange14")} +
    +
    ${new Date(this.selectedTransaction.timestamp).toString()}
    + ${translate("walletpage.wchange16")} +
    +
    + ${this.selectedTransaction.txHash} +
    +
    + + ${translate("general.close")} + +
    + +
    +

    ${translate("walletpage.wchange5")}

    +
    +
    +
    + ${translate("walletpage.wchange6")} +
    +
    + ${translate("walletpage.wchange40")} + ${this.selectedTransaction.dogeTxnFlow === 'OUT' ? html`${translate("walletpage.wchange7")}` : html`${translate("walletpage.wchange8")}`} +
    + ${translate("walletpage.wchange9")} +
    +
    + ${this.selectedTransaction.dogeSender} +
    +
    + ${translate("walletpage.wchange10")} +
    +
    + ${this.selectedTransaction.dogeReceiver} + this.sendToDogeAddress()} title="${translate("walletpage.wchange46")}"> + this.openAddDogeAddressDialog()} title="${translate("walletpage.wchange49")}"> +
    +
    + ${translate("walletpage.wchange12")} +
    +
    + ${(this.selectedTransaction.feeAmount / 1e8).toFixed(8)} DOGE +
    + ${translate("walletpage.wchange37")} +
    +
    + ${(this.selectedTransaction.totalAmount / 1e8).toFixed(8)} DOGE +
    + ${translate("walletpage.wchange14")} +
    +
    ${new Date(this.selectedTransaction.timestamp).toString()}
    + ${translate("walletpage.wchange16")} +
    +
    + ${this.selectedTransaction.txHash} +
    +
    + + ${translate("general.close")} + +
    + +
    +

    ${translate("walletpage.wchange5")}

    +
    +
    +
    + ${translate("walletpage.wchange6")} +
    +
    + ${translate("walletpage.wchange40")} + ${this.selectedTransaction.dgbTxnFlow === 'OUT' ? html`${translate("walletpage.wchange7")}` : html`${translate("walletpage.wchange8")}`} +
    + ${translate("walletpage.wchange9")} +
    +
    + ${this.selectedTransaction.dgbSender} +
    + ${translate("walletpage.wchange10")} +
    +
    + ${this.selectedTransaction.dgbReceiver} + this.sendToDgbAddress()} title="${translate("walletpage.wchange46")}"> + this.openAddDgbAddressDialog()} title="${translate("walletpage.wchange49")}"> +
    +
    + ${translate("walletpage.wchange12")} +
    +
    + ${(this.selectedTransaction.feeAmount / 1e8).toFixed(8)} DGB +
    + ${translate("walletpage.wchange37")} +
    +
    + ${(this.selectedTransaction.totalAmount / 1e8).toFixed(8)} DGB +
    + ${translate("walletpage.wchange14")} +
    +
    ${new Date(this.selectedTransaction.timestamp).toString()}
    + ${translate("walletpage.wchange16")} +
    +
    + ${this.selectedTransaction.txHash} +
    +
    + + ${translate("general.close")} + +
    + +
    +

    ${translate("walletpage.wchange5")}

    +
    +
    +
    + ${translate("walletpage.wchange6")} +
    +
    + ${translate("walletpage.wchange40")} + ${this.selectedTransaction.rvnTxnFlow === 'OUT' ? html`${translate("walletpage.wchange7")}` : html`${translate("walletpage.wchange8")}`} +
    + ${translate("walletpage.wchange9")} +
    +
    + ${this.selectedTransaction.rvnSender} +
    + ${translate("walletpage.wchange10")} +
    +
    + ${this.selectedTransaction.rvnReceiver} + this.sendToRvnAddress()} title="${translate("walletpage.wchange46")}"> + this.openAddRvnAddressDialog()} title="${translate("walletpage.wchange49")}"> +
    +
    + ${translate("walletpage.wchange12")} +
    +
    + ${(this.selectedTransaction.feeAmount / 1e8).toFixed(8)} RVN +
    + ${translate("walletpage.wchange37")} +
    +
    + ${(this.selectedTransaction.totalAmount / 1e8).toFixed(8)} RVN +
    + ${translate("walletpage.wchange14")} +
    +
    ${new Date(this.selectedTransaction.timestamp).toString()}
    + ${translate("walletpage.wchange16")} +
    +
    + ${this.selectedTransaction.txHash} +
    +
    + + ${translate("general.close")} + +
    + +
    +

    ${translate("walletpage.wchange5")}

    +
    +
    +
    + ${translate("walletpage.wchange6")} +
    +
    + ${translate("walletpage.wchange40")} + ${this.selectedTransaction.arrrTxnFlow === 'OUT' ? html`${translate("walletpage.wchange7")}` : html`${translate("walletpage.wchange8")}`} +
    + ${translate("walletpage.wchange9")} +
    +
    + ${this.selectedTransaction.arrrSender} +
    + ${translate("walletpage.wchange10")} +
    +
    + ${this.selectedTransaction.arrrReceiver} + this.sendToArrrAddress()} title="${translate("walletpage.wchange46")}"> + this.openAddArrrAddressDialog()} title="${translate("walletpage.wchange49")}"> +
    +
    + ${translate("walletpage.wchange12")} +
    +
    + ${(this.selectedTransaction.feeAmount / 1e8).toFixed(8)} ARRR +
    + ${translate("walletpage.wchange37")} +
    +
    + ${(this.selectedTransaction.totalAmount / 1e8).toFixed(8)} ARRR +
    + ${translate("walletpage.wchange14")} +
    +
    ${new Date(this.selectedTransaction.timestamp).toString()}
    + ${translate("walletpage.wchange16")} +
    +
    + ${this.selectedTransaction.txHash} +
    +
    + + ${translate("general.close")} + +
    + +
    +
    + +

    ${translate("walletpage.wchange17")} QORT

    +
    +
    +

    + ${translate("walletpage.wchange18")}:
    + ${this.getSelectedWalletAddress()} +

    +

    + ${translate("walletpage.wchange19")}:
    + ${this.balanceString}
    + + this.calculateQortAll()}> + + ${translate("walletpage.wchange45")} QORT + + +
      +

    +

    + + +

    +

    + + +

    +
    +

    ${translate("walletpage.wchange21")} ${this.qortPaymentFee} QORT

    +
    + ${this.renderClearSuccess()} + ${this.renderClearError()} + ${this.sendMoneyLoading ? html` + + ` : ''} +
    +
    + this.sendQort()}> + + ${translate("walletpage.wchange17")} QORT + +
    ${this.renderWarning()}
    +
    +
    +
    + + ${translate("general.close")} + +
    + +
    +
    + +

    ${translate("walletpage.wchange17")} BTC

    +
    +
    +

    + From address:
    + ${this.getSelectedWalletAddress()} +

    +

    + Available balance:
    + ${this.balanceString}
    + + this.calculateBtcAll()}> + + ${translate("walletpage.wchange45")} BTC + + +
      +

    +

    + + +

    +

    + + +

    +
    +

    ${translate("walletpage.wchange24")}: ${(this.btcFeePerByte / 1e8).toFixed(8)} BTC
    ${translate("walletpage.wchange25")}

    + + +
    + ${this.renderClearSuccess()} + ${this.renderClearError()} + ${this.sendMoneyLoading ? html` + + ` : ''} +
    +
    + this.sendBtc()}> + + ${translate("walletpage.wchange17")} BTC + +
    +
    +
    + + ${translate("general.close")} + +
    + +
    +
    + +

    ${translate("walletpage.wchange17")} LTC

    +
    +
    +

    + ${translate("walletpage.wchange18")}:
    + ${this.getSelectedWalletAddress()} +

    +

    + ${translate("walletpage.wchange19")}:
    + ${this.balanceString}
    + + this.calculateLtcAll()}> + + ${translate("walletpage.wchange45")} LTC + + +
      +

    +

    + + +

    +

    + + +

    +
    +

    ${translate("walletpage.wchange24")}: ${(this.ltcFeePerByte / 1e8).toFixed(8)} LTC
    ${translate("walletpage.wchange25")}

    + + +
    + ${this.renderClearSuccess()} + ${this.renderClearError()} + ${this.sendMoneyLoading ? html` + + ` : ''} +
    +
    + this.sendLtc()}> + + ${translate("walletpage.wchange17")} LTC + +
    +
    +
    + + ${translate("general.close")} + +
    + +
    +
    + +

    ${translate("walletpage.wchange17")} DOGE

    +
    +
    +

    + ${translate("walletpage.wchange18")}:
    + ${this.getSelectedWalletAddress()} +

    +

    + ${translate("walletpage.wchange19")}:
    + ${this.balanceString}
    + + this.calculateDogeAll()}> + + ${translate("walletpage.wchange45")} DOGE + + +
      +

    +

    + + +

    +

    + + +

    +
    +

    + ${translate("walletpage.wchange24")}: ${(this.dogeFeePerByte / 1e8).toFixed(8)} DOGE
    ${translate("walletpage.wchange25")} +

    + + +
    + ${this.renderClearSuccess()} + ${this.renderClearError()} + ${this.sendMoneyLoading ? html` + + ` : ''} +
    +
    + this.sendDoge()}> + + ${translate("walletpage.wchange17")} DOGE + +
    +
    +
    + + ${translate("general.close")} + +
    + +
    +
    + +

    ${translate("walletpage.wchange17")} DGB

    +
    +
    +

    + ${translate("walletpage.wchange18")}:
    + ${this.getSelectedWalletAddress()} +

    +

    + ${translate("walletpage.wchange19")}:
    + ${this.balanceString}
    + + this.calculateDgbAll()}> + + ${translate("walletpage.wchange45")} DGB + + +
      +

    +

    + + +

    +

    + + +

    +
    +

    + ${translate("walletpage.wchange24")}: ${(this.dgbFeePerByte / 1e8).toFixed(8)} DGB
    ${translate("walletpage.wchange25")} +

    + + +
    + ${this.renderClearSuccess()} + ${this.renderClearError()} + ${this.sendMoneyLoading ? html` + + ` : ''} +
    +
    + this.sendDgb()}> + + ${translate("walletpage.wchange17")} DGB + +
    +
    +
    + + ${translate("general.close")} + +
    + +
    +
    + +

    ${translate("walletpage.wchange17")} RVN

    +
    +
    +

    + ${translate("walletpage.wchange18")}:
    + ${this.getSelectedWalletAddress()} +

    +

    + ${translate("walletpage.wchange19")}:
    + ${this.balanceString}
    + + this.calculateRvnAll()}> + + ${translate("walletpage.wchange45")} RVN + + +
      +

    +

    + + +

    +

    + + +

    +
    +

    + ${translate("walletpage.wchange24")}: ${(this.rvnFeePerByte / 1e8).toFixed(8)} RVN
    ${translate("walletpage.wchange25")} +

    + + +
    + ${this.renderClearSuccess()} + ${this.renderClearError()} + ${this.sendMoneyLoading ? html` + + ` : ''} +
    +
    + this.sendRvn()}> + + ${translate("walletpage.wchange17")} RVN + +
    +
    +
    + + ${translate("general.close")} + +
    + +
    +
    + +

    ${translate("walletpage.wchange17")} ARRR

    +
    +
    +

    + ${translate("walletpage.wchange18")}:
    + ${this.getSelectedWalletAddress()} +

    +

    + ${translate("walletpage.wchange19")}:
    + ${this.balanceString}
    + + this.calculateArrrAll()}> + + ${translate("walletpage.wchange45")} ARRR + + +
      +

    +

    + + +

    +

    + + +

    +

    + + +

    +

    ${this.errorMessage}

    +

    ${this.successMessage}

    + ${this.sendMoneyLoading ? html` + + ` : ''} +
    +
    + this.sendArrr()}> + + ${translate("walletpage.wchange17")} ARRR + +
    +
    +
    + + ${translate("general.close")} + +
    + +
    + +

    Qortal ${translate("walletpage.wchange47")}

    +
    +
    ${this.renderExportAddressbookButton()}
    +
    ${this.renderImportAddressbookButton()}
    +

    +
    +
    + + + + { + render(html`${this.renderSendFromQortAddressbookButton(data.item)}`, root) + }}> + + { + render(html` + this.removeQortAddress(data.item.address)}> + delete +  ${translate("nodepage.nchange12")} + + `, root) + }}> + + + ${this.isEmptyArray(this.qortBook) ? html` + ${translate("walletpage.wchange48")} + `: ''} + + ${translate("general.close")} + + this.openAddToQortAddressbook()} + > + ${translate("rewardsharepage.rchange14")} + +
    + +
    + +

    Bitcoin ${translate("walletpage.wchange47")}

    +
    +
    ${this.renderExportAddressbookButton()}
    +
    ${this.renderImportAddressbookButton()}
    +

    +
    +
    + + + + { + render(html`${this.renderSendFromBtcAddressbookButton(data.item)}`, root) + }}> + + { + render(html` + this.removeBtcAddress(data.item.address)}> + delete +  ${translate("nodepage.nchange12")} + + `, root) + }}> + + + ${this.isEmptyArray(this.btcBook) ? html` + ${translate("walletpage.wchange48")} + `: ''} + + ${translate("general.close")} + + this.openAddToBtcAddressbook()} + > + ${translate("rewardsharepage.rchange14")} + +
    + +
    + +

    Litecoin ${translate("walletpage.wchange47")}

    +
    +
    ${this.renderExportAddressbookButton()}
    +
    ${this.renderImportAddressbookButton()}
    +

    +
    +
    + + + + { + render(html`${this.renderSendFromLtcAddressbookButton(data.item)}`, root) + }}> + + { + render(html` + this.removeLtcAddress(data.item.address)}> + delete +  ${translate("nodepage.nchange12")} + + `, root) + }}> + + + ${this.isEmptyArray(this.ltcBook) ? html` + ${translate("walletpage.wchange48")} + `: ''} + + ${translate("general.close")} + + this.openAddToLtcAddressbook()} + > + ${translate("rewardsharepage.rchange14")} + +
    + +
    + +

    Dogecoin ${translate("walletpage.wchange47")}

    +
    +
    ${this.renderExportAddressbookButton()}
    +
    ${this.renderImportAddressbookButton()}
    +

    +
    +
    + + + + { + render(html`${this.renderSendFromDogeAddressbookButton(data.item)}`, root) + }}> + + { + render(html` + this.removeDogeAddress(data.item.address)}> + delete +  ${translate("nodepage.nchange12")} + + `, root) + }}> + + + ${this.isEmptyArray(this.dogeBook) ? html` + ${translate("walletpage.wchange48")} + `: ''} + + ${translate("general.close")} + + this.openAddToDogeAddressbook()} + > + ${translate("rewardsharepage.rchange14")} + +
    + +
    + +

    Digibyte ${translate("walletpage.wchange47")}

    +
    +
    ${this.renderExportAddressbookButton()}
    +
    ${this.renderImportAddressbookButton()}
    +

    +
    +
    + + + + { + render(html`${this.renderSendFromDgbAddressbookButton(data.item)}`, root) + }}> + + { + render(html` + this.removeDgbAddress(data.item.address)}> + delete +  ${translate("nodepage.nchange12")} + + `, root) + }}> + + + ${this.isEmptyArray(this.dgbBook) ? html` + ${translate("walletpage.wchange48")} + `: ''} + + ${translate("general.close")} + + this.openAddToDgbAddressbook()} + > + ${translate("rewardsharepage.rchange14")} + +
    + +
    + +

    Ravencoin ${translate("walletpage.wchange47")}

    +
    +
    ${this.renderExportAddressbookButton()}
    +
    ${this.renderImportAddressbookButton()}
    +

    +
    +
    + + + + { + render(html`${this.renderSendFromRvnAddressbookButton(data.item)}`, root) + }}> + + { + render(html` + this.removeRvnAddress(data.item.address)}> + delete +  ${translate("nodepage.nchange12")} + + `, root) + }}> + + + ${this.isEmptyArray(this.rvnBook) ? html` + ${translate("walletpage.wchange48")} + `: ''} + + ${translate("general.close")} + + this.openAddToRvnAddressbook()} + > + ${translate("rewardsharepage.rchange14")} + +
    + +
    + +

    Pirate Chain ${translate("walletpage.wchange47")}

    +
    +
    ${this.renderExportAddressbookButton()}
    +
    ${this.renderImportAddressbookButton()}
    +

    +
    +
    + + + + { + render(html`${this.renderSendFromArrrAddressbookButton(data.item)}`, root) + }}> + + { + render(html` + this.removeArrrAddress(data.item.address)}> + delete +  ${translate("nodepage.nchange12")} + + `, root) + }}> + + + ${this.isEmptyArray(this.arrrBook) ? html` + ${translate("walletpage.wchange48")} + `: ''} + + ${translate("general.close")} + + this.openAddToArrrAddressbook()} + > + ${translate("rewardsharepage.rchange14")} + +
    + +
    + +

    Qortal ${translate("walletpage.wchange47")}

    +
    +

    ${translate("walletpage.wchange49")}

    +
    +
    +
    +
    +

    + + +

    +

    + + +

    +
    +
    +
    + + this.addToQortalAddressbook()}> + + ${translate("walletpage.wchange49")} + +
    +
    + + ${translate("general.close")} + +
    + +
    + +

    Bitcoin ${translate("walletpage.wchange47")}

    +
    +

    ${translate("walletpage.wchange49")}

    +
    +
    +
    +
    +

    + + +

    +

    + + +

    +
    +
    +
    + + this.addToBitcoinAddressbook()}> + + ${translate("walletpage.wchange49")} + +
    +
    + + ${translate("general.close")} + +
    + +
    + +

    Litecoin ${translate("walletpage.wchange47")}

    +
    +

    ${translate("walletpage.wchange49")}

    +
    +
    +
    +
    +

    + + +

    +

    + + +

    +
    +
    +
    + + this.addToLitecoinAddressbook()}> + + ${translate("walletpage.wchange49")} + +
    +
    + + ${translate("general.close")} + +
    + +
    + +

    Dogecoin ${translate("walletpage.wchange47")}

    +
    +

    ${translate("walletpage.wchange49")}

    +
    +
    +
    +
    +

    + + +

    +

    + + +

    +
    +
    +
    + + this.addToDogecoinAddressbook()}> + + ${translate("walletpage.wchange49")} + +
    +
    + + ${translate("general.close")} + +
    + +
    + +

    Digibyte ${translate("walletpage.wchange47")}

    +
    +

    ${translate("walletpage.wchange49")}

    +
    +
    +
    +
    +

    + + +

    +

    + + +

    +
    +
    +
    + + this.addToDigibyteAddressbook()}> + + ${translate("walletpage.wchange49")} + +
    +
    + + ${translate("general.close")} + +
    + +
    + +

    Ravencoin ${translate("walletpage.wchange47")}

    +
    +

    ${translate("walletpage.wchange49")}

    +
    +
    +
    +
    +

    + + +

    +

    + + +

    +
    +
    +
    + + this.addToRavencoinAddressbook()}> + + ${translate("walletpage.wchange49")} + +
    +
    + + ${translate("general.close")} + +
    + +
    + +

    Pirate Chain ${translate("walletpage.wchange47")}

    +
    +

    ${translate("walletpage.wchange49")}

    +
    +
    +
    +
    +

    + + +

    +

    + + +

    +
    +
    +
    + + this.addToPiratechainAddressbook()}> + + ${translate("walletpage.wchange49")} + +
    +
    + + ${translate("general.close")} + +
    + +
    + +

    Qortal ${translate("walletpage.wchange53")}

    +
    +
    +
    +
    +
    + +

    ${translate("walletpage.wchange56")}

    +
    ${translate("walletpage.wchange55")}
    +
    + + ${translate("general.close")} + +
    + +
    + +

    Bitcoin ${translate("walletpage.wchange53")}

    +
    +
    +
    +
    +
    + +

    ${translate("walletpage.wchange56")}

    +
    ${translate("walletpage.wchange55")}
    +
    + + ${translate("general.close")} + +
    + +
    + +

    Litecoin ${translate("walletpage.wchange53")}

    +
    +
    +
    +
    +
    + +

    ${translate("walletpage.wchange56")}

    +
    ${translate("walletpage.wchange55")}
    +
    + + ${translate("general.close")} + +
    + +
    + +

    Dogecoin ${translate("walletpage.wchange53")}

    +
    +
    +
    +
    +
    + +

    ${translate("walletpage.wchange56")}

    +
    ${translate("walletpage.wchange55")}
    +
    + + ${translate("general.close")} + +
    + +
    + +

    Digibyte ${translate("walletpage.wchange53")}

    +
    +
    +
    +
    +
    + +

    ${translate("walletpage.wchange56")}

    +
    ${translate("walletpage.wchange55")}
    +
    + + ${translate("general.close")} + +
    + +
    + +

    Litecoin ${translate("walletpage.wchange53")}

    +
    +
    +
    +
    +
    + +

    ${translate("walletpage.wchange56")}

    +
    ${translate("walletpage.wchange55")}
    +
    + + ${translate("general.close")} + +
    + +
    + +

    Pirate Chain ${translate("walletpage.wchange53")}

    +
    +
    +
    +
    +
    + +

    ${translate("walletpage.wchange56")}

    +
    ${translate("walletpage.wchange55")}
    +
    + + ${translate("general.close")} + +
    +
    + +
    +

    Qortal ${translate("tabmenu.tm5")} ${translate("login.lp1")}

    +
    +
    +
    +

    ${translate("login.lp2")}

    +

    ${translate("login.lp3")}

    +
    +
    + password + +
    +
    + password + +
    +
    + ${translate("login.lp4")} + ${translate("login.lp5")} +
    +
    + +
    +

    Qortal ${translate("tabmenu.tm5")} ${translate("login.lp1")}

    +
    +
    +
    +

    ${translate("login.lessthen8")}

    +
    +
    + ${translate("login.lp4")} + ${translate("login.lp5")} +
    +
    + +
    + ${translate("sidemenu.wallets")}
    + ${translate("login.lp9")} + ${translate("login.lp10")} +
    +
    + password + +
    + ${this.walletHelperMessage} +
    +
    +
    +
    + +
    +
    + ` + } + + firstUpdated() { + + this.changeTheme() + this.changeLanguage() + this.paymentFee() + this.getNodeConfig() + + this.bookQortalAddress = window.parent.reduxStore.getState().app.selectedAddress.address + this.bookBitcoinAddress = window.parent.reduxStore.getState().app.selectedAddress.btcWallet.address + this.bookLitecoinAddress = window.parent.reduxStore.getState().app.selectedAddress.ltcWallet.address + this.bookDogecoinAddress = window.parent.reduxStore.getState().app.selectedAddress.dogeWallet.address + this.bookDigibyteAddress = window.parent.reduxStore.getState().app.selectedAddress.dgbWallet.address + this.bookRavencoinAddress = window.parent.reduxStore.getState().app.selectedAddress.rvnWallet.address + this.bookPiratechainAddress = window.parent.reduxStore.getState().app.selectedAddress.arrrWallet.address + + this.walletHelperMessage = this.renderWalletHelperPass() + + this.walletSalt = '' + this.walletSalt = Base58.encode(window.parent.reduxStore.getState().app.wallet._addresses[0].keyPair.privateKey) + + this.walletStorageData = '' + this.walletStorageData = window.parent.reduxStore.getState().app.selectedAddress.address + + this.walletLockScreenPass = '' + this.walletLockScreenPass = 'walletLockScreenPass-' + this.walletStorageData + + this.walletLockScreenSet = '' + this.walletLockScreenSet = 'walletLockScreenSet-' + this.walletStorageData + + this.walletLockPass = '' + this.walletLockPass = encryptData(false, this.walletSalt) + + this.walletLockSet = '' + this.walletLockSet = encryptData(false, this.walletSalt) + + if (localStorage.getItem(this.walletLockScreenPass) === null && localStorage.getItem(this.walletLockScreenSet) === null) { + localStorage.setItem(this.walletLockScreenPass, this.walletLockPass) + localStorage.setItem(this.walletLockScreenSet, this.walletLockSet) + this.myWalletLockScreenPass = '' + this.myWalletLockScreenPass = decryptData(localStorage.getItem(this.walletLockScreenPass), this.walletSalt) + this.myWalletLockScreenSet = '' + this.myWalletLockScreenSet = decryptData(localStorage.getItem(this.walletLockScreenSet), this.walletSalt) + } else { + this.myWalletLockScreenPass = '' + this.myWalletLockScreenPass = decryptData(localStorage.getItem(this.walletLockScreenPass), this.walletSalt) + this.myWalletLockScreenSet = '' + this.myWalletLockScreenSet = decryptData(localStorage.getItem(this.walletLockScreenSet), this.walletSalt) + } + + if (this.myWalletLockScreenSet === true) { + this.shadowRoot.getElementById('walletLockScreenActive').open() + } + + this.qortAddressbook() + this.btcAddressbook() + this.ltcAddressbook() + this.dogeAddressbook() + this.dgbAddressbook() + this.rvnAddressbook() + this.arrrAddressbook() + + this.transactionsDOM = this.shadowRoot.getElementById('transactionsDOM') + + this.showWallet() + + window.addEventListener('storage', () => { + const checkLanguage = localStorage.getItem('qortalLanguage') + const checkTheme = localStorage.getItem('qortalTheme') + + use(checkLanguage) + + if (checkTheme === 'dark') { + this.theme = 'dark' + } else { + this.theme = 'light' + } + document.querySelector('html').setAttribute('theme', this.theme) + }) + + if (!isElectron()) { + } else { + window.addEventListener('contextmenu', (event) => { + event.preventDefault() + window.parent.electronAPI.showMyMenu() + }) + } + + this.clearConsole() + + setInterval(() => { + this.clearConsole() + this.getNodeConfig() + }, 60000) + + setInterval(() => { + this.paymentFee() + }, 600000) + } + + async paymentFee() { + const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] + const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port + const url = `${nodeUrl}/transactions/unitfee?txType=PAYMENT` + + await fetch(url).then((response) => { + if (response.ok) { + return response.json() + } + return Promise.reject(response) + }).then((json) => { + this.qortPaymentFee = (Number(json) / 1e8).toFixed(8) + }) + } + + clearConsole() { + if (!isElectron()) { + } else { + console.clear() + window.parent.electronAPI.clearCache() + } + } + + pingCoinBalancesController() { + if (!this._selectedWallet) return + const customEvent = new CustomEvent('ping-coin-controller-with-coin', { + detail: this._selectedWallet + }) + window.parent.dispatchEvent(customEvent) + } + + connectedCallback() { + super.connectedCallback() + this.intervalID = setInterval(this.pingCoinBalancesController, 30000) + } + + disconnectedCallback() { + super.disconnectedCallback() + if (this.intervalID) { + clearInterval(this.intervalID) + } + } + + renderWalletLockButton() { + if (this.myWalletLockScreenPass === false && this.myWalletLockScreenSet === false) { + return html` +
    + this.openWalletSetScreenLockPass()} title="${translate("login.lp11")}"> +
    + ` + } else if (this.myWalletLockScreenSet === false) { + return html` +
    + this.setWalletLockQortal()} title="${translate("login.lp11")}"> +
    + ` + } else if (this.myWalletLockScreenSet === true) { + return html` +
    + +
    + ` + } + } + + openWalletSetScreenLockPass() { + this.shadowRoot.getElementById('walletLockPassword').value = '' + this.shadowRoot.getElementById('walletLockPasswordConfirm').value = '' + this.shadowRoot.getElementById('setWalletLockScreenPass').open() + } + + closewWalletSetScreenLockPass() { + this.shadowRoot.getElementById('setWalletLockScreenPass').close() + } + + walletCheckPass() { + const walletPassword = this.shadowRoot.getElementById('walletLockPassword').value + const walletRePassword = this.shadowRoot.getElementById('walletLockPasswordConfirm').value + + if (walletPassword === '') { + let snackbar1string = get("login.pleaseenter") + parentEpml.request('showSnackBar', `${snackbar1string}`) + return + } + + if (walletPassword != walletRePassword) { + let snackbar2string = get("login.notmatch") + parentEpml.request('showSnackBar', `${snackbar2string}`) + return + } + + if (walletPassword.length < 8) { + let snackbar3string = get("login.lessthen8") + parentEpml.request('showSnackBar', `${snackbar3string}`) + this.walletExtraConfirm() + } + + if (walletPassword.length >= 8) { + this.setWalletNewScreenPass() + let snackbar4string = get("login.lp6") + parentEpml.request('showSnackBar', `${snackbar4string}`) + } + } + + walletExtraConfirm() { + this.shadowRoot.getElementById('setWalletLockScreenPass').close() + this.shadowRoot.getElementById('walletExtraConfirmPass').open() + } + + closWalletExtraConfirmPass() { + this.shadowRoot.getElementById('walletExtraConfirmPass').close() + this.shadowRoot.getElementById('walletLockPassword').value = '' + this.shadowRoot.getElementById('walletLockPasswordConfirm').value = '' + } + + setWalletNewScreenPass() { + const walletRawPassword = this.shadowRoot.getElementById('walletLockPassword').value + const walletCryptPassword = encryptData(walletRawPassword, this.walletSalt) + localStorage.setItem(this.walletLockScreenPass, walletCryptPassword) + this.myWalletLockScreenPass = '' + this.myWalletLockScreenPass = decryptData(localStorage.getItem(this.walletLockScreenPass), this.walletSalt) + this.shadowRoot.getElementById('setWalletLockScreenPass').close() + this.shadowRoot.getElementById('walletExtraConfirmPass').close() + this.shadowRoot.getElementById('walletLockPassword').value = '' + this.shadowRoot.getElementById('walletLockPasswordConfirm').value = '' + } + + setWalletLockQortal() { + this.walletHelperMessage = this.renderWalletHelperPass() + this.walletLockSet = '' + this.walletLockSet = encryptData(true, this.walletSalt) + localStorage.setItem(this.walletLockScreenSet, this.walletLockSet) + this.myWalletLockScreenSet = '' + this.myWalletLockScreenSet = decryptData(localStorage.getItem(this.walletLockScreenSet), this.walletSalt) + this.shadowRoot.getElementById('walletLockScreenActive').open() + } + + walletPassKeyListener(e) { + if (e.key === 'Enter') { + this.closeWalletLockScreenActive() + } + } + + async closeWalletLockScreenActive() { + const myWalletPass = decryptData(localStorage.getItem(this.walletLockScreenPass), this.walletSalt) + const walletCheckPass = this.shadowRoot.getElementById('walletUnlockPassword').value + const errDelay = ms => new Promise(res => setTimeout(res, ms)) + + if (walletCheckPass === myWalletPass) { + this.walletLockSet = '' + this.walletLockSet = encryptData(false, this.walletSalt) + localStorage.setItem(this.walletLockScreenSet, this.walletLockSet) + this.myWalletLockScreenSet = '' + this.myWalletLockScreenSet = decryptData(localStorage.getItem(this.walletLockScreenSet), this.walletSalt) + this.shadowRoot.getElementById('walletLockScreenActive').close() + this.shadowRoot.getElementById('walletUnlockPassword').value = '' + this.walletHelperMessage = this.renderWalletHelperPass() + } else { + this.shadowRoot.getElementById('walletUnlockPassword').value = '' + this.walletHelperMessage = this.renderWalletHelperErr() + await errDelay(3000) + this.walletHelperMessage = this.renderWalletHelperPass() + } + } + + renderWalletHelperPass() { + return html`${translate("login.pleaseenter")}` + } + + renderWalletHelperErr() { + return html`${translate("login.lp8")}` + } + + renderWarning() { + return html`${translate("tradepage.tchange48")} QORT` + } + + renderClearSuccess() { + let strSuccessValue = this.successMessage + if (strSuccessValue === "") { + return html`` + } else { + return html` +
    + ${this.successMessage} + + + +
    +
    +

    ${translate("walletpage.wchange43")}

    +
    + ` + } + } + + renderClearError() { + let strErrorValue = this.errorMessage + if (strErrorValue === "") { + return html`` + } else { + return html` +
    + ${this.errorMessage} + + + +
    +
    +

    ${translate("walletpage.wchange44")}

    +
    + ` + } + } + + tabWalletQort() { + this._selectedWallet = 'qort' + this.showWallet() + } + + tabWalletBtc() { + this._selectedWallet = 'btc' + this.showWallet() + } + + tabWalletLtc() { + this._selectedWallet = 'ltc' + this.showWallet() + } + + tabWalletDoge() { + this._selectedWallet = 'doge' + this.showWallet() + } + + tabWalletDgb() { + this._selectedWallet = 'dgb' + this.showWallet() + } + + tabWalletRvn() { + this._selectedWallet = 'rvn' + this.showWallet() + } + + tabWalletArrr() { + this._selectedWallet = 'arrr' + this.showWallet() + } + + qortAddressbook() { + const storedQortalAddressBook = 'addressbookQort-' + this.bookQortalAddress + if (localStorage.getItem(storedQortalAddressBook) === null) { + localStorage.setItem(storedQortalAddressBook, "") + } else { + this.qortBook = JSON.parse(localStorage.getItem(storedQortalAddressBook) || "[]") + } + } + + btcAddressbook() { + const storedBitcoinAddressBook = 'addressbookBtc-' + this.bookBitcoinAddress + if (localStorage.getItem(storedBitcoinAddressBook) === null) { + localStorage.setItem(storedBitcoinAddressBook, "") + } else { + this.btcBook = JSON.parse(localStorage.getItem(storedBitcoinAddressBook) || "[]") + } + } + + ltcAddressbook() { + const storedLitecoinAddressBook = 'addressbookLtc-' + this.bookLitecoinAddress + if (localStorage.getItem(storedLitecoinAddressBook) === null) { + localStorage.setItem(storedLitecoinAddressBook, "") + } else { + this.ltcBook = JSON.parse(localStorage.getItem(storedLitecoinAddressBook) || "[]") + } + } + + dogeAddressbook() { + const storedDogecoinAddressBook = 'addressbookDoge-' + this.bookDogecoinAddress + if (localStorage.getItem(storedDogecoinAddressBook) === null) { + localStorage.setItem(storedDogecoinAddressBook, "") + } else { + this.dogeBook = JSON.parse(localStorage.getItem(storedDogecoinAddressBook) || "[]") + } + } + + dgbAddressbook() { + const storedDigibyteAddressBook = 'addressbookDgb-' + this.bookDigibyteAddress + if (localStorage.getItem(storedDigibyteAddressBook) === null) { + localStorage.setItem(storedDigibyteAddressBook, "") + } else { + this.dgbBook = JSON.parse(localStorage.getItem(storedDigibyteAddressBook) || "[]") + } + } + + rvnAddressbook() { + const storedRavencoinAddressBook = 'addressbookRvn-' + this.bookRavencoinAddress + if (localStorage.getItem(storedRavencoinAddressBook) === null) { + localStorage.setItem(storedRavencoinAddressBook, "") + } else { + this.rvnBook = JSON.parse(localStorage.getItem(storedRavencoinAddressBook) || "[]") + } + } + + arrrAddressbook() { + const storedPiratechainAddressBook = 'addressbookArrr-' + this.bookPiratechainAddress + if (localStorage.getItem(storedPiratechainAddressBook) === null) { + localStorage.setItem(storedPiratechainAddressBook, "") + } else { + this.arrrBook = JSON.parse(localStorage.getItem(storedPiratechainAddressBook) || "[]") + } + } + + openQortAddressbook() { + this.shadowRoot.querySelector("#qortBookDialog").show() + } + + openBtcAddressbook() { + this.shadowRoot.querySelector("#btcBookDialog").show() + } + + openLtcAddressbook() { + this.shadowRoot.querySelector("#ltcBookDialog").show() + } + + openDogeAddressbook() { + this.shadowRoot.querySelector("#dogeBookDialog").show() + } + + openDgbAddressbook() { + this.shadowRoot.querySelector("#dgbBookDialog").show() + } + + openRvnAddressbook() { + this.shadowRoot.querySelector("#rvnBookDialog").show() + } + + openArrrAddressbook() { + this.shadowRoot.querySelector("#arrrBookDialog").show() + } + + openAddQortAddressDialog() { + this.qortBookAddress = this.selectedTransaction.recipient + this.openAddToQortAddressbook() + this.shadowRoot.querySelector('#showTransactionDetailsDialog').close() + } + + openAddBtcAddressDialog() { + this.btcBookAddress = this.selectedTransaction.btcReceiver + this.openAddToBtcAddressbook() + this.shadowRoot.querySelector('#showBtcTransactionDetailsDialog').close() + } + + openAddLtcAddressDialog() { + this.ltcBookAddress = this.selectedTransaction.ltcReceiver + this.openAddToLtcAddressbook() + this.shadowRoot.querySelector('#showLtcTransactionDetailsDialog').close() + } + + openAddDogeAddressDialog() { + this.dogeBookAddress = this.selectedTransaction.dogeReceiver + this.openAddToDogeAddressbook() + this.shadowRoot.querySelector('#showDogeTransactionDetailsDialog').close() + } + + openAddDgbAddressDialog() { + this.dgbBookAddress = this.selectedTransaction.dgbReceiver + this.openAddToDgbAddressbook() + this.shadowRoot.querySelector('#showDgbTransactionDetailsDialog').close() + } + + openAddRvnAddressDialog() { + this.rvnBookAddress = this.selectedTransaction.rvnReceiver + this.openAddToRvnAddressbook() + this.shadowRoot.querySelector('#showRvnTransactionDetailsDialog').close() + } + + openAddArrrAddressDialog() { + this.arrrBookAddress = this.selectedTransaction.arrrReceiver + this.openAddToArrrAddressbook() + this.shadowRoot.querySelector('#showArrrTransactionDetailsDialog').close() + } + + openAddToQortAddressbook() { + this.shadowRoot.querySelector("#addQortAddressDialog").show() + } + + openAddToBtcAddressbook() { + this.shadowRoot.querySelector("#addBtcAddressDialog").show() + } + + openAddToLtcAddressbook() { + this.shadowRoot.querySelector("#addLtcAddressDialog").show() + } + + openAddToDogeAddressbook() { + this.shadowRoot.querySelector("#addDogeAddressDialog").show() + } + + openAddToDgbAddressbook() { + this.shadowRoot.querySelector("#addDgbAddressDialog").show() + } + + openAddToRvnAddressbook() { + this.shadowRoot.querySelector("#addRvnAddressDialog").show() + } + + openAddToArrrAddressbook() { + this.shadowRoot.querySelector("#addArrrAddressDialog").show() + } + + openImportQortAddressbook() { + this.shadowRoot.querySelector("#importQortAddressbookDialog").show() + } + + openImportBtcAddressbook() { + this.shadowRoot.querySelector("#importBtcAddressbookDialog").show() + } + + openImportLtcAddressbook() { + this.shadowRoot.querySelector("#importLtcAddressbookDialog").show() + } + + openImportDogeAddressbook() { + this.shadowRoot.querySelector("#importDogeAddressbookDialog").show() + } + + openImportDgbAddressbook() { + this.shadowRoot.querySelector("#importDgbAddressbookDialog").show() + } + + openImportRvnAddressbook() { + this.shadowRoot.querySelector("#importRvnAddressbookDialog").show() + } + + openImportArrrAddressbook() { + this.shadowRoot.querySelector("#importArrrAddressbookDialog").show() + } + + closeQortAddressDialog() { + this.shadowRoot.querySelector('#addQortAddressDialog').close() + this.shadowRoot.getElementById('qortNameInput').value = '' + this.shadowRoot.getElementById('qortAddressInput').value = '' + this.qortBookName = '' + this.qortBookAddress = '' + } + + closeBtcAddressDialog() { + this.shadowRoot.querySelector('#addBtcAddressDialog').close() + this.shadowRoot.getElementById('btcNameInput').value = '' + this.shadowRoot.getElementById('btcAddressInput').value = '' + this.btcBookName = '' + this.btcBookAddress = '' + } + + closeLtcAddressDialog() { + this.shadowRoot.querySelector('#addLtcAddressDialog').close() + this.shadowRoot.getElementById('ltcNameInput').value = '' + this.shadowRoot.getElementById('ltcAddressInput').value = '' + this.ltcBookName = '' + this.ltcBookAddress = '' + } + + closeDogeAddressDialog() { + this.shadowRoot.querySelector('#addDogeAddressDialog').close() + this.shadowRoot.getElementById('dogeNameInput').value = '' + this.shadowRoot.getElementById('dogeAddressInput').value = '' + this.dogeBookName = '' + this.dogeBookAddress = '' + } + + closeDgbAddressDialog() { + this.shadowRoot.querySelector('#addDgbAddressDialog').close() + this.shadowRoot.getElementById('dgbNameInput').value = '' + this.shadowRoot.getElementById('dgbAddressInput').value = '' + this.dgbBookName = '' + this.dgbBookAddress = '' + } + + closeRvnAddressDialog() { + this.shadowRoot.querySelector('#addRvnAddressDialog').close() + this.shadowRoot.getElementById('rvnNameInput').value = '' + this.shadowRoot.getElementById('rvnAddressInput').value = '' + this.rvnBookName = '' + this.rvnBookAddress = '' + } + + closeArrrAddressDialog() { + this.shadowRoot.querySelector('#addArrrAddressDialog').close() + this.shadowRoot.getElementById('arrrNameInput').value = '' + this.shadowRoot.getElementById('arrrAddressInput').value = '' + this.arrrBookName = '' + this.arrrBookAddress = '' + } + + closeImportQortAddressbookDialog() { + this.shadowRoot.querySelector("#importQortAddressbookDialog").close() + } + + closeImportBtcAddressbookDialog() { + this.shadowRoot.querySelector("#importBtcAddressbookDialog").close() + } + + closeImportLtcAddressbookDialog() { + this.shadowRoot.querySelector("#importLtcAddressbookDialog").close() + } + + closeImportDogeAddressbookDialog() { + this.shadowRoot.querySelector("#importDogeAddressbookDialog").close() + } + + closeImportDgbAddressbookDialog() { + this.shadowRoot.querySelector("#importDgbAddressbookDialog").close() + } + + closeImportRvnAddressbookDialog() { + this.shadowRoot.querySelector("#importRvnAddressbookDialog").close() + } + + closeImportArrrAddressbookDialog() { + this.shadowRoot.querySelector("#importArrrAddressbookDialog").close() + } + + addToQortalAddressbook() { + const myQortalAddressBook = 'addressbookQort-' + this.bookQortalAddress + + let name = this.shadowRoot.getElementById('qortNameInput').value + let address = this.shadowRoot.getElementById('qortAddressInput').value + + var oldQortalBook = JSON.parse(localStorage.getItem(myQortalAddressBook) || "[]") + + if (name.length === 0) { + let qortbookstring1 = get("walletpage.wchange50") + parentEpml.request('showSnackBar', `${qortbookstring1}`) + return false + } + + if (address.length === 0) { + let qortbookstring2 = get("walletpage.wchange51") + parentEpml.request('showSnackBar', `${qortbookstring2}`) + return false + } + + const newQortalBookItem = { + name: name, + address: address + } + + oldQortalBook.push(newQortalBookItem) + + localStorage.setItem(myQortalAddressBook, JSON.stringify(oldQortalBook)) + + let qortbookstring2 = get("walletpage.wchange52") + parentEpml.request('showSnackBar', `${qortbookstring2}`) + + this.closeQortAddressDialog() + this.qortBook = JSON.parse(localStorage.getItem(myQortalAddressBook) || "[]") + } + + addToBitcoinAddressbook() { + const myBitcoinAddressBook = 'addressbookBtc-' + this.bookBitcoinAddress - let name = this.shadowRoot.getElementById('btcNameInput').value - let address = this.shadowRoot.getElementById('btcAddressInput').value + let name = this.shadowRoot.getElementById('btcNameInput').value + let address = this.shadowRoot.getElementById('btcAddressInput').value - var oldBitcoinBook = JSON.parse(localStorage.getItem(myBitcoinAddressBook) || "[]") + var oldBitcoinBook = JSON.parse(localStorage.getItem(myBitcoinAddressBook) || "[]") - if (name.length === 0) { - let btcbookstring1 = get("walletpage.wchange50") - parentEpml.request('showSnackBar', `${btcbookstring1}`) - return false - } + if (name.length === 0) { + let btcbookstring1 = get("walletpage.wchange50") + parentEpml.request('showSnackBar', `${btcbookstring1}`) + return false + } - if (address.length === 0) { - let btcbookstring2 = get("walletpage.wchange51") - parentEpml.request('showSnackBar', `${btcbookstring2}`) - return false - } + if (address.length === 0) { + let btcbookstring2 = get("walletpage.wchange51") + parentEpml.request('showSnackBar', `${btcbookstring2}`) + return false + } - const newBitcoinBookItem = { - name: name, - address: address - } + const newBitcoinBookItem = { + name: name, + address: address + } - oldBitcoinBook.push(newBitcoinBookItem) + oldBitcoinBook.push(newBitcoinBookItem) - localStorage.setItem(myBitcoinAddressBook, JSON.stringify(oldBitcoinBook)) + localStorage.setItem(myBitcoinAddressBook, JSON.stringify(oldBitcoinBook)) - let btcbookstring3 = get("walletpage.wchange52") - parentEpml.request('showSnackBar', `${btcbookstring3}`) + let btcbookstring3 = get("walletpage.wchange52") + parentEpml.request('showSnackBar', `${btcbookstring3}`) - this.closeBtcAddressDialog() - this.btcBook = JSON.parse(localStorage.getItem(myBitcoinAddressBook) || "[]") - } + this.closeBtcAddressDialog() + this.btcBook = JSON.parse(localStorage.getItem(myBitcoinAddressBook) || "[]") + } - addToLitecoinAddressbook() { - const myLitecoinAddressBook = 'addressbookLtc-' + this.bookLitecoinAddress + addToLitecoinAddressbook() { + const myLitecoinAddressBook = 'addressbookLtc-' + this.bookLitecoinAddress - let name = this.shadowRoot.getElementById('ltcNameInput').value - let address = this.shadowRoot.getElementById('ltcAddressInput').value + let name = this.shadowRoot.getElementById('ltcNameInput').value + let address = this.shadowRoot.getElementById('ltcAddressInput').value - var oldLitecoinBook = JSON.parse(localStorage.getItem(myLitecoinAddressBook) || "[]") + var oldLitecoinBook = JSON.parse(localStorage.getItem(myLitecoinAddressBook) || "[]") - if (name.length === 0) { - let ltcbookstring1 = get("walletpage.wchange50") - parentEpml.request('showSnackBar', `${ltcbookstring1}`) - return false - } + if (name.length === 0) { + let ltcbookstring1 = get("walletpage.wchange50") + parentEpml.request('showSnackBar', `${ltcbookstring1}`) + return false + } - if (address.length === 0) { - let ltcbookstring2 = get("walletpage.wchange51") - parentEpml.request('showSnackBar', `${ltcbookstring2}`) - return false - } + if (address.length === 0) { + let ltcbookstring2 = get("walletpage.wchange51") + parentEpml.request('showSnackBar', `${ltcbookstring2}`) + return false + } - const newLitecoinBookItem = { - name: name, - address: address - } + const newLitecoinBookItem = { + name: name, + address: address + } - oldLitecoinBook.push(newLitecoinBookItem) + oldLitecoinBook.push(newLitecoinBookItem) - localStorage.setItem(myLitecoinAddressBook, JSON.stringify(oldLitecoinBook)) + localStorage.setItem(myLitecoinAddressBook, JSON.stringify(oldLitecoinBook)) - let ltcbookstring3 = get("walletpage.wchange52") - parentEpml.request('showSnackBar', `${ltcbookstring3}`) + let ltcbookstring3 = get("walletpage.wchange52") + parentEpml.request('showSnackBar', `${ltcbookstring3}`) - this.closeLtcAddressDialog() - this.ltcBook = JSON.parse(localStorage.getItem(myLitecoinAddressBook) || "[]") - } + this.closeLtcAddressDialog() + this.ltcBook = JSON.parse(localStorage.getItem(myLitecoinAddressBook) || "[]") + } - addToDogecoinAddressbook() { - const myDogecoinAddressBook = 'addressbookDoge-' + this.bookDogecoinAddress + addToDogecoinAddressbook() { + const myDogecoinAddressBook = 'addressbookDoge-' + this.bookDogecoinAddress - let name = this.shadowRoot.getElementById('dogeNameInput').value - let address = this.shadowRoot.getElementById('dogeAddressInput').value + let name = this.shadowRoot.getElementById('dogeNameInput').value + let address = this.shadowRoot.getElementById('dogeAddressInput').value - var oldDogecoinBook = JSON.parse(localStorage.getItem(myDogecoinAddressBook) || "[]") + var oldDogecoinBook = JSON.parse(localStorage.getItem(myDogecoinAddressBook) || "[]") - if (name.length === 0) { - let dogebookstring1 = get("walletpage.wchange50") - parentEpml.request('showSnackBar', `${dogebookstring1}`) - return false - } + if (name.length === 0) { + let dogebookstring1 = get("walletpage.wchange50") + parentEpml.request('showSnackBar', `${dogebookstring1}`) + return false + } - if (address.length === 0) { - let dogebookstring2 = get("walletpage.wchange51") - parentEpml.request('showSnackBar', `${dogebookstring2}`) - return false - } + if (address.length === 0) { + let dogebookstring2 = get("walletpage.wchange51") + parentEpml.request('showSnackBar', `${dogebookstring2}`) + return false + } - const newDogecoinBookItem = { - name: name, - address: address - } + const newDogecoinBookItem = { + name: name, + address: address + } - oldDogecoinBook.push(newDogecoinBookItem) + oldDogecoinBook.push(newDogecoinBookItem) - localStorage.setItem(myDogecoinAddressBook, JSON.stringify(oldDogecoinBook)) + localStorage.setItem(myDogecoinAddressBook, JSON.stringify(oldDogecoinBook)) - let dogebookstring3 = get("walletpage.wchange52") - parentEpml.request('showSnackBar', `${dogebookstring3}`) + let dogebookstring3 = get("walletpage.wchange52") + parentEpml.request('showSnackBar', `${dogebookstring3}`) - this.closeDogeAddressDialog() - this.dogeBook = JSON.parse(localStorage.getItem(myDogecoinAddressBook) || "[]") - } + this.closeDogeAddressDialog() + this.dogeBook = JSON.parse(localStorage.getItem(myDogecoinAddressBook) || "[]") + } - addToDigibyteAddressbook() { - const myDigibyteAddressBook = 'addressbookDgb-' + this.bookDigibyteAddress + addToDigibyteAddressbook() { + const myDigibyteAddressBook = 'addressbookDgb-' + this.bookDigibyteAddress - let name = this.shadowRoot.getElementById('dgbNameInput').value - let address = this.shadowRoot.getElementById('dgbAddressInput').value + let name = this.shadowRoot.getElementById('dgbNameInput').value + let address = this.shadowRoot.getElementById('dgbAddressInput').value - var oldDigibyteBook = JSON.parse(localStorage.getItem(myDigibyteAddressBook) || "[]") + var oldDigibyteBook = JSON.parse(localStorage.getItem(myDigibyteAddressBook) || "[]") - if (name.length === 0) { - let dgbbookstring1 = get("walletpage.wchange50") - parentEpml.request('showSnackBar', `${dgbbookstring1}`) - return false - } + if (name.length === 0) { + let dgbbookstring1 = get("walletpage.wchange50") + parentEpml.request('showSnackBar', `${dgbbookstring1}`) + return false + } - if (address.length === 0) { - let dgbbookstring2 = get("walletpage.wchange51") - parentEpml.request('showSnackBar', `${dgbbookstring2}`) - return false - } + if (address.length === 0) { + let dgbbookstring2 = get("walletpage.wchange51") + parentEpml.request('showSnackBar', `${dgbbookstring2}`) + return false + } - const newDigibyteBookItem = { - name: name, - address: address - } + const newDigibyteBookItem = { + name: name, + address: address + } - oldDigibyteBook.push(newDigibyteBookItem) + oldDigibyteBook.push(newDigibyteBookItem) - localStorage.setItem(myDigibyteAddressBook, JSON.stringify(oldDigibyteBook)) + localStorage.setItem(myDigibyteAddressBook, JSON.stringify(oldDigibyteBook)) - let dgbbookstring3 = get("walletpage.wchange52") - parentEpml.request('showSnackBar', `${dgbbookstring3}`) + let dgbbookstring3 = get("walletpage.wchange52") + parentEpml.request('showSnackBar', `${dgbbookstring3}`) - this.closeDgbAddressDialog() - this.dgbBook = JSON.parse(localStorage.getItem(myDigibyteAddressBook) || "[]") - } + this.closeDgbAddressDialog() + this.dgbBook = JSON.parse(localStorage.getItem(myDigibyteAddressBook) || "[]") + } - addToRavencoinAddressbook() { - const myRavencoinAddressBook = 'addressbookRvn-' + this.bookRavencoinAddress + addToRavencoinAddressbook() { + const myRavencoinAddressBook = 'addressbookRvn-' + this.bookRavencoinAddress - let name = this.shadowRoot.getElementById('rvnNameInput').value - let address = this.shadowRoot.getElementById('rvnAddressInput').value + let name = this.shadowRoot.getElementById('rvnNameInput').value + let address = this.shadowRoot.getElementById('rvnAddressInput').value - var oldRavencoinBook = JSON.parse(localStorage.getItem(myRavencoinAddressBook) || "[]") + var oldRavencoinBook = JSON.parse(localStorage.getItem(myRavencoinAddressBook) || "[]") - if (name.length === 0) { - let rvnbookstring1 = get("walletpage.wchange50") - parentEpml.request('showSnackBar', `${rvnbookstring1}`) - return false - } + if (name.length === 0) { + let rvnbookstring1 = get("walletpage.wchange50") + parentEpml.request('showSnackBar', `${rvnbookstring1}`) + return false + } - if (address.length === 0) { - let rvnbookstring2 = get("walletpage.wchange51") - parentEpml.request('showSnackBar', `${rvnbookstring2}`) - return false - } + if (address.length === 0) { + let rvnbookstring2 = get("walletpage.wchange51") + parentEpml.request('showSnackBar', `${rvnbookstring2}`) + return false + } - const newRavencoinBookItem = { - name: name, - address: address - } + const newRavencoinBookItem = { + name: name, + address: address + } - oldRavencoinBook.push(newRavencoinBookItem) + oldRavencoinBook.push(newRavencoinBookItem) - localStorage.setItem(myRavencoinAddressBook, JSON.stringify(oldRavencoinBook)) + localStorage.setItem(myRavencoinAddressBook, JSON.stringify(oldRavencoinBook)) - let rvnbookstring3 = get("walletpage.wchange52") - parentEpml.request('showSnackBar', `${rvnbookstring3}`) + let rvnbookstring3 = get("walletpage.wchange52") + parentEpml.request('showSnackBar', `${rvnbookstring3}`) - this.closeRvnAddressDialog() - this.rvnBook = JSON.parse(localStorage.getItem(myRavencoinAddressBook) || "[]") - } + this.closeRvnAddressDialog() + this.rvnBook = JSON.parse(localStorage.getItem(myRavencoinAddressBook) || "[]") + } - addToPiratechainAddressbook() { - const myPiratechainAddressBook = 'addressbookArrr-' + this.bookPiratechainAddress + addToPiratechainAddressbook() { + const myPiratechainAddressBook = 'addressbookArrr-' + this.bookPiratechainAddress - let name = this.shadowRoot.getElementById('arrrNameInput').value - let address = this.shadowRoot.getElementById('arrrAddressInput').value + let name = this.shadowRoot.getElementById('arrrNameInput').value + let address = this.shadowRoot.getElementById('arrrAddressInput').value - var oldPiratechainBook = JSON.parse(localStorage.getItem(myPiratechainAddressBook) || "[]") + var oldPiratechainBook = JSON.parse(localStorage.getItem(myPiratechainAddressBook) || "[]") - if (name.length === 0) { - let arrrbookstring1 = get("walletpage.wchange50") - parentEpml.request('showSnackBar', `${arrrbookstring1}`) - return false - } + if (name.length === 0) { + let arrrbookstring1 = get("walletpage.wchange50") + parentEpml.request('showSnackBar', `${arrrbookstring1}`) + return false + } - if (address.length === 0) { - let arrrbookstring2 = get("walletpage.wchange51") - parentEpml.request('showSnackBar', `${arrrbookstring2}`) - return false - } + if (address.length === 0) { + let arrrbookstring2 = get("walletpage.wchange51") + parentEpml.request('showSnackBar', `${arrrbookstring2}`) + return false + } - const newPiratechainBookItem = { - name: name, - address: address - } + const newPiratechainBookItem = { + name: name, + address: address + } - oldPiratechainBook.push(newPiratechainBookItem) + oldPiratechainBook.push(newPiratechainBookItem) - localStorage.setItem(myPiratechainAddressBook, JSON.stringify(oldPiratechainBook)) + localStorage.setItem(myPiratechainAddressBook, JSON.stringify(oldPiratechainBook)) - let arrrbookstring3 = get("walletpage.wchange52") - parentEpml.request('showSnackBar', `${arrrbookstring3}`) + let arrrbookstring3 = get("walletpage.wchange52") + parentEpml.request('showSnackBar', `${arrrbookstring3}`) - this.closeArrrAddressDialog() - this.arrrBook = JSON.parse(localStorage.getItem(myPiratechainAddressBook) || "[]") - } + this.closeArrrAddressDialog() + this.arrrBook = JSON.parse(localStorage.getItem(myPiratechainAddressBook) || "[]") + } - sendFromQortAddressbook(websiteObj) { + sendFromQortAddressbook(websiteObj) { this.recipient = websiteObj.address - this.openSendQort() - this.shadowRoot.querySelector('#qortBookDialog').close() - } + this.openSendQort() + this.shadowRoot.querySelector('#qortBookDialog').close() + } - sendFromBtcAddressbook(websiteObj) { + sendFromBtcAddressbook(websiteObj) { this.btcRecipient = websiteObj.address - this.openSendBtc() - this.shadowRoot.querySelector('#btcBookDialog').close() - } + this.openSendBtc() + this.shadowRoot.querySelector('#btcBookDialog').close() + } - sendFromLtcAddressbook(websiteObj) { + sendFromLtcAddressbook(websiteObj) { this.ltcRecipient = websiteObj.address - this.openSendLtc() - this.shadowRoot.querySelector('#ltcBookDialog').close() - } + this.openSendLtc() + this.shadowRoot.querySelector('#ltcBookDialog').close() + } - sendFromDogeAddressbook(websiteObj) { + sendFromDogeAddressbook(websiteObj) { this.dogeRecipient = websiteObj.address - this.openSendDoge() - this.shadowRoot.querySelector('#dogeBookDialog').close() - } + this.openSendDoge() + this.shadowRoot.querySelector('#dogeBookDialog').close() + } - sendFromDgbAddressbook(websiteObj) { + sendFromDgbAddressbook(websiteObj) { this.dgbRecipient = websiteObj.address - this.openSendDgb() - this.shadowRoot.querySelector('#dgbBookDialog').close() - } + this.openSendDgb() + this.shadowRoot.querySelector('#dgbBookDialog').close() + } - sendFromRvnAddressbook(websiteObj) { + sendFromRvnAddressbook(websiteObj) { this.rvnRecipient = websiteObj.address - this.openSendRvn() - this.shadowRoot.querySelector('#rvnBookDialog').close() - } + this.openSendRvn() + this.shadowRoot.querySelector('#rvnBookDialog').close() + } - sendFromArrrAddressbook(websiteObj) { + sendFromArrrAddressbook(websiteObj) { this.arrrRecipient = websiteObj.address - this.openSendArrr() - this.shadowRoot.querySelector('#arrrBookDialog').close() - } + this.openSendArrr() + this.shadowRoot.querySelector('#arrrBookDialog').close() + } - removeQortAddress(adressObj) { - const theQortalAddressBook = 'addressbookQort-' + this.bookQortalAddress - const addressToRemove = adressObj - this.newQortBookFilter = [] - this.newQortBookFilter = this.qortBook.filter((item) => item.address !== addressToRemove) - const myNewObj = JSON.stringify(this.newQortBookFilter) - localStorage.removeItem(theQortalAddressBook) - localStorage.setItem(theQortalAddressBook, myNewObj) - this.qortBook = JSON.parse(localStorage.getItem(theQortalAddressBook) || "[]") - } + removeQortAddress(adressObj) { + const theQortalAddressBook = 'addressbookQort-' + this.bookQortalAddress + const addressToRemove = adressObj + this.newQortBookFilter = [] + this.newQortBookFilter = this.qortBook.filter((item) => item.address !== addressToRemove) + const myNewObj = JSON.stringify(this.newQortBookFilter) + localStorage.removeItem(theQortalAddressBook) + localStorage.setItem(theQortalAddressBook, myNewObj) + this.qortBook = JSON.parse(localStorage.getItem(theQortalAddressBook) || "[]") + } - removeBtcAddress(adressObj) { - const theBitcoinAddressBook = 'addressbookBtc-' + this.bookBitcoinAddress - const addressToRemove = adressObj - this.newBtcBookFilter = [] - this.newBtcBookFilter = this.btcBook.filter((item) => item.address !== addressToRemove) - const myNewObj = JSON.stringify(this.newBtcBookFilter) - localStorage.removeItem(theBitcoinAddressBook) - localStorage.setItem(theBitcoinAddressBook, myNewObj) - this.btcBook = JSON.parse(localStorage.getItem(theBitcoinAddressBook) || "[]") - } + removeBtcAddress(adressObj) { + const theBitcoinAddressBook = 'addressbookBtc-' + this.bookBitcoinAddress + const addressToRemove = adressObj + this.newBtcBookFilter = [] + this.newBtcBookFilter = this.btcBook.filter((item) => item.address !== addressToRemove) + const myNewObj = JSON.stringify(this.newBtcBookFilter) + localStorage.removeItem(theBitcoinAddressBook) + localStorage.setItem(theBitcoinAddressBook, myNewObj) + this.btcBook = JSON.parse(localStorage.getItem(theBitcoinAddressBook) || "[]") + } - removeLtcAddress(adressObj) { - const theLitecoinAddressBook = 'addressbookLtc-' + this.bookLitecoinAddress - const addressToRemove = adressObj - this.newLtcBookFilter = [] - this.newLtcBookFilter = this.ltcBook.filter((item) => item.address !== addressToRemove) - const myNewObj = JSON.stringify(this.newLtcBookFilter) - localStorage.removeItem(theLitecoinAddressBook) - localStorage.setItem(theLitecoinAddressBook, myNewObj) - this.ltcBook = JSON.parse(localStorage.getItem(theLitecoinAddressBook) || "[]") - } + removeLtcAddress(adressObj) { + const theLitecoinAddressBook = 'addressbookLtc-' + this.bookLitecoinAddress + const addressToRemove = adressObj + this.newLtcBookFilter = [] + this.newLtcBookFilter = this.ltcBook.filter((item) => item.address !== addressToRemove) + const myNewObj = JSON.stringify(this.newLtcBookFilter) + localStorage.removeItem(theLitecoinAddressBook) + localStorage.setItem(theLitecoinAddressBook, myNewObj) + this.ltcBook = JSON.parse(localStorage.getItem(theLitecoinAddressBook) || "[]") + } - removeDogeAddress(adressObj) { - const theDogecoinAddressBook = 'addressbookDoge-' + this.bookDogecoinAddress - const addressToRemove = adressObj - this.newDogeBookFilter = [] - this.newDogeBookFilter = this.dogeBook.filter((item) => item.address !== addressToRemove) - const myNewObj = JSON.stringify(this.newDogeBookFilter) - localStorage.removeItem(theDogecoinAddressBook) - localStorage.setItem(theDogecoinAddressBook, myNewObj) - this.dogeBook = JSON.parse(localStorage.getItem(theDogecoinAddressBook) || "[]") - } + removeDogeAddress(adressObj) { + const theDogecoinAddressBook = 'addressbookDoge-' + this.bookDogecoinAddress + const addressToRemove = adressObj + this.newDogeBookFilter = [] + this.newDogeBookFilter = this.dogeBook.filter((item) => item.address !== addressToRemove) + const myNewObj = JSON.stringify(this.newDogeBookFilter) + localStorage.removeItem(theDogecoinAddressBook) + localStorage.setItem(theDogecoinAddressBook, myNewObj) + this.dogeBook = JSON.parse(localStorage.getItem(theDogecoinAddressBook) || "[]") + } - removeDgbAddress(adressObj) { - const theDigibyteAddressBook = 'addressbookDgb-' + this.bookDigibyteAddress - const addressToRemove = adressObj - this.newDgbBookFilter = [] - this.newDgbBookFilter = this.dgbBook.filter((item) => item.address !== addressToRemove) - const myNewObj = JSON.stringify(this.newDgbBookFilter) - localStorage.removeItem(theDigibyteAddressBook) - localStorage.setItem(theDigibyteAddressBook, myNewObj) - this.dgbBook = JSON.parse(localStorage.getItem(theDigibyteAddressBook) || "[]") - } + removeDgbAddress(adressObj) { + const theDigibyteAddressBook = 'addressbookDgb-' + this.bookDigibyteAddress + const addressToRemove = adressObj + this.newDgbBookFilter = [] + this.newDgbBookFilter = this.dgbBook.filter((item) => item.address !== addressToRemove) + const myNewObj = JSON.stringify(this.newDgbBookFilter) + localStorage.removeItem(theDigibyteAddressBook) + localStorage.setItem(theDigibyteAddressBook, myNewObj) + this.dgbBook = JSON.parse(localStorage.getItem(theDigibyteAddressBook) || "[]") + } - removeRvnAddress(adressObj) { - const theRavencoinAddressBook = 'addressbookRvn-' + this.bookRavencoinAddress - const addressToRemove = adressObj - this.newRvnBookFilter = [] - this.newRvnBookFilter = this.rvnBook.filter((item) => item.address !== addressToRemove) - const myNewObj = JSON.stringify(this.newRvnBookFilter) - localStorage.removeItem(theRavencoinAddressBook) - localStorage.setItem(theRavencoinAddressBook, myNewObj) - this.rvnBook = JSON.parse(localStorage.getItem(theRavencoinAddressBook) || "[]") - } + removeRvnAddress(adressObj) { + const theRavencoinAddressBook = 'addressbookRvn-' + this.bookRavencoinAddress + const addressToRemove = adressObj + this.newRvnBookFilter = [] + this.newRvnBookFilter = this.rvnBook.filter((item) => item.address !== addressToRemove) + const myNewObj = JSON.stringify(this.newRvnBookFilter) + localStorage.removeItem(theRavencoinAddressBook) + localStorage.setItem(theRavencoinAddressBook, myNewObj) + this.rvnBook = JSON.parse(localStorage.getItem(theRavencoinAddressBook) || "[]") + } - removeArrrAddress(adressObj) { - const thePiratechainAddressBook = 'addressbookArrr-' + this.bookPiratechainAddress - const addressToRemove = adressObj - this.newArrrBookFilter = [] - this.newArrrBookFilter = this.arrrBook.filter((item) => item.address !== addressToRemove) - const myNewObj = JSON.stringify(this.newArrrBookFilter) - localStorage.removeItem(thePiratechainAddressBook) - localStorage.setItem(thePiratechainAddressBook, myNewObj) - this.arrrBook = JSON.parse(localStorage.getItem(thePiratechainAddressBook) || "[]") - } + removeArrrAddress(adressObj) { + const thePiratechainAddressBook = 'addressbookArrr-' + this.bookPiratechainAddress + const addressToRemove = adressObj + this.newArrrBookFilter = [] + this.newArrrBookFilter = this.arrrBook.filter((item) => item.address !== addressToRemove) + const myNewObj = JSON.stringify(this.newArrrBookFilter) + localStorage.removeItem(thePiratechainAddressBook) + localStorage.setItem(thePiratechainAddressBook, myNewObj) + this.arrrBook = JSON.parse(localStorage.getItem(thePiratechainAddressBook) || "[]") + } - renderSendFromQortAddressbookButton(websiteObj) { - return html`` - } + renderSendFromQortAddressbookButton(websiteObj) { + return html`` + } - renderSendFromBtcAddressbookButton(websiteObj) { - return html`` - } + renderSendFromBtcAddressbookButton(websiteObj) { + return html`` + } - renderSendFromLtcAddressbookButton(websiteObj) { - return html`` - } + renderSendFromLtcAddressbookButton(websiteObj) { + return html`` + } - renderSendFromDogeAddressbookButton(websiteObj) { - return html`` - } + renderSendFromDogeAddressbookButton(websiteObj) { + return html`` + } - renderSendFromDgbAddressbookButton(websiteObj) { - return html`` - } + renderSendFromDgbAddressbookButton(websiteObj) { + return html`` + } - renderSendFromRvnAddressbookButton(websiteObj) { - return html`` - } + renderSendFromRvnAddressbookButton(websiteObj) { + return html`` + } - renderSendFromArrrAddressbookButton(websiteObj) { - return html`` - } + renderSendFromArrrAddressbookButton(websiteObj) { + return html`` + } - exportQortAddressbook() { - const expQortalAddressBook = 'addressbookQort-' + this.bookQortalAddress - let bookname = "" - const qortBookData = JSON.stringify(localStorage.getItem(expQortalAddressBook)) - const qortBookSave = JSON.parse((qortBookData) || "[]") - const blob = new Blob([qortBookSave], { type: 'text/plain;charset=utf-8' }) - bookname = "qortal_addressbook." + this.bookQortalAddress + ".qort.json" - this.saveFileToDisk(blob, bookname) - } + exportQortAddressbook() { + const expQortalAddressBook = 'addressbookQort-' + this.bookQortalAddress + let bookname = "" + const qortBookData = JSON.stringify(localStorage.getItem(expQortalAddressBook)) + const qortBookSave = JSON.parse((qortBookData) || "[]") + const blob = new Blob([qortBookSave], { type: 'text/plain;charset=utf-8' }) + bookname = "qortal_addressbook." + this.bookQortalAddress + ".qort.json" + this.saveFileToDisk(blob, bookname) + } - exportBtcAddressbook() { - const expBitcoinAddressBook = 'addressbookBtc-' + this.bookBitcoinAddress - let bookname = "" - const btcBookData = JSON.stringify(localStorage.getItem(expBitcoinAddressBook)) - const btcBookSave = JSON.parse((btcBookData) || "[]") - const blob = new Blob([btcBookSave], { type: 'text/plain;charset=utf-8' }) - bookname = "bitcoin_addressbook." + this.bookBitcoinAddress + ".btc.json" - this.saveFileToDisk(blob, bookname) - } + exportBtcAddressbook() { + const expBitcoinAddressBook = 'addressbookBtc-' + this.bookBitcoinAddress + let bookname = "" + const btcBookData = JSON.stringify(localStorage.getItem(expBitcoinAddressBook)) + const btcBookSave = JSON.parse((btcBookData) || "[]") + const blob = new Blob([btcBookSave], { type: 'text/plain;charset=utf-8' }) + bookname = "bitcoin_addressbook." + this.bookBitcoinAddress + ".btc.json" + this.saveFileToDisk(blob, bookname) + } - exportLtcAddressbook() { - const expLitecoinAddressBook = 'addressbookLtc-' + this.bookLitecoinAddress - let bookname = "" - const ltcBookData = JSON.stringify(localStorage.getItem(expLitecoinAddressBook)) - const ltcBookSave = JSON.parse((ltcBookData) || "[]") - const blob = new Blob([ltcBookSave], { type: 'text/plain;charset=utf-8' }) - bookname = "litecoin_addressbook." + this.bookLitecoinAddress + ".ltc.json" - this.saveFileToDisk(blob, bookname) - } + exportLtcAddressbook() { + const expLitecoinAddressBook = 'addressbookLtc-' + this.bookLitecoinAddress + let bookname = "" + const ltcBookData = JSON.stringify(localStorage.getItem(expLitecoinAddressBook)) + const ltcBookSave = JSON.parse((ltcBookData) || "[]") + const blob = new Blob([ltcBookSave], { type: 'text/plain;charset=utf-8' }) + bookname = "litecoin_addressbook." + this.bookLitecoinAddress + ".ltc.json" + this.saveFileToDisk(blob, bookname) + } - exportDogeAddressbook() { - const expDogecoinAddressBook = 'addressbookDoge-' + this.bookDogecoinAddress - let bookname = "" - const dogeBookData = JSON.stringify(localStorage.getItem(expDogecoinAddressBook)) - const dogeBookSave = JSON.parse((dogeBookData) || "[]") - const blob = new Blob([dogeBookSave], { type: 'text/plain;charset=utf-8' }) - bookname = "dogecoin_addressbook." + this.bookDogecoinAddress + ".doge.json" - this.saveFileToDisk(blob, bookname) - } + exportDogeAddressbook() { + const expDogecoinAddressBook = 'addressbookDoge-' + this.bookDogecoinAddress + let bookname = "" + const dogeBookData = JSON.stringify(localStorage.getItem(expDogecoinAddressBook)) + const dogeBookSave = JSON.parse((dogeBookData) || "[]") + const blob = new Blob([dogeBookSave], { type: 'text/plain;charset=utf-8' }) + bookname = "dogecoin_addressbook." + this.bookDogecoinAddress + ".doge.json" + this.saveFileToDisk(blob, bookname) + } - exportDgbAddressbook() { - const expDigibyteAddressBook = 'addressbookDgb-' + this.bookDigibyteAddress - let bookname = "" - const dgbBookData = JSON.stringify(localStorage.getItem(expDigibyteAddressBook)) - const dgbBookSave = JSON.parse((dgbBookData) || "[]") - const blob = new Blob([dgbBookSave], { type: 'text/plain;charset=utf-8' }) - bookname = "digibyte_addressbook." + this.bookDigibyteAddress + ".dgb.json" - this.saveFileToDisk(blob, bookname) - } + exportDgbAddressbook() { + const expDigibyteAddressBook = 'addressbookDgb-' + this.bookDigibyteAddress + let bookname = "" + const dgbBookData = JSON.stringify(localStorage.getItem(expDigibyteAddressBook)) + const dgbBookSave = JSON.parse((dgbBookData) || "[]") + const blob = new Blob([dgbBookSave], { type: 'text/plain;charset=utf-8' }) + bookname = "digibyte_addressbook." + this.bookDigibyteAddress + ".dgb.json" + this.saveFileToDisk(blob, bookname) + } - exportRvnAddressbook() { - const expRavencoinAddressBook = 'addressbookRvn-' + this.bookRavencoinAddress - let bookname = "" - const rvnBookData = JSON.stringify(localStorage.getItem(expRavencoinAddressBook)) - const rvnBookSave = JSON.parse((rvnBookData) || "[]") - const blob = new Blob([rvnBookSave], { type: 'text/plain;charset=utf-8' }) - bookname = "ravencoin_addressbook." + this.bookRavencoinAddress + ".rvn.json" - this.saveFileToDisk(blob, bookname) - } + exportRvnAddressbook() { + const expRavencoinAddressBook = 'addressbookRvn-' + this.bookRavencoinAddress + let bookname = "" + const rvnBookData = JSON.stringify(localStorage.getItem(expRavencoinAddressBook)) + const rvnBookSave = JSON.parse((rvnBookData) || "[]") + const blob = new Blob([rvnBookSave], { type: 'text/plain;charset=utf-8' }) + bookname = "ravencoin_addressbook." + this.bookRavencoinAddress + ".rvn.json" + this.saveFileToDisk(blob, bookname) + } - exportArrrAddressbook() { - const expPiratechainAddressBook = 'addressbookArrr-' + this.bookPiratechainAddress - let bookname = "" - const arrrBookData = JSON.stringify(localStorage.getItem(expPiratechainAddressBook)) - const arrrBookSave = JSON.parse((arrrBookData) || "[]") - const blob = new Blob([arrrBookSave], { type: 'text/plain;charset=utf-8' }) - bookname = "piratechain_addressbook." + this.bookPiratechainAddress + ".arrr.json" - this.saveFileToDisk(blob, bookname) - } + exportArrrAddressbook() { + const expPiratechainAddressBook = 'addressbookArrr-' + this.bookPiratechainAddress + let bookname = "" + const arrrBookData = JSON.stringify(localStorage.getItem(expPiratechainAddressBook)) + const arrrBookSave = JSON.parse((arrrBookData) || "[]") + const blob = new Blob([arrrBookSave], { type: 'text/plain;charset=utf-8' }) + bookname = "piratechain_addressbook." + this.bookPiratechainAddress + ".arrr.json" + this.saveFileToDisk(blob, bookname) + } - importQortAddressbook(file) { - const impQortalAddressBook = 'addressbookQort-' + this.bookQortalAddress - localStorage.removeItem(impQortalAddressBook) - const newItems = JSON.parse((file) || "[]") - localStorage.setItem(impQortalAddressBook, JSON.stringify(newItems)) - this.qortBook = JSON.parse(localStorage.getItem(impQortalAddressBook) || "[]") - this.shadowRoot.querySelector('#importQortAddressbookDialog').close() - } + importQortAddressbook(file) { + const impQortalAddressBook = 'addressbookQort-' + this.bookQortalAddress + localStorage.removeItem(impQortalAddressBook) + const newItems = JSON.parse((file) || "[]") + localStorage.setItem(impQortalAddressBook, JSON.stringify(newItems)) + this.qortBook = JSON.parse(localStorage.getItem(impQortalAddressBook) || "[]") + this.shadowRoot.querySelector('#importQortAddressbookDialog').close() + } - importBtcAddressbook(file) { - const impBitcoinAddressBook = 'addressbookBtc-' + this.bookBitcoinAddress - localStorage.removeItem(impBitcoinAddressBook) - const newItems = JSON.parse((file) || "[]") - localStorage.setItem(impBitcoinAddressBook, JSON.stringify(newItems)) - this.btcBook = JSON.parse(localStorage.getItem(impBitcoinAddressBook) || "[]") - this.shadowRoot.querySelector('#importBtcAddressbookDialog').close() - } + importBtcAddressbook(file) { + const impBitcoinAddressBook = 'addressbookBtc-' + this.bookBitcoinAddress + localStorage.removeItem(impBitcoinAddressBook) + const newItems = JSON.parse((file) || "[]") + localStorage.setItem(impBitcoinAddressBook, JSON.stringify(newItems)) + this.btcBook = JSON.parse(localStorage.getItem(impBitcoinAddressBook) || "[]") + this.shadowRoot.querySelector('#importBtcAddressbookDialog').close() + } - importLtcAddressbook(file) { - const impLitecoinAddressBook = 'addressbookLtc-' + this.bookLitecoinAddress - localStorage.removeItem(impLitecoinAddressBook) - const newItems = JSON.parse((file) || "[]") - localStorage.setItem(impLitecoinAddressBook, JSON.stringify(newItems)) - this.ltcBook = JSON.parse(localStorage.getItem(impLitecoinAddressBook) || "[]") - this.shadowRoot.querySelector('#importLtcAddressbookDialog').close() - } + importLtcAddressbook(file) { + const impLitecoinAddressBook = 'addressbookLtc-' + this.bookLitecoinAddress + localStorage.removeItem(impLitecoinAddressBook) + const newItems = JSON.parse((file) || "[]") + localStorage.setItem(impLitecoinAddressBook, JSON.stringify(newItems)) + this.ltcBook = JSON.parse(localStorage.getItem(impLitecoinAddressBook) || "[]") + this.shadowRoot.querySelector('#importLtcAddressbookDialog').close() + } - importDogeAddressbook(file) { - const impDogecoinAddressBook = 'addressbookDoge-' + this.bookDogecoinAddress - localStorage.removeItem(impDogecoinAddressBook) - const newItems = JSON.parse((file) || "[]") - localStorage.setItem(impDogecoinAddressBook, JSON.stringify(newItems)) - this.dogeBook = JSON.parse(localStorage.getItem(impDogecoinAddressBook) || "[]") - this.shadowRoot.querySelector('#importDogeAddressbookDialog').close() - } + importDogeAddressbook(file) { + const impDogecoinAddressBook = 'addressbookDoge-' + this.bookDogecoinAddress + localStorage.removeItem(impDogecoinAddressBook) + const newItems = JSON.parse((file) || "[]") + localStorage.setItem(impDogecoinAddressBook, JSON.stringify(newItems)) + this.dogeBook = JSON.parse(localStorage.getItem(impDogecoinAddressBook) || "[]") + this.shadowRoot.querySelector('#importDogeAddressbookDialog').close() + } - importDgbAddressbook(file) { - const impDigibyteAddressBook = 'addressbookDgb-' + this.bookDigibyteAddress - localStorage.removeItem(impDigibyteAddressBook) - const newItems = JSON.parse((file) || "[]") - localStorage.setItem(impDigibyteAddressBook, JSON.stringify(newItems)) - this.dgbBook = JSON.parse(localStorage.getItem(impDigibyteAddressBook) || "[]") - this.shadowRoot.querySelector('#importDgbAddressbookDialog').close() - } + importDgbAddressbook(file) { + const impDigibyteAddressBook = 'addressbookDgb-' + this.bookDigibyteAddress + localStorage.removeItem(impDigibyteAddressBook) + const newItems = JSON.parse((file) || "[]") + localStorage.setItem(impDigibyteAddressBook, JSON.stringify(newItems)) + this.dgbBook = JSON.parse(localStorage.getItem(impDigibyteAddressBook) || "[]") + this.shadowRoot.querySelector('#importDgbAddressbookDialog').close() + } - importRvnAddressbook(file) { - const impRavencoinAddressBook = 'addressbookRvn-' + this.bookRavencoinAddress - localStorage.removeItem(impRavencoinAddressBook) - const newItems = JSON.parse((file) || "[]") - localStorage.setItem(impRavencoinAddressBook, JSON.stringify(newItems)) - this.rvnBook = JSON.parse(localStorage.getItem(impRavencoinAddressBook) || "[]") - this.shadowRoot.querySelector('#importRvnAddressbookDialog').close() - } + importRvnAddressbook(file) { + const impRavencoinAddressBook = 'addressbookRvn-' + this.bookRavencoinAddress + localStorage.removeItem(impRavencoinAddressBook) + const newItems = JSON.parse((file) || "[]") + localStorage.setItem(impRavencoinAddressBook, JSON.stringify(newItems)) + this.rvnBook = JSON.parse(localStorage.getItem(impRavencoinAddressBook) || "[]") + this.shadowRoot.querySelector('#importRvnAddressbookDialog').close() + } - importArrrAddressbook(file) { - const impPiratechainAddressBook = 'addressbookArrr-' + this.bookPiratechainAddress - localStorage.removeItem(impPiratechainAddressBook) - const newItems = JSON.parse((file) || "[]") - localStorage.setItem(impPiratechainAddressBook, JSON.stringify(newItems)) - this.arrrBook = JSON.parse(localStorage.getItem(impPiratechainAddressBook) || "[]") - this.shadowRoot.querySelector('#importArrrAddressbookDialog').close() - } + importArrrAddressbook(file) { + const impPiratechainAddressBook = 'addressbookArrr-' + this.bookPiratechainAddress + localStorage.removeItem(impPiratechainAddressBook) + const newItems = JSON.parse((file) || "[]") + localStorage.setItem(impPiratechainAddressBook, JSON.stringify(newItems)) + this.arrrBook = JSON.parse(localStorage.getItem(impPiratechainAddressBook) || "[]") + this.shadowRoot.querySelector('#importArrrAddressbookDialog').close() + } - closeQortDialog() { - this.shadowRoot.querySelector('#sendQortDialog').close() - this.shadowRoot.getElementById('amountInput').value = '' - this.shadowRoot.getElementById('recipient').value = '' - this.recipient = '' - this.amount = 0 - this.successMessage = '' - this.errorMessage = '' - } + closeQortDialog() { + this.shadowRoot.querySelector('#sendQortDialog').close() + this.shadowRoot.getElementById('amountInput').value = '' + this.shadowRoot.getElementById('recipient').value = '' + this.recipient = '' + this.amount = 0 + this.successMessage = '' + this.errorMessage = '' + } - closeBtcDialog() { - this.shadowRoot.querySelector('#sendBtcDialog').close() - this.shadowRoot.getElementById('btcAmountInput').value = 0 - this.shadowRoot.getElementById('btcRecipient').value = '' - this.btcRecipient = '' - this.btcAmount = 0 - this.successMessage = '' - this.errorMessage = '' - } + closeBtcDialog() { + this.shadowRoot.querySelector('#sendBtcDialog').close() + this.shadowRoot.getElementById('btcAmountInput').value = 0 + this.shadowRoot.getElementById('btcRecipient').value = '' + this.btcRecipient = '' + this.btcAmount = 0 + this.successMessage = '' + this.errorMessage = '' + } - closeLtcDialog() { - this.shadowRoot.querySelector('#sendLtcDialog').close() - this.shadowRoot.getElementById('ltcAmountInput').value = 0 - this.shadowRoot.getElementById('ltcRecipient').value = '' - this.ltcRecipient = '' - this.ltcAmount = 0 - this.successMessage = '' - this.errorMessage = '' - } + closeLtcDialog() { + this.shadowRoot.querySelector('#sendLtcDialog').close() + this.shadowRoot.getElementById('ltcAmountInput').value = 0 + this.shadowRoot.getElementById('ltcRecipient').value = '' + this.ltcRecipient = '' + this.ltcAmount = 0 + this.successMessage = '' + this.errorMessage = '' + } - closeDogeDialog() { - this.shadowRoot.querySelector('#sendDogeDialog').close() - this.shadowRoot.getElementById('dogeAmountInput').value = 0 - this.shadowRoot.getElementById('dogeRecipient').value = '' - this.dogeRecipient = '' - this.dogeAmount = 0 - this.successMessage = '' - this.errorMessage = '' - } + closeDogeDialog() { + this.shadowRoot.querySelector('#sendDogeDialog').close() + this.shadowRoot.getElementById('dogeAmountInput').value = 0 + this.shadowRoot.getElementById('dogeRecipient').value = '' + this.dogeRecipient = '' + this.dogeAmount = 0 + this.successMessage = '' + this.errorMessage = '' + } - closeDgbDialog() { - this.shadowRoot.querySelector('#sendDgbDialog').close() - this.shadowRoot.getElementById('dgbAmountInput').value = 0 - this.shadowRoot.getElementById('dgbRecipient').value = '' - this.dgbRecipient = '' - this.dgbAmount = 0 - this.successMessage = '' - this.errorMessage = '' - } + closeDgbDialog() { + this.shadowRoot.querySelector('#sendDgbDialog').close() + this.shadowRoot.getElementById('dgbAmountInput').value = 0 + this.shadowRoot.getElementById('dgbRecipient').value = '' + this.dgbRecipient = '' + this.dgbAmount = 0 + this.successMessage = '' + this.errorMessage = '' + } - closeRvnDialog() { - this.shadowRoot.querySelector('#sendRvnDialog').close() - this.shadowRoot.getElementById('rvnAmountInput').value = 0 - this.shadowRoot.getElementById('rvRecipient').value = '' - this.rvnRecipient = '' - this.rvnAmount = 0 - this.successMessage = '' - this.errorMessage = '' - } + closeRvnDialog() { + this.shadowRoot.querySelector('#sendRvnDialog').close() + this.shadowRoot.getElementById('rvnAmountInput').value = 0 + this.shadowRoot.getElementById('rvRecipient').value = '' + this.rvnRecipient = '' + this.rvnAmount = 0 + this.successMessage = '' + this.errorMessage = '' + } - closeArrrDialog() { - this.shadowRoot.querySelector('#sendArrrDialog').close() - this.shadowRoot.getElementById('arrrRecipient').value = '' - this.shadowRoot.getElementById('arrrMemo').value = '' - this.arrrRecipient = '' - this.arrrMemo='' - this.arrrAmount = 0 - this.successMessage = '' - this.errorMessage = '' - } + closeArrrDialog() { + this.shadowRoot.querySelector('#sendArrrDialog').close() + this.shadowRoot.getElementById('arrrRecipient').value = '' + this.shadowRoot.getElementById('arrrMemo').value = '' + this.arrrRecipient = '' + this.arrrMemo = '' + this.arrrAmount = 0 + this.successMessage = '' + this.errorMessage = '' + } - sendToQortAddress() { - this.recipient = this.selectedTransaction.recipient - this.openSendQort() - this.shadowRoot.querySelector('#showTransactionDetailsDialog').close() - } + sendToQortAddress() { + this.recipient = this.selectedTransaction.recipient + this.openSendQort() + this.shadowRoot.querySelector('#showTransactionDetailsDialog').close() + } - sendToBtcAddress() { - this.btcRecipient = this.selectedTransaction.btcReceiver - this.openSendBtc() - this.shadowRoot.querySelector('#showBtcTransactionDetailsDialog').close() - } + sendToBtcAddress() { + this.btcRecipient = this.selectedTransaction.btcReceiver + this.openSendBtc() + this.shadowRoot.querySelector('#showBtcTransactionDetailsDialog').close() + } - sendToLtcAddress() { - this.ltcRecipient = this.selectedTransaction.ltcReceiver - this.openSendLtc() - this.shadowRoot.querySelector('#showLtcTransactionDetailsDialog').close() - } + sendToLtcAddress() { + this.ltcRecipient = this.selectedTransaction.ltcReceiver + this.openSendLtc() + this.shadowRoot.querySelector('#showLtcTransactionDetailsDialog').close() + } - sendToDogeAddress() { - this.dogeRecipient = this.selectedTransaction.dogeReceiver - this.openSendDoge() - this.shadowRoot.querySelector('#showDogeTransactionDetailsDialog').close() - } + sendToDogeAddress() { + this.dogeRecipient = this.selectedTransaction.dogeReceiver + this.openSendDoge() + this.shadowRoot.querySelector('#showDogeTransactionDetailsDialog').close() + } - sendToDgbAddress() { - this.dgbRecipient = this.selectedTransaction.dgbReceiver - this.openSendDgb() - this.shadowRoot.querySelector('#showDgbTransactionDetailsDialog').close() - } + sendToDgbAddress() { + this.dgbRecipient = this.selectedTransaction.dgbReceiver + this.openSendDgb() + this.shadowRoot.querySelector('#showDgbTransactionDetailsDialog').close() + } - sendToRvnAddress() { - this.rvnRecipient = this.selectedTransaction.rvnReceiver - this.openSendRvn() - this.shadowRoot.querySelector('#showRvnTransactionDetailsDialog').close() - } + sendToRvnAddress() { + this.rvnRecipient = this.selectedTransaction.rvnReceiver + this.openSendRvn() + this.shadowRoot.querySelector('#showRvnTransactionDetailsDialog').close() + } - sendToArrrAddress() { - this.arrrRecipient = this.selectedTransaction.arrrReceiver - this.openSendArrr() - this.shadowRoot.querySelector('#showArrrTransactionDetailsDialog').close() - } + sendToArrrAddress() { + this.arrrRecipient = this.selectedTransaction.arrrReceiver + this.openSendArrr() + this.shadowRoot.querySelector('#showArrrTransactionDetailsDialog').close() + } - calculateQortAll() { - this.amount = 0 - this.shadowRoot.getElementById('amountInput').value = this.amount - if (this.balance < 0.01100000) { - let not_enough_string = get("walletpage.wchange26") - parentEpml.request('showSnackBar', `${not_enough_string}`) - } else { - this.amount = (this.balance - 0.01100000).toFixed(8) - this.shadowRoot.getElementById('amountInput').value = this.amount - this.shadowRoot.getElementById('amountInput').blur() - this.shadowRoot.getElementById('amountInput').focus() - } - } + calculateQortAll() { + this.amount = 0 + this.shadowRoot.getElementById('amountInput').value = this.amount + if (this.balance < 0.01100000) { + let not_enough_string = get("walletpage.wchange26") + parentEpml.request('showSnackBar', `${not_enough_string}`) + } else { + this.amount = (this.balance - 0.01100000).toFixed(8) + this.shadowRoot.getElementById('amountInput').value = this.amount + this.shadowRoot.getElementById('amountInput').blur() + this.shadowRoot.getElementById('amountInput').focus() + } + } - calculateBtcAll() { - if (this.balance < 0.00051000) { - let not_enough_string = get("walletpage.wchange26") - parentEpml.request('showSnackBar', `${not_enough_string}`) - } else { - this.btcAmount = (this.balance - 0.00050000).toFixed(8) - this.btcFeePerByte = 100 - } - } + calculateBtcAll() { + if (this.balance < 0.00051000) { + let not_enough_string = get("walletpage.wchange26") + parentEpml.request('showSnackBar', `${not_enough_string}`) + } else { + this.btcAmount = (this.balance - 0.00050000).toFixed(8) + this.btcFeePerByte = 100 + } + } - calculateLtcAll() { - if (this.balance < 0.00031000) { - let not_enough_string = get("walletpage.wchange26") - parentEpml.request('showSnackBar', `${not_enough_string}`) - } else { - this.ltcAmount = (this.balance - 0.00030000).toFixed(8) - this.ltcFeePerByte = 15 - } - } + calculateLtcAll() { + if (this.balance < 0.00031000) { + let not_enough_string = get("walletpage.wchange26") + parentEpml.request('showSnackBar', `${not_enough_string}`) + } else { + this.ltcAmount = (this.balance - 0.00030000).toFixed(8) + this.ltcFeePerByte = 15 + } + } - calculateDogeAll() { - if (this.balance < 0.05100000) { - let not_enough_string = get("walletpage.wchange26") - parentEpml.request('showSnackBar', `${not_enough_string}`) - } else { - this.dogeAmount = (this.balance - 0.05000000).toFixed(8) - this.dogeFeePerByte = 1000 - } - } + calculateDogeAll() { + if (this.balance < 0.05100000) { + let not_enough_string = get("walletpage.wchange26") + parentEpml.request('showSnackBar', `${not_enough_string}`) + } else { + this.dogeAmount = (this.balance - 0.05000000).toFixed(8) + this.dogeFeePerByte = 1000 + } + } - calculateDgbAll() { - if (this.balance < 0.00005100) { - let not_enough_string = get("walletpage.wchange26") - parentEpml.request('showSnackBar', `${not_enough_string}`) - } else { - this.dgbAmount = (this.balance - 0.00005000).toFixed(8) - this.dgbFeePerByte = 10 - } - } + calculateDgbAll() { + if (this.balance < 0.00005100) { + let not_enough_string = get("walletpage.wchange26") + parentEpml.request('showSnackBar', `${not_enough_string}`) + } else { + this.dgbAmount = (this.balance - 0.00005000).toFixed(8) + this.dgbFeePerByte = 10 + } + } - calculateRvnAll() { - if (this.balance < 0.00572500) { - let not_enough_string = get("walletpage.wchange26") - parentEpml.request('showSnackBar', `${not_enough_string}`) - } else { - this.rvnAmount = (this.balance - 0.00562500).toFixed(8) - this.rvnFeePerByte = 1125 - } - } + calculateRvnAll() { + if (this.balance < 0.00572500) { + let not_enough_string = get("walletpage.wchange26") + parentEpml.request('showSnackBar', `${not_enough_string}`) + } else { + this.rvnAmount = (this.balance - 0.00562500).toFixed(8) + this.rvnFeePerByte = 1125 + } + } - calculateArrrAll() { - if (this.balance < 0.00011000) { - let not_enough_string = get("walletpage.wchange26") - parentEpml.request('showSnackBar', `${not_enough_string}`) - } else { - this.arrrAmount = (this.balance - 0.00010000).toFixed(8) - } - } + calculateArrrAll() { + if (this.balance < 0.00011000) { + let not_enough_string = get("walletpage.wchange26") + parentEpml.request('showSnackBar', `${not_enough_string}`) + } else { + this.arrrAmount = (this.balance - 0.00010000).toFixed(8) + } + } - renderSQB() { - let displaybutton = this.selectedTransaction.recipient - if (displaybutton == null) { - return html`${this.selectedTransaction.recipient}` - } else { - return html` - ${this.selectedTransaction.recipient} - this.sendToQortAddress()} title="${translate("walletpage.wchange46")}"> - this.openAddQortAddressDialog()} title="${translate("walletpage.wchange49")}"> - ` - } - } + renderSQB() { + let displaybutton = this.selectedTransaction.recipient + if (displaybutton == null) { + return html`${this.selectedTransaction.recipient}` + } else { + return html` + ${this.selectedTransaction.recipient} + this.sendToQortAddress()} title="${translate("walletpage.wchange46")}"> + this.openAddQortAddressDialog()} title="${translate("walletpage.wchange49")}"> + ` + } + } - renderCAB() { - return html` + renderCAB() { + return html` ${this.selectedTransaction.aTAddress} ` - } + } - renderFetchText() { - return html`${translate("walletpage.wchange1")}` - } + renderFetchText() { + return html`${translate("walletpage.wchange1")}` + } - renderInvalidText() { - return html`${translate("walletpage.wchange27")}` - } + renderInvalidText() { + return html`${translate("walletpage.wchange27")}` + } - renderReceiverText() { - return html`${translate("walletpage.wchange29")}` - } + renderReceiverText() { + return html`${translate("walletpage.wchange29")}` + } - renderSuccessText() { - return html`${translate("walletpage.wchange30")}` - } + renderSuccessText() { + return html`${translate("walletpage.wchange30")}` + } - renderFailText() { - return html`${translate("walletpage.wchange31")}` - } + renderFailText() { + return html`${translate("walletpage.wchange31")}` + } - renderOutText() { - return html`${translate("walletpage.wchange7")}` - } + renderOutText() { + return html`${translate("walletpage.wchange7")}` + } - renderInText() { - return html`${translate("walletpage.wchange8")}` - } + renderInText() { + return html`${translate("walletpage.wchange8")}` + } - _checkAmount(e) { - const targetAmount = e.target.value - const target = e.target + _checkAmount(e) { + const targetAmount = e.target.value + const target = e.target - if (targetAmount.length === 0) { - this.isValidAmount = false - this.btnDisable = true + if (targetAmount.length === 0) { + this.isValidAmount = false + this.btnDisable = true - e.target.blur() - e.target.focus() + e.target.blur() + e.target.focus() - e.target.invalid = true - e.target.validationMessage = this.renderInvalidText() - } else { - this.btnDisable = false - } + e.target.invalid = true + e.target.validationMessage = this.renderInvalidText() + } else { + this.btnDisable = false + } - e.target.blur() - e.target.focus() + e.target.blur() + e.target.focus() - e.target.validityTransform = (newValue, nativeValidity) => { - if (newValue.includes('-') === true) { - this.btnDisable = true - target.validationMessage = this.renderInvalidText() + e.target.validityTransform = (newValue, nativeValidity) => { + if (newValue.includes('-') === true) { + this.btnDisable = true + target.validationMessage = this.renderInvalidText() - return { - valid: false, - } - } else if (!nativeValidity.valid) { - if (newValue.includes('.') === true) { - let myAmount = newValue.split('.') - if (myAmount[1].length > 8) { - this.btnDisable = true - target.validationMessage = this.renderInvalidText() - } else { - return { - valid: true, - } - } - } - } else { - this.btnDisable = false - } - } - } + return { + valid: false + } + } else if (!nativeValidity.valid) { + if (newValue.includes('.') === true) { + let myAmount = newValue.split('.') + if (myAmount[1].length > 8) { + this.btnDisable = true + target.validationMessage = this.renderInvalidText() + } else { + return { + valid: true + } + } + } + } else { + this.btnDisable = false + } + } + } - checkQortAmount(e) { - const targetAmount = e.target.value - const target = e.target - this.btnDisable = true - this.qortWarning = false + checkQortAmount(e) { + const targetAmount = e.target.value + const target = e.target + this.btnDisable = true + this.qortWarning = false - if (targetAmount.length === 0) { - this.isValidAmount = false - this.btnDisable = true - this.qortWarning = false - e.target.blur() - e.target.focus() - e.target.invalid = true - } else { - const checkQortAmountInput = this.shadowRoot.getElementById('amountInput').value - const checkQortAmount = this.round(parseFloat(checkQortAmountInput)) - const myFunds = this.round(parseFloat(this.balance - 0.01100000)) - if (Number(myFunds) >= Number(checkQortAmount)) { - this.shadowRoot.getElementById('amountInput').value = checkQortAmountInput - this.btnDisable = false - this.qortWarning = false - } else { - this.shadowRoot.getElementById('amountInput').value = checkQortAmountInput - this.btnDisable = true - this.qortWarning = true - } - } + if (targetAmount.length === 0) { + this.isValidAmount = false + this.btnDisable = true + this.qortWarning = false + e.target.blur() + e.target.focus() + e.target.invalid = true + } else { + const checkQortAmountInput = this.shadowRoot.getElementById('amountInput').value + const checkQortAmount = this.round(parseFloat(checkQortAmountInput)) + const myFunds = this.round(parseFloat(this.balance - 0.01100000)) + if (Number(myFunds) >= Number(checkQortAmount)) { + this.shadowRoot.getElementById('amountInput').value = checkQortAmountInput + this.btnDisable = false + this.qortWarning = false + } else { + this.shadowRoot.getElementById('amountInput').value = checkQortAmountInput + this.btnDisable = true + this.qortWarning = true + } + } - e.target.blur() - e.target.focus() + e.target.blur() + e.target.focus() - e.target.validityTransform = (newValue, nativeValidity) => { - if (newValue.includes('-') === true) { - this.btnDisable = true - this.qortWarning = false - return { - valid: false, - } - } else if (!nativeValidity.valid) { - if (newValue.includes('.') === true) { - let myAmount = newValue.split('.') - if (myAmount[1].length > 8) { - this.btnDisable = true - this.qortWarning = false - } else { - const checkQortAmountInput = this.shadowRoot.getElementById('amountInput').value - const checkQortAmount = this.round(parseFloat(checkQortAmountInput)) - const myFunds = this.round(parseFloat(this.balance - 0.01100000)) - if (Number(myFunds) >= Number(checkQortAmount)) { - this.shadowRoot.getElementById('amountInput').value = checkQortAmountInput - this.btnDisable = false - this.qortWarning = false - } else { - this.shadowRoot.getElementById('amountInput').value = checkQortAmountInput - this.btnDisable = true - this.qortWarning = true - } - return { - valid: true, - } - } - } - } else { - const checkQortAmountInput = this.shadowRoot.getElementById('amountInput').value - const checkQortAmount = this.round(parseFloat(checkQortAmountInput)) - const myFunds = this.round(parseFloat(this.balance - 0.01100000)) - if (Number(myFunds) >= Number(checkQortAmount)) { - this.shadowRoot.getElementById('amountInput').value = checkQortAmountInput - this.btnDisable = false - this.qortWarning = false - } else { - this.shadowRoot.getElementById('amountInput').value = checkQortAmountInput - this.btnDisable = true - this.qortWarning = true - } - } - } - } + e.target.validityTransform = (newValue, nativeValidity) => { + if (newValue.includes('-') === true) { + this.btnDisable = true + this.qortWarning = false + return { + valid: false + } + } else if (!nativeValidity.valid) { + if (newValue.includes('.') === true) { + let myAmount = newValue.split('.') + if (myAmount[1].length > 8) { + this.btnDisable = true + this.qortWarning = false + } else { + const checkQortAmountInput = this.shadowRoot.getElementById('amountInput').value + const checkQortAmount = this.round(parseFloat(checkQortAmountInput)) + const myFunds = this.round(parseFloat(this.balance - 0.01100000)) + if (Number(myFunds) >= Number(checkQortAmount)) { + this.shadowRoot.getElementById('amountInput').value = checkQortAmountInput + this.btnDisable = false + this.qortWarning = false + } else { + this.shadowRoot.getElementById('amountInput').value = checkQortAmountInput + this.btnDisable = true + this.qortWarning = true + } + return { + valid: true + } + } + } + } else { + const checkQortAmountInput = this.shadowRoot.getElementById('amountInput').value + const checkQortAmount = this.round(parseFloat(checkQortAmountInput)) + const myFunds = this.round(parseFloat(this.balance - 0.01100000)) + if (Number(myFunds) >= Number(checkQortAmount)) { + this.shadowRoot.getElementById('amountInput').value = checkQortAmountInput + this.btnDisable = false + this.qortWarning = false + } else { + this.shadowRoot.getElementById('amountInput').value = checkQortAmountInput + this.btnDisable = true + this.qortWarning = true + } + } + } + } - async sendQort() { - const sendFee = this.qortPaymentFee - const amount = this.shadowRoot.getElementById('amountInput').value - let recipient = this.shadowRoot.getElementById('recipient').value + async sendQort() { + const sendFee = this.qortPaymentFee + const amount = this.shadowRoot.getElementById('amountInput').value + let recipient = this.shadowRoot.getElementById('recipient').value - this.sendMoneyLoading = true - this.btnDisable = true + this.sendMoneyLoading = true + this.btnDisable = true - if (parseFloat(amount) + parseFloat(0.001) > parseFloat(this.balance)) { - this.sendMoneyLoading = false - this.btnDisable = false - let snack1string = get("walletpage.wchange26") - parentEpml.request('showSnackBar', `${snack1string}`) - return false - } + if (parseFloat(amount) + parseFloat(0.001) > parseFloat(this.balance)) { + this.sendMoneyLoading = false + this.btnDisable = false + let snack1string = get("walletpage.wchange26") + parentEpml.request('showSnackBar', `${snack1string}`) + return false + } - if (parseFloat(amount) <= 0) { - this.sendMoneyLoading = false - this.btnDisable = false - let snack2string = get("walletpage.wchange27") - parentEpml.request('showSnackBar', `${snack2string}`) - return false - } + if (parseFloat(amount) <= 0) { + this.sendMoneyLoading = false + this.btnDisable = false + let snack2string = get("walletpage.wchange27") + parentEpml.request('showSnackBar', `${snack2string}`) + return false + } - if (recipient.length === 0) { - this.sendMoneyLoading = false - this.btnDisable = false - let snack3string = get("walletpage.wchange28") - parentEpml.request('showSnackBar', `${snack3string}`) - return false - } + if (recipient.length === 0) { + this.sendMoneyLoading = false + this.btnDisable = false + let snack3string = get("walletpage.wchange28") + parentEpml.request('showSnackBar', `${snack3string}`) + return false + } - const getLastRef = async () => { - return await parentEpml.request('apiCall', { - type: 'api', - url: `/addresses/lastreference/${this.getSelectedWalletAddress()}`, - }) - } + const getLastRef = async () => { + return await parentEpml.request('apiCall', { + type: 'api', + url: `/addresses/lastreference/${this.getSelectedWalletAddress()}` + }) + } - const validateName = async (receiverName) => { - let myRes - let myNameRes = await parentEpml.request('apiCall', { - type: 'api', - url: `/names/${receiverName}`, - }) + const validateName = async (receiverName) => { + let myRes + let myNameRes = await parentEpml.request('apiCall', { + type: 'api', + url: `/names/${receiverName}` + }) - if (myNameRes.error === 401) { - myRes = false - } else { - myRes = myNameRes - } - return myRes - } + if (myNameRes.error === 401) { + myRes = false + } else { + myRes = myNameRes + } + return myRes + } - const validateAddress = async (receiverAddress) => { + const validateAddress = async (receiverAddress) => { return await window.parent.validateAddress(receiverAddress) - } + } - const validateReceiver = async (recipient) => { - let lastRef = await getLastRef() - let isAddress + const validateReceiver = async (recipient) => { + let lastRef = await getLastRef() + let isAddress - try { - isAddress = await validateAddress(recipient) - } catch (err) { - isAddress = false - } + try { + isAddress = await validateAddress(recipient) + } catch (err) { + isAddress = false + } - if (isAddress) { - let myTransaction = await makeTransactionRequest(recipient, lastRef) - getTxnRequestResponse(myTransaction) - } else { - let myNameRes = await validateName(recipient) - if (myNameRes !== false) { - let myNameAddress = myNameRes.owner - let myTransaction = await makeTransactionRequest(myNameAddress, lastRef) - getTxnRequestResponse(myTransaction) - } else { - console.error(this.renderReceiverText()) - this.errorMessage = this.renderReceiverText() - this.sendMoneyLoading = false - this.btnDisable = false - } - } - } + if (isAddress) { + let myTransaction = await makeTransactionRequest(recipient, lastRef) + getTxnRequestResponse(myTransaction) + } else { + let myNameRes = await validateName(recipient) + if (myNameRes !== false) { + let myNameAddress = myNameRes.owner + let myTransaction = await makeTransactionRequest(myNameAddress, lastRef) + getTxnRequestResponse(myTransaction) + } else { + console.error(this.renderReceiverText()) + this.errorMessage = this.renderReceiverText() + this.sendMoneyLoading = false + this.btnDisable = false + } + } + } - const getName = async (recipient)=> { - try { - const getNames = await parentEpml.request("apiCall", { - type: "api", - url: `/names/address/${recipient}`, - }) - if(getNames?.length > 0 ){ - return getNames[0].name - } else { - return '' - } - } catch (error) { - return "" - } - } + const getName = async (recipient) => { + try { + const getNames = await parentEpml.request("apiCall", { + type: "api", + url: `/names/address/${recipient}` + }) + if (getNames?.length > 0) { + return getNames[0].name + } else { + return '' + } + } catch (error) { + return '' + } + } - const makeTransactionRequest = async (receiver, lastRef) => { - let myReceiver = receiver - let mylastRef = lastRef - let dialogamount = get("transactions.amount") - let dialogAddress = get("login.address") - let dialogName = get("login.name") - let dialogto = get("transactions.to") - let recipientName = await getName(myReceiver) + const makeTransactionRequest = async (receiver, lastRef) => { + let myReceiver = receiver + let mylastRef = lastRef + let dialogamount = get("transactions.amount") + let dialogAddress = get("login.address") + let dialogName = get("login.name") + let dialogto = get("transactions.to") + let recipientName = await getName(myReceiver) - return await parentEpml.request('transaction', { - type: 2, - nonce: this.wallets.get(this._selectedWallet).wallet.nonce, - params: { - recipient: myReceiver, - recipientName: recipientName, - amount: amount, - lastReference: mylastRef, - fee: sendFee, - dialogamount: dialogamount, - dialogto: dialogto, - dialogAddress, - dialogName - }, - }) - } + return await parentEpml.request('transaction', { + type: 2, + nonce: this.wallets.get(this._selectedWallet).wallet.nonce, + params: { + recipient: myReceiver, + recipientName: recipientName, + amount: amount, + lastReference: mylastRef, + fee: sendFee, + dialogamount: dialogamount, + dialogto: dialogto, + dialogAddress, + dialogName + }, + }) + } - const getTxnRequestResponse = (txnResponse) => { - if (txnResponse.success === false && txnResponse.message) { - this.errorMessage = txnResponse.message - this.sendMoneyLoading = false - this.btnDisable = false - throw new Error(txnResponse) - } else if (txnResponse.success === true && !txnResponse.data.error) { - this.shadowRoot.getElementById('amountInput').value = '' - this.shadowRoot.getElementById('recipient').value = '' - this.errorMessage = '' - this.recipient = '' - this.amount = 0 - this.successMessage = this.renderSuccessText() - this.sendMoneyLoading = false - this.btnDisable = false - } else { - this.errorMessage = txnResponse.data.message - this.sendMoneyLoading = false - this.btnDisable = false - throw new Error(txnResponse) - } - } - await validateReceiver(recipient) - await this.showWallet() - } + const getTxnRequestResponse = (txnResponse) => { + if (txnResponse.success === false && txnResponse.message) { + this.errorMessage = txnResponse.message + this.sendMoneyLoading = false + this.btnDisable = false + throw new Error(txnResponse) + } else if (txnResponse.success === true && !txnResponse.data.error) { + this.shadowRoot.getElementById('amountInput').value = '' + this.shadowRoot.getElementById('recipient').value = '' + this.errorMessage = '' + this.recipient = '' + this.amount = 0 + this.successMessage = this.renderSuccessText() + this.sendMoneyLoading = false + this.btnDisable = false + } else { + this.errorMessage = txnResponse.data.message + this.sendMoneyLoading = false + this.btnDisable = false + throw new Error(txnResponse) + } + } + await validateReceiver(recipient) + await this.showWallet() + } - async sendBtc() { - const btcAmount = this.shadowRoot.getElementById('btcAmountInput').value - let btcRecipient = this.shadowRoot.getElementById('btcRecipient').value - const xprv58 = this.wallets.get(this._selectedWallet).wallet.derivedMasterPrivateKey + async sendBtc() { + const btcAmount = this.shadowRoot.getElementById('btcAmountInput').value + let btcRecipient = this.shadowRoot.getElementById('btcRecipient').value + const xprv58 = this.wallets.get(this._selectedWallet).wallet.derivedMasterPrivateKey - this.sendMoneyLoading = true - this.btnDisable = true + this.sendMoneyLoading = true + this.btnDisable = true - const makeRequest = async () => { - const opts = { - xprv58: xprv58, - receivingAddress: btcRecipient, - bitcoinAmount: btcAmount, - feePerByte: (this.btcFeePerByte / 1e8).toFixed(8), - } - return await parentEpml.request('sendBtc', opts) - } + const makeRequest = async () => { + const opts = { + xprv58: xprv58, + receivingAddress: btcRecipient, + bitcoinAmount: btcAmount, + feePerByte: (this.btcFeePerByte / 1e8).toFixed(8) + } + return await parentEpml.request('sendBtc', opts) + } - const manageResponse = (response) => { - if (response.length === 64) { - this.shadowRoot.getElementById('btcAmountInput').value = 0 - this.shadowRoot.getElementById('btcRecipient').value = '' - this.errorMessage = '' - this.btcRecipient = '' - this.btcAmount = 0 - this.successMessage = this.renderSuccessText() - this.sendMoneyLoading = false - this.btnDisable = false - } else if (response === false) { - this.errorMessage = this.renderFailText() - this.sendMoneyLoading = false - this.btnDisable = false - throw new Error(txnResponse) - } else { - this.errorMessage = response.message - this.sendMoneyLoading = false - this.btnDisable = false - throw new Error(response) - } - } - const res = await makeRequest() - manageResponse(res) - await this.showWallet() - } + const manageResponse = (response) => { + if (response.length === 64) { + this.shadowRoot.getElementById('btcAmountInput').value = 0 + this.shadowRoot.getElementById('btcRecipient').value = '' + this.errorMessage = '' + this.btcRecipient = '' + this.btcAmount = 0 + this.successMessage = this.renderSuccessText() + this.sendMoneyLoading = false + this.btnDisable = false + } else if (response === false) { + this.errorMessage = this.renderFailText() + this.sendMoneyLoading = false + this.btnDisable = false + throw new Error(txnResponse) + } else { + this.errorMessage = response.message + this.sendMoneyLoading = false + this.btnDisable = false + throw new Error(response) + } + } + const res = await makeRequest() + manageResponse(res) + await this.showWallet() + } - async sendLtc() { - const ltcAmount = this.shadowRoot.getElementById('ltcAmountInput').value - const ltcRecipient = this.shadowRoot.getElementById('ltcRecipient').value - const xprv58 = this.wallets.get(this._selectedWallet).wallet.derivedMasterPrivateKey + async sendLtc() { + const ltcAmount = this.shadowRoot.getElementById('ltcAmountInput').value + const ltcRecipient = this.shadowRoot.getElementById('ltcRecipient').value + const xprv58 = this.wallets.get(this._selectedWallet).wallet.derivedMasterPrivateKey - this.sendMoneyLoading = true - this.btnDisable = true + this.sendMoneyLoading = true + this.btnDisable = true - const makeRequest = async () => { - const opts = { - xprv58: xprv58, - receivingAddress: ltcRecipient, - litecoinAmount: ltcAmount, - feePerByte: (this.ltcFeePerByte / 1e8).toFixed(8), - } + const makeRequest = async () => { + const opts = { + xprv58: xprv58, + receivingAddress: ltcRecipient, + litecoinAmount: ltcAmount, + feePerByte: (this.ltcFeePerByte / 1e8).toFixed(8) + } return await parentEpml.request('sendLtc', opts) - } + } - const manageResponse = (response) => { - if (response.length === 64) { - this.shadowRoot.getElementById('ltcAmountInput').value = 0 - this.shadowRoot.getElementById('ltcRecipient').value = '' - this.errorMessage = '' - this.ltcRecipient = '' - this.ltcAmount = 0 - this.successMessage = this.renderSuccessText() - this.sendMoneyLoading = false - this.btnDisable = false - } else if (response === false) { - this.errorMessage = this.renderFailText() - this.sendMoneyLoading = false - this.btnDisable = false - throw new Error(txnResponse) - } else { - this.errorMessage = response.message - this.sendMoneyLoading = false - this.btnDisable = false - throw new Error(response) - } - } - const res = await makeRequest() - manageResponse(res) - await this.showWallet() - } + const manageResponse = (response) => { + if (response.length === 64) { + this.shadowRoot.getElementById('ltcAmountInput').value = 0 + this.shadowRoot.getElementById('ltcRecipient').value = '' + this.errorMessage = '' + this.ltcRecipient = '' + this.ltcAmount = 0 + this.successMessage = this.renderSuccessText() + this.sendMoneyLoading = false + this.btnDisable = false + } else if (response === false) { + this.errorMessage = this.renderFailText() + this.sendMoneyLoading = false + this.btnDisable = false + throw new Error(txnResponse) + } else { + this.errorMessage = response.message + this.sendMoneyLoading = false + this.btnDisable = false + throw new Error(response) + } + } + const res = await makeRequest() + manageResponse(res) + await this.showWallet() + } - async sendDoge() { - const dogeAmount = this.shadowRoot.getElementById('dogeAmountInput').value - let dogeRecipient = this.shadowRoot.getElementById('dogeRecipient').value - const xprv58 = this.wallets.get(this._selectedWallet).wallet.derivedMasterPrivateKey + async sendDoge() { + const dogeAmount = this.shadowRoot.getElementById('dogeAmountInput').value + let dogeRecipient = this.shadowRoot.getElementById('dogeRecipient').value + const xprv58 = this.wallets.get(this._selectedWallet).wallet.derivedMasterPrivateKey - this.sendMoneyLoading = true - this.btnDisable = true + this.sendMoneyLoading = true + this.btnDisable = true - const makeRequest = async () => { - const opts = { - xprv58: xprv58, - receivingAddress: dogeRecipient, - dogecoinAmount: dogeAmount, - feePerByte: (this.dogeFeePerByte / 1e8).toFixed(8), - } - return await parentEpml.request('sendDoge', opts) - } + const makeRequest = async () => { + const opts = { + xprv58: xprv58, + receivingAddress: dogeRecipient, + dogecoinAmount: dogeAmount, + feePerByte: (this.dogeFeePerByte / 1e8).toFixed(8) + } + return await parentEpml.request('sendDoge', opts) + } - const manageResponse = (response) => { - if (response.length === 64) { - this.shadowRoot.getElementById('dogeAmountInput').value = 0 - this.shadowRoot.getElementById('dogeRecipient').value = '' - this.errorMessage = '' - this.dogeRecipient = '' - this.dogeAmount = 0 - this.successMessage = this.renderSuccessText() - this.sendMoneyLoading = false - this.btnDisable = false - } else if (response === false) { - this.errorMessage = this.renderFailText() - this.sendMoneyLoading = false - this.btnDisable = false - throw new Error(txnResponse) - } else { - this.errorMessage = response.message - this.sendMoneyLoading = false - this.btnDisable = false - throw new Error(response) - } - } - const res = await makeRequest() - manageResponse(res) - await this.showWallet() - } + const manageResponse = (response) => { + if (response.length === 64) { + this.shadowRoot.getElementById('dogeAmountInput').value = 0 + this.shadowRoot.getElementById('dogeRecipient').value = '' + this.errorMessage = '' + this.dogeRecipient = '' + this.dogeAmount = 0 + this.successMessage = this.renderSuccessText() + this.sendMoneyLoading = false + this.btnDisable = false + } else if (response === false) { + this.errorMessage = this.renderFailText() + this.sendMoneyLoading = false + this.btnDisable = false + throw new Error(txnResponse) + } else { + this.errorMessage = response.message + this.sendMoneyLoading = false + this.btnDisable = false + throw new Error(response) + } + } + const res = await makeRequest() + manageResponse(res) + await this.showWallet() + } - async sendDgb() { - const dgbAmount = this.shadowRoot.getElementById('dgbAmountInput').value - let dgbRecipient = this.shadowRoot.getElementById('dgbRecipient').value - const xprv58 = this.wallets.get(this._selectedWallet).wallet.derivedMasterPrivateKey + async sendDgb() { + const dgbAmount = this.shadowRoot.getElementById('dgbAmountInput').value + let dgbRecipient = this.shadowRoot.getElementById('dgbRecipient').value + const xprv58 = this.wallets.get(this._selectedWallet).wallet.derivedMasterPrivateKey - this.sendMoneyLoading = true - this.btnDisable = true + this.sendMoneyLoading = true + this.btnDisable = true - const makeRequest = async () => { - const opts = { - xprv58: xprv58, - receivingAddress: dgbRecipient, - digibyteAmount: dgbAmount, - feePerByte: (this.dgbFeePerByte / 1e8).toFixed(8), - } - return await parentEpml.request('sendDgb', opts) - } + const makeRequest = async () => { + const opts = { + xprv58: xprv58, + receivingAddress: dgbRecipient, + digibyteAmount: dgbAmount, + feePerByte: (this.dgbFeePerByte / 1e8).toFixed(8) + } + return await parentEpml.request('sendDgb', opts) + } - const manageResponse = (response) => { - if (response.length === 64) { - this.shadowRoot.getElementById('dgbAmountInput').value = 0 - this.shadowRoot.getElementById('dgbRecipient').value = '' - this.errorMessage = '' - this.dgbRecipient = '' - this.dgbAmount = 0 - this.successMessage = this.renderSuccessText() - this.sendMoneyLoading = false - this.btnDisable = false - } else if (response === false) { - this.errorMessage = this.renderFailText() - this.sendMoneyLoading = false - this.btnDisable = false - throw new Error(txnResponse) - } else { - this.errorMessage = response.message - this.sendMoneyLoading = false - this.btnDisable = false - throw new Error(response) - } - } - const res = await makeRequest() - manageResponse(res) - await this.showWallet() - } + const manageResponse = (response) => { + if (response.length === 64) { + this.shadowRoot.getElementById('dgbAmountInput').value = 0 + this.shadowRoot.getElementById('dgbRecipient').value = '' + this.errorMessage = '' + this.dgbRecipient = '' + this.dgbAmount = 0 + this.successMessage = this.renderSuccessText() + this.sendMoneyLoading = false + this.btnDisable = false + } else if (response === false) { + this.errorMessage = this.renderFailText() + this.sendMoneyLoading = false + this.btnDisable = false + throw new Error(txnResponse) + } else { + this.errorMessage = response.message + this.sendMoneyLoading = false + this.btnDisable = false + throw new Error(response) + } + } + const res = await makeRequest() + manageResponse(res) + await this.showWallet() + } - async sendRvn() { - const rvnAmount = this.shadowRoot.getElementById('rvnAmountInput').value - let rvnRecipient = this.shadowRoot.getElementById('rvnRecipient').value - const xprv58 = this.wallets.get(this._selectedWallet).wallet.derivedMasterPrivateKey + async sendRvn() { + const rvnAmount = this.shadowRoot.getElementById('rvnAmountInput').value + let rvnRecipient = this.shadowRoot.getElementById('rvnRecipient').value + const xprv58 = this.wallets.get(this._selectedWallet).wallet.derivedMasterPrivateKey - this.sendMoneyLoading = true - this.btnDisable = true + this.sendMoneyLoading = true + this.btnDisable = true - const makeRequest = async () => { - const opts = { - xprv58: xprv58, - receivingAddress: rvnRecipient, - ravencoinAmount: rvnAmount, - feePerByte: (this.rvnFeePerByte / 1e8).toFixed(8), - } + const makeRequest = async () => { + const opts = { + xprv58: xprv58, + receivingAddress: rvnRecipient, + ravencoinAmount: rvnAmount, + feePerByte: (this.rvnFeePerByte / 1e8).toFixed(8) + } return await parentEpml.request('sendRvn', opts) - } - - const manageResponse = (response) => { - if (response.length === 64) { - this.shadowRoot.getElementById('rvnAmountInput').value = 0 - this.shadowRoot.getElementById('rvnRecipient').value = '' - this.errorMessage = '' - this.rvnRecipient = '' - this.rvnAmount = 0 - this.successMessage = this.renderSuccessText() - this.sendMoneyLoading = false - this.btnDisable = false - } else if (response === false) { - this.errorMessage = this.renderFailText() - this.sendMoneyLoading = false - this.btnDisable = false - throw new Error(txnResponse) - } else { - this.errorMessage = response.message - this.sendMoneyLoading = false - this.btnDisable = false - throw new Error(response) - } - } - const res = await makeRequest() - manageResponse(res) - await this.showWallet() - } - - async sendArrr() { - const arrrAmount = this.shadowRoot.getElementById('arrrAmountInput').value - let arrrRecipient = this.shadowRoot.getElementById('arrrRecipient').value - let arrrMemo = this.shadowRoot.getElementById('arrrMemo').value - const seed58 = this.wallets.get(this._selectedWallet).wallet.seed58 - - this.sendMoneyLoading = true - this.btnDisable = true - - const makeRequest = async () => { - const opts = { - entropy58: seed58, - receivingAddress: arrrRecipient, - arrrAmount: arrrAmount, - memo: arrrMemo - } - return await parentEpml.request('sendArrr', opts) - } - - const manageResponse = (response) => { - if (response.length === 64) { - this.shadowRoot.getElementById('arrrAmountInput').value = 0 - this.shadowRoot.getElementById('arrrRecipient').value = '' - this.shadowRoot.getElementById('arrrMemo').value = '' - this.errorMessage = '' - this.arrrRecipient = '' - this.arrrMemo='' - this.arrrAmount = 0 - this.successMessage = this.renderSuccessText() - this.sendMoneyLoading = false - this.btnDisable = false - } else if (response === false) { - this.errorMessage = this.renderFailText() - this.sendMoneyLoading = false - this.btnDisable = false - throw new Error(txnResponse) - } else { - this.errorMessage = response.message - this.sendMoneyLoading = false - this.btnDisable = false - throw new Error(response) - } - } - const res = await makeRequest() - manageResponse(res) - await this.showWallet() - } - - async showWallet() { - this.transactionsDOM.hidden = true - this.loading = true - - if (this._selectedWallet == 'qort') { - if (!window.parent.reduxStore.getState().app.blockInfo.height) { - await parentEpml.request('apiCall', { url: `/blocks/height`, type: 'api' }) - .then(height => parentEpml.request('updateBlockInfo', { height })) - } - } - const coin = this._selectedWallet - await this.fetchWalletAddress(this._selectedWallet) - await this.fetchWalletServer(this._selectedWallet) - await this.fetchWalletDetails(this._selectedWallet) - await this.fetchWalletServer(this._selectedWallet) - if (this._selectedWallet == coin) { - await this.renderTransactions() - await this.getTransactionGrid(this._selectedWallet) - await this.updateItemsFromPage(1, true) - this.loading = false - this.transactionsDOM.hidden = false - } - } - - async fetchWalletDetails(coin) { - switch (coin) { - case 'qort': - this.balanceString = this.renderFetchText() - parentEpml.request('apiCall', { - url: `/addresses/balance/${this.wallets.get('qort').wallet.address}?apiKey=${this.getApiKey()}`, - }) - .then((res) => { - if (isNaN(Number(res))) { - let snack4string = get("walletpage.wchange32") - parentEpml.request('showSnackBar', `${snack4string}`) - } else { - if (this._selectedWallet == coin) { - this.wallets.get(coin).balance = Number(res).toFixed(8) - this.balanceString = this.wallets.get(this._selectedWallet).balance + " " + this._selectedWallet.toLocaleUpperCase() - this.balance = this.wallets.get(this._selectedWallet).balance - } - } - }) - const txsQort = await parentEpml.request('apiCall', { - url: `/transactions/search?address=${this.wallets.get('qort').wallet.address}&confirmationStatus=CONFIRMED&reverse=true&txType=PAYMENT&txType=REGISTER_NAME&txType=UPDATE_NAME&txType=SELL_NAME&txType=CANCEL_SELL_NAME&txType=BUY_NAME&txType=CREATE_POLL&txType=VOTE_ON_POLL&txType=ARBITRARY&txType=ISSUE_ASSET&txType=TRANSFER_ASSET&txType=CREATE_ASSET_ORDER&txType=CANCEL_ASSET_ORDER&txType=MULTI_PAYMENT&txType=DEPLOY_AT&txType=MESSAGE&txType=AIRDROP&txType=AT&txType=CREATE_GROUP&txType=UPDATE_GROUP&txType=ADD_GROUP_ADMIN&txType=REMOVE_GROUP_ADMIN&txType=GROUP_BAN&txType=CANCEL_GROUP_BAN&txType=GROUP_KICK&txType=GROUP_INVITE&txType=CANCEL_GROUP_INVITE&txType=JOIN_GROUP&txType=LEAVE_GROUP&txType=GROUP_APPROVAL&txType=SET_GROUP&txType=UPDATE_ASSET&txType=ACCOUNT_FLAGS&txType=ENABLE_FORGING&txType=REWARD_SHARE&txType=ACCOUNT_LEVEL&txType=TRANSFER_PRIVS&txType=PRESENCE`, - }) - const pendingTxsQort = await parentEpml.request('apiCall', { - url: `/transactions/unconfirmed?creator=${this.wallets.get('qort').wallet.base58PublicKey}&reverse=true&txType=PAYMENT&txType=REGISTER_NAME&txType=UPDATE_NAME&txType=SELL_NAME&txType=CANCEL_SELL_NAME&txType=BUY_NAME&txType=CREATE_POLL&txType=VOTE_ON_POLL&txType=ARBITRARY&txType=ISSUE_ASSET&txType=TRANSFER_ASSET&txType=CREATE_ASSET_ORDER&txType=CANCEL_ASSET_ORDER&txType=MULTI_PAYMENT&txType=DEPLOY_AT&txType=MESSAGE&txType=AIRDROP&txType=AT&txType=CREATE_GROUP&txType=UPDATE_GROUP&txType=ADD_GROUP_ADMIN&txType=REMOVE_GROUP_ADMIN&txType=GROUP_BAN&txType=CANCEL_GROUP_BAN&txType=GROUP_KICK&txType=GROUP_INVITE&txType=CANCEL_GROUP_INVITE&txType=JOIN_GROUP&txType=LEAVE_GROUP&txType=GROUP_APPROVAL&txType=SET_GROUP&txType=UPDATE_ASSET&txType=ACCOUNT_FLAGS&txType=ENABLE_FORGING&txType=REWARD_SHARE&txType=ACCOUNT_LEVEL&txType=TRANSFER_PRIVS&txType=PRESENCE`, - }) - if (this._selectedWallet == coin) { - this.wallets.get(coin).transactions = pendingTxsQort.concat(txsQort) - } - break - case 'btc': - case 'ltc': - case 'doge': - case 'dgb': - case 'rvn': - this.balanceString = this.renderFetchText() - const walletName = `${coin}Wallet` - parentEpml.request('apiCall', { - url: `/crosschain/${coin}/walletbalance?apiKey=${this.getApiKey()}`, - method: 'POST', - body: `${window.parent.reduxStore.getState().app.selectedAddress[walletName].derivedMasterPublicKey}`, - }) - .then((res) => { - if (isNaN(Number(res))) { - let snack5string = get("walletpage.wchange33") - let snack6string = get("walletpage.wchange34") - parentEpml.request('showSnackBar', `${snack5string} ${coin.toLocaleUpperCase()} ${snack6string}!`) - } else { - if (this._selectedWallet == coin) { - this.wallets.get(this._selectedWallet).balance = (Number(res) / 1e8).toFixed(8) - this.balanceString = this.wallets.get(this._selectedWallet).balance + " " + this._selectedWallet.toLocaleUpperCase() - this.balance = this.wallets.get(this._selectedWallet).balance - } - } - }) - - const txs = await parentEpml.request('apiCall', { - url: `/crosschain/${coin}/wallettransactions?apiKey=${this.getApiKey()}`, - method: 'POST', - body: `${window.parent.reduxStore.getState().app.selectedAddress[walletName].derivedMasterPublicKey}`, - }) - - const compareFn = (a, b) => { - return b.timestamp - a.timestamp - } - - const sortedTransactions = txs.sort(compareFn) - if (this._selectedWallet == coin) { - this.wallets.get(this._selectedWallet).transactions = sortedTransactions - } - break - case 'arrr': - const arrrWalletName = `${coin}Wallet` - - const res = await parentEpml.request('apiCall', { - url: `/crosschain/${coin}/syncstatus?apiKey=${this.getApiKey()}`, - method: 'POST', - body: `${window.parent.reduxStore.getState().app.selectedAddress[arrrWalletName].seed58}`, - }) - - if (coin != this._selectedWallet) { - // We've switched away from this coin - } - - if (res.indexOf('<') > -1) { - this.balanceString = this.renderFetchText() - await new Promise(resolve => setTimeout(resolve, 2000)) - await this.showWallet() - return - } else if (res !== "Synchronized") { - this.balanceString = res - await new Promise(resolve => setTimeout(resolve, 2000)) - await this.showWallet() - return - } - - this.balanceString = this.renderFetchText() - - parentEpml.request('apiCall', { - url: `/crosschain/${coin}/walletbalance?apiKey=${this.getApiKey()}`, - method: 'POST', - body: `${window.parent.reduxStore.getState().app.selectedAddress[arrrWalletName].seed58}`, - }) - .then((res) => { - if (isNaN(Number(res))) { - let snack5string = get("walletpage.wchange33") - let snack6string = get("walletpage.wchange34") - parentEpml.request('showSnackBar', `${snack5string} ${coin.toLocaleUpperCase()} ${snack6string}!`) - } else { - if (this._selectedWallet == coin) { - this.wallets.get(this._selectedWallet).balance = (Number(res) / 1e8).toFixed(8) - this.balanceString = this.wallets.get(this._selectedWallet).balance + " " + this._selectedWallet.toLocaleUpperCase() - this.balance = this.wallets.get(this._selectedWallet).balance - } - } - }) - - const arrrTxs = await parentEpml.request('apiCall', { - url: `/crosschain/${coin}/wallettransactions?apiKey=${this.getApiKey()}`, - method: 'POST', - body: `${window.parent.reduxStore.getState().app.selectedAddress[arrrWalletName].seed58}`, - }) - - const arrrCompareFn = (a, b) => { - return b.timestamp - a.timestamp - } - - const arrrSortedTransactions = arrrTxs.sort(arrrCompareFn) - - if (this._selectedWallet == coin) { - this.wallets.get(this._selectedWallet).transactions = arrrSortedTransactions - } - break - default: - break - } - } - - async fetchWalletAddress(coin) { - switch (coin) { - case 'arrr': - const arrrWalletName = `${coin}Wallet` - let res = await parentEpml.request('apiCall', { - url: `/crosschain/${coin}/walletaddress?apiKey=${this.getApiKey()}`, - method: 'POST', - body: `${window.parent.reduxStore.getState().app.selectedAddress[arrrWalletName].seed58}`, - }) - if (res != null && res.error != 1201 && res.length === 78) { - this.arrrWalletAddress = res - } - break - - default: - // Not used for other coins yet - break - } - } - - renderSendButton() { - if ( this._selectedWallet === "qort" ) { - return html` this.openSendQort()}> ${translate("walletpage.wchange17")} QORT` - } else if ( this._selectedWallet === "btc" ) { - return html` this.openSendBtc()}> ${translate("walletpage.wchange17")} BTC` - } else if ( this._selectedWallet === "ltc" ) { - return html` this.openSendLtc()}> ${translate("walletpage.wchange17")} LTC` - } else if ( this._selectedWallet === "doge" ) { - return html` this.openSendDoge()}> ${translate("walletpage.wchange17")} DOGE` - } else if ( this._selectedWallet === "dgb" ) { - return html` this.openSendDgb()}> ${translate("walletpage.wchange17")} DGB` - } else if ( this._selectedWallet === "rvn" ) { - return html` this.openSendRvn()}> ${translate("walletpage.wchange17")} RVN` - } else if ( this._selectedWallet === "arrr" ) { - return html` this.openSendArrr()}> ${translate("walletpage.wchange17")} ARRR` - } else { - return html`` - } - } - - renderAddressbookButton() { - if ( this._selectedWallet === "qort" ) { - return html` this.openQortAddressbook()}> ${translate("walletpage.wchange47")}` - } else if ( this._selectedWallet === "btc" ) { - return html` this.openBtcAddressbook()}> ${translate("walletpage.wchange47")}` - } else if ( this._selectedWallet === "ltc" ) { - return html` this.openLtcAddressbook()}> ${translate("walletpage.wchange47")}` - } else if ( this._selectedWallet === "doge" ) { - return html` this.openDogeAddressbook()}> ${translate("walletpage.wchange47")}` - } else if ( this._selectedWallet === "dgb" ) { - return html` this.openDgbAddressbook()}> ${translate("walletpage.wchange47")}` - } else if ( this._selectedWallet === "rvn" ) { - return html` this.openRvnAddressbook()}> ${translate("walletpage.wchange47")}` - } else if ( this._selectedWallet === "arrr" ) { - return html` this.openArrrAddressbook()}> ${translate("walletpage.wchange47")}` - } else { - return html`` - } - } - - renderExportAddressbookButton() { - if ( this._selectedWallet === "qort" ) { - return html` this.exportQortAddressbook()}> ${translate("walletpage.wchange54")}` - } else if ( this._selectedWallet === "btc" ) { - return html` this.exportBtcAddressbook()}> ${translate("walletpage.wchange54")}` - } else if ( this._selectedWallet === "ltc" ) { - return html` this.exportLtcAddressbook()}> ${translate("walletpage.wchange54")}` - } else if ( this._selectedWallet === "doge" ) { - return html` this.exportDogeAddressbook()}> ${translate("walletpage.wchange54")}` - } else if ( this._selectedWallet === "dgb" ) { - return html` this.exportDgbAddressbook()}> ${translate("walletpage.wchange54")}` - } else if ( this._selectedWallet === "rvn" ) { - return html` this.exportRvnAddressbook()}> ${translate("walletpage.wchange54")}` - } else if ( this._selectedWallet === "arrr" ) { - return html` this.exportArrrAddressbook()}> ${translate("walletpage.wchange54")}` - } else { - return html`` - } - } - - renderImportAddressbookButton() { - if ( this._selectedWallet === "qort" ) { - return html` this.openImportQortAddressbook()}> ${translate("walletpage.wchange53")}` - } else if ( this._selectedWallet === "btc" ) { - return html` this.openImportBtcAddressbook()}> ${translate("walletpage.wchange53")}` - } else if ( this._selectedWallet === "ltc" ) { - return html` this.openImportLtcAddressbook()}> ${translate("walletpage.wchange53")}` - } else if ( this._selectedWallet === "doge" ) { - return html` this.openImportDogeAddressbook()}> ${translate("walletpage.wchange53")}` - } else if ( this._selectedWallet === "dgb" ) { - return html` this.openImportDgbAddressbook()}> ${translate("walletpage.wchange53")}` - } else if ( this._selectedWallet === "rvn" ) { - return html` this.openImportRvnAddressbook()}> ${translate("walletpage.wchange53")}` - } else if ( this._selectedWallet === "arrr" ) { - return html` this.openImportArrrAddressbook()}> ${translate("walletpage.wchange53")}` - } else { - return html`` - } - } - - openSendQort() { - this.shadowRoot.querySelector("#sendQortDialog").show(); - } - - openSendBtc() { - this.shadowRoot.querySelector("#sendBtcDialog").show(); - } - - openSendLtc() { - this.shadowRoot.querySelector("#sendLtcDialog").show(); - } - - openSendDoge() { - this.shadowRoot.querySelector("#sendDogeDialog").show(); - } - - openSendDgb() { - this.shadowRoot.querySelector("#sendDgbDialog").show(); - } - - openSendRvn() { - this.shadowRoot.querySelector("#sendRvnDialog").show(); - } - - openSendArrr() { - this.shadowRoot.querySelector("#sendArrrDialog").show(); - } - - changeTheme() { - const checkTheme = localStorage.getItem('qortalTheme') - if (checkTheme === 'dark') { - this.theme = 'dark'; - } else { - this.theme = 'light'; - } - document.querySelector('html').setAttribute('theme', this.theme); - } - - changeLanguage() { - const checkLanguage = localStorage.getItem('qortalLanguage') - - if (checkLanguage === null || checkLanguage.length === 0) { - localStorage.setItem('qortalLanguage', 'us') - use('us') - } else { - use(checkLanguage) - } - } - - getSelectedWalletAddress() { - switch (this._selectedWallet) { - case "arrr": - // Use address returned by core API - return this.arrrWalletAddress - - default: - // Use locally derived address - return this.wallets.get(this._selectedWallet).wallet.address - } - } - - getSelectedWalletServer() { - switch (this._selectedWallet) { - case "qort": - return this.nodeDomain - - case "btc": - return this.btcServer - - case "ltc": - return this.ltcServer - - case "doge": - return this.dogeServer - - case "dgb": - return this.dgbServer - - case "rvn": - return this.rvnServer - - case "arrr": - return this.arrrServer - - default: - return - } - } - - async fetchWalletServer(coin) { - if (coin == 'qort') { - return - } - let walletServer = '' - try { - const serverInfo = await parentEpml.request('apiCall', { - type: 'api', - /* TODO */ - url: `/crosschain/${coin}/serverinfos`, - // TODO when 'current' parameter is added to 'serverinfos' API call, change above line to: - // url: `/crosschain/${coin}/serverinfos?current=true`, - }) - /* TODO */ - let currentServerFound = false - for (const server of serverInfo.servers) { - if (server.isCurrent === true) { - walletServer = `${server.hostName}:${server.port}` - currentServerFound = true - break - } - } - if (!currentServerFound) { - walletServer = 'Not Connected' - } - // TODO when 'current' parameter is added to 'serverinfos' API call, change above 'let,for,if' sections to: - /*if (serverInfo.servers[0]) { - const currentServerInfo = `${serverInfo.servers[0].hostName}:${serverInfo.servers[0].port}` - walletServer = currentServerInfo - } else { - walletServer = 'Not Connected' - }*/ - } catch (error) { - console.error('Failed to fetch server info:', error) - walletServer = `Error fetching server: ${error}` - } - switch (coin) { - case "btc": - this.btcServer = walletServer - break - case "ltc": - this.ltcServer = walletServer - break - case "doge": - this.dogeServer = walletServer - break - case "dgb": - this.dgbServer = walletServer - break - case "rvn": - this.rvnServer = walletServer - break - case "arrr": - this.arrrServer = walletServer - break - default: - break - } - } - - getNodeConfig() { - this.nodeDomain = "" - const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] - this.nodeDomain = myNode.domain + ":" + myNode.port - - this.nodeConfig = {} - parentEpml.request("getNodeConfig").then((res) => { - this.nodeConfig = res - }) - } - - async getTransactionGrid(coin) { - this.transactionsGrid = this.shadowRoot.querySelector(`#${coin}TransactionsGrid`) - if (coin === 'qort') { - this.transactionsGrid.addEventListener( - 'click', - (e) => { - let qortItem = this.transactionsGrid.getEventContext(e).item - this.showQortTransactionDetails(qortItem, this.wallets.get(this._selectedWallet).transactions) - }, - { passive: true } - ) - } else if (coin === 'btc') { - this.transactionsGrid.addEventListener( - 'click', - (e) => { - let btcItem = this.transactionsGrid.getEventContext(e).item - this.showBtcTransactionDetails(btcItem, this.wallets.get(this._selectedWallet).transactions) - }, - { passive: true } - ) - } else if (coin === 'ltc') { - this.transactionsGrid.addEventListener( - 'click', - (e) => { - let ltcItem = this.transactionsGrid.getEventContext(e).item - this.showLtcTransactionDetails(ltcItem, this.wallets.get(this._selectedWallet).transactions) - }, - { passive: true } - ) - } else if (coin === 'doge') { - this.transactionsGrid.addEventListener( - 'click', - (e) => { - let dogeItem = this.transactionsGrid.getEventContext(e).item - this.showDogeTransactionDetails(dogeItem, this.wallets.get(this._selectedWallet).transactions) - }, - { passive: true } - ) - } else if (coin === 'dgb') { - this.transactionsGrid.addEventListener( - 'click', - (e) => { - let dgbItem = this.transactionsGrid.getEventContext(e).item - this.showDgbTransactionDetails(dgbItem, this.wallets.get(this._selectedWallet).transactions) - }, - { passive: true } - ) - } else if (coin === 'rvn') { - this.transactionsGrid.addEventListener( - 'click', - (e) => { - let rvnItem = this.transactionsGrid.getEventContext(e).item - this.showRvnTransactionDetails(rvnItem, this.wallets.get(this._selectedWallet).transactions) - }, - { passive: true } - ) - } else if (coin === 'arrr') { - this.transactionsGrid.addEventListener( - 'click', - (e) => { - let arrrItem = this.transactionsGrid.getEventContext(e).item - this.showArrrTransactionDetails(arrrItem, this.wallets.get(this._selectedWallet).transactions) - }, - { passive: true } - ) - } - - this.pagesControl = this.shadowRoot.querySelector('#pages') - this.pages = undefined - } - - async renderTransactions() { - if (this._selectedWallet === 'qort') { - render(this.renderQortTransactions(this.wallets.get(this._selectedWallet).transactions, this._selectedWallet), this.transactionsDOM) - } else if (this._selectedWallet === 'btc') { - render(this.renderBtcTransactions(this.wallets.get(this._selectedWallet).transactions, this._selectedWallet), this.transactionsDOM) - } else if (this._selectedWallet === 'ltc') { - render(this.renderLtcTransactions(this.wallets.get(this._selectedWallet).transactions, this._selectedWallet), this.transactionsDOM) - } else if (this._selectedWallet === 'doge') { - render(this.renderDogeTransactions(this.wallets.get(this._selectedWallet).transactions, this._selectedWallet), this.transactionsDOM) - } else if (this._selectedWallet === 'dgb') { - render(this.renderDgbTransactions(this.wallets.get(this._selectedWallet).transactions, this._selectedWallet), this.transactionsDOM) - } else if (this._selectedWallet === 'rvn') { - render(this.renderRvnTransactions(this.wallets.get(this._selectedWallet).transactions, this._selectedWallet), this.transactionsDOM) - } else if (this._selectedWallet === 'arrr') { - render(this.renderArrrTransactions(this.wallets.get(this._selectedWallet).transactions, this._selectedWallet), this.transactionsDOM) - } - } - - renderQortTransactions(transactions, coin) { - const requiredConfirmations = 3 - const currentBlockHeight = window.parent.reduxStore.getState().app.blockInfo.height - if (Array.isArray(transactions)) { - transactions = transactions.map(tx => { - tx.confirmations = (currentBlockHeight - (tx.blockHeight - 1)) || '' - return tx - }) - } - - return html` -
    ${translate("walletpage.wchange38")}
    - - { - if (!currentBlockHeight) { - return render(html``, root) - } - const confirmed = data.item.confirmations >= requiredConfirmations - const unconfirmed = data.item.confirmations == 0 - if (confirmed) { - render(html`check`, root) - } else if (unconfirmed) { - render(html`schedule`, root) - } else { - render(html`schedule`, root) - } - }} - > - - { - render(html` ${data.item.type} ${data.item.creatorAddress === this.wallets.get('qort').wallet.address ? html`${translate("walletpage.wchange7")}` : html`${translate("walletpage.wchange8")}`} `, root) - }} - > - - { - render(html`${data.item.type === 'AT' ? html`${data.item.atAddress}` : html`${data.item.creatorAddress}`}`, root) - }} - > - - { - render(html`${data.item.type === 'DEPLOY_AT' ? html`${data.item.aTAddress}` : html`${data.item.recipient}`}`, root) - }} - > - - - - { - const time = new Date(data.item.timestamp) - render(html` `, root) - }} - > - - -
    - ` - } - - renderBtcTransactions(transactions, coin) { - return html` -
    ${translate("walletpage.wchange38")}
    - - { - render(html`check`, root) - }} - > - - { - render(html` ${translate("walletpage.wchange40")} ${data.item.inputs[0].address === this.wallets.get(this._selectedWallet).wallet.address ? html`${translate("walletpage.wchange7")}` : html`${translate("walletpage.wchange8")}`} `, root) - }} - > - - { - render(html`${data.item.inputs[0].address}`, root) - }} - > - - { - render(html`${data.item.outputs[0].address}`, root) - }} - > - - - { - const amount = (Number(data.item.totalAmount) / 1e8).toFixed(8) - render(html`${amount}`, root) - }} - > - - { - const time = new Date(data.item.timestamp) - render(html` `, root) - }} - > - - -
    - ` - } - - renderLtcTransactions(transactions, coin) { - return html` -
    ${translate("walletpage.wchange38")}
    - - { - render(html`check`, root) - }} - > - - { - render(html` ${translate("walletpage.wchange40")} ${data.item.inputs[0].address === this.wallets.get(this._selectedWallet).wallet.address ? html`${translate("walletpage.wchange7")}` : html`${translate("walletpage.wchange8")}`} `, root) - }} - > - - { - render(html`${data.item.inputs[0].address}`, root) - }} - > - - { - render(html`${data.item.outputs[0].address}`, root) - }} - > - - - { - const amount = (Number(data.item.totalAmount) / 1e8).toFixed(8) - render(html`${amount}`, root) - }} - > - - { - const time = new Date(data.item.timestamp) - render(html` `, root) - }} - > - - -
    - ` - } - - renderDogeTransactions(transactions, coin) { - return html` -
    ${translate("walletpage.wchange38")}
    - - { - render(html`check`, root) - }} - > - - { - render(html` ${translate("walletpage.wchange40")} ${data.item.inputs[0].address === this.wallets.get(this._selectedWallet).wallet.address ? html`${translate("walletpage.wchange7")}` : html`${translate("walletpage.wchange8")}`} `, root) - }} - > - - { - render(html`${data.item.inputs[0].address}`, root) - }} - > - - { - render(html`${data.item.outputs[0].address}`, root) - }} - > - - - { - const amount = (Number(data.item.totalAmount) / 1e8).toFixed(8) - render(html`${amount}`, root) - }} - > - - { - const time = new Date(data.item.timestamp) - render(html` `, root) - }} - > - - -
    - ` - } - - renderDgbTransactions(transactions, coin) { - return html` -
    ${translate("walletpage.wchange38")}
    - - { - render(html`check`, root) - }} - > - - { - render(html` ${translate("walletpage.wchange40")} ${data.item.inputs[0].address === this.wallets.get(this._selectedWallet).wallet.address ? html`${translate("walletpage.wchange7")}` : html`${translate("walletpage.wchange8")}`} `, root) - }} - > - - { - render(html`${data.item.inputs[0].address}`, root) - }} - > - - { - render(html`${data.item.outputs[0].address}`, root) - }} - > - - - { - const amount = (Number(data.item.totalAmount) / 1e8).toFixed(8) - render(html`${amount}`, root) - }} - > - - { - const time = new Date(data.item.timestamp) - render(html` `, root) - }} - > - - -
    - ` - } - - renderRvnTransactions(transactions, coin) { - return html` -
    ${translate("walletpage.wchange38")}
    - - { - render(html`check`, root) - }} - > - - { - render(html` ${translate("walletpage.wchange40")} ${data.item.inputs[0].address === this.wallets.get(this._selectedWallet).wallet.address ? html`${translate("walletpage.wchange7")}` : html`${translate("walletpage.wchange8")}`} `, root) - }} - > - - { - render(html`${data.item.inputs[0].address}`, root) - }} - > - - { - render(html`${data.item.outputs[0].address}`, root) - }} - > - - - { - const amount = (Number(data.item.totalAmount) / 1e8).toFixed(8) - render(html`${amount}`, root) - }} - > - - { - const time = new Date(data.item.timestamp) - render(html` `, root) - }} - > - - -
    - ` - } - - renderArrrTransactions(transactions, coin) { - return html` -
    ${translate("walletpage.wchange38")}
    - - { - render(html`check`, root) - }} - > - - { - render(html` ${translate("walletpage.wchange40")} ${data.item.totalAmount < 0 ? html`${translate("walletpage.wchange7")}` : html`${translate("walletpage.wchange8")}`} `, root) - }} - > - - - - { - const amount = (Number(data.item.totalAmount) / 1e8).toFixed(8) - render(html`${amount}`, root) - }} - > - - { - const time = new Date(data.item.timestamp) - render(html` `, root) - }} - > - - { - render(html`${data.item.memo}`, root) - }} - > - - -
    - ` - } - - async updateItemsFromPage(page, changeWallet = false) { - if (page === undefined) { - return - } - - changeWallet === true ? (this.pagesControl.innerHTML = '') : null - - if (!this.pages) { - this.pages = Array.apply(null, { length: Math.ceil(this.wallets.get(this._selectedWallet).transactions.length / this.transactionsGrid.pageSize) }).map((item, index) => { - return index + 1 - }) - - const prevBtn = document.createElement('button') - prevBtn.textContent = '<' - prevBtn.addEventListener('click', () => { - const selectedPage = parseInt(this.pagesControl.querySelector('[selected]').textContent) - this.updateItemsFromPage(selectedPage - 1) - }) - this.pagesControl.appendChild(prevBtn) - - this.pages.forEach((pageNumber) => { - const pageBtn = document.createElement('button') - pageBtn.textContent = pageNumber - pageBtn.addEventListener('click', (e) => { - this.updateItemsFromPage(parseInt(e.target.textContent)) - }) - if (pageNumber === page) { - pageBtn.setAttribute('selected', true) - } - this.pagesControl.appendChild(pageBtn) - }) - - const nextBtn = window.document.createElement('button') - nextBtn.textContent = '>' - nextBtn.addEventListener('click', () => { - const selectedPage = parseInt(this.pagesControl.querySelector('[selected]').textContent) - this.updateItemsFromPage(selectedPage + 1) - }) - this.pagesControl.appendChild(nextBtn) - } - - const buttons = Array.from(this.pagesControl.children) - buttons.forEach((btn, index) => { - if (parseInt(btn.textContent) === page) { - btn.setAttribute('selected', true) - } else { - btn.removeAttribute('selected') - } - if (index === 0) { - if (page === 1) { - btn.setAttribute('disabled', '') - } else { - btn.removeAttribute('disabled') - } - } - if (index === buttons.length - 1) { - if (page === this.pages.length) { - btn.setAttribute('disabled', '') - } else { - btn.removeAttribute('disabled') - } - } - }) - let start = (page - 1) * this.transactionsGrid.pageSize - let end = page * this.transactionsGrid.pageSize - - this.transactionsGrid.items = this.wallets.get(this._selectedWallet).transactions.slice(start, end) - } - - getApiKey() { - const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] - return myNode.apiKey - } - - transactionItem(transactionObject) { - return ` -
    -
    -

    ${transactionObject.name}

    - ${transactionObject.category} ${transactionObject.ID} - ${transactionObject.date} -
    -
    -

    ${transactionObject.amount}

    -
    -
    - ` - } - - showQortTransactionDetails(myTransaction, allTransactions) { - allTransactions.forEach((transaction) => { - if (myTransaction.signature === transaction.signature) { - let txnFlow = myTransaction.creatorAddress === this.wallets.get('qort').wallet.address ? 'OUT' : 'IN' - this.selectedTransaction = { ...transaction, txnFlow } - if (this.selectedTransaction.signature.length != 0) { - this.shadowRoot.querySelector('#showTransactionDetailsDialog').show() - } - } - }) - } - - showBtcTransactionDetails(myTransaction, allTransactions) { - allTransactions.forEach((transaction) => { - if (myTransaction.txHash === transaction.txHash) { - let btcTxnFlow = myTransaction.inputs[0].address === this.wallets.get(this._selectedWallet).wallet.address ? 'OUT' : 'IN' - let btcSender = myTransaction.inputs[0].address - let btcReceiver = myTransaction.outputs[0].address - this.selectedTransaction = { ...transaction, btcTxnFlow, btcSender, btcReceiver } - if (this.selectedTransaction.txHash.length != 0) { - this.shadowRoot.querySelector('#showBtcTransactionDetailsDialog').show() - } - } - }) - } - - showLtcTransactionDetails(myTransaction, allTransactions) { - allTransactions.forEach((transaction) => { - if (myTransaction.txHash === transaction.txHash) { - let ltcTxnFlow = myTransaction.inputs[0].address === this.wallets.get(this._selectedWallet).wallet.address ? 'OUT' : 'IN' - let ltcSender = myTransaction.inputs[0].address - let ltcReceiver = myTransaction.outputs[0].address - this.selectedTransaction = { ...transaction, ltcTxnFlow, ltcSender, ltcReceiver } - if (this.selectedTransaction.txHash.length != 0) { - this.shadowRoot.querySelector('#showLtcTransactionDetailsDialog').show() - } - } - }) - } - - showDogeTransactionDetails(myTransaction, allTransactions) { - allTransactions.forEach((transaction) => { - if (myTransaction.txHash === transaction.txHash) { - let dogeTxnFlow = myTransaction.inputs[0].address === this.wallets.get(this._selectedWallet).wallet.address ? 'OUT' : 'IN' - let dogeSender = myTransaction.inputs[0].address - let dogeReceiver = myTransaction.outputs[0].address - this.selectedTransaction = { ...transaction, dogeTxnFlow, dogeSender, dogeReceiver } - if (this.selectedTransaction.txHash.length != 0) { - this.shadowRoot.querySelector('#showDogeTransactionDetailsDialog').show() - } - } - }) - } - - showDgbTransactionDetails(myTransaction, allTransactions) { - allTransactions.forEach((transaction) => { - if (myTransaction.txHash === transaction.txHash) { - let dgbTxnFlow = myTransaction.inputs[0].address === this.wallets.get(this._selectedWallet).wallet.address ? 'OUT' : 'IN' - let dgbSender = myTransaction.inputs[0].address - let dgbReceiver = myTransaction.outputs[0].address - this.selectedTransaction = { ...transaction, dgbTxnFlow, dgbSender, dgbReceiver } - if (this.selectedTransaction.txHash.length != 0) { - this.shadowRoot.querySelector('#showDgbTransactionDetailsDialog').show() - } - } - }) - } - - showRvnTransactionDetails(myTransaction, allTransactions) { - allTransactions.forEach((transaction) => { - if (myTransaction.txHash === transaction.txHash) { - let rvnTxnFlow = myTransaction.inputs[0].address === this.wallets.get(this._selectedWallet).wallet.address ? 'OUT' : 'IN' - let rvnSender = myTransaction.inputs[0].address - let rvnReceiver = myTransaction.outputs[0].address - this.selectedTransaction = { ...transaction, rvnTxnFlow, rvnSender, rvnReceiver } - if (this.selectedTransaction.txHash.length != 0) { - this.shadowRoot.querySelector('#showRvnTransactionDetailsDialog').show() - } - } - }) - } - - showArrrTransactionDetails(myTransaction, allTransactions) { - allTransactions.forEach((transaction) => { - if (myTransaction.txHash === transaction.txHash) { - let arrrTxnFlow = myTransaction.inputs[0].address === this.wallets.get(this._selectedWallet).wallet.address ? 'OUT' : 'IN' - let arrrSender = myTransaction.inputs[0].address - let arrrReceiver = myTransaction.outputs[0].address - this.selectedTransaction = { ...transaction, arrrTxnFlow, arrrSender, arrrReceiver } - if (this.selectedTransaction.txHash.length != 0) { - this.shadowRoot.querySelector('#showArrrTransactionDetailsDialog').show() - } - } - }) - } - - async saveFileToDisk(blob, fileName) { - try { - const fileHandle = await self.showSaveFilePicker({ - suggestedName: fileName, - types: [{ - description: "File", - }] - }) - const writeFile = async (fileHandle, contents) => { - const writable = await fileHandle.createWritable() - await writable.write(contents) - await writable.close() - } - writeFile(fileHandle, blob).then(() => console.log("FILE SAVED")) - let snack4string = get("general.save") - parentEpml.request('showSnackBar', `${snack4string} ${fileName} ✅`) - } catch (error) { - if (error.name === 'AbortError') { - return - } - FileSaver.saveAs(blob, fileName) - } - } - - isEmptyArray(arr) { - if (!arr) { - return true - } - return arr.length === 0 - } - - floor(num) { - num = parseFloat(num) - return isNaN(num) ? 0 : this._format(Math.floor(num)) - } - - decimals(num) { - num = parseFloat(num) - return num % 1 > 0 ? (num + '').split('.')[1] : '0' - } - - round(number) { - return (Math.round(parseFloat(number) * 1e8) / 1e8).toFixed(8) - } - - subtract(num1, num2) { - return num1 - num2 - } - - getConfirmations(height, lastBlockHeight) { - return lastBlockHeight - height + 1 - } - - _format(num) { - return num.toLocaleString() - } - - _unconfirmedClass(unconfirmed) { - return unconfirmed ? 'unconfirmed' : '' - } + } + + const manageResponse = (response) => { + if (response.length === 64) { + this.shadowRoot.getElementById('rvnAmountInput').value = 0 + this.shadowRoot.getElementById('rvnRecipient').value = '' + this.errorMessage = '' + this.rvnRecipient = '' + this.rvnAmount = 0 + this.successMessage = this.renderSuccessText() + this.sendMoneyLoading = false + this.btnDisable = false + } else if (response === false) { + this.errorMessage = this.renderFailText() + this.sendMoneyLoading = false + this.btnDisable = false + throw new Error(txnResponse) + } else { + this.errorMessage = response.message + this.sendMoneyLoading = false + this.btnDisable = false + throw new Error(response) + } + } + const res = await makeRequest() + manageResponse(res) + await this.showWallet() + } + + async sendArrr() { + const arrrAmount = this.shadowRoot.getElementById('arrrAmountInput').value + let arrrRecipient = this.shadowRoot.getElementById('arrrRecipient').value + let arrrMemo = this.shadowRoot.getElementById('arrrMemo').value + const seed58 = this.wallets.get(this._selectedWallet).wallet.seed58 + + this.sendMoneyLoading = true + this.btnDisable = true + + const makeRequest = async () => { + const opts = { + entropy58: seed58, + receivingAddress: arrrRecipient, + arrrAmount: arrrAmount, + memo: arrrMemo + } + return await parentEpml.request('sendArrr', opts) + } + + const manageResponse = (response) => { + if (response.length === 64) { + this.shadowRoot.getElementById('arrrAmountInput').value = 0 + this.shadowRoot.getElementById('arrrRecipient').value = '' + this.shadowRoot.getElementById('arrrMemo').value = '' + this.errorMessage = '' + this.arrrRecipient = '' + this.arrrMemo = '' + this.arrrAmount = 0 + this.successMessage = this.renderSuccessText() + this.sendMoneyLoading = false + this.btnDisable = false + } else if (response === false) { + this.errorMessage = this.renderFailText() + this.sendMoneyLoading = false + this.btnDisable = false + throw new Error(txnResponse) + } else { + this.errorMessage = response.message + this.sendMoneyLoading = false + this.btnDisable = false + throw new Error(response) + } + } + const res = await makeRequest() + manageResponse(res) + await this.showWallet() + } + + async showWallet() { + this.transactionsDOM.hidden = true + this.loading = true + + if (this._selectedWallet == 'qort') { + if (!window.parent.reduxStore.getState().app.blockInfo.height) { + await parentEpml.request('apiCall', { url: `/blocks/height`, type: 'api' }) + .then(height => parentEpml.request('updateBlockInfo', { height })) + } + } + const coin = this._selectedWallet + await this.fetchWalletAddress(this._selectedWallet) + await this.fetchWalletServer(this._selectedWallet) + await this.fetchWalletDetails(this._selectedWallet) + await this.fetchWalletServer(this._selectedWallet) + if (this._selectedWallet == coin) { + await this.renderTransactions() + await this.getTransactionGrid(this._selectedWallet) + await this.updateItemsFromPage(1, true) + this.loading = false + this.transactionsDOM.hidden = false + } + } + + async fetchWalletDetails(coin) { + switch (coin) { + case 'qort': + this.balanceString = this.renderFetchText() + parentEpml.request('apiCall', { + url: `/addresses/balance/${this.wallets.get('qort').wallet.address}?apiKey=${this.getApiKey()}` + }).then((res) => { + if (isNaN(Number(res))) { + let snack4string = get("walletpage.wchange32") + parentEpml.request('showSnackBar', `${snack4string}`) + } else { + if (this._selectedWallet == coin) { + this.wallets.get(coin).balance = Number(res).toFixed(8) + this.balanceString = this.wallets.get(this._selectedWallet).balance + " " + this._selectedWallet.toLocaleUpperCase() + this.balance = this.wallets.get(this._selectedWallet).balance + } + } + }) + const txsQort = await parentEpml.request('apiCall', { + url: `/transactions/search?address=${this.wallets.get('qort').wallet.address}&confirmationStatus=CONFIRMED&reverse=true&txType=PAYMENT&txType=REGISTER_NAME&txType=UPDATE_NAME&txType=SELL_NAME&txType=CANCEL_SELL_NAME&txType=BUY_NAME&txType=CREATE_POLL&txType=VOTE_ON_POLL&txType=ARBITRARY&txType=ISSUE_ASSET&txType=TRANSFER_ASSET&txType=CREATE_ASSET_ORDER&txType=CANCEL_ASSET_ORDER&txType=MULTI_PAYMENT&txType=DEPLOY_AT&txType=MESSAGE&txType=AIRDROP&txType=AT&txType=CREATE_GROUP&txType=UPDATE_GROUP&txType=ADD_GROUP_ADMIN&txType=REMOVE_GROUP_ADMIN&txType=GROUP_BAN&txType=CANCEL_GROUP_BAN&txType=GROUP_KICK&txType=GROUP_INVITE&txType=CANCEL_GROUP_INVITE&txType=JOIN_GROUP&txType=LEAVE_GROUP&txType=GROUP_APPROVAL&txType=SET_GROUP&txType=UPDATE_ASSET&txType=ACCOUNT_FLAGS&txType=ENABLE_FORGING&txType=REWARD_SHARE&txType=ACCOUNT_LEVEL&txType=TRANSFER_PRIVS&txType=PRESENCE`, + }) + const pendingTxsQort = await parentEpml.request('apiCall', { + url: `/transactions/unconfirmed?creator=${this.wallets.get('qort').wallet.base58PublicKey}&reverse=true&txType=PAYMENT&txType=REGISTER_NAME&txType=UPDATE_NAME&txType=SELL_NAME&txType=CANCEL_SELL_NAME&txType=BUY_NAME&txType=CREATE_POLL&txType=VOTE_ON_POLL&txType=ARBITRARY&txType=ISSUE_ASSET&txType=TRANSFER_ASSET&txType=CREATE_ASSET_ORDER&txType=CANCEL_ASSET_ORDER&txType=MULTI_PAYMENT&txType=DEPLOY_AT&txType=MESSAGE&txType=AIRDROP&txType=AT&txType=CREATE_GROUP&txType=UPDATE_GROUP&txType=ADD_GROUP_ADMIN&txType=REMOVE_GROUP_ADMIN&txType=GROUP_BAN&txType=CANCEL_GROUP_BAN&txType=GROUP_KICK&txType=GROUP_INVITE&txType=CANCEL_GROUP_INVITE&txType=JOIN_GROUP&txType=LEAVE_GROUP&txType=GROUP_APPROVAL&txType=SET_GROUP&txType=UPDATE_ASSET&txType=ACCOUNT_FLAGS&txType=ENABLE_FORGING&txType=REWARD_SHARE&txType=ACCOUNT_LEVEL&txType=TRANSFER_PRIVS&txType=PRESENCE`, + }) + if (this._selectedWallet == coin) { + this.wallets.get(coin).transactions = pendingTxsQort.concat(txsQort) + } + break + case 'btc': + case 'ltc': + case 'doge': + case 'dgb': + case 'rvn': + this.balanceString = this.renderFetchText() + const walletName = `${coin}Wallet` + parentEpml.request('apiCall', { + url: `/crosschain/${coin}/walletbalance?apiKey=${this.getApiKey()}`, + method: 'POST', + body: `${window.parent.reduxStore.getState().app.selectedAddress[walletName].derivedMasterPublicKey}` + }).then((res) => { + if (isNaN(Number(res))) { + let snack5string = get("walletpage.wchange33") + let snack6string = get("walletpage.wchange34") + parentEpml.request('showSnackBar', `${snack5string} ${coin.toLocaleUpperCase()} ${snack6string}!`) + } else { + if (this._selectedWallet == coin) { + this.wallets.get(this._selectedWallet).balance = (Number(res) / 1e8).toFixed(8) + this.balanceString = this.wallets.get(this._selectedWallet).balance + " " + this._selectedWallet.toLocaleUpperCase() + this.balance = this.wallets.get(this._selectedWallet).balance + } + } + }) + + const txs = await parentEpml.request('apiCall', { + url: `/crosschain/${coin}/wallettransactions?apiKey=${this.getApiKey()}`, + method: 'POST', + body: `${window.parent.reduxStore.getState().app.selectedAddress[walletName].derivedMasterPublicKey}`, + }) + + const compareFn = (a, b) => { + return b.timestamp - a.timestamp + } + + const sortedTransactions = txs.sort(compareFn) + if (this._selectedWallet == coin) { + this.wallets.get(this._selectedWallet).transactions = sortedTransactions + } + break + case 'arrr': + const arrrWalletName = `${coin}Wallet` + + const res = await parentEpml.request('apiCall', { + url: `/crosschain/${coin}/syncstatus?apiKey=${this.getApiKey()}`, + method: 'POST', + body: `${window.parent.reduxStore.getState().app.selectedAddress[arrrWalletName].seed58}` + }) + + if (coin != this._selectedWallet) { + // We've switched away from this coin + } + + if (res.indexOf('<') > -1) { + this.balanceString = this.renderFetchText() + await new Promise(resolve => setTimeout(resolve, 2000)) + await this.showWallet() + return + } else if (res !== "Synchronized") { + this.balanceString = res + await new Promise(resolve => setTimeout(resolve, 2000)) + await this.showWallet() + return + } + + this.balanceString = this.renderFetchText() + + parentEpml.request('apiCall', { + url: `/crosschain/${coin}/walletbalance?apiKey=${this.getApiKey()}`, + method: 'POST', + body: `${window.parent.reduxStore.getState().app.selectedAddress[arrrWalletName].seed58}`, + }).then((res) => { + if (isNaN(Number(res))) { + let snack5string = get("walletpage.wchange33") + let snack6string = get("walletpage.wchange34") + parentEpml.request('showSnackBar', `${snack5string} ${coin.toLocaleUpperCase()} ${snack6string}!`) + } else { + if (this._selectedWallet == coin) { + this.wallets.get(this._selectedWallet).balance = (Number(res) / 1e8).toFixed(8) + this.balanceString = this.wallets.get(this._selectedWallet).balance + " " + this._selectedWallet.toLocaleUpperCase() + this.balance = this.wallets.get(this._selectedWallet).balance + } + } + }) + + const arrrTxs = await parentEpml.request('apiCall', { + url: `/crosschain/${coin}/wallettransactions?apiKey=${this.getApiKey()}`, + method: 'POST', + body: `${window.parent.reduxStore.getState().app.selectedAddress[arrrWalletName].seed58}`, + }) + + const arrrCompareFn = (a, b) => { + return b.timestamp - a.timestamp + } + + const arrrSortedTransactions = arrrTxs.sort(arrrCompareFn) + + if (this._selectedWallet == coin) { + this.wallets.get(this._selectedWallet).transactions = arrrSortedTransactions + } + break + default: + break + } + } + + async fetchWalletAddress(coin) { + switch (coin) { + case 'arrr': + const arrrWalletName = `${coin}Wallet` + let res = await parentEpml.request('apiCall', { + url: `/crosschain/${coin}/walletaddress?apiKey=${this.getApiKey()}`, + method: 'POST', + body: `${window.parent.reduxStore.getState().app.selectedAddress[arrrWalletName].seed58}`, + }) + if (res != null && res.error != 1201 && res.length === 78) { + this.arrrWalletAddress = res + } + break + + default: + // Not used for other coins yet + break + } + } + + renderSendButton() { + if (this._selectedWallet === "qort") { + return html` this.openSendQort()}> ${translate("walletpage.wchange17")} QORT` + } else if (this._selectedWallet === "btc") { + return html` this.openSendBtc()}> ${translate("walletpage.wchange17")} BTC` + } else if (this._selectedWallet === "ltc") { + return html` this.openSendLtc()}> ${translate("walletpage.wchange17")} LTC` + } else if (this._selectedWallet === "doge") { + return html` this.openSendDoge()}> ${translate("walletpage.wchange17")} DOGE` + } else if (this._selectedWallet === "dgb") { + return html` this.openSendDgb()}> ${translate("walletpage.wchange17")} DGB` + } else if (this._selectedWallet === "rvn") { + return html` this.openSendRvn()}> ${translate("walletpage.wchange17")} RVN` + } else if (this._selectedWallet === "arrr") { + return html` this.openSendArrr()}> ${translate("walletpage.wchange17")} ARRR` + } else { + return html`` + } + } + + renderAddressbookButton() { + if (this._selectedWallet === "qort") { + return html` this.openQortAddressbook()}> ${translate("walletpage.wchange47")}` + } else if (this._selectedWallet === "btc") { + return html` this.openBtcAddressbook()}> ${translate("walletpage.wchange47")}` + } else if (this._selectedWallet === "ltc") { + return html` this.openLtcAddressbook()}> ${translate("walletpage.wchange47")}` + } else if (this._selectedWallet === "doge") { + return html` this.openDogeAddressbook()}> ${translate("walletpage.wchange47")}` + } else if (this._selectedWallet === "dgb") { + return html` this.openDgbAddressbook()}> ${translate("walletpage.wchange47")}` + } else if (this._selectedWallet === "rvn") { + return html` this.openRvnAddressbook()}> ${translate("walletpage.wchange47")}` + } else if (this._selectedWallet === "arrr") { + return html` this.openArrrAddressbook()}> ${translate("walletpage.wchange47")}` + } else { + return html`` + } + } + + renderExportAddressbookButton() { + if (this._selectedWallet === "qort") { + return html` this.exportQortAddressbook()}> ${translate("walletpage.wchange54")}` + } else if (this._selectedWallet === "btc") { + return html` this.exportBtcAddressbook()}> ${translate("walletpage.wchange54")}` + } else if (this._selectedWallet === "ltc") { + return html` this.exportLtcAddressbook()}> ${translate("walletpage.wchange54")}` + } else if (this._selectedWallet === "doge") { + return html` this.exportDogeAddressbook()}> ${translate("walletpage.wchange54")}` + } else if (this._selectedWallet === "dgb") { + return html` this.exportDgbAddressbook()}> ${translate("walletpage.wchange54")}` + } else if (this._selectedWallet === "rvn") { + return html` this.exportRvnAddressbook()}> ${translate("walletpage.wchange54")}` + } else if (this._selectedWallet === "arrr") { + return html` this.exportArrrAddressbook()}> ${translate("walletpage.wchange54")}` + } else { + return html`` + } + } + + renderImportAddressbookButton() { + if (this._selectedWallet === "qort") { + return html` this.openImportQortAddressbook()}> ${translate("walletpage.wchange53")}` + } else if (this._selectedWallet === "btc") { + return html` this.openImportBtcAddressbook()}> ${translate("walletpage.wchange53")}` + } else if (this._selectedWallet === "ltc") { + return html` this.openImportLtcAddressbook()}> ${translate("walletpage.wchange53")}` + } else if (this._selectedWallet === "doge") { + return html` this.openImportDogeAddressbook()}> ${translate("walletpage.wchange53")}` + } else if (this._selectedWallet === "dgb") { + return html` this.openImportDgbAddressbook()}> ${translate("walletpage.wchange53")}` + } else if (this._selectedWallet === "rvn") { + return html` this.openImportRvnAddressbook()}> ${translate("walletpage.wchange53")}` + } else if (this._selectedWallet === "arrr") { + return html` this.openImportArrrAddressbook()}> ${translate("walletpage.wchange53")}` + } else { + return html`` + } + } + + openSendQort() { + this.shadowRoot.querySelector("#sendQortDialog").show(); + } + + openSendBtc() { + this.shadowRoot.querySelector("#sendBtcDialog").show(); + } + + openSendLtc() { + this.shadowRoot.querySelector("#sendLtcDialog").show(); + } + + openSendDoge() { + this.shadowRoot.querySelector("#sendDogeDialog").show(); + } + + openSendDgb() { + this.shadowRoot.querySelector("#sendDgbDialog").show(); + } + + openSendRvn() { + this.shadowRoot.querySelector("#sendRvnDialog").show(); + } + + openSendArrr() { + this.shadowRoot.querySelector("#sendArrrDialog").show(); + } + + changeTheme() { + const checkTheme = localStorage.getItem('qortalTheme') + if (checkTheme === 'dark') { + this.theme = 'dark'; + } else { + this.theme = 'light'; + } + document.querySelector('html').setAttribute('theme', this.theme); + } + + changeLanguage() { + const checkLanguage = localStorage.getItem('qortalLanguage') + + if (checkLanguage === null || checkLanguage.length === 0) { + localStorage.setItem('qortalLanguage', 'us') + use('us') + } else { + use(checkLanguage) + } + } + + getSelectedWalletAddress() { + switch (this._selectedWallet) { + case "arrr": + // Use address returned by core API + return this.arrrWalletAddress + + default: + // Use locally derived address + return this.wallets.get(this._selectedWallet).wallet.address + } + } + + getSelectedWalletServer() { + switch (this._selectedWallet) { + case "qort": + return this.nodeDomain + case "btc": + return this.btcServer + case "ltc": + return this.ltcServer + case "doge": + return this.dogeServer + case "dgb": + return this.dgbServer + case "rvn": + return this.rvnServer + case "arrr": + return this.arrrServer + default: + return + } + } + + async fetchWalletServer(coin) { + if (coin == 'qort') { + return + } + let walletServer = '' + try { + const serverInfo = await parentEpml.request('apiCall', { + type: 'api', + /* TODO */ + url: `/crosschain/${coin}/serverinfos`, + // TODO when 'current' parameter is added to 'serverinfos' API call, change above line to: + // url: `/crosschain/${coin}/serverinfos?current=true`, + }) + /* TODO */ + let currentServerFound = false + for (const server of serverInfo.servers) { + if (server.isCurrent === true) { + walletServer = `${server.hostName}:${server.port}` + currentServerFound = true + break + } + } + if (!currentServerFound) { + walletServer = 'Not Connected' + } + // TODO when 'current' parameter is added to 'serverinfos' API call, change above 'let,for,if' sections to: + /*if (serverInfo.servers[0]) { + const currentServerInfo = `${serverInfo.servers[0].hostName}:${serverInfo.servers[0].port}` + walletServer = currentServerInfo + } else { + walletServer = 'Not Connected' + }*/ + } catch (error) { + console.error('Failed to fetch server info:', error) + walletServer = `Error fetching server: ${error}` + } + switch (coin) { + case "btc": + this.btcServer = walletServer + break + case "ltc": + this.ltcServer = walletServer + break + case "doge": + this.dogeServer = walletServer + break + case "dgb": + this.dgbServer = walletServer + break + case "rvn": + this.rvnServer = walletServer + break + case "arrr": + this.arrrServer = walletServer + break + default: + break + } + } + + getNodeConfig() { + this.nodeDomain = "" + const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] + this.nodeDomain = myNode.domain + ":" + myNode.port + this.nodeConfig = {} + parentEpml.request("getNodeConfig").then((res) => { + this.nodeConfig = res + }) + } + + async getTransactionGrid(coin) { + this.transactionsGrid = this.shadowRoot.querySelector(`#${coin}TransactionsGrid`) + if (coin === 'qort') { + this.transactionsGrid.addEventListener( + 'click', + (e) => { + let qortItem = this.transactionsGrid.getEventContext(e).item + this.showQortTransactionDetails(qortItem, this.wallets.get(this._selectedWallet).transactions) + }, + { passive: true } + ) + } else if (coin === 'btc') { + this.transactionsGrid.addEventListener( + 'click', + (e) => { + let btcItem = this.transactionsGrid.getEventContext(e).item + this.showBtcTransactionDetails(btcItem, this.wallets.get(this._selectedWallet).transactions) + }, + { passive: true } + ) + } else if (coin === 'ltc') { + this.transactionsGrid.addEventListener( + 'click', + (e) => { + let ltcItem = this.transactionsGrid.getEventContext(e).item + this.showLtcTransactionDetails(ltcItem, this.wallets.get(this._selectedWallet).transactions) + }, + { passive: true } + ) + } else if (coin === 'doge') { + this.transactionsGrid.addEventListener( + 'click', + (e) => { + let dogeItem = this.transactionsGrid.getEventContext(e).item + this.showDogeTransactionDetails(dogeItem, this.wallets.get(this._selectedWallet).transactions) + }, + { passive: true } + ) + } else if (coin === 'dgb') { + this.transactionsGrid.addEventListener( + 'click', + (e) => { + let dgbItem = this.transactionsGrid.getEventContext(e).item + this.showDgbTransactionDetails(dgbItem, this.wallets.get(this._selectedWallet).transactions) + }, + { passive: true } + ) + } else if (coin === 'rvn') { + this.transactionsGrid.addEventListener( + 'click', + (e) => { + let rvnItem = this.transactionsGrid.getEventContext(e).item + this.showRvnTransactionDetails(rvnItem, this.wallets.get(this._selectedWallet).transactions) + }, + { passive: true } + ) + } else if (coin === 'arrr') { + this.transactionsGrid.addEventListener( + 'click', + (e) => { + let arrrItem = this.transactionsGrid.getEventContext(e).item + this.showArrrTransactionDetails(arrrItem, this.wallets.get(this._selectedWallet).transactions) + }, + { passive: true } + ) + } + + this.pagesControl = this.shadowRoot.querySelector('#pages') + this.pages = undefined + } + + async renderTransactions() { + if (this._selectedWallet === 'qort') { + render(this.renderQortTransactions(this.wallets.get(this._selectedWallet).transactions, this._selectedWallet), this.transactionsDOM) + } else if (this._selectedWallet === 'btc') { + render(this.renderBtcTransactions(this.wallets.get(this._selectedWallet).transactions, this._selectedWallet), this.transactionsDOM) + } else if (this._selectedWallet === 'ltc') { + render(this.renderLtcTransactions(this.wallets.get(this._selectedWallet).transactions, this._selectedWallet), this.transactionsDOM) + } else if (this._selectedWallet === 'doge') { + render(this.renderDogeTransactions(this.wallets.get(this._selectedWallet).transactions, this._selectedWallet), this.transactionsDOM) + } else if (this._selectedWallet === 'dgb') { + render(this.renderDgbTransactions(this.wallets.get(this._selectedWallet).transactions, this._selectedWallet), this.transactionsDOM) + } else if (this._selectedWallet === 'rvn') { + render(this.renderRvnTransactions(this.wallets.get(this._selectedWallet).transactions, this._selectedWallet), this.transactionsDOM) + } else if (this._selectedWallet === 'arrr') { + render(this.renderArrrTransactions(this.wallets.get(this._selectedWallet).transactions, this._selectedWallet), this.transactionsDOM) + } + } + + renderQortTransactions(transactions, coin) { + const requiredConfirmations = 3 + const currentBlockHeight = window.parent.reduxStore.getState().app.blockInfo.height + if (Array.isArray(transactions)) { + transactions = transactions.map(tx => { + tx.confirmations = (currentBlockHeight - (tx.blockHeight - 1)) || '' + return tx + }) + } + return html` +
    ${translate("walletpage.wchange38")}
    + + { + if (!currentBlockHeight) { + return render(html``, root) + } + const confirmed = data.item.confirmations >= requiredConfirmations + const unconfirmed = data.item.confirmations == 0 + if (confirmed) { + render(html`check`, root) + } else if (unconfirmed) { + render(html`schedule`, root) + } else { + render(html`schedule`, root) + } + }} + > + + { + render(html` + ${data.item.type} ${data.item.creatorAddress === this.wallets.get('qort').wallet.address ? + html` + ${translate("walletpage.wchange7")} + ` : html` + ${translate("walletpage.wchange8")} + ` + } + `, root) + }} + > + + { + render(html`${data.item.type === 'AT' ? html`${data.item.atAddress}` : html`${data.item.creatorAddress}`}`, root) + }} + > + + { + render(html`${data.item.type === 'DEPLOY_AT' ? html`${data.item.aTAddress}` : html`${data.item.recipient}`}`, root) + }} + > + + + + { + const time = new Date(data.item.timestamp) + render(html` + + `, root) + }} + > + + +
    + ` + } + + renderBtcTransactions(transactions, coin) { + return html` +
    ${translate("walletpage.wchange38")}
    + + { + render(html` + check + `, root) + }} + > + + { + render(html` + ${translate("walletpage.wchange40")} ${data.item.inputs[0].address === this.wallets.get(this._selectedWallet).wallet.address ? + html` + ${translate("walletpage.wchange7")} + ` : html` + ${translate("walletpage.wchange8")} + ` + } + `, root) + }} + > + + { + render(html`${data.item.inputs[0].address}`, root) + }} + > + + { + render(html`${data.item.outputs[0].address}`, root) + }} + > + + + { + const amount = (Number(data.item.totalAmount) / 1e8).toFixed(8) + render(html`${amount}`, root) + }} + > + + { + const time = new Date(data.item.timestamp) + render(html` + + `, root) + }} + > + + +
    + ` + } + + renderLtcTransactions(transactions, coin) { + return html` +
    ${translate("walletpage.wchange38")}
    + + { + render(html` + check + `, root) + }} + > + + { + render(html` + ${translate("walletpage.wchange40")} ${data.item.inputs[0].address === this.wallets.get(this._selectedWallet).wallet.address ? + html` + ${translate("walletpage.wchange7")} + ` : html` + ${translate("walletpage.wchange8")} + ` + } + `, root) + }} + > + + { + render(html`${data.item.inputs[0].address}`, root) + }} + > + + { + render(html`${data.item.outputs[0].address}`, root) + }} + > + + + { + const amount = (Number(data.item.totalAmount) / 1e8).toFixed(8) + render(html`${amount}`, root) + }} + > + + { + const time = new Date(data.item.timestamp) + render(html` + + `, root) + }} + > + + +
    + ` + } + + renderDogeTransactions(transactions, coin) { + return html` +
    +
    ${translate("walletpage.wchange38")}
    + + { + render(html` + check + `, root) + }} + > + + { + render(html` + ${translate("walletpage.wchange40")} ${data.item.inputs[0].address === this.wallets.get(this._selectedWallet).wallet.address ? + html` + ${translate("walletpage.wchange7")} + ` : html` + ${translate("walletpage.wchange8")} + ` + } + `, root) + }} + > + + { + render(html`${data.item.inputs[0].address}`, root) + }} + > + + { + render(html`${data.item.outputs[0].address}`, root) + }} + > + + + { + const amount = (Number(data.item.totalAmount) / 1e8).toFixed(8) + render(html`${amount}`, root) + }} + > + + { + const time = new Date(data.item.timestamp) + render(html` + + `, root) + }} + > + + +
    + ` + } + + renderDgbTransactions(transactions, coin) { + return html` +
    ${translate("walletpage.wchange38")}
    + + { + render(html` + check + `, root) + }} + > + + { + render(html` + ${translate("walletpage.wchange40")} ${data.item.inputs[0].address === this.wallets.get(this._selectedWallet).wallet.address ? + html` + ${translate("walletpage.wchange7")} + ` : html` + ${translate("walletpage.wchange8")} + ` + } + `, root) + }} + > + + { + render(html`${data.item.inputs[0].address}`, root) + }} + > + + { + render(html`${data.item.outputs[0].address}`, root) + }} + > + + + { + const amount = (Number(data.item.totalAmount) / 1e8).toFixed(8) + render(html`${amount}`, root) + }} + > + + { + const time = new Date(data.item.timestamp) + render(html` + + `, root) + }} + > + + +
    + ` + } + + renderRvnTransactions(transactions, coin) { + return html` +
    ${translate("walletpage.wchange38")}
    + + { + render(html` + check + `, root) + }} + > + + { + render(html` + ${translate("walletpage.wchange40")} ${data.item.inputs[0].address === this.wallets.get(this._selectedWallet).wallet.address ? + html` + ${translate("walletpage.wchange7")} + ` : html` + ${translate("walletpage.wchange8")} + ` + } + `, root) + }} + > + + { + render(html`${data.item.inputs[0].address}`, root) + }} + > + + { + render(html`${data.item.outputs[0].address}`, root) + }} + > + + + { + const amount = (Number(data.item.totalAmount) / 1e8).toFixed(8) + render(html`${amount}`, root) + }} + > + + { + const time = new Date(data.item.timestamp) + render(html` + + `, root) + }} + > + + +
    + ` + } + + renderArrrTransactions(transactions, coin) { + return html` +
    ${translate("walletpage.wchange38")}
    + + { + render(html` + check + `, root) + }} + > + + { + render(html` + ${translate("walletpage.wchange40")} ${data.item.totalAmount < 0 ? + html` + ${translate("walletpage.wchange7")} + ` : html` + ${translate("walletpage.wchange8")} + ` + } + `, root) + }} + > + + + { + const amount = (Number(data.item.totalAmount) / 1e8).toFixed(8) + render(html`${amount}`, root) + }} + > + + { + const time = new Date(data.item.timestamp) + render(html` + + `, root) + }} + > + + { + render(html`${data.item.memo}`, root) + }} + > + + +
    + ` + } + + async updateItemsFromPage(page, changeWallet = false) { + if (page === undefined) { + return + } + + changeWallet === true ? (this.pagesControl.innerHTML = '') : null + + if (!this.pages) { + this.pages = Array.apply(null, { length: Math.ceil(this.wallets.get(this._selectedWallet).transactions.length / this.transactionsGrid.pageSize) }).map((item, index) => { + return index + 1 + }) + + const prevBtn = document.createElement('button') + prevBtn.textContent = '<' + prevBtn.addEventListener('click', () => { + const selectedPage = parseInt(this.pagesControl.querySelector('[selected]').textContent) + this.updateItemsFromPage(selectedPage - 1) + }) + this.pagesControl.appendChild(prevBtn) + + this.pages.forEach((pageNumber) => { + const pageBtn = document.createElement('button') + pageBtn.textContent = pageNumber + pageBtn.addEventListener('click', (e) => { + this.updateItemsFromPage(parseInt(e.target.textContent)) + }) + if (pageNumber === page) { + pageBtn.setAttribute('selected', true) + } + this.pagesControl.appendChild(pageBtn) + }) + + const nextBtn = window.document.createElement('button') + nextBtn.textContent = '>' + nextBtn.addEventListener('click', () => { + const selectedPage = parseInt(this.pagesControl.querySelector('[selected]').textContent) + this.updateItemsFromPage(selectedPage + 1) + }) + this.pagesControl.appendChild(nextBtn) + } + + const buttons = Array.from(this.pagesControl.children) + buttons.forEach((btn, index) => { + if (parseInt(btn.textContent) === page) { + btn.setAttribute('selected', true) + } else { + btn.removeAttribute('selected') + } + if (index === 0) { + if (page === 1) { + btn.setAttribute('disabled', '') + } else { + btn.removeAttribute('disabled') + } + } + if (index === buttons.length - 1) { + if (page === this.pages.length) { + btn.setAttribute('disabled', '') + } else { + btn.removeAttribute('disabled') + } + } + }) + let start = (page - 1) * this.transactionsGrid.pageSize + let end = page * this.transactionsGrid.pageSize + + this.transactionsGrid.items = this.wallets.get(this._selectedWallet).transactions.slice(start, end) + } + + transactionItem(transactionObject) { + return ` +
    +
    +

    ${transactionObject.name}

    + ${transactionObject.category} ${transactionObject.ID} - ${transactionObject.date} +
    +
    +

    ${transactionObject.amount}

    +
    +
    + ` + } + + showQortTransactionDetails(myTransaction, allTransactions) { + allTransactions.forEach((transaction) => { + if (myTransaction.signature === transaction.signature) { + let txnFlow = myTransaction.creatorAddress === this.wallets.get('qort').wallet.address ? 'OUT' : 'IN' + this.selectedTransaction = { ...transaction, txnFlow } + if (this.selectedTransaction.signature.length != 0) { + this.shadowRoot.querySelector('#showTransactionDetailsDialog').show() + } + } + }) + } + + showBtcTransactionDetails(myTransaction, allTransactions) { + allTransactions.forEach((transaction) => { + if (myTransaction.txHash === transaction.txHash) { + let btcTxnFlow = myTransaction.inputs[0].address === this.wallets.get(this._selectedWallet).wallet.address ? 'OUT' : 'IN' + let btcSender = myTransaction.inputs[0].address + let btcReceiver = myTransaction.outputs[0].address + this.selectedTransaction = { ...transaction, btcTxnFlow, btcSender, btcReceiver } + if (this.selectedTransaction.txHash.length != 0) { + this.shadowRoot.querySelector('#showBtcTransactionDetailsDialog').show() + } + } + }) + } + + showLtcTransactionDetails(myTransaction, allTransactions) { + allTransactions.forEach((transaction) => { + if (myTransaction.txHash === transaction.txHash) { + let ltcTxnFlow = myTransaction.inputs[0].address === this.wallets.get(this._selectedWallet).wallet.address ? 'OUT' : 'IN' + let ltcSender = myTransaction.inputs[0].address + let ltcReceiver = myTransaction.outputs[0].address + this.selectedTransaction = { ...transaction, ltcTxnFlow, ltcSender, ltcReceiver } + if (this.selectedTransaction.txHash.length != 0) { + this.shadowRoot.querySelector('#showLtcTransactionDetailsDialog').show() + } + } + }) + } + + showDogeTransactionDetails(myTransaction, allTransactions) { + allTransactions.forEach((transaction) => { + if (myTransaction.txHash === transaction.txHash) { + let dogeTxnFlow = myTransaction.inputs[0].address === this.wallets.get(this._selectedWallet).wallet.address ? 'OUT' : 'IN' + let dogeSender = myTransaction.inputs[0].address + let dogeReceiver = myTransaction.outputs[0].address + this.selectedTransaction = { ...transaction, dogeTxnFlow, dogeSender, dogeReceiver } + if (this.selectedTransaction.txHash.length != 0) { + this.shadowRoot.querySelector('#showDogeTransactionDetailsDialog').show() + } + } + }) + } + + showDgbTransactionDetails(myTransaction, allTransactions) { + allTransactions.forEach((transaction) => { + if (myTransaction.txHash === transaction.txHash) { + let dgbTxnFlow = myTransaction.inputs[0].address === this.wallets.get(this._selectedWallet).wallet.address ? 'OUT' : 'IN' + let dgbSender = myTransaction.inputs[0].address + let dgbReceiver = myTransaction.outputs[0].address + this.selectedTransaction = { ...transaction, dgbTxnFlow, dgbSender, dgbReceiver } + if (this.selectedTransaction.txHash.length != 0) { + this.shadowRoot.querySelector('#showDgbTransactionDetailsDialog').show() + } + } + }) + } + + showRvnTransactionDetails(myTransaction, allTransactions) { + allTransactions.forEach((transaction) => { + if (myTransaction.txHash === transaction.txHash) { + let rvnTxnFlow = myTransaction.inputs[0].address === this.wallets.get(this._selectedWallet).wallet.address ? 'OUT' : 'IN' + let rvnSender = myTransaction.inputs[0].address + let rvnReceiver = myTransaction.outputs[0].address + this.selectedTransaction = { ...transaction, rvnTxnFlow, rvnSender, rvnReceiver } + if (this.selectedTransaction.txHash.length != 0) { + this.shadowRoot.querySelector('#showRvnTransactionDetailsDialog').show() + } + } + }) + } + + showArrrTransactionDetails(myTransaction, allTransactions) { + allTransactions.forEach((transaction) => { + if (myTransaction.txHash === transaction.txHash) { + let arrrTxnFlow = myTransaction.inputs[0].address === this.wallets.get(this._selectedWallet).wallet.address ? 'OUT' : 'IN' + let arrrSender = myTransaction.inputs[0].address + let arrrReceiver = myTransaction.outputs[0].address + this.selectedTransaction = { ...transaction, arrrTxnFlow, arrrSender, arrrReceiver } + if (this.selectedTransaction.txHash.length != 0) { + this.shadowRoot.querySelector('#showArrrTransactionDetailsDialog').show() + } + } + }) + } + + async saveFileToDisk(blob, fileName) { + try { + const fileHandle = await self.showSaveFilePicker({ + suggestedName: fileName, + types: [{ + description: "File" + }] + }) + const writeFile = async (fileHandle, contents) => { + const writable = await fileHandle.createWritable() + await writable.write(contents) + await writable.close() + } + writeFile(fileHandle, blob).then(() => console.log("FILE SAVED")) + let snack4string = get("general.save") + parentEpml.request('showSnackBar', `${snack4string} ${fileName} ✅`) + } catch (error) { + if (error.name === 'AbortError') { + return + } + FileSaver.saveAs(blob, fileName) + } + } + + getConfirmations(height, lastBlockHeight) { + return lastBlockHeight - height + 1 + } + + _unconfirmedClass(unconfirmed) { + return unconfirmed ? 'unconfirmed' : '' + } + + // Standard functions + getApiKey() { + const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] + return myNode.apiKey + } + + isEmptyArray(arr) { + if (!arr) { return true } + return arr.length === 0 + } + + round(number) { + return (Math.round(parseFloat(number) * 1e8) / 1e8).toFixed(8) + } + + floor(num) { + num = parseFloat(num) + return isNaN(num) ? 0 : this.format(Math.floor(num)) + } + + decimals(num) { + num = parseFloat(num) + return num % 1 > 0 ? (num + '').split('.')[1] : '0' + } + + subtract(num1, num2) { + return num1 - num2 + } + + format(num) { + return num.toLocaleString() + } } window.customElements.define('multi-wallet', MultiWallet) \ No newline at end of file diff --git a/plugins/plugins/utils/blocks-needed.js b/plugins/plugins/utils/blocks-needed.js deleted file mode 100644 index ee5dc6ce..00000000 --- a/plugins/plugins/utils/blocks-needed.js +++ /dev/null @@ -1,23 +0,0 @@ -export const blocksNeed = (level) => { - if (level === 0) { - return '7200'; - } else if (level === 1) { - return '72000'; - } else if (level === 2) { - return '201600'; - } else if (level === 3) { - return '374400'; - } else if (level === 4) { - return '618400'; - } else if (level === 5) { - return '964000'; - } else if (level === 6) { - return '1482400'; - } else if (level === 7) { - return '2173600'; - } else if (level === 8) { - return '3037600'; - } else if (level === 9) { - return '4074400'; - } -}; \ No newline at end of file diff --git a/plugins/plugins/utils/bytesToMegabytes.js b/plugins/plugins/utils/bytesToMegabytes.js deleted file mode 100644 index 9b271e4f..00000000 --- a/plugins/plugins/utils/bytesToMegabytes.js +++ /dev/null @@ -1,3 +0,0 @@ -export function bytesToMegabytes(bytes) { - return bytes / (1024 * 1024); -} \ No newline at end of file diff --git a/plugins/plugins/utils/classes.js b/plugins/plugins/utils/classes.js new file mode 100644 index 00000000..c16b4bcf --- /dev/null +++ b/plugins/plugins/utils/classes.js @@ -0,0 +1,926 @@ +import { get } from '../../../core/translate' + +const getApiKey = () => { + const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] + return myNode.apiKey +} + +export class RequestQueue { + constructor(maxConcurrent = 5) { + this.queue = [] + this.maxConcurrent = maxConcurrent + this.currentConcurrent = 0 + } + + push(request) { + return new Promise((resolve, reject) => { + this.queue.push({ request, resolve, reject }) + this.checkQueue() + }) + } + + checkQueue() { + if (this.queue.length === 0 || this.currentConcurrent >= this.maxConcurrent) { + return + } + + const { request, resolve, reject } = this.queue.shift() + + this.currentConcurrent++ + + request().then(resolve).catch(reject).finally(() => { + this.currentConcurrent-- + this.checkQueue() + }) + } +} + +export class RequestQueueWithPromise { + constructor(maxConcurrent = 5) { + this.queue = [] + this.maxConcurrent = maxConcurrent + this.currentlyProcessing = 0 + } + + // Add a request to the queue and return a promise + enqueue(request) { + return new Promise((resolve, reject) => { + // Push the request and its resolve and reject callbacks to the queue + this.queue.push({ request, resolve, reject }) + this.process() + }) + } + + // Process requests in the queue + async process() { + while (this.queue.length > 0 && this.currentlyProcessing < this.maxConcurrent) { + this.currentlyProcessing++ + + const { request, resolve, reject } = this.queue.shift() + + try { + const response = await request() + resolve(response) + } catch (error) { + reject(error) + } finally { + this.currentlyProcessing-- + await this.process() + } + } + } +} + +export class Loader { + constructor() { + this.loader = document.createElement("div") + this.loader.className = "loader" + this.loader.innerHTML = `
    ` + this.styles = document.createElement("style") + this.styles.innerHTML = ` + .loader { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: rgba(0, 0, 0, 0.5); + display: flex; + justify-content: center; + align-items: center; + z-index: 1000001; + } + + .loader-spinner { + border: 4px solid #f3f3f3; + border-top: 4px solid #3498db; + border-radius: 50%; + width: 32px; + height: 32px; + animation: spin 1s linear infinite; + } + + @keyframes spin { + from { transform: rotate(0deg); } + to { transform: rotate(360deg); } + } + ` + } + + show() { + document.head.appendChild(this.styles) + document.body.appendChild(this.loader) + } + + hide() { + if (this.loader.parentNode) { + this.loader.parentNode.removeChild(this.loader) + } + if (this.styles.parentNode) { + this.styles.parentNode.removeChild(this.styles) + } + } +} + +export class ModalHelper { + constructor() { + this.initializeStyles() + } + + async getArbitraryFee() { + const timestamp = Date.now() + const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] + const nodeUrl = `${myNode.protocol}://${myNode.domain}:${myNode.port}` + const url = `${nodeUrl}/transactions/unitfee?txType=ARBITRARY×tamp=${timestamp}` + const response = await fetch(url) + + if (!response.ok) { + throw new Error('Error when fetching arbitrary fee') + } + + const data = await response.json() + const arbitraryFee = (Number(data) / 1e8).toFixed(8) + + return { + timestamp, + fee: Number(data), + feeToShow: arbitraryFee + } + } + + async showModalAndWaitPublish(data) { + return new Promise((resolve) => { + const modal = this.createModal(data) + document.body.appendChild(modal) + this.addModalEventListeners(modal, resolve) + }) + } + + createModal(data) { + const modal = document.createElement('div') + modal.id = "backdrop" + modal.classList.add("backdrop") + + modal.innerHTML = ` + + ` + + return modal + } + + addModalEventListeners(modal, resolve) { + // Event listener for the 'OK' button + const okButton = modal.querySelector('#ok-button') + okButton.addEventListener('click', () => { + const userData = { isWithFee: true } + if (modal.parentNode === document.body) { + document.body.removeChild(modal) + } + + resolve({ action: 'accept', userData }) + }) + + // Prevent modal content from closing the modal + const modalContent = modal.querySelector('.modal-content') + modalContent.addEventListener('click', e => { + e.stopPropagation() + }) + + // Event listener for 'Backdrop' button + const backdropClick = document.getElementById('backdrop') + backdropClick.addEventListener('click', () => { + if (modal.parentNode === document.body) { + document.body.removeChild(modal) + } + + resolve({ action: 'reject' }) + }) + + // Event listener for 'Cancel' button + const cancelButton = modal.querySelector('#cancel-button') + cancelButton.addEventListener('click', () => { + if (modal.parentNode === document.body) { + document.body.removeChild(modal) + } + + resolve({ action: 'reject' }) + }) + } + + initializeStyles() { + const styles = ` + * { + --mdc-theme-primary: rgb(3, 169, 244); + --mdc-theme-secondary: var(--mdc-theme-primary); + --paper-input-container-focus-color: var(--mdc-theme-primary); + --mdc-checkbox-unchecked-color: var(--black); + --mdc-theme-on-surface: var(--black); + --mdc-checkbox-disabled-color: var(--black); + --mdc-checkbox-ink-color: var(--black); + } + + .backdrop { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: rgb(186 186 186 / 26%); + overflow: hidden; + animation: backdrop_blur cubic-bezier(0.22, 1, 0.36, 1) 0.1s forwards; + z-index: 1000000; + } + + @keyframes backdrop_blur { + 0% { + backdrop-filter: blur(0px); + background: transparent; + } + + 100% { + backdrop-filter: blur(5px); + background: rgb(186 186 186 / 26%); + } + } + + @keyframes modal_transition { + 0% { + visibility: hidden; + opacity: 0; + } + + 100% { + visibility: visible; + opacity: 1; + } + } + + .modal { + position: relative; + display: flex; + justify-content: center; + align-items: center; + width: 100%; + height: 100%; + animation: 0.1s cubic-bezier(0.22, 1, 0.36, 1) 0s 1 normal forwards running modal_transition; + z-index: 1000001; + } + + @keyframes modal_transition { + 0% { + visibility: hidden; + opacity: 0; + } + + 100% { + visibility: visible; + opacity: 1; + } + } + + .modal-content { + background-color: var(--white); + border-radius: 10px; + padding: 20px; + box-shadow: 0 0 10px rgba(0, 0, 0, 0.3); + max-width: 80%; + min-width: 300px; + display: flex; + flex-direction: column; + justify-content: space-between; + } + + .modal-body { + padding: 25px; + } + + .modal-subcontainer { + color: var(--black); + display: flex; + flex-direction: column; + align-items: flex-start; + gap: 15px; + } + + .modal-subcontainer-error { + color: var(--black); + display: flex; + flex-direction: column; + align-items: center; + gap: 15px; + } + + .modal-paragraph-error { + font-family: Roboto, sans-serif; + font-size: 20px; + letter-spacing: 0.3px; + font-weight: 700; + color: var(--black); + margin: 0; + } + + .modal-paragraph { + font-family: Roboto, sans-serif; + font-size: 18px; + letter-spacing: 0.3px; + font-weight: 300; + color: var(--black); + margin: 0; + word-wrap: break-word; + overflow-wrap: break-word; + } + + .capitalize-first { + text-transform: capitalize; + } + + .checkbox-row { + display: flex; + align-items: center; + font-family: Montserrat, sans-serif; + font-weight: 600; + color: var(--black); + } + + .modal-buttons { + display: flex; + justify-content: space-between; + margin-top: 20px; + } + + .modal-buttons button { + background-color: #4caf50; + border: none; + color: #fff; + padding: 10px 20px; + border-radius: 5px; + cursor: pointer; + transition: background-color 0.2s; + } + + .modal-buttons button:hover { + background-color: #3e8e41; + } + + #cancel-button { + background-color: #f44336; + } + + #cancel-button:hover { + background-color: #d32f2f; + } + ` + + const styleSheet = new CSSStyleSheet() + + styleSheet.replaceSync(styles) + + document.adoptedStyleSheets = [styleSheet] + } + + static getInstance() { + if (!ModalHelper.instance) { + ModalHelper.instance = new ModalHelper() + } + + return ModalHelper.instance + } +} + +export class WarningModal { + constructor() { + this.initializeStyles() + } + + async showModalAndWaitPublish(data) { + return new Promise((resolve) => { + const modal = this.createModal(data) + document.body.appendChild(modal) + this.addModalEventListeners(modal, resolve) + }) + } + + createModal(data) { + const modal = document.createElement('div') + + modal.id = "backdrop" + modal.classList.add("backdrop") + + modal.innerHTML = ` + + ` + + return modal + } + + addModalEventListeners(modal, resolve) { + // Event listener for the 'OK' button + const okButton = modal.querySelector('#ok-button') + okButton.addEventListener('click', () => { + const userData = { isWithFee: true } + + if (modal.parentNode === document.body) { + document.body.removeChild(modal) + } + + resolve({ action: 'accept', userData }) + }) + + // Prevent modal content from closing the modal + const modalContent = modal.querySelector('.modal-content') + modalContent.addEventListener('click', e => { + e.stopPropagation() + }) + + // Event listener for 'Backdrop' button + const backdropClick = document.getElementById('backdrop') + backdropClick.addEventListener('click', () => { + if (modal.parentNode === document.body) { + document.body.removeChild(modal) + } + + resolve({ action: 'reject' }) + }) + + // Event listener for 'Cancel' button + const cancelButton = modal.querySelector('#cancel-button') + cancelButton.addEventListener('click', () => { + if (modal.parentNode === document.body) { + document.body.removeChild(modal) + } + + resolve({ action: 'reject' }) + }) + } + + initializeStyles() { + const styles = ` + * { + --mdc-theme-primary: rgb(3, 169, 244); + --mdc-theme-secondary: var(--mdc-theme-primary); + --paper-input-container-focus-color: var(--mdc-theme-primary); + --mdc-checkbox-unchecked-color: var(--black); + --mdc-theme-on-surface: var(--black); + --mdc-checkbox-disabled-color: var(--black); + --mdc-checkbox-ink-color: var(--black); + } + + .backdrop { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: rgb(186 186 186 / 26%); + overflow: hidden; + animation: backdrop_blur cubic-bezier(0.22, 1, 0.36, 1) 0.1s forwards; + z-index: 1000000; + } + + @keyframes backdrop_blur { + 0% { + backdrop-filter: blur(0px); + background: transparent; + } + + 100% { + backdrop-filter: blur(5px); + background: rgb(186 186 186 / 26%); + } + } + + @keyframes modal_transition { + 0% { + visibility: hidden; + opacity: 0; + } + + 100% { + visibility: visible; + opacity: 1; + } + } + + .modal { + position: relative; + display: flex; + justify-content: center; + align-items: center; + width: 100%; + height: 100%; + animation: 0.1s cubic-bezier(0.22, 1, 0.36, 1) 0s 1 normal forwards running modal_transition; + z-index: 1000001; + } + + @keyframes modal_transition { + 0% { + visibility: hidden; + opacity: 0; + } + + 100% { + visibility: visible; + opacity: 1; + } + } + + .modal-content { + background-color: var(--white); + border-radius: 10px; + padding: 20px; + box-shadow: 0 0 10px rgba(0, 0, 0, 0.3); + max-width: 650px; + min-width: 300px; + display: flex; + flex-direction: column; + justify-content: space-between; + } + + .modal-body { + padding: 25px; + } + + .modal-subcontainer { + color: var(--black); + display: flex; + flex-direction: column; + align-items: flex-start; + gap: 15px; + } + + .modal-subcontainer-error { + color: var(--black); + display: flex; + flex-direction: column; + align-items: center; + gap: 15px; + } + + .modal-paragraph-error { + font-family: Roboto, sans-serif; + font-size: 20px; + letter-spacing: 0.3px; + font-weight: 700; + color: var(--black); + margin: 0; + } + + .modal-paragraph { + font-family: Roboto, sans-serif; + font-size: 18px; + letter-spacing: 0.3px; + font-weight: 300; + color: var(--black); + margin: 0; + word-wrap: break-word; + overflow-wrap: break-word; + } + + .capitalize-first { + text-transform: capitalize; + } + + .checkbox-row { + display: flex; + align-items: center; + font-family: Montserrat, sans-serif; + font-weight: 600; + color: var(--black); + } + + .modal-buttons { + display: flex; + justify-content: space-between; + margin-top: 20px; + } + + .modal-buttons button { + background-color: #4caf50; + border: none; + color: #fff; + padding: 10px 20px; + border-radius: 5px; + cursor: pointer; + transition: background-color 0.2s; + } + + .modal-buttons button:hover { + background-color: #3e8e41; + } + + #cancel-button { + background-color: #f44336; + } + + #cancel-button:hover { + background-color: #d32f2f; + } + ` + + const styleSheet = new CSSStyleSheet() + + styleSheet.replaceSync(styles) + + document.adoptedStyleSheets = [styleSheet] + } + + static getInstance() { + if (!WarningModal.instance) { + WarningModal.instance = new WarningModal() + } + + return WarningModal.instance + } +} + +export const modalHelper = ModalHelper.getInstance() +export const warningModal = WarningModal.getInstance() + +export const publishData = async ({ + registeredName, + path, + file, + service, + identifier, + parentEpml, + uploadType, + selectedAddress, + worker, + isBase64, + filename, + apiVersion, + withFee, + title, + description, + category, + tag1, + tag2, + tag3, + tag4, + tag5, + feeAmount +}) => { + const validateName = async (receiverName) => { + return await parentEpml.request('apiCall', { + type: 'api', + url: `/names/${receiverName}` + }) + } + + const convertBytesForSigning = async (transactionBytesBase58) => { + return await parentEpml.request('apiCall', { + type: 'api', + method: 'POST', + url: `/transactions/convert`, + body: `${transactionBytesBase58}` + }) + } + + const getArbitraryFee = async () => { + const timestamp = Date.now() + + let fee = await parentEpml.request('apiCall', { + url: `/transactions/unitfee?txType=ARBITRARY×tamp=${timestamp}` + }) + + return { + timestamp, + fee: Number(fee), + feeToShow: (Number(fee) / 1e8).toFixed(8) + } + } + + const signAndProcess = async (transactionBytesBase58) => { + let convertedBytesBase58 = await convertBytesForSigning( + transactionBytesBase58 + ) + + if (convertedBytesBase58.error) { + throw new Error('Error when signing') + } + + const convertedBytes = window.parent.Base58.decode(convertedBytesBase58) + + let nonce = null + + const computPath = window.parent.location.origin + '/memory-pow/memory-pow.wasm.full' + + await new Promise((res, rej) => { + worker.postMessage({ convertedBytes, path: computPath }) + + worker.onmessage = e => { + worker.terminate() + nonce = e.data.nonce + res() + } + }) + + let response = await parentEpml.request('sign_arbitrary', { + nonce: selectedAddress.nonce, + arbitraryBytesBase58: transactionBytesBase58, + arbitraryBytesForSigningBase58: convertedBytesBase58, + arbitraryNonce: nonce, + apiVersion: apiVersion ? apiVersion : null + }) + + let myResponse = { error: '' } + + if (response === false) { + throw new Error('Error when signing') + } else { + myResponse = response + } + + return myResponse + } + + const signAndProcessWithFee = async (transactionBytesBase58) => { + let convertedBytesBase58 = await convertBytesForSigning( + transactionBytesBase58 + ) + + if (convertedBytesBase58.error) { + throw new Error('Error when signing') + } + + let response = await parentEpml.request('sign_arbitrary_with_fee', { + nonce: selectedAddress.nonce, + arbitraryBytesBase58: transactionBytesBase58, + arbitraryBytesForSigningBase58: convertedBytesBase58, + apiVersion: apiVersion ? apiVersion : null + }) + + let myResponse = { error: '' } + + if (response === false) { + throw new Error('Error when signing') + } else { + myResponse = response + } + + return myResponse + } + + const validate = async () => { + let validNameRes = await validateName(registeredName) + + if (validNameRes.error) { + throw new Error('Name not found') + } + + let fee = null + + if (withFee && feeAmount) { + fee = feeAmount + } else if (withFee) { + const res = await getArbitraryFee() + + if (res.fee) { + fee = res.fee + } else { + throw new Error('unable to get fee') + } + } + + let transactionBytes = await uploadData(registeredName, path, file, fee) + + if (transactionBytes.error) { + throw new Error(transactionBytes.message || 'Error when uploading') + } else if (transactionBytes.includes('Error 500 Internal Server Error')) { + throw new Error('Error when uploading') + } + + let signAndProcessRes + + if (withFee) { + signAndProcessRes = await signAndProcessWithFee(transactionBytes) + } + + if (!withFee) { + signAndProcessRes = await signAndProcess(transactionBytes) + } + + if (signAndProcessRes.error) { + throw new Error('Error when signing') + } + + return signAndProcessRes + } + + const uploadData = async (registeredName, path, file, fee) => { + if (identifier != null && identifier.trim().length > 0) { + let postBody = path + let urlSuffix = '' + + if (file != null) { + // If we're sending zipped data, make sure to use the /zip version of the POST /arbitrary/* API + if (uploadType === 'zip') { + urlSuffix = '/zip' + } + + // If we're sending file data, use the /base64 version of the POST /arbitrary/* API + else if (uploadType === 'file') { + urlSuffix = '/base64' + } + + // Base64 encode the file to work around compatibility issues between javascript and java byte arrays + if (isBase64) { + postBody = file + } + + if (!isBase64) { + let fileBuffer = new Uint8Array(await file.arrayBuffer()) + postBody = Buffer.from(fileBuffer).toString("base64") + } + + } + + let uploadDataUrl = `/arbitrary/${service}/${registeredName}${urlSuffix}?apiKey=${getApiKey()}` + + if (identifier.trim().length > 0) { + uploadDataUrl = `/arbitrary/${service}/${registeredName}/${identifier}${urlSuffix}?apiKey=${getApiKey()}` + } + + if (withFee) { + uploadDataUrl = uploadDataUrl + `&fee=${fee}` + } + + if (filename != null && filename != 'undefined') { + uploadDataUrl = uploadDataUrl + '&filename=' + encodeURIComponent(filename) + } + + if (title != null && title != 'undefined') { + uploadDataUrl = uploadDataUrl + '&title=' + encodeURIComponent(title) + } + + if (description != null && description != 'undefined') { + uploadDataUrl = uploadDataUrl + '&description=' + encodeURIComponent(description) + } + + if (category != null && category != 'undefined') { + uploadDataUrl = uploadDataUrl + '&category=' + encodeURIComponent(category) + } + + if (tag1 != null && tag1 != 'undefined') { + uploadDataUrl = uploadDataUrl + '&tags=' + encodeURIComponent(tag1) + } + + if (tag2 != null && tag2 != 'undefined') { + uploadDataUrl = uploadDataUrl + '&tags=' + encodeURIComponent(tag2) + } + + if (tag3 != null && tag3 != 'undefined') { + uploadDataUrl = uploadDataUrl + '&tags=' + encodeURIComponent(tag3) + } + + if (tag4 != null && tag4 != 'undefined') { + uploadDataUrl = uploadDataUrl + '&tags=' + encodeURIComponent(tag4) + } + + if (tag5 != null && tag5 != 'undefined') { + uploadDataUrl = uploadDataUrl + '&tags=' + encodeURIComponent(tag5) + } + + return await parentEpml.request('apiCall', { + type: 'api', + method: 'POST', + url: `${uploadDataUrl}`, + body: `${postBody}` + }) + } + } + + try { + return await validate() + } catch (error) { + throw new Error(error.message) + } +} \ No newline at end of file diff --git a/plugins/plugins/utils/cropAddress.js b/plugins/plugins/utils/cropAddress.js deleted file mode 100644 index 8c0c3f1b..00000000 --- a/plugins/plugins/utils/cropAddress.js +++ /dev/null @@ -1,8 +0,0 @@ -export function cropAddress(string = "", range = 5) { - const [start, end] = [ - string?.substring(0, range), - string?.substring(string?.length - range, string?.length), - // - ]; - return start + "..." + end; -} diff --git a/plugins/plugins/utils/functions.js b/plugins/plugins/utils/functions.js new file mode 100644 index 00000000..138a7b7b --- /dev/null +++ b/plugins/plugins/utils/functions.js @@ -0,0 +1,208 @@ +import { Epml } from '../../epml' + +const parentEpml = new Epml({ type: 'WINDOW', source: window.parent }) + +export const inputKeyCodes = [ + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, + 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, + 85, 86, 87, 88, 89, 90, 96, 97, 98, 99, 100, 101, + 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, + 160, 161, 162, 163, 164, 165, 170, 171, 186, 187, + 188, 189, 190, 191, 192, 193, 194, 219, 220, 221, + 222, 223, 226 +] + +export const blocksNeed = (level) => { + if (level === 0) { + return '7200' + } else if (level === 1) { + return '72000' + } else if (level === 2) { + return '201600' + } else if (level === 3) { + return '374400' + } else if (level === 4) { + return '618400' + } else if (level === 5) { + return '964000' + } else if (level === 6) { + return '1482400' + } else if (level === 7) { + return '2173600' + } else if (level === 8) { + return '3037600' + } else if (level === 9) { + return '4074400' + } +} + +export const getUserNameFromAddress = async (address) => { + try { + const getNames = await parentEpml.request("apiCall", { + type: "api", + url: `/names/address/${address}` + }) + + if (Array.isArray(getNames) && getNames.length > 0 ) { + return getNames[0].name + } else { + return address + } + } catch (error) { + console.error(error) + } +} + +export const replaceMessagesEdited = async ({ decodedMessages, parentEpml, isReceipient, decodeMessageFunc, _publicKey, addToUpdateMessageHashmap }) => { + const MAX_CONCURRENT_REQUESTS = 5 // Maximum number of concurrent requests + + const executeWithConcurrencyLimit = async (array, asyncFn) => { + const results = [] + const concurrencyPool = [] + + for (const item of array) { + const promise = asyncFn(item) + concurrencyPool.push(promise) + + if (concurrencyPool.length >= MAX_CONCURRENT_REQUESTS) { + results.push(...await Promise.all(concurrencyPool)) + concurrencyPool.length = 0 // Clear the concurrency pool + } + } + + if (concurrencyPool.length > 0) { + results.push(...await Promise.all(concurrencyPool)) + } + + return results + } + + const findUpdatedMessage = async (msg) => { + let msgItem = { ...msg } + + try { + let msgQuery = `&involving=${msg.recipient}&involving=${msg.sender}` + if (!isReceipient) { + msgQuery = `&txGroupId=${msg.txGroupId}` + } + + // Find new messages first + const newMsgResponse = await parentEpml.request("apiCall", { + type: "api", + url: `/chat/messages?chatreference=${msg.signature}&reverse=true${msgQuery}&limit=1&sender=${msg.sender}&encoding=BASE64` + }) + + if (Array.isArray(newMsgResponse) && newMsgResponse.length > 0) { + const decodeResponseItem = decodeMessageFunc(newMsgResponse[0], isReceipient, _publicKey) + + delete decodeResponseItem.timestamp + + msgItem = { + ...msgItem, + ...decodeResponseItem, + senderName: msg.senderName, + sender: msg.sender, + editedTimestamp: newMsgResponse[0].timestamp, + originalSignature: msg.signature + } + } + + // Then check and find replies in the same iteration + let parsedMessageObj + + try { + parsedMessageObj = JSON.parse(msg.decodedMessage) + } catch (error) { + // If parsing fails, return the msgItem as is + return msgItem + } + + if (parsedMessageObj.repliedTo) { + let originalReply + + if (+parsedMessageObj.version > 2) { + originalReply = await parentEpml.request("apiCall", { + type: "api", + url: `/chat/message/${parsedMessageObj.repliedTo}?encoding=BASE64` + }) + } else { + originalReply = await parentEpml.request("apiCall", { + type: "api", + url: `/chat/messages?reference=${parsedMessageObj.repliedTo}&reverse=true${msgQuery}&encoding=BASE64` + }) + } + + const originalReplyMessage = originalReply.timestamp ? originalReply : originalReply.length > 0 ? originalReply[0] : null + + const replyResponse = await parentEpml.request("apiCall", { + type: "api", + url: `/chat/messages?chatreference=${parsedMessageObj.repliedTo}&reverse=true${msgQuery}&limit=1&sender=${originalReplyMessage.sender}&encoding=BASE64` + }) + + if (originalReplyMessage && Array.isArray(replyResponse) && replyResponse.length !== 0) { + const decodeOriginalReply = decodeMessageFunc(originalReplyMessage, isReceipient, _publicKey) + const decodeUpdatedReply = decodeMessageFunc(replyResponse[0], isReceipient, _publicKey) + + msgItem.repliedToData = { + ...decodeUpdatedReply, + senderName: decodeOriginalReply.senderName, + sender: decodeOriginalReply.sender + } + } else if (originalReplyMessage) { + msgItem.repliedToData = decodeMessageFunc(originalReplyMessage, isReceipient, _publicKey) + } + } + + } catch (error) { + // Handle or log the error gracefully + console.error(error) + } + + return msgItem + } + + const sortedMessages = decodedMessages.sort((a, b) => b.timestamp - a.timestamp) + + // Execute the functions with concurrency limit + const updatedMessages = await executeWithConcurrencyLimit(sortedMessages, findUpdatedMessage) + addToUpdateMessageHashmap(updatedMessages) + + return updatedMessages +} + +export function bytesToMegabytes(bytes) { + return bytes / (1024 * 1024) +} + +export function cropAddress(string = '', range = 5) { + const [start, end] = [ + string?.substring(0, range), + string?.substring(string?.length - range, string?.length) + ] + + return start + '...' + end +} + +export function roundToNearestDecimal(num) { + const mb = num / 1000000 + return Math.round(mb * 10) / 10 +} + +export function simpleHash(str) { + let hash = 0 + + for (let i = 0; i < str.length; i++) { + hash = (hash << 5) - hash + str.charCodeAt(i) + hash = hash & hash // Convert to 32bit integer + } + + return hash.toString() +} + +export function generateIdFromAddresses(address1, address2) { + // Sort addresses lexicographically and concatenate + const sortedAddresses = [address1, address2].sort().join('') + + return simpleHash(sortedAddresses) +} \ No newline at end of file diff --git a/plugins/plugins/utils/getUserNameFromAddress.js b/plugins/plugins/utils/getUserNameFromAddress.js deleted file mode 100644 index be8a3d69..00000000 --- a/plugins/plugins/utils/getUserNameFromAddress.js +++ /dev/null @@ -1,20 +0,0 @@ -import {Epml} from '../../epml.js'; - -const parentEpml = new Epml({ type: 'WINDOW', source: window.parent }) - -export const getUserNameFromAddress = async (address) => { - try { - const getNames = await parentEpml.request("apiCall", { - type: "api", - url: `/names/address/${address}`, - }); - - if (Array.isArray(getNames) && getNames.length > 0 ) { - return getNames[0].name; - } else { - return address; - } - } catch (error) { - console.error(error); - } -} diff --git a/plugins/plugins/utils/id-generation.js b/plugins/plugins/utils/id-generation.js deleted file mode 100644 index 88323156..00000000 --- a/plugins/plugins/utils/id-generation.js +++ /dev/null @@ -1,14 +0,0 @@ -export function simpleHash(str) { - let hash = 0; - for (let i = 0; i < str.length; i++) { - hash = (hash << 5) - hash + str.charCodeAt(i); - hash = hash & hash; // Convert to 32bit integer - } - return hash.toString(); -} - -export function generateIdFromAddresses(address1, address2) { - // Sort addresses lexicographically and concatenate - const sortedAddresses = [address1, address2].sort().join(''); - return simpleHash(sortedAddresses); -} \ No newline at end of file diff --git a/plugins/plugins/utils/keyCodes.js b/plugins/plugins/utils/keyCodes.js deleted file mode 100644 index d4d6ca50..00000000 --- a/plugins/plugins/utils/keyCodes.js +++ /dev/null @@ -1 +0,0 @@ -export const inputKeyCodes = [48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 160, 161, 162, 163, 164, 165, 170, 171, 186, 187, 188, 189, 190, 191, 192, 193, 194, 219, 220, 221, 222, 223, 226]; diff --git a/plugins/plugins/utils/loader.js b/plugins/plugins/utils/loader.js deleted file mode 100644 index 18123c3d..00000000 --- a/plugins/plugins/utils/loader.js +++ /dev/null @@ -1,52 +0,0 @@ -export class Loader { - constructor() { - this.loader = document.createElement("div"); - this.loader.className = "loader"; - this.loader.innerHTML = ` -
    - `; - this.styles = document.createElement("style"); - this.styles.innerHTML = ` - .loader { - position: fixed; - top: 0; - left: 0; - right: 0; - bottom: 0; - background-color: rgba(0, 0, 0, 0.5); - display: flex; - justify-content: center; - align-items: center; - z-index: 1000001 - } - - .loader-spinner { - border: 4px solid #f3f3f3; - border-top: 4px solid #3498db; - border-radius: 50%; - width: 32px; - height: 32px; - animation: spin 1s linear infinite; - } - - @keyframes spin { - from { transform: rotate(0deg); } - to { transform: rotate(360deg); } - } - `; - } - - show() { - document.head.appendChild(this.styles); - document.body.appendChild(this.loader); - } - - hide() { - if (this.loader.parentNode) { - this.loader.parentNode.removeChild(this.loader); - } - if (this.styles.parentNode) { - this.styles.parentNode.removeChild(this.styles); - } - } - } \ No newline at end of file diff --git a/plugins/plugins/utils/publish-image.js b/plugins/plugins/utils/publish-image.js deleted file mode 100644 index cc408a32..00000000 --- a/plugins/plugins/utils/publish-image.js +++ /dev/null @@ -1,248 +0,0 @@ -const getApiKey = () => { - const myNode = - window.parent.reduxStore.getState().app.nodeConfig.knownNodes[ - window.parent.reduxStore.getState().app.nodeConfig.node - ] - return myNode.apiKey -} - -export const publishData = async ({ - registeredName, - path, - file, - service, - identifier, - parentEpml, - uploadType, - selectedAddress, - worker, - isBase64, - filename, - apiVersion, - withFee, - title, - description, - category, - tag1, - tag2, - tag3, - tag4, - tag5, - feeAmount -}) => { - const validateName = async (receiverName) => { - return await parentEpml.request("apiCall", { - type: "api", - url: `/names/${receiverName}`, - }) - } - - const convertBytesForSigning = async (transactionBytesBase58) => { - return await parentEpml.request("apiCall", { - type: "api", - method: "POST", - url: `/transactions/convert`, - body: `${transactionBytesBase58}`, - }) - } - const getArbitraryFee = async () => { - const timestamp = Date.now() - let fee = await parentEpml.request('apiCall', { - url: `/transactions/unitfee?txType=ARBITRARY×tamp=${timestamp}` - }) - return { - timestamp, - fee : Number(fee), - feeToShow: (Number(fee) / 1e8).toFixed(8) - } - } - - const signAndProcess = async (transactionBytesBase58) => { - let convertedBytesBase58 = await convertBytesForSigning( - transactionBytesBase58 - ) - if (convertedBytesBase58.error) { - throw new Error('Error when signing'); - } - - const convertedBytes = - window.parent.Base58.decode(convertedBytesBase58) - let nonce = null - const computPath =window.parent.location.origin + '/memory-pow/memory-pow.wasm.full' - await new Promise((res, rej) => { - - worker.postMessage({convertedBytes, path: computPath}); - - worker.onmessage = e => { - - worker.terminate() - - nonce = e.data.nonce - res() - - } - }) - - - let response = await parentEpml.request("sign_arbitrary", { - nonce: selectedAddress.nonce, - arbitraryBytesBase58: transactionBytesBase58, - arbitraryBytesForSigningBase58: convertedBytesBase58, - arbitraryNonce: nonce, - apiVersion: apiVersion ? apiVersion : null - }) - let myResponse = { error: "" } - if (response === false) { - throw new Error('Error when signing'); - } else { - myResponse = response - } - - return myResponse - } - - const signAndProcessWithFee = async (transactionBytesBase58) => { - let convertedBytesBase58 = await convertBytesForSigning( - transactionBytesBase58 - ) - if (convertedBytesBase58.error) { - throw new Error('Error when signing'); - } - - - - - let response = await parentEpml.request("sign_arbitrary_with_fee", { - nonce: selectedAddress.nonce, - arbitraryBytesBase58: transactionBytesBase58, - arbitraryBytesForSigningBase58: convertedBytesBase58, - apiVersion: apiVersion ? apiVersion : null - }) - let myResponse = { error: "" } - if (response === false) { - throw new Error('Error when signing'); - } else { - myResponse = response - } - - return myResponse - } - - const validate = async () => { - let validNameRes = await validateName(registeredName) - if (validNameRes.error) { - throw new Error('Name not found'); - } - let fee = null - if(withFee && feeAmount){ - fee= feeAmount - } else if(withFee){ - const res = await getArbitraryFee() - if(res.fee){ - fee= res.fee - } else { - throw new Error('unable to get fee') - } - } - let transactionBytes = await uploadData(registeredName, path, file, fee) - if (transactionBytes.error) { - throw new Error(transactionBytes.message || 'Error when uploading'); - } else if ( - transactionBytes.includes("Error 500 Internal Server Error") - ) { - throw new Error('Error when uploading'); - } - - let signAndProcessRes - if(withFee){ - signAndProcessRes = await signAndProcessWithFee(transactionBytes) - - } - if(!withFee){ - signAndProcessRes = await signAndProcess(transactionBytes) - - } - if (signAndProcessRes.error) { - throw new Error('Error when signing'); - } - return signAndProcessRes - } - - const uploadData = async (registeredName, path, file, fee) => { - if (identifier != null && identifier.trim().length > 0) { - let postBody = path - let urlSuffix = "" - if (file != null) { - // If we're sending zipped data, make sure to use the /zip version of the POST /arbitrary/* API - if (uploadType === "zip") { - urlSuffix = "/zip" - } - // If we're sending file data, use the /base64 version of the POST /arbitrary/* API - else if (uploadType === "file") { - urlSuffix = "/base64" - } - - // Base64 encode the file to work around compatibility issues between javascript and java byte arrays - if(isBase64){ - postBody = file - } - if(!isBase64){ - let fileBuffer = new Uint8Array(await file.arrayBuffer()) - postBody = Buffer.from(fileBuffer).toString("base64") - } - - } - - let uploadDataUrl = `/arbitrary/${service}/${registeredName}${urlSuffix}?apiKey=${getApiKey()}` - if (identifier.trim().length > 0) { - uploadDataUrl = `/arbitrary/${service}/${registeredName}/${identifier}${urlSuffix}?apiKey=${getApiKey()}` - - } - - if(withFee){ - uploadDataUrl = uploadDataUrl + `&fee=${fee}` - } - - if(filename != null && filename != "undefined"){ - uploadDataUrl = uploadDataUrl + '&filename=' + encodeURIComponent(filename) - } - if(title != null && title != "undefined"){ - uploadDataUrl = uploadDataUrl + '&title=' + encodeURIComponent(title) - } - if(description != null && description != "undefined"){ - uploadDataUrl = uploadDataUrl + '&description=' + encodeURIComponent(description) - } - if(category != null && category != "undefined"){ - uploadDataUrl = uploadDataUrl + '&category=' + encodeURIComponent(category) - } - if(tag1 != null && tag1 != "undefined"){ - uploadDataUrl = uploadDataUrl + '&tags=' + encodeURIComponent(tag1) - } - if(tag2 != null && tag2 != "undefined"){ - uploadDataUrl = uploadDataUrl + '&tags=' + encodeURIComponent(tag2) - } - if(tag3 != null && tag3 != "undefined"){ - uploadDataUrl = uploadDataUrl + '&tags=' + encodeURIComponent(tag3) - } - if(tag4 != null && tag4 != "undefined"){ - uploadDataUrl = uploadDataUrl + '&tags=' + encodeURIComponent(tag4) - } - if(tag5 != null && tag5 != "undefined"){ - uploadDataUrl = uploadDataUrl + '&tags=' + encodeURIComponent(tag5) - } - - return await parentEpml.request("apiCall", { - type: "api", - method: "POST", - url: `${uploadDataUrl}`, - body: `${postBody}`, - }) - } - } - try { - return await validate() - } catch (error) { - throw new Error(error.message) - } - -} diff --git a/plugins/plugins/utils/publish-modal.css b/plugins/plugins/utils/publish-modal.css deleted file mode 100644 index f5ded060..00000000 --- a/plugins/plugins/utils/publish-modal.css +++ /dev/null @@ -1,147 +0,0 @@ -.backdrop { - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - background: rgb(186 186 186 / 26%); - overflow: hidden; - animation: backdrop_blur cubic-bezier(0.22, 1, 0.36, 1) 1s forwards; - z-index: 1000000; -} - -@keyframes backdrop_blur { - 0% { - backdrop-filter: blur(0px); - background: transparent; - } - 100% { - backdrop-filter: blur(5px); - background: rgb(186 186 186 / 26%); - } -} - -@keyframes modal_transition { - 0% { - visibility: hidden; - opacity: 0; -} - 100% { - visibility: visible; - opacity: 1; - } -} - -.modal { - position: relative; - display: flex; - justify-content: center; - align-items: center; - width: 100%; - height: 100%; - animation: 1s cubic-bezier(0.22, 1, 0.36, 1) 0s 1 normal forwards running modal_transition; - z-index: 1000001; -} - -@keyframes modal_transition { - 0% { - visibility: hidden; - opacity: 0; - } - 100% { - visibility: visible; - opacity: 1; - } -} - -.modal-content { - background-color: var(--white); - border-radius: 10px; - padding: 20px; - box-shadow: 0 0 10px rgba(0, 0, 0, 0.3); - max-width: 80%; - min-width: 300px; - display: flex; - flex-direction: column; - justify-content: space-between; -} - -.modal-body { - padding: 25px; -} - -.modal-subcontainer { - color: var(--black); - display: flex; - flex-direction: column; - align-items: flex-start; - gap: 15px; -} - -.modal-subcontainer-error { - color: var(--black); - display: flex; - flex-direction: column; - align-items: center; - gap: 15px; -} - -.modal-paragraph-error { - font-family: Roboto, sans-serif; - font-size: 20px; - letter-spacing: 0.3px; - font-weight: 700; - color: var(--black); - margin: 0; -} - -.modal-paragraph { - font-family: Roboto, sans-serif; - font-size: 18px; - letter-spacing: 0.3px; - font-weight: 300; - color: var(--black); - margin: 0; - word-wrap: break-word; - overflow-wrap: break-word; -} - -.capitalize-first { - text-transform: capitalize; -} - -.checkbox-row { - display: flex; - align-items: center; - font-family: Montserrat, sans-serif; - font-weight: 600; - color: var(--black); -} - -.modal-buttons { - display: flex; - justify-content: space-between; - margin-top: 20px; -} - -.modal-buttons button { - background-color: #4caf50; - border: none; - color: #fff; - padding: 10px 20px; - border-radius: 5px; - cursor: pointer; - transition: background-color 0.2s; -} - -.modal-buttons button:hover { - background-color: #3e8e41; -} - -#cancel-button { - background-color: #f44336; -} - -#cancel-button:hover { - background-color: #d32f2f; -} \ No newline at end of file diff --git a/plugins/plugins/utils/publish-modal.js b/plugins/plugins/utils/publish-modal.js deleted file mode 100644 index 76c60f67..00000000 --- a/plugins/plugins/utils/publish-modal.js +++ /dev/null @@ -1,270 +0,0 @@ -import {get} from '../../../core/translate' - -export class ModalHelper { - constructor() { - this.initializeStyles(); - } - - async getArbitraryFee() { - const timestamp = Date.now(); - const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]; - const nodeUrl = `${myNode.protocol}://${myNode.domain}:${myNode.port}`; - const url = `${nodeUrl}/transactions/unitfee?txType=ARBITRARY×tamp=${timestamp}`; - const response = await fetch(url); - - if (!response.ok) { - throw new Error('Error when fetching arbitrary fee'); - } - - const data = await response.json(); - const arbitraryFee = (Number(data) / 1e8).toFixed(8); - return { - timestamp, - fee: Number(data), - feeToShow: arbitraryFee - }; - } - - async showModalAndWaitPublish(data) { - return new Promise((resolve) => { - const modal = this.createModal(data); - document.body.appendChild(modal); - this.addModalEventListeners(modal, resolve); - }); - } - - createModal(data) { - const modal = document.createElement('div'); - modal.id = "backdrop"; - modal.classList.add("backdrop"); - modal.innerHTML = ` - - `; - return modal; - } - - addModalEventListeners(modal, resolve) { - // Event listener for the 'OK' button - const okButton = modal.querySelector('#ok-button'); - okButton.addEventListener('click', () => { - const userData = { isWithFee: true }; - if (modal.parentNode === document.body) { - document.body.removeChild(modal); - } - resolve({ action: 'accept', userData }); - }); - - // Prevent modal content from closing the modal - const modalContent = modal.querySelector('.modal-content'); - modalContent.addEventListener('click', e => { - e.stopPropagation(); - }); - - // Event listeners for backdrop and 'Cancel' button - const backdropClick = document.getElementById('backdrop'); - backdropClick.addEventListener('click', () => { - if (modal.parentNode === document.body) { - document.body.removeChild(modal); - } - resolve({ action: 'reject' }); - }); - - const cancelButton = modal.querySelector('#cancel-button'); - cancelButton.addEventListener('click', () => { - if (modal.parentNode === document.body) { - document.body.removeChild(modal); - } - resolve({ action: 'reject' }); - }); - } - - initializeStyles() { - const styles = ` - * { - --mdc-theme-primary: rgb(3, 169, 244); - --mdc-theme-secondary: var(--mdc-theme-primary); - --paper-input-container-focus-color: var(--mdc-theme-primary); - --mdc-checkbox-unchecked-color: var(--black); - --mdc-theme-on-surface: var(--black); - --mdc-checkbox-disabled-color: var(--black); - --mdc-checkbox-ink-color: var(--black); - } - - .backdrop { - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - background: rgb(186 186 186 / 26%); - overflow: hidden; - animation: backdrop_blur cubic-bezier(0.22, 1, 0.36, 1) 0.1s forwards; - z-index: 1000000; - } - - @keyframes backdrop_blur { - 0% { - backdrop-filter: blur(0px); - background: transparent; - } - 100% { - backdrop-filter: blur(5px); - background: rgb(186 186 186 / 26%); - } - } - - @keyframes modal_transition { - 0% { - visibility: hidden; - opacity: 0; - } - 100% { - visibility: visible; - opacity: 1; - } - } - - .modal { - position: relative; - display: flex; - justify-content: center; - align-items: center; - width: 100%; - height: 100%; - animation: 0.1s cubic-bezier(0.22, 1, 0.36, 1) 0s 1 normal forwards running modal_transition; - z-index: 1000001; - } - - @keyframes modal_transition { - 0% { - visibility: hidden; - opacity: 0; - } - 100% { - visibility: visible; - opacity: 1; - } - } - - .modal-content { - background-color: var(--white); - border-radius: 10px; - padding: 20px; - box-shadow: 0 0 10px rgba(0, 0, 0, 0.3); - max-width: 80%; - min-width: 300px; - display: flex; - flex-direction: column; - justify-content: space-between; - } - - .modal-body { - padding: 25px; - } - - .modal-subcontainer { - color: var(--black); - display: flex; - flex-direction: column; - align-items: flex-start; - gap: 15px; - } - - .modal-subcontainer-error { - color: var(--black); - display: flex; - flex-direction: column; - align-items: center; - gap: 15px; - } - - .modal-paragraph-error { - font-family: Roboto, sans-serif; - font-size: 20px; - letter-spacing: 0.3px; - font-weight: 700; - color: var(--black); - margin: 0; - } - - .modal-paragraph { - font-family: Roboto, sans-serif; - font-size: 18px; - letter-spacing: 0.3px; - font-weight: 300; - color: var(--black); - margin: 0; - word-wrap: break-word; - overflow-wrap: break-word; - } - - .capitalize-first { - text-transform: capitalize; - } - - .checkbox-row { - display: flex; - align-items: center; - font-family: Montserrat, sans-serif; - font-weight: 600; - color: var(--black); - } - - .modal-buttons { - display: flex; - justify-content: space-between; - margin-top: 20px; - } - - .modal-buttons button { - background-color: #4caf50; - border: none; - color: #fff; - padding: 10px 20px; - border-radius: 5px; - cursor: pointer; - transition: background-color 0.2s; - } - - .modal-buttons button:hover { - background-color: #3e8e41; - } - - #cancel-button { - background-color: #f44336; - } - - #cancel-button:hover { - background-color: #d32f2f; - } - `; - - const styleSheet = new CSSStyleSheet(); - styleSheet.replaceSync(styles); - - document.adoptedStyleSheets = [styleSheet]; - } - - static getInstance() { - if (!ModalHelper.instance) { - ModalHelper.instance = new ModalHelper(); - } - return ModalHelper.instance; - } -} - -export const modalHelper = ModalHelper.getInstance(); diff --git a/plugins/plugins/utils/queue.js b/plugins/plugins/utils/queue.js deleted file mode 100644 index f4b9ff62..00000000 --- a/plugins/plugins/utils/queue.js +++ /dev/null @@ -1,71 +0,0 @@ -export class RequestQueue { - constructor(maxConcurrent = 5) { - this.queue = []; - this.maxConcurrent = maxConcurrent; - this.currentConcurrent = 0; - } - - push(request) { - return new Promise((resolve, reject) => { - this.queue.push({ - request, - resolve, - reject, - }); - this.checkQueue(); - }); - } - - checkQueue() { - if (this.queue.length === 0 || this.currentConcurrent >= this.maxConcurrent) return; - - const { request, resolve, reject } = this.queue.shift(); - this.currentConcurrent++; - - request() - .then(resolve) - .catch(reject) - .finally(() => { - this.currentConcurrent--; - this.checkQueue(); - }); - } -} - -export class RequestQueueWithPromise { - constructor(maxConcurrent = 5) { - this.queue = []; - this.maxConcurrent = maxConcurrent; - this.currentlyProcessing = 0; - } - - // Add a request to the queue and return a promise - enqueue(request) { - return new Promise((resolve, reject) => { - // Push the request and its resolve and reject callbacks to the queue - this.queue.push({ request, resolve, reject }); - this.process(); - }); - } - - // Process requests in the queue - async process() { - while (this.queue.length > 0 && this.currentlyProcessing < this.maxConcurrent) { - this.currentlyProcessing++; - const { request, resolve, reject } = this.queue.shift(); - try { - const response = await request(); - resolve(response); - } catch (error) { - reject(error); - } finally { - this.currentlyProcessing--; - await this.process(); - } - } - } - } - - - - diff --git a/plugins/plugins/utils/replace-messages-edited.js b/plugins/plugins/utils/replace-messages-edited.js deleted file mode 100644 index 129a4a8b..00000000 --- a/plugins/plugins/utils/replace-messages-edited.js +++ /dev/null @@ -1,251 +0,0 @@ -// export const replaceMessagesEdited = async ({ -// decodedMessages, -// parentEpml, -// isReceipient, -// decodeMessageFunc, -// _publicKey, -// addToUpdateMessageHashmap -// }) => { -// const findNewMessages = decodedMessages.map(async (msg) => { -// let msgItem = null -// try { -// let msgQuery = `&involving=${msg.recipient}&involving=${msg.sender}` -// if (!isReceipient) { -// msgQuery = `&txGroupId=${msg.txGroupId}` -// } -// const response = await parentEpml.request("apiCall", { -// type: "api", -// url: `/chat/messages?chatreference=${msg.signature}&reverse=true${msgQuery}&limit=1&sender=${msg.sender}&encoding=BASE64`, -// }) - -// if (response && Array.isArray(response) && response.length !== 0) { -// let responseItem = { ...response[0] } -// const decodeResponseItem = decodeMessageFunc(responseItem, isReceipient, _publicKey) -// delete decodeResponseItem.timestamp - -// msgItem = { -// ...msg, -// ...decodeResponseItem, -// senderName: msg.senderName, -// sender: msg.sender, -// editedTimestamp: response[0].timestamp, -// originalSignature: msg.signature -// } -// } -// } catch (error) { -// } - -// return msgItem -// }) -// const updateMessages = await Promise.all(findNewMessages) -// const filterOutNull = updateMessages.filter((item)=> item !== 'null' && item !== null) - -// const findNewMessages2 = filterOutNull.map(async (msg) => { -// let parsedMessageObj = msg -// try { -// parsedMessageObj = JSON.parse(msg.decodedMessage) -// } catch (error) { -// return msg -// } -// let msgItem = msg -// try { -// let msgQuery = `&involving=${msg.recipient}&involving=${msg.sender}` -// if (!isReceipient) { -// msgQuery = `&txGroupId=${msg.txGroupId}` -// } -// if (parsedMessageObj.repliedTo) { -// let originalReply -// if(+parsedMessageObj.version > 2){ -// originalReply = await parentEpml.request("apiCall", { -// type: "api", -// url: `/chat/message/${parsedMessageObj.repliedTo}?encoding=BASE64`, -// }) -// } -// if(+parsedMessageObj.version < 3){ -// originalReply = await parentEpml.request("apiCall", { -// type: "api", -// url: `/chat/messages?reference=${parsedMessageObj.repliedTo}&reverse=true${msgQuery}&encoding=BASE64`, -// }) -// } - - - - -// const originalReplyMessage = originalReply.timestamp ? originalReply : originalReply.length !== 0 ? originalReply[0] : null - -// const response = await parentEpml.request("apiCall", { -// type: "api", -// url: `/chat/messages?chatreference=${parsedMessageObj.repliedTo}&reverse=true${msgQuery}&limit=1&sender=${originalReplyMessage.sender}&encoding=BASE64`, -// }) - -// if ( -// originalReplyMessage && -// response && -// Array.isArray(response) && -// response.length !== 0 -// ) { -// const decodeOriginalReply = decodeMessageFunc(originalReplyMessage, isReceipient, _publicKey) - -// const decodeUpdatedReply = decodeMessageFunc(response[0], isReceipient, _publicKey) -// const formattedRepliedToData = { -// ...decodeUpdatedReply, -// senderName: decodeOriginalReply.senderName, -// sender: decodeOriginalReply.sender, -// } -// msgItem = { -// ...msg, -// repliedToData: formattedRepliedToData, -// } -// } else { - - -// if ( -// originalReplyMessage -// ) { - -// msgItem = { -// ...msg, -// repliedToData: decodeMessageFunc(originalReplyMessage, isReceipient, _publicKey), -// } -// } -// } -// } -// } catch (error) { -// } - -// return msgItem -// }) -// const updateMessages2 = await Promise.all(findNewMessages2) -// console.log({updateMessages2}) -// updateMessages2.forEach((item)=> { -// addToUpdateMessageHashmap(item.originalSignature, item) -// }) -// return updateMessages2 -// } - - -export const replaceMessagesEdited = async ({ - decodedMessages, - parentEpml, - isReceipient, - decodeMessageFunc, - _publicKey, - addToUpdateMessageHashmap -}) => { - const MAX_CONCURRENT_REQUESTS = 5; // Maximum number of concurrent requests - - const executeWithConcurrencyLimit = async (array, asyncFn) => { - const results = []; - const concurrencyPool = []; - - for (const item of array) { - const promise = asyncFn(item); - concurrencyPool.push(promise); - - if (concurrencyPool.length >= MAX_CONCURRENT_REQUESTS) { - results.push(...await Promise.all(concurrencyPool)); - concurrencyPool.length = 0; // Clear the concurrency pool - } - } - - if (concurrencyPool.length > 0) { - results.push(...await Promise.all(concurrencyPool)); - } - - return results; - }; - - const findUpdatedMessage = async (msg) => { - let msgItem = { ...msg }; - - try { - let msgQuery = `&involving=${msg.recipient}&involving=${msg.sender}`; - if (!isReceipient) { - msgQuery = `&txGroupId=${msg.txGroupId}`; - } - - // Find new messages first - const newMsgResponse = await parentEpml.request("apiCall", { - type: "api", - url: `/chat/messages?chatreference=${msg.signature}&reverse=true${msgQuery}&limit=1&sender=${msg.sender}&encoding=BASE64`, - }); - - if (Array.isArray(newMsgResponse) && newMsgResponse.length > 0) { - const decodeResponseItem = decodeMessageFunc(newMsgResponse[0], isReceipient, _publicKey); - delete decodeResponseItem.timestamp; - - msgItem = { - ...msgItem, - ...decodeResponseItem, - senderName: msg.senderName, - sender: msg.sender, - editedTimestamp: newMsgResponse[0].timestamp, - originalSignature: msg.signature - }; - } - - // Then check and find replies in the same iteration - let parsedMessageObj; - try { - parsedMessageObj = JSON.parse(msg.decodedMessage); - } catch (error) { - // If parsing fails, return the msgItem as is - return msgItem; - } - - if (parsedMessageObj.repliedTo) { - let originalReply; - if(+parsedMessageObj.version > 2){ - originalReply = await parentEpml.request("apiCall", { - type: "api", - url: `/chat/message/${parsedMessageObj.repliedTo}?encoding=BASE64`, - }); - } else { - originalReply = await parentEpml.request("apiCall", { - type: "api", - url: `/chat/messages?reference=${parsedMessageObj.repliedTo}&reverse=true${msgQuery}&encoding=BASE64`, - }); - } - - const originalReplyMessage = originalReply.timestamp ? originalReply : originalReply.length > 0 ? originalReply[0] : null; - - const replyResponse = await parentEpml.request("apiCall", { - type: "api", - url: `/chat/messages?chatreference=${parsedMessageObj.repliedTo}&reverse=true${msgQuery}&limit=1&sender=${originalReplyMessage.sender}&encoding=BASE64`, - }); - - if ( - originalReplyMessage && - Array.isArray(replyResponse) && - replyResponse.length !== 0 - ) { - const decodeOriginalReply = decodeMessageFunc(originalReplyMessage, isReceipient, _publicKey); - const decodeUpdatedReply = decodeMessageFunc(replyResponse[0], isReceipient, _publicKey); - - msgItem.repliedToData = { - ...decodeUpdatedReply, - senderName: decodeOriginalReply.senderName, - sender: decodeOriginalReply.sender, - }; - } else if (originalReplyMessage) { - msgItem.repliedToData = decodeMessageFunc(originalReplyMessage, isReceipient, _publicKey); - } - } - - } catch (error) { - // Handle or log the error gracefully - console.error(error); - } - - return msgItem; - }; - - const sortedMessages = decodedMessages.sort((a, b) => b.timestamp - a.timestamp); - - // Execute the functions with concurrency limit - const updatedMessages = await executeWithConcurrencyLimit(sortedMessages, findUpdatedMessage); - addToUpdateMessageHashmap(updatedMessages); - - return updatedMessages; - -}; diff --git a/plugins/plugins/utils/roundToNearestDecimal.js b/plugins/plugins/utils/roundToNearestDecimal.js deleted file mode 100644 index 5e3fe0aa..00000000 --- a/plugins/plugins/utils/roundToNearestDecimal.js +++ /dev/null @@ -1,4 +0,0 @@ -export function roundToNearestDecimal(num) { - const mb = num / 1000000; - return Math.round(mb * 10) / 10; -} \ No newline at end of file diff --git a/plugins/plugins/utils/warning-modal.js b/plugins/plugins/utils/warning-modal.js deleted file mode 100644 index 0399591f..00000000 --- a/plugins/plugins/utils/warning-modal.js +++ /dev/null @@ -1,252 +0,0 @@ -import {get} from '../../../core/translate' - -export class WarningModal { - constructor() { - this.initializeStyles(); - } - - - async showModalAndWaitPublish(data) { - return new Promise((resolve) => { - const modal = this.createModal(data); - document.body.appendChild(modal); - this.addModalEventListeners(modal, resolve); - }); - } - - createModal(data) { - const modal = document.createElement('div'); - modal.id = "backdrop"; - modal.classList.add("backdrop"); - modal.innerHTML = ` - - `; - return modal; - } - - addModalEventListeners(modal, resolve) { - // Event listener for the 'OK' button - const okButton = modal.querySelector('#ok-button'); - okButton.addEventListener('click', () => { - const userData = { isWithFee: true }; - if (modal.parentNode === document.body) { - document.body.removeChild(modal); - } - resolve({ action: 'accept', userData }); - }); - - // Prevent modal content from closing the modal - const modalContent = modal.querySelector('.modal-content'); - modalContent.addEventListener('click', e => { - e.stopPropagation(); - }); - - // Event listeners for backdrop and 'Cancel' button - const backdropClick = document.getElementById('backdrop'); - backdropClick.addEventListener('click', () => { - if (modal.parentNode === document.body) { - document.body.removeChild(modal); - } - resolve({ action: 'reject' }); - }); - - const cancelButton = modal.querySelector('#cancel-button'); - cancelButton.addEventListener('click', () => { - if (modal.parentNode === document.body) { - document.body.removeChild(modal); - } - resolve({ action: 'reject' }); - }); - } - - initializeStyles() { - const styles = ` - * { - --mdc-theme-primary: rgb(3, 169, 244); - --mdc-theme-secondary: var(--mdc-theme-primary); - --paper-input-container-focus-color: var(--mdc-theme-primary); - --mdc-checkbox-unchecked-color: var(--black); - --mdc-theme-on-surface: var(--black); - --mdc-checkbox-disabled-color: var(--black); - --mdc-checkbox-ink-color: var(--black); - } - - .backdrop { - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - background: rgb(186 186 186 / 26%); - overflow: hidden; - animation: backdrop_blur cubic-bezier(0.22, 1, 0.36, 1) 0.1s forwards; - z-index: 1000000; - } - - @keyframes backdrop_blur { - 0% { - backdrop-filter: blur(0px); - background: transparent; - } - 100% { - backdrop-filter: blur(5px); - background: rgb(186 186 186 / 26%); - } - } - - @keyframes modal_transition { - 0% { - visibility: hidden; - opacity: 0; - } - 100% { - visibility: visible; - opacity: 1; - } - } - - .modal { - position: relative; - display: flex; - justify-content: center; - align-items: center; - width: 100%; - height: 100%; - animation: 0.1s cubic-bezier(0.22, 1, 0.36, 1) 0s 1 normal forwards running modal_transition; - z-index: 1000001; - } - - @keyframes modal_transition { - 0% { - visibility: hidden; - opacity: 0; - } - 100% { - visibility: visible; - opacity: 1; - } - } - - .modal-content { - background-color: var(--white); - border-radius: 10px; - padding: 20px; - box-shadow: 0 0 10px rgba(0, 0, 0, 0.3); - max-width: 650px; - min-width: 300px; - display: flex; - flex-direction: column; - justify-content: space-between; - } - - .modal-body { - padding: 25px; - } - - .modal-subcontainer { - color: var(--black); - display: flex; - flex-direction: column; - align-items: flex-start; - gap: 15px; - } - - .modal-subcontainer-error { - color: var(--black); - display: flex; - flex-direction: column; - align-items: center; - gap: 15px; - } - - .modal-paragraph-error { - font-family: Roboto, sans-serif; - font-size: 20px; - letter-spacing: 0.3px; - font-weight: 700; - color: var(--black); - margin: 0; - } - - .modal-paragraph { - font-family: Roboto, sans-serif; - font-size: 18px; - letter-spacing: 0.3px; - font-weight: 300; - color: var(--black); - margin: 0; - word-wrap: break-word; - overflow-wrap: break-word; - } - - .capitalize-first { - text-transform: capitalize; - } - - .checkbox-row { - display: flex; - align-items: center; - font-family: Montserrat, sans-serif; - font-weight: 600; - color: var(--black); - } - - .modal-buttons { - display: flex; - justify-content: space-between; - margin-top: 20px; - } - - .modal-buttons button { - background-color: #4caf50; - border: none; - color: #fff; - padding: 10px 20px; - border-radius: 5px; - cursor: pointer; - transition: background-color 0.2s; - } - - .modal-buttons button:hover { - background-color: #3e8e41; - } - - #cancel-button { - background-color: #f44336; - } - - #cancel-button:hover { - background-color: #d32f2f; - } - `; - - const styleSheet = new CSSStyleSheet(); - styleSheet.replaceSync(styles); - - document.adoptedStyleSheets = [styleSheet]; - } - - - static getInstance() { - if (!WarningModal.instance) { - WarningModal.instance = new WarningModal(); - } - return WarningModal.instance; - } -} - -export const warningModal = WarningModal.getInstance(); diff --git a/plugins/watch.js b/plugins/watch.js index e42b9195..f6bb3998 100644 --- a/plugins/watch.js +++ b/plugins/watch.js @@ -1,5 +1,4 @@ const rollup = require('rollup') - const configs = require('./build-config.js')() const watch = () => { @@ -19,4 +18,4 @@ const watch = () => { console.log('WATCH PLUGINS ==> Write Bundle : Done 🎉') } -module.exports = watch +module.exports = watch \ No newline at end of file diff --git a/scripts/afterPack.js b/scripts/afterPack.js index 73bda2a0..f7084bd8 100644 --- a/scripts/afterPack.js +++ b/scripts/afterPack.js @@ -1,45 +1,39 @@ const path = require('path') -const shell = require("shelljs"); +const shell = require("shelljs") const runShellCommand = (appOutDir) => { + shell.exec( + `chmod 4755 ${path.join(appOutDir, "chrome-sandbox")}`, - shell.exec( - `chmod 4755 ${path.join(appOutDir, "chrome-sandbox")}`, - - function (code, stdout, stderr) { - console.log('runShellCommand ==> Exit code:', code); - if (stderr) { - console.log('runShellCommand ==> Program stderr:', stderr); - } - }); + function (code, stdout, stderr) { + console.log('runShellCommand ==> Exit code:', code) + if (stderr) { + console.log('runShellCommand ==> Program stderr:', stderr) + } + } + ) } async function doLinux(context) { + console.log("Running doLinux ==> ") - console.log("Running doLinux ==> "); + const { targets, appOutDir } = context - const { targets, appOutDir } = context - - targets.forEach(async target => { - - if (!["appimage", "snap"].includes(target.name.toLowerCase())) { - - await runShellCommand(appOutDir) - } - }); + targets.forEach(async target => { + if (!["appimage", "snap"].includes(target.name.toLowerCase())) { + await runShellCommand(appOutDir) + } + }) } async function afterPack(context) { + console.log("Running AfterPack") - console.log("Running AfterPack"); - - const electronPlatformName = context.electronPlatformName.toLowerCase(); - - if (electronPlatformName.includes("linux")) { - await doLinux(context); - - } + const electronPlatformName = context.electronPlatformName.toLowerCase() + if (electronPlatformName.includes("linux")) { + await doLinux(context) + } } -module.exports = afterPack +module.exports = afterPack \ No newline at end of file diff --git a/scripts/notarize.js b/scripts/notarize.js index f4541f5c..81a8f6c2 100644 --- a/scripts/notarize.js +++ b/scripts/notarize.js @@ -1,20 +1,21 @@ -require('dotenv').config(); -const { notarize } = require('@electron/notarize'); +require('dotenv').config() +const { notarize } = require('@electron/notarize') exports.default = async function notarizing(context) { - const { electronPlatformName, appOutDir } = context; - if (electronPlatformName !== 'darwin') { - return; - } + const { electronPlatformName, appOutDir } = context - const appName = context.packager.appInfo.productFilename; + if (electronPlatformName !== 'darwin') { + return + } - return await notarize({ - appBundleId: 'org.qortal.QortalUI', - appPath: `${appOutDir}/${appName}.app`, - tool: "notarytool", - teamId: process.env.APPLETEAMID, - appleId: process.env.APPLEID, - appleIdPassword: process.env.APPLEIDPASS, - }); -}; + const appName = context.packager.appInfo.productFilename + + return await notarize({ + appBundleId: 'org.qortal.QortalUI', + appPath: `${appOutDir}/${appName}.app`, + tool: "notarytool", + teamId: process.env.APPLETEAMID, + appleId: process.env.APPLEID, + appleIdPassword: process.env.APPLEIDPASS + }) +} \ No newline at end of file diff --git a/server.js b/server.js index c53090f3..fad65218 100644 --- a/server.js +++ b/server.js @@ -1,30 +1,24 @@ const path = require("path") - const uiCore = require('./core/ui-core.js') const createServer = uiCore('server') - const config = require('./config/config.js') - const pluginsController = require('./plugins/default-plugins.js') + const qortalPlugins = pluginsController('plugins') - -const plugins = [ - ...qortalPlugins -] - +const plugins = [...qortalPlugins] const rootDir = process.env.NODE_ENV === 'production' ? __dirname : __dirname - const conf = { - ...config, - build: { - ...config.build, - options: { - ...config.build.options, - outputDir: path.join(rootDir, '/builtWWW') - } - } + ...config, + build: { + ...config.build, + options: { + ...config.build.options, + outputDir: path.join(rootDir, '/builtWWW') + } + } } const server = createServer(conf, plugins) -server.start() + +server.start() \ No newline at end of file diff --git a/watch-inline.js b/watch-inline.js index e14bbe91..8a870f84 100644 --- a/watch-inline.js +++ b/watch-inline.js @@ -1,25 +1,24 @@ const path = require('path') const uiCore = require('./core/ui-core.js') +const config = require('./config/config.js') +const pluginsController = require('./plugins/default-plugins.js') + const generateBuildConfig = uiCore('generate_build_config') const watchInlines = uiCore('watch_inline') -const config = require('./config/config.js') - -const pluginsController = require('./plugins/default-plugins.js') const watchDefaultPlugins = pluginsController('watch') - let srcConfig = { - ...config.build, - options: { - ...config.build.options, - outputDir: path.join(__dirname, '/builtWWW'), - sassOutputDir: path.join(__dirname, '/builtWWW/styles.bundle.css'), - } + ...config.build, + options: { + ...config.build.options, + outputDir: path.join(__dirname, '/builtWWW'), + sassOutputDir: path.join(__dirname, '/builtWWW/styles.bundle.css') + } } const { inlineConfigs } = generateBuildConfig(srcConfig) module.exports = () => { - watchInlines(inlineConfigs) - watchDefaultPlugins() -} + watchInlines(inlineConfigs) + watchDefaultPlugins() +} \ No newline at end of file diff --git a/watch.js b/watch.js index 3116d7ea..dfd8a096 100644 --- a/watch.js +++ b/watch.js @@ -3,23 +3,22 @@ const uiCore = require('./core/ui-core.js') const generateBuildConfig = uiCore('generate_build_config') const watch = uiCore('watch') const config = require('./config/config.js') - const pluginsController = require('./plugins/default-plugins.js') -const watchPlugins = pluginsController('watch') - const watchInline = require('./watch-inline.js') +const watchPlugins = pluginsController('watch') + let srcConfig = { - ...config.build, - options: { - ...config.build.options, - outputDir: path.join(__dirname, '/builtWWW'), - sassOutputDir: path.join(__dirname, '/builtWWW/styles.bundle.css'), - } + ...config.build, + options: { + ...config.build.options, + outputDir: path.join(__dirname, '/builtWWW'), + sassOutputDir: path.join(__dirname, '/builtWWW/styles.bundle.css') + } } const { buildConfig, inlineConfigs } = generateBuildConfig(srcConfig) watch(buildConfig.options, buildConfig.outputs, buildConfig.outputOptions, buildConfig.inputOptions) watchInline() -watchPlugins() +watchPlugins() \ No newline at end of file From a66d945ed41b7d85b16c07211f14ef897f8311d6 Mon Sep 17 00:00:00 2001 From: AlphaX-Projects <77661270+AlphaX-Projects@users.noreply.github.com> Date: Wed, 8 May 2024 13:21:29 +0200 Subject: [PATCH 02/11] Add missing files become-minter --- .../core/become-minter/not-sponsored.js | 144 ++++++++++++++++++ .../core/become-minter/yes-sponsored.js | 125 +++++++++++++++ 2 files changed, 269 insertions(+) create mode 100644 plugins/plugins/core/become-minter/not-sponsored.js create mode 100644 plugins/plugins/core/become-minter/yes-sponsored.js diff --git a/plugins/plugins/core/become-minter/not-sponsored.js b/plugins/plugins/core/become-minter/not-sponsored.js new file mode 100644 index 00000000..2199eef0 --- /dev/null +++ b/plugins/plugins/core/become-minter/not-sponsored.js @@ -0,0 +1,144 @@ +import { html, LitElement } from 'lit' +import { Epml } from '../../../epml' +import { becomeMinterStyles } from '../components/plugins-css' +import '../components/ButtonIconCopy' +import '@material/mwc-button' +import '@material/mwc-textfield' +import '@polymer/paper-spinner/paper-spinner-lite.js' +import '@vaadin/button' + +// Multi language support +import { translate } from '../../../../core/translate' + +const parentEpml = new Epml({ type: 'WINDOW', source: window.parent }) + +class NotSponsored extends LitElement { + static properties = { + atMount: { type: Function }, + isLoadingSponsorshipKeySubmit: { type: Boolean }, + sponsorshipKeyValue: { type: String }, + addMintingAccountMessage: { type: String } + } + + static get styles() { + return [becomeMinterStyles] + } + + constructor() { + super() + this.isLoadingSponsorshipKeySubmit = false + this.sponsorshipKeyValue = '' + this.addMintingAccountMessage = '' + this.atMount = () => {} + } + + render() { + return html` +
    +
    +

    + ${translate('mintingpage.mchange33')} +

    +

    + ${translate('mintingpage.mchange34')} +

    +

    + ${translate('mintingpage.mchange35')} +

    +

    + ${translate('mintingpage.mchange36')} +

    +

    + ${translate('mintingpage.mchange37')} +

    +

    ${this.addMintingAccountMessage}

    +
    +
    + + +
    +
    + + ${this.isLoadingSponsorshipKeySubmit === false ? + html` + ${translate('puzzlepage.pchange15')} + ` + : html` + + ` + } + +
    +
    +
    +
    + ` + } + + firstUpdated() { + // ... + } + + renderErr1Text() { + return html`${translate('nodepage.nchange27')}` + } + + renderErr2Text() { + return html`${translate('nodepage.nchange28')}` + } + + addMintingAccount(e) { + this.isLoadingSponsorshipKeySubmit = true + this.addMintingAccountMessage = 'Loading...' + parentEpml.request('apiCall', { + url: `/admin/mintingaccounts?apiKey=${this.getApiKey()}`, + method: 'POST', + body: this.sponsorshipKeyValue + }).then((res) => { + if (res === true) { + // refetch data + this.atMount() + this.sponsorshipKeyValue = '' + this.addMintingAccountMessage = this.renderErr1Text() + this.isLoadingSponsorshipKeySubmit = false + } else { + this.sponsorshipKeyValue = '' + this.addMintingAccountMessage = this.renderErr2Text() + this.isLoadingSponsorshipKeySubmit = false + } + }) + } + + inputHandler(e) { + this.sponsorshipKeyValue = e.target.value + } + + // Standard functions + getApiKey() { + const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] + return myNode.apiKey + } + + isEmptyArray(arr) { + if (!arr) { return true } + return arr.length === 0 + } + + round(number) { + return (Math.round(parseFloat(number) * 1e8) / 1e8).toFixed(8) + } +} + +window.customElements.define('not-sponsored', NotSponsored) diff --git a/plugins/plugins/core/become-minter/yes-sponsored.js b/plugins/plugins/core/become-minter/yes-sponsored.js new file mode 100644 index 00000000..44179592 --- /dev/null +++ b/plugins/plugins/core/become-minter/yes-sponsored.js @@ -0,0 +1,125 @@ +import { html, LitElement } from 'lit' +import { blocksNeed } from '../../utils/functions' +import { becomeMinterStyles } from '../components/plugins-css' +import '../components/ButtonIconCopy' +import '@material/mwc-button' +import '@material/mwc-textfield' +import '@polymer/paper-spinner/paper-spinner-lite.js' +import '@vaadin/button' + +// Multi language support +import { translate } from '../../../../core/translate' + +class YesSponsored extends LitElement { + static get properties() { + return { + addressInfo: { type: Object }, + rewardSharePublicKey: { type: String }, + isMinting: {type: Boolean} + } + } + + static get styles() { + return [becomeMinterStyles] + } + + constructor() { + super() + this.addressInfo = {} + this.rewardSharePublicKey = '' + this.isMinting = false + } + + render() { + return html` +
    +
    +
    + + ${translate('becomeMinterPage.bchange10')} + +
    +
    +
    +
    +
    + + ${translate('walletpage.wchange41')} + +
    + ${this.isMinting ? html` +

    ${translate('becomeMinterPage.bchange12')}

    + ` : html` +

    ${translate('mintingpage.mchange9')}

    + `} +
    +
    +
    +
    + + ${translate('becomeMinterPage.bchange13')} + +
    +

    + ${this._levelUpBlocks()} + ${translate('mintingpage.mchange26')} +

    +
    +
    +
    +
    + + ${translate('becomeMinterPage.bchange15')} + +
    +

    + ${translate('becomeMinterPage.bchange16')} +

    +
    +

    + ${this.rewardSharePublicKey} +

    + + +
    +
    +
    +
    +
    + ` + } + + firstUpdated() { + // ... + } + + _levelUpBlocks() { + return (blocksNeed(0) - (this.addressInfo?.blocksMinted + this.addressInfo?.blocksMintedAdjustment)).toString() + } + + // Standard functions + getApiKey() { + const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] + return myNode.apiKey + } + + isEmptyArray(arr) { + if (!arr) { return true } + return arr.length === 0 + } + + round(number) { + return (Math.round(parseFloat(number) * 1e8) / 1e8).toFixed(8) + } +} + +window.customElements.define('yes-sponsored', YesSponsored) From 3b4581a448a1ed104ba21348ff54ad8b0bc3a517 Mon Sep 17 00:00:00 2001 From: AlphaX-Projects <77661270+AlphaX-Projects@users.noreply.github.com> Date: Wed, 8 May 2024 13:23:07 +0200 Subject: [PATCH 03/11] Add missing file q-chat --- .../plugins/core/q-chat/computePowWorker.js | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 plugins/plugins/core/q-chat/computePowWorker.js diff --git a/plugins/plugins/core/q-chat/computePowWorker.js b/plugins/plugins/core/q-chat/computePowWorker.js new file mode 100644 index 00000000..0e260f6b --- /dev/null +++ b/plugins/plugins/core/q-chat/computePowWorker.js @@ -0,0 +1,53 @@ +import { Sha256 } from 'asmcrypto.js' + +function sbrk(size, heap) { + let brk = 512 * 1024 // stack top + let old = brk + brk += size + if (brk > heap.length) throw new Error('heap exhausted') + return old +} + +self.addEventListener('message', async e => { + const response = await computePow(e.data.chatBytes, e.data.path, e.data.difficulty) + postMessage(response) +}) + +const memory = new WebAssembly.Memory({ initial: 256, maximum: 256 }) +const heap = new Uint8Array(memory.buffer) + +const computePow = async (chatBytes, path, difficulty) => { + let response = null + await new Promise((resolve, reject) => { + const _chatBytesArray = Object.keys(chatBytes).map(function (key) { + return chatBytes[key] + }) + const chatBytesArray = new Uint8Array(_chatBytesArray) + const chatBytesHash = new Sha256().process(chatBytesArray).finish().result + const hashPtr = sbrk(32, heap) + const hashAry = new Uint8Array(memory.buffer, hashPtr, 32) + hashAry.set(chatBytesHash) + const workBufferLength = 8 * 1024 * 1024 + const workBufferPtr = sbrk(workBufferLength, heap) + const importObject = { + env: { + memory: memory + } + } + function loadWebAssembly(filename, imports) { + // Fetch the file and compile it + return fetch(filename).then(response => response.arrayBuffer()).then(buffer => WebAssembly.compile(buffer)).then(module => { + // Create the instance. + return new WebAssembly.Instance(module, importObject) + }) + } + loadWebAssembly(path) + .then(wasmModule => { + response = { + nonce: wasmModule.exports.compute2(hashPtr, workBufferPtr, workBufferLength, difficulty), chatBytesArray + } + resolve() + }) + }) + return response +} \ No newline at end of file From db93f510834f97bf9031156613927d53209e362f Mon Sep 17 00:00:00 2001 From: AlphaX-Projects <77661270+AlphaX-Projects@users.noreply.github.com> Date: Wed, 8 May 2024 13:24:06 +0200 Subject: [PATCH 04/11] Add missing files browser --- .../core/qdn/browser/computePowWorker.js | 54 +++++++++++++++ .../core/qdn/browser/computePowWorkerFile.js | 65 +++++++++++++++++++ 2 files changed, 119 insertions(+) create mode 100644 plugins/plugins/core/qdn/browser/computePowWorker.js create mode 100644 plugins/plugins/core/qdn/browser/computePowWorkerFile.js diff --git a/plugins/plugins/core/qdn/browser/computePowWorker.js b/plugins/plugins/core/qdn/browser/computePowWorker.js new file mode 100644 index 00000000..d2ee3ab2 --- /dev/null +++ b/plugins/plugins/core/qdn/browser/computePowWorker.js @@ -0,0 +1,54 @@ +import { Sha256 } from 'asmcrypto.js' + +function sbrk(size, heap) { + let brk = 512 * 1024 // stack top + let old = brk + brk += size + if (brk > heap.length) throw new Error('heap exhausted') + return old +} + +self.addEventListener('message', async e => { + const response = await computePow(e.data.chatBytes, e.data.path, e.data.difficulty) + postMessage(response) +}) + +const memory = new WebAssembly.Memory({ initial: 256, maximum: 256 }) +const heap = new Uint8Array(memory.buffer) + +const computePow = async (chatBytes, path, difficulty) => { + let response = null + await new Promise((resolve, reject) => { + const _chatBytesArray = Object.keys(chatBytes).map(function (key) { return chatBytes[key]; }) + const chatBytesArray = new Uint8Array(_chatBytesArray) + const chatBytesHash = new Sha256().process(chatBytesArray).finish().result + const hashPtr = sbrk(32, heap); + const hashAry = new Uint8Array(memory.buffer, hashPtr, 32) + hashAry.set(chatBytesHash) + const workBufferLength = 8 * 1024 * 1024 + const workBufferPtr = sbrk(workBufferLength, heap) + const importObject = { + env: { + memory: memory + } + } + function loadWebAssembly(filename, imports) { + // Fetch the file and compile it + return fetch(filename) + .then(response => response.arrayBuffer()) + .then(buffer => WebAssembly.compile(buffer)) + .then(module => { + // Create the instance. + return new WebAssembly.Instance(module, importObject) + }) + } + loadWebAssembly(path).then(wasmModule => { + response = { + nonce: wasmModule.exports.compute2(hashPtr, workBufferPtr, workBufferLength, difficulty), + chatBytesArray + } + resolve() + }) + }) + return response +} \ No newline at end of file diff --git a/plugins/plugins/core/qdn/browser/computePowWorkerFile.js b/plugins/plugins/core/qdn/browser/computePowWorkerFile.js new file mode 100644 index 00000000..c20c9d4b --- /dev/null +++ b/plugins/plugins/core/qdn/browser/computePowWorkerFile.js @@ -0,0 +1,65 @@ +import { Sha256 } from 'asmcrypto.js' + +function sbrk(size, heap) { + let brk = 512 * 1024 // stack top + let old = brk + brk += size + if (brk > heap.length) throw new Error('heap exhausted') + return old +} + +self.addEventListener('message', async e => { + const response = await computePow(e.data.convertedBytes, e.data.path) + postMessage(response) +}) + +const memory = new WebAssembly.Memory({ initial: 256, maximum: 256 }) +const heap = new Uint8Array(memory.buffer) + +const computePow = async (convertedBytes, path) => { + let response = null + await new Promise((resolve, reject) => { + const _convertedBytesArray = Object.keys(convertedBytes).map( + function (key) { + return convertedBytes[key] + } + ) + const convertedBytesArray = new Uint8Array(_convertedBytesArray) + const convertedBytesHash = new Sha256() + .process(convertedBytesArray) + .finish().result + const hashPtr = sbrk(32, heap) + const hashAry = new Uint8Array( + memory.buffer, + hashPtr, + 32 + ) + hashAry.set(convertedBytesHash) + const difficulty = 14 + const workBufferLength = 8 * 1024 * 1024 + const workBufferPtr = sbrk( + workBufferLength, + heap + ) + const importObject = { + env: { + memory: memory + } + } + function loadWebAssembly(filename, imports) { + return fetch(filename) + .then(response => response.arrayBuffer()) + .then(buffer => WebAssembly.compile(buffer)) + .then(module => { + return new WebAssembly.Instance(module, importObject) + }) + } + loadWebAssembly(path).then(wasmModule => { + response = { + nonce: wasmModule.exports.compute2(hashPtr, workBufferPtr, workBufferLength, difficulty), + } + resolve() + }) + }) + return response +} \ No newline at end of file From 1383022cd6abfea69700b6746dc41dfd34f82417 Mon Sep 17 00:00:00 2001 From: AlphaX-Projects <77661270+AlphaX-Projects@users.noreply.github.com> Date: Wed, 8 May 2024 14:11:48 +0200 Subject: [PATCH 05/11] Update dependencies --- package-lock.json | 558 ++++++++++++++++++---------------------------- package.json | 14 +- 2 files changed, 230 insertions(+), 342 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4f938fc1..792fc709 100644 --- a/package-lock.json +++ b/package-lock.json @@ -27,9 +27,9 @@ "compressorjs": "1.2.1", "crypto-js": "4.2.0", "driver.js": "1.3.1", - "electron-dl": "4.0.0", + "electron-dl": "3.5.2", "electron-log": "5.1.2", - "electron-store": "9.0.0", + "electron-store": "8.2.0", "electron-updater": "6.1.8", "emoji-picker-js": "https://github.com/Qortal/emoji-picker-js", "extract-zip": "2.0.1", @@ -42,12 +42,12 @@ "prosemirror-gapcursor": "1.3.2", "prosemirror-history": "1.4.0", "prosemirror-keymap": "1.2.2", - "prosemirror-model": "1.20.0", + "prosemirror-model": "1.21.0", "prosemirror-schema-list": "1.3.0", "prosemirror-state": "1.4.3", - "prosemirror-transform": "1.8.0", + "prosemirror-transform": "1.9.0", "prosemirror-view": "1.33.6", - "sass": "1.76.0", + "sass": "1.77.0", "short-unique-id": "5.2.0", "xhr2": "0.2.1" }, @@ -102,13 +102,13 @@ "@vaadin/icons": "24.2.9", "@vaadin/password-field": "24.2.9", "@vaadin/tooltip": "24.2.9", - "@zip.js/zip.js": "2.7.43", + "@zip.js/zip.js": "2.7.44", "axios": "1.6.8", "electron": "30.0.2", "electron-builder": "24.13.3", "epml": "0.3.3", "eslint": "8.57.0", - "eslint-plugin-lit": "1.11.0", + "eslint-plugin-lit": "1.12.0", "eslint-plugin-wc": "2.0.4", "file-saver": "2.0.5", "highcharts": "11.1.0", @@ -618,26 +618,11 @@ "url": "https://github.com/electron/packager?sponsor=1" } }, - "node_modules/@electron/packager/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/@electron/packager/node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "version": "7.6.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.1.tgz", + "integrity": "sha512-f/vbBsu+fOiYt+lmwZV0rVwJScl46HppnOA1ZvIuBWKOTlllpyJ3bfVax76/OrhCH38dyxoDIA8K7uB963IYgA==", "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, "bin": { "semver": "bin/semver.js" }, @@ -645,12 +630,6 @@ "node": ">=10" } }, - "node_modules/@electron/packager/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, "node_modules/@electron/universal": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/@electron/universal/-/universal-2.0.1.tgz", @@ -3712,9 +3691,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.12.8", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.8.tgz", - "integrity": "sha512-NU0rJLJnshZWdE/097cdCBbyW1h4hEg0xpovcoAQYHl8dnEyp/NAOiE45pvc+Bd1Dt+2r94v2eGFpQJ4R7g+2w==", + "version": "20.12.10", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.10.tgz", + "integrity": "sha512-Eem5pH9pmWBHoGAT8Dr5fdc5rYA+4NAovdM4EktRPVAAiJhmWWfQrA0cFhAbOsQdSfIHjAud6YdkbL69+zSKjw==", "devOptional": true, "dependencies": { "undici-types": "~5.26.4" @@ -4020,9 +3999,9 @@ } }, "node_modules/@vaadin/vaadin-development-mode-detector": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/@vaadin/vaadin-development-mode-detector/-/vaadin-development-mode-detector-2.0.6.tgz", - "integrity": "sha512-N6a5nLT/ytEUlpPo+nvdCKIGoyNjPsj3rzPGvGYK8x9Ceg76OTe1xI/GtN71mRW9e2HUScR0kCNOkl1Z63YDjw==", + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@vaadin/vaadin-development-mode-detector/-/vaadin-development-mode-detector-2.0.7.tgz", + "integrity": "sha512-9FhVhr0ynSR3X2ao+vaIEttcNU5XfzCbxtmYOV8uIRnUCtNgbvMOIcyGBvntsX9I5kvIP2dV3cFAOG9SILJzEA==", "dev": true }, "node_modules/@vaadin/vaadin-lumo-styles": { @@ -4087,9 +4066,9 @@ } }, "node_modules/@zip.js/zip.js": { - "version": "2.7.43", - "resolved": "https://registry.npmjs.org/@zip.js/zip.js/-/zip.js-2.7.43.tgz", - "integrity": "sha512-kW7elA/Q1o5xusStfZeysCvheD1SvW3TWDfqTCmoWW4ALBSqKonZSTrQgdEGOUec2U/TLMSGq0SuSMTAxy4gFg==", + "version": "2.7.44", + "resolved": "https://registry.npmjs.org/@zip.js/zip.js/-/zip.js-2.7.44.tgz", + "integrity": "sha512-ZzMhAcAyRAYi1FZELsvKaw8I4ADxNTqbiVIjyo/syBe4HGWop9+OADnuBnHpm2TxgXPogxxhhPffOhDD40jUdA==", "dev": true, "engines": { "bun": ">=0.7.0", @@ -4455,18 +4434,6 @@ "url": "https://github.com/sponsors/gjtorikian/" } }, - "node_modules/app-builder-lib/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/app-builder-lib/node_modules/minimatch": { "version": "5.1.6", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", @@ -4489,13 +4456,10 @@ } }, "node_modules/app-builder-lib/node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "version": "7.6.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.1.tgz", + "integrity": "sha512-f/vbBsu+fOiYt+lmwZV0rVwJScl46HppnOA1ZvIuBWKOTlllpyJ3bfVax76/OrhCH38dyxoDIA8K7uB963IYgA==", "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, "bin": { "semver": "bin/semver.js" }, @@ -4503,12 +4467,6 @@ "node": ">=10" } }, - "node_modules/app-builder-lib/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, "node_modules/archiver": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/archiver/-/archiver-5.3.2.tgz", @@ -4644,12 +4602,11 @@ } }, "node_modules/atomically": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/atomically/-/atomically-2.0.3.tgz", - "integrity": "sha512-kU6FmrwZ3Lx7/7y3hPS5QnbJfaohcIul5fGqf7ok+4KklIEk9tJ0C2IQPdacSbVUWv6zVHXEBWoWd6NrVMT7Cw==", - "dependencies": { - "stubborn-fs": "^1.2.5", - "when-exit": "^2.1.1" + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/atomically/-/atomically-1.7.0.tgz", + "integrity": "sha512-Xcz9l0z7y9yQ9rdDaxlmaI4uJHf/T8g9hOEzJcsEqX2SjCj4J20uK7+ldkDHMbpJDK76wF7xEIgxc/vSlsfw5w==", + "engines": { + "node": ">=10.12.0" } }, "node_modules/author-regex": { @@ -5061,9 +5018,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001615", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001615.tgz", - "integrity": "sha512-1IpazM5G3r38meiae0bHRnPhz+CBQ3ZLqbQMtrg+AsTPKAXgW38JNsXkyZ+v8waCsDmPq87lmfun5Q2AGysNEQ==", + "version": "1.0.30001616", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001616.tgz", + "integrity": "sha512-RHVYKov7IcdNjVHJFNY/78RdG4oGVjbayxv8u5IO74Wv7Hlq4PnJE6mo/OjFijjVFNy5ijnCt6H3IIo4t+wfEw==", "dev": true, "funding": [ { @@ -5284,22 +5241,23 @@ "dev": true }, "node_modules/conf": { - "version": "12.0.0", - "resolved": "https://registry.npmjs.org/conf/-/conf-12.0.0.tgz", - "integrity": "sha512-fIWyWUXrJ45cHCIQX+Ck1hrZDIf/9DR0P0Zewn3uNht28hbt5OfGUq8rRWsxi96pZWPyBEd0eY9ama01JTaknA==", + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/conf/-/conf-10.2.0.tgz", + "integrity": "sha512-8fLl9F04EJqjSqH+QjITQfJF8BrOVaYr1jewVgSRAEWePfxT0sku4w2hrGQ60BC/TNLGQ2pgxNlTbWQmMPFvXg==", "dependencies": { - "ajv": "^8.12.0", + "ajv": "^8.6.3", "ajv-formats": "^2.1.1", - "atomically": "^2.0.2", - "debounce-fn": "^5.1.2", - "dot-prop": "^8.0.2", - "env-paths": "^3.0.0", - "json-schema-typed": "^8.0.1", - "semver": "^7.5.4", - "uint8array-extras": "^0.3.0" + "atomically": "^1.7.0", + "debounce-fn": "^4.0.0", + "dot-prop": "^6.0.1", + "env-paths": "^2.2.1", + "json-schema-typed": "^7.0.3", + "onetime": "^5.1.2", + "pkg-up": "^3.1.0", + "semver": "^7.3.5" }, "engines": { - "node": ">=18" + "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -5320,40 +5278,15 @@ "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/conf/node_modules/env-paths": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-3.0.0.tgz", - "integrity": "sha512-dtJUTepzMW3Lm/NPxRf3wP4642UWhjL2sQxc+ym2YMj1m/H2zDNQOlezafzkHwn6sMstjHTwG6iQQsctDW/b1A==", - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/conf/node_modules/json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" }, - "node_modules/conf/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/conf/node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", - "dependencies": { - "lru-cache": "^6.0.0" - }, + "version": "7.6.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.1.tgz", + "integrity": "sha512-f/vbBsu+fOiYt+lmwZV0rVwJScl46HppnOA1ZvIuBWKOTlllpyJ3bfVax76/OrhCH38dyxoDIA8K7uB963IYgA==", "bin": { "semver": "bin/semver.js" }, @@ -5361,11 +5294,6 @@ "node": ">=10" } }, - "node_modules/conf/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, "node_modules/config-file-ts": { "version": "0.2.6", "resolved": "https://registry.npmjs.org/config-file-ts/-/config-file-ts-0.2.6.tgz", @@ -5423,9 +5351,9 @@ } }, "node_modules/config-file-ts/node_modules/minipass": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", - "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.0.tgz", + "integrity": "sha512-oGZRv2OT1lO2UF1zUcwdTb3wqUwI0kBGTgt/T7OdSj6M6N5m3o5uPf0AIW6lVxGGoiWUR7e2AwTE+xiwK8WQig==", "dev": true, "engines": { "node": ">=16 || 14 >=14.17" @@ -5546,14 +5474,14 @@ } }, "node_modules/debounce-fn": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/debounce-fn/-/debounce-fn-5.1.2.tgz", - "integrity": "sha512-Sr4SdOZ4vw6eQDvPYNxHogvrxmCIld/VenC5JbNrFwMiwd7lY/Z18ZFfo+EWNG4DD9nFlAujWAo/wGuOPHmy5A==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/debounce-fn/-/debounce-fn-4.0.0.tgz", + "integrity": "sha512-8pYCQiL9Xdcg0UPSD3d+0KMlOjp+KGU5EPwYddgzQ7DATsg4fuUDjQtsYLmWjnk2obnNHgV3vE2Y4jejSOJVBQ==", "dependencies": { - "mimic-fn": "^4.0.0" + "mimic-fn": "^3.0.0" }, "engines": { - "node": ">=12" + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -5758,25 +5686,14 @@ } }, "node_modules/dot-prop": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-8.0.2.tgz", - "integrity": "sha512-xaBe6ZT4DHPkg0k4Ytbvn5xoxgpG0jOS1dYxSOwAHPuNLjP3/OzN0gH55SrLqpx8cBfSaVt91lXYkApjb+nYdQ==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-6.0.1.tgz", + "integrity": "sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==", "dependencies": { - "type-fest": "^3.8.0" + "is-obj": "^2.0.0" }, "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/dot-prop/node_modules/type-fest": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-3.13.1.tgz", - "integrity": "sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g==", - "engines": { - "node": ">=14.16" + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -5980,16 +5897,16 @@ } }, "node_modules/electron-dl": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/electron-dl/-/electron-dl-4.0.0.tgz", - "integrity": "sha512-USiB9816d2JzKv0LiSbreRfTg5lDk3lWh0vlx/gugCO92ZIJkHVH0UM18EHvKeadErP6Xn4yiTphWzYfbA2Ong==", + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/electron-dl/-/electron-dl-3.5.2.tgz", + "integrity": "sha512-i104cl+u8yJ0lhpRAtUWfeGuWuL1PL6TBiw2gLf0MMIBjfgE485Ags2mcySx4uWU9P9uj/vsD3jd7X+w1lzZxw==", "dependencies": { "ext-name": "^5.0.0", - "pupa": "^3.1.0", - "unused-filename": "^4.0.1" + "pupa": "^2.0.1", + "unused-filename": "^2.1.0" }, "engines": { - "node": ">=18" + "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -6103,24 +6020,21 @@ } }, "node_modules/electron-store": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/electron-store/-/electron-store-9.0.0.tgz", - "integrity": "sha512-7LZ2dR3N3bF93G2c4x+1NZ/8fpsKv6bKrMxeOQWLqdRbxvopxVqy9QXQy9axSV2O3P1kVGTj1q2wq5/W4isiOg==", + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/electron-store/-/electron-store-8.2.0.tgz", + "integrity": "sha512-ukLL5Bevdil6oieAOXz3CMy+OgaItMiVBg701MNlG6W5RaC0AHN7rvlqTCmeb6O7jP0Qa1KKYTE0xV0xbhF4Hw==", "dependencies": { - "conf": "^12.0.0", - "type-fest": "^4.18.1" - }, - "engines": { - "node": ">=20" + "conf": "^10.2.0", + "type-fest": "^2.17.0" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/electron-to-chromium": { - "version": "1.4.754", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.754.tgz", - "integrity": "sha512-7Kr5jUdns5rL/M9wFFmMZAgFDuL2YOnanFH4OI4iFzUqyh3XOL7nAGbSlSMZdzKMIyyTpNSbqZsWG9odwLeKvA==", + "version": "1.4.758", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.758.tgz", + "integrity": "sha512-/o9x6TCdrYZBMdGeTifAP3wlF/gVT+TtWJe3BSmtNh92Mw81U9hrYwW9OAGUh+sEOX/yz5e34sksqRruZbjYrw==", "dev": true }, "node_modules/electron-updater": { @@ -6163,24 +6077,10 @@ "node": ">=12" } }, - "node_modules/electron-updater/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/electron-updater/node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", - "dependencies": { - "lru-cache": "^6.0.0" - }, + "version": "7.6.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.1.tgz", + "integrity": "sha512-f/vbBsu+fOiYt+lmwZV0rVwJScl46HppnOA1ZvIuBWKOTlllpyJ3bfVax76/OrhCH38dyxoDIA8K7uB963IYgA==", "bin": { "semver": "bin/semver.js" }, @@ -6188,11 +6088,6 @@ "node": ">=10" } }, - "node_modules/electron-updater/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, "node_modules/electron/node_modules/@electron/get": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/@electron/get/-/get-2.0.3.tgz", @@ -6290,7 +6185,6 @@ "version": "2.2.1", "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", - "dev": true, "engines": { "node": ">=6" } @@ -6356,14 +6250,11 @@ } }, "node_modules/escape-goat": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-4.0.0.tgz", - "integrity": "sha512-2Sd4ShcWxbx6OY1IHyla/CVNwvg7XwZVoXZHcSu9w9SReNP1EzzD5T8NWKIR38fIqEns9kDWKUQTXXAmlDrdPg==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-2.1.1.tgz", + "integrity": "sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==", "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=8" } }, "node_modules/escape-string-regexp": { @@ -6431,9 +6322,9 @@ } }, "node_modules/eslint-plugin-lit": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-lit/-/eslint-plugin-lit-1.11.0.tgz", - "integrity": "sha512-jVqy2juQTAtOzj1ILf+ZW5GpDobXlSw0kvpP2zu2r8ZbW7KISt7ikj1Gw9DhNeirEU1UlSJR0VIWpdr4lzjayw==", + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-lit/-/eslint-plugin-lit-1.12.0.tgz", + "integrity": "sha512-wADj+b6ZksWs1qqASYBYzi4U6k0Tvhtp4GJupveZ7Z5IfVHMixxFueSSwIl/4ksov4jsahWbyHnhOpvJ5Z8M7w==", "dev": true, "dependencies": { "parse5": "^6.0.1", @@ -7232,28 +7123,12 @@ "node": ">=10.0" } }, - "node_modules/global-agent/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "optional": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/global-agent/node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "version": "7.6.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.1.tgz", + "integrity": "sha512-f/vbBsu+fOiYt+lmwZV0rVwJScl46HppnOA1ZvIuBWKOTlllpyJ3bfVax76/OrhCH38dyxoDIA8K7uB963IYgA==", "dev": true, "optional": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, "bin": { "semver": "bin/semver.js" }, @@ -7261,13 +7136,6 @@ "node": ">=10" } }, - "node_modules/global-agent/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true, - "optional": true - }, "node_modules/globals": { "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", @@ -7742,6 +7610,14 @@ "node": ">=0.12.0" } }, + "node_modules/is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", + "engines": { + "node": ">=8" + } + }, "node_modules/is-path-inside": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", @@ -7837,9 +7713,9 @@ } }, "node_modules/jake": { - "version": "10.8.7", - "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.7.tgz", - "integrity": "sha512-ZDi3aP+fG/LchyBzUM804VjddnwfSfsdeYkwt8NcbKRvo4rFkjhs456iLFn3k2ZUWvNe4i48WACDbza8fhq2+w==", + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.1.tgz", + "integrity": "sha512-61btcOHNnLnsOdtLgA5efqQWjnSi/vow5HbI7HMdKKWqvrKR1bLK3BPlJn9gcSaP2ewuamUSMB5XEy76KUIS2w==", "dev": true, "dependencies": { "async": "^3.2.3", @@ -7972,9 +7848,9 @@ "dev": true }, "node_modules/json-schema-typed": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/json-schema-typed/-/json-schema-typed-8.0.1.tgz", - "integrity": "sha512-XQmWYj2Sm4kn4WeTYvmpKEbyPsL7nBsb647c7pMe6l02/yx2+Jfc4dT6UZkEXnIUb5LhD55r2HPsJ1milQ4rDg==" + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/json-schema-typed/-/json-schema-typed-7.0.3.tgz", + "integrity": "sha512-7DE8mpG+/fVw+dTpjbxnx47TaMnDfOI1jwft9g1VybltZCduyRQPJPvc+zzKY9WPHxhPWczyFuYa6I8Mw4iU5A==" }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", @@ -8401,14 +8277,11 @@ } }, "node_modules/mimic-fn": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", - "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-3.1.0.tgz", + "integrity": "sha512-Ysbi9uYW9hFyfrThdDEQuykN4Ey6BuwPD2kpI5ES/nFTDn/98yxYNLZJcgUAKPT/mcrLLKaGzJR9YVxJrIdASQ==", "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=8" } }, "node_modules/mimic-response": { @@ -8493,6 +8366,14 @@ "node": ">=10" } }, + "node_modules/modify-filename": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/modify-filename/-/modify-filename-1.1.0.tgz", + "integrity": "sha512-EickqnKq3kVVaZisYuCxhtKbZjInCuwgwZWyAmRIp1NTMhri7r3380/uqwrUHfaDiPzLVTuoNy4whX66bxPVog==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -8709,12 +8590,11 @@ } }, "node_modules/p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", - "dev": true, + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "engines": { - "node": ">=4" + "node": ">=6" } }, "node_modules/parent-module": { @@ -8778,7 +8658,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, "engines": { "node": ">=8" } @@ -8888,6 +8767,73 @@ "node": ">=0.10.0" } }, + "node_modules/pkg-up": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", + "integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==", + "dependencies": { + "find-up": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-up/node_modules/find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dependencies": { + "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-up/node_modules/locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dependencies": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-up/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkg-up/node_modules/p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dependencies": { + "p-limit": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-up/node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "engines": { + "node": ">=4" + } + }, "node_modules/plist": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/plist/-/plist-3.1.0.tgz", @@ -9067,9 +9013,9 @@ } }, "node_modules/prosemirror-model": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/prosemirror-model/-/prosemirror-model-1.20.0.tgz", - "integrity": "sha512-q7AY7vMjKYqDCeoedgUiAgrLabliXxndJuuFmcmc2+YU1SblvnOiG2WEACF2lwAZsMlfLpiAilA3L+TWlDqIsQ==", + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/prosemirror-model/-/prosemirror-model-1.21.0.tgz", + "integrity": "sha512-zLpS1mVCZLA7VTp82P+BfMiYVPcX1/z0Mf3gsjKZtzMWubwn2pN7CceMV0DycjlgE5JeXPR7UF4hJPbBV98oWA==", "dependencies": { "orderedmap": "^2.0.0" } @@ -9140,11 +9086,11 @@ } }, "node_modules/prosemirror-transform": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/prosemirror-transform/-/prosemirror-transform-1.8.0.tgz", - "integrity": "sha512-BaSBsIMv52F1BVVMvOmp1yzD3u65uC3HTzCBQV1WDPqJRQ2LuHKcyfn0jwqodo8sR9vVzMzZyI+Dal5W9E6a9A==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/prosemirror-transform/-/prosemirror-transform-1.9.0.tgz", + "integrity": "sha512-5UXkr1LIRx3jmpXXNKDhv8OyAOeLTGuXNwdVfg8x27uASna/wQkr9p6fD3eupGOi4PLJfbezxTyi/7fSJypXHg==", "dependencies": { - "prosemirror-model": "^1.0.0" + "prosemirror-model": "^1.21.0" } }, "node_modules/prosemirror-view": { @@ -9189,17 +9135,14 @@ } }, "node_modules/pupa": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/pupa/-/pupa-3.1.0.tgz", - "integrity": "sha512-FLpr4flz5xZTSJxSeaheeMKN/EDzMdK7b8PTOC6a5PYFKTucWbdqjgqaEyH0shFiSJrVB1+Qqi4Tk19ccU6Aug==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/pupa/-/pupa-2.1.1.tgz", + "integrity": "sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A==", "dependencies": { - "escape-goat": "^4.0.0" + "escape-goat": "^2.0.0" }, "engines": { - "node": ">=12.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=8" } }, "node_modules/pwa-helpers": { @@ -9342,6 +9285,15 @@ "node": ">=4" } }, + "node_modules/read-pkg-up/node_modules/p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/read-pkg-up/node_modules/path-exists": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", @@ -9749,9 +9701,9 @@ } }, "node_modules/sass": { - "version": "1.76.0", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.76.0.tgz", - "integrity": "sha512-nc3LeqvF2FNW5xGF1zxZifdW3ffIz5aBb7I7tSvOoNu7z1RQ6pFt9MBuiPtjgaI62YWrM/txjWlOCFiGtf2xpw==", + "version": "1.77.0", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.77.0.tgz", + "integrity": "sha512-eGj4HNfXqBWtSnvItNkn7B6icqH14i3CiCGbzMKs3BAPTq62pp9NBYsBgyN4cA+qssqo9r26lW4JSvlaUUWbgw==", "dependencies": { "chokidar": ">=3.0.0 <4.0.0", "immutable": "^4.0.0", @@ -9885,26 +9837,11 @@ "node": ">=10" } }, - "node_modules/simple-update-notifier/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/simple-update-notifier/node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "version": "7.6.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.1.tgz", + "integrity": "sha512-f/vbBsu+fOiYt+lmwZV0rVwJScl46HppnOA1ZvIuBWKOTlllpyJ3bfVax76/OrhCH38dyxoDIA8K7uB963IYgA==", "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, "bin": { "semver": "bin/semver.js" }, @@ -9912,12 +9849,6 @@ "node": ">=10" } }, - "node_modules/simple-update-notifier/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, "node_modules/slash": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", @@ -10200,11 +10131,6 @@ "node": ">=0.10.0" } }, - "node_modules/stubborn-fs": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/stubborn-fs/-/stubborn-fs-1.2.5.tgz", - "integrity": "sha512-H2N9c26eXjzL/S/K+i/RHHcFanE74dptvvjM8iwzwbVcWY/zjBbgRqF3K0DY4+OD+uTTASTBvDoxPDaPN02D7g==" - }, "node_modules/sumchecker": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/sumchecker/-/sumchecker-3.0.1.tgz", @@ -10483,11 +10409,11 @@ } }, "node_modules/type-fest": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.18.1.tgz", - "integrity": "sha512-qXhgeNsX15bM63h5aapNFcQid9jRF/l3ojDoDFmekDQEUufZ9U4ErVt6SjDxnHp48Ltrw616R8yNc3giJ3KvVQ==", + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", + "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", "engines": { - "node": ">=16" + "node": ">=12.20" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -10511,17 +10437,6 @@ "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==" }, - "node_modules/uint8array-extras": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/uint8array-extras/-/uint8array-extras-0.3.0.tgz", - "integrity": "sha512-erJsJwQ0tKdwuqI0359U8ijkFmfiTcq25JvvzRVc1VP+2son1NJRXhxcAKJmAW3ajM8JSGAfsAXye8g4s+znxA==", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/undici-types": { "version": "5.26.5", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", @@ -10537,43 +10452,21 @@ } }, "node_modules/unused-filename": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/unused-filename/-/unused-filename-4.0.1.tgz", - "integrity": "sha512-ZX6U1J04K1FoSUeoX1OicAhw4d0aro2qo+L8RhJkiGTNtBNkd/Fi1Wxoc9HzcVu6HfOzm0si/N15JjxFmD1z6A==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unused-filename/-/unused-filename-2.1.0.tgz", + "integrity": "sha512-BMiNwJbuWmqCpAM1FqxCTD7lXF97AvfQC8Kr/DIeA6VtvhJaMDupZ82+inbjl5yVP44PcxOuCSxye1QMS0wZyg==", "dependencies": { - "escape-string-regexp": "^5.0.0", - "path-exists": "^5.0.0" + "modify-filename": "^1.1.0", + "path-exists": "^4.0.0" }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/unused-filename/node_modules/escape-string-regexp": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", - "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/unused-filename/node_modules/path-exists": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", - "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">=8" } }, "node_modules/update-browserslist-db": { - "version": "1.0.14", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.14.tgz", - "integrity": "sha512-JixKH8GR2pWYshIPUg/NujK3JO7JiqEEUiNArE86NQyrgUuZeTlZQN3xuS/yiV5Kb48ev9K6RqNkaJjXsdg7Jw==", + "version": "1.0.15", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.15.tgz", + "integrity": "sha512-K9HWH62x3/EalU1U6sjSZiylm9C8tgq2mSvshZpqc7QE69RaA2qjhkW2HlNA0tFpEbtyFz7HTqbSdN4MSwUodA==", "dev": true, "funding": [ { @@ -10657,11 +10550,6 @@ "resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz", "integrity": "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==" }, - "node_modules/when-exit": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/when-exit/-/when-exit-2.1.2.tgz", - "integrity": "sha512-u9J+toaf3CCxCAzM/484qNAxQE75rFdVgiFEEV8Xps2gzYhf0tx73s1WXDQhkwV17E3MxRMz40m7Ekd2/121Lg==" - }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", diff --git a/package.json b/package.json index 21b90589..019ccee1 100644 --- a/package.json +++ b/package.json @@ -49,9 +49,9 @@ "compressorjs": "1.2.1", "crypto-js": "4.2.0", "driver.js": "1.3.1", - "electron-dl": "4.0.0", + "electron-dl": "3.5.2", "electron-log": "5.1.2", - "electron-store": "9.0.0", + "electron-store": "8.2.0", "electron-updater": "6.1.8", "emoji-picker-js": "https://github.com/Qortal/emoji-picker-js", "extract-zip": "2.0.1", @@ -64,12 +64,12 @@ "prosemirror-gapcursor": "1.3.2", "prosemirror-history": "1.4.0", "prosemirror-keymap": "1.2.2", - "prosemirror-model": "1.20.0", + "prosemirror-model": "1.21.0", "prosemirror-schema-list": "1.3.0", "prosemirror-state": "1.4.3", - "prosemirror-transform": "1.8.0", + "prosemirror-transform": "1.9.0", "prosemirror-view": "1.33.6", - "sass": "1.76.0", + "sass": "1.77.0", "short-unique-id": "5.2.0", "xhr2": "0.2.1" }, @@ -124,13 +124,13 @@ "@vaadin/icons": "24.2.9", "@vaadin/password-field": "24.2.9", "@vaadin/tooltip": "24.2.9", - "@zip.js/zip.js": "2.7.43", + "@zip.js/zip.js": "2.7.44", "axios": "1.6.8", "electron": "30.0.2", "electron-builder": "24.13.3", "epml": "0.3.3", "eslint": "8.57.0", - "eslint-plugin-lit": "1.11.0", + "eslint-plugin-lit": "1.12.0", "eslint-plugin-wc": "2.0.4", "file-saver": "2.0.5", "highcharts": "11.1.0", From 62579a8929dacf6c40320ee46f3f7a107cac2d02 Mon Sep 17 00:00:00 2001 From: AlphaX-Projects <77661270+AlphaX-Projects@users.noreply.github.com> Date: Wed, 8 May 2024 18:38:02 +0200 Subject: [PATCH 06/11] Update us.json --- core/language/us.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/language/us.json b/core/language/us.json index 85af3543..f67afad4 100644 --- a/core/language/us.json +++ b/core/language/us.json @@ -92,7 +92,7 @@ "login": { "login": "Log In", "createaccount": "Create Account", - "name": "Display Name", + "name": "Name", "address": "Address", "password": "Password", "youraccounts": "Your accounts", From 8f8e6255744a50bbd198bc4f76d337018b838ac9 Mon Sep 17 00:00:00 2001 From: AlphaX-Projects <77661270+AlphaX-Projects@users.noreply.github.com> Date: Thu, 9 May 2024 10:17:28 +0200 Subject: [PATCH 07/11] Fix broken links for readd a plugin --- core/src/components/show-plugin.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/src/components/show-plugin.js b/core/src/components/show-plugin.js index 98fa307f..a5e965a9 100644 --- a/core/src/components/show-plugin.js +++ b/core/src/components/show-plugin.js @@ -1597,19 +1597,19 @@ class NavBar extends connect(store)(LitElement) { } else if (this.pluginType === 'reward-share') { this.pluginPage = 'reward-share/index.html' } else if (this.pluginType === 'q-chat') { - this.pluginPage = 'messaging/q-chat/index.html' + this.pluginPage = 'q-chat/index.html' } else if (this.pluginType === 'name-registration') { this.pluginPage = 'name-registration/index.html' } else if (this.pluginType === 'names-market') { this.pluginPage = 'names-market/index.html' } else if (this.pluginType === 'websites') { - this.pluginPage = 'qdn/index.html' + this.pluginPage = 'q-website/index.html' } else if (this.pluginType === 'qapps') { this.pluginPage = 'q-app/index.html' } else if (this.pluginType === 'group-management') { this.pluginPage = 'group-management/index.html' } else if (this.pluginType === 'data-management') { - this.pluginPage = 'qdn/data-management/index.html' + this.pluginPage = 'data-management/index.html' } else if (this.pluginType === 'puzzles') { this.pluginPage = 'puzzles/index.html' } else if (this.pluginType === 'node-management') { From 5cb2d02063b4cba3469f3ebd82f375143c53af5d Mon Sep 17 00:00:00 2001 From: AlphaX-Projects <77661270+AlphaX-Projects@users.noreply.github.com> Date: Fri, 10 May 2024 10:49:47 +0200 Subject: [PATCH 08/11] Fix text color, broken link and remove last tab --- core/src/components/show-plugin.js | 62 ++++++++++++++++++------------ core/src/styles/core-css.js | 1 + 2 files changed, 38 insertions(+), 25 deletions(-) diff --git a/core/src/components/show-plugin.js b/core/src/components/show-plugin.js index a5e965a9..8885a5fa 100644 --- a/core/src/components/show-plugin.js +++ b/core/src/components/show-plugin.js @@ -421,35 +421,46 @@ class ShowPlugin extends connect(store)(LitElement) { let iconId = '' this.tabs = this.tabs.filter((tab, tIndex) => tIndex !== index) - this.currentTab = this.tabs.length - 1; + this.currentTab = this.tabs.length - 1 const tabD = this.tabs.length - 1 - const plugObj = this.tabs[tabD].url - theId = this.tabs[tabD].id - tabId = 'tab-' + theId - frameId = 'frame-' + theId - plugId = 'plug-' + theId - iconId = 'icon-' + theId - var tabActive = this.shadowRoot.getElementById(tabId) - var frameActive = this.shadowRoot.getElementById(frameId) - var plugActive = this.shadowRoot.getElementById(plugId) - var iconActive = this.shadowRoot.getElementById(iconId) - - if (plugObj === undefined || '') { - tabActive.classList.add('active') - iconActive.classList.remove('iconInactive') - iconActive.classList.add('iconActive') - plugActive.classList.remove('hideIframe') - plugActive.classList.add('showIframe') + if (tabD < 0) { + const lengthOfTabs = this.tabs.length + this.addTab({ + url: '', + id: this.uid.rnd() + }) + this.currentTab = lengthOfTabs } else { - tabActive.classList.add('active') - iconActive.classList.remove('iconInactive') - iconActive.classList.add('iconActive') - frameActive.classList.remove('hideIframe') - frameActive.classList.add('showIframe') + const plugObj = this.tabs[tabD].url + theId = this.tabs[tabD].id + tabId = 'tab-' + theId + frameId = 'frame-' + theId + plugId = 'plug-' + theId + iconId = 'icon-' + theId + + var tabActive = this.shadowRoot.getElementById(tabId) + var frameActive = this.shadowRoot.getElementById(frameId) + var plugActive = this.shadowRoot.getElementById(plugId) + var iconActive = this.shadowRoot.getElementById(iconId) + + if (plugObj === undefined || '') { + tabActive.classList.add('active') + iconActive.classList.remove('iconInactive') + iconActive.classList.add('iconActive') + plugActive.classList.remove('hideIframe') + plugActive.classList.add('showIframe') + } else { + tabActive.classList.add('active') + iconActive.classList.remove('iconInactive') + iconActive.classList.add('iconActive') + frameActive.classList.remove('hideIframe') + frameActive.classList.add('showIframe') + } + + this.requestUpdate() } - this.requestUpdate() } else { // Remove tab from array this.tabs = this.tabs.filter((tab, tIndex) => tIndex !== index) @@ -457,6 +468,7 @@ class ShowPlugin extends connect(store)(LitElement) { if (this.tabs.length !== 0) { this.currentTab = 0 } + this.requestUpdate() } } @@ -1583,7 +1595,7 @@ class NavBar extends connect(store)(LitElement) { if (this.pluginType === 'overview-page') { this.pluginPage = 'overview-page/index.html' } else if (this.pluginType === 'minting') { - this.pluginPage = 'minting/index.html' + this.pluginPage = 'minting-info/index.html' } else if (this.pluginType === 'become-minter') { this.pluginPage = 'become-minter/index.html' } else if (this.pluginType === 'sponsorship-list') { diff --git a/core/src/styles/core-css.js b/core/src/styles/core-css.js index 400cc10e..ca5ebdfb 100644 --- a/core/src/styles/core-css.js +++ b/core/src/styles/core-css.js @@ -2497,6 +2497,7 @@ export const showPluginStyles = css` --mdc-theme-surface: var(--white); --mdc-text-field-outlined-idle-border-color: var(--txtfieldborder); --mdc-text-field-outlined-hover-border-color: var(--txtfieldhoverborder); + --mdc-text-field-disabled-ink-color: var(--black); --mdc-text-field-label-ink-color: var(--black); --mdc-text-field-ink-color: var(--black); --mdc-select-ink-color: var(--black); From 3cc5d544a274e3675185617079a82eecb56a4707 Mon Sep 17 00:00:00 2001 From: AlphaX-Projects <77661270+AlphaX-Projects@users.noreply.github.com> Date: Fri, 10 May 2024 17:55:06 +0200 Subject: [PATCH 09/11] Add group avatar to chat select , fix typos in chat text editor, close edit and reply to on group change --- plugins/plugins/core/components/ChatPage.js | 20 +++++++--- plugins/plugins/core/components/ChatSelect.js | 40 +++++++++++++------ .../plugins/core/components/ChatTextEditor.js | 28 ++++++------- .../plugins/core/components/plugins-css.js | 6 +-- 4 files changed, 60 insertions(+), 34 deletions(-) diff --git a/plugins/plugins/core/components/ChatPage.js b/plugins/plugins/core/components/ChatPage.js index 3bb80f9c..030126b3 100644 --- a/plugins/plugins/core/components/ChatPage.js +++ b/plugins/plugins/core/components/ChatPage.js @@ -321,13 +321,13 @@ class ChatPage extends LitElement {

    ${this.repliedToMessageObj.senderName ? this.repliedToMessageObj.senderName : this.repliedToMessageObj.sender}

    ${this.repliedToMessageObj.version.toString() === '1' ? html` - ${this.repliedToMessageObj.message} + ${this.repliedToMessageObj.message} ` : '' } ${+this.repliedToMessageObj.version > 1 ? html` - ${unsafeHTML(generateHTML(this.repliedToMessageObj.message, [StarterKit, Underline, Highlight]))} + ${unsafeHTML(generateHTML(this.repliedToMessageObj.message, [StarterKit, Underline, Highlight]))} ` : '' } @@ -344,7 +344,7 @@ class ChatPage extends LitElement {

    ${translate("chatpage.cchange25")}

    - ${unsafeHTML(generateHTML(this.editedMessageObj.message, [StarterKit, Underline, Highlight]))} + ${unsafeHTML(generateHTML(this.editedMessageObj.message, [StarterKit, Underline, Highlight]))}
    this.closeEditMessageContainer()}>
    @@ -1366,11 +1366,23 @@ class ChatPage extends LitElement { shouldUpdate(changedProperties) { if (changedProperties.has('chatId')) { + if (this.repliedToMessageObj) { + this.closeRepliedToContainer() + return true + } + + if (this.editedMessageObj) { + this.closeEditMessageContainer() + return true + } + return true } + if (changedProperties.has('setActiveChatHeadUrl')) { return false } + if (changedProperties.has('setOpenPrivateMessage')) { return false } @@ -1666,8 +1678,6 @@ class ChatPage extends LitElement { let list = [...decodeMsgs] - - this.messagesRendered = { messages: list, type: 'old', diff --git a/plugins/plugins/core/components/ChatSelect.js b/plugins/plugins/core/components/ChatSelect.js index 2565fc52..7e175ddd 100644 --- a/plugins/plugins/core/components/ChatSelect.js +++ b/plugins/plugins/core/components/ChatSelect.js @@ -14,7 +14,9 @@ class ChatSelect extends LitElement { iconName: { type: String }, activeChatHeadUrl: { type: String }, isImageLoaded: { type: Boolean }, - setActiveChatHeadUrl: { attribute: false } + setActiveChatHeadUrl: { attribute: false }, + avatarImg: { type: String } + } } @@ -27,8 +29,7 @@ class ChatSelect extends LitElement { this.selectedAddress = {} this.config = { user: { - node: { - } + node: {} } } this.chatInfo = {} @@ -36,29 +37,44 @@ class ChatSelect extends LitElement { this.activeChatHeadUrl = '' this.isImageLoaded = false this.imageFetches = 0 + this.avatarImg = '' } render() { - let avatarImg = '' - let backupAvatarImg = '' + let groupString = 'Group_' + this.chatInfo.groupId + let groupAvatarString = 'qortal_group_avatar_' + this.chatInfo.groupId - if (this.chatInfo.name) { - const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] - const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port + const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node] + const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port + + if (groupString === 'Group_0') { + const avatarUrl = `/img/qgcgroup.png` + this.avatarImg = this.createImage(avatarUrl) + } else if (groupString === 'Group_1') { + const avatarUrl = `/img/qdcgroup.png` + this.avatarImg = this.createImage(avatarUrl) + } else if (this.chatInfo.name) { const avatarUrl = `${nodeUrl}/arbitrary/THUMBNAIL/${this.chatInfo.name}/qortal_avatar?async=true` - avatarImg = this.createImage(avatarUrl) + this.avatarImg = this.createImage(avatarUrl) + } else if (this.chatInfo.ownerName) { + if (this.chatInfo.ownerName === undefined) { + // Nothing to do + } else { + const avatarUrl = `${nodeUrl}/arbitrary/THUMBNAIL/${this.chatInfo.ownerName}/${groupAvatarString}?async=true` + this.avatarImg = this.createImage(avatarUrl) + } } return html`
  • this.getUrl(this.chatInfo.url)} class="clearfix ${this.activeChatHeadUrl === this.chatInfo.url ? 'active' : ''}"> - ${this.isImageLoaded ? html`${avatarImg}` : html``} + ${this.isImageLoaded ? html`${this.avatarImg}` : html``} ${!this.isImageLoaded && !this.chatInfo.name && !this.chatInfo.groupName ? html`account_circle` : html``} ${!this.isImageLoaded && this.chatInfo.name ? html`
    ${this.chatInfo.name.charAt(0)}
    @@ -70,7 +86,7 @@ class ChatSelect extends LitElement {
    ${this.chatInfo.groupName.charAt(0)}
    diff --git a/plugins/plugins/core/components/ChatTextEditor.js b/plugins/plugins/core/components/ChatTextEditor.js index c989c169..3d6d07d4 100644 --- a/plugins/plugins/core/components/ChatTextEditor.js +++ b/plugins/plugins/core/components/ChatTextEditor.js @@ -60,12 +60,12 @@ class ChatTextEditor extends LitElement { render() { return html` -
    -
    +
    +
    @@ -104,7 +104,7 @@ class ChatTextEditor extends LitElement {
    ${this.iframeId === "_chatEditorDOM" ? html` -
    +
    @@ -126,8 +126,8 @@ class ChatTextEditor extends LitElement { : '' }
    -
    -
    {this.preventUserSendingImage(e)}}> +
    +
    {this.preventUserSendingImage(e)}}>
    - +
    ${this.editedMessageObj ? - (html` -
    + html` +
    ${this.isLoading === false ? html` {this.sendMessageFunc(this.messageQueue)}}> @@ -162,11 +162,11 @@ class ChatTextEditor extends LitElement { ` }
    - `) : html` + ` : html`
    ${this.isLoading === false ? html` - send-icon {this.sendMessageFunc(this.messageQueue)}} /> + send-icon {this.sendMessageFunc(this.messageQueue)}}> ` : html` ` @@ -178,7 +178,7 @@ class ChatTextEditor extends LitElement { ${this.chatMessageSize >= 750 ? html`
    -
    +
    ${`Your message size is of ${this.chatMessageSize} bytes out of a maximum of 4000`}
    diff --git a/plugins/plugins/core/components/plugins-css.js b/plugins/plugins/core/components/plugins-css.js index ee320917..e4b00fb1 100644 --- a/plugins/plugins/core/components/plugins-css.js +++ b/plugins/plugins/core/components/plugins-css.js @@ -120,7 +120,7 @@ export const chatpageStyles = css` .message-size { font-family: Roboto, sans-serif; font-size: 12px; - color: black; + color: var(--black); } .lds-grid { @@ -508,7 +508,7 @@ export const chatpageStyles = css` .message-size { font-family: Roboto, sans-serif; font-size: 12px; - color: black; + color: var(--black); } .lds-grid { @@ -3529,7 +3529,7 @@ export const chatTextEditorStyles = css` .message-size { font-family: Roboto, sans-serif; font-size: 12px; - color: black; + color: var(--black); } .paperclip-icon { From 0b2bceb84294e02548d0f862a9d96bc8439cf1ec Mon Sep 17 00:00:00 2001 From: AlphaX-Projects <77661270+AlphaX-Projects@users.noreply.github.com> Date: Fri, 10 May 2024 18:00:47 +0200 Subject: [PATCH 10/11] Remove use strict make api full esm compatible --- crypto/api.js | 18 +- crypto/api/PhraseWallet.js | 15 +- crypto/api/api.js | 10 +- crypto/api/bitcoin/AltcoinHDWallet.js | 1272 +++-- crypto/api/bitcoin/ecbn.js | 4978 ++++++++--------- crypto/api/bitcoin/jsbn.js | 3875 +++++++------ crypto/api/constants.js | 2 - crypto/api/createTransaction.js | 16 +- crypto/api/createWallet.js | 8 +- crypto/api/decryptStoredWallet.js | 10 +- crypto/api/deps/Base58.js | 171 +- crypto/api/deps/Base64.js | 19 +- crypto/api/deps/bcrypt.js | 2670 ++++----- crypto/api/deps/broken-ripemd160.js | 343 +- crypto/api/deps/deps.js | 5 +- crypto/api/deps/ed2curve.js | 476 +- crypto/api/deps/nacl-fast.js | 3947 +++++++------ crypto/api/deps/qora.js | 88 +- crypto/api/deps/ripemd160.js | 2 + crypto/api/deps/sha256.js | 245 +- crypto/api/deps/utils.js | 119 +- crypto/api/fetch-request.js | 2 +- crypto/api/kdf.js | 12 +- crypto/api/registerUsername.js | 2 +- crypto/api/storeWallet.js | 6 +- crypto/api/tradeRequest.js | 10 +- crypto/api/transactions/AirdropTransaction.js | 2 +- .../api/transactions/DeployAtTransaction.js | 4 +- crypto/api/transactions/PaymentTransaction.js | 2 +- .../api/transactions/PublicizeTransaction.js | 32 +- crypto/api/transactions/TransactionBase.js | 2 +- .../transactions/TransferPrivsTransaction.js | 4 +- crypto/api/transactions/arbitraryV3.js | 62 +- crypto/api/transactions/chat/ChatBase.js | 236 +- .../api/transactions/chat/ChatTransaction.js | 4 +- .../transactions/chat/GroupChatTransaction.js | 2 +- .../transactions/chat/decryptChatMessage.js | 2 +- .../groups/AddGroupAdminTransaction.js | 2 +- .../groups/CancelGroupBanTransaction.js | 2 +- .../groups/CancelGroupInviteTransaction.js | 2 +- .../groups/CreateGroupTransaction.js | 2 +- .../groups/GroupBanTransaction.js | 2 +- .../groups/GroupInviteTransaction.js | 2 +- .../groups/GroupKickTransaction.js | 2 +- .../groups/JoinGroupTransaction.js | 2 +- .../groups/LeaveGroupTransaction.js | 2 +- .../groups/RemoveGroupAdminTransaction.js | 2 +- .../groups/UpdateGroupTransaction.js | 2 +- .../transactions/names/BuyNameTransacion.js | 2 +- .../names/CancelSellNameTransacion.js | 2 +- .../names/RegisterNameTransaction.js | 2 +- .../transactions/names/SellNameTransacion.js | 2 +- .../names/UpdateNameTransaction.js | 2 +- .../polls/CreatePollTransaction.js | 6 +- .../polls/VoteOnPollTransaction.js | 4 +- .../api/transactions/registerName_dnsthing.js | 60 +- .../RemoveRewardShareTransaction.js | 4 +- .../reward-share/RewardShareTransaction.js | 4 +- crypto/api/utils/randomBase58Generator.js | 18 +- crypto/api/utils/stateAwait.js | 40 +- crypto/api/wallet/base58PublicKeyToAddress.js | 2 +- crypto/api/wallet/publicKeyToAddress.js | 14 +- crypto/api/wallet/validateAddress.js | 4 +- crypto/config.js | 2 +- 64 files changed, 9391 insertions(+), 9472 deletions(-) diff --git a/crypto/api.js b/crypto/api.js index e7ea9034..244be3a5 100644 --- a/crypto/api.js +++ b/crypto/api.js @@ -1,9 +1,9 @@ -import {Sha256} from 'asmcrypto.js' +import { Sha256 } from 'asmcrypto.js' import Base58 from './api/deps/Base58' import Base64 from './api/deps/Base64' -import {base58PublicKeyToAddress} from './api/wallet/base58PublicKeyToAddress' -import {validateAddress} from './api/wallet/validateAddress' -import {decryptChatMessage, decryptChatMessageBase64} from './api/transactions/chat/decryptChatMessage' +import { base58PublicKeyToAddress } from './api/wallet/base58PublicKeyToAddress' +import { validateAddress } from './api/wallet/validateAddress' +import { decryptChatMessage, decryptChatMessageBase64 } from './api/transactions/chat/decryptChatMessage' import _ from 'lodash' window.Sha256 = Sha256 @@ -15,8 +15,8 @@ window.validateAddress = validateAddress window.decryptChatMessage = decryptChatMessage window.decryptChatMessageBase64 = decryptChatMessageBase64 -export { initApi, store } from './api_deps.js' -export * from './api/deps/deps.js' -export * from './api/api.js' -export * from './api/registerUsername.js' -export { createWallet } from './api/createWallet.js' +export { initApi, store } from './api_deps' +export * from './api/deps/deps' +export * from './api/api' +export * from './api/registerUsername' +export { createWallet } from './api/createWallet' diff --git a/crypto/api/PhraseWallet.js b/crypto/api/PhraseWallet.js index bfe81999..8c7732cb 100644 --- a/crypto/api/PhraseWallet.js +++ b/crypto/api/PhraseWallet.js @@ -1,15 +1,12 @@ /* Copyright 2017-2018 @ irontiga and vbcs (original developer) */ -'use strict' -import Base58 from './deps/Base58.js' -import {Sha256, Sha512} from 'asmcrypto.js' -import nacl from './deps/nacl-fast.js' -import utils from './deps/utils.js' - -import {generateSaveWalletData} from './storeWallet.js' - -import publicKeyToAddress from './wallet/publicKeyToAddress.js' +import Base58 from './deps/Base58' +import { Sha256, Sha512 } from 'asmcrypto.js' +import nacl from './deps/nacl-fast' +import utils from './deps/utils' +import { generateSaveWalletData } from './storeWallet' +import publicKeyToAddress from './wallet/publicKeyToAddress' import AltcoinHDWallet from "./bitcoin/AltcoinHDWallet" export default class PhraseWallet { diff --git a/crypto/api/api.js b/crypto/api/api.js index 36a635cc..3c240b2e 100644 --- a/crypto/api/api.js +++ b/crypto/api/api.js @@ -1,5 +1,5 @@ -export { request } from './fetch-request.js' -export { transactionTypes as transactions } from './transactions/transactions.js' -export { processTransaction, processTransactionVersion2, createTransaction, computeChatNonce, signChatTransaction, signArbitraryTransaction, signArbitraryWithFeeTransaction } from './createTransaction.js' -export { tradeBotCreateRequest, tradeBotRespondRequest, signTradeBotTxn, deleteTradeOffer, sendBtc, sendLtc, sendDoge, sendDgb, sendRvn, sendArrr } from './tradeRequest.js' -export { cancelAllOffers } from './transactions/trade-portal/tradeoffer/cancelAllOffers.js' +export { request } from './fetch-request' +export { transactionTypes as transactions } from './transactions/transactions' +export { processTransaction, processTransactionVersion2, createTransaction, computeChatNonce, signChatTransaction, signArbitraryTransaction, signArbitraryWithFeeTransaction } from './createTransaction' +export { tradeBotCreateRequest, tradeBotRespondRequest, signTradeBotTxn, deleteTradeOffer, sendBtc, sendLtc, sendDoge, sendDgb, sendRvn, sendArrr } from './tradeRequest' +export { cancelAllOffers } from './transactions/trade-portal/tradeoffer/cancelAllOffers' diff --git a/crypto/api/bitcoin/AltcoinHDWallet.js b/crypto/api/bitcoin/AltcoinHDWallet.js index b7391b8a..a802382c 100644 --- a/crypto/api/bitcoin/AltcoinHDWallet.js +++ b/crypto/api/bitcoin/AltcoinHDWallet.js @@ -1,859 +1,845 @@ -'use strict'; -import Base58 from '../deps/Base58.js' -import {Sha256, Sha512} from 'asmcrypto.js' +import Base58 from '../deps/Base58' +import { Sha256, Sha512 } from 'asmcrypto.js' import jsSHA from 'jssha' -import RIPEMD160 from '../deps/ripemd160.js' -import utils from '../deps/utils.js' -import {BigInteger, EllipticCurve} from './ecbn.js' +import RIPEMD160 from '../deps/ripemd160' +import utils from '../deps/utils' +import { BigInteger, EllipticCurve } from './ecbn' export default class AltcoinHDWallet { - constructor(addressParams) { + constructor(addressParams) { - /** - * Seed - 32 bytes - */ + /** + * Seed - 32 bytes + */ - this.seed = new Uint8Array(32) + this.seed = new Uint8Array(32) - /** - * Version Bytes - 4 byte - */ + /** + * Version Bytes - 4 byte + */ - this.versionBytes = addressParams + this.versionBytes = addressParams - /** - * Depth - 1 byte - */ + /** + * Depth - 1 byte + */ - this.depth = 0 + this.depth = 0 - /** - * Parent Fingerprint - 4 bytes - */ + /** + * Parent Fingerprint - 4 bytes + */ - this.parentFingerprint = '0x00000000' // master key + this.parentFingerprint = '0x00000000' // master key - /** - * Child Index - 4 bytes - */ + /** + * Child Index - 4 bytes + */ - this.childIndex = '0x00000000' // master key + this.childIndex = '0x00000000' // master key - /** - * Chain Code - 32 bytes - */ + /** + * Chain Code - 32 bytes + */ - this.chainCode = new Uint8Array(32) + this.chainCode = new Uint8Array(32) - /** - * Key Data - 33 bytes - */ + /** + * Key Data - 33 bytes + */ - this.keyData = new Uint8Array(33) + this.keyData = new Uint8Array(33) - /** - * Seed Hash - 64 bytes - */ + /** + * Seed Hash - 64 bytes + */ - this.seedHash = new Uint8Array(64) + this.seedHash = new Uint8Array(64) - /** - * Private Key - 32 bytes - */ + /** + * Private Key - 32 bytes + */ - this.privateKey = new Uint8Array(32) + this.privateKey = new Uint8Array(32) - /** - * Public Key - 33 bytes (compressed) - */ + /** + * Public Key - 33 bytes (compressed) + */ - this.publicKey = new Uint8Array(33) + this.publicKey = new Uint8Array(33) - /** - * Public Key Hash160 (used to derive the parent fingerprint for derived) - */ + /** + * Public Key Hash160 (used to derive the parent fingerprint for derived) + */ - this.publicKeyHash = new Uint8Array(20) + this.publicKeyHash = new Uint8Array(20) - /** - * Master Private Key (Base58 encoded) - */ + /** + * Master Private Key (Base58 encoded) + */ - this.masterPrivateKey = '' + this.masterPrivateKey = '' - /** - * Master Public Key (Base58 encoded) - */ + /** + * Master Public Key (Base58 encoded) + */ - this.masterPublicKey = '' + this.masterPublicKey = '' - /** - * Testnet Master Private Key (Base58 encoded) - THIS IS TESTNET - */ + /** + * Testnet Master Private Key (Base58 encoded) - THIS IS TESTNET + */ - this._tMasterPrivateKey = '' + this._tMasterPrivateKey = '' - /** - * Testnet Master Public Key (Base58 encoded) - THIS IS TESTNET - */ + /** + * Testnet Master Public Key (Base58 encoded) - THIS IS TESTNET + */ - this._tmasterPublicKey = '' + this._tmasterPublicKey = '' - /** - * Child Keys Derivation from the Parent Keys - */ + /** + * Child Keys Derivation from the Parent Keys + */ - /** - * Child Private Key - 32 bytes - */ + /** + * Child Private Key - 32 bytes + */ - this.childPrivateKey = new Uint8Array(32) + this.childPrivateKey = new Uint8Array(32) - /** - * Child Chain Code - 32 bytes - */ + /** + * Child Chain Code - 32 bytes + */ - this.childChainCode = new Uint8Array(32) + this.childChainCode = new Uint8Array(32) - /** - * Child Public Key - 33 bytes (compressed) - */ + /** + * Child Public Key - 33 bytes (compressed) + */ - this.childPublicKey = new Uint8Array(33) + this.childPublicKey = new Uint8Array(33) - /** - * Child Public Key Hash160 (used to derive the parent fingerprint for derived) - */ + /** + * Child Public Key Hash160 (used to derive the parent fingerprint for derived) + */ - this.childPublicKeyHash = new Uint8Array(20) + this.childPublicKeyHash = new Uint8Array(20) - /** - * Extended Private Child Key - Base58 encoded - */ + /** + * Extended Private Child Key - Base58 encoded + */ - this.xPrivateChildKey = '' + this.xPrivateChildKey = '' - /** - * Extended Public Child Key - Base58 encoded - */ + /** + * Extended Public Child Key - Base58 encoded + */ - this.xPublicChildKey = '' + this.xPublicChildKey = '' - /** - * Grand Child Keys Derivation from the Child Keys - */ + /** + * Grand Child Keys Derivation from the Child Keys + */ - /** - * Grand Child Private Key - 32 bytes - */ + /** + * Grand Child Private Key - 32 bytes + */ - this.grandChildPrivateKey = new Uint8Array(32) + this.grandChildPrivateKey = new Uint8Array(32) - /** - * Grand Child Chain Code - 32 bytes - */ + /** + * Grand Child Chain Code - 32 bytes + */ - this.grandChildChainCode = new Uint8Array(32) + this.grandChildChainCode = new Uint8Array(32) - /** - * Grand Child Public Key - 33 bytes (compressed) - */ + /** + * Grand Child Public Key - 33 bytes (compressed) + */ - this.grandChildPublicKey = new Uint8Array(33) + this.grandChildPublicKey = new Uint8Array(33) - /** - * Grand Public Key Hash160 (used to derive the parent fingerprint for derived) - */ + /** + * Grand Public Key Hash160 (used to derive the parent fingerprint for derived) + */ - this.grandChildPublicKeyHash = new Uint8Array(20) + this.grandChildPublicKeyHash = new Uint8Array(20) - /** - * Extended Private Grand Child Key - Base58 encoded - */ + /** + * Extended Private Grand Child Key - Base58 encoded + */ - this.xPrivateGrandChildKey = '' + this.xPrivateGrandChildKey = '' - /** - * Extended Public Grand Child Key - Base58 encoded - */ + /** + * Extended Public Grand Child Key - Base58 encoded + */ - this.xPublicGrandChildKey = '' + this.xPublicGrandChildKey = '' - /** - * Litecoin Legacy Address - Derived from the Grand Child Public Key Hash - */ + /** + * Litecoin Legacy Address - Derived from the Grand Child Public Key Hash + */ - this.litecoinLegacyAddress = '' + this.litecoinLegacyAddress = '' - /** - * TESTNET Litecoin Legacy Address (Derived from the Grand Child Public Key Hash) - THIS IS TESTNET - */ + /** + * TESTNET Litecoin Legacy Address (Derived from the Grand Child Public Key Hash) - THIS IS TESTNET + */ - this._tlitecoinLegacyAddress = '' + this._tlitecoinLegacyAddress = '' - /** - * Wallet - Wallet Object (keys...) - */ + /** + * Wallet - Wallet Object (keys...) + */ - this.wallet = {} - } + this.wallet = {} + } - setSeed(seed) { - this.seed = seed - } + setSeed(seed) { + this.seed = seed + } - createWallet(seed, isBIP44, indicator = null) { + createWallet(seed, isBIP44, indicator = null) { - // Set Seeed - this.setSeed(seed) + // Set Seeed + this.setSeed(seed) - // Generate Seed Hash - this.generateSeedHash(this.seed, isBIP44, indicator) + // Generate Seed Hash + this.generateSeedHash(this.seed, isBIP44, indicator) - // Generate Private Key - this.generatePrivateKey(this.seedHash) + // Generate Private Key + this.generatePrivateKey(this.seedHash) - // Generate Chain Code - this.generateChainCode(this.seedHash) + // Generate Chain Code + this.generateChainCode(this.seedHash) - // Generate Public Key from Private Key - this.generatePublicKey(this.privateKey) + // Generate Public Key from Private Key + this.generatePublicKey(this.privateKey) - // Generate Mainnet Master Private Key - this.generateMainnetMasterPrivateKey() + // Generate Mainnet Master Private Key + this.generateMainnetMasterPrivateKey() - // Generate Mainnet Master Public Key - this.generateMainnetMasterPublicKey() + // Generate Mainnet Master Public Key + this.generateMainnetMasterPublicKey() - // Generate Testnet Master Private Key - this.generateTestnetMasterPrivateKey() + // Generate Testnet Master Private Key + this.generateTestnetMasterPrivateKey() - // Generate Testnet Master Public Key - this.generateTestnetMasterPublicKey() + // Generate Testnet Master Public Key + this.generateTestnetMasterPublicKey() - // Generate Child and Grand Child Keys - this.generateDerivedChildKeys() + // Generate Child and Grand Child Keys + this.generateDerivedChildKeys() - // Return Wallet Object Specification - return this.returnWallet() - } + // Return Wallet Object Specification + return this.returnWallet() + } - generateSeedHash(seed, isBIP44, indicator = null) { - let buffer + generateSeedHash(seed, isBIP44, indicator = null) { + let buffer - if (isBIP44) { - buffer = utils.appendBuffer(seed.reverse(), utils.int32ToBytes(indicator)) - } else { - if(indicator !== null) { - const indicatorString = utils.stringtoUTF8Array(indicator) - buffer = utils.appendBuffer(seed.reverse(), indicatorString) - } - else - { - buffer = seed.reverse() - } - } + if (isBIP44) { + buffer = utils.appendBuffer(seed.reverse(), utils.int32ToBytes(indicator)) + } else { + if (indicator !== null) { + const indicatorString = utils.stringtoUTF8Array(indicator) + buffer = utils.appendBuffer(seed.reverse(), indicatorString) + } + else { + buffer = seed.reverse() + } + } - const _reverseSeedHash = new Sha256().process(buffer).finish().result - this.seedHash = new Sha512().process(utils.appendBuffer(seed, _reverseSeedHash)).finish().result - } + const _reverseSeedHash = new Sha256().process(buffer).finish().result + this.seedHash = new Sha512().process(utils.appendBuffer(seed, _reverseSeedHash)).finish().result + } - generatePrivateKey(seedHash) { - const SECP256K1_CURVE_ORDER = new BigInteger("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141") + generatePrivateKey(seedHash) { + const SECP256K1_CURVE_ORDER = new BigInteger("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141") - const privateKeyHash = seedHash.slice(0, 32) + const privateKeyHash = seedHash.slice(0, 32) - this.seed58 = Base58.encode(privateKeyHash) + this.seed58 = Base58.encode(privateKeyHash) - const _privateKeyHash = [...privateKeyHash] - let privateKeyBigInt = BigInteger.fromByteArrayUnsigned(_privateKeyHash) + const _privateKeyHash = [...privateKeyHash] + let privateKeyBigInt = BigInteger.fromByteArrayUnsigned(_privateKeyHash) - const privateKey = (privateKeyBigInt.mod(SECP256K1_CURVE_ORDER.subtract(BigInteger.ONE))).add(BigInteger.ONE) - this.privateKey = privateKey.toByteArrayUnsigned() - } + const privateKey = (privateKeyBigInt.mod(SECP256K1_CURVE_ORDER.subtract(BigInteger.ONE))).add(BigInteger.ONE) + this.privateKey = privateKey.toByteArrayUnsigned() + } - generateChainCode(seedHash) { - this.chainCode = new Sha256().process(seedHash.slice(32, 64)).finish().result - } + generateChainCode(seedHash) { + this.chainCode = new Sha256().process(seedHash.slice(32, 64)).finish().result + } - generatePublicKey(privateKey) { - const _privateKey = [...privateKey] - const privateKeyBigInt = BigInteger.fromByteArrayUnsigned(_privateKey) + generatePublicKey(privateKey) { + const _privateKey = [...privateKey] + const privateKeyBigInt = BigInteger.fromByteArrayUnsigned(_privateKey) - const epCurve = EllipticCurve.getSECCurveByName("secp256k1") - const curvePoints = epCurve.getG().multiply(privateKeyBigInt) + const epCurve = EllipticCurve.getSECCurveByName("secp256k1") + const curvePoints = epCurve.getG().multiply(privateKeyBigInt) - const x = curvePoints.getX().toBigInteger() - const y = curvePoints.getY().toBigInteger() + const x = curvePoints.getX().toBigInteger() + const y = curvePoints.getY().toBigInteger() - /** - * Deriving Uncompressed Public Key (65 bytes) - * - * const publicKeyBytes = EllipticCurve.integerToBytes(x, 32) - * this.publicKey = publicKeyBytes.concat(EllipticCurve.integerToBytes(y, 32)) - * this.publicKey.unshift(0x04) // append point indicator - */ + /** + * Deriving Uncompressed Public Key (65 bytes) + * + * const publicKeyBytes = EllipticCurve.integerToBytes(x, 32) + * this.publicKey = publicKeyBytes.concat(EllipticCurve.integerToBytes(y, 32)) + * this.publicKey.unshift(0x04) // append point indicator + */ - // Compressed Public Key (33 bytes) - this.publicKey = EllipticCurve.integerToBytes(x, 32) + // Compressed Public Key (33 bytes) + this.publicKey = EllipticCurve.integerToBytes(x, 32) - if (y.isEven()) { - this.publicKey.unshift(0x02) // append point indicator - } else { - this.publicKey.unshift(0x03) // append point indicator - } + if (y.isEven()) { + this.publicKey.unshift(0x02) // append point indicator + } else { + this.publicKey.unshift(0x03) // append point indicator + } - // PublicKey Hash - const publicKeySHA256 = new Sha256().process(new Uint8Array(this.publicKey)).finish().result + // PublicKey Hash + const publicKeySHA256 = new Sha256().process(new Uint8Array(this.publicKey)).finish().result this.publicKeyHash = new RIPEMD160().update(Buffer.from(publicKeySHA256)).digest('hex') - } + } - generateMainnetMasterPrivateKey() { - // Serialization Variable - const s = [] + generateMainnetMasterPrivateKey() { + // Serialization Variable + const s = [] - // Append Version Byte - s.push(...(utils.int32ToBytes(this.versionBytes.mainnet.private))) + // Append Version Byte + s.push(...(utils.int32ToBytes(this.versionBytes.mainnet.private))) - // Append Depth - s.push(this.depth) + // Append Depth + s.push(this.depth) - // Append Parent Fingerprint - s.push(...(utils.int32ToBytes(this.parentFingerprint))) + // Append Parent Fingerprint + s.push(...(utils.int32ToBytes(this.parentFingerprint))) - // Append Child Number - s.push(...(utils.int32ToBytes(this.childIndex))) + // Append Child Number + s.push(...(utils.int32ToBytes(this.childIndex))) - // Append Chain Code - s.push(...this.chainCode) + // Append Chain Code + s.push(...this.chainCode) - // Append 1 byte '0x00' (to make the key data 33 bytes, DO THIS ONLY FOR PRIVATE KEYS ) - s.push(0) + // Append 1 byte '0x00' (to make the key data 33 bytes, DO THIS ONLY FOR PRIVATE KEYS ) + s.push(0) - //if the private key length is less than 32 let's add leading zeros - if(this.privateKey.length<32){ - for(let i=this.privateKey.length;i<32;i++){ - s.push(0) - } - } + //if the private key length is less than 32 let's add leading zeros + if (this.privateKey.length < 32) { + for (let i = this.privateKey.length; i < 32; i++) { + s.push(0) + } + } - // Append Private Key - s.push(...this.privateKey) + // Append Private Key + s.push(...this.privateKey) - // Generate CheckSum - const _s = new Uint8Array(s) - const _checkSum = new Sha256().process(new Sha256().process(_s).finish().result).finish().result - const checkSum = _checkSum.slice(0, 4) + // Generate CheckSum + const _s = new Uint8Array(s) + const _checkSum = new Sha256().process(new Sha256().process(_s).finish().result).finish().result + const checkSum = _checkSum.slice(0, 4) - // Append CheckSum - s.push(...checkSum) // And this brings us to the end of the serialization... + // Append CheckSum + s.push(...checkSum) // And this brings us to the end of the serialization... - // Save to Private Key as Base58 encoded - this.masterPrivateKey = Base58.encode(s) - } + // Save to Private Key as Base58 encoded + this.masterPrivateKey = Base58.encode(s) + } - generateMainnetMasterPublicKey() { - // Serialization Variable - const s = [] + generateMainnetMasterPublicKey() { + // Serialization Variable + const s = [] - // Append Version Byte - s.push(...(utils.int32ToBytes(this.versionBytes.mainnet.public))) + // Append Version Byte + s.push(...(utils.int32ToBytes(this.versionBytes.mainnet.public))) - // Append Depth - s.push(this.depth) + // Append Depth + s.push(this.depth) - // Append Parent Fingerprint - s.push(...(utils.int32ToBytes(this.parentFingerprint))) + // Append Parent Fingerprint + s.push(...(utils.int32ToBytes(this.parentFingerprint))) - // Append Child Number - s.push(...(utils.int32ToBytes(this.childIndex))) + // Append Child Number + s.push(...(utils.int32ToBytes(this.childIndex))) - // Append Chain Code - s.push(...this.chainCode) + // Append Chain Code + s.push(...this.chainCode) - // Append Public Key - s.push(...this.publicKey) + // Append Public Key + s.push(...this.publicKey) - // Generate CheckSum - const _s = new Uint8Array(s) - const _checkSum = new Sha256().process(new Sha256().process(_s).finish().result).finish().result - const checkSum = _checkSum.slice(0, 4) + // Generate CheckSum + const _s = new Uint8Array(s) + const _checkSum = new Sha256().process(new Sha256().process(_s).finish().result).finish().result + const checkSum = _checkSum.slice(0, 4) - // Append CheckSum - s.push(...checkSum) // And this brings us to the end of the serialization... + // Append CheckSum + s.push(...checkSum) // And this brings us to the end of the serialization... - // Save to Public Key as Base58 encoded - this.masterPublicKey = Base58.encode(s) - } + // Save to Public Key as Base58 encoded + this.masterPublicKey = Base58.encode(s) + } - generateTestnetMasterPrivateKey() { + generateTestnetMasterPrivateKey() { - // To be Used ONLY in Testnet... + // To be Used ONLY in Testnet... - // Serialization Variable - const s = [] + // Serialization Variable + const s = [] - // Append Version Byte - s.push(...(utils.int32ToBytes(this.versionBytes.testnet.private))) + // Append Version Byte + s.push(...(utils.int32ToBytes(this.versionBytes.testnet.private))) - // Append Depth - s.push(this.depth) + // Append Depth + s.push(this.depth) - // Append Parent Fingerprint - s.push(...(utils.int32ToBytes(this.parentFingerprint))) + // Append Parent Fingerprint + s.push(...(utils.int32ToBytes(this.parentFingerprint))) - // Append Child Number - s.push(...(utils.int32ToBytes(this.childIndex))) + // Append Child Number + s.push(...(utils.int32ToBytes(this.childIndex))) - // Append Chain Code - s.push(...this.chainCode) + // Append Chain Code + s.push(...this.chainCode) - // Append 1 byte '0x00' (to make the key data 33 bytes, DO THIS ONLY FOR PRIVATE KEYS ) - s.push(0) + // Append 1 byte '0x00' (to make the key data 33 bytes, DO THIS ONLY FOR PRIVATE KEYS ) + s.push(0) - // Append Private Key - s.push(...this.privateKey) + // Append Private Key + s.push(...this.privateKey) - // Generate CheckSum - const _s = new Uint8Array(s) - const _checkSum = new Sha256().process(new Sha256().process(_s).finish().result).finish().result - const checkSum = _checkSum.slice(0, 4) + // Generate CheckSum + const _s = new Uint8Array(s) + const _checkSum = new Sha256().process(new Sha256().process(_s).finish().result).finish().result + const checkSum = _checkSum.slice(0, 4) - // Append CheckSum - s.push(...checkSum) // And this brings us to the end of the serialization... + // Append CheckSum + s.push(...checkSum) // And this brings us to the end of the serialization... - // Save to Private Key as Base58 encoded - this._tMasterPrivateKey = Base58.encode(s) - } + // Save to Private Key as Base58 encoded + this._tMasterPrivateKey = Base58.encode(s) + } - generateTestnetMasterPublicKey() { + generateTestnetMasterPublicKey() { - // To be Used ONLY in Testnet... + // To be Used ONLY in Testnet... - // Serialization Variable - const s = [] + // Serialization Variable + const s = [] - // Append Version Byte - s.push(...(utils.int32ToBytes(this.versionBytes.testnet.public))) + // Append Version Byte + s.push(...(utils.int32ToBytes(this.versionBytes.testnet.public))) - // Append Depth - s.push(this.depth) + // Append Depth + s.push(this.depth) - // Append Parent Fingerprint - s.push(...(utils.int32ToBytes(this.parentFingerprint))) + // Append Parent Fingerprint + s.push(...(utils.int32ToBytes(this.parentFingerprint))) - // Append Child Number - s.push(...(utils.int32ToBytes(this.childIndex))) + // Append Child Number + s.push(...(utils.int32ToBytes(this.childIndex))) - // Append Chain Code - s.push(...this.chainCode) + // Append Chain Code + s.push(...this.chainCode) - // Append Private Key - s.push(...this.publicKey) + // Append Private Key + s.push(...this.publicKey) - // Generate CheckSum - const _s = new Uint8Array(s) - const _checkSum = new Sha256().process(new Sha256().process(_s).finish().result).finish().result - const checkSum = _checkSum.slice(0, 4) + // Generate CheckSum + const _s = new Uint8Array(s) + const _checkSum = new Sha256().process(new Sha256().process(_s).finish().result).finish().result + const checkSum = _checkSum.slice(0, 4) - // Append CheckSum - s.push(...checkSum) // And this brings us to the end of the serialization... + // Append CheckSum + s.push(...checkSum) // And this brings us to the end of the serialization... - // Save to Private Key as Base58 encoded - this._tmasterPublicKey = Base58.encode(s) - } + // Save to Private Key as Base58 encoded + this._tmasterPublicKey = Base58.encode(s) + } - generateDerivedChildKeys() { + generateDerivedChildKeys() { - // SPEC INFO: https://en.bitcoin.it/wiki/BIP_0032#Child_key_derivation_.28CKD.29_functions - // NOTE: will not be using some of derivations func as the value is known. (So I'd rather shove in the values and rewrite out the derivations later ?) + // SPEC INFO: https://en.bitcoin.it/wiki/BIP_0032#Child_key_derivation_.28CKD.29_functions + // NOTE: will not be using some of derivations func as the value is known. (So I'd rather shove in the values and rewrite out the derivations later ?) - // NOTE: I "re-wrote" and "reduplicate" the code for child and grandChild keys derivations inorder to get the child and grandchild from the child - // TODO: Make this more better in the future + // NOTE: I "re-wrote" and "reduplicate" the code for child and grandChild keys derivations inorder to get the child and grandchild from the child + // TODO: Make this more better in the future - const path = 'm/0/0' - // let p = path.split('/') + const path = 'm/0/0' + // let p = path.split('/') - // Get Public kEY - const derivePublicChildKey = () => { + // Get Public kEY + const derivePublicChildKey = () => { - const _privateKey = [...this.childPrivateKey] - const privateKeyBigInt = BigInteger.fromByteArrayUnsigned(_privateKey) + const _privateKey = [...this.childPrivateKey] + const privateKeyBigInt = BigInteger.fromByteArrayUnsigned(_privateKey) - const epCurve = EllipticCurve.getSECCurveByName("secp256k1") - const curvePoints = epCurve.getG().multiply(privateKeyBigInt) + const epCurve = EllipticCurve.getSECCurveByName("secp256k1") + const curvePoints = epCurve.getG().multiply(privateKeyBigInt) - const x = curvePoints.getX().toBigInteger() - const y = curvePoints.getY().toBigInteger() + const x = curvePoints.getX().toBigInteger() + const y = curvePoints.getY().toBigInteger() - // Compressed Public Key (33 bytes) - this.childPublicKey = EllipticCurve.integerToBytes(x, 32) + // Compressed Public Key (33 bytes) + this.childPublicKey = EllipticCurve.integerToBytes(x, 32) - if (y.isEven()) { + if (y.isEven()) { - this.childPublicKey.unshift(0x02) // append point indicator - } else { + this.childPublicKey.unshift(0x02) // append point indicator + } else { - this.childPublicKey.unshift(0x03) // append point indicator - } + this.childPublicKey.unshift(0x03) // append point indicator + } - // PublicKey Hash - const childPublicKeySHA256 = new Sha256().process(new Uint8Array(this.childPublicKey)).finish().result + // PublicKey Hash + const childPublicKeySHA256 = new Sha256().process(new Uint8Array(this.childPublicKey)).finish().result this.childPublicKeyHash = new RIPEMD160().update(Buffer.from(childPublicKeySHA256)).digest('hex') + // Call deriveExtendedPublicChildKey // WIll be hardcoding the values... + deriveExtendedPublicChildKey(1, 0) + } - // Call deriveExtendedPublicChildKey // WIll be hardcoding the values... - deriveExtendedPublicChildKey(1, 0) - } + const derivePrivateChildKey = (cI) => { - const derivePrivateChildKey = (cI) => { + let ib = [] + ib.push((cI >> 24) & 0xff) + ib.push((cI >> 16) & 0xff) + ib.push((cI >> 8) & 0xff) + ib.push(cI & 0xff) - let ib = [] - ib.push((cI >> 24) & 0xff) - ib.push((cI >> 16) & 0xff) - ib.push((cI >> 8) & 0xff) - ib.push(cI & 0xff) + const s = [...this.publicKey].concat(ib) - const s = [...this.publicKey].concat(ib) + const _hmacSha512 = new jsSHA("SHA-512", "UINT8ARRAY", { numRounds: 1, hmacKey: { value: this.chainCode, format: "UINT8ARRAY" } }) + _hmacSha512.update(new Uint8Array(s)) - const _hmacSha512 = new jsSHA("SHA-512", "UINT8ARRAY", { numRounds: 1, hmacKey: { value: this.chainCode, format: "UINT8ARRAY" } }) - _hmacSha512.update(new Uint8Array(s)) + const IL = BigInteger.fromByteArrayUnsigned([..._hmacSha512.getHMAC('UINT8ARRAY').slice(0, 32)]) + this.childChainCode = _hmacSha512.getHMAC('UINT8ARRAY').slice(32, 64) // IR according to the SPEC + + // SECP256k1 init + const epCurve = EllipticCurve.getSECCurveByName("secp256k1") + + const ki = IL.add(BigInteger.fromByteArrayUnsigned(this.privateKey)).mod(epCurve.getN()) // parse256(IL) + kpar (mod n) ==> ki + this.childPrivateKey = ki.toByteArrayUnsigned() + + // Call deriveExtendedPrivateChildKey + deriveExtendedPrivateChildKey(1, 0) + } - const IL = BigInteger.fromByteArrayUnsigned([..._hmacSha512.getHMAC('UINT8ARRAY').slice(0, 32)]) - this.childChainCode = _hmacSha512.getHMAC('UINT8ARRAY').slice(32, 64) // IR according to the SPEC + const deriveExtendedPrivateChildKey = (i, childIndex) => { + + // Serialization Variable + const s = [] + + // Append Version Byte + s.push(...(utils.int32ToBytes(this.versionBytes.mainnet.private))) + + // Append Depth (using the index as depth) + i = parseInt(i) + s.push(i) + + // Append Parent Fingerprint + s.push(...(this.publicKeyHash.slice(0, 4))) + + // Append Child Index + s.push(childIndex >>> 24) + s.push((childIndex >>> 16) & 0xff) + s.push((childIndex >>> 8) & 0xff) + s.push(childIndex & 0xff) + + // Append Chain Code + s.push(...this.childChainCode) + + // Append 1 byte '0x00' (to make the key data 33 bytes, DO THIS ONLY FOR PRIVATE KEYS ) + s.push(0) + + // Append Private Key + s.push(...this.childPrivateKey) + + // Generate CheckSum + const _s = new Uint8Array(s) + const _checkSum = new Sha256().process(new Sha256().process(_s).finish().result).finish().result + const checkSum = _checkSum.slice(0, 4) + + // Append CheckSum + s.push(...checkSum) // And this brings us to the end of the serialization... + + // Save to Private Key as Base58 encoded + this.xPrivateChildKey = Base58.encode(s) + } + + const deriveExtendedPublicChildKey = (i, childIndex) => { + + // Serialization Variable + const s = [] + + // Append Version Byte + s.push(...(utils.int32ToBytes(this.versionBytes.mainnet.public))) + + // Append Depth + i = parseInt(i) + s.push(i) + + // Append Parent Fingerprint + s.push(...(this.publicKeyHash.slice(0, 4))) + + // Append Child Index + s.push(childIndex >>> 24) + s.push((childIndex >>> 16) & 0xff) + s.push((childIndex >>> 8) & 0xff) + s.push(childIndex & 0xff) + + // Append Chain Code + s.push(...this.childChainCode) + + // Append Public Key + s.push(...this.childPublicKey) + + // Generate CheckSum + const _s = new Uint8Array(s) + const _checkSum = new Sha256().process(new Sha256().process(_s).finish().result).finish().result + const checkSum = _checkSum.slice(0, 4) + + // Append CheckSum + s.push(...checkSum) // And this brings us to the end of the serialization... - // SECP256k1 init - const epCurve = EllipticCurve.getSECCurveByName("secp256k1") + // Save to Public Key as Base58 encoded + this.xPublicChildKey = Base58.encode(s) + } - const ki = IL.add(BigInteger.fromByteArrayUnsigned(this.privateKey)).mod(epCurve.getN()) // parse256(IL) + kpar (mod n) ==> ki - this.childPrivateKey = ki.toByteArrayUnsigned() + /** + * GRAND CHILD KEYS + * + * NOTE: I know this is not the best way to generate this (even though it works the way it ought) + * Things to rewrite will be and not limited to deriving this through a for loop, removing hard code values, etc... + */ - // Call deriveExtendedPrivateChildKey - deriveExtendedPrivateChildKey(1, 0) - } + const derivePublicGrandChildKey = () => { + + const _privateKey = [...this.grandChildPrivateKey] + const privateKeyBigInt = BigInteger.fromByteArrayUnsigned(_privateKey) - const deriveExtendedPrivateChildKey = (i, childIndex) => { + const epCurve = EllipticCurve.getSECCurveByName("secp256k1") + const curvePoints = epCurve.getG().multiply(privateKeyBigInt) - // Serialization Variable - const s = [] + const x = curvePoints.getX().toBigInteger() + const y = curvePoints.getY().toBigInteger() - // Append Version Byte - s.push(...(utils.int32ToBytes(this.versionBytes.mainnet.private))) - - // Append Depth (using the index as depth) - i = parseInt(i) - s.push(i) - - // Append Parent Fingerprint - s.push(...(this.publicKeyHash.slice(0, 4))) - - // Append Child Index - s.push(childIndex >>> 24) - s.push((childIndex >>> 16) & 0xff) - s.push((childIndex >>> 8) & 0xff) - s.push(childIndex & 0xff) - - // Append Chain Code - s.push(...this.childChainCode) - - // Append 1 byte '0x00' (to make the key data 33 bytes, DO THIS ONLY FOR PRIVATE KEYS ) - s.push(0) - - // Append Private Key - s.push(...this.childPrivateKey) - - // Generate CheckSum - const _s = new Uint8Array(s) - const _checkSum = new Sha256().process(new Sha256().process(_s).finish().result).finish().result - const checkSum = _checkSum.slice(0, 4) - - // Append CheckSum - s.push(...checkSum) // And this brings us to the end of the serialization... - - // Save to Private Key as Base58 encoded - this.xPrivateChildKey = Base58.encode(s) - } - - const deriveExtendedPublicChildKey = (i, childIndex) => { - - // Serialization Variable - const s = [] - - // Append Version Byte - s.push(...(utils.int32ToBytes(this.versionBytes.mainnet.public))) - - // Append Depth - i = parseInt(i) - s.push(i) - - // Append Parent Fingerprint - s.push(...(this.publicKeyHash.slice(0, 4))) - - // Append Child Index - s.push(childIndex >>> 24) - s.push((childIndex >>> 16) & 0xff) - s.push((childIndex >>> 8) & 0xff) - s.push(childIndex & 0xff) - - // Append Chain Code - s.push(...this.childChainCode) - - // Append Public Key - s.push(...this.childPublicKey) - - // Generate CheckSum - const _s = new Uint8Array(s) - const _checkSum = new Sha256().process(new Sha256().process(_s).finish().result).finish().result - const checkSum = _checkSum.slice(0, 4) - - // Append CheckSum - s.push(...checkSum) // And this brings us to the end of the serialization... + // Compressed Public Key (33 bytes) + this.grandChildPublicKey = EllipticCurve.integerToBytes(x, 32) - // Save to Public Key as Base58 encoded - this.xPublicChildKey = Base58.encode(s) - } + if (y.isEven()) { + this.grandChildPublicKey.unshift(0x02) // append point indicator + } else { + this.grandChildPublicKey.unshift(0x03) // append point indicator + } - - /** - * GRAND CHILD KEYS - * - * NOTE: I know this is not the best way to generate this (even though it works the way it ought) - * Things to rewrite will be and not limited to deriving this through a for loop, removing hard code values, etc... - */ - - const derivePublicGrandChildKey = () => { - - const _privateKey = [...this.grandChildPrivateKey] - const privateKeyBigInt = BigInteger.fromByteArrayUnsigned(_privateKey) - - - const epCurve = EllipticCurve.getSECCurveByName("secp256k1") - const curvePoints = epCurve.getG().multiply(privateKeyBigInt) - - const x = curvePoints.getX().toBigInteger() - const y = curvePoints.getY().toBigInteger() - - // Compressed Public Key (33 bytes) - this.grandChildPublicKey = EllipticCurve.integerToBytes(x, 32) - - - if (y.isEven()) { - this.grandChildPublicKey.unshift(0x02) // append point indicator - } else { - this.grandChildPublicKey.unshift(0x03) // append point indicator - } - - - // PublicKey Hash - const grandChildPublicKeySHA256 = new Sha256().process(new Uint8Array(this.grandChildPublicKey)).finish().result + // PublicKey Hash + const grandChildPublicKeySHA256 = new Sha256().process(new Uint8Array(this.grandChildPublicKey)).finish().result this.grandChildPublicKeyHash = new RIPEMD160().update(Buffer.from(grandChildPublicKeySHA256)).digest('hex') - // Call deriveExtendedPublicChildKey // WIll be hardcoding the values... - deriveExtendedPublicGrandChildKey(2, 0) + // Call deriveExtendedPublicChildKey // WIll be hardcoding the values... + deriveExtendedPublicGrandChildKey(2, 0) - /** - * Derive Litecoin Legacy Address - */ + /** + * Derive Litecoin Legacy Address + */ - // Append Address Prefix - let prefix = [this.versionBytes.mainnet.prefix] - if (2 == this.versionBytes.mainnet.prefix.length) { - prefix = [this.versionBytes.mainnet.prefix[0]] - prefix.push([this.versionBytes.mainnet.prefix[1]]) - } + // Append Address Prefix + let prefix = [this.versionBytes.mainnet.prefix] + if (2 == this.versionBytes.mainnet.prefix.length) { + prefix = [this.versionBytes.mainnet.prefix[0]] + prefix.push([this.versionBytes.mainnet.prefix[1]]) + } - const k = prefix.concat(...this.grandChildPublicKeyHash) + const k = prefix.concat(...this.grandChildPublicKeyHash) - // Derive Checksum - const _addressCheckSum = new Sha256().process(new Sha256().process(new Uint8Array(k)).finish().result).finish().result - const addressCheckSum = _addressCheckSum.slice(0, 4) + // Derive Checksum + const _addressCheckSum = new Sha256().process(new Sha256().process(new Uint8Array(k)).finish().result).finish().result + const addressCheckSum = _addressCheckSum.slice(0, 4) - // Append CheckSum - const _litecoinLegacyAddress = k.concat(...addressCheckSum) + // Append CheckSum + const _litecoinLegacyAddress = k.concat(...addressCheckSum) - // Convert to Base58 - this.litecoinLegacyAddress = Base58.encode(_litecoinLegacyAddress) + // Convert to Base58 + this.litecoinLegacyAddress = Base58.encode(_litecoinLegacyAddress) - /** - * Derive TESTNET Litecoin Legacy Address - */ + /** + * Derive TESTNET Litecoin Legacy Address + */ - // Append Version Byte - const tK = [this.versionBytes.testnet.prefix].concat(...this.grandChildPublicKeyHash) + // Append Version Byte + const tK = [this.versionBytes.testnet.prefix].concat(...this.grandChildPublicKeyHash) - // Derive Checksum - const _tAddressCheckSum = new Sha256().process(new Sha256().process(new Uint8Array(tK)).finish().result).finish().result - const tAddressCheckSum = _tAddressCheckSum.slice(0, 4) + // Derive Checksum + const _tAddressCheckSum = new Sha256().process(new Sha256().process(new Uint8Array(tK)).finish().result).finish().result + const tAddressCheckSum = _tAddressCheckSum.slice(0, 4) - // Append CheckSum - const _tlitecoinLegacyAddress = tK.concat(...tAddressCheckSum) + // Append CheckSum + const _tlitecoinLegacyAddress = tK.concat(...tAddressCheckSum) - // Convert to Base58 - this._tlitecoinLegacyAddress = Base58.encode(_tlitecoinLegacyAddress) - } + // Convert to Base58 + this._tlitecoinLegacyAddress = Base58.encode(_tlitecoinLegacyAddress) + } - const derivePrivateGrandChildKey = (cI, i) => { + const derivePrivateGrandChildKey = (cI, i) => { - let ib = [] - ib.push((cI >> 24) & 0xff) - ib.push((cI >> 16) & 0xff) - ib.push((cI >> 8) & 0xff) - ib.push(cI & 0xff) + let ib = [] + ib.push((cI >> 24) & 0xff) + ib.push((cI >> 16) & 0xff) + ib.push((cI >> 8) & 0xff) + ib.push(cI & 0xff) - const s = [...this.childPublicKey].concat(ib) + const s = [...this.childPublicKey].concat(ib) - const _hmacSha512 = new jsSHA("SHA-512", "UINT8ARRAY", { numRounds: 1, hmacKey: { value: this.childChainCode, format: "UINT8ARRAY" } }) - _hmacSha512.update(new Uint8Array(s)) + const _hmacSha512 = new jsSHA("SHA-512", "UINT8ARRAY", { numRounds: 1, hmacKey: { value: this.childChainCode, format: "UINT8ARRAY" } }) + _hmacSha512.update(new Uint8Array(s)) - const IL = BigInteger.fromByteArrayUnsigned([..._hmacSha512.getHMAC('UINT8ARRAY').slice(0, 32)]) - this.grandChildChainCode = _hmacSha512.getHMAC('UINT8ARRAY').slice(32, 64) // IR according to the SPEC + const IL = BigInteger.fromByteArrayUnsigned([..._hmacSha512.getHMAC('UINT8ARRAY').slice(0, 32)]) + this.grandChildChainCode = _hmacSha512.getHMAC('UINT8ARRAY').slice(32, 64) // IR according to the SPEC - // SECP256k1 init - const epCurve = EllipticCurve.getSECCurveByName("secp256k1") + // SECP256k1 init + const epCurve = EllipticCurve.getSECCurveByName("secp256k1") - const ki = IL.add(BigInteger.fromByteArrayUnsigned(this.childPrivateKey)).mod(epCurve.getN()) // parse256(IL) + kpar (mod n) ==> ki - this.grandChildPrivateKey = ki.toByteArrayUnsigned() + const ki = IL.add(BigInteger.fromByteArrayUnsigned(this.childPrivateKey)).mod(epCurve.getN()) // parse256(IL) + kpar (mod n) ==> ki + this.grandChildPrivateKey = ki.toByteArrayUnsigned() - // Call deriveExtendedPrivateChildKey - deriveExtendedPrivateGrandChildKey(2, 0) - } + // Call deriveExtendedPrivateChildKey + deriveExtendedPrivateGrandChildKey(2, 0) + } + + const deriveExtendedPrivateGrandChildKey = (i, childIndex) => { + + // Serialization Variable + const s = [] + + // Append Version Byte + s.push(...(utils.int32ToBytes(this.versionBytes.mainnet.private))) + + // Append Depth (using the index as depth) + i = parseInt(i) + s.push(i) + + // Append Parent Fingerprint + s.push(...(this.childPublicKeyHash.slice(0, 4))) + + // Append Child Index + s.push(childIndex >>> 24) + s.push((childIndex >>> 16) & 0xff) + s.push((childIndex >>> 8) & 0xff) + s.push(childIndex & 0xff) + + // Append Chain Code + s.push(...this.grandChildChainCode) + + // Append 1 byte '0x00' (to make the key data 33 bytes, DO THIS ONLY FOR PRIVATE KEYS ) + s.push(0) + + // Append Private Key + s.push(...this.grandChildPrivateKey) + + // Generate CheckSum + const _s = new Uint8Array(s) + const _checkSum = new Sha256().process(new Sha256().process(_s).finish().result).finish().result + const checkSum = _checkSum.slice(0, 4) + + // Append CheckSum + s.push(...checkSum) // And this brings us to the end of the serialization... + + // Save to Private Key as Base58 encoded + this.xPrivateGrandChildKey = Base58.encode(s) + } + + const deriveExtendedPublicGrandChildKey = (i, childIndex) => { + + // Serialization Variable + const s = [] + + // Append Version Byte + s.push(...(utils.int32ToBytes(this.versionBytes.mainnet.public))) + + // Append Depth + i = parseInt(i) + s.push(i) + + // Append Parent Fingerprint + s.push(...(this.childPublicKeyHash.slice(0, 4))) + + // Append Child Index + s.push(childIndex >>> 24) + s.push((childIndex >>> 16) & 0xff) + s.push((childIndex >>> 8) & 0xff) + s.push(childIndex & 0xff) + + // Append Chain Code + s.push(...this.grandChildChainCode) + + // Append Public Key + s.push(...this.grandChildPublicKey) + + // Generate CheckSum + const _s = new Uint8Array(s) + const _checkSum = new Sha256().process(new Sha256().process(_s).finish().result).finish().result + const checkSum = _checkSum.slice(0, 4) + + // Append CheckSum + s.push(...checkSum) // And this brings us to the end of the serialization... + + // Save to Public Key as Base58 encoded + this.xPublicGrandChildKey = Base58.encode(s) + } + + // Hard Code value.. + let childIndex = 0 + + // Call derivePrivateChildKey //Hard code value + derivePrivateChildKey(childIndex) + + // Call derivePublicChildKey + derivePublicChildKey() - const deriveExtendedPrivateGrandChildKey = (i, childIndex) => { + // Call derivePrivateGrandChildKey // Hard Code value... + derivePrivateGrandChildKey(0, 2) - // Serialization Variable - const s = [] + // Call derivePublicGrandChildKey + derivePublicGrandChildKey() + } - // Append Version Byte - s.push(...(utils.int32ToBytes(this.versionBytes.mainnet.private))) + returnWallet() { - // Append Depth (using the index as depth) - i = parseInt(i) - s.push(i) + // Will be limiting the exported Wallet Object to just the Master keys and Legacy Addresses - // Append Parent Fingerprint - s.push(...(this.childPublicKeyHash.slice(0, 4))) + const wallet = { + derivedMasterPrivateKey: this.masterPrivateKey, + derivedMasterPublicKey: this.masterPublicKey, + _tDerivedMasterPrivateKey: this._tMasterPrivateKey, + _tDerivedmasterPublicKey: this._tmasterPublicKey, + seed58: this.seed58, + address: this.litecoinLegacyAddress, + _taddress: this._tlitecoinLegacyAddress + } - // Append Child Index - s.push(childIndex >>> 24) - s.push((childIndex >>> 16) & 0xff) - s.push((childIndex >>> 8) & 0xff) - s.push(childIndex & 0xff) - - // Append Chain Code - s.push(...this.grandChildChainCode) - - // Append 1 byte '0x00' (to make the key data 33 bytes, DO THIS ONLY FOR PRIVATE KEYS ) - s.push(0) - - // Append Private Key - s.push(...this.grandChildPrivateKey) - - // Generate CheckSum - const _s = new Uint8Array(s) - const _checkSum = new Sha256().process(new Sha256().process(_s).finish().result).finish().result - const checkSum = _checkSum.slice(0, 4) - - // Append CheckSum - s.push(...checkSum) // And this brings us to the end of the serialization... - - // Save to Private Key as Base58 encoded - this.xPrivateGrandChildKey = Base58.encode(s) - } - - const deriveExtendedPublicGrandChildKey = (i, childIndex) => { - - // Serialization Variable - const s = [] - - // Append Version Byte - s.push(...(utils.int32ToBytes(this.versionBytes.mainnet.public))) - - // Append Depth - i = parseInt(i) - s.push(i) - - // Append Parent Fingerprint - s.push(...(this.childPublicKeyHash.slice(0, 4))) - - // Append Child Index - s.push(childIndex >>> 24) - s.push((childIndex >>> 16) & 0xff) - s.push((childIndex >>> 8) & 0xff) - s.push(childIndex & 0xff) - - // Append Chain Code - s.push(...this.grandChildChainCode) - - // Append Public Key - s.push(...this.grandChildPublicKey) - - // Generate CheckSum - const _s = new Uint8Array(s) - const _checkSum = new Sha256().process(new Sha256().process(_s).finish().result).finish().result - const checkSum = _checkSum.slice(0, 4) - - // Append CheckSum - s.push(...checkSum) // And this brings us to the end of the serialization... - - // Save to Public Key as Base58 encoded - this.xPublicGrandChildKey = Base58.encode(s) - } - - - - // Hard Code value.. - let childIndex = 0 - - // Call derivePrivateChildKey //Hard code value - derivePrivateChildKey(childIndex) - - // Call derivePublicChildKey - derivePublicChildKey() - - - // Call derivePrivateGrandChildKey // Hard Code value... - derivePrivateGrandChildKey(0, 2) - - // Call derivePublicGrandChildKey - derivePublicGrandChildKey() - } - - returnWallet() { - - // Will be limiting the exported Wallet Object to just the Master keys and Legacy Addresses - - const wallet = { - derivedMasterPrivateKey: this.masterPrivateKey, - derivedMasterPublicKey: this.masterPublicKey, - _tDerivedMasterPrivateKey: this._tMasterPrivateKey, - _tDerivedmasterPublicKey: this._tmasterPublicKey, - seed58: this.seed58, - // derivedPrivateChildKey: this.xPrivateChildKey, - // derivedPublicChildKey: this.xPublicChildKey, - // derivedPrivateGrandChildKey: this.xPrivateGrandChildKey, - // derivedPublicGrandChildKey: this.xPublicGrandChildKey, - address: this.litecoinLegacyAddress, - _taddress: this._tlitecoinLegacyAddress - } - - this.wallet = wallet - return wallet - } + this.wallet = wallet + return wallet + } } diff --git a/crypto/api/bitcoin/ecbn.js b/crypto/api/bitcoin/ecbn.js index 5c08091a..311cc2ef 100644 --- a/crypto/api/bitcoin/ecbn.js +++ b/crypto/api/bitcoin/ecbn.js @@ -6,1998 +6,1988 @@ */ (function () { - - - // Copyright (c) 2005 Tom Wu - // All Rights Reserved. - // See "LICENSE" for details. - - // Basic JavaScript BN library - subset useful for RSA encryption. - - // Bits per digit - var dbits; - - // JavaScript engine analysis - var canary = 0xdeadbeefcafe; - var j_lm = (canary & 0xffffff) == 0xefcafe; - - // (public) Constructor - function BigInteger(a, b, c) { - if (a != null) - if ('number' == typeof a) this.fromNumber(a, b, c); - else if (b == null && 'string' != typeof a) this.fromString(a, 256); - else this.fromString(a, b); - } - - // return new, unset BigInteger - function nbi() { - return new BigInteger(null); - } - - // am: Compute w_j += (x*this_i), propagate carries, - // c is initial carry, returns final carry. - // c < 3*dvalue, x < 2*dvalue, this_i < dvalue - // We need to select the fastest one that works in this environment. - - // am1: use a single mult and divide to get the high bits, - // max digit bits should be 26 because - // max internal value = 2*dvalue^2-2*dvalue (< 2^53) - function am1(i, x, w, j, c, n) { - while (--n >= 0) { - var v = x * this[i++] + w[j] + c; - c = Math.floor(v / 0x4000000); - w[j++] = v & 0x3ffffff; - } - return c; - } - // am2 avoids a big mult-and-extract completely. - // Max digit bits should be <= 30 because we do bitwise ops - // on values up to 2*hdvalue^2-hdvalue-1 (< 2^31) - function am2(i, x, w, j, c, n) { - var xl = x & 0x7fff, - xh = x >> 15; - while (--n >= 0) { - var l = this[i] & 0x7fff; - var h = this[i++] >> 15; - var m = xh * l + h * xl; - l = xl * l + ((m & 0x7fff) << 15) + w[j] + (c & 0x3fffffff); - c = (l >>> 30) + (m >>> 15) + xh * h + (c >>> 30); - w[j++] = l & 0x3fffffff; - } - return c; - } - // Alternately, set max digit bits to 28 since some - // browsers slow down when dealing with 32-bit numbers. - function am3(i, x, w, j, c, n) { - var xl = x & 0x3fff, - xh = x >> 14; - while (--n >= 0) { - var l = this[i] & 0x3fff; - var h = this[i++] >> 14; - var m = xh * l + h * xl; - l = xl * l + ((m & 0x3fff) << 14) + w[j] + c; - c = (l >> 28) + (m >> 14) + xh * h; - w[j++] = l & 0xfffffff; - } - return c; - } - var inBrowser = typeof navigator !== 'undefined'; - if (inBrowser && j_lm && navigator.appName == 'Microsoft Internet Explorer') { - BigInteger.prototype.am = am2; - dbits = 30; - } else if (inBrowser && j_lm && navigator.appName != 'Netscape') { - BigInteger.prototype.am = am1; - dbits = 26; - } else { - // Mozilla/Netscape seems to prefer am3 - BigInteger.prototype.am = am3; - dbits = 28; - } - - BigInteger.prototype.DB = dbits; - BigInteger.prototype.DM = (1 << dbits) - 1; - BigInteger.prototype.DV = 1 << dbits; - - var BI_FP = 52; - BigInteger.prototype.FV = Math.pow(2, BI_FP); - BigInteger.prototype.F1 = BI_FP - dbits; - BigInteger.prototype.F2 = 2 * dbits - BI_FP; - - // Digit conversions - var BI_RM = '0123456789abcdefghijklmnopqrstuvwxyz'; - var BI_RC = new Array(); - var rr, vv; - rr = '0'.charCodeAt(0); - for (vv = 0; vv <= 9; ++vv) BI_RC[rr++] = vv; - rr = 'a'.charCodeAt(0); - for (vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv; - rr = 'A'.charCodeAt(0); - for (vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv; - - function int2char(n) { - return BI_RM.charAt(n); - } - function intAt(s, i) { - var c = BI_RC[s.charCodeAt(i)]; - return c == null ? -1 : c; - } - - // (protected) copy this to r - function bnpCopyTo(r) { - for (var i = this.t - 1; i >= 0; --i) r[i] = this[i]; - r.t = this.t; - r.s = this.s; - } - - // (protected) set from integer value x, -DV <= x < DV - function bnpFromInt(x) { - this.t = 1; - this.s = x < 0 ? -1 : 0; - if (x > 0) this[0] = x; - else if (x < -1) this[0] = x + this.DV; - else this.t = 0; - } - - // return bigint initialized to value - function nbv(i) { - var r = nbi(); - r.fromInt(i); - return r; - } - - // (protected) set from string and radix - function bnpFromString(s, b) { - // Auto-detect string notations - if (!b && s.length >= 2 && s[0] === '0') { - var isDetected = true; - switch (s[1]) { - case 'x': // Hexadecimal notation - b = 16; - break; - case 'b': // Binary notation - b = 2; - break; - case 'o': // Octal notation - b = 8; - break; - default: - isDetected = false; - } - - // Remove the notation string if any has been detected - if (isDetected) { - s = s.substr(2); - } - } - - var k; - if (b == 16) k = 4; - else if (b == 8) k = 3; - else if (b == 256) k = 8; - // byte array - else if (b == 2) k = 1; - else if (b == 32) k = 5; - else if (b == 4) k = 2; - else { - this.fromRadix(s, b); - return; - } - this.t = 0; - this.s = 0; - var i = s.length, - mi = false, - sh = 0; - while (--i >= 0) { - var x = k == 8 ? s[i] & 0xff : intAt(s, i); - if (x < 0) { - if (s.charAt(i) == '-') mi = true; - continue; - } - mi = false; - if (sh == 0) this[this.t++] = x; - else if (sh + k > this.DB) { - this[this.t - 1] |= (x & ((1 << (this.DB - sh)) - 1)) << sh; - this[this.t++] = x >> (this.DB - sh); - } else this[this.t - 1] |= x << sh; - sh += k; - if (sh >= this.DB) sh -= this.DB; - } - if (k == 8 && (s[0] & 0x80) != 0) { - this.s = -1; - if (sh > 0) this[this.t - 1] |= ((1 << (this.DB - sh)) - 1) << sh; - } - this.clamp(); - if (mi) BigInteger.ZERO.subTo(this, this); - } - - // (protected) clamp off excess high words - function bnpClamp() { - var c = this.s & this.DM; - while (this.t > 0 && this[this.t - 1] == c) --this.t; - } - - // (public) return string representation in given radix - function bnToString(b) { - if (this.s < 0) return '-' + this.negate().toString(b); - var k; - if (b == 16) k = 4; - else if (b == 8) k = 3; - else if (b == 2) k = 1; - else if (b == 32) k = 5; - else if (b == 4) k = 2; - else return this.toRadix(b); - var km = (1 << k) - 1, - d, - m = false, - r = '', - i = this.t; - var p = this.DB - ((i * this.DB) % k); - if (i-- > 0) { - if (p < this.DB && (d = this[i] >> p) > 0) { - m = true; - r = int2char(d); - } - while (i >= 0) { - if (p < k) { - d = (this[i] & ((1 << p) - 1)) << (k - p); - d |= this[--i] >> (p += this.DB - k); - } else { - d = (this[i] >> (p -= k)) & km; - if (p <= 0) { - p += this.DB; - --i; - } - } - if (d > 0) m = true; - if (m) r += int2char(d); - } - } - return m ? r : '0'; - } - - // (public) -this - function bnNegate() { - var r = nbi(); - BigInteger.ZERO.subTo(this, r); - return r; - } - - // (public) |this| - function bnAbs() { - return this.s < 0 ? this.negate() : this; - } - - // (public) return + if this > a, - if this < a, 0 if equal - function bnCompareTo(a) { - var r = this.s - a.s; - if (r != 0) return r; - var i = this.t; - r = i - a.t; - if (r != 0) return this.s < 0 ? -r : r; - while (--i >= 0) if ((r = this[i] - a[i]) != 0) return r; - return 0; - } - - // returns bit length of the integer x - function nbits(x) { - var r = 1, - t; - if ((t = x >>> 16) != 0) { - x = t; - r += 16; - } - if ((t = x >> 8) != 0) { - x = t; - r += 8; - } - if ((t = x >> 4) != 0) { - x = t; - r += 4; - } - if ((t = x >> 2) != 0) { - x = t; - r += 2; - } - if ((t = x >> 1) != 0) { - x = t; - r += 1; - } - return r; - } - - // (public) return the number of bits in "this" - function bnBitLength() { - if (this.t <= 0) return 0; - return ( - this.DB * (this.t - 1) + nbits(this[this.t - 1] ^ (this.s & this.DM)) - ); - } - - // (protected) r = this << n*DB - function bnpDLShiftTo(n, r) { - var i; - for (i = this.t - 1; i >= 0; --i) r[i + n] = this[i]; - for (i = n - 1; i >= 0; --i) r[i] = 0; - r.t = this.t + n; - r.s = this.s; - } - - // (protected) r = this >> n*DB - function bnpDRShiftTo(n, r) { - for (var i = n; i < this.t; ++i) r[i - n] = this[i]; - r.t = Math.max(this.t - n, 0); - r.s = this.s; - } - - // (protected) r = this << n - function bnpLShiftTo(n, r) { - var bs = n % this.DB; - var cbs = this.DB - bs; - var bm = (1 << cbs) - 1; - var ds = Math.floor(n / this.DB), - c = (this.s << bs) & this.DM, - i; - for (i = this.t - 1; i >= 0; --i) { - r[i + ds + 1] = (this[i] >> cbs) | c; - c = (this[i] & bm) << bs; - } - for (i = ds - 1; i >= 0; --i) r[i] = 0; - r[ds] = c; - r.t = this.t + ds + 1; - r.s = this.s; - r.clamp(); - } - - // (protected) r = this >> n - function bnpRShiftTo(n, r) { - r.s = this.s; - var ds = Math.floor(n / this.DB); - if (ds >= this.t) { - r.t = 0; - return; - } - var bs = n % this.DB; - var cbs = this.DB - bs; - var bm = (1 << bs) - 1; - r[0] = this[ds] >> bs; - for (var i = ds + 1; i < this.t; ++i) { - r[i - ds - 1] |= (this[i] & bm) << cbs; - r[i - ds] = this[i] >> bs; - } - if (bs > 0) r[this.t - ds - 1] |= (this.s & bm) << cbs; - r.t = this.t - ds; - r.clamp(); - } - - // (protected) r = this - a - function bnpSubTo(a, r) { - var i = 0, - c = 0, - m = Math.min(a.t, this.t); - while (i < m) { - c += this[i] - a[i]; - r[i++] = c & this.DM; - c >>= this.DB; - } - if (a.t < this.t) { - c -= a.s; - while (i < this.t) { - c += this[i]; - r[i++] = c & this.DM; - c >>= this.DB; - } - c += this.s; - } else { - c += this.s; - while (i < a.t) { - c -= a[i]; - r[i++] = c & this.DM; - c >>= this.DB; - } - c -= a.s; - } - r.s = c < 0 ? -1 : 0; - if (c < -1) r[i++] = this.DV + c; - else if (c > 0) r[i++] = c; - r.t = i; - r.clamp(); - } - - // (protected) r = this * a, r != this,a (HAC 14.12) - // "this" should be the larger one if appropriate. - function bnpMultiplyTo(a, r) { - var x = this.abs(), - y = a.abs(); - var i = x.t; - r.t = i + y.t; - while (--i >= 0) r[i] = 0; - for (i = 0; i < y.t; ++i) r[i + x.t] = x.am(0, y[i], r, i, 0, x.t); - r.s = 0; - r.clamp(); - if (this.s != a.s) BigInteger.ZERO.subTo(r, r); - } - - // (protected) r = this^2, r != this (HAC 14.16) - function bnpSquareTo(r) { - var x = this.abs(); - var i = (r.t = 2 * x.t); - while (--i >= 0) r[i] = 0; - for (i = 0; i < x.t - 1; ++i) { - var c = x.am(i, x[i], r, 2 * i, 0, 1); - if ( - (r[i + x.t] += x.am(i + 1, 2 * x[i], r, 2 * i + 1, c, x.t - i - 1)) >= - x.DV - ) { - r[i + x.t] -= x.DV; - r[i + x.t + 1] = 1; - } - } - if (r.t > 0) r[r.t - 1] += x.am(i, x[i], r, 2 * i, 0, 1); - r.s = 0; - r.clamp(); - } - - // (protected) divide this by m, quotient and remainder to q, r (HAC 14.20) - // r != q, this != m. q or r may be null. - function bnpDivRemTo(m, q, r) { - var pm = m.abs(); - if (pm.t <= 0) return; - var pt = this.abs(); - if (pt.t < pm.t) { - if (q != null) q.fromInt(0); - if (r != null) this.copyTo(r); - return; - } - if (r == null) r = nbi(); - var y = nbi(), - ts = this.s, - ms = m.s; - var nsh = this.DB - nbits(pm[pm.t - 1]); // normalize modulus - if (nsh > 0) { - pm.lShiftTo(nsh, y); - pt.lShiftTo(nsh, r); - } else { - pm.copyTo(y); - pt.copyTo(r); - } - var ys = y.t; - var y0 = y[ys - 1]; - if (y0 == 0) return; - var yt = y0 * (1 << this.F1) + (ys > 1 ? y[ys - 2] >> this.F2 : 0); - var d1 = this.FV / yt, - d2 = (1 << this.F1) / yt, - e = 1 << this.F2; - var i = r.t, - j = i - ys, - t = q == null ? nbi() : q; - y.dlShiftTo(j, t); - if (r.compareTo(t) >= 0) { - r[r.t++] = 1; - r.subTo(t, r); - } - BigInteger.ONE.dlShiftTo(ys, t); - t.subTo(y, y); // "negative" y so we can replace sub with am later - while (y.t < ys) y[y.t++] = 0; - while (--j >= 0) { - // Estimate quotient digit - var qd = - r[--i] == y0 ? this.DM : Math.floor(r[i] * d1 + (r[i - 1] + e) * d2); - if ((r[i] += y.am(0, qd, r, j, 0, ys)) < qd) { - // Try it out - y.dlShiftTo(j, t); - r.subTo(t, r); - while (r[i] < --qd) r.subTo(t, r); - } - } - if (q != null) { - r.drShiftTo(ys, q); - if (ts != ms) BigInteger.ZERO.subTo(q, q); - } - r.t = ys; - r.clamp(); - if (nsh > 0) r.rShiftTo(nsh, r); // Denormalize remainder - if (ts < 0) BigInteger.ZERO.subTo(r, r); - } - - // (public) this mod a - function bnMod(a) { - var r = nbi(); - this.abs().divRemTo(a, null, r); - if (this.s < 0 && r.compareTo(BigInteger.ZERO) > 0) a.subTo(r, r); - return r; - } - - // Modular reduction using "classic" algorithm - function Classic(m) { - this.m = m; - } - function cConvert(x) { - if (x.s < 0 || x.compareTo(this.m) >= 0) return x.mod(this.m); - else return x; - } - function cRevert(x) { - return x; - } - function cReduce(x) { - x.divRemTo(this.m, null, x); - } - function cMulTo(x, y, r) { - x.multiplyTo(y, r); - this.reduce(r); - } - function cSqrTo(x, r) { - x.squareTo(r); - this.reduce(r); - } - - Classic.prototype.convert = cConvert; - Classic.prototype.revert = cRevert; - Classic.prototype.reduce = cReduce; - Classic.prototype.mulTo = cMulTo; - Classic.prototype.sqrTo = cSqrTo; - - // (protected) return "-1/this % 2^DB"; useful for Mont. reduction - // justification: - // xy == 1 (mod m) - // xy = 1+km - // xy(2-xy) = (1+km)(1-km) - // x[y(2-xy)] = 1-k^2m^2 - // x[y(2-xy)] == 1 (mod m^2) - // if y is 1/x mod m, then y(2-xy) is 1/x mod m^2 - // should reduce x and y(2-xy) by m^2 at each step to keep size bounded. - // JS multiply "overflows" differently from C/C++, so care is needed here. - function bnpInvDigit() { - if (this.t < 1) return 0; - var x = this[0]; - if ((x & 1) == 0) return 0; - var y = x & 3; // y == 1/x mod 2^2 - y = (y * (2 - (x & 0xf) * y)) & 0xf; // y == 1/x mod 2^4 - y = (y * (2 - (x & 0xff) * y)) & 0xff; // y == 1/x mod 2^8 - y = (y * (2 - (((x & 0xffff) * y) & 0xffff))) & 0xffff; // y == 1/x mod 2^16 - // last step - calculate inverse mod DV directly; - // assumes 16 < DB <= 32 and assumes ability to handle 48-bit ints - y = (y * (2 - ((x * y) % this.DV))) % this.DV; // y == 1/x mod 2^dbits - // we really want the negative inverse, and -DV < y < DV - return y > 0 ? this.DV - y : -y; - } - - // Montgomery reduction - function Montgomery(m) { - this.m = m; - this.mp = m.invDigit(); - this.mpl = this.mp & 0x7fff; - this.mph = this.mp >> 15; - this.um = (1 << (m.DB - 15)) - 1; - this.mt2 = 2 * m.t; - } - - // xR mod m - function montConvert(x) { - var r = nbi(); - x.abs().dlShiftTo(this.m.t, r); - r.divRemTo(this.m, null, r); - if (x.s < 0 && r.compareTo(BigInteger.ZERO) > 0) this.m.subTo(r, r); - return r; - } - - // x/R mod m - function montRevert(x) { - var r = nbi(); - x.copyTo(r); - this.reduce(r); - return r; - } - - // x = x/R mod m (HAC 14.32) - function montReduce(x) { - while ( - x.t <= this.mt2 // pad x so am has enough room later - ) - x[x.t++] = 0; - for (var i = 0; i < this.m.t; ++i) { - // faster way of calculating u0 = x[i]*mp mod DV - var j = x[i] & 0x7fff; - var u0 = - (j * this.mpl + - (((j * this.mph + (x[i] >> 15) * this.mpl) & this.um) << 15)) & - x.DM; - // use am to combine the multiply-shift-add into one call - j = i + this.m.t; - x[j] += this.m.am(0, u0, x, i, 0, this.m.t); - // propagate carry - while (x[j] >= x.DV) { - x[j] -= x.DV; - x[++j]++; - } - } - x.clamp(); - x.drShiftTo(this.m.t, x); - if (x.compareTo(this.m) >= 0) x.subTo(this.m, x); - } - - // r = "x^2/R mod m"; x != r - function montSqrTo(x, r) { - x.squareTo(r); - this.reduce(r); - } - - // r = "xy/R mod m"; x,y != r - function montMulTo(x, y, r) { - x.multiplyTo(y, r); - this.reduce(r); - } - - Montgomery.prototype.convert = montConvert; - Montgomery.prototype.revert = montRevert; - Montgomery.prototype.reduce = montReduce; - Montgomery.prototype.mulTo = montMulTo; - Montgomery.prototype.sqrTo = montSqrTo; - - // (protected) true iff this is even - function bnpIsEven() { - return (this.t > 0 ? this[0] & 1 : this.s) == 0; - } - - // (protected) this^e, e < 2^32, doing sqr and mul with "r" (HAC 14.79) - function bnpExp(e, z) { - if (e > 0xffffffff || e < 1) return BigInteger.ONE; - var r = nbi(), - r2 = nbi(), - g = z.convert(this), - i = nbits(e) - 1; - g.copyTo(r); - while (--i >= 0) { - z.sqrTo(r, r2); - if ((e & (1 << i)) > 0) z.mulTo(r2, g, r); - else { - var t = r; - r = r2; - r2 = t; - } - } - return z.revert(r); - } - - // (public) this^e % m, 0 <= e < 2^32 - function bnModPowInt(e, m) { - var z; - if (e < 256 || m.isEven()) z = new Classic(m); - else z = new Montgomery(m); - return this.exp(e, z); - } - - // protected - BigInteger.prototype.copyTo = bnpCopyTo; - BigInteger.prototype.fromInt = bnpFromInt; - BigInteger.prototype.fromString = bnpFromString; - BigInteger.prototype.clamp = bnpClamp; - BigInteger.prototype.dlShiftTo = bnpDLShiftTo; - BigInteger.prototype.drShiftTo = bnpDRShiftTo; - BigInteger.prototype.lShiftTo = bnpLShiftTo; - BigInteger.prototype.rShiftTo = bnpRShiftTo; - BigInteger.prototype.subTo = bnpSubTo; - BigInteger.prototype.multiplyTo = bnpMultiplyTo; - BigInteger.prototype.squareTo = bnpSquareTo; - BigInteger.prototype.divRemTo = bnpDivRemTo; - BigInteger.prototype.invDigit = bnpInvDigit; - BigInteger.prototype.isEven = bnpIsEven; - BigInteger.prototype.exp = bnpExp; - - // public - BigInteger.prototype.toString = bnToString; - BigInteger.prototype.negate = bnNegate; - BigInteger.prototype.abs = bnAbs; - BigInteger.prototype.compareTo = bnCompareTo; - BigInteger.prototype.bitLength = bnBitLength; - BigInteger.prototype.mod = bnMod; - BigInteger.prototype.modPowInt = bnModPowInt; - - // "constants" - BigInteger.ZERO = nbv(0); - BigInteger.ONE = nbv(1); - BigInteger.valueOf = nbv; - - // Copyright (c) 2005-2009 Tom Wu - // All Rights Reserved. - // See "LICENSE" for details. - - // Extended JavaScript BN functions, required for RSA private ops. - - // Version 1.1: new BigInteger("0", 10) returns "proper" zero - // Version 1.2: square() API, isProbablePrime fix - - // (public) - function bnClone() { - var r = nbi(); - this.copyTo(r); - return r; - } - - // (public) return value as integer - function bnIntValue() { - if (this.s < 0) { - if (this.t == 1) return this[0] - this.DV; - else if (this.t == 0) return -1; - } else if (this.t == 1) return this[0]; - else if (this.t == 0) return 0; - // assumes 16 < DB < 32 - return ((this[1] & ((1 << (32 - this.DB)) - 1)) << this.DB) | this[0]; - } - - // (public) return value as byte - function bnByteValue() { - return this.t == 0 ? this.s : (this[0] << 24) >> 24; - } - - // (public) return value as short (assumes DB>=16) - function bnShortValue() { - return this.t == 0 ? this.s : (this[0] << 16) >> 16; - } - - // (protected) return x s.t. r^x < DV - function bnpChunkSize(r) { - return Math.floor((Math.LN2 * this.DB) / Math.log(r)); - } - - // (public) 0 if this == 0, 1 if this > 0 - function bnSigNum() { - if (this.s < 0) return -1; - else if (this.t <= 0 || (this.t == 1 && this[0] <= 0)) return 0; - else return 1; - } - - // (protected) convert to radix string - function bnpToRadix(b) { - if (b == null) b = 10; - if (this.signum() == 0 || b < 2 || b > 36) return '0'; - var cs = this.chunkSize(b); - var a = Math.pow(b, cs); - var d = nbv(a), - y = nbi(), - z = nbi(), - r = ''; - this.divRemTo(d, y, z); - while (y.signum() > 0) { - r = (a + z.intValue()).toString(b).substr(1) + r; - y.divRemTo(d, y, z); - } - return z.intValue().toString(b) + r; - } - - // (protected) convert from radix string - function bnpFromRadix(s, b) { - this.fromInt(0); - if (b == null) b = 10; - var cs = this.chunkSize(b); - var d = Math.pow(b, cs), - mi = false, - j = 0, - w = 0; - for (var i = 0; i < s.length; ++i) { - var x = intAt(s, i); - if (x < 0) { - if (s.charAt(i) == '-' && this.signum() == 0) mi = true; - continue; - } - w = b * w + x; - if (++j >= cs) { - this.dMultiply(d); - this.dAddOffset(w, 0); - j = 0; - w = 0; - } - } - if (j > 0) { - this.dMultiply(Math.pow(b, j)); - this.dAddOffset(w, 0); - } - if (mi) BigInteger.ZERO.subTo(this, this); - } - - // (protected) alternate constructor - function bnpFromNumber(a, b, c) { - if ('number' == typeof b) { - // new BigInteger(int,int,RNG) - if (a < 2) this.fromInt(1); - else { - this.fromNumber(a, c); - if (!this.testBit(a - 1)) - // force MSB set - this.bitwiseTo(BigInteger.ONE.shiftLeft(a - 1), op_or, this); - if (this.isEven()) this.dAddOffset(1, 0); // force odd - while (!this.isProbablePrime(b)) { - this.dAddOffset(2, 0); - if (this.bitLength() > a) - this.subTo(BigInteger.ONE.shiftLeft(a - 1), this); - } - } - } else { - // new BigInteger(int,RNG) - var x = new Array(), - t = a & 7; - x.length = (a >> 3) + 1; - b.nextBytes(x); - if (t > 0) x[0] &= (1 << t) - 1; - else x[0] = 0; - this.fromString(x, 256); - } - } - - // (public) convert to bigendian byte array - function bnToByteArray() { - var i = this.t, - r = new Array(); - r[0] = this.s; - var p = this.DB - ((i * this.DB) % 8), - d, - k = 0; - if (i-- > 0) { - if (p < this.DB && (d = this[i] >> p) != (this.s & this.DM) >> p) - r[k++] = d | (this.s << (this.DB - p)); - while (i >= 0) { - if (p < 8) { - d = (this[i] & ((1 << p) - 1)) << (8 - p); - d |= this[--i] >> (p += this.DB - 8); - } else { - d = (this[i] >> (p -= 8)) & 0xff; - if (p <= 0) { - p += this.DB; - --i; - } - } - if ((d & 0x80) != 0) d |= -256; - if (k == 0 && (this.s & 0x80) != (d & 0x80)) ++k; - if (k > 0 || d != this.s) r[k++] = d; - } - } - return r; - } - - function bnEquals(a) { - return this.compareTo(a) == 0; - } - function bnMin(a) { - return this.compareTo(a) < 0 ? this : a; - } - function bnMax(a) { - return this.compareTo(a) > 0 ? this : a; - } - - // (protected) r = this op a (bitwise) - function bnpBitwiseTo(a, op, r) { - var i, - f, - m = Math.min(a.t, this.t); - for (i = 0; i < m; ++i) r[i] = op(this[i], a[i]); - if (a.t < this.t) { - f = a.s & this.DM; - for (i = m; i < this.t; ++i) r[i] = op(this[i], f); - r.t = this.t; - } else { - f = this.s & this.DM; - for (i = m; i < a.t; ++i) r[i] = op(f, a[i]); - r.t = a.t; - } - r.s = op(this.s, a.s); - r.clamp(); - } - - // (public) this & a - function op_and(x, y) { - return x & y; - } - function bnAnd(a) { - var r = nbi(); - this.bitwiseTo(a, op_and, r); - return r; - } - - // (public) this | a - function op_or(x, y) { - return x | y; - } - function bnOr(a) { - var r = nbi(); - this.bitwiseTo(a, op_or, r); - return r; - } - - // (public) this ^ a - function op_xor(x, y) { - return x ^ y; - } - function bnXor(a) { - var r = nbi(); - this.bitwiseTo(a, op_xor, r); - return r; - } - - // (public) this & ~a - function op_andnot(x, y) { - return x & ~y; - } - function bnAndNot(a) { - var r = nbi(); - this.bitwiseTo(a, op_andnot, r); - return r; - } - - // (public) ~this - function bnNot() { - var r = nbi(); - for (var i = 0; i < this.t; ++i) r[i] = this.DM & ~this[i]; - r.t = this.t; - r.s = ~this.s; - return r; - } - - // (public) this << n - function bnShiftLeft(n) { - var r = nbi(); - if (n < 0) this.rShiftTo(-n, r); - else this.lShiftTo(n, r); - return r; - } - - // (public) this >> n - function bnShiftRight(n) { - var r = nbi(); - if (n < 0) this.lShiftTo(-n, r); - else this.rShiftTo(n, r); - return r; - } - - // return index of lowest 1-bit in x, x < 2^31 - function lbit(x) { - if (x == 0) return -1; - var r = 0; - if ((x & 0xffff) == 0) { - x >>= 16; - r += 16; - } - if ((x & 0xff) == 0) { - x >>= 8; - r += 8; - } - if ((x & 0xf) == 0) { - x >>= 4; - r += 4; - } - if ((x & 3) == 0) { - x >>= 2; - r += 2; - } - if ((x & 1) == 0) ++r; - return r; - } - - // (public) returns index of lowest 1-bit (or -1 if none) - function bnGetLowestSetBit() { - for (var i = 0; i < this.t; ++i) - if (this[i] != 0) return i * this.DB + lbit(this[i]); - if (this.s < 0) return this.t * this.DB; - return -1; - } - - // return number of 1 bits in x - function cbit(x) { - var r = 0; - while (x != 0) { - x &= x - 1; - ++r; - } - return r; - } - - // (public) return number of set bits - function bnBitCount() { - var r = 0, - x = this.s & this.DM; - for (var i = 0; i < this.t; ++i) r += cbit(this[i] ^ x); - return r; - } - - // (public) true iff nth bit is set - function bnTestBit(n) { - var j = Math.floor(n / this.DB); - if (j >= this.t) return this.s != 0; - return (this[j] & (1 << n % this.DB)) != 0; - } - - // (protected) this op (1<>= this.DB; - } - if (a.t < this.t) { - c += a.s; - while (i < this.t) { - c += this[i]; - r[i++] = c & this.DM; - c >>= this.DB; - } - c += this.s; - } else { - c += this.s; - while (i < a.t) { - c += a[i]; - r[i++] = c & this.DM; - c >>= this.DB; - } - c += a.s; - } - r.s = c < 0 ? -1 : 0; - if (c > 0) r[i++] = c; - else if (c < -1) r[i++] = this.DV + c; - r.t = i; - r.clamp(); - } - - // (public) this + a - function bnAdd(a) { - var r = nbi(); - this.addTo(a, r); - return r; - } - - // (public) this - a - function bnSubtract(a) { - var r = nbi(); - this.subTo(a, r); - return r; - } - - // (public) this * a - function bnMultiply(a) { - var r = nbi(); - this.multiplyTo(a, r); - return r; - } - - // (public) this^2 - function bnSquare() { - var r = nbi(); - this.squareTo(r); - return r; - } - - // (public) this / a - function bnDivide(a) { - var r = nbi(); - this.divRemTo(a, r, null); - return r; - } - - // (public) this % a - function bnRemainder(a) { - var r = nbi(); - this.divRemTo(a, null, r); - return r; - } - - // (public) [this/a,this%a] - function bnDivideAndRemainder(a) { - var q = nbi(), - r = nbi(); - this.divRemTo(a, q, r); - return new Array(q, r); - } - - // (protected) this *= n, this >= 0, 1 < n < DV - function bnpDMultiply(n) { - this[this.t] = this.am(0, n - 1, this, 0, 0, this.t); - ++this.t; - this.clamp(); - } - - // (protected) this += n << w words, this >= 0 - function bnpDAddOffset(n, w) { - if (n == 0) return; - while (this.t <= w) this[this.t++] = 0; - this[w] += n; - while (this[w] >= this.DV) { - this[w] -= this.DV; - if (++w >= this.t) this[this.t++] = 0; - ++this[w]; - } - } - - // A "null" reducer - function NullExp() { } - function nNop(x) { - return x; - } - function nMulTo(x, y, r) { - x.multiplyTo(y, r); - } - function nSqrTo(x, r) { - x.squareTo(r); - } - - NullExp.prototype.convert = nNop; - NullExp.prototype.revert = nNop; - NullExp.prototype.mulTo = nMulTo; - NullExp.prototype.sqrTo = nSqrTo; - - // (public) this^e - function bnPow(e) { - return this.exp(e, new NullExp()); - } - - // (protected) r = lower n words of "this * a", a.t <= n - // "this" should be the larger one if appropriate. - function bnpMultiplyLowerTo(a, n, r) { - var i = Math.min(this.t + a.t, n); - r.s = 0; // assumes a,this >= 0 - r.t = i; - while (i > 0) r[--i] = 0; - var j; - for (j = r.t - this.t; i < j; ++i) - r[i + this.t] = this.am(0, a[i], r, i, 0, this.t); - for (j = Math.min(a.t, n); i < j; ++i) this.am(0, a[i], r, i, 0, n - i); - r.clamp(); - } - - // (protected) r = "this * a" without lower n words, n > 0 - // "this" should be the larger one if appropriate. - function bnpMultiplyUpperTo(a, n, r) { - --n; - var i = (r.t = this.t + a.t - n); - r.s = 0; // assumes a,this >= 0 - while (--i >= 0) r[i] = 0; - for (i = Math.max(n - this.t, 0); i < a.t; ++i) - r[this.t + i - n] = this.am(n - i, a[i], r, 0, 0, this.t + i - n); - r.clamp(); - r.drShiftTo(1, r); - } - - // Barrett modular reduction - function Barrett(m) { - // setup Barrett - this.r2 = nbi(); - this.q3 = nbi(); - BigInteger.ONE.dlShiftTo(2 * m.t, this.r2); - this.mu = this.r2.divide(m); - this.m = m; - } - - function barrettConvert(x) { - if (x.s < 0 || x.t > 2 * this.m.t) return x.mod(this.m); - else if (x.compareTo(this.m) < 0) return x; - else { - var r = nbi(); - x.copyTo(r); - this.reduce(r); - return r; - } - } - - function barrettRevert(x) { - return x; - } - - // x = x mod m (HAC 14.42) - function barrettReduce(x) { - x.drShiftTo(this.m.t - 1, this.r2); - if (x.t > this.m.t + 1) { - x.t = this.m.t + 1; - x.clamp(); - } - this.mu.multiplyUpperTo(this.r2, this.m.t + 1, this.q3); - this.m.multiplyLowerTo(this.q3, this.m.t + 1, this.r2); - while (x.compareTo(this.r2) < 0) x.dAddOffset(1, this.m.t + 1); - x.subTo(this.r2, x); - while (x.compareTo(this.m) >= 0) x.subTo(this.m, x); - } - - // r = x^2 mod m; x != r - function barrettSqrTo(x, r) { - x.squareTo(r); - this.reduce(r); - } - - // r = x*y mod m; x,y != r - function barrettMulTo(x, y, r) { - x.multiplyTo(y, r); - this.reduce(r); - } - - Barrett.prototype.convert = barrettConvert; - Barrett.prototype.revert = barrettRevert; - Barrett.prototype.reduce = barrettReduce; - Barrett.prototype.mulTo = barrettMulTo; - Barrett.prototype.sqrTo = barrettSqrTo; - - // (public) this^e % m (HAC 14.85) - function bnModPow(e, m) { - var i = e.bitLength(), - k, - r = nbv(1), - z; - if (i <= 0) return r; - else if (i < 18) k = 1; - else if (i < 48) k = 3; - else if (i < 144) k = 4; - else if (i < 768) k = 5; - else k = 6; - if (i < 8) z = new Classic(m); - else if (m.isEven()) z = new Barrett(m); - else z = new Montgomery(m); - - // precomputation - var g = new Array(), - n = 3, - k1 = k - 1, - km = (1 << k) - 1; - g[1] = z.convert(this); - if (k > 1) { - var g2 = nbi(); - z.sqrTo(g[1], g2); - while (n <= km) { - g[n] = nbi(); - z.mulTo(g2, g[n - 2], g[n]); - n += 2; - } - } - - var j = e.t - 1, - w, - is1 = true, - r2 = nbi(), - t; - i = nbits(e[j]) - 1; - while (j >= 0) { - if (i >= k1) w = (e[j] >> (i - k1)) & km; - else { - w = (e[j] & ((1 << (i + 1)) - 1)) << (k1 - i); - if (j > 0) w |= e[j - 1] >> (this.DB + i - k1); - } - - n = k; - while ((w & 1) == 0) { - w >>= 1; - --n; - } - if ((i -= n) < 0) { - i += this.DB; - --j; - } - if (is1) { - // ret == 1, don't bother squaring or multiplying it - g[w].copyTo(r); - is1 = false; - } else { - while (n > 1) { - z.sqrTo(r, r2); - z.sqrTo(r2, r); - n -= 2; - } - if (n > 0) z.sqrTo(r, r2); - else { - t = r; - r = r2; - r2 = t; - } - z.mulTo(r2, g[w], r); - } - - while (j >= 0 && (e[j] & (1 << i)) == 0) { - z.sqrTo(r, r2); - t = r; - r = r2; - r2 = t; - if (--i < 0) { - i = this.DB - 1; - --j; - } - } - } - return z.revert(r); - } - - // (public) gcd(this,a) (HAC 14.54) - function bnGCD(a) { - var x = this.s < 0 ? this.negate() : this.clone(); - var y = a.s < 0 ? a.negate() : a.clone(); - if (x.compareTo(y) < 0) { - var t = x; - x = y; - y = t; - } - var i = x.getLowestSetBit(), - g = y.getLowestSetBit(); - if (g < 0) return x; - if (i < g) g = i; - if (g > 0) { - x.rShiftTo(g, x); - y.rShiftTo(g, y); - } - while (x.signum() > 0) { - if ((i = x.getLowestSetBit()) > 0) x.rShiftTo(i, x); - if ((i = y.getLowestSetBit()) > 0) y.rShiftTo(i, y); - if (x.compareTo(y) >= 0) { - x.subTo(y, x); - x.rShiftTo(1, x); - } else { - y.subTo(x, y); - y.rShiftTo(1, y); - } - } - if (g > 0) y.lShiftTo(g, y); - return y; - } - - // (protected) this % n, n < 2^26 - function bnpModInt(n) { - if (n <= 0) return 0; - var d = this.DV % n, - r = this.s < 0 ? n - 1 : 0; - if (this.t > 0) - if (d == 0) r = this[0] % n; - else for (var i = this.t - 1; i >= 0; --i) r = (d * r + this[i]) % n; - return r; - } - - // (public) 1/this % m (HAC 14.61) - function bnModInverse(m) { - var ac = m.isEven(); - if ((this.isEven() && ac) || m.signum() == 0) return BigInteger.ZERO; - var u = m.clone(), - v = this.clone(); - var a = nbv(1), - b = nbv(0), - c = nbv(0), - d = nbv(1); - while (u.signum() != 0) { - while (u.isEven()) { - u.rShiftTo(1, u); - if (ac) { - if (!a.isEven() || !b.isEven()) { - a.addTo(this, a); - b.subTo(m, b); - } - a.rShiftTo(1, a); - } else if (!b.isEven()) b.subTo(m, b); - b.rShiftTo(1, b); - } - while (v.isEven()) { - v.rShiftTo(1, v); - if (ac) { - if (!c.isEven() || !d.isEven()) { - c.addTo(this, c); - d.subTo(m, d); - } - c.rShiftTo(1, c); - } else if (!d.isEven()) d.subTo(m, d); - d.rShiftTo(1, d); - } - if (u.compareTo(v) >= 0) { - u.subTo(v, u); - if (ac) a.subTo(c, a); - b.subTo(d, b); - } else { - v.subTo(u, v); - if (ac) c.subTo(a, c); - d.subTo(b, d); - } - } - if (v.compareTo(BigInteger.ONE) != 0) return BigInteger.ZERO; - if (d.compareTo(m) >= 0) return d.subtract(m); - if (d.signum() < 0) d.addTo(m, d); - else return d; - if (d.signum() < 0) return d.add(m); - else return d; - } - - var lowprimes = [ - 2, - 3, - 5, - 7, - 11, - 13, - 17, - 19, - 23, - 29, - 31, - 37, - 41, - 43, - 47, - 53, - 59, - 61, - 67, - 71, - 73, - 79, - 83, - 89, - 97, - 101, - 103, - 107, - 109, - 113, - 127, - 131, - 137, - 139, - 149, - 151, - 157, - 163, - 167, - 173, - 179, - 181, - 191, - 193, - 197, - 199, - 211, - 223, - 227, - 229, - 233, - 239, - 241, - 251, - 257, - 263, - 269, - 271, - 277, - 281, - 283, - 293, - 307, - 311, - 313, - 317, - 331, - 337, - 347, - 349, - 353, - 359, - 367, - 373, - 379, - 383, - 389, - 397, - 401, - 409, - 419, - 421, - 431, - 433, - 439, - 443, - 449, - 457, - 461, - 463, - 467, - 479, - 487, - 491, - 499, - 503, - 509, - 521, - 523, - 541, - 547, - 557, - 563, - 569, - 571, - 577, - 587, - 593, - 599, - 601, - 607, - 613, - 617, - 619, - 631, - 641, - 643, - 647, - 653, - 659, - 661, - 673, - 677, - 683, - 691, - 701, - 709, - 719, - 727, - 733, - 739, - 743, - 751, - 757, - 761, - 769, - 773, - 787, - 797, - 809, - 811, - 821, - 823, - 827, - 829, - 839, - 853, - 857, - 859, - 863, - 877, - 881, - 883, - 887, - 907, - 911, - 919, - 929, - 937, - 941, - 947, - 953, - 967, - 971, - 977, - 983, - 991, - 997, - ]; - var lplim = (1 << 26) / lowprimes[lowprimes.length - 1]; - - // (public) test primality with certainty >= 1-.5^t - function bnIsProbablePrime(t) { - var i, - x = this.abs(); - if (x.t == 1 && x[0] <= lowprimes[lowprimes.length - 1]) { - for (i = 0; i < lowprimes.length; ++i) - if (x[0] == lowprimes[i]) return true; - return false; - } - if (x.isEven()) return false; - i = 1; - while (i < lowprimes.length) { - var m = lowprimes[i], - j = i + 1; - while (j < lowprimes.length && m < lplim) m *= lowprimes[j++]; - m = x.modInt(m); - while (i < j) if (m % lowprimes[i++] == 0) return false; - } - return x.millerRabin(t); - } - - // (protected) true if probably prime (HAC 4.24, Miller-Rabin) - function bnpMillerRabin(t) { - var n1 = this.subtract(BigInteger.ONE); - var k = n1.getLowestSetBit(); - if (k <= 0) return false; - var r = n1.shiftRight(k); - t = (t + 1) >> 1; - if (t > lowprimes.length) t = lowprimes.length; - var a = nbi(); - for (var i = 0; i < t; ++i) { - //Pick bases at random, instead of starting at 2 - a.fromInt(lowprimes[Math.floor(Math.random() * lowprimes.length)]); - var y = a.modPow(r, this); - if (y.compareTo(BigInteger.ONE) != 0 && y.compareTo(n1) != 0) { - var j = 1; - while (j++ < k && y.compareTo(n1) != 0) { - y = y.modPowInt(2, this); - if (y.compareTo(BigInteger.ONE) == 0) return false; - } - if (y.compareTo(n1) != 0) return false; - } - } - return true; - } - - // protected - BigInteger.prototype.chunkSize = bnpChunkSize; - BigInteger.prototype.toRadix = bnpToRadix; - BigInteger.prototype.fromRadix = bnpFromRadix; - BigInteger.prototype.fromNumber = bnpFromNumber; - BigInteger.prototype.bitwiseTo = bnpBitwiseTo; - BigInteger.prototype.changeBit = bnpChangeBit; - BigInteger.prototype.addTo = bnpAddTo; - BigInteger.prototype.dMultiply = bnpDMultiply; - BigInteger.prototype.dAddOffset = bnpDAddOffset; - BigInteger.prototype.multiplyLowerTo = bnpMultiplyLowerTo; - BigInteger.prototype.multiplyUpperTo = bnpMultiplyUpperTo; - BigInteger.prototype.modInt = bnpModInt; - BigInteger.prototype.millerRabin = bnpMillerRabin; - - // public - BigInteger.prototype.clone = bnClone; - BigInteger.prototype.intValue = bnIntValue; - BigInteger.prototype.byteValue = bnByteValue; - BigInteger.prototype.shortValue = bnShortValue; - BigInteger.prototype.signum = bnSigNum; - BigInteger.prototype.toByteArray = bnToByteArray; - BigInteger.prototype.equals = bnEquals; - BigInteger.prototype.min = bnMin; - BigInteger.prototype.max = bnMax; - BigInteger.prototype.and = bnAnd; - BigInteger.prototype.or = bnOr; - BigInteger.prototype.xor = bnXor; - BigInteger.prototype.andNot = bnAndNot; - BigInteger.prototype.not = bnNot; - BigInteger.prototype.shiftLeft = bnShiftLeft; - BigInteger.prototype.shiftRight = bnShiftRight; - BigInteger.prototype.getLowestSetBit = bnGetLowestSetBit; - BigInteger.prototype.bitCount = bnBitCount; - BigInteger.prototype.testBit = bnTestBit; - BigInteger.prototype.setBit = bnSetBit; - BigInteger.prototype.clearBit = bnClearBit; - BigInteger.prototype.flipBit = bnFlipBit; - BigInteger.prototype.add = bnAdd; - BigInteger.prototype.subtract = bnSubtract; - BigInteger.prototype.multiply = bnMultiply; - BigInteger.prototype.divide = bnDivide; - BigInteger.prototype.remainder = bnRemainder; - BigInteger.prototype.divideAndRemainder = bnDivideAndRemainder; - BigInteger.prototype.modPow = bnModPow; - BigInteger.prototype.modInverse = bnModInverse; - BigInteger.prototype.pow = bnPow; - BigInteger.prototype.gcd = bnGCD; - BigInteger.prototype.isProbablePrime = bnIsProbablePrime; - - // JSBN-specific extension - BigInteger.prototype.square = bnSquare; - - // Expose the Barrett function - BigInteger.prototype.Barrett = Barrett; - - // BigInteger interfaces not implemented in jsbn: - - // BigInteger(int signum, byte[] magnitude) - // double doubleValue() - // float floatValue() - // int hashCode() - // long longValue() - // static BigInteger valueOf(long val) - - // Imported from bitcoinjs-lib - - /** - * Turns a byte array into a big integer. - * - * This function will interpret a byte array as a big integer in big - * endian notation and ignore leading zeros. - */ - - BigInteger.fromByteArrayUnsigned = function (ba) { - - if (!ba.length) { - return new BigInteger.valueOf(0); - } else if (ba[0] & 0x80) { - // Prepend a zero so the BigInteger class doesn't mistake this - // for a negative integer. - return new BigInteger([0].concat(ba)); - } else { - return new BigInteger(ba); - } - }; - - /** - * Parse a signed big integer byte representation. - * - * For details on the format please see BigInteger.toByteArraySigned. - */ - - BigInteger.fromByteArraySigned = function (ba) { - // Check for negative value - if (ba[0] & 0x80) { - // Remove sign bit - ba[0] &= 0x7f; - - return BigInteger.fromByteArrayUnsigned(ba).negate(); - } else { - return BigInteger.fromByteArrayUnsigned(ba); - } - }; - - /** - * Returns a byte array representation of the big integer. - * - * This returns the absolute of the contained value in big endian - * form. A value of zero results in an empty array. - */ - - BigInteger.prototype.toByteArrayUnsigned = function () { - var ba = this.abs().toByteArray(); - - // Empty array, nothing to do - if (!ba.length) { - return ba; - } - - // remove leading 0 - if (ba[0] === 0) { - ba = ba.slice(1); - } - - // all values must be positive - for (var i = 0; i < ba.length; ++i) { - ba[i] = (ba[i] < 0) ? ba[i] + 256 : ba[i]; - } - - return ba; - }; - - /* - * Converts big integer to signed byte representation. - * - * The format for this value uses the most significant bit as a sign - * bit. If the most significant bit is already occupied by the - * absolute value, an extra byte is prepended and the sign bit is set - * there. - * - * Examples: - * - * 0 => 0x00 - * 1 => 0x01 - * -1 => 0x81 - * 127 => 0x7f - * -127 => 0xff - * 128 => 0x0080 - * -128 => 0x8080 - * 255 => 0x00ff - * -255 => 0x80ff - * 16300 => 0x3fac - * -16300 => 0xbfac - * 62300 => 0x00f35c - * -62300 => 0x80f35c - */ - - BigInteger.prototype.toByteArraySigned = function () { - var val = this.toByteArrayUnsigned(); - var neg = this.s < 0; - - // if the first bit is set, we always unshift - // either unshift 0x80 or 0x00 - if (val[0] & 0x80) { - val.unshift((neg) ? 0x80 : 0x00); - } - // if the first bit isn't set, set it if negative - else if (neg) { - val[0] |= 0x80; - } - - return val; - }; - - // Random number generator - requires a PRNG backend, e.g. prng4.js - - // For best results, put code like - // - // in your main HTML document. - - var rng_state; - var rng_pool; - var rng_pptr; - - // Mix in a 32-bit integer into the pool - function rng_seed_int(x) { - rng_pool[rng_pptr++] ^= x & 255; - rng_pool[rng_pptr++] ^= (x >> 8) & 255; - rng_pool[rng_pptr++] ^= (x >> 16) & 255; - rng_pool[rng_pptr++] ^= (x >> 24) & 255; - if (rng_pptr >= rng_psize) rng_pptr -= rng_psize; - } - - // Mix in the current time (w/milliseconds) into the pool - function rng_seed_time() { - rng_seed_int(new Date().getTime()); - } - - // Initialize the pool with junk if needed. - if (rng_pool == null) { - rng_pool = new Array(); - rng_pptr = 0; - var t; - if (typeof window !== 'undefined' && window.crypto) { - if (window.crypto.getRandomValues) { - // Use webcrypto if available - var ua = new Uint8Array(32); - window.crypto.getRandomValues(ua); - for (t = 0; t < 32; ++t) rng_pool[rng_pptr++] = ua[t]; - } else if ( - navigator.appName == 'Netscape' && - navigator.appVersion < '5' - ) { - // Extract entropy (256 bits) from NS4 RNG if available - var z = window.crypto.random(32); - for (t = 0; t < z.length; ++t) - rng_pool[rng_pptr++] = z.charCodeAt(t) & 255; - } - } - while (rng_pptr < rng_psize) { - // extract some randomness from Math.random() - t = Math.floor(65536 * Math.random()); - rng_pool[rng_pptr++] = t >>> 8; - rng_pool[rng_pptr++] = t & 255; - } - rng_pptr = 0; - rng_seed_time(); - //rng_seed_int(window.screenX); - //rng_seed_int(window.screenY); - } - - function rng_get_byte() { - if (rng_state == null) { - rng_seed_time(); - rng_state = prng_newstate(); - rng_state.init(rng_pool); - for (rng_pptr = 0; rng_pptr < rng_pool.length; ++rng_pptr) - rng_pool[rng_pptr] = 0; - rng_pptr = 0; - //rng_pool = null; - } - // TODO: allow reseeding after first request - return rng_state.next(); - } - - function rng_get_bytes(ba) { - var i; - for (i = 0; i < ba.length; ++i) ba[i] = rng_get_byte(); - } - - function SecureRandom() { } - - SecureRandom.prototype.nextBytes = rng_get_bytes; - - // prng4.js - uses Arcfour as a PRNG - - function Arcfour() { - this.i = 0; - this.j = 0; - this.S = new Array(); - } - - // Initialize arcfour context from key, an array of ints, each from [0..255] - function ARC4init(key) { - var i, j, t; - for (i = 0; i < 256; ++i) this.S[i] = i; - j = 0; - for (i = 0; i < 256; ++i) { - j = (j + this.S[i] + key[i % key.length]) & 255; - t = this.S[i]; - this.S[i] = this.S[j]; - this.S[j] = t; - } - this.i = 0; - this.j = 0; - } - - function ARC4next() { - var t; - this.i = (this.i + 1) & 255; - this.j = (this.j + this.S[this.i]) & 255; - t = this.S[this.i]; - this.S[this.i] = this.S[this.j]; - this.S[this.j] = t; - return this.S[(t + this.S[this.i]) & 255]; - } - - Arcfour.prototype.init = ARC4init; - Arcfour.prototype.next = ARC4next; - - // Plug in your RNG constructor here - function prng_newstate() { - return new Arcfour(); - } - - // Pool size must be a multiple of 4 and greater than 32. - // An array of bytes the size of the pool will be passed to init() - var rng_psize = 256; - - - - - /*! - * Basic Javascript Elliptic Curve implementation - * Ported loosely from BouncyCastle's Java EC code - * Only Fp curves implemented for now - * - * Copyright Tom Wu, bitaddress.org BSD License. - * http://www-cs-students.stanford.edu/~tjw/jsbn/LICENSE - */ - - // Constructor function of Global EllipticCurve object - var ec = function () { }; - - - // ---------------- - // ECFieldElementFp constructor - // q instanceof BigInteger - // x instanceof BigInteger - ec.FieldElementFp = function (q, x) { - this.x = x; - // TODO if(x.compareTo(q) >= 0) error - this.q = q; - }; - - ec.FieldElementFp.prototype.equals = function (other) { - if (other == this) return true; - return (this.q.equals(other.q) && this.x.equals(other.x)); - }; - - ec.FieldElementFp.prototype.toBigInteger = function () { - return this.x; - }; - - ec.FieldElementFp.prototype.negate = function () { - return new ec.FieldElementFp(this.q, this.x.negate().mod(this.q)); - }; - - ec.FieldElementFp.prototype.add = function (b) { - return new ec.FieldElementFp(this.q, this.x.add(b.toBigInteger()).mod(this.q)); - }; - - ec.FieldElementFp.prototype.subtract = function (b) { - return new ec.FieldElementFp(this.q, this.x.subtract(b.toBigInteger()).mod(this.q)); - }; - - ec.FieldElementFp.prototype.multiply = function (b) { - return new ec.FieldElementFp(this.q, this.x.multiply(b.toBigInteger()).mod(this.q)); - }; - - ec.FieldElementFp.prototype.square = function () { - return new ec.FieldElementFp(this.q, this.x.square().mod(this.q)); - }; - - ec.FieldElementFp.prototype.divide = function (b) { - return new ec.FieldElementFp(this.q, this.x.multiply(b.toBigInteger().modInverse(this.q)).mod(this.q)); - }; - - ec.FieldElementFp.prototype.getByteLength = function () { - return Math.floor((this.toBigInteger().bitLength() + 7) / 8); - }; - - // D.1.4 91 + // Copyright (c) 2005 Tom Wu + // All Rights Reserved. + // See "LICENSE" for details. + + // Basic JavaScript BN library - subset useful for RSA encryption. + + // Bits per digit + var dbits; + + // JavaScript engine analysis + var canary = 0xdeadbeefcafe; + var j_lm = (canary & 0xffffff) == 0xefcafe; + + // (public) Constructor + function BigInteger(a, b, c) { + if (a != null) + if ('number' == typeof a) this.fromNumber(a, b, c); + else if (b == null && 'string' != typeof a) this.fromString(a, 256); + else this.fromString(a, b); + } + + // return new, unset BigInteger + function nbi() { + return new BigInteger(null); + } + + // am: Compute w_j += (x*this_i), propagate carries, + // c is initial carry, returns final carry. + // c < 3*dvalue, x < 2*dvalue, this_i < dvalue + // We need to select the fastest one that works in this environment. + + // am1: use a single mult and divide to get the high bits, + // max digit bits should be 26 because + // max internal value = 2*dvalue^2-2*dvalue (< 2^53) + function am1(i, x, w, j, c, n) { + while (--n >= 0) { + var v = x * this[i++] + w[j] + c; + c = Math.floor(v / 0x4000000); + w[j++] = v & 0x3ffffff; + } + return c; + } + // am2 avoids a big mult-and-extract completely. + // Max digit bits should be <= 30 because we do bitwise ops + // on values up to 2*hdvalue^2-hdvalue-1 (< 2^31) + function am2(i, x, w, j, c, n) { + var xl = x & 0x7fff, + xh = x >> 15; + while (--n >= 0) { + var l = this[i] & 0x7fff; + var h = this[i++] >> 15; + var m = xh * l + h * xl; + l = xl * l + ((m & 0x7fff) << 15) + w[j] + (c & 0x3fffffff); + c = (l >>> 30) + (m >>> 15) + xh * h + (c >>> 30); + w[j++] = l & 0x3fffffff; + } + return c; + } + // Alternately, set max digit bits to 28 since some + // browsers slow down when dealing with 32-bit numbers. + function am3(i, x, w, j, c, n) { + var xl = x & 0x3fff, + xh = x >> 14; + while (--n >= 0) { + var l = this[i] & 0x3fff; + var h = this[i++] >> 14; + var m = xh * l + h * xl; + l = xl * l + ((m & 0x3fff) << 14) + w[j] + c; + c = (l >> 28) + (m >> 14) + xh * h; + w[j++] = l & 0xfffffff; + } + return c; + } + var inBrowser = typeof navigator !== 'undefined'; + if (inBrowser && j_lm && navigator.appName == 'Microsoft Internet Explorer') { + BigInteger.prototype.am = am2; + dbits = 30; + } else if (inBrowser && j_lm && navigator.appName != 'Netscape') { + BigInteger.prototype.am = am1; + dbits = 26; + } else { + // Mozilla/Netscape seems to prefer am3 + BigInteger.prototype.am = am3; + dbits = 28; + } + + BigInteger.prototype.DB = dbits; + BigInteger.prototype.DM = (1 << dbits) - 1; + BigInteger.prototype.DV = 1 << dbits; + + var BI_FP = 52; + BigInteger.prototype.FV = Math.pow(2, BI_FP); + BigInteger.prototype.F1 = BI_FP - dbits; + BigInteger.prototype.F2 = 2 * dbits - BI_FP; + + // Digit conversions + var BI_RM = '0123456789abcdefghijklmnopqrstuvwxyz'; + var BI_RC = new Array(); + var rr, vv; + rr = '0'.charCodeAt(0); + for (vv = 0; vv <= 9; ++vv) BI_RC[rr++] = vv; + rr = 'a'.charCodeAt(0); + for (vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv; + rr = 'A'.charCodeAt(0); + for (vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv; + + function int2char(n) { + return BI_RM.charAt(n); + } + function intAt(s, i) { + var c = BI_RC[s.charCodeAt(i)]; + return c == null ? -1 : c; + } + + // (protected) copy this to r + function bnpCopyTo(r) { + for (var i = this.t - 1; i >= 0; --i) r[i] = this[i]; + r.t = this.t; + r.s = this.s; + } + + // (protected) set from integer value x, -DV <= x < DV + function bnpFromInt(x) { + this.t = 1; + this.s = x < 0 ? -1 : 0; + if (x > 0) this[0] = x; + else if (x < -1) this[0] = x + this.DV; + else this.t = 0; + } + + // return bigint initialized to value + function nbv(i) { + var r = nbi(); + r.fromInt(i); + return r; + } + + // (protected) set from string and radix + function bnpFromString(s, b) { + // Auto-detect string notations + if (!b && s.length >= 2 && s[0] === '0') { + var isDetected = true; + switch (s[1]) { + case 'x': // Hexadecimal notation + b = 16; + break; + case 'b': // Binary notation + b = 2; + break; + case 'o': // Octal notation + b = 8; + break; + default: + isDetected = false; + } + + // Remove the notation string if any has been detected + if (isDetected) { + s = s.substr(2); + } + } + + var k; + if (b == 16) k = 4; + else if (b == 8) k = 3; + else if (b == 256) k = 8; + // byte array + else if (b == 2) k = 1; + else if (b == 32) k = 5; + else if (b == 4) k = 2; + else { + this.fromRadix(s, b); + return; + } + this.t = 0; + this.s = 0; + var i = s.length, + mi = false, + sh = 0; + while (--i >= 0) { + var x = k == 8 ? s[i] & 0xff : intAt(s, i); + if (x < 0) { + if (s.charAt(i) == '-') mi = true; + continue; + } + mi = false; + if (sh == 0) this[this.t++] = x; + else if (sh + k > this.DB) { + this[this.t - 1] |= (x & ((1 << (this.DB - sh)) - 1)) << sh; + this[this.t++] = x >> (this.DB - sh); + } else this[this.t - 1] |= x << sh; + sh += k; + if (sh >= this.DB) sh -= this.DB; + } + if (k == 8 && (s[0] & 0x80) != 0) { + this.s = -1; + if (sh > 0) this[this.t - 1] |= ((1 << (this.DB - sh)) - 1) << sh; + } + this.clamp(); + if (mi) BigInteger.ZERO.subTo(this, this); + } + + // (protected) clamp off excess high words + function bnpClamp() { + var c = this.s & this.DM; + while (this.t > 0 && this[this.t - 1] == c) --this.t; + } + + // (public) return string representation in given radix + function bnToString(b) { + if (this.s < 0) return '-' + this.negate().toString(b); + var k; + if (b == 16) k = 4; + else if (b == 8) k = 3; + else if (b == 2) k = 1; + else if (b == 32) k = 5; + else if (b == 4) k = 2; + else return this.toRadix(b); + var km = (1 << k) - 1, + d, + m = false, + r = '', + i = this.t; + var p = this.DB - ((i * this.DB) % k); + if (i-- > 0) { + if (p < this.DB && (d = this[i] >> p) > 0) { + m = true; + r = int2char(d); + } + while (i >= 0) { + if (p < k) { + d = (this[i] & ((1 << p) - 1)) << (k - p); + d |= this[--i] >> (p += this.DB - k); + } else { + d = (this[i] >> (p -= k)) & km; + if (p <= 0) { + p += this.DB; + --i; + } + } + if (d > 0) m = true; + if (m) r += int2char(d); + } + } + return m ? r : '0'; + } + + // (public) -this + function bnNegate() { + var r = nbi(); + BigInteger.ZERO.subTo(this, r); + return r; + } + + // (public) |this| + function bnAbs() { + return this.s < 0 ? this.negate() : this; + } + + // (public) return + if this > a, - if this < a, 0 if equal + function bnCompareTo(a) { + var r = this.s - a.s; + if (r != 0) return r; + var i = this.t; + r = i - a.t; + if (r != 0) return this.s < 0 ? -r : r; + while (--i >= 0) if ((r = this[i] - a[i]) != 0) return r; + return 0; + } + + // returns bit length of the integer x + function nbits(x) { + var r = 1, + t; + if ((t = x >>> 16) != 0) { + x = t; + r += 16; + } + if ((t = x >> 8) != 0) { + x = t; + r += 8; + } + if ((t = x >> 4) != 0) { + x = t; + r += 4; + } + if ((t = x >> 2) != 0) { + x = t; + r += 2; + } + if ((t = x >> 1) != 0) { + x = t; + r += 1; + } + return r; + } + + // (public) return the number of bits in "this" + function bnBitLength() { + if (this.t <= 0) return 0; + return ( + this.DB * (this.t - 1) + nbits(this[this.t - 1] ^ (this.s & this.DM)) + ); + } + + // (protected) r = this << n*DB + function bnpDLShiftTo(n, r) { + var i; + for (i = this.t - 1; i >= 0; --i) r[i + n] = this[i]; + for (i = n - 1; i >= 0; --i) r[i] = 0; + r.t = this.t + n; + r.s = this.s; + } + + // (protected) r = this >> n*DB + function bnpDRShiftTo(n, r) { + for (var i = n; i < this.t; ++i) r[i - n] = this[i]; + r.t = Math.max(this.t - n, 0); + r.s = this.s; + } + + // (protected) r = this << n + function bnpLShiftTo(n, r) { + var bs = n % this.DB; + var cbs = this.DB - bs; + var bm = (1 << cbs) - 1; + var ds = Math.floor(n / this.DB), + c = (this.s << bs) & this.DM, + i; + for (i = this.t - 1; i >= 0; --i) { + r[i + ds + 1] = (this[i] >> cbs) | c; + c = (this[i] & bm) << bs; + } + for (i = ds - 1; i >= 0; --i) r[i] = 0; + r[ds] = c; + r.t = this.t + ds + 1; + r.s = this.s; + r.clamp(); + } + + // (protected) r = this >> n + function bnpRShiftTo(n, r) { + r.s = this.s; + var ds = Math.floor(n / this.DB); + if (ds >= this.t) { + r.t = 0; + return; + } + var bs = n % this.DB; + var cbs = this.DB - bs; + var bm = (1 << bs) - 1; + r[0] = this[ds] >> bs; + for (var i = ds + 1; i < this.t; ++i) { + r[i - ds - 1] |= (this[i] & bm) << cbs; + r[i - ds] = this[i] >> bs; + } + if (bs > 0) r[this.t - ds - 1] |= (this.s & bm) << cbs; + r.t = this.t - ds; + r.clamp(); + } + + // (protected) r = this - a + function bnpSubTo(a, r) { + var i = 0, + c = 0, + m = Math.min(a.t, this.t); + while (i < m) { + c += this[i] - a[i]; + r[i++] = c & this.DM; + c >>= this.DB; + } + if (a.t < this.t) { + c -= a.s; + while (i < this.t) { + c += this[i]; + r[i++] = c & this.DM; + c >>= this.DB; + } + c += this.s; + } else { + c += this.s; + while (i < a.t) { + c -= a[i]; + r[i++] = c & this.DM; + c >>= this.DB; + } + c -= a.s; + } + r.s = c < 0 ? -1 : 0; + if (c < -1) r[i++] = this.DV + c; + else if (c > 0) r[i++] = c; + r.t = i; + r.clamp(); + } + + // (protected) r = this * a, r != this,a (HAC 14.12) + // "this" should be the larger one if appropriate. + function bnpMultiplyTo(a, r) { + var x = this.abs(), + y = a.abs(); + var i = x.t; + r.t = i + y.t; + while (--i >= 0) r[i] = 0; + for (i = 0; i < y.t; ++i) r[i + x.t] = x.am(0, y[i], r, i, 0, x.t); + r.s = 0; + r.clamp(); + if (this.s != a.s) BigInteger.ZERO.subTo(r, r); + } + + // (protected) r = this^2, r != this (HAC 14.16) + function bnpSquareTo(r) { + var x = this.abs(); + var i = (r.t = 2 * x.t); + while (--i >= 0) r[i] = 0; + for (i = 0; i < x.t - 1; ++i) { + var c = x.am(i, x[i], r, 2 * i, 0, 1); + if ( + (r[i + x.t] += x.am(i + 1, 2 * x[i], r, 2 * i + 1, c, x.t - i - 1)) >= + x.DV + ) { + r[i + x.t] -= x.DV; + r[i + x.t + 1] = 1; + } + } + if (r.t > 0) r[r.t - 1] += x.am(i, x[i], r, 2 * i, 0, 1); + r.s = 0; + r.clamp(); + } + + // (protected) divide this by m, quotient and remainder to q, r (HAC 14.20) + // r != q, this != m. q or r may be null. + function bnpDivRemTo(m, q, r) { + var pm = m.abs(); + if (pm.t <= 0) return; + var pt = this.abs(); + if (pt.t < pm.t) { + if (q != null) q.fromInt(0); + if (r != null) this.copyTo(r); + return; + } + if (r == null) r = nbi(); + var y = nbi(), + ts = this.s, + ms = m.s; + var nsh = this.DB - nbits(pm[pm.t - 1]); // normalize modulus + if (nsh > 0) { + pm.lShiftTo(nsh, y); + pt.lShiftTo(nsh, r); + } else { + pm.copyTo(y); + pt.copyTo(r); + } + var ys = y.t; + var y0 = y[ys - 1]; + if (y0 == 0) return; + var yt = y0 * (1 << this.F1) + (ys > 1 ? y[ys - 2] >> this.F2 : 0); + var d1 = this.FV / yt, + d2 = (1 << this.F1) / yt, + e = 1 << this.F2; + var i = r.t, + j = i - ys, + t = q == null ? nbi() : q; + y.dlShiftTo(j, t); + if (r.compareTo(t) >= 0) { + r[r.t++] = 1; + r.subTo(t, r); + } + BigInteger.ONE.dlShiftTo(ys, t); + t.subTo(y, y); // "negative" y so we can replace sub with am later + while (y.t < ys) y[y.t++] = 0; + while (--j >= 0) { + // Estimate quotient digit + var qd = + r[--i] == y0 ? this.DM : Math.floor(r[i] * d1 + (r[i - 1] + e) * d2); + if ((r[i] += y.am(0, qd, r, j, 0, ys)) < qd) { + // Try it out + y.dlShiftTo(j, t); + r.subTo(t, r); + while (r[i] < --qd) r.subTo(t, r); + } + } + if (q != null) { + r.drShiftTo(ys, q); + if (ts != ms) BigInteger.ZERO.subTo(q, q); + } + r.t = ys; + r.clamp(); + if (nsh > 0) r.rShiftTo(nsh, r); // Denormalize remainder + if (ts < 0) BigInteger.ZERO.subTo(r, r); + } + + // (public) this mod a + function bnMod(a) { + var r = nbi(); + this.abs().divRemTo(a, null, r); + if (this.s < 0 && r.compareTo(BigInteger.ZERO) > 0) a.subTo(r, r); + return r; + } + + // Modular reduction using "classic" algorithm + function Classic(m) { + this.m = m; + } + function cConvert(x) { + if (x.s < 0 || x.compareTo(this.m) >= 0) return x.mod(this.m); + else return x; + } + function cRevert(x) { + return x; + } + function cReduce(x) { + x.divRemTo(this.m, null, x); + } + function cMulTo(x, y, r) { + x.multiplyTo(y, r); + this.reduce(r); + } + function cSqrTo(x, r) { + x.squareTo(r); + this.reduce(r); + } + + Classic.prototype.convert = cConvert; + Classic.prototype.revert = cRevert; + Classic.prototype.reduce = cReduce; + Classic.prototype.mulTo = cMulTo; + Classic.prototype.sqrTo = cSqrTo; + + // (protected) return "-1/this % 2^DB"; useful for Mont. reduction + // justification: + // xy == 1 (mod m) + // xy = 1+km + // xy(2-xy) = (1+km)(1-km) + // x[y(2-xy)] = 1-k^2m^2 + // x[y(2-xy)] == 1 (mod m^2) + // if y is 1/x mod m, then y(2-xy) is 1/x mod m^2 + // should reduce x and y(2-xy) by m^2 at each step to keep size bounded. + // JS multiply "overflows" differently from C/C++, so care is needed here. + function bnpInvDigit() { + if (this.t < 1) return 0; + var x = this[0]; + if ((x & 1) == 0) return 0; + var y = x & 3; // y == 1/x mod 2^2 + y = (y * (2 - (x & 0xf) * y)) & 0xf; // y == 1/x mod 2^4 + y = (y * (2 - (x & 0xff) * y)) & 0xff; // y == 1/x mod 2^8 + y = (y * (2 - (((x & 0xffff) * y) & 0xffff))) & 0xffff; // y == 1/x mod 2^16 + // last step - calculate inverse mod DV directly; + // assumes 16 < DB <= 32 and assumes ability to handle 48-bit ints + y = (y * (2 - ((x * y) % this.DV))) % this.DV; // y == 1/x mod 2^dbits + // we really want the negative inverse, and -DV < y < DV + return y > 0 ? this.DV - y : -y; + } + + // Montgomery reduction + function Montgomery(m) { + this.m = m; + this.mp = m.invDigit(); + this.mpl = this.mp & 0x7fff; + this.mph = this.mp >> 15; + this.um = (1 << (m.DB - 15)) - 1; + this.mt2 = 2 * m.t; + } + + // xR mod m + function montConvert(x) { + var r = nbi(); + x.abs().dlShiftTo(this.m.t, r); + r.divRemTo(this.m, null, r); + if (x.s < 0 && r.compareTo(BigInteger.ZERO) > 0) this.m.subTo(r, r); + return r; + } + + // x/R mod m + function montRevert(x) { + var r = nbi(); + x.copyTo(r); + this.reduce(r); + return r; + } + + // x = x/R mod m (HAC 14.32) + function montReduce(x) { + while ( + x.t <= this.mt2 // pad x so am has enough room later + ) + x[x.t++] = 0; + for (var i = 0; i < this.m.t; ++i) { + // faster way of calculating u0 = x[i]*mp mod DV + var j = x[i] & 0x7fff; + var u0 = + (j * this.mpl + + (((j * this.mph + (x[i] >> 15) * this.mpl) & this.um) << 15)) & + x.DM; + // use am to combine the multiply-shift-add into one call + j = i + this.m.t; + x[j] += this.m.am(0, u0, x, i, 0, this.m.t); + // propagate carry + while (x[j] >= x.DV) { + x[j] -= x.DV; + x[++j]++; + } + } + x.clamp(); + x.drShiftTo(this.m.t, x); + if (x.compareTo(this.m) >= 0) x.subTo(this.m, x); + } + + // r = "x^2/R mod m"; x != r + function montSqrTo(x, r) { + x.squareTo(r); + this.reduce(r); + } + + // r = "xy/R mod m"; x,y != r + function montMulTo(x, y, r) { + x.multiplyTo(y, r); + this.reduce(r); + } + + Montgomery.prototype.convert = montConvert; + Montgomery.prototype.revert = montRevert; + Montgomery.prototype.reduce = montReduce; + Montgomery.prototype.mulTo = montMulTo; + Montgomery.prototype.sqrTo = montSqrTo; + + // (protected) true iff this is even + function bnpIsEven() { + return (this.t > 0 ? this[0] & 1 : this.s) == 0; + } + + // (protected) this^e, e < 2^32, doing sqr and mul with "r" (HAC 14.79) + function bnpExp(e, z) { + if (e > 0xffffffff || e < 1) return BigInteger.ONE; + var r = nbi(), + r2 = nbi(), + g = z.convert(this), + i = nbits(e) - 1; + g.copyTo(r); + while (--i >= 0) { + z.sqrTo(r, r2); + if ((e & (1 << i)) > 0) z.mulTo(r2, g, r); + else { + var t = r; + r = r2; + r2 = t; + } + } + return z.revert(r); + } + + // (public) this^e % m, 0 <= e < 2^32 + function bnModPowInt(e, m) { + var z; + if (e < 256 || m.isEven()) z = new Classic(m); + else z = new Montgomery(m); + return this.exp(e, z); + } + + // protected + BigInteger.prototype.copyTo = bnpCopyTo; + BigInteger.prototype.fromInt = bnpFromInt; + BigInteger.prototype.fromString = bnpFromString; + BigInteger.prototype.clamp = bnpClamp; + BigInteger.prototype.dlShiftTo = bnpDLShiftTo; + BigInteger.prototype.drShiftTo = bnpDRShiftTo; + BigInteger.prototype.lShiftTo = bnpLShiftTo; + BigInteger.prototype.rShiftTo = bnpRShiftTo; + BigInteger.prototype.subTo = bnpSubTo; + BigInteger.prototype.multiplyTo = bnpMultiplyTo; + BigInteger.prototype.squareTo = bnpSquareTo; + BigInteger.prototype.divRemTo = bnpDivRemTo; + BigInteger.prototype.invDigit = bnpInvDigit; + BigInteger.prototype.isEven = bnpIsEven; + BigInteger.prototype.exp = bnpExp; + + // public + BigInteger.prototype.toString = bnToString; + BigInteger.prototype.negate = bnNegate; + BigInteger.prototype.abs = bnAbs; + BigInteger.prototype.compareTo = bnCompareTo; + BigInteger.prototype.bitLength = bnBitLength; + BigInteger.prototype.mod = bnMod; + BigInteger.prototype.modPowInt = bnModPowInt; + + // "constants" + BigInteger.ZERO = nbv(0); + BigInteger.ONE = nbv(1); + BigInteger.valueOf = nbv; + + // Copyright (c) 2005-2009 Tom Wu + // All Rights Reserved. + // See "LICENSE" for details. + + // Extended JavaScript BN functions, required for RSA private ops. + + // Version 1.1: new BigInteger("0", 10) returns "proper" zero + // Version 1.2: square() API, isProbablePrime fix + + // (public) + function bnClone() { + var r = nbi(); + this.copyTo(r); + return r; + } + + // (public) return value as integer + function bnIntValue() { + if (this.s < 0) { + if (this.t == 1) return this[0] - this.DV; + else if (this.t == 0) return -1; + } else if (this.t == 1) return this[0]; + else if (this.t == 0) return 0; + // assumes 16 < DB < 32 + return ((this[1] & ((1 << (32 - this.DB)) - 1)) << this.DB) | this[0]; + } + + // (public) return value as byte + function bnByteValue() { + return this.t == 0 ? this.s : (this[0] << 24) >> 24; + } + + // (public) return value as short (assumes DB>=16) + function bnShortValue() { + return this.t == 0 ? this.s : (this[0] << 16) >> 16; + } + + // (protected) return x s.t. r^x < DV + function bnpChunkSize(r) { + return Math.floor((Math.LN2 * this.DB) / Math.log(r)); + } + + // (public) 0 if this == 0, 1 if this > 0 + function bnSigNum() { + if (this.s < 0) return -1; + else if (this.t <= 0 || (this.t == 1 && this[0] <= 0)) return 0; + else return 1; + } + + // (protected) convert to radix string + function bnpToRadix(b) { + if (b == null) b = 10; + if (this.signum() == 0 || b < 2 || b > 36) return '0'; + var cs = this.chunkSize(b); + var a = Math.pow(b, cs); + var d = nbv(a), + y = nbi(), + z = nbi(), + r = ''; + this.divRemTo(d, y, z); + while (y.signum() > 0) { + r = (a + z.intValue()).toString(b).substr(1) + r; + y.divRemTo(d, y, z); + } + return z.intValue().toString(b) + r; + } + + // (protected) convert from radix string + function bnpFromRadix(s, b) { + this.fromInt(0); + if (b == null) b = 10; + var cs = this.chunkSize(b); + var d = Math.pow(b, cs), + mi = false, + j = 0, + w = 0; + for (var i = 0; i < s.length; ++i) { + var x = intAt(s, i); + if (x < 0) { + if (s.charAt(i) == '-' && this.signum() == 0) mi = true; + continue; + } + w = b * w + x; + if (++j >= cs) { + this.dMultiply(d); + this.dAddOffset(w, 0); + j = 0; + w = 0; + } + } + if (j > 0) { + this.dMultiply(Math.pow(b, j)); + this.dAddOffset(w, 0); + } + if (mi) BigInteger.ZERO.subTo(this, this); + } + + // (protected) alternate constructor + function bnpFromNumber(a, b, c) { + if ('number' == typeof b) { + // new BigInteger(int,int,RNG) + if (a < 2) this.fromInt(1); + else { + this.fromNumber(a, c); + if (!this.testBit(a - 1)) + // force MSB set + this.bitwiseTo(BigInteger.ONE.shiftLeft(a - 1), op_or, this); + if (this.isEven()) this.dAddOffset(1, 0); // force odd + while (!this.isProbablePrime(b)) { + this.dAddOffset(2, 0); + if (this.bitLength() > a) + this.subTo(BigInteger.ONE.shiftLeft(a - 1), this); + } + } + } else { + // new BigInteger(int,RNG) + var x = new Array(), + t = a & 7; + x.length = (a >> 3) + 1; + b.nextBytes(x); + if (t > 0) x[0] &= (1 << t) - 1; + else x[0] = 0; + this.fromString(x, 256); + } + } + + // (public) convert to bigendian byte array + function bnToByteArray() { + var i = this.t, + r = new Array(); + r[0] = this.s; + var p = this.DB - ((i * this.DB) % 8), + d, + k = 0; + if (i-- > 0) { + if (p < this.DB && (d = this[i] >> p) != (this.s & this.DM) >> p) + r[k++] = d | (this.s << (this.DB - p)); + while (i >= 0) { + if (p < 8) { + d = (this[i] & ((1 << p) - 1)) << (8 - p); + d |= this[--i] >> (p += this.DB - 8); + } else { + d = (this[i] >> (p -= 8)) & 0xff; + if (p <= 0) { + p += this.DB; + --i; + } + } + if ((d & 0x80) != 0) d |= -256; + if (k == 0 && (this.s & 0x80) != (d & 0x80)) ++k; + if (k > 0 || d != this.s) r[k++] = d; + } + } + return r; + } + + function bnEquals(a) { + return this.compareTo(a) == 0; + } + function bnMin(a) { + return this.compareTo(a) < 0 ? this : a; + } + function bnMax(a) { + return this.compareTo(a) > 0 ? this : a; + } + + // (protected) r = this op a (bitwise) + function bnpBitwiseTo(a, op, r) { + var i, + f, + m = Math.min(a.t, this.t); + for (i = 0; i < m; ++i) r[i] = op(this[i], a[i]); + if (a.t < this.t) { + f = a.s & this.DM; + for (i = m; i < this.t; ++i) r[i] = op(this[i], f); + r.t = this.t; + } else { + f = this.s & this.DM; + for (i = m; i < a.t; ++i) r[i] = op(f, a[i]); + r.t = a.t; + } + r.s = op(this.s, a.s); + r.clamp(); + } + + // (public) this & a + function op_and(x, y) { + return x & y; + } + function bnAnd(a) { + var r = nbi(); + this.bitwiseTo(a, op_and, r); + return r; + } + + // (public) this | a + function op_or(x, y) { + return x | y; + } + function bnOr(a) { + var r = nbi(); + this.bitwiseTo(a, op_or, r); + return r; + } + + // (public) this ^ a + function op_xor(x, y) { + return x ^ y; + } + function bnXor(a) { + var r = nbi(); + this.bitwiseTo(a, op_xor, r); + return r; + } + + // (public) this & ~a + function op_andnot(x, y) { + return x & ~y; + } + function bnAndNot(a) { + var r = nbi(); + this.bitwiseTo(a, op_andnot, r); + return r; + } + + // (public) ~this + function bnNot() { + var r = nbi(); + for (var i = 0; i < this.t; ++i) r[i] = this.DM & ~this[i]; + r.t = this.t; + r.s = ~this.s; + return r; + } + + // (public) this << n + function bnShiftLeft(n) { + var r = nbi(); + if (n < 0) this.rShiftTo(-n, r); + else this.lShiftTo(n, r); + return r; + } + + // (public) this >> n + function bnShiftRight(n) { + var r = nbi(); + if (n < 0) this.lShiftTo(-n, r); + else this.rShiftTo(n, r); + return r; + } + + // return index of lowest 1-bit in x, x < 2^31 + function lbit(x) { + if (x == 0) return -1; + var r = 0; + if ((x & 0xffff) == 0) { + x >>= 16; + r += 16; + } + if ((x & 0xff) == 0) { + x >>= 8; + r += 8; + } + if ((x & 0xf) == 0) { + x >>= 4; + r += 4; + } + if ((x & 3) == 0) { + x >>= 2; + r += 2; + } + if ((x & 1) == 0) ++r; + return r; + } + + // (public) returns index of lowest 1-bit (or -1 if none) + function bnGetLowestSetBit() { + for (var i = 0; i < this.t; ++i) + if (this[i] != 0) return i * this.DB + lbit(this[i]); + if (this.s < 0) return this.t * this.DB; + return -1; + } + + // return number of 1 bits in x + function cbit(x) { + var r = 0; + while (x != 0) { + x &= x - 1; + ++r; + } + return r; + } + + // (public) return number of set bits + function bnBitCount() { + var r = 0, + x = this.s & this.DM; + for (var i = 0; i < this.t; ++i) r += cbit(this[i] ^ x); + return r; + } + + // (public) true iff nth bit is set + function bnTestBit(n) { + var j = Math.floor(n / this.DB); + if (j >= this.t) return this.s != 0; + return (this[j] & (1 << n % this.DB)) != 0; + } + + // (protected) this op (1<>= this.DB; + } + if (a.t < this.t) { + c += a.s; + while (i < this.t) { + c += this[i]; + r[i++] = c & this.DM; + c >>= this.DB; + } + c += this.s; + } else { + c += this.s; + while (i < a.t) { + c += a[i]; + r[i++] = c & this.DM; + c >>= this.DB; + } + c += a.s; + } + r.s = c < 0 ? -1 : 0; + if (c > 0) r[i++] = c; + else if (c < -1) r[i++] = this.DV + c; + r.t = i; + r.clamp(); + } + + // (public) this + a + function bnAdd(a) { + var r = nbi(); + this.addTo(a, r); + return r; + } + + // (public) this - a + function bnSubtract(a) { + var r = nbi(); + this.subTo(a, r); + return r; + } + + // (public) this * a + function bnMultiply(a) { + var r = nbi(); + this.multiplyTo(a, r); + return r; + } + + // (public) this^2 + function bnSquare() { + var r = nbi(); + this.squareTo(r); + return r; + } + + // (public) this / a + function bnDivide(a) { + var r = nbi(); + this.divRemTo(a, r, null); + return r; + } + + // (public) this % a + function bnRemainder(a) { + var r = nbi(); + this.divRemTo(a, null, r); + return r; + } + + // (public) [this/a,this%a] + function bnDivideAndRemainder(a) { + var q = nbi(), + r = nbi(); + this.divRemTo(a, q, r); + return new Array(q, r); + } + + // (protected) this *= n, this >= 0, 1 < n < DV + function bnpDMultiply(n) { + this[this.t] = this.am(0, n - 1, this, 0, 0, this.t); + ++this.t; + this.clamp(); + } + + // (protected) this += n << w words, this >= 0 + function bnpDAddOffset(n, w) { + if (n == 0) return; + while (this.t <= w) this[this.t++] = 0; + this[w] += n; + while (this[w] >= this.DV) { + this[w] -= this.DV; + if (++w >= this.t) this[this.t++] = 0; + ++this[w]; + } + } + + // A "null" reducer + function NullExp() { } + function nNop(x) { + return x; + } + function nMulTo(x, y, r) { + x.multiplyTo(y, r); + } + function nSqrTo(x, r) { + x.squareTo(r); + } + + NullExp.prototype.convert = nNop; + NullExp.prototype.revert = nNop; + NullExp.prototype.mulTo = nMulTo; + NullExp.prototype.sqrTo = nSqrTo; + + // (public) this^e + function bnPow(e) { + return this.exp(e, new NullExp()); + } + + // (protected) r = lower n words of "this * a", a.t <= n + // "this" should be the larger one if appropriate. + function bnpMultiplyLowerTo(a, n, r) { + var i = Math.min(this.t + a.t, n); + r.s = 0; // assumes a,this >= 0 + r.t = i; + while (i > 0) r[--i] = 0; + var j; + for (j = r.t - this.t; i < j; ++i) + r[i + this.t] = this.am(0, a[i], r, i, 0, this.t); + for (j = Math.min(a.t, n); i < j; ++i) this.am(0, a[i], r, i, 0, n - i); + r.clamp(); + } + + // (protected) r = "this * a" without lower n words, n > 0 + // "this" should be the larger one if appropriate. + function bnpMultiplyUpperTo(a, n, r) { + --n; + var i = (r.t = this.t + a.t - n); + r.s = 0; // assumes a,this >= 0 + while (--i >= 0) r[i] = 0; + for (i = Math.max(n - this.t, 0); i < a.t; ++i) + r[this.t + i - n] = this.am(n - i, a[i], r, 0, 0, this.t + i - n); + r.clamp(); + r.drShiftTo(1, r); + } + + // Barrett modular reduction + function Barrett(m) { + // setup Barrett + this.r2 = nbi(); + this.q3 = nbi(); + BigInteger.ONE.dlShiftTo(2 * m.t, this.r2); + this.mu = this.r2.divide(m); + this.m = m; + } + + function barrettConvert(x) { + if (x.s < 0 || x.t > 2 * this.m.t) return x.mod(this.m); + else if (x.compareTo(this.m) < 0) return x; + else { + var r = nbi(); + x.copyTo(r); + this.reduce(r); + return r; + } + } + + function barrettRevert(x) { + return x; + } + + // x = x mod m (HAC 14.42) + function barrettReduce(x) { + x.drShiftTo(this.m.t - 1, this.r2); + if (x.t > this.m.t + 1) { + x.t = this.m.t + 1; + x.clamp(); + } + this.mu.multiplyUpperTo(this.r2, this.m.t + 1, this.q3); + this.m.multiplyLowerTo(this.q3, this.m.t + 1, this.r2); + while (x.compareTo(this.r2) < 0) x.dAddOffset(1, this.m.t + 1); + x.subTo(this.r2, x); + while (x.compareTo(this.m) >= 0) x.subTo(this.m, x); + } + + // r = x^2 mod m; x != r + function barrettSqrTo(x, r) { + x.squareTo(r); + this.reduce(r); + } + + // r = x*y mod m; x,y != r + function barrettMulTo(x, y, r) { + x.multiplyTo(y, r); + this.reduce(r); + } + + Barrett.prototype.convert = barrettConvert; + Barrett.prototype.revert = barrettRevert; + Barrett.prototype.reduce = barrettReduce; + Barrett.prototype.mulTo = barrettMulTo; + Barrett.prototype.sqrTo = barrettSqrTo; + + // (public) this^e % m (HAC 14.85) + function bnModPow(e, m) { + var i = e.bitLength(), + k, + r = nbv(1), + z; + if (i <= 0) return r; + else if (i < 18) k = 1; + else if (i < 48) k = 3; + else if (i < 144) k = 4; + else if (i < 768) k = 5; + else k = 6; + if (i < 8) z = new Classic(m); + else if (m.isEven()) z = new Barrett(m); + else z = new Montgomery(m); + + // precomputation + var g = new Array(), + n = 3, + k1 = k - 1, + km = (1 << k) - 1; + g[1] = z.convert(this); + if (k > 1) { + var g2 = nbi(); + z.sqrTo(g[1], g2); + while (n <= km) { + g[n] = nbi(); + z.mulTo(g2, g[n - 2], g[n]); + n += 2; + } + } + + var j = e.t - 1, + w, + is1 = true, + r2 = nbi(), + t; + i = nbits(e[j]) - 1; + while (j >= 0) { + if (i >= k1) w = (e[j] >> (i - k1)) & km; + else { + w = (e[j] & ((1 << (i + 1)) - 1)) << (k1 - i); + if (j > 0) w |= e[j - 1] >> (this.DB + i - k1); + } + + n = k; + while ((w & 1) == 0) { + w >>= 1; + --n; + } + if ((i -= n) < 0) { + i += this.DB; + --j; + } + if (is1) { + // ret == 1, don't bother squaring or multiplying it + g[w].copyTo(r); + is1 = false; + } else { + while (n > 1) { + z.sqrTo(r, r2); + z.sqrTo(r2, r); + n -= 2; + } + if (n > 0) z.sqrTo(r, r2); + else { + t = r; + r = r2; + r2 = t; + } + z.mulTo(r2, g[w], r); + } + + while (j >= 0 && (e[j] & (1 << i)) == 0) { + z.sqrTo(r, r2); + t = r; + r = r2; + r2 = t; + if (--i < 0) { + i = this.DB - 1; + --j; + } + } + } + return z.revert(r); + } + + // (public) gcd(this,a) (HAC 14.54) + function bnGCD(a) { + var x = this.s < 0 ? this.negate() : this.clone(); + var y = a.s < 0 ? a.negate() : a.clone(); + if (x.compareTo(y) < 0) { + var t = x; + x = y; + y = t; + } + var i = x.getLowestSetBit(), + g = y.getLowestSetBit(); + if (g < 0) return x; + if (i < g) g = i; + if (g > 0) { + x.rShiftTo(g, x); + y.rShiftTo(g, y); + } + while (x.signum() > 0) { + if ((i = x.getLowestSetBit()) > 0) x.rShiftTo(i, x); + if ((i = y.getLowestSetBit()) > 0) y.rShiftTo(i, y); + if (x.compareTo(y) >= 0) { + x.subTo(y, x); + x.rShiftTo(1, x); + } else { + y.subTo(x, y); + y.rShiftTo(1, y); + } + } + if (g > 0) y.lShiftTo(g, y); + return y; + } + + // (protected) this % n, n < 2^26 + function bnpModInt(n) { + if (n <= 0) return 0; + var d = this.DV % n, + r = this.s < 0 ? n - 1 : 0; + if (this.t > 0) + if (d == 0) r = this[0] % n; + else for (var i = this.t - 1; i >= 0; --i) r = (d * r + this[i]) % n; + return r; + } + + // (public) 1/this % m (HAC 14.61) + function bnModInverse(m) { + var ac = m.isEven(); + if ((this.isEven() && ac) || m.signum() == 0) return BigInteger.ZERO; + var u = m.clone(), + v = this.clone(); + var a = nbv(1), + b = nbv(0), + c = nbv(0), + d = nbv(1); + while (u.signum() != 0) { + while (u.isEven()) { + u.rShiftTo(1, u); + if (ac) { + if (!a.isEven() || !b.isEven()) { + a.addTo(this, a); + b.subTo(m, b); + } + a.rShiftTo(1, a); + } else if (!b.isEven()) b.subTo(m, b); + b.rShiftTo(1, b); + } + while (v.isEven()) { + v.rShiftTo(1, v); + if (ac) { + if (!c.isEven() || !d.isEven()) { + c.addTo(this, c); + d.subTo(m, d); + } + c.rShiftTo(1, c); + } else if (!d.isEven()) d.subTo(m, d); + d.rShiftTo(1, d); + } + if (u.compareTo(v) >= 0) { + u.subTo(v, u); + if (ac) a.subTo(c, a); + b.subTo(d, b); + } else { + v.subTo(u, v); + if (ac) c.subTo(a, c); + d.subTo(b, d); + } + } + if (v.compareTo(BigInteger.ONE) != 0) return BigInteger.ZERO; + if (d.compareTo(m) >= 0) return d.subtract(m); + if (d.signum() < 0) d.addTo(m, d); + else return d; + if (d.signum() < 0) return d.add(m); + else return d; + } + + var lowprimes = [ + 2, + 3, + 5, + 7, + 11, + 13, + 17, + 19, + 23, + 29, + 31, + 37, + 41, + 43, + 47, + 53, + 59, + 61, + 67, + 71, + 73, + 79, + 83, + 89, + 97, + 101, + 103, + 107, + 109, + 113, + 127, + 131, + 137, + 139, + 149, + 151, + 157, + 163, + 167, + 173, + 179, + 181, + 191, + 193, + 197, + 199, + 211, + 223, + 227, + 229, + 233, + 239, + 241, + 251, + 257, + 263, + 269, + 271, + 277, + 281, + 283, + 293, + 307, + 311, + 313, + 317, + 331, + 337, + 347, + 349, + 353, + 359, + 367, + 373, + 379, + 383, + 389, + 397, + 401, + 409, + 419, + 421, + 431, + 433, + 439, + 443, + 449, + 457, + 461, + 463, + 467, + 479, + 487, + 491, + 499, + 503, + 509, + 521, + 523, + 541, + 547, + 557, + 563, + 569, + 571, + 577, + 587, + 593, + 599, + 601, + 607, + 613, + 617, + 619, + 631, + 641, + 643, + 647, + 653, + 659, + 661, + 673, + 677, + 683, + 691, + 701, + 709, + 719, + 727, + 733, + 739, + 743, + 751, + 757, + 761, + 769, + 773, + 787, + 797, + 809, + 811, + 821, + 823, + 827, + 829, + 839, + 853, + 857, + 859, + 863, + 877, + 881, + 883, + 887, + 907, + 911, + 919, + 929, + 937, + 941, + 947, + 953, + 967, + 971, + 977, + 983, + 991, + 997, + ]; + var lplim = (1 << 26) / lowprimes[lowprimes.length - 1]; + + // (public) test primality with certainty >= 1-.5^t + function bnIsProbablePrime(t) { + var i, + x = this.abs(); + if (x.t == 1 && x[0] <= lowprimes[lowprimes.length - 1]) { + for (i = 0; i < lowprimes.length; ++i) + if (x[0] == lowprimes[i]) return true; + return false; + } + if (x.isEven()) return false; + i = 1; + while (i < lowprimes.length) { + var m = lowprimes[i], + j = i + 1; + while (j < lowprimes.length && m < lplim) m *= lowprimes[j++]; + m = x.modInt(m); + while (i < j) if (m % lowprimes[i++] == 0) return false; + } + return x.millerRabin(t); + } + + // (protected) true if probably prime (HAC 4.24, Miller-Rabin) + function bnpMillerRabin(t) { + var n1 = this.subtract(BigInteger.ONE); + var k = n1.getLowestSetBit(); + if (k <= 0) return false; + var r = n1.shiftRight(k); + t = (t + 1) >> 1; + if (t > lowprimes.length) t = lowprimes.length; + var a = nbi(); + for (var i = 0; i < t; ++i) { + //Pick bases at random, instead of starting at 2 + a.fromInt(lowprimes[Math.floor(Math.random() * lowprimes.length)]); + var y = a.modPow(r, this); + if (y.compareTo(BigInteger.ONE) != 0 && y.compareTo(n1) != 0) { + var j = 1; + while (j++ < k && y.compareTo(n1) != 0) { + y = y.modPowInt(2, this); + if (y.compareTo(BigInteger.ONE) == 0) return false; + } + if (y.compareTo(n1) != 0) return false; + } + } + return true; + } + + // protected + BigInteger.prototype.chunkSize = bnpChunkSize; + BigInteger.prototype.toRadix = bnpToRadix; + BigInteger.prototype.fromRadix = bnpFromRadix; + BigInteger.prototype.fromNumber = bnpFromNumber; + BigInteger.prototype.bitwiseTo = bnpBitwiseTo; + BigInteger.prototype.changeBit = bnpChangeBit; + BigInteger.prototype.addTo = bnpAddTo; + BigInteger.prototype.dMultiply = bnpDMultiply; + BigInteger.prototype.dAddOffset = bnpDAddOffset; + BigInteger.prototype.multiplyLowerTo = bnpMultiplyLowerTo; + BigInteger.prototype.multiplyUpperTo = bnpMultiplyUpperTo; + BigInteger.prototype.modInt = bnpModInt; + BigInteger.prototype.millerRabin = bnpMillerRabin; + + // public + BigInteger.prototype.clone = bnClone; + BigInteger.prototype.intValue = bnIntValue; + BigInteger.prototype.byteValue = bnByteValue; + BigInteger.prototype.shortValue = bnShortValue; + BigInteger.prototype.signum = bnSigNum; + BigInteger.prototype.toByteArray = bnToByteArray; + BigInteger.prototype.equals = bnEquals; + BigInteger.prototype.min = bnMin; + BigInteger.prototype.max = bnMax; + BigInteger.prototype.and = bnAnd; + BigInteger.prototype.or = bnOr; + BigInteger.prototype.xor = bnXor; + BigInteger.prototype.andNot = bnAndNot; + BigInteger.prototype.not = bnNot; + BigInteger.prototype.shiftLeft = bnShiftLeft; + BigInteger.prototype.shiftRight = bnShiftRight; + BigInteger.prototype.getLowestSetBit = bnGetLowestSetBit; + BigInteger.prototype.bitCount = bnBitCount; + BigInteger.prototype.testBit = bnTestBit; + BigInteger.prototype.setBit = bnSetBit; + BigInteger.prototype.clearBit = bnClearBit; + BigInteger.prototype.flipBit = bnFlipBit; + BigInteger.prototype.add = bnAdd; + BigInteger.prototype.subtract = bnSubtract; + BigInteger.prototype.multiply = bnMultiply; + BigInteger.prototype.divide = bnDivide; + BigInteger.prototype.remainder = bnRemainder; + BigInteger.prototype.divideAndRemainder = bnDivideAndRemainder; + BigInteger.prototype.modPow = bnModPow; + BigInteger.prototype.modInverse = bnModInverse; + BigInteger.prototype.pow = bnPow; + BigInteger.prototype.gcd = bnGCD; + BigInteger.prototype.isProbablePrime = bnIsProbablePrime; + + // JSBN-specific extension + BigInteger.prototype.square = bnSquare; + + // Expose the Barrett function + BigInteger.prototype.Barrett = Barrett; + + // BigInteger interfaces not implemented in jsbn: + + // BigInteger(int signum, byte[] magnitude) + // double doubleValue() + // float floatValue() + // int hashCode() + // long longValue() + // static BigInteger valueOf(long val) + + // Imported from bitcoinjs-lib + + /** + * Turns a byte array into a big integer. + * + * This function will interpret a byte array as a big integer in big + * endian notation and ignore leading zeros. + */ + + BigInteger.fromByteArrayUnsigned = function (ba) { + + if (!ba.length) { + return new BigInteger.valueOf(0); + } else if (ba[0] & 0x80) { + // Prepend a zero so the BigInteger class doesn't mistake this + // for a negative integer. + return new BigInteger([0].concat(ba)); + } else { + return new BigInteger(ba); + } + }; + + /** + * Parse a signed big integer byte representation. + * + * For details on the format please see BigInteger.toByteArraySigned. + */ + + BigInteger.fromByteArraySigned = function (ba) { + // Check for negative value + if (ba[0] & 0x80) { + // Remove sign bit + ba[0] &= 0x7f; + + return BigInteger.fromByteArrayUnsigned(ba).negate(); + } else { + return BigInteger.fromByteArrayUnsigned(ba); + } + }; + + /** + * Returns a byte array representation of the big integer. + * + * This returns the absolute of the contained value in big endian + * form. A value of zero results in an empty array. + */ + + BigInteger.prototype.toByteArrayUnsigned = function () { + var ba = this.abs().toByteArray(); + + // Empty array, nothing to do + if (!ba.length) { + return ba; + } + + // remove leading 0 + if (ba[0] === 0) { + ba = ba.slice(1); + } + + // all values must be positive + for (var i = 0; i < ba.length; ++i) { + ba[i] = (ba[i] < 0) ? ba[i] + 256 : ba[i]; + } + + return ba; + }; + + /* + * Converts big integer to signed byte representation. + * + * The format for this value uses the most significant bit as a sign + * bit. If the most significant bit is already occupied by the + * absolute value, an extra byte is prepended and the sign bit is set + * there. + * + * Examples: + * + * 0 => 0x00 + * 1 => 0x01 + * -1 => 0x81 + * 127 => 0x7f + * -127 => 0xff + * 128 => 0x0080 + * -128 => 0x8080 + * 255 => 0x00ff + * -255 => 0x80ff + * 16300 => 0x3fac + * -16300 => 0xbfac + * 62300 => 0x00f35c + * -62300 => 0x80f35c + */ + + BigInteger.prototype.toByteArraySigned = function () { + var val = this.toByteArrayUnsigned(); + var neg = this.s < 0; + + // if the first bit is set, we always unshift + // either unshift 0x80 or 0x00 + if (val[0] & 0x80) { + val.unshift((neg) ? 0x80 : 0x00); + } + // if the first bit isn't set, set it if negative + else if (neg) { + val[0] |= 0x80; + } + + return val; + }; + + // Random number generator - requires a PRNG backend, e.g. prng4.js + + // For best results, put code like + // + // in your main HTML document. + + var rng_state; + var rng_pool; + var rng_pptr; + + // Mix in a 32-bit integer into the pool + function rng_seed_int(x) { + rng_pool[rng_pptr++] ^= x & 255; + rng_pool[rng_pptr++] ^= (x >> 8) & 255; + rng_pool[rng_pptr++] ^= (x >> 16) & 255; + rng_pool[rng_pptr++] ^= (x >> 24) & 255; + if (rng_pptr >= rng_psize) rng_pptr -= rng_psize; + } + + // Mix in the current time (w/milliseconds) into the pool + function rng_seed_time() { + rng_seed_int(new Date().getTime()); + } + + // Initialize the pool with junk if needed. + if (rng_pool == null) { + rng_pool = new Array(); + rng_pptr = 0; + var t; + if (typeof window !== 'undefined' && window.crypto) { + if (window.crypto.getRandomValues) { + // Use webcrypto if available + var ua = new Uint8Array(32); + window.crypto.getRandomValues(ua); + for (t = 0; t < 32; ++t) rng_pool[rng_pptr++] = ua[t]; + } else if ( + navigator.appName == 'Netscape' && + navigator.appVersion < '5' + ) { + // Extract entropy (256 bits) from NS4 RNG if available + var z = window.crypto.random(32); + for (t = 0; t < z.length; ++t) + rng_pool[rng_pptr++] = z.charCodeAt(t) & 255; + } + } + while (rng_pptr < rng_psize) { + // extract some randomness from Math.random() + t = Math.floor(65536 * Math.random()); + rng_pool[rng_pptr++] = t >>> 8; + rng_pool[rng_pptr++] = t & 255; + } + rng_pptr = 0; + rng_seed_time(); + } + + function rng_get_byte() { + if (rng_state == null) { + rng_seed_time(); + rng_state = prng_newstate(); + rng_state.init(rng_pool); + for (rng_pptr = 0; rng_pptr < rng_pool.length; ++rng_pptr) + rng_pool[rng_pptr] = 0; + rng_pptr = 0; + } + // TODO: allow reseeding after first request + return rng_state.next(); + } + + function rng_get_bytes(ba) { + var i; + for (i = 0; i < ba.length; ++i) ba[i] = rng_get_byte(); + } + + function SecureRandom() { } + + SecureRandom.prototype.nextBytes = rng_get_bytes; + + // prng4.js - uses Arcfour as a PRNG + function Arcfour() { + this.i = 0; + this.j = 0; + this.S = new Array(); + } + + // Initialize arcfour context from key, an array of ints, each from [0..255] + function ARC4init(key) { + var i, j, t; + for (i = 0; i < 256; ++i) this.S[i] = i; + j = 0; + for (i = 0; i < 256; ++i) { + j = (j + this.S[i] + key[i % key.length]) & 255; + t = this.S[i]; + this.S[i] = this.S[j]; + this.S[j] = t; + } + this.i = 0; + this.j = 0; + } + + function ARC4next() { + var t; + this.i = (this.i + 1) & 255; + this.j = (this.j + this.S[this.i]) & 255; + t = this.S[this.i]; + this.S[this.i] = this.S[this.j]; + this.S[this.j] = t; + return this.S[(t + this.S[this.i]) & 255]; + } + + Arcfour.prototype.init = ARC4init; + Arcfour.prototype.next = ARC4next; + + // Plug in your RNG constructor here + function prng_newstate() { + return new Arcfour(); + } + + // Pool size must be a multiple of 4 and greater than 32. + // An array of bytes the size of the pool will be passed to init() + var rng_psize = 256; + + /*! + * Basic Javascript Elliptic Curve implementation + * Ported loosely from BouncyCastle's Java EC code + * Only Fp curves implemented for now + * + * Copyright Tom Wu, bitaddress.org BSD License. + * http://www-cs-students.stanford.edu/~tjw/jsbn/LICENSE + */ + + // Constructor function of Global EllipticCurve object + var ec = function () { }; + + // ---------------- + // ECFieldElementFp constructor + // q instanceof BigInteger + // x instanceof BigInteger + ec.FieldElementFp = function (q, x) { + this.x = x; + // TODO if(x.compareTo(q) >= 0) error + this.q = q; + }; + + ec.FieldElementFp.prototype.equals = function (other) { + if (other == this) return true; + return (this.q.equals(other.q) && this.x.equals(other.x)); + }; + + ec.FieldElementFp.prototype.toBigInteger = function () { + return this.x; + }; + + ec.FieldElementFp.prototype.negate = function () { + return new ec.FieldElementFp(this.q, this.x.negate().mod(this.q)); + }; + + ec.FieldElementFp.prototype.add = function (b) { + return new ec.FieldElementFp(this.q, this.x.add(b.toBigInteger()).mod(this.q)); + }; + + ec.FieldElementFp.prototype.subtract = function (b) { + return new ec.FieldElementFp(this.q, this.x.subtract(b.toBigInteger()).mod(this.q)); + }; + + ec.FieldElementFp.prototype.multiply = function (b) { + return new ec.FieldElementFp(this.q, this.x.multiply(b.toBigInteger()).mod(this.q)); + }; + + ec.FieldElementFp.prototype.square = function () { + return new ec.FieldElementFp(this.q, this.x.square().mod(this.q)); + }; + + ec.FieldElementFp.prototype.divide = function (b) { + return new ec.FieldElementFp(this.q, this.x.multiply(b.toBigInteger().modInverse(this.q)).mod(this.q)); + }; + + ec.FieldElementFp.prototype.getByteLength = function () { + return Math.floor((this.toBigInteger().bitLength() + 7) / 8); + }; + + // D.1.4 91 /** * return a sqrt root - the routine verifies that the calculation * returns the right value - if none exists it returns null. @@ -2005,530 +1995,526 @@ * Copyright (c) 2000 - 2011 The Legion Of The Bouncy Castle (http://www.bouncycastle.org) * Ported to JavaScript by bitaddress.org */ - ec.FieldElementFp.prototype.sqrt = function () { - if (!this.q.testBit(0)) throw new Error("even value of q"); + ec.FieldElementFp.prototype.sqrt = function () { + if (!this.q.testBit(0)) throw new Error("even value of q"); - // p mod 4 == 3 - if (this.q.testBit(1)) { - // z = g^(u+1) + p, p = 4u + 3 - var z = new ec.FieldElementFp(this.q, this.x.modPow(this.q.shiftRight(2).add(BigInteger.ONE), this.q)); - return z.square().equals(this) ? z : null; - } + // p mod 4 == 3 + if (this.q.testBit(1)) { + // z = g^(u+1) + p, p = 4u + 3 + var z = new ec.FieldElementFp(this.q, this.x.modPow(this.q.shiftRight(2).add(BigInteger.ONE), this.q)); + return z.square().equals(this) ? z : null; + } - // p mod 4 == 1 - var qMinusOne = this.q.subtract(BigInteger.ONE); - var legendreExponent = qMinusOne.shiftRight(1); - if (!(this.x.modPow(legendreExponent, this.q).equals(BigInteger.ONE))) return null; - var u = qMinusOne.shiftRight(2); - var k = u.shiftLeft(1).add(BigInteger.ONE); - var Q = this.x; - var fourQ = Q.shiftLeft(2).mod(this.q); - var U, V; + // p mod 4 == 1 + var qMinusOne = this.q.subtract(BigInteger.ONE); + var legendreExponent = qMinusOne.shiftRight(1); + if (!(this.x.modPow(legendreExponent, this.q).equals(BigInteger.ONE))) return null; + var u = qMinusOne.shiftRight(2); + var k = u.shiftLeft(1).add(BigInteger.ONE); + var Q = this.x; + var fourQ = Q.shiftLeft(2).mod(this.q); + var U, V; - do { - var rand = new SecureRandom(); - var P; - do { - P = new BigInteger(this.q.bitLength(), rand); - } - while (P.compareTo(this.q) >= 0 || !(P.multiply(P).subtract(fourQ).modPow(legendreExponent, this.q).equals(qMinusOne))); + do { + var rand = new SecureRandom(); + var P; + do { + P = new BigInteger(this.q.bitLength(), rand); + } + while (P.compareTo(this.q) >= 0 || !(P.multiply(P).subtract(fourQ).modPow(legendreExponent, this.q).equals(qMinusOne))); - var result = ec.FieldElementFp.fastLucasSequence(this.q, P, Q, k); + var result = ec.FieldElementFp.fastLucasSequence(this.q, P, Q, k); - U = result[0]; - V = result[1]; - if (V.multiply(V).mod(this.q).equals(fourQ)) { - // Integer division by 2, mod q - if (V.testBit(0)) { - V = V.add(this.q); - } - V = V.shiftRight(1); - return new ec.FieldElementFp(this.q, V); - } - } - while (U.equals(BigInteger.ONE) || U.equals(qMinusOne)); + U = result[0]; + V = result[1]; + if (V.multiply(V).mod(this.q).equals(fourQ)) { + // Integer division by 2, mod q + if (V.testBit(0)) { + V = V.add(this.q); + } + V = V.shiftRight(1); + return new ec.FieldElementFp(this.q, V); + } + } + while (U.equals(BigInteger.ONE) || U.equals(qMinusOne)); - return null; - }; + return null; + }; /* * Copyright (c) 2000 - 2011 The Legion Of The Bouncy Castle (http://www.bouncycastle.org) * Ported to JavaScript by bitaddress.org */ - ec.FieldElementFp.fastLucasSequence = function (p, P, Q, k) { - // TODO Research and apply "common-multiplicand multiplication here" + ec.FieldElementFp.fastLucasSequence = function (p, P, Q, k) { + // TODO Research and apply "common-multiplicand multiplication here" - var n = k.bitLength(); - var s = k.getLowestSetBit(); - var Uh = BigInteger.ONE; - var Vl = BigInteger.TWO; - var Vh = P; - var Ql = BigInteger.ONE; - var Qh = BigInteger.ONE; + var n = k.bitLength(); + var s = k.getLowestSetBit(); + var Uh = BigInteger.ONE; + var Vl = BigInteger.TWO; + var Vh = P; + var Ql = BigInteger.ONE; + var Qh = BigInteger.ONE; - for (var j = n - 1; j >= s + 1; --j) { - Ql = Ql.multiply(Qh).mod(p); - if (k.testBit(j)) { - Qh = Ql.multiply(Q).mod(p); - Uh = Uh.multiply(Vh).mod(p); - Vl = Vh.multiply(Vl).subtract(P.multiply(Ql)).mod(p); - Vh = Vh.multiply(Vh).subtract(Qh.shiftLeft(1)).mod(p); - } - else { - Qh = Ql; - Uh = Uh.multiply(Vl).subtract(Ql).mod(p); - Vh = Vh.multiply(Vl).subtract(P.multiply(Ql)).mod(p); - Vl = Vl.multiply(Vl).subtract(Ql.shiftLeft(1)).mod(p); - } - } + for (var j = n - 1; j >= s + 1; --j) { + Ql = Ql.multiply(Qh).mod(p); + if (k.testBit(j)) { + Qh = Ql.multiply(Q).mod(p); + Uh = Uh.multiply(Vh).mod(p); + Vl = Vh.multiply(Vl).subtract(P.multiply(Ql)).mod(p); + Vh = Vh.multiply(Vh).subtract(Qh.shiftLeft(1)).mod(p); + } + else { + Qh = Ql; + Uh = Uh.multiply(Vl).subtract(Ql).mod(p); + Vh = Vh.multiply(Vl).subtract(P.multiply(Ql)).mod(p); + Vl = Vl.multiply(Vl).subtract(Ql.shiftLeft(1)).mod(p); + } + } - Ql = Ql.multiply(Qh).mod(p); - Qh = Ql.multiply(Q).mod(p); - Uh = Uh.multiply(Vl).subtract(Ql).mod(p); - Vl = Vh.multiply(Vl).subtract(P.multiply(Ql)).mod(p); - Ql = Ql.multiply(Qh).mod(p); + Ql = Ql.multiply(Qh).mod(p); + Qh = Ql.multiply(Q).mod(p); + Uh = Uh.multiply(Vl).subtract(Ql).mod(p); + Vl = Vh.multiply(Vl).subtract(P.multiply(Ql)).mod(p); + Ql = Ql.multiply(Qh).mod(p); - for (var j = 1; j <= s; ++j) { - Uh = Uh.multiply(Vl).mod(p); - Vl = Vl.multiply(Vl).subtract(Ql.shiftLeft(1)).mod(p); - Ql = Ql.multiply(Ql).mod(p); - } + for (var j = 1; j <= s; ++j) { + Uh = Uh.multiply(Vl).mod(p); + Vl = Vl.multiply(Vl).subtract(Ql.shiftLeft(1)).mod(p); + Ql = Ql.multiply(Ql).mod(p); + } - return [Uh, Vl]; - }; + return [Uh, Vl]; + }; - // ---------------- - // ECPointFp constructor - ec.PointFp = function (curve, x, y, z, compressed) { - this.curve = curve; - this.x = x; - this.y = y; - // Projective coordinates: either zinv == null or z * zinv == 1 - // z and zinv are just BigIntegers, not fieldElements - if (z == null) { - this.z = BigInteger.ONE; - } - else { - this.z = z; - } - this.zinv = null; - // compression flag - this.compressed = !!compressed; - }; + // ---------------- + // ECPointFp constructor + ec.PointFp = function (curve, x, y, z, compressed) { + this.curve = curve; + this.x = x; + this.y = y; + // Projective coordinates: either zinv == null or z * zinv == 1 + // z and zinv are just BigIntegers, not fieldElements + if (z == null) { + this.z = BigInteger.ONE; + } + else { + this.z = z; + } + this.zinv = null; + // compression flag + this.compressed = !!compressed; + }; - ec.PointFp.prototype.getX = function () { - if (this.zinv == null) { - this.zinv = this.z.modInverse(this.curve.q); - } - var r = this.x.toBigInteger().multiply(this.zinv); - this.curve.reduce(r); - return this.curve.fromBigInteger(r); - }; + ec.PointFp.prototype.getX = function () { + if (this.zinv == null) { + this.zinv = this.z.modInverse(this.curve.q); + } + var r = this.x.toBigInteger().multiply(this.zinv); + this.curve.reduce(r); + return this.curve.fromBigInteger(r); + }; - ec.PointFp.prototype.getY = function () { - if (this.zinv == null) { - this.zinv = this.z.modInverse(this.curve.q); - } - var r = this.y.toBigInteger().multiply(this.zinv); - this.curve.reduce(r); - return this.curve.fromBigInteger(r); - }; + ec.PointFp.prototype.getY = function () { + if (this.zinv == null) { + this.zinv = this.z.modInverse(this.curve.q); + } + var r = this.y.toBigInteger().multiply(this.zinv); + this.curve.reduce(r); + return this.curve.fromBigInteger(r); + }; - ec.PointFp.prototype.equals = function (other) { - if (other == this) return true; - if (this.isInfinity()) return other.isInfinity(); - if (other.isInfinity()) return this.isInfinity(); - var u, v; - // u = Y2 * Z1 - Y1 * Z2 - u = other.y.toBigInteger().multiply(this.z).subtract(this.y.toBigInteger().multiply(other.z)).mod(this.curve.q); - if (!u.equals(BigInteger.ZERO)) return false; - // v = X2 * Z1 - X1 * Z2 - v = other.x.toBigInteger().multiply(this.z).subtract(this.x.toBigInteger().multiply(other.z)).mod(this.curve.q); - return v.equals(BigInteger.ZERO); - }; + ec.PointFp.prototype.equals = function (other) { + if (other == this) return true; + if (this.isInfinity()) return other.isInfinity(); + if (other.isInfinity()) return this.isInfinity(); + var u, v; + // u = Y2 * Z1 - Y1 * Z2 + u = other.y.toBigInteger().multiply(this.z).subtract(this.y.toBigInteger().multiply(other.z)).mod(this.curve.q); + if (!u.equals(BigInteger.ZERO)) return false; + // v = X2 * Z1 - X1 * Z2 + v = other.x.toBigInteger().multiply(this.z).subtract(this.x.toBigInteger().multiply(other.z)).mod(this.curve.q); + return v.equals(BigInteger.ZERO); + }; - ec.PointFp.prototype.isInfinity = function () { - if ((this.x == null) && (this.y == null)) return true; - return this.z.equals(BigInteger.ZERO) && !this.y.toBigInteger().equals(BigInteger.ZERO); - }; + ec.PointFp.prototype.isInfinity = function () { + if ((this.x == null) && (this.y == null)) return true; + return this.z.equals(BigInteger.ZERO) && !this.y.toBigInteger().equals(BigInteger.ZERO); + }; - ec.PointFp.prototype.negate = function () { - return new ec.PointFp(this.curve, this.x, this.y.negate(), this.z); - }; + ec.PointFp.prototype.negate = function () { + return new ec.PointFp(this.curve, this.x, this.y.negate(), this.z); + }; - ec.PointFp.prototype.add = function (b) { - if (this.isInfinity()) return b; - if (b.isInfinity()) return this; + ec.PointFp.prototype.add = function (b) { + if (this.isInfinity()) return b; + if (b.isInfinity()) return this; - // u = Y2 * Z1 - Y1 * Z2 - var u = b.y.toBigInteger().multiply(this.z).subtract(this.y.toBigInteger().multiply(b.z)).mod(this.curve.q); - // v = X2 * Z1 - X1 * Z2 - var v = b.x.toBigInteger().multiply(this.z).subtract(this.x.toBigInteger().multiply(b.z)).mod(this.curve.q); + // u = Y2 * Z1 - Y1 * Z2 + var u = b.y.toBigInteger().multiply(this.z).subtract(this.y.toBigInteger().multiply(b.z)).mod(this.curve.q); + // v = X2 * Z1 - X1 * Z2 + var v = b.x.toBigInteger().multiply(this.z).subtract(this.x.toBigInteger().multiply(b.z)).mod(this.curve.q); - if (BigInteger.ZERO.equals(v)) { - if (BigInteger.ZERO.equals(u)) { - return this.twice(); // this == b, so double - } - return this.curve.getInfinity(); // this = -b, so infinity - } + if (BigInteger.ZERO.equals(v)) { + if (BigInteger.ZERO.equals(u)) { + return this.twice(); // this == b, so double + } + return this.curve.getInfinity(); // this = -b, so infinity + } - var THREE = new BigInteger("3"); - var x1 = this.x.toBigInteger(); - var y1 = this.y.toBigInteger(); - var x2 = b.x.toBigInteger(); - var y2 = b.y.toBigInteger(); + var THREE = new BigInteger("3"); + var x1 = this.x.toBigInteger(); + var y1 = this.y.toBigInteger(); + var x2 = b.x.toBigInteger(); + var y2 = b.y.toBigInteger(); - var v2 = v.square(); - var v3 = v2.multiply(v); - var x1v2 = x1.multiply(v2); - var zu2 = u.square().multiply(this.z); + var v2 = v.square(); + var v3 = v2.multiply(v); + var x1v2 = x1.multiply(v2); + var zu2 = u.square().multiply(this.z); - // x3 = v * (z2 * (z1 * u^2 - 2 * x1 * v^2) - v^3) - var x3 = zu2.subtract(x1v2.shiftLeft(1)).multiply(b.z).subtract(v3).multiply(v).mod(this.curve.q); - // y3 = z2 * (3 * x1 * u * v^2 - y1 * v^3 - z1 * u^3) + u * v^3 - var y3 = x1v2.multiply(THREE).multiply(u).subtract(y1.multiply(v3)).subtract(zu2.multiply(u)).multiply(b.z).add(u.multiply(v3)).mod(this.curve.q); - // z3 = v^3 * z1 * z2 - var z3 = v3.multiply(this.z).multiply(b.z).mod(this.curve.q); + // x3 = v * (z2 * (z1 * u^2 - 2 * x1 * v^2) - v^3) + var x3 = zu2.subtract(x1v2.shiftLeft(1)).multiply(b.z).subtract(v3).multiply(v).mod(this.curve.q); + // y3 = z2 * (3 * x1 * u * v^2 - y1 * v^3 - z1 * u^3) + u * v^3 + var y3 = x1v2.multiply(THREE).multiply(u).subtract(y1.multiply(v3)).subtract(zu2.multiply(u)).multiply(b.z).add(u.multiply(v3)).mod(this.curve.q); + // z3 = v^3 * z1 * z2 + var z3 = v3.multiply(this.z).multiply(b.z).mod(this.curve.q); - return new ec.PointFp(this.curve, this.curve.fromBigInteger(x3), this.curve.fromBigInteger(y3), z3); - }; + return new ec.PointFp(this.curve, this.curve.fromBigInteger(x3), this.curve.fromBigInteger(y3), z3); + }; - ec.PointFp.prototype.twice = function () { - if (this.isInfinity()) return this; - if (this.y.toBigInteger().signum() == 0) return this.curve.getInfinity(); + ec.PointFp.prototype.twice = function () { + if (this.isInfinity()) return this; + if (this.y.toBigInteger().signum() == 0) return this.curve.getInfinity(); - // TODO: optimized handling of constants - var THREE = new BigInteger("3"); - var x1 = this.x.toBigInteger(); - var y1 = this.y.toBigInteger(); + // TODO: optimized handling of constants + var THREE = new BigInteger("3"); + var x1 = this.x.toBigInteger(); + var y1 = this.y.toBigInteger(); - var y1z1 = y1.multiply(this.z); - var y1sqz1 = y1z1.multiply(y1).mod(this.curve.q); - var a = this.curve.a.toBigInteger(); + var y1z1 = y1.multiply(this.z); + var y1sqz1 = y1z1.multiply(y1).mod(this.curve.q); + var a = this.curve.a.toBigInteger(); - // w = 3 * x1^2 + a * z1^2 - var w = x1.square().multiply(THREE); - if (!BigInteger.ZERO.equals(a)) { - w = w.add(this.z.square().multiply(a)); - } - w = w.mod(this.curve.q); - //this.curve.reduce(w); - // x3 = 2 * y1 * z1 * (w^2 - 8 * x1 * y1^2 * z1) - var x3 = w.square().subtract(x1.shiftLeft(3).multiply(y1sqz1)).shiftLeft(1).multiply(y1z1).mod(this.curve.q); - // y3 = 4 * y1^2 * z1 * (3 * w * x1 - 2 * y1^2 * z1) - w^3 - var y3 = w.multiply(THREE).multiply(x1).subtract(y1sqz1.shiftLeft(1)).shiftLeft(2).multiply(y1sqz1).subtract(w.square().multiply(w)).mod(this.curve.q); - // z3 = 8 * (y1 * z1)^3 - var z3 = y1z1.square().multiply(y1z1).shiftLeft(3).mod(this.curve.q); + // w = 3 * x1^2 + a * z1^2 + var w = x1.square().multiply(THREE); + if (!BigInteger.ZERO.equals(a)) { + w = w.add(this.z.square().multiply(a)); + } + w = w.mod(this.curve.q); + //this.curve.reduce(w); + // x3 = 2 * y1 * z1 * (w^2 - 8 * x1 * y1^2 * z1) + var x3 = w.square().subtract(x1.shiftLeft(3).multiply(y1sqz1)).shiftLeft(1).multiply(y1z1).mod(this.curve.q); + // y3 = 4 * y1^2 * z1 * (3 * w * x1 - 2 * y1^2 * z1) - w^3 + var y3 = w.multiply(THREE).multiply(x1).subtract(y1sqz1.shiftLeft(1)).shiftLeft(2).multiply(y1sqz1).subtract(w.square().multiply(w)).mod(this.curve.q); + // z3 = 8 * (y1 * z1)^3 + var z3 = y1z1.square().multiply(y1z1).shiftLeft(3).mod(this.curve.q); - return new ec.PointFp(this.curve, this.curve.fromBigInteger(x3), this.curve.fromBigInteger(y3), z3); - }; + return new ec.PointFp(this.curve, this.curve.fromBigInteger(x3), this.curve.fromBigInteger(y3), z3); + }; - // Simple NAF (Non-Adjacent Form) multiplication algorithm - // TODO: modularize the multiplication algorithm - ec.PointFp.prototype.multiply = function (k) { - if (this.isInfinity()) return this; - if (k.signum() == 0) return this.curve.getInfinity(); + // Simple NAF (Non-Adjacent Form) multiplication algorithm + // TODO: modularize the multiplication algorithm + ec.PointFp.prototype.multiply = function (k) { + if (this.isInfinity()) return this; + if (k.signum() == 0) return this.curve.getInfinity(); - var e = k; - var h = e.multiply(new BigInteger("3")); + var e = k; + var h = e.multiply(new BigInteger("3")); - var neg = this.negate(); - var R = this; + var neg = this.negate(); + var R = this; - var i; - for (i = h.bitLength() - 2; i > 0; --i) { - R = R.twice(); + var i; + for (i = h.bitLength() - 2; i > 0; --i) { + R = R.twice(); - var hBit = h.testBit(i); - var eBit = e.testBit(i); + var hBit = h.testBit(i); + var eBit = e.testBit(i); - if (hBit != eBit) { - R = R.add(hBit ? this : neg); - } - } + if (hBit != eBit) { + R = R.add(hBit ? this : neg); + } + } - return R; - }; + return R; + }; - // Compute this*j + x*k (simultaneous multiplication) - ec.PointFp.prototype.multiplyTwo = function (j, x, k) { - var i; - if (j.bitLength() > k.bitLength()) - i = j.bitLength() - 1; - else - i = k.bitLength() - 1; + // Compute this*j + x*k (simultaneous multiplication) + ec.PointFp.prototype.multiplyTwo = function (j, x, k) { + var i; + if (j.bitLength() > k.bitLength()) + i = j.bitLength() - 1; + else + i = k.bitLength() - 1; - var R = this.curve.getInfinity(); - var both = this.add(x); - while (i >= 0) { - R = R.twice(); - if (j.testBit(i)) { - if (k.testBit(i)) { - R = R.add(both); - } - else { - R = R.add(this); - } - } - else { - if (k.testBit(i)) { - R = R.add(x); - } - } - --i; - } + var R = this.curve.getInfinity(); + var both = this.add(x); + while (i >= 0) { + R = R.twice(); + if (j.testBit(i)) { + if (k.testBit(i)) { + R = R.add(both); + } + else { + R = R.add(this); + } + } + else { + if (k.testBit(i)) { + R = R.add(x); + } + } + --i; + } - return R; - }; + return R; + }; - // patched by bitaddress.org and Casascius for use with Bitcoin.ECKey - // patched by coretechs to support compressed public keys - ec.PointFp.prototype.getEncoded = function (compressed) { - var x = this.getX().toBigInteger(); - var y = this.getY().toBigInteger(); - var len = 32; // integerToBytes will zero pad if integer is less than 32 bytes. 32 bytes length is required by the Bitcoin protocol. - var enc = ec.integerToBytes(x, len); + // patched by bitaddress.org and Casascius for use with Bitcoin.ECKey + // patched by coretechs to support compressed public keys + ec.PointFp.prototype.getEncoded = function (compressed) { + var x = this.getX().toBigInteger(); + var y = this.getY().toBigInteger(); + var len = 32; // integerToBytes will zero pad if integer is less than 32 bytes. 32 bytes length is required by the Bitcoin protocol. + var enc = ec.integerToBytes(x, len); - // when compressed prepend byte depending if y point is even or odd - if (compressed) { - if (y.isEven()) { - enc.unshift(0x02); - } - else { - enc.unshift(0x03); - } - } - else { - enc.unshift(0x04); - enc = enc.concat(ec.integerToBytes(y, len)); // uncompressed public key appends the bytes of the y point - } - return enc; - }; + // when compressed prepend byte depending if y point is even or odd + if (compressed) { + if (y.isEven()) { + enc.unshift(0x02); + } + else { + enc.unshift(0x03); + } + } + else { + enc.unshift(0x04); + enc = enc.concat(ec.integerToBytes(y, len)); // uncompressed public key appends the bytes of the y point + } + return enc; + }; - ec.PointFp.decodeFrom = function (curve, enc) { - var type = enc[0]; - var dataLen = enc.length - 1; + ec.PointFp.decodeFrom = function (curve, enc) { + var type = enc[0]; + var dataLen = enc.length - 1; - // Extract x and y as byte arrays - var xBa = enc.slice(1, 1 + dataLen / 2); - var yBa = enc.slice(1 + dataLen / 2, 1 + dataLen); + // Extract x and y as byte arrays + var xBa = enc.slice(1, 1 + dataLen / 2); + var yBa = enc.slice(1 + dataLen / 2, 1 + dataLen); - // Prepend zero byte to prevent interpretation as negative integer - xBa.unshift(0); - yBa.unshift(0); + // Prepend zero byte to prevent interpretation as negative integer + xBa.unshift(0); + yBa.unshift(0); - // Convert to BigIntegers - var x = new BigInteger(xBa); - var y = new BigInteger(yBa); + // Convert to BigIntegers + var x = new BigInteger(xBa); + var y = new BigInteger(yBa); - // Return point - return new ec.PointFp(curve, curve.fromBigInteger(x), curve.fromBigInteger(y)); - }; + // Return point + return new ec.PointFp(curve, curve.fromBigInteger(x), curve.fromBigInteger(y)); + }; - ec.PointFp.prototype.add2D = function (b) { - if (this.isInfinity()) return b; - if (b.isInfinity()) return this; + ec.PointFp.prototype.add2D = function (b) { + if (this.isInfinity()) return b; + if (b.isInfinity()) return this; - if (this.x.equals(b.x)) { - if (this.y.equals(b.y)) { - // this = b, i.e. this must be doubled - return this.twice(); - } - // this = -b, i.e. the result is the point at infinity - return this.curve.getInfinity(); - } + if (this.x.equals(b.x)) { + if (this.y.equals(b.y)) { + // this = b, i.e. this must be doubled + return this.twice(); + } + // this = -b, i.e. the result is the point at infinity + return this.curve.getInfinity(); + } - var x_x = b.x.subtract(this.x); - var y_y = b.y.subtract(this.y); - var gamma = y_y.divide(x_x); + var x_x = b.x.subtract(this.x); + var y_y = b.y.subtract(this.y); + var gamma = y_y.divide(x_x); - var x3 = gamma.square().subtract(this.x).subtract(b.x); - var y3 = gamma.multiply(this.x.subtract(x3)).subtract(this.y); + var x3 = gamma.square().subtract(this.x).subtract(b.x); + var y3 = gamma.multiply(this.x.subtract(x3)).subtract(this.y); - return new ec.PointFp(this.curve, x3, y3); - }; + return new ec.PointFp(this.curve, x3, y3); + }; - ec.PointFp.prototype.twice2D = function () { - if (this.isInfinity()) return this; - if (this.y.toBigInteger().signum() == 0) { - // if y1 == 0, then (x1, y1) == (x1, -y1) - // and hence this = -this and thus 2(x1, y1) == infinity - return this.curve.getInfinity(); - } + ec.PointFp.prototype.twice2D = function () { + if (this.isInfinity()) return this; + if (this.y.toBigInteger().signum() == 0) { + // if y1 == 0, then (x1, y1) == (x1, -y1) + // and hence this = -this and thus 2(x1, y1) == infinity + return this.curve.getInfinity(); + } - var TWO = this.curve.fromBigInteger(BigInteger.valueOf(2)); - var THREE = this.curve.fromBigInteger(BigInteger.valueOf(3)); - var gamma = this.x.square().multiply(THREE).add(this.curve.a).divide(this.y.multiply(TWO)); + var TWO = this.curve.fromBigInteger(BigInteger.valueOf(2)); + var THREE = this.curve.fromBigInteger(BigInteger.valueOf(3)); + var gamma = this.x.square().multiply(THREE).add(this.curve.a).divide(this.y.multiply(TWO)); - var x3 = gamma.square().subtract(this.x.multiply(TWO)); - var y3 = gamma.multiply(this.x.subtract(x3)).subtract(this.y); + var x3 = gamma.square().subtract(this.x.multiply(TWO)); + var y3 = gamma.multiply(this.x.subtract(x3)).subtract(this.y); - return new ec.PointFp(this.curve, x3, y3); - }; + return new ec.PointFp(this.curve, x3, y3); + }; - ec.PointFp.prototype.multiply2D = function (k) { - if (this.isInfinity()) return this; - if (k.signum() == 0) return this.curve.getInfinity(); + ec.PointFp.prototype.multiply2D = function (k) { + if (this.isInfinity()) return this; + if (k.signum() == 0) return this.curve.getInfinity(); - var e = k; - var h = e.multiply(new BigInteger("3")); + var e = k; + var h = e.multiply(new BigInteger("3")); - var neg = this.negate(); - var R = this; + var neg = this.negate(); + var R = this; - var i; - for (i = h.bitLength() - 2; i > 0; --i) { - R = R.twice(); + var i; + for (i = h.bitLength() - 2; i > 0; --i) { + R = R.twice(); - var hBit = h.testBit(i); - var eBit = e.testBit(i); + var hBit = h.testBit(i); + var eBit = e.testBit(i); - if (hBit != eBit) { - R = R.add2D(hBit ? this : neg); - } - } + if (hBit != eBit) { + R = R.add2D(hBit ? this : neg); + } + } - return R; - }; + return R; + }; + ec.PointFp.prototype.isOnCurve = function () { + var x = this.getX().toBigInteger(); + var y = this.getY().toBigInteger(); + var a = this.curve.getA().toBigInteger(); + var b = this.curve.getB().toBigInteger(); + var n = this.curve.getQ(); + var lhs = y.multiply(y).mod(n); + var rhs = x.multiply(x).multiply(x).add(a.multiply(x)).add(b).mod(n); + return lhs.equals(rhs); + }; - ec.PointFp.prototype.isOnCurve = function () { - var x = this.getX().toBigInteger(); - var y = this.getY().toBigInteger(); - var a = this.curve.getA().toBigInteger(); - var b = this.curve.getB().toBigInteger(); - var n = this.curve.getQ(); - var lhs = y.multiply(y).mod(n); - var rhs = x.multiply(x).multiply(x).add(a.multiply(x)).add(b).mod(n); - return lhs.equals(rhs); - }; - - ec.PointFp.prototype.toString = function () { - return '(' + this.getX().toBigInteger().toString() + ',' + this.getY().toBigInteger().toString() + ')'; - }; + ec.PointFp.prototype.toString = function () { + return '(' + this.getX().toBigInteger().toString() + ',' + this.getY().toBigInteger().toString() + ')'; + }; /** * Validate an elliptic curve point. * * See SEC 1, section 3.2.2.1: Elliptic Curve Public Key Validation Primitive */ - ec.PointFp.prototype.validate = function () { - var n = this.curve.getQ(); + ec.PointFp.prototype.validate = function () { + var n = this.curve.getQ(); - // Check Q != O - if (this.isInfinity()) { - throw new Error("Point is at infinity."); - } + // Check Q != O + if (this.isInfinity()) { + throw new Error("Point is at infinity."); + } - // Check coordinate bounds - var x = this.getX().toBigInteger(); - var y = this.getY().toBigInteger(); - if (x.compareTo(BigInteger.ONE) < 0 || x.compareTo(n.subtract(BigInteger.ONE)) > 0) { - throw new Error('x coordinate out of bounds'); - } - if (y.compareTo(BigInteger.ONE) < 0 || y.compareTo(n.subtract(BigInteger.ONE)) > 0) { - throw new Error('y coordinate out of bounds'); - } + // Check coordinate bounds + var x = this.getX().toBigInteger(); + var y = this.getY().toBigInteger(); + if (x.compareTo(BigInteger.ONE) < 0 || x.compareTo(n.subtract(BigInteger.ONE)) > 0) { + throw new Error('x coordinate out of bounds'); + } + if (y.compareTo(BigInteger.ONE) < 0 || y.compareTo(n.subtract(BigInteger.ONE)) > 0) { + throw new Error('y coordinate out of bounds'); + } - // Check y^2 = x^3 + ax + b (mod n) - if (!this.isOnCurve()) { - throw new Error("Point is not on the curve."); - } + // Check y^2 = x^3 + ax + b (mod n) + if (!this.isOnCurve()) { + throw new Error("Point is not on the curve."); + } - // Check nQ = 0 (Q is a scalar multiple of G) - if (this.multiply(n).isInfinity()) { - // TODO: This check doesn't work - fix. - throw new Error("Point is not a scalar multiple of G."); - } + // Check nQ = 0 (Q is a scalar multiple of G) + if (this.multiply(n).isInfinity()) { + // TODO: This check doesn't work - fix. + throw new Error("Point is not a scalar multiple of G."); + } - return true; - }; + return true; + }; + // ---------------- + // ECCurveFp constructor + ec.CurveFp = function (q, a, b) { + this.q = q; + this.a = this.fromBigInteger(a); + this.b = this.fromBigInteger(b); + this.infinity = new ec.PointFp(this, null, null); + this.reducer = new Barrett(this.q); + } + ec.CurveFp.prototype.getQ = function () { + return this.q; + }; + ec.CurveFp.prototype.getA = function () { + return this.a; + }; - // ---------------- - // ECCurveFp constructor - ec.CurveFp = function (q, a, b) { - this.q = q; - this.a = this.fromBigInteger(a); - this.b = this.fromBigInteger(b); - this.infinity = new ec.PointFp(this, null, null); - this.reducer = new Barrett(this.q); - } + ec.CurveFp.prototype.getB = function () { + return this.b; + }; - ec.CurveFp.prototype.getQ = function () { - return this.q; - }; + ec.CurveFp.prototype.equals = function (other) { + if (other == this) return true; + return (this.q.equals(other.q) && this.a.equals(other.a) && this.b.equals(other.b)); + }; - ec.CurveFp.prototype.getA = function () { - return this.a; - }; + ec.CurveFp.prototype.getInfinity = function () { + return this.infinity; + }; - ec.CurveFp.prototype.getB = function () { - return this.b; - }; + ec.CurveFp.prototype.fromBigInteger = function (x) { + return new ec.FieldElementFp(this.q, x); + }; - ec.CurveFp.prototype.equals = function (other) { - if (other == this) return true; - return (this.q.equals(other.q) && this.a.equals(other.a) && this.b.equals(other.b)); - }; + ec.CurveFp.prototype.reduce = function (x) { + this.reducer.reduce(x); + }; - ec.CurveFp.prototype.getInfinity = function () { - return this.infinity; - }; + // for now, work with hex strings because they're easier in JS + // compressed support added by bitaddress.org + ec.CurveFp.prototype.decodePointHex = function (s) { + var firstByte = parseInt(s.substr(0, 2), 16); + switch (firstByte) { // first byte + case 0: + return this.infinity; + case 2: // compressed + case 3: // compressed + var yTilde = firstByte & 1; + var xHex = s.substr(2, s.length - 2); + var X1 = new BigInteger(xHex, 16); + return this.decompressPoint(yTilde, X1); + case 4: // uncompressed + case 6: // hybrid + case 7: // hybrid + var len = (s.length - 2) / 2; + var xHex = s.substr(2, len); + var yHex = s.substr(len + 2, len); - ec.CurveFp.prototype.fromBigInteger = function (x) { - return new ec.FieldElementFp(this.q, x); - }; + return new ec.PointFp(this, + this.fromBigInteger(new BigInteger(xHex, 16)), + this.fromBigInteger(new BigInteger(yHex, 16))); - ec.CurveFp.prototype.reduce = function (x) { - this.reducer.reduce(x); - }; + default: // unsupported + return null; + } + }; - // for now, work with hex strings because they're easier in JS - // compressed support added by bitaddress.org - ec.CurveFp.prototype.decodePointHex = function (s) { - var firstByte = parseInt(s.substr(0, 2), 16); - switch (firstByte) { // first byte - case 0: - return this.infinity; - case 2: // compressed - case 3: // compressed - var yTilde = firstByte & 1; - var xHex = s.substr(2, s.length - 2); - var X1 = new BigInteger(xHex, 16); - return this.decompressPoint(yTilde, X1); - case 4: // uncompressed - case 6: // hybrid - case 7: // hybrid - var len = (s.length - 2) / 2; - var xHex = s.substr(2, len); - var yHex = s.substr(len + 2, len); - - return new ec.PointFp(this, - this.fromBigInteger(new BigInteger(xHex, 16)), - this.fromBigInteger(new BigInteger(yHex, 16))); - - default: // unsupported - return null; - } - }; - - ec.CurveFp.prototype.encodePointHex = function (p) { - if (p.isInfinity()) return "00"; - var xHex = p.getX().toBigInteger().toString(16); - var yHex = p.getY().toBigInteger().toString(16); - var oLen = this.getQ().toString(16).length; - if ((oLen % 2) != 0) oLen++; - while (xHex.length < oLen) { - xHex = "0" + xHex; - } - while (yHex.length < oLen) { - yHex = "0" + yHex; - } - return "04" + xHex + yHex; - }; + ec.CurveFp.prototype.encodePointHex = function (p) { + if (p.isInfinity()) return "00"; + var xHex = p.getX().toBigInteger().toString(16); + var yHex = p.getY().toBigInteger().toString(16); + var oLen = this.getQ().toString(16).length; + if ((oLen % 2) != 0) oLen++; + while (xHex.length < oLen) { + xHex = "0" + xHex; + } + while (yHex.length < oLen) { + yHex = "0" + yHex; + } + return "04" + xHex + yHex; + }; /* * Copyright (c) 2000 - 2011 The Legion Of The Bouncy Castle (http://www.bouncycastle.org) @@ -2537,84 +2523,84 @@ * Number yTilde * BigInteger X1 */ - ec.CurveFp.prototype.decompressPoint = function (yTilde, X1) { - var x = this.fromBigInteger(X1); - var alpha = x.multiply(x.square().add(this.getA())).add(this.getB()); - var beta = alpha.sqrt(); - // if we can't find a sqrt we haven't got a point on the curve - run! - if (beta == null) throw new Error("Invalid point compression"); - var betaValue = beta.toBigInteger(); - var bit0 = betaValue.testBit(0) ? 1 : 0; - if (bit0 != yTilde) { - // Use the other root - beta = this.fromBigInteger(this.getQ().subtract(betaValue)); - } - return new ec.PointFp(this, x, beta, null, true); - }; + ec.CurveFp.prototype.decompressPoint = function (yTilde, X1) { + var x = this.fromBigInteger(X1); + var alpha = x.multiply(x.square().add(this.getA())).add(this.getB()); + var beta = alpha.sqrt(); + // if we can't find a sqrt we haven't got a point on the curve - run! + if (beta == null) throw new Error("Invalid point compression"); + var betaValue = beta.toBigInteger(); + var bit0 = betaValue.testBit(0) ? 1 : 0; + if (bit0 != yTilde) { + // Use the other root + beta = this.fromBigInteger(this.getQ().subtract(betaValue)); + } + return new ec.PointFp(this, x, beta, null, true); + }; - ec.fromHex = function (s) { return new BigInteger(s, 16); }; + ec.fromHex = function (s) { return new BigInteger(s, 16); }; - ec.integerToBytes = function (i, len) { - var bytes = i.toByteArrayUnsigned(); - if (len < bytes.length) { - bytes = bytes.slice(bytes.length - len); - } else while (len > bytes.length) { - bytes.unshift(0); - } - return bytes; - }; + ec.integerToBytes = function (i, len) { + var bytes = i.toByteArrayUnsigned(); + if (len < bytes.length) { + bytes = bytes.slice(bytes.length - len); + } else while (len > bytes.length) { + bytes.unshift(0); + } + return bytes; + }; - // Named EC curves - // ---------------- - // X9ECParameters constructor - ec.X9Parameters = function (curve, g, n, h) { - this.curve = curve; - this.g = g; - this.n = n; - this.h = h; - } - ec.X9Parameters.prototype.getCurve = function () { return this.curve; }; - ec.X9Parameters.prototype.getG = function () { return this.g; }; - ec.X9Parameters.prototype.getN = function () { return this.n; }; - ec.X9Parameters.prototype.getH = function () { return this.h; }; + // Named EC curves + // ---------------- + // X9ECParameters constructor + ec.X9Parameters = function (curve, g, n, h) { + this.curve = curve; + this.g = g; + this.n = n; + this.h = h; + } + ec.X9Parameters.prototype.getCurve = function () { return this.curve; }; + ec.X9Parameters.prototype.getG = function () { return this.g; }; + ec.X9Parameters.prototype.getN = function () { return this.n; }; + ec.X9Parameters.prototype.getH = function () { return this.h; }; - // secp256k1 is the Curve used by Bitcoin - ec.secNamedCurves = { - // used by Bitcoin - "secp256k1": function () { - // p = 2^256 - 2^32 - 2^9 - 2^8 - 2^7 - 2^6 - 2^4 - 1 - var p = ec.fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F"); - var a = BigInteger.ZERO; - var b = ec.fromHex("7"); - var n = ec.fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141"); - var h = BigInteger.ONE; - var curve = new ec.CurveFp(p, a, b); - var G = curve.decodePointHex("04" - + "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798" - + "483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8"); - return new ec.X9Parameters(curve, G, n, h); - } - }; + // secp256k1 is the Curve used by Bitcoin + ec.secNamedCurves = { + // used by Bitcoin + "secp256k1": function () { + // p = 2^256 - 2^32 - 2^9 - 2^8 - 2^7 - 2^6 - 2^4 - 1 + var p = ec.fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F"); + var a = BigInteger.ZERO; + var b = ec.fromHex("7"); + var n = ec.fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141"); + var h = BigInteger.ONE; + var curve = new ec.CurveFp(p, a, b); + var G = curve.decodePointHex("04" + + "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798" + + "483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8"); + return new ec.X9Parameters(curve, G, n, h); + } + }; - // secp256k1 called by Bitcoin's ECKEY - ec.getSECCurveByName = function (name) { - if (ec.secNamedCurves[name] == undefined) return null; - return ec.secNamedCurves[name](); - } + // secp256k1 called by Bitcoin's ECKEY + ec.getSECCurveByName = function (name) { + if (ec.secNamedCurves[name] == undefined) return null; + return ec.secNamedCurves[name](); + } - if (typeof exports !== 'undefined') { - exports = module.exports = { - default: ec, - EllipticCurve: ec, - BigInteger: BigInteger - }; - } else { - this.ecbn = { - EllipticCurve: ec, - BigInteger: BigInteger - }; - } + if (typeof exports !== 'undefined') { + exports = module.exports = { + default: ec, + EllipticCurve: ec, + BigInteger: BigInteger + }; + } else { + this.ecbn = { + EllipticCurve: ec, + BigInteger: BigInteger + }; + } -}).call(this); \ No newline at end of file +}).call(this); diff --git a/crypto/api/bitcoin/jsbn.js b/crypto/api/bitcoin/jsbn.js index 0e306853..e3c323bd 100644 --- a/crypto/api/bitcoin/jsbn.js +++ b/crypto/api/bitcoin/jsbn.js @@ -1,1940 +1,1937 @@ (function () { - // Copyright (c) 2005 Tom Wu - // All Rights Reserved. - // See "LICENSE" for details. - - // Basic JavaScript BN library - subset useful for RSA encryption. - - // Bits per digit - var dbits; - - // JavaScript engine analysis - var canary = 0xdeadbeefcafe; - var j_lm = (canary & 0xffffff) == 0xefcafe; - - // (public) Constructor - function BigInteger(a, b, c) { - if (a != null) - if ('number' == typeof a) this.fromNumber(a, b, c); - else if (b == null && 'string' != typeof a) this.fromString(a, 256); - else this.fromString(a, b); - } - - // return new, unset BigInteger - function nbi() { - return new BigInteger(null); - } - - // am: Compute w_j += (x*this_i), propagate carries, - // c is initial carry, returns final carry. - // c < 3*dvalue, x < 2*dvalue, this_i < dvalue - // We need to select the fastest one that works in this environment. - - // am1: use a single mult and divide to get the high bits, - // max digit bits should be 26 because - // max internal value = 2*dvalue^2-2*dvalue (< 2^53) - function am1(i, x, w, j, c, n) { - while (--n >= 0) { - var v = x * this[i++] + w[j] + c; - c = Math.floor(v / 0x4000000); - w[j++] = v & 0x3ffffff; - } - return c; - } - // am2 avoids a big mult-and-extract completely. - // Max digit bits should be <= 30 because we do bitwise ops - // on values up to 2*hdvalue^2-hdvalue-1 (< 2^31) - function am2(i, x, w, j, c, n) { - var xl = x & 0x7fff, - xh = x >> 15; - while (--n >= 0) { - var l = this[i] & 0x7fff; - var h = this[i++] >> 15; - var m = xh * l + h * xl; - l = xl * l + ((m & 0x7fff) << 15) + w[j] + (c & 0x3fffffff); - c = (l >>> 30) + (m >>> 15) + xh * h + (c >>> 30); - w[j++] = l & 0x3fffffff; - } - return c; - } - // Alternately, set max digit bits to 28 since some - // browsers slow down when dealing with 32-bit numbers. - function am3(i, x, w, j, c, n) { - var xl = x & 0x3fff, - xh = x >> 14; - while (--n >= 0) { - var l = this[i] & 0x3fff; - var h = this[i++] >> 14; - var m = xh * l + h * xl; - l = xl * l + ((m & 0x3fff) << 14) + w[j] + c; - c = (l >> 28) + (m >> 14) + xh * h; - w[j++] = l & 0xfffffff; - } - return c; - } - var inBrowser = typeof navigator !== 'undefined'; - if (inBrowser && j_lm && navigator.appName == 'Microsoft Internet Explorer') { - BigInteger.prototype.am = am2; - dbits = 30; - } else if (inBrowser && j_lm && navigator.appName != 'Netscape') { - BigInteger.prototype.am = am1; - dbits = 26; - } else { - // Mozilla/Netscape seems to prefer am3 - BigInteger.prototype.am = am3; - dbits = 28; - } - - BigInteger.prototype.DB = dbits; - BigInteger.prototype.DM = (1 << dbits) - 1; - BigInteger.prototype.DV = 1 << dbits; - - var BI_FP = 52; - BigInteger.prototype.FV = Math.pow(2, BI_FP); - BigInteger.prototype.F1 = BI_FP - dbits; - BigInteger.prototype.F2 = 2 * dbits - BI_FP; - - // Digit conversions - var BI_RM = '0123456789abcdefghijklmnopqrstuvwxyz'; - var BI_RC = new Array(); - var rr, vv; - rr = '0'.charCodeAt(0); - for (vv = 0; vv <= 9; ++vv) BI_RC[rr++] = vv; - rr = 'a'.charCodeAt(0); - for (vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv; - rr = 'A'.charCodeAt(0); - for (vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv; - - function int2char(n) { - return BI_RM.charAt(n); - } - function intAt(s, i) { - var c = BI_RC[s.charCodeAt(i)]; - return c == null ? -1 : c; - } - - // (protected) copy this to r - function bnpCopyTo(r) { - for (var i = this.t - 1; i >= 0; --i) r[i] = this[i]; - r.t = this.t; - r.s = this.s; - } - - // (protected) set from integer value x, -DV <= x < DV - function bnpFromInt(x) { - this.t = 1; - this.s = x < 0 ? -1 : 0; - if (x > 0) this[0] = x; - else if (x < -1) this[0] = x + this.DV; - else this.t = 0; - } - - // return bigint initialized to value - function nbv(i) { - var r = nbi(); - r.fromInt(i); - return r; - } - - // (protected) set from string and radix - function bnpFromString(s, b) { - // Auto-detect string notations - if (!b && s.length >= 2 && s[0] === '0') { - var isDetected = true; - switch (s[1]) { - case 'x': // Hexadecimal notation - b = 16; - break; - case 'b': // Binary notation - b = 2; - break; - case 'o': // Octal notation - b = 8; - break; - default: - isDetected = false; - } - - // Remove the notation string if any has been detected - if (isDetected) { - s = s.substr(2); - } - } - - var k; - if (b == 16) k = 4; - else if (b == 8) k = 3; - else if (b == 256) k = 8; - // byte array - else if (b == 2) k = 1; - else if (b == 32) k = 5; - else if (b == 4) k = 2; - else { - this.fromRadix(s, b); - return; - } - this.t = 0; - this.s = 0; - var i = s.length, - mi = false, - sh = 0; - while (--i >= 0) { - var x = k == 8 ? s[i] & 0xff : intAt(s, i); - if (x < 0) { - if (s.charAt(i) == '-') mi = true; - continue; - } - mi = false; - if (sh == 0) this[this.t++] = x; - else if (sh + k > this.DB) { - this[this.t - 1] |= (x & ((1 << (this.DB - sh)) - 1)) << sh; - this[this.t++] = x >> (this.DB - sh); - } else this[this.t - 1] |= x << sh; - sh += k; - if (sh >= this.DB) sh -= this.DB; - } - if (k == 8 && (s[0] & 0x80) != 0) { - this.s = -1; - if (sh > 0) this[this.t - 1] |= ((1 << (this.DB - sh)) - 1) << sh; - } - this.clamp(); - if (mi) BigInteger.ZERO.subTo(this, this); - } - - // (protected) clamp off excess high words - function bnpClamp() { - var c = this.s & this.DM; - while (this.t > 0 && this[this.t - 1] == c) --this.t; - } - - // (public) return string representation in given radix - function bnToString(b) { - if (this.s < 0) return '-' + this.negate().toString(b); - var k; - if (b == 16) k = 4; - else if (b == 8) k = 3; - else if (b == 2) k = 1; - else if (b == 32) k = 5; - else if (b == 4) k = 2; - else return this.toRadix(b); - var km = (1 << k) - 1, - d, - m = false, - r = '', - i = this.t; - var p = this.DB - ((i * this.DB) % k); - if (i-- > 0) { - if (p < this.DB && (d = this[i] >> p) > 0) { - m = true; - r = int2char(d); - } - while (i >= 0) { - if (p < k) { - d = (this[i] & ((1 << p) - 1)) << (k - p); - d |= this[--i] >> (p += this.DB - k); - } else { - d = (this[i] >> (p -= k)) & km; - if (p <= 0) { - p += this.DB; - --i; - } - } - if (d > 0) m = true; - if (m) r += int2char(d); - } - } - return m ? r : '0'; - } - - // (public) -this - function bnNegate() { - var r = nbi(); - BigInteger.ZERO.subTo(this, r); - return r; - } - - // (public) |this| - function bnAbs() { - return this.s < 0 ? this.negate() : this; - } - - // (public) return + if this > a, - if this < a, 0 if equal - function bnCompareTo(a) { - var r = this.s - a.s; - if (r != 0) return r; - var i = this.t; - r = i - a.t; - if (r != 0) return this.s < 0 ? -r : r; - while (--i >= 0) if ((r = this[i] - a[i]) != 0) return r; - return 0; - } - - // returns bit length of the integer x - function nbits(x) { - var r = 1, - t; - if ((t = x >>> 16) != 0) { - x = t; - r += 16; - } - if ((t = x >> 8) != 0) { - x = t; - r += 8; - } - if ((t = x >> 4) != 0) { - x = t; - r += 4; - } - if ((t = x >> 2) != 0) { - x = t; - r += 2; - } - if ((t = x >> 1) != 0) { - x = t; - r += 1; - } - return r; - } - - // (public) return the number of bits in "this" - function bnBitLength() { - if (this.t <= 0) return 0; - return ( - this.DB * (this.t - 1) + nbits(this[this.t - 1] ^ (this.s & this.DM)) - ); - } - - // (protected) r = this << n*DB - function bnpDLShiftTo(n, r) { - var i; - for (i = this.t - 1; i >= 0; --i) r[i + n] = this[i]; - for (i = n - 1; i >= 0; --i) r[i] = 0; - r.t = this.t + n; - r.s = this.s; - } - - // (protected) r = this >> n*DB - function bnpDRShiftTo(n, r) { - for (var i = n; i < this.t; ++i) r[i - n] = this[i]; - r.t = Math.max(this.t - n, 0); - r.s = this.s; - } - - // (protected) r = this << n - function bnpLShiftTo(n, r) { - var bs = n % this.DB; - var cbs = this.DB - bs; - var bm = (1 << cbs) - 1; - var ds = Math.floor(n / this.DB), - c = (this.s << bs) & this.DM, - i; - for (i = this.t - 1; i >= 0; --i) { - r[i + ds + 1] = (this[i] >> cbs) | c; - c = (this[i] & bm) << bs; - } - for (i = ds - 1; i >= 0; --i) r[i] = 0; - r[ds] = c; - r.t = this.t + ds + 1; - r.s = this.s; - r.clamp(); - } - - // (protected) r = this >> n - function bnpRShiftTo(n, r) { - r.s = this.s; - var ds = Math.floor(n / this.DB); - if (ds >= this.t) { - r.t = 0; - return; - } - var bs = n % this.DB; - var cbs = this.DB - bs; - var bm = (1 << bs) - 1; - r[0] = this[ds] >> bs; - for (var i = ds + 1; i < this.t; ++i) { - r[i - ds - 1] |= (this[i] & bm) << cbs; - r[i - ds] = this[i] >> bs; - } - if (bs > 0) r[this.t - ds - 1] |= (this.s & bm) << cbs; - r.t = this.t - ds; - r.clamp(); - } - - // (protected) r = this - a - function bnpSubTo(a, r) { - var i = 0, - c = 0, - m = Math.min(a.t, this.t); - while (i < m) { - c += this[i] - a[i]; - r[i++] = c & this.DM; - c >>= this.DB; - } - if (a.t < this.t) { - c -= a.s; - while (i < this.t) { - c += this[i]; - r[i++] = c & this.DM; - c >>= this.DB; - } - c += this.s; - } else { - c += this.s; - while (i < a.t) { - c -= a[i]; - r[i++] = c & this.DM; - c >>= this.DB; - } - c -= a.s; - } - r.s = c < 0 ? -1 : 0; - if (c < -1) r[i++] = this.DV + c; - else if (c > 0) r[i++] = c; - r.t = i; - r.clamp(); - } - - // (protected) r = this * a, r != this,a (HAC 14.12) - // "this" should be the larger one if appropriate. - function bnpMultiplyTo(a, r) { - var x = this.abs(), - y = a.abs(); - var i = x.t; - r.t = i + y.t; - while (--i >= 0) r[i] = 0; - for (i = 0; i < y.t; ++i) r[i + x.t] = x.am(0, y[i], r, i, 0, x.t); - r.s = 0; - r.clamp(); - if (this.s != a.s) BigInteger.ZERO.subTo(r, r); - } - - // (protected) r = this^2, r != this (HAC 14.16) - function bnpSquareTo(r) { - var x = this.abs(); - var i = (r.t = 2 * x.t); - while (--i >= 0) r[i] = 0; - for (i = 0; i < x.t - 1; ++i) { - var c = x.am(i, x[i], r, 2 * i, 0, 1); - if ( - (r[i + x.t] += x.am(i + 1, 2 * x[i], r, 2 * i + 1, c, x.t - i - 1)) >= - x.DV - ) { - r[i + x.t] -= x.DV; - r[i + x.t + 1] = 1; - } - } - if (r.t > 0) r[r.t - 1] += x.am(i, x[i], r, 2 * i, 0, 1); - r.s = 0; - r.clamp(); - } - - // (protected) divide this by m, quotient and remainder to q, r (HAC 14.20) - // r != q, this != m. q or r may be null. - function bnpDivRemTo(m, q, r) { - var pm = m.abs(); - if (pm.t <= 0) return; - var pt = this.abs(); - if (pt.t < pm.t) { - if (q != null) q.fromInt(0); - if (r != null) this.copyTo(r); - return; - } - if (r == null) r = nbi(); - var y = nbi(), - ts = this.s, - ms = m.s; - var nsh = this.DB - nbits(pm[pm.t - 1]); // normalize modulus - if (nsh > 0) { - pm.lShiftTo(nsh, y); - pt.lShiftTo(nsh, r); - } else { - pm.copyTo(y); - pt.copyTo(r); - } - var ys = y.t; - var y0 = y[ys - 1]; - if (y0 == 0) return; - var yt = y0 * (1 << this.F1) + (ys > 1 ? y[ys - 2] >> this.F2 : 0); - var d1 = this.FV / yt, - d2 = (1 << this.F1) / yt, - e = 1 << this.F2; - var i = r.t, - j = i - ys, - t = q == null ? nbi() : q; - y.dlShiftTo(j, t); - if (r.compareTo(t) >= 0) { - r[r.t++] = 1; - r.subTo(t, r); - } - BigInteger.ONE.dlShiftTo(ys, t); - t.subTo(y, y); // "negative" y so we can replace sub with am later - while (y.t < ys) y[y.t++] = 0; - while (--j >= 0) { - // Estimate quotient digit - var qd = - r[--i] == y0 ? this.DM : Math.floor(r[i] * d1 + (r[i - 1] + e) * d2); - if ((r[i] += y.am(0, qd, r, j, 0, ys)) < qd) { - // Try it out - y.dlShiftTo(j, t); - r.subTo(t, r); - while (r[i] < --qd) r.subTo(t, r); - } - } - if (q != null) { - r.drShiftTo(ys, q); - if (ts != ms) BigInteger.ZERO.subTo(q, q); - } - r.t = ys; - r.clamp(); - if (nsh > 0) r.rShiftTo(nsh, r); // Denormalize remainder - if (ts < 0) BigInteger.ZERO.subTo(r, r); - } - - // (public) this mod a - function bnMod(a) { - var r = nbi(); - this.abs().divRemTo(a, null, r); - if (this.s < 0 && r.compareTo(BigInteger.ZERO) > 0) a.subTo(r, r); - return r; - } - - // Modular reduction using "classic" algorithm - function Classic(m) { - this.m = m; - } - function cConvert(x) { - if (x.s < 0 || x.compareTo(this.m) >= 0) return x.mod(this.m); - else return x; - } - function cRevert(x) { - return x; - } - function cReduce(x) { - x.divRemTo(this.m, null, x); - } - function cMulTo(x, y, r) { - x.multiplyTo(y, r); - this.reduce(r); - } - function cSqrTo(x, r) { - x.squareTo(r); - this.reduce(r); - } - - Classic.prototype.convert = cConvert; - Classic.prototype.revert = cRevert; - Classic.prototype.reduce = cReduce; - Classic.prototype.mulTo = cMulTo; - Classic.prototype.sqrTo = cSqrTo; - - // (protected) return "-1/this % 2^DB"; useful for Mont. reduction - // justification: - // xy == 1 (mod m) - // xy = 1+km - // xy(2-xy) = (1+km)(1-km) - // x[y(2-xy)] = 1-k^2m^2 - // x[y(2-xy)] == 1 (mod m^2) - // if y is 1/x mod m, then y(2-xy) is 1/x mod m^2 - // should reduce x and y(2-xy) by m^2 at each step to keep size bounded. - // JS multiply "overflows" differently from C/C++, so care is needed here. - function bnpInvDigit() { - if (this.t < 1) return 0; - var x = this[0]; - if ((x & 1) == 0) return 0; - var y = x & 3; // y == 1/x mod 2^2 - y = (y * (2 - (x & 0xf) * y)) & 0xf; // y == 1/x mod 2^4 - y = (y * (2 - (x & 0xff) * y)) & 0xff; // y == 1/x mod 2^8 - y = (y * (2 - (((x & 0xffff) * y) & 0xffff))) & 0xffff; // y == 1/x mod 2^16 - // last step - calculate inverse mod DV directly; - // assumes 16 < DB <= 32 and assumes ability to handle 48-bit ints - y = (y * (2 - ((x * y) % this.DV))) % this.DV; // y == 1/x mod 2^dbits - // we really want the negative inverse, and -DV < y < DV - return y > 0 ? this.DV - y : -y; - } - - // Montgomery reduction - function Montgomery(m) { - this.m = m; - this.mp = m.invDigit(); - this.mpl = this.mp & 0x7fff; - this.mph = this.mp >> 15; - this.um = (1 << (m.DB - 15)) - 1; - this.mt2 = 2 * m.t; - } - - // xR mod m - function montConvert(x) { - var r = nbi(); - x.abs().dlShiftTo(this.m.t, r); - r.divRemTo(this.m, null, r); - if (x.s < 0 && r.compareTo(BigInteger.ZERO) > 0) this.m.subTo(r, r); - return r; - } - - // x/R mod m - function montRevert(x) { - var r = nbi(); - x.copyTo(r); - this.reduce(r); - return r; - } - - // x = x/R mod m (HAC 14.32) - function montReduce(x) { - while ( - x.t <= this.mt2 // pad x so am has enough room later - ) - x[x.t++] = 0; - for (var i = 0; i < this.m.t; ++i) { - // faster way of calculating u0 = x[i]*mp mod DV - var j = x[i] & 0x7fff; - var u0 = - (j * this.mpl + - (((j * this.mph + (x[i] >> 15) * this.mpl) & this.um) << 15)) & - x.DM; - // use am to combine the multiply-shift-add into one call - j = i + this.m.t; - x[j] += this.m.am(0, u0, x, i, 0, this.m.t); - // propagate carry - while (x[j] >= x.DV) { - x[j] -= x.DV; - x[++j]++; - } - } - x.clamp(); - x.drShiftTo(this.m.t, x); - if (x.compareTo(this.m) >= 0) x.subTo(this.m, x); - } - - // r = "x^2/R mod m"; x != r - function montSqrTo(x, r) { - x.squareTo(r); - this.reduce(r); - } - - // r = "xy/R mod m"; x,y != r - function montMulTo(x, y, r) { - x.multiplyTo(y, r); - this.reduce(r); - } - - Montgomery.prototype.convert = montConvert; - Montgomery.prototype.revert = montRevert; - Montgomery.prototype.reduce = montReduce; - Montgomery.prototype.mulTo = montMulTo; - Montgomery.prototype.sqrTo = montSqrTo; - - // (protected) true iff this is even - function bnpIsEven() { - return (this.t > 0 ? this[0] & 1 : this.s) == 0; - } - - // (protected) this^e, e < 2^32, doing sqr and mul with "r" (HAC 14.79) - function bnpExp(e, z) { - if (e > 0xffffffff || e < 1) return BigInteger.ONE; - var r = nbi(), - r2 = nbi(), - g = z.convert(this), - i = nbits(e) - 1; - g.copyTo(r); - while (--i >= 0) { - z.sqrTo(r, r2); - if ((e & (1 << i)) > 0) z.mulTo(r2, g, r); - else { - var t = r; - r = r2; - r2 = t; - } - } - return z.revert(r); - } - - // (public) this^e % m, 0 <= e < 2^32 - function bnModPowInt(e, m) { - var z; - if (e < 256 || m.isEven()) z = new Classic(m); - else z = new Montgomery(m); - return this.exp(e, z); - } - - // protected - BigInteger.prototype.copyTo = bnpCopyTo; - BigInteger.prototype.fromInt = bnpFromInt; - BigInteger.prototype.fromString = bnpFromString; - BigInteger.prototype.clamp = bnpClamp; - BigInteger.prototype.dlShiftTo = bnpDLShiftTo; - BigInteger.prototype.drShiftTo = bnpDRShiftTo; - BigInteger.prototype.lShiftTo = bnpLShiftTo; - BigInteger.prototype.rShiftTo = bnpRShiftTo; - BigInteger.prototype.subTo = bnpSubTo; - BigInteger.prototype.multiplyTo = bnpMultiplyTo; - BigInteger.prototype.squareTo = bnpSquareTo; - BigInteger.prototype.divRemTo = bnpDivRemTo; - BigInteger.prototype.invDigit = bnpInvDigit; - BigInteger.prototype.isEven = bnpIsEven; - BigInteger.prototype.exp = bnpExp; - - // public - BigInteger.prototype.toString = bnToString; - BigInteger.prototype.negate = bnNegate; - BigInteger.prototype.abs = bnAbs; - BigInteger.prototype.compareTo = bnCompareTo; - BigInteger.prototype.bitLength = bnBitLength; - BigInteger.prototype.mod = bnMod; - BigInteger.prototype.modPowInt = bnModPowInt; - - // "constants" - BigInteger.ZERO = nbv(0); - BigInteger.ONE = nbv(1); - BigInteger.valueOf = nbv; - - // Copyright (c) 2005-2009 Tom Wu - // All Rights Reserved. - // See "LICENSE" for details. - - // Extended JavaScript BN functions, required for RSA private ops. - - // Version 1.1: new BigInteger("0", 10) returns "proper" zero - // Version 1.2: square() API, isProbablePrime fix - - // (public) - function bnClone() { - var r = nbi(); - this.copyTo(r); - return r; - } - - // (public) return value as integer - function bnIntValue() { - if (this.s < 0) { - if (this.t == 1) return this[0] - this.DV; - else if (this.t == 0) return -1; - } else if (this.t == 1) return this[0]; - else if (this.t == 0) return 0; - // assumes 16 < DB < 32 - return ((this[1] & ((1 << (32 - this.DB)) - 1)) << this.DB) | this[0]; - } - - // (public) return value as byte - function bnByteValue() { - return this.t == 0 ? this.s : (this[0] << 24) >> 24; - } - - // (public) return value as short (assumes DB>=16) - function bnShortValue() { - return this.t == 0 ? this.s : (this[0] << 16) >> 16; - } - - // (protected) return x s.t. r^x < DV - function bnpChunkSize(r) { - return Math.floor((Math.LN2 * this.DB) / Math.log(r)); - } - - // (public) 0 if this == 0, 1 if this > 0 - function bnSigNum() { - if (this.s < 0) return -1; - else if (this.t <= 0 || (this.t == 1 && this[0] <= 0)) return 0; - else return 1; - } - - // (protected) convert to radix string - function bnpToRadix(b) { - if (b == null) b = 10; - if (this.signum() == 0 || b < 2 || b > 36) return '0'; - var cs = this.chunkSize(b); - var a = Math.pow(b, cs); - var d = nbv(a), - y = nbi(), - z = nbi(), - r = ''; - this.divRemTo(d, y, z); - while (y.signum() > 0) { - r = (a + z.intValue()).toString(b).substr(1) + r; - y.divRemTo(d, y, z); - } - return z.intValue().toString(b) + r; - } - - // (protected) convert from radix string - function bnpFromRadix(s, b) { - this.fromInt(0); - if (b == null) b = 10; - var cs = this.chunkSize(b); - var d = Math.pow(b, cs), - mi = false, - j = 0, - w = 0; - for (var i = 0; i < s.length; ++i) { - var x = intAt(s, i); - if (x < 0) { - if (s.charAt(i) == '-' && this.signum() == 0) mi = true; - continue; - } - w = b * w + x; - if (++j >= cs) { - this.dMultiply(d); - this.dAddOffset(w, 0); - j = 0; - w = 0; - } - } - if (j > 0) { - this.dMultiply(Math.pow(b, j)); - this.dAddOffset(w, 0); - } - if (mi) BigInteger.ZERO.subTo(this, this); - } - - // (protected) alternate constructor - function bnpFromNumber(a, b, c) { - if ('number' == typeof b) { - // new BigInteger(int,int,RNG) - if (a < 2) this.fromInt(1); - else { - this.fromNumber(a, c); - if (!this.testBit(a - 1)) - // force MSB set - this.bitwiseTo(BigInteger.ONE.shiftLeft(a - 1), op_or, this); - if (this.isEven()) this.dAddOffset(1, 0); // force odd - while (!this.isProbablePrime(b)) { - this.dAddOffset(2, 0); - if (this.bitLength() > a) - this.subTo(BigInteger.ONE.shiftLeft(a - 1), this); - } - } - } else { - // new BigInteger(int,RNG) - var x = new Array(), - t = a & 7; - x.length = (a >> 3) + 1; - b.nextBytes(x); - if (t > 0) x[0] &= (1 << t) - 1; - else x[0] = 0; - this.fromString(x, 256); - } - } - - // (public) convert to bigendian byte array - function bnToByteArray() { - var i = this.t, - r = new Array(); - r[0] = this.s; - var p = this.DB - ((i * this.DB) % 8), - d, - k = 0; - if (i-- > 0) { - if (p < this.DB && (d = this[i] >> p) != (this.s & this.DM) >> p) - r[k++] = d | (this.s << (this.DB - p)); - while (i >= 0) { - if (p < 8) { - d = (this[i] & ((1 << p) - 1)) << (8 - p); - d |= this[--i] >> (p += this.DB - 8); - } else { - d = (this[i] >> (p -= 8)) & 0xff; - if (p <= 0) { - p += this.DB; - --i; - } - } - if ((d & 0x80) != 0) d |= -256; - if (k == 0 && (this.s & 0x80) != (d & 0x80)) ++k; - if (k > 0 || d != this.s) r[k++] = d; - } - } - return r; - } - - function bnEquals(a) { - return this.compareTo(a) == 0; - } - function bnMin(a) { - return this.compareTo(a) < 0 ? this : a; - } - function bnMax(a) { - return this.compareTo(a) > 0 ? this : a; - } - - // (protected) r = this op a (bitwise) - function bnpBitwiseTo(a, op, r) { - var i, - f, - m = Math.min(a.t, this.t); - for (i = 0; i < m; ++i) r[i] = op(this[i], a[i]); - if (a.t < this.t) { - f = a.s & this.DM; - for (i = m; i < this.t; ++i) r[i] = op(this[i], f); - r.t = this.t; - } else { - f = this.s & this.DM; - for (i = m; i < a.t; ++i) r[i] = op(f, a[i]); - r.t = a.t; - } - r.s = op(this.s, a.s); - r.clamp(); - } - - // (public) this & a - function op_and(x, y) { - return x & y; - } - function bnAnd(a) { - var r = nbi(); - this.bitwiseTo(a, op_and, r); - return r; - } - - // (public) this | a - function op_or(x, y) { - return x | y; - } - function bnOr(a) { - var r = nbi(); - this.bitwiseTo(a, op_or, r); - return r; - } - - // (public) this ^ a - function op_xor(x, y) { - return x ^ y; - } - function bnXor(a) { - var r = nbi(); - this.bitwiseTo(a, op_xor, r); - return r; - } - - // (public) this & ~a - function op_andnot(x, y) { - return x & ~y; - } - function bnAndNot(a) { - var r = nbi(); - this.bitwiseTo(a, op_andnot, r); - return r; - } - - // (public) ~this - function bnNot() { - var r = nbi(); - for (var i = 0; i < this.t; ++i) r[i] = this.DM & ~this[i]; - r.t = this.t; - r.s = ~this.s; - return r; - } - - // (public) this << n - function bnShiftLeft(n) { - var r = nbi(); - if (n < 0) this.rShiftTo(-n, r); - else this.lShiftTo(n, r); - return r; - } - - // (public) this >> n - function bnShiftRight(n) { - var r = nbi(); - if (n < 0) this.lShiftTo(-n, r); - else this.rShiftTo(n, r); - return r; - } - - // return index of lowest 1-bit in x, x < 2^31 - function lbit(x) { - if (x == 0) return -1; - var r = 0; - if ((x & 0xffff) == 0) { - x >>= 16; - r += 16; - } - if ((x & 0xff) == 0) { - x >>= 8; - r += 8; - } - if ((x & 0xf) == 0) { - x >>= 4; - r += 4; - } - if ((x & 3) == 0) { - x >>= 2; - r += 2; - } - if ((x & 1) == 0) ++r; - return r; - } - - // (public) returns index of lowest 1-bit (or -1 if none) - function bnGetLowestSetBit() { - for (var i = 0; i < this.t; ++i) - if (this[i] != 0) return i * this.DB + lbit(this[i]); - if (this.s < 0) return this.t * this.DB; - return -1; - } - - // return number of 1 bits in x - function cbit(x) { - var r = 0; - while (x != 0) { - x &= x - 1; - ++r; - } - return r; - } - - // (public) return number of set bits - function bnBitCount() { - var r = 0, - x = this.s & this.DM; - for (var i = 0; i < this.t; ++i) r += cbit(this[i] ^ x); - return r; - } - - // (public) true iff nth bit is set - function bnTestBit(n) { - var j = Math.floor(n / this.DB); - if (j >= this.t) return this.s != 0; - return (this[j] & (1 << n % this.DB)) != 0; - } - - // (protected) this op (1<>= this.DB; - } - if (a.t < this.t) { - c += a.s; - while (i < this.t) { - c += this[i]; - r[i++] = c & this.DM; - c >>= this.DB; - } - c += this.s; - } else { - c += this.s; - while (i < a.t) { - c += a[i]; - r[i++] = c & this.DM; - c >>= this.DB; - } - c += a.s; - } - r.s = c < 0 ? -1 : 0; - if (c > 0) r[i++] = c; - else if (c < -1) r[i++] = this.DV + c; - r.t = i; - r.clamp(); - } - - // (public) this + a - function bnAdd(a) { - var r = nbi(); - this.addTo(a, r); - return r; - } - - // (public) this - a - function bnSubtract(a) { - var r = nbi(); - this.subTo(a, r); - return r; - } - - // (public) this * a - function bnMultiply(a) { - var r = nbi(); - this.multiplyTo(a, r); - return r; - } - - // (public) this^2 - function bnSquare() { - var r = nbi(); - this.squareTo(r); - return r; - } - - // (public) this / a - function bnDivide(a) { - var r = nbi(); - this.divRemTo(a, r, null); - return r; - } - - // (public) this % a - function bnRemainder(a) { - var r = nbi(); - this.divRemTo(a, null, r); - return r; - } - - // (public) [this/a,this%a] - function bnDivideAndRemainder(a) { - var q = nbi(), - r = nbi(); - this.divRemTo(a, q, r); - return new Array(q, r); - } - - // (protected) this *= n, this >= 0, 1 < n < DV - function bnpDMultiply(n) { - this[this.t] = this.am(0, n - 1, this, 0, 0, this.t); - ++this.t; - this.clamp(); - } - - // (protected) this += n << w words, this >= 0 - function bnpDAddOffset(n, w) { - if (n == 0) return; - while (this.t <= w) this[this.t++] = 0; - this[w] += n; - while (this[w] >= this.DV) { - this[w] -= this.DV; - if (++w >= this.t) this[this.t++] = 0; - ++this[w]; - } - } - - // A "null" reducer - function NullExp() { } - function nNop(x) { - return x; - } - function nMulTo(x, y, r) { - x.multiplyTo(y, r); - } - function nSqrTo(x, r) { - x.squareTo(r); - } - - NullExp.prototype.convert = nNop; - NullExp.prototype.revert = nNop; - NullExp.prototype.mulTo = nMulTo; - NullExp.prototype.sqrTo = nSqrTo; - - // (public) this^e - function bnPow(e) { - return this.exp(e, new NullExp()); - } - - // (protected) r = lower n words of "this * a", a.t <= n - // "this" should be the larger one if appropriate. - function bnpMultiplyLowerTo(a, n, r) { - var i = Math.min(this.t + a.t, n); - r.s = 0; // assumes a,this >= 0 - r.t = i; - while (i > 0) r[--i] = 0; - var j; - for (j = r.t - this.t; i < j; ++i) - r[i + this.t] = this.am(0, a[i], r, i, 0, this.t); - for (j = Math.min(a.t, n); i < j; ++i) this.am(0, a[i], r, i, 0, n - i); - r.clamp(); - } - - // (protected) r = "this * a" without lower n words, n > 0 - // "this" should be the larger one if appropriate. - function bnpMultiplyUpperTo(a, n, r) { - --n; - var i = (r.t = this.t + a.t - n); - r.s = 0; // assumes a,this >= 0 - while (--i >= 0) r[i] = 0; - for (i = Math.max(n - this.t, 0); i < a.t; ++i) - r[this.t + i - n] = this.am(n - i, a[i], r, 0, 0, this.t + i - n); - r.clamp(); - r.drShiftTo(1, r); - } - - // Barrett modular reduction - function Barrett(m) { - // setup Barrett - this.r2 = nbi(); - this.q3 = nbi(); - BigInteger.ONE.dlShiftTo(2 * m.t, this.r2); - this.mu = this.r2.divide(m); - this.m = m; - } - - function barrettConvert(x) { - if (x.s < 0 || x.t > 2 * this.m.t) return x.mod(this.m); - else if (x.compareTo(this.m) < 0) return x; - else { - var r = nbi(); - x.copyTo(r); - this.reduce(r); - return r; - } - } - - function barrettRevert(x) { - return x; - } - - // x = x mod m (HAC 14.42) - function barrettReduce(x) { - x.drShiftTo(this.m.t - 1, this.r2); - if (x.t > this.m.t + 1) { - x.t = this.m.t + 1; - x.clamp(); - } - this.mu.multiplyUpperTo(this.r2, this.m.t + 1, this.q3); - this.m.multiplyLowerTo(this.q3, this.m.t + 1, this.r2); - while (x.compareTo(this.r2) < 0) x.dAddOffset(1, this.m.t + 1); - x.subTo(this.r2, x); - while (x.compareTo(this.m) >= 0) x.subTo(this.m, x); - } - - // r = x^2 mod m; x != r - function barrettSqrTo(x, r) { - x.squareTo(r); - this.reduce(r); - } - - // r = x*y mod m; x,y != r - function barrettMulTo(x, y, r) { - x.multiplyTo(y, r); - this.reduce(r); - } - - Barrett.prototype.convert = barrettConvert; - Barrett.prototype.revert = barrettRevert; - Barrett.prototype.reduce = barrettReduce; - Barrett.prototype.mulTo = barrettMulTo; - Barrett.prototype.sqrTo = barrettSqrTo; - - // (public) this^e % m (HAC 14.85) - function bnModPow(e, m) { - var i = e.bitLength(), - k, - r = nbv(1), - z; - if (i <= 0) return r; - else if (i < 18) k = 1; - else if (i < 48) k = 3; - else if (i < 144) k = 4; - else if (i < 768) k = 5; - else k = 6; - if (i < 8) z = new Classic(m); - else if (m.isEven()) z = new Barrett(m); - else z = new Montgomery(m); - - // precomputation - var g = new Array(), - n = 3, - k1 = k - 1, - km = (1 << k) - 1; - g[1] = z.convert(this); - if (k > 1) { - var g2 = nbi(); - z.sqrTo(g[1], g2); - while (n <= km) { - g[n] = nbi(); - z.mulTo(g2, g[n - 2], g[n]); - n += 2; - } - } - - var j = e.t - 1, - w, - is1 = true, - r2 = nbi(), - t; - i = nbits(e[j]) - 1; - while (j >= 0) { - if (i >= k1) w = (e[j] >> (i - k1)) & km; - else { - w = (e[j] & ((1 << (i + 1)) - 1)) << (k1 - i); - if (j > 0) w |= e[j - 1] >> (this.DB + i - k1); - } - - n = k; - while ((w & 1) == 0) { - w >>= 1; - --n; - } - if ((i -= n) < 0) { - i += this.DB; - --j; - } - if (is1) { - // ret == 1, don't bother squaring or multiplying it - g[w].copyTo(r); - is1 = false; - } else { - while (n > 1) { - z.sqrTo(r, r2); - z.sqrTo(r2, r); - n -= 2; - } - if (n > 0) z.sqrTo(r, r2); - else { - t = r; - r = r2; - r2 = t; - } - z.mulTo(r2, g[w], r); - } - - while (j >= 0 && (e[j] & (1 << i)) == 0) { - z.sqrTo(r, r2); - t = r; - r = r2; - r2 = t; - if (--i < 0) { - i = this.DB - 1; - --j; - } - } - } - return z.revert(r); - } - - // (public) gcd(this,a) (HAC 14.54) - function bnGCD(a) { - var x = this.s < 0 ? this.negate() : this.clone(); - var y = a.s < 0 ? a.negate() : a.clone(); - if (x.compareTo(y) < 0) { - var t = x; - x = y; - y = t; - } - var i = x.getLowestSetBit(), - g = y.getLowestSetBit(); - if (g < 0) return x; - if (i < g) g = i; - if (g > 0) { - x.rShiftTo(g, x); - y.rShiftTo(g, y); - } - while (x.signum() > 0) { - if ((i = x.getLowestSetBit()) > 0) x.rShiftTo(i, x); - if ((i = y.getLowestSetBit()) > 0) y.rShiftTo(i, y); - if (x.compareTo(y) >= 0) { - x.subTo(y, x); - x.rShiftTo(1, x); - } else { - y.subTo(x, y); - y.rShiftTo(1, y); - } - } - if (g > 0) y.lShiftTo(g, y); - return y; - } - - // (protected) this % n, n < 2^26 - function bnpModInt(n) { - if (n <= 0) return 0; - var d = this.DV % n, - r = this.s < 0 ? n - 1 : 0; - if (this.t > 0) - if (d == 0) r = this[0] % n; - else for (var i = this.t - 1; i >= 0; --i) r = (d * r + this[i]) % n; - return r; - } - - // (public) 1/this % m (HAC 14.61) - function bnModInverse(m) { - var ac = m.isEven(); - if ((this.isEven() && ac) || m.signum() == 0) return BigInteger.ZERO; - var u = m.clone(), - v = this.clone(); - var a = nbv(1), - b = nbv(0), - c = nbv(0), - d = nbv(1); - while (u.signum() != 0) { - while (u.isEven()) { - u.rShiftTo(1, u); - if (ac) { - if (!a.isEven() || !b.isEven()) { - a.addTo(this, a); - b.subTo(m, b); - } - a.rShiftTo(1, a); - } else if (!b.isEven()) b.subTo(m, b); - b.rShiftTo(1, b); - } - while (v.isEven()) { - v.rShiftTo(1, v); - if (ac) { - if (!c.isEven() || !d.isEven()) { - c.addTo(this, c); - d.subTo(m, d); - } - c.rShiftTo(1, c); - } else if (!d.isEven()) d.subTo(m, d); - d.rShiftTo(1, d); - } - if (u.compareTo(v) >= 0) { - u.subTo(v, u); - if (ac) a.subTo(c, a); - b.subTo(d, b); - } else { - v.subTo(u, v); - if (ac) c.subTo(a, c); - d.subTo(b, d); - } - } - if (v.compareTo(BigInteger.ONE) != 0) return BigInteger.ZERO; - if (d.compareTo(m) >= 0) return d.subtract(m); - if (d.signum() < 0) d.addTo(m, d); - else return d; - if (d.signum() < 0) return d.add(m); - else return d; - } - - var lowprimes = [ - 2, - 3, - 5, - 7, - 11, - 13, - 17, - 19, - 23, - 29, - 31, - 37, - 41, - 43, - 47, - 53, - 59, - 61, - 67, - 71, - 73, - 79, - 83, - 89, - 97, - 101, - 103, - 107, - 109, - 113, - 127, - 131, - 137, - 139, - 149, - 151, - 157, - 163, - 167, - 173, - 179, - 181, - 191, - 193, - 197, - 199, - 211, - 223, - 227, - 229, - 233, - 239, - 241, - 251, - 257, - 263, - 269, - 271, - 277, - 281, - 283, - 293, - 307, - 311, - 313, - 317, - 331, - 337, - 347, - 349, - 353, - 359, - 367, - 373, - 379, - 383, - 389, - 397, - 401, - 409, - 419, - 421, - 431, - 433, - 439, - 443, - 449, - 457, - 461, - 463, - 467, - 479, - 487, - 491, - 499, - 503, - 509, - 521, - 523, - 541, - 547, - 557, - 563, - 569, - 571, - 577, - 587, - 593, - 599, - 601, - 607, - 613, - 617, - 619, - 631, - 641, - 643, - 647, - 653, - 659, - 661, - 673, - 677, - 683, - 691, - 701, - 709, - 719, - 727, - 733, - 739, - 743, - 751, - 757, - 761, - 769, - 773, - 787, - 797, - 809, - 811, - 821, - 823, - 827, - 829, - 839, - 853, - 857, - 859, - 863, - 877, - 881, - 883, - 887, - 907, - 911, - 919, - 929, - 937, - 941, - 947, - 953, - 967, - 971, - 977, - 983, - 991, - 997, - ]; - var lplim = (1 << 26) / lowprimes[lowprimes.length - 1]; - - // (public) test primality with certainty >= 1-.5^t - function bnIsProbablePrime(t) { - var i, - x = this.abs(); - if (x.t == 1 && x[0] <= lowprimes[lowprimes.length - 1]) { - for (i = 0; i < lowprimes.length; ++i) - if (x[0] == lowprimes[i]) return true; - return false; - } - if (x.isEven()) return false; - i = 1; - while (i < lowprimes.length) { - var m = lowprimes[i], - j = i + 1; - while (j < lowprimes.length && m < lplim) m *= lowprimes[j++]; - m = x.modInt(m); - while (i < j) if (m % lowprimes[i++] == 0) return false; - } - return x.millerRabin(t); - } - - // (protected) true if probably prime (HAC 4.24, Miller-Rabin) - function bnpMillerRabin(t) { - var n1 = this.subtract(BigInteger.ONE); - var k = n1.getLowestSetBit(); - if (k <= 0) return false; - var r = n1.shiftRight(k); - t = (t + 1) >> 1; - if (t > lowprimes.length) t = lowprimes.length; - var a = nbi(); - for (var i = 0; i < t; ++i) { - //Pick bases at random, instead of starting at 2 - a.fromInt(lowprimes[Math.floor(Math.random() * lowprimes.length)]); - var y = a.modPow(r, this); - if (y.compareTo(BigInteger.ONE) != 0 && y.compareTo(n1) != 0) { - var j = 1; - while (j++ < k && y.compareTo(n1) != 0) { - y = y.modPowInt(2, this); - if (y.compareTo(BigInteger.ONE) == 0) return false; - } - if (y.compareTo(n1) != 0) return false; - } - } - return true; - } - - // protected - BigInteger.prototype.chunkSize = bnpChunkSize; - BigInteger.prototype.toRadix = bnpToRadix; - BigInteger.prototype.fromRadix = bnpFromRadix; - BigInteger.prototype.fromNumber = bnpFromNumber; - BigInteger.prototype.bitwiseTo = bnpBitwiseTo; - BigInteger.prototype.changeBit = bnpChangeBit; - BigInteger.prototype.addTo = bnpAddTo; - BigInteger.prototype.dMultiply = bnpDMultiply; - BigInteger.prototype.dAddOffset = bnpDAddOffset; - BigInteger.prototype.multiplyLowerTo = bnpMultiplyLowerTo; - BigInteger.prototype.multiplyUpperTo = bnpMultiplyUpperTo; - BigInteger.prototype.modInt = bnpModInt; - BigInteger.prototype.millerRabin = bnpMillerRabin; - - // public - BigInteger.prototype.clone = bnClone; - BigInteger.prototype.intValue = bnIntValue; - BigInteger.prototype.byteValue = bnByteValue; - BigInteger.prototype.shortValue = bnShortValue; - BigInteger.prototype.signum = bnSigNum; - BigInteger.prototype.toByteArray = bnToByteArray; - BigInteger.prototype.equals = bnEquals; - BigInteger.prototype.min = bnMin; - BigInteger.prototype.max = bnMax; - BigInteger.prototype.and = bnAnd; - BigInteger.prototype.or = bnOr; - BigInteger.prototype.xor = bnXor; - BigInteger.prototype.andNot = bnAndNot; - BigInteger.prototype.not = bnNot; - BigInteger.prototype.shiftLeft = bnShiftLeft; - BigInteger.prototype.shiftRight = bnShiftRight; - BigInteger.prototype.getLowestSetBit = bnGetLowestSetBit; - BigInteger.prototype.bitCount = bnBitCount; - BigInteger.prototype.testBit = bnTestBit; - BigInteger.prototype.setBit = bnSetBit; - BigInteger.prototype.clearBit = bnClearBit; - BigInteger.prototype.flipBit = bnFlipBit; - BigInteger.prototype.add = bnAdd; - BigInteger.prototype.subtract = bnSubtract; - BigInteger.prototype.multiply = bnMultiply; - BigInteger.prototype.divide = bnDivide; - BigInteger.prototype.remainder = bnRemainder; - BigInteger.prototype.divideAndRemainder = bnDivideAndRemainder; - BigInteger.prototype.modPow = bnModPow; - BigInteger.prototype.modInverse = bnModInverse; - BigInteger.prototype.pow = bnPow; - BigInteger.prototype.gcd = bnGCD; - BigInteger.prototype.isProbablePrime = bnIsProbablePrime; - - // JSBN-specific extension - BigInteger.prototype.square = bnSquare; - - // Expose the Barrett function - BigInteger.prototype.Barrett = Barrett; - - // BigInteger interfaces not implemented in jsbn: - - // BigInteger(int signum, byte[] magnitude) - // double doubleValue() - // float floatValue() - // int hashCode() - // long longValue() - // static BigInteger valueOf(long val) - - // Imported from bitcoinjs-lib - - /** - * Turns a byte array into a big integer. - * - * This function will interpret a byte array as a big integer in big - * endian notation and ignore leading zeros. - */ - - BigInteger.fromByteArrayUnsigned = function (ba) { - - if (!ba.length) { - return new BigInteger.valueOf(0); - } else if (ba[0] & 0x80) { - // Prepend a zero so the BigInteger class doesn't mistake this - // for a negative integer. - return new BigInteger([0].concat(ba)); - } else { - return new BigInteger(ba); - } - }; - - /** - * Parse a signed big integer byte representation. - * - * For details on the format please see BigInteger.toByteArraySigned. - */ - - BigInteger.fromByteArraySigned = function (ba) { - // Check for negative value - if (ba[0] & 0x80) { - // Remove sign bit - ba[0] &= 0x7f; - - return BigInteger.fromByteArrayUnsigned(ba).negate(); - } else { - return BigInteger.fromByteArrayUnsigned(ba); - } - }; - - /** - * Returns a byte array representation of the big integer. - * - * This returns the absolute of the contained value in big endian - * form. A value of zero results in an empty array. - */ - - BigInteger.prototype.toByteArrayUnsigned = function () { - var ba = this.abs().toByteArray(); - - // Empty array, nothing to do - if (!ba.length) { - return ba; - } - - // remove leading 0 - if (ba[0] === 0) { - ba = ba.slice(1); - } - - // all values must be positive - for (var i = 0; i < ba.length; ++i) { - ba[i] = (ba[i] < 0) ? ba[i] + 256 : ba[i]; - } - - return ba; - }; - - /* - * Converts big integer to signed byte representation. - * - * The format for this value uses the most significant bit as a sign - * bit. If the most significant bit is already occupied by the - * absolute value, an extra byte is prepended and the sign bit is set - * there. - * - * Examples: - * - * 0 => 0x00 - * 1 => 0x01 - * -1 => 0x81 - * 127 => 0x7f - * -127 => 0xff - * 128 => 0x0080 - * -128 => 0x8080 - * 255 => 0x00ff - * -255 => 0x80ff - * 16300 => 0x3fac - * -16300 => 0xbfac - * 62300 => 0x00f35c - * -62300 => 0x80f35c - */ - - BigInteger.prototype.toByteArraySigned = function () { - var val = this.toByteArrayUnsigned(); - var neg = this.s < 0; - - // if the first bit is set, we always unshift - // either unshift 0x80 or 0x00 - if (val[0] & 0x80) { - val.unshift((neg) ? 0x80 : 0x00); - } - // if the first bit isn't set, set it if negative - else if (neg) { - val[0] |= 0x80; - } - - return val; - }; - - // Random number generator - requires a PRNG backend, e.g. prng4.js - - // For best results, put code like - // - // in your main HTML document. - - var rng_state; - var rng_pool; - var rng_pptr; - - // Mix in a 32-bit integer into the pool - function rng_seed_int(x) { - rng_pool[rng_pptr++] ^= x & 255; - rng_pool[rng_pptr++] ^= (x >> 8) & 255; - rng_pool[rng_pptr++] ^= (x >> 16) & 255; - rng_pool[rng_pptr++] ^= (x >> 24) & 255; - if (rng_pptr >= rng_psize) rng_pptr -= rng_psize; - } - - // Mix in the current time (w/milliseconds) into the pool - function rng_seed_time() { - rng_seed_int(new Date().getTime()); - } - - // Initialize the pool with junk if needed. - if (rng_pool == null) { - rng_pool = new Array(); - rng_pptr = 0; - var t; - if (typeof window !== 'undefined' && window.crypto) { - if (window.crypto.getRandomValues) { - // Use webcrypto if available - var ua = new Uint8Array(32); - window.crypto.getRandomValues(ua); - for (t = 0; t < 32; ++t) rng_pool[rng_pptr++] = ua[t]; - } else if ( - navigator.appName == 'Netscape' && - navigator.appVersion < '5' - ) { - // Extract entropy (256 bits) from NS4 RNG if available - var z = window.crypto.random(32); - for (t = 0; t < z.length; ++t) - rng_pool[rng_pptr++] = z.charCodeAt(t) & 255; - } - } - while (rng_pptr < rng_psize) { - // extract some randomness from Math.random() - t = Math.floor(65536 * Math.random()); - rng_pool[rng_pptr++] = t >>> 8; - rng_pool[rng_pptr++] = t & 255; - } - rng_pptr = 0; - rng_seed_time(); - //rng_seed_int(window.screenX); - //rng_seed_int(window.screenY); - } - - function rng_get_byte() { - if (rng_state == null) { - rng_seed_time(); - rng_state = prng_newstate(); - rng_state.init(rng_pool); - for (rng_pptr = 0; rng_pptr < rng_pool.length; ++rng_pptr) - rng_pool[rng_pptr] = 0; - rng_pptr = 0; - //rng_pool = null; - } - // TODO: allow reseeding after first request - return rng_state.next(); - } - - function rng_get_bytes(ba) { - var i; - for (i = 0; i < ba.length; ++i) ba[i] = rng_get_byte(); - } - - function SecureRandom() { } - - SecureRandom.prototype.nextBytes = rng_get_bytes; - - // prng4.js - uses Arcfour as a PRNG - - function Arcfour() { - this.i = 0; - this.j = 0; - this.S = new Array(); - } - - // Initialize arcfour context from key, an array of ints, each from [0..255] - function ARC4init(key) { - var i, j, t; - for (i = 0; i < 256; ++i) this.S[i] = i; - j = 0; - for (i = 0; i < 256; ++i) { - j = (j + this.S[i] + key[i % key.length]) & 255; - t = this.S[i]; - this.S[i] = this.S[j]; - this.S[j] = t; - } - this.i = 0; - this.j = 0; - } - - function ARC4next() { - var t; - this.i = (this.i + 1) & 255; - this.j = (this.j + this.S[this.i]) & 255; - t = this.S[this.i]; - this.S[this.i] = this.S[this.j]; - this.S[this.j] = t; - return this.S[(t + this.S[this.i]) & 255]; - } - - Arcfour.prototype.init = ARC4init; - Arcfour.prototype.next = ARC4next; - - // Plug in your RNG constructor here - function prng_newstate() { - return new Arcfour(); - } - - // Pool size must be a multiple of 4 and greater than 32. - // An array of bytes the size of the pool will be passed to init() - var rng_psize = 256; - - if (typeof exports !== 'undefined') { - exports = module.exports = { - default: BigInteger, - BigInteger: BigInteger, - SecureRandom: SecureRandom, - }; - } else { - this.jsbn = { - BigInteger: BigInteger, - SecureRandom: SecureRandom, - }; - } -}.call(this)); \ No newline at end of file + // Copyright (c) 2005 Tom Wu + // All Rights Reserved. + // See "LICENSE" for details. + + // Basic JavaScript BN library - subset useful for RSA encryption. + + // Bits per digit + var dbits; + + // JavaScript engine analysis + var canary = 0xdeadbeefcafe; + var j_lm = (canary & 0xffffff) == 0xefcafe; + + // (public) Constructor + function BigInteger(a, b, c) { + if (a != null) + if ('number' == typeof a) this.fromNumber(a, b, c); + else if (b == null && 'string' != typeof a) this.fromString(a, 256); + else this.fromString(a, b); + } + + // return new, unset BigInteger + function nbi() { + return new BigInteger(null); + } + + // am: Compute w_j += (x*this_i), propagate carries, + // c is initial carry, returns final carry. + // c < 3*dvalue, x < 2*dvalue, this_i < dvalue + // We need to select the fastest one that works in this environment. + + // am1: use a single mult and divide to get the high bits, + // max digit bits should be 26 because + // max internal value = 2*dvalue^2-2*dvalue (< 2^53) + function am1(i, x, w, j, c, n) { + while (--n >= 0) { + var v = x * this[i++] + w[j] + c; + c = Math.floor(v / 0x4000000); + w[j++] = v & 0x3ffffff; + } + return c; + } + // am2 avoids a big mult-and-extract completely. + // Max digit bits should be <= 30 because we do bitwise ops + // on values up to 2*hdvalue^2-hdvalue-1 (< 2^31) + function am2(i, x, w, j, c, n) { + var xl = x & 0x7fff, + xh = x >> 15; + while (--n >= 0) { + var l = this[i] & 0x7fff; + var h = this[i++] >> 15; + var m = xh * l + h * xl; + l = xl * l + ((m & 0x7fff) << 15) + w[j] + (c & 0x3fffffff); + c = (l >>> 30) + (m >>> 15) + xh * h + (c >>> 30); + w[j++] = l & 0x3fffffff; + } + return c; + } + // Alternately, set max digit bits to 28 since some + // browsers slow down when dealing with 32-bit numbers. + function am3(i, x, w, j, c, n) { + var xl = x & 0x3fff, + xh = x >> 14; + while (--n >= 0) { + var l = this[i] & 0x3fff; + var h = this[i++] >> 14; + var m = xh * l + h * xl; + l = xl * l + ((m & 0x3fff) << 14) + w[j] + c; + c = (l >> 28) + (m >> 14) + xh * h; + w[j++] = l & 0xfffffff; + } + return c; + } + var inBrowser = typeof navigator !== 'undefined'; + if (inBrowser && j_lm && navigator.appName == 'Microsoft Internet Explorer') { + BigInteger.prototype.am = am2; + dbits = 30; + } else if (inBrowser && j_lm && navigator.appName != 'Netscape') { + BigInteger.prototype.am = am1; + dbits = 26; + } else { + // Mozilla/Netscape seems to prefer am3 + BigInteger.prototype.am = am3; + dbits = 28; + } + + BigInteger.prototype.DB = dbits; + BigInteger.prototype.DM = (1 << dbits) - 1; + BigInteger.prototype.DV = 1 << dbits; + + var BI_FP = 52; + BigInteger.prototype.FV = Math.pow(2, BI_FP); + BigInteger.prototype.F1 = BI_FP - dbits; + BigInteger.prototype.F2 = 2 * dbits - BI_FP; + + // Digit conversions + var BI_RM = '0123456789abcdefghijklmnopqrstuvwxyz'; + var BI_RC = new Array(); + var rr, vv; + rr = '0'.charCodeAt(0); + for (vv = 0; vv <= 9; ++vv) BI_RC[rr++] = vv; + rr = 'a'.charCodeAt(0); + for (vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv; + rr = 'A'.charCodeAt(0); + for (vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv; + + function int2char(n) { + return BI_RM.charAt(n); + } + function intAt(s, i) { + var c = BI_RC[s.charCodeAt(i)]; + return c == null ? -1 : c; + } + + // (protected) copy this to r + function bnpCopyTo(r) { + for (var i = this.t - 1; i >= 0; --i) r[i] = this[i]; + r.t = this.t; + r.s = this.s; + } + + // (protected) set from integer value x, -DV <= x < DV + function bnpFromInt(x) { + this.t = 1; + this.s = x < 0 ? -1 : 0; + if (x > 0) this[0] = x; + else if (x < -1) this[0] = x + this.DV; + else this.t = 0; + } + + // return bigint initialized to value + function nbv(i) { + var r = nbi(); + r.fromInt(i); + return r; + } + + // (protected) set from string and radix + function bnpFromString(s, b) { + // Auto-detect string notations + if (!b && s.length >= 2 && s[0] === '0') { + var isDetected = true; + switch (s[1]) { + case 'x': // Hexadecimal notation + b = 16; + break; + case 'b': // Binary notation + b = 2; + break; + case 'o': // Octal notation + b = 8; + break; + default: + isDetected = false; + } + + // Remove the notation string if any has been detected + if (isDetected) { + s = s.substr(2); + } + } + + var k; + if (b == 16) k = 4; + else if (b == 8) k = 3; + else if (b == 256) k = 8; + // byte array + else if (b == 2) k = 1; + else if (b == 32) k = 5; + else if (b == 4) k = 2; + else { + this.fromRadix(s, b); + return; + } + this.t = 0; + this.s = 0; + var i = s.length, + mi = false, + sh = 0; + while (--i >= 0) { + var x = k == 8 ? s[i] & 0xff : intAt(s, i); + if (x < 0) { + if (s.charAt(i) == '-') mi = true; + continue; + } + mi = false; + if (sh == 0) this[this.t++] = x; + else if (sh + k > this.DB) { + this[this.t - 1] |= (x & ((1 << (this.DB - sh)) - 1)) << sh; + this[this.t++] = x >> (this.DB - sh); + } else this[this.t - 1] |= x << sh; + sh += k; + if (sh >= this.DB) sh -= this.DB; + } + if (k == 8 && (s[0] & 0x80) != 0) { + this.s = -1; + if (sh > 0) this[this.t - 1] |= ((1 << (this.DB - sh)) - 1) << sh; + } + this.clamp(); + if (mi) BigInteger.ZERO.subTo(this, this); + } + + // (protected) clamp off excess high words + function bnpClamp() { + var c = this.s & this.DM; + while (this.t > 0 && this[this.t - 1] == c) --this.t; + } + + // (public) return string representation in given radix + function bnToString(b) { + if (this.s < 0) return '-' + this.negate().toString(b); + var k; + if (b == 16) k = 4; + else if (b == 8) k = 3; + else if (b == 2) k = 1; + else if (b == 32) k = 5; + else if (b == 4) k = 2; + else return this.toRadix(b); + var km = (1 << k) - 1, + d, + m = false, + r = '', + i = this.t; + var p = this.DB - ((i * this.DB) % k); + if (i-- > 0) { + if (p < this.DB && (d = this[i] >> p) > 0) { + m = true; + r = int2char(d); + } + while (i >= 0) { + if (p < k) { + d = (this[i] & ((1 << p) - 1)) << (k - p); + d |= this[--i] >> (p += this.DB - k); + } else { + d = (this[i] >> (p -= k)) & km; + if (p <= 0) { + p += this.DB; + --i; + } + } + if (d > 0) m = true; + if (m) r += int2char(d); + } + } + return m ? r : '0'; + } + + // (public) -this + function bnNegate() { + var r = nbi(); + BigInteger.ZERO.subTo(this, r); + return r; + } + + // (public) |this| + function bnAbs() { + return this.s < 0 ? this.negate() : this; + } + + // (public) return + if this > a, - if this < a, 0 if equal + function bnCompareTo(a) { + var r = this.s - a.s; + if (r != 0) return r; + var i = this.t; + r = i - a.t; + if (r != 0) return this.s < 0 ? -r : r; + while (--i >= 0) if ((r = this[i] - a[i]) != 0) return r; + return 0; + } + + // returns bit length of the integer x + function nbits(x) { + var r = 1, + t; + if ((t = x >>> 16) != 0) { + x = t; + r += 16; + } + if ((t = x >> 8) != 0) { + x = t; + r += 8; + } + if ((t = x >> 4) != 0) { + x = t; + r += 4; + } + if ((t = x >> 2) != 0) { + x = t; + r += 2; + } + if ((t = x >> 1) != 0) { + x = t; + r += 1; + } + return r; + } + + // (public) return the number of bits in "this" + function bnBitLength() { + if (this.t <= 0) return 0; + return ( + this.DB * (this.t - 1) + nbits(this[this.t - 1] ^ (this.s & this.DM)) + ); + } + + // (protected) r = this << n*DB + function bnpDLShiftTo(n, r) { + var i; + for (i = this.t - 1; i >= 0; --i) r[i + n] = this[i]; + for (i = n - 1; i >= 0; --i) r[i] = 0; + r.t = this.t + n; + r.s = this.s; + } + + // (protected) r = this >> n*DB + function bnpDRShiftTo(n, r) { + for (var i = n; i < this.t; ++i) r[i - n] = this[i]; + r.t = Math.max(this.t - n, 0); + r.s = this.s; + } + + // (protected) r = this << n + function bnpLShiftTo(n, r) { + var bs = n % this.DB; + var cbs = this.DB - bs; + var bm = (1 << cbs) - 1; + var ds = Math.floor(n / this.DB), + c = (this.s << bs) & this.DM, + i; + for (i = this.t - 1; i >= 0; --i) { + r[i + ds + 1] = (this[i] >> cbs) | c; + c = (this[i] & bm) << bs; + } + for (i = ds - 1; i >= 0; --i) r[i] = 0; + r[ds] = c; + r.t = this.t + ds + 1; + r.s = this.s; + r.clamp(); + } + + // (protected) r = this >> n + function bnpRShiftTo(n, r) { + r.s = this.s; + var ds = Math.floor(n / this.DB); + if (ds >= this.t) { + r.t = 0; + return; + } + var bs = n % this.DB; + var cbs = this.DB - bs; + var bm = (1 << bs) - 1; + r[0] = this[ds] >> bs; + for (var i = ds + 1; i < this.t; ++i) { + r[i - ds - 1] |= (this[i] & bm) << cbs; + r[i - ds] = this[i] >> bs; + } + if (bs > 0) r[this.t - ds - 1] |= (this.s & bm) << cbs; + r.t = this.t - ds; + r.clamp(); + } + + // (protected) r = this - a + function bnpSubTo(a, r) { + var i = 0, + c = 0, + m = Math.min(a.t, this.t); + while (i < m) { + c += this[i] - a[i]; + r[i++] = c & this.DM; + c >>= this.DB; + } + if (a.t < this.t) { + c -= a.s; + while (i < this.t) { + c += this[i]; + r[i++] = c & this.DM; + c >>= this.DB; + } + c += this.s; + } else { + c += this.s; + while (i < a.t) { + c -= a[i]; + r[i++] = c & this.DM; + c >>= this.DB; + } + c -= a.s; + } + r.s = c < 0 ? -1 : 0; + if (c < -1) r[i++] = this.DV + c; + else if (c > 0) r[i++] = c; + r.t = i; + r.clamp(); + } + + // (protected) r = this * a, r != this,a (HAC 14.12) + // "this" should be the larger one if appropriate. + function bnpMultiplyTo(a, r) { + var x = this.abs(), + y = a.abs(); + var i = x.t; + r.t = i + y.t; + while (--i >= 0) r[i] = 0; + for (i = 0; i < y.t; ++i) r[i + x.t] = x.am(0, y[i], r, i, 0, x.t); + r.s = 0; + r.clamp(); + if (this.s != a.s) BigInteger.ZERO.subTo(r, r); + } + + // (protected) r = this^2, r != this (HAC 14.16) + function bnpSquareTo(r) { + var x = this.abs(); + var i = (r.t = 2 * x.t); + while (--i >= 0) r[i] = 0; + for (i = 0; i < x.t - 1; ++i) { + var c = x.am(i, x[i], r, 2 * i, 0, 1); + if ( + (r[i + x.t] += x.am(i + 1, 2 * x[i], r, 2 * i + 1, c, x.t - i - 1)) >= + x.DV + ) { + r[i + x.t] -= x.DV; + r[i + x.t + 1] = 1; + } + } + if (r.t > 0) r[r.t - 1] += x.am(i, x[i], r, 2 * i, 0, 1); + r.s = 0; + r.clamp(); + } + + // (protected) divide this by m, quotient and remainder to q, r (HAC 14.20) + // r != q, this != m. q or r may be null. + function bnpDivRemTo(m, q, r) { + var pm = m.abs(); + if (pm.t <= 0) return; + var pt = this.abs(); + if (pt.t < pm.t) { + if (q != null) q.fromInt(0); + if (r != null) this.copyTo(r); + return; + } + if (r == null) r = nbi(); + var y = nbi(), + ts = this.s, + ms = m.s; + var nsh = this.DB - nbits(pm[pm.t - 1]); // normalize modulus + if (nsh > 0) { + pm.lShiftTo(nsh, y); + pt.lShiftTo(nsh, r); + } else { + pm.copyTo(y); + pt.copyTo(r); + } + var ys = y.t; + var y0 = y[ys - 1]; + if (y0 == 0) return; + var yt = y0 * (1 << this.F1) + (ys > 1 ? y[ys - 2] >> this.F2 : 0); + var d1 = this.FV / yt, + d2 = (1 << this.F1) / yt, + e = 1 << this.F2; + var i = r.t, + j = i - ys, + t = q == null ? nbi() : q; + y.dlShiftTo(j, t); + if (r.compareTo(t) >= 0) { + r[r.t++] = 1; + r.subTo(t, r); + } + BigInteger.ONE.dlShiftTo(ys, t); + t.subTo(y, y); // "negative" y so we can replace sub with am later + while (y.t < ys) y[y.t++] = 0; + while (--j >= 0) { + // Estimate quotient digit + var qd = + r[--i] == y0 ? this.DM : Math.floor(r[i] * d1 + (r[i - 1] + e) * d2); + if ((r[i] += y.am(0, qd, r, j, 0, ys)) < qd) { + // Try it out + y.dlShiftTo(j, t); + r.subTo(t, r); + while (r[i] < --qd) r.subTo(t, r); + } + } + if (q != null) { + r.drShiftTo(ys, q); + if (ts != ms) BigInteger.ZERO.subTo(q, q); + } + r.t = ys; + r.clamp(); + if (nsh > 0) r.rShiftTo(nsh, r); // Denormalize remainder + if (ts < 0) BigInteger.ZERO.subTo(r, r); + } + + // (public) this mod a + function bnMod(a) { + var r = nbi(); + this.abs().divRemTo(a, null, r); + if (this.s < 0 && r.compareTo(BigInteger.ZERO) > 0) a.subTo(r, r); + return r; + } + + // Modular reduction using "classic" algorithm + function Classic(m) { + this.m = m; + } + function cConvert(x) { + if (x.s < 0 || x.compareTo(this.m) >= 0) return x.mod(this.m); + else return x; + } + function cRevert(x) { + return x; + } + function cReduce(x) { + x.divRemTo(this.m, null, x); + } + function cMulTo(x, y, r) { + x.multiplyTo(y, r); + this.reduce(r); + } + function cSqrTo(x, r) { + x.squareTo(r); + this.reduce(r); + } + + Classic.prototype.convert = cConvert; + Classic.prototype.revert = cRevert; + Classic.prototype.reduce = cReduce; + Classic.prototype.mulTo = cMulTo; + Classic.prototype.sqrTo = cSqrTo; + + // (protected) return "-1/this % 2^DB"; useful for Mont. reduction + // justification: + // xy == 1 (mod m) + // xy = 1+km + // xy(2-xy) = (1+km)(1-km) + // x[y(2-xy)] = 1-k^2m^2 + // x[y(2-xy)] == 1 (mod m^2) + // if y is 1/x mod m, then y(2-xy) is 1/x mod m^2 + // should reduce x and y(2-xy) by m^2 at each step to keep size bounded. + // JS multiply "overflows" differently from C/C++, so care is needed here. + function bnpInvDigit() { + if (this.t < 1) return 0; + var x = this[0]; + if ((x & 1) == 0) return 0; + var y = x & 3; // y == 1/x mod 2^2 + y = (y * (2 - (x & 0xf) * y)) & 0xf; // y == 1/x mod 2^4 + y = (y * (2 - (x & 0xff) * y)) & 0xff; // y == 1/x mod 2^8 + y = (y * (2 - (((x & 0xffff) * y) & 0xffff))) & 0xffff; // y == 1/x mod 2^16 + // last step - calculate inverse mod DV directly; + // assumes 16 < DB <= 32 and assumes ability to handle 48-bit ints + y = (y * (2 - ((x * y) % this.DV))) % this.DV; // y == 1/x mod 2^dbits + // we really want the negative inverse, and -DV < y < DV + return y > 0 ? this.DV - y : -y; + } + + // Montgomery reduction + function Montgomery(m) { + this.m = m; + this.mp = m.invDigit(); + this.mpl = this.mp & 0x7fff; + this.mph = this.mp >> 15; + this.um = (1 << (m.DB - 15)) - 1; + this.mt2 = 2 * m.t; + } + + // xR mod m + function montConvert(x) { + var r = nbi(); + x.abs().dlShiftTo(this.m.t, r); + r.divRemTo(this.m, null, r); + if (x.s < 0 && r.compareTo(BigInteger.ZERO) > 0) this.m.subTo(r, r); + return r; + } + + // x/R mod m + function montRevert(x) { + var r = nbi(); + x.copyTo(r); + this.reduce(r); + return r; + } + + // x = x/R mod m (HAC 14.32) + function montReduce(x) { + while ( + x.t <= this.mt2 // pad x so am has enough room later + ) + x[x.t++] = 0; + for (var i = 0; i < this.m.t; ++i) { + // faster way of calculating u0 = x[i]*mp mod DV + var j = x[i] & 0x7fff; + var u0 = + (j * this.mpl + + (((j * this.mph + (x[i] >> 15) * this.mpl) & this.um) << 15)) & + x.DM; + // use am to combine the multiply-shift-add into one call + j = i + this.m.t; + x[j] += this.m.am(0, u0, x, i, 0, this.m.t); + // propagate carry + while (x[j] >= x.DV) { + x[j] -= x.DV; + x[++j]++; + } + } + x.clamp(); + x.drShiftTo(this.m.t, x); + if (x.compareTo(this.m) >= 0) x.subTo(this.m, x); + } + + // r = "x^2/R mod m"; x != r + function montSqrTo(x, r) { + x.squareTo(r); + this.reduce(r); + } + + // r = "xy/R mod m"; x,y != r + function montMulTo(x, y, r) { + x.multiplyTo(y, r); + this.reduce(r); + } + + Montgomery.prototype.convert = montConvert; + Montgomery.prototype.revert = montRevert; + Montgomery.prototype.reduce = montReduce; + Montgomery.prototype.mulTo = montMulTo; + Montgomery.prototype.sqrTo = montSqrTo; + + // (protected) true iff this is even + function bnpIsEven() { + return (this.t > 0 ? this[0] & 1 : this.s) == 0; + } + + // (protected) this^e, e < 2^32, doing sqr and mul with "r" (HAC 14.79) + function bnpExp(e, z) { + if (e > 0xffffffff || e < 1) return BigInteger.ONE; + var r = nbi(), + r2 = nbi(), + g = z.convert(this), + i = nbits(e) - 1; + g.copyTo(r); + while (--i >= 0) { + z.sqrTo(r, r2); + if ((e & (1 << i)) > 0) z.mulTo(r2, g, r); + else { + var t = r; + r = r2; + r2 = t; + } + } + return z.revert(r); + } + + // (public) this^e % m, 0 <= e < 2^32 + function bnModPowInt(e, m) { + var z; + if (e < 256 || m.isEven()) z = new Classic(m); + else z = new Montgomery(m); + return this.exp(e, z); + } + + // protected + BigInteger.prototype.copyTo = bnpCopyTo; + BigInteger.prototype.fromInt = bnpFromInt; + BigInteger.prototype.fromString = bnpFromString; + BigInteger.prototype.clamp = bnpClamp; + BigInteger.prototype.dlShiftTo = bnpDLShiftTo; + BigInteger.prototype.drShiftTo = bnpDRShiftTo; + BigInteger.prototype.lShiftTo = bnpLShiftTo; + BigInteger.prototype.rShiftTo = bnpRShiftTo; + BigInteger.prototype.subTo = bnpSubTo; + BigInteger.prototype.multiplyTo = bnpMultiplyTo; + BigInteger.prototype.squareTo = bnpSquareTo; + BigInteger.prototype.divRemTo = bnpDivRemTo; + BigInteger.prototype.invDigit = bnpInvDigit; + BigInteger.prototype.isEven = bnpIsEven; + BigInteger.prototype.exp = bnpExp; + + // public + BigInteger.prototype.toString = bnToString; + BigInteger.prototype.negate = bnNegate; + BigInteger.prototype.abs = bnAbs; + BigInteger.prototype.compareTo = bnCompareTo; + BigInteger.prototype.bitLength = bnBitLength; + BigInteger.prototype.mod = bnMod; + BigInteger.prototype.modPowInt = bnModPowInt; + + // "constants" + BigInteger.ZERO = nbv(0); + BigInteger.ONE = nbv(1); + BigInteger.valueOf = nbv; + + // Copyright (c) 2005-2009 Tom Wu + // All Rights Reserved. + // See "LICENSE" for details. + + // Extended JavaScript BN functions, required for RSA private ops. + + // Version 1.1: new BigInteger("0", 10) returns "proper" zero + // Version 1.2: square() API, isProbablePrime fix + + // (public) + function bnClone() { + var r = nbi(); + this.copyTo(r); + return r; + } + + // (public) return value as integer + function bnIntValue() { + if (this.s < 0) { + if (this.t == 1) return this[0] - this.DV; + else if (this.t == 0) return -1; + } else if (this.t == 1) return this[0]; + else if (this.t == 0) return 0; + // assumes 16 < DB < 32 + return ((this[1] & ((1 << (32 - this.DB)) - 1)) << this.DB) | this[0]; + } + + // (public) return value as byte + function bnByteValue() { + return this.t == 0 ? this.s : (this[0] << 24) >> 24; + } + + // (public) return value as short (assumes DB>=16) + function bnShortValue() { + return this.t == 0 ? this.s : (this[0] << 16) >> 16; + } + + // (protected) return x s.t. r^x < DV + function bnpChunkSize(r) { + return Math.floor((Math.LN2 * this.DB) / Math.log(r)); + } + + // (public) 0 if this == 0, 1 if this > 0 + function bnSigNum() { + if (this.s < 0) return -1; + else if (this.t <= 0 || (this.t == 1 && this[0] <= 0)) return 0; + else return 1; + } + + // (protected) convert to radix string + function bnpToRadix(b) { + if (b == null) b = 10; + if (this.signum() == 0 || b < 2 || b > 36) return '0'; + var cs = this.chunkSize(b); + var a = Math.pow(b, cs); + var d = nbv(a), + y = nbi(), + z = nbi(), + r = ''; + this.divRemTo(d, y, z); + while (y.signum() > 0) { + r = (a + z.intValue()).toString(b).substr(1) + r; + y.divRemTo(d, y, z); + } + return z.intValue().toString(b) + r; + } + + // (protected) convert from radix string + function bnpFromRadix(s, b) { + this.fromInt(0); + if (b == null) b = 10; + var cs = this.chunkSize(b); + var d = Math.pow(b, cs), + mi = false, + j = 0, + w = 0; + for (var i = 0; i < s.length; ++i) { + var x = intAt(s, i); + if (x < 0) { + if (s.charAt(i) == '-' && this.signum() == 0) mi = true; + continue; + } + w = b * w + x; + if (++j >= cs) { + this.dMultiply(d); + this.dAddOffset(w, 0); + j = 0; + w = 0; + } + } + if (j > 0) { + this.dMultiply(Math.pow(b, j)); + this.dAddOffset(w, 0); + } + if (mi) BigInteger.ZERO.subTo(this, this); + } + + // (protected) alternate constructor + function bnpFromNumber(a, b, c) { + if ('number' == typeof b) { + // new BigInteger(int,int,RNG) + if (a < 2) this.fromInt(1); + else { + this.fromNumber(a, c); + if (!this.testBit(a - 1)) + // force MSB set + this.bitwiseTo(BigInteger.ONE.shiftLeft(a - 1), op_or, this); + if (this.isEven()) this.dAddOffset(1, 0); // force odd + while (!this.isProbablePrime(b)) { + this.dAddOffset(2, 0); + if (this.bitLength() > a) + this.subTo(BigInteger.ONE.shiftLeft(a - 1), this); + } + } + } else { + // new BigInteger(int,RNG) + var x = new Array(), + t = a & 7; + x.length = (a >> 3) + 1; + b.nextBytes(x); + if (t > 0) x[0] &= (1 << t) - 1; + else x[0] = 0; + this.fromString(x, 256); + } + } + + // (public) convert to bigendian byte array + function bnToByteArray() { + var i = this.t, + r = new Array(); + r[0] = this.s; + var p = this.DB - ((i * this.DB) % 8), + d, + k = 0; + if (i-- > 0) { + if (p < this.DB && (d = this[i] >> p) != (this.s & this.DM) >> p) + r[k++] = d | (this.s << (this.DB - p)); + while (i >= 0) { + if (p < 8) { + d = (this[i] & ((1 << p) - 1)) << (8 - p); + d |= this[--i] >> (p += this.DB - 8); + } else { + d = (this[i] >> (p -= 8)) & 0xff; + if (p <= 0) { + p += this.DB; + --i; + } + } + if ((d & 0x80) != 0) d |= -256; + if (k == 0 && (this.s & 0x80) != (d & 0x80)) ++k; + if (k > 0 || d != this.s) r[k++] = d; + } + } + return r; + } + + function bnEquals(a) { + return this.compareTo(a) == 0; + } + function bnMin(a) { + return this.compareTo(a) < 0 ? this : a; + } + function bnMax(a) { + return this.compareTo(a) > 0 ? this : a; + } + + // (protected) r = this op a (bitwise) + function bnpBitwiseTo(a, op, r) { + var i, + f, + m = Math.min(a.t, this.t); + for (i = 0; i < m; ++i) r[i] = op(this[i], a[i]); + if (a.t < this.t) { + f = a.s & this.DM; + for (i = m; i < this.t; ++i) r[i] = op(this[i], f); + r.t = this.t; + } else { + f = this.s & this.DM; + for (i = m; i < a.t; ++i) r[i] = op(f, a[i]); + r.t = a.t; + } + r.s = op(this.s, a.s); + r.clamp(); + } + + // (public) this & a + function op_and(x, y) { + return x & y; + } + function bnAnd(a) { + var r = nbi(); + this.bitwiseTo(a, op_and, r); + return r; + } + + // (public) this | a + function op_or(x, y) { + return x | y; + } + function bnOr(a) { + var r = nbi(); + this.bitwiseTo(a, op_or, r); + return r; + } + + // (public) this ^ a + function op_xor(x, y) { + return x ^ y; + } + function bnXor(a) { + var r = nbi(); + this.bitwiseTo(a, op_xor, r); + return r; + } + + // (public) this & ~a + function op_andnot(x, y) { + return x & ~y; + } + function bnAndNot(a) { + var r = nbi(); + this.bitwiseTo(a, op_andnot, r); + return r; + } + + // (public) ~this + function bnNot() { + var r = nbi(); + for (var i = 0; i < this.t; ++i) r[i] = this.DM & ~this[i]; + r.t = this.t; + r.s = ~this.s; + return r; + } + + // (public) this << n + function bnShiftLeft(n) { + var r = nbi(); + if (n < 0) this.rShiftTo(-n, r); + else this.lShiftTo(n, r); + return r; + } + + // (public) this >> n + function bnShiftRight(n) { + var r = nbi(); + if (n < 0) this.lShiftTo(-n, r); + else this.rShiftTo(n, r); + return r; + } + + // return index of lowest 1-bit in x, x < 2^31 + function lbit(x) { + if (x == 0) return -1; + var r = 0; + if ((x & 0xffff) == 0) { + x >>= 16; + r += 16; + } + if ((x & 0xff) == 0) { + x >>= 8; + r += 8; + } + if ((x & 0xf) == 0) { + x >>= 4; + r += 4; + } + if ((x & 3) == 0) { + x >>= 2; + r += 2; + } + if ((x & 1) == 0) ++r; + return r; + } + + // (public) returns index of lowest 1-bit (or -1 if none) + function bnGetLowestSetBit() { + for (var i = 0; i < this.t; ++i) + if (this[i] != 0) return i * this.DB + lbit(this[i]); + if (this.s < 0) return this.t * this.DB; + return -1; + } + + // return number of 1 bits in x + function cbit(x) { + var r = 0; + while (x != 0) { + x &= x - 1; + ++r; + } + return r; + } + + // (public) return number of set bits + function bnBitCount() { + var r = 0, + x = this.s & this.DM; + for (var i = 0; i < this.t; ++i) r += cbit(this[i] ^ x); + return r; + } + + // (public) true iff nth bit is set + function bnTestBit(n) { + var j = Math.floor(n / this.DB); + if (j >= this.t) return this.s != 0; + return (this[j] & (1 << n % this.DB)) != 0; + } + + // (protected) this op (1<>= this.DB; + } + if (a.t < this.t) { + c += a.s; + while (i < this.t) { + c += this[i]; + r[i++] = c & this.DM; + c >>= this.DB; + } + c += this.s; + } else { + c += this.s; + while (i < a.t) { + c += a[i]; + r[i++] = c & this.DM; + c >>= this.DB; + } + c += a.s; + } + r.s = c < 0 ? -1 : 0; + if (c > 0) r[i++] = c; + else if (c < -1) r[i++] = this.DV + c; + r.t = i; + r.clamp(); + } + + // (public) this + a + function bnAdd(a) { + var r = nbi(); + this.addTo(a, r); + return r; + } + + // (public) this - a + function bnSubtract(a) { + var r = nbi(); + this.subTo(a, r); + return r; + } + + // (public) this * a + function bnMultiply(a) { + var r = nbi(); + this.multiplyTo(a, r); + return r; + } + + // (public) this^2 + function bnSquare() { + var r = nbi(); + this.squareTo(r); + return r; + } + + // (public) this / a + function bnDivide(a) { + var r = nbi(); + this.divRemTo(a, r, null); + return r; + } + + // (public) this % a + function bnRemainder(a) { + var r = nbi(); + this.divRemTo(a, null, r); + return r; + } + + // (public) [this/a,this%a] + function bnDivideAndRemainder(a) { + var q = nbi(), + r = nbi(); + this.divRemTo(a, q, r); + return new Array(q, r); + } + + // (protected) this *= n, this >= 0, 1 < n < DV + function bnpDMultiply(n) { + this[this.t] = this.am(0, n - 1, this, 0, 0, this.t); + ++this.t; + this.clamp(); + } + + // (protected) this += n << w words, this >= 0 + function bnpDAddOffset(n, w) { + if (n == 0) return; + while (this.t <= w) this[this.t++] = 0; + this[w] += n; + while (this[w] >= this.DV) { + this[w] -= this.DV; + if (++w >= this.t) this[this.t++] = 0; + ++this[w]; + } + } + + // A "null" reducer + function NullExp() { } + function nNop(x) { + return x; + } + function nMulTo(x, y, r) { + x.multiplyTo(y, r); + } + function nSqrTo(x, r) { + x.squareTo(r); + } + + NullExp.prototype.convert = nNop; + NullExp.prototype.revert = nNop; + NullExp.prototype.mulTo = nMulTo; + NullExp.prototype.sqrTo = nSqrTo; + + // (public) this^e + function bnPow(e) { + return this.exp(e, new NullExp()); + } + + // (protected) r = lower n words of "this * a", a.t <= n + // "this" should be the larger one if appropriate. + function bnpMultiplyLowerTo(a, n, r) { + var i = Math.min(this.t + a.t, n); + r.s = 0; // assumes a,this >= 0 + r.t = i; + while (i > 0) r[--i] = 0; + var j; + for (j = r.t - this.t; i < j; ++i) + r[i + this.t] = this.am(0, a[i], r, i, 0, this.t); + for (j = Math.min(a.t, n); i < j; ++i) this.am(0, a[i], r, i, 0, n - i); + r.clamp(); + } + + // (protected) r = "this * a" without lower n words, n > 0 + // "this" should be the larger one if appropriate. + function bnpMultiplyUpperTo(a, n, r) { + --n; + var i = (r.t = this.t + a.t - n); + r.s = 0; // assumes a,this >= 0 + while (--i >= 0) r[i] = 0; + for (i = Math.max(n - this.t, 0); i < a.t; ++i) + r[this.t + i - n] = this.am(n - i, a[i], r, 0, 0, this.t + i - n); + r.clamp(); + r.drShiftTo(1, r); + } + + // Barrett modular reduction + function Barrett(m) { + // setup Barrett + this.r2 = nbi(); + this.q3 = nbi(); + BigInteger.ONE.dlShiftTo(2 * m.t, this.r2); + this.mu = this.r2.divide(m); + this.m = m; + } + + function barrettConvert(x) { + if (x.s < 0 || x.t > 2 * this.m.t) return x.mod(this.m); + else if (x.compareTo(this.m) < 0) return x; + else { + var r = nbi(); + x.copyTo(r); + this.reduce(r); + return r; + } + } + + function barrettRevert(x) { + return x; + } + + // x = x mod m (HAC 14.42) + function barrettReduce(x) { + x.drShiftTo(this.m.t - 1, this.r2); + if (x.t > this.m.t + 1) { + x.t = this.m.t + 1; + x.clamp(); + } + this.mu.multiplyUpperTo(this.r2, this.m.t + 1, this.q3); + this.m.multiplyLowerTo(this.q3, this.m.t + 1, this.r2); + while (x.compareTo(this.r2) < 0) x.dAddOffset(1, this.m.t + 1); + x.subTo(this.r2, x); + while (x.compareTo(this.m) >= 0) x.subTo(this.m, x); + } + + // r = x^2 mod m; x != r + function barrettSqrTo(x, r) { + x.squareTo(r); + this.reduce(r); + } + + // r = x*y mod m; x,y != r + function barrettMulTo(x, y, r) { + x.multiplyTo(y, r); + this.reduce(r); + } + + Barrett.prototype.convert = barrettConvert; + Barrett.prototype.revert = barrettRevert; + Barrett.prototype.reduce = barrettReduce; + Barrett.prototype.mulTo = barrettMulTo; + Barrett.prototype.sqrTo = barrettSqrTo; + + // (public) this^e % m (HAC 14.85) + function bnModPow(e, m) { + var i = e.bitLength(), + k, + r = nbv(1), + z; + if (i <= 0) return r; + else if (i < 18) k = 1; + else if (i < 48) k = 3; + else if (i < 144) k = 4; + else if (i < 768) k = 5; + else k = 6; + if (i < 8) z = new Classic(m); + else if (m.isEven()) z = new Barrett(m); + else z = new Montgomery(m); + + // precomputation + var g = new Array(), + n = 3, + k1 = k - 1, + km = (1 << k) - 1; + g[1] = z.convert(this); + if (k > 1) { + var g2 = nbi(); + z.sqrTo(g[1], g2); + while (n <= km) { + g[n] = nbi(); + z.mulTo(g2, g[n - 2], g[n]); + n += 2; + } + } + + var j = e.t - 1, + w, + is1 = true, + r2 = nbi(), + t; + i = nbits(e[j]) - 1; + while (j >= 0) { + if (i >= k1) w = (e[j] >> (i - k1)) & km; + else { + w = (e[j] & ((1 << (i + 1)) - 1)) << (k1 - i); + if (j > 0) w |= e[j - 1] >> (this.DB + i - k1); + } + + n = k; + while ((w & 1) == 0) { + w >>= 1; + --n; + } + if ((i -= n) < 0) { + i += this.DB; + --j; + } + if (is1) { + // ret == 1, don't bother squaring or multiplying it + g[w].copyTo(r); + is1 = false; + } else { + while (n > 1) { + z.sqrTo(r, r2); + z.sqrTo(r2, r); + n -= 2; + } + if (n > 0) z.sqrTo(r, r2); + else { + t = r; + r = r2; + r2 = t; + } + z.mulTo(r2, g[w], r); + } + + while (j >= 0 && (e[j] & (1 << i)) == 0) { + z.sqrTo(r, r2); + t = r; + r = r2; + r2 = t; + if (--i < 0) { + i = this.DB - 1; + --j; + } + } + } + return z.revert(r); + } + + // (public) gcd(this,a) (HAC 14.54) + function bnGCD(a) { + var x = this.s < 0 ? this.negate() : this.clone(); + var y = a.s < 0 ? a.negate() : a.clone(); + if (x.compareTo(y) < 0) { + var t = x; + x = y; + y = t; + } + var i = x.getLowestSetBit(), + g = y.getLowestSetBit(); + if (g < 0) return x; + if (i < g) g = i; + if (g > 0) { + x.rShiftTo(g, x); + y.rShiftTo(g, y); + } + while (x.signum() > 0) { + if ((i = x.getLowestSetBit()) > 0) x.rShiftTo(i, x); + if ((i = y.getLowestSetBit()) > 0) y.rShiftTo(i, y); + if (x.compareTo(y) >= 0) { + x.subTo(y, x); + x.rShiftTo(1, x); + } else { + y.subTo(x, y); + y.rShiftTo(1, y); + } + } + if (g > 0) y.lShiftTo(g, y); + return y; + } + + // (protected) this % n, n < 2^26 + function bnpModInt(n) { + if (n <= 0) return 0; + var d = this.DV % n, + r = this.s < 0 ? n - 1 : 0; + if (this.t > 0) + if (d == 0) r = this[0] % n; + else for (var i = this.t - 1; i >= 0; --i) r = (d * r + this[i]) % n; + return r; + } + + // (public) 1/this % m (HAC 14.61) + function bnModInverse(m) { + var ac = m.isEven(); + if ((this.isEven() && ac) || m.signum() == 0) return BigInteger.ZERO; + var u = m.clone(), + v = this.clone(); + var a = nbv(1), + b = nbv(0), + c = nbv(0), + d = nbv(1); + while (u.signum() != 0) { + while (u.isEven()) { + u.rShiftTo(1, u); + if (ac) { + if (!a.isEven() || !b.isEven()) { + a.addTo(this, a); + b.subTo(m, b); + } + a.rShiftTo(1, a); + } else if (!b.isEven()) b.subTo(m, b); + b.rShiftTo(1, b); + } + while (v.isEven()) { + v.rShiftTo(1, v); + if (ac) { + if (!c.isEven() || !d.isEven()) { + c.addTo(this, c); + d.subTo(m, d); + } + c.rShiftTo(1, c); + } else if (!d.isEven()) d.subTo(m, d); + d.rShiftTo(1, d); + } + if (u.compareTo(v) >= 0) { + u.subTo(v, u); + if (ac) a.subTo(c, a); + b.subTo(d, b); + } else { + v.subTo(u, v); + if (ac) c.subTo(a, c); + d.subTo(b, d); + } + } + if (v.compareTo(BigInteger.ONE) != 0) return BigInteger.ZERO; + if (d.compareTo(m) >= 0) return d.subtract(m); + if (d.signum() < 0) d.addTo(m, d); + else return d; + if (d.signum() < 0) return d.add(m); + else return d; + } + + var lowprimes = [ + 2, + 3, + 5, + 7, + 11, + 13, + 17, + 19, + 23, + 29, + 31, + 37, + 41, + 43, + 47, + 53, + 59, + 61, + 67, + 71, + 73, + 79, + 83, + 89, + 97, + 101, + 103, + 107, + 109, + 113, + 127, + 131, + 137, + 139, + 149, + 151, + 157, + 163, + 167, + 173, + 179, + 181, + 191, + 193, + 197, + 199, + 211, + 223, + 227, + 229, + 233, + 239, + 241, + 251, + 257, + 263, + 269, + 271, + 277, + 281, + 283, + 293, + 307, + 311, + 313, + 317, + 331, + 337, + 347, + 349, + 353, + 359, + 367, + 373, + 379, + 383, + 389, + 397, + 401, + 409, + 419, + 421, + 431, + 433, + 439, + 443, + 449, + 457, + 461, + 463, + 467, + 479, + 487, + 491, + 499, + 503, + 509, + 521, + 523, + 541, + 547, + 557, + 563, + 569, + 571, + 577, + 587, + 593, + 599, + 601, + 607, + 613, + 617, + 619, + 631, + 641, + 643, + 647, + 653, + 659, + 661, + 673, + 677, + 683, + 691, + 701, + 709, + 719, + 727, + 733, + 739, + 743, + 751, + 757, + 761, + 769, + 773, + 787, + 797, + 809, + 811, + 821, + 823, + 827, + 829, + 839, + 853, + 857, + 859, + 863, + 877, + 881, + 883, + 887, + 907, + 911, + 919, + 929, + 937, + 941, + 947, + 953, + 967, + 971, + 977, + 983, + 991, + 997, + ]; + var lplim = (1 << 26) / lowprimes[lowprimes.length - 1]; + + // (public) test primality with certainty >= 1-.5^t + function bnIsProbablePrime(t) { + var i, + x = this.abs(); + if (x.t == 1 && x[0] <= lowprimes[lowprimes.length - 1]) { + for (i = 0; i < lowprimes.length; ++i) + if (x[0] == lowprimes[i]) return true; + return false; + } + if (x.isEven()) return false; + i = 1; + while (i < lowprimes.length) { + var m = lowprimes[i], + j = i + 1; + while (j < lowprimes.length && m < lplim) m *= lowprimes[j++]; + m = x.modInt(m); + while (i < j) if (m % lowprimes[i++] == 0) return false; + } + return x.millerRabin(t); + } + + // (protected) true if probably prime (HAC 4.24, Miller-Rabin) + function bnpMillerRabin(t) { + var n1 = this.subtract(BigInteger.ONE); + var k = n1.getLowestSetBit(); + if (k <= 0) return false; + var r = n1.shiftRight(k); + t = (t + 1) >> 1; + if (t > lowprimes.length) t = lowprimes.length; + var a = nbi(); + for (var i = 0; i < t; ++i) { + //Pick bases at random, instead of starting at 2 + a.fromInt(lowprimes[Math.floor(Math.random() * lowprimes.length)]); + var y = a.modPow(r, this); + if (y.compareTo(BigInteger.ONE) != 0 && y.compareTo(n1) != 0) { + var j = 1; + while (j++ < k && y.compareTo(n1) != 0) { + y = y.modPowInt(2, this); + if (y.compareTo(BigInteger.ONE) == 0) return false; + } + if (y.compareTo(n1) != 0) return false; + } + } + return true; + } + + // protected + BigInteger.prototype.chunkSize = bnpChunkSize; + BigInteger.prototype.toRadix = bnpToRadix; + BigInteger.prototype.fromRadix = bnpFromRadix; + BigInteger.prototype.fromNumber = bnpFromNumber; + BigInteger.prototype.bitwiseTo = bnpBitwiseTo; + BigInteger.prototype.changeBit = bnpChangeBit; + BigInteger.prototype.addTo = bnpAddTo; + BigInteger.prototype.dMultiply = bnpDMultiply; + BigInteger.prototype.dAddOffset = bnpDAddOffset; + BigInteger.prototype.multiplyLowerTo = bnpMultiplyLowerTo; + BigInteger.prototype.multiplyUpperTo = bnpMultiplyUpperTo; + BigInteger.prototype.modInt = bnpModInt; + BigInteger.prototype.millerRabin = bnpMillerRabin; + + // public + BigInteger.prototype.clone = bnClone; + BigInteger.prototype.intValue = bnIntValue; + BigInteger.prototype.byteValue = bnByteValue; + BigInteger.prototype.shortValue = bnShortValue; + BigInteger.prototype.signum = bnSigNum; + BigInteger.prototype.toByteArray = bnToByteArray; + BigInteger.prototype.equals = bnEquals; + BigInteger.prototype.min = bnMin; + BigInteger.prototype.max = bnMax; + BigInteger.prototype.and = bnAnd; + BigInteger.prototype.or = bnOr; + BigInteger.prototype.xor = bnXor; + BigInteger.prototype.andNot = bnAndNot; + BigInteger.prototype.not = bnNot; + BigInteger.prototype.shiftLeft = bnShiftLeft; + BigInteger.prototype.shiftRight = bnShiftRight; + BigInteger.prototype.getLowestSetBit = bnGetLowestSetBit; + BigInteger.prototype.bitCount = bnBitCount; + BigInteger.prototype.testBit = bnTestBit; + BigInteger.prototype.setBit = bnSetBit; + BigInteger.prototype.clearBit = bnClearBit; + BigInteger.prototype.flipBit = bnFlipBit; + BigInteger.prototype.add = bnAdd; + BigInteger.prototype.subtract = bnSubtract; + BigInteger.prototype.multiply = bnMultiply; + BigInteger.prototype.divide = bnDivide; + BigInteger.prototype.remainder = bnRemainder; + BigInteger.prototype.divideAndRemainder = bnDivideAndRemainder; + BigInteger.prototype.modPow = bnModPow; + BigInteger.prototype.modInverse = bnModInverse; + BigInteger.prototype.pow = bnPow; + BigInteger.prototype.gcd = bnGCD; + BigInteger.prototype.isProbablePrime = bnIsProbablePrime; + + // JSBN-specific extension + BigInteger.prototype.square = bnSquare; + + // Expose the Barrett function + BigInteger.prototype.Barrett = Barrett; + + // BigInteger interfaces not implemented in jsbn: + + // BigInteger(int signum, byte[] magnitude) + // double doubleValue() + // float floatValue() + // int hashCode() + // long longValue() + // static BigInteger valueOf(long val) + + // Imported from bitcoinjs-lib + + /** + * Turns a byte array into a big integer. + * + * This function will interpret a byte array as a big integer in big + * endian notation and ignore leading zeros. + */ + + BigInteger.fromByteArrayUnsigned = function (ba) { + + if (!ba.length) { + return new BigInteger.valueOf(0); + } else if (ba[0] & 0x80) { + // Prepend a zero so the BigInteger class doesn't mistake this + // for a negative integer. + return new BigInteger([0].concat(ba)); + } else { + return new BigInteger(ba); + } + }; + + /** + * Parse a signed big integer byte representation. + * + * For details on the format please see BigInteger.toByteArraySigned. + */ + + BigInteger.fromByteArraySigned = function (ba) { + // Check for negative value + if (ba[0] & 0x80) { + // Remove sign bit + ba[0] &= 0x7f; + + return BigInteger.fromByteArrayUnsigned(ba).negate(); + } else { + return BigInteger.fromByteArrayUnsigned(ba); + } + }; + + /** + * Returns a byte array representation of the big integer. + * + * This returns the absolute of the contained value in big endian + * form. A value of zero results in an empty array. + */ + + BigInteger.prototype.toByteArrayUnsigned = function () { + var ba = this.abs().toByteArray(); + + // Empty array, nothing to do + if (!ba.length) { + return ba; + } + + // remove leading 0 + if (ba[0] === 0) { + ba = ba.slice(1); + } + + // all values must be positive + for (var i = 0; i < ba.length; ++i) { + ba[i] = (ba[i] < 0) ? ba[i] + 256 : ba[i]; + } + + return ba; + }; + + /* + * Converts big integer to signed byte representation. + * + * The format for this value uses the most significant bit as a sign + * bit. If the most significant bit is already occupied by the + * absolute value, an extra byte is prepended and the sign bit is set + * there. + * + * Examples: + * + * 0 => 0x00 + * 1 => 0x01 + * -1 => 0x81 + * 127 => 0x7f + * -127 => 0xff + * 128 => 0x0080 + * -128 => 0x8080 + * 255 => 0x00ff + * -255 => 0x80ff + * 16300 => 0x3fac + * -16300 => 0xbfac + * 62300 => 0x00f35c + * -62300 => 0x80f35c + */ + + BigInteger.prototype.toByteArraySigned = function () { + var val = this.toByteArrayUnsigned(); + var neg = this.s < 0; + + // if the first bit is set, we always unshift + // either unshift 0x80 or 0x00 + if (val[0] & 0x80) { + val.unshift((neg) ? 0x80 : 0x00); + } + // if the first bit isn't set, set it if negative + else if (neg) { + val[0] |= 0x80; + } + + return val; + }; + + // Random number generator - requires a PRNG backend, e.g. prng4.js + + // For best results, put code like + // + // in your main HTML document. + + var rng_state; + var rng_pool; + var rng_pptr; + + // Mix in a 32-bit integer into the pool + function rng_seed_int(x) { + rng_pool[rng_pptr++] ^= x & 255; + rng_pool[rng_pptr++] ^= (x >> 8) & 255; + rng_pool[rng_pptr++] ^= (x >> 16) & 255; + rng_pool[rng_pptr++] ^= (x >> 24) & 255; + if (rng_pptr >= rng_psize) rng_pptr -= rng_psize; + } + + // Mix in the current time (w/milliseconds) into the pool + function rng_seed_time() { + rng_seed_int(new Date().getTime()); + } + + // Initialize the pool with junk if needed. + if (rng_pool == null) { + rng_pool = new Array(); + rng_pptr = 0; + var t; + if (typeof window !== 'undefined' && window.crypto) { + if (window.crypto.getRandomValues) { + // Use webcrypto if available + var ua = new Uint8Array(32); + window.crypto.getRandomValues(ua); + for (t = 0; t < 32; ++t) rng_pool[rng_pptr++] = ua[t]; + } else if ( + navigator.appName == 'Netscape' && + navigator.appVersion < '5' + ) { + // Extract entropy (256 bits) from NS4 RNG if available + var z = window.crypto.random(32); + for (t = 0; t < z.length; ++t) + rng_pool[rng_pptr++] = z.charCodeAt(t) & 255; + } + } + while (rng_pptr < rng_psize) { + // extract some randomness from Math.random() + t = Math.floor(65536 * Math.random()); + rng_pool[rng_pptr++] = t >>> 8; + rng_pool[rng_pptr++] = t & 255; + } + rng_pptr = 0; + rng_seed_time(); + } + + function rng_get_byte() { + if (rng_state == null) { + rng_seed_time(); + rng_state = prng_newstate(); + rng_state.init(rng_pool); + for (rng_pptr = 0; rng_pptr < rng_pool.length; ++rng_pptr) + rng_pool[rng_pptr] = 0; + rng_pptr = 0; + } + // TODO: allow reseeding after first request + return rng_state.next(); + } + + function rng_get_bytes(ba) { + var i; + for (i = 0; i < ba.length; ++i) ba[i] = rng_get_byte(); + } + + function SecureRandom() { } + + SecureRandom.prototype.nextBytes = rng_get_bytes; + + // prng4.js - uses Arcfour as a PRNG + + function Arcfour() { + this.i = 0; + this.j = 0; + this.S = new Array(); + } + + // Initialize arcfour context from key, an array of ints, each from [0..255] + function ARC4init(key) { + var i, j, t; + for (i = 0; i < 256; ++i) this.S[i] = i; + j = 0; + for (i = 0; i < 256; ++i) { + j = (j + this.S[i] + key[i % key.length]) & 255; + t = this.S[i]; + this.S[i] = this.S[j]; + this.S[j] = t; + } + this.i = 0; + this.j = 0; + } + + function ARC4next() { + var t; + this.i = (this.i + 1) & 255; + this.j = (this.j + this.S[this.i]) & 255; + t = this.S[this.i]; + this.S[this.i] = this.S[this.j]; + this.S[this.j] = t; + return this.S[(t + this.S[this.i]) & 255]; + } + + Arcfour.prototype.init = ARC4init; + Arcfour.prototype.next = ARC4next; + + // Plug in your RNG constructor here + function prng_newstate() { + return new Arcfour(); + } + + // Pool size must be a multiple of 4 and greater than 32. + // An array of bytes the size of the pool will be passed to init() + var rng_psize = 256; + + if (typeof exports !== 'undefined') { + exports = module.exports = { + default: BigInteger, + BigInteger: BigInteger, + SecureRandom: SecureRandom, + }; + } else { + this.jsbn = { + BigInteger: BigInteger, + SecureRandom: SecureRandom, + }; + } +}.call(this)); diff --git a/crypto/api/constants.js b/crypto/api/constants.js index c59f0faa..ebd180d3 100644 --- a/crypto/api/constants.js +++ b/crypto/api/constants.js @@ -1,5 +1,3 @@ -'use strict' - // Qortal TX types const TX_TYPES = { 1: "Genesis", diff --git a/crypto/api/createTransaction.js b/crypto/api/createTransaction.js index 3d9c19d9..c8b35543 100644 --- a/crypto/api/createTransaction.js +++ b/crypto/api/createTransaction.js @@ -1,9 +1,9 @@ -import {transactionTypes as transactions} from './transactions/transactions.js' -import Base58 from './deps/Base58.js' -import {request} from './fetch-request' -import signChat from './transactions/chat/signChat.js' -import signArbitrary from './transactions/arbitrary/signArbitrary.js' -import signArbitraryWithFee from './transactions/arbitrary/signArbitraryWithFee.js' +import { transactionTypes as transactions } from './transactions/transactions' +import Base58 from './deps/Base58' +import { request } from './fetch-request' +import signChat from './transactions/chat/signChat' +import signArbitrary from './transactions/arbitrary/signArbitrary' +import signArbitraryWithFee from './transactions/arbitrary/signArbitraryWithFee' export const createTransaction = (type, keyPair, params) => { const tx = new transactions[type]() @@ -31,8 +31,8 @@ export const signArbitraryTransaction = (arbitraryBytesBase58, arbitraryBytesFor return signArbitrary(arbitraryBytesBase58, arbitraryBytesForSigningBase58, nonce, keyPair) } -export const signArbitraryWithFeeTransaction = (arbitraryBytesBase58, arbitraryBytesForSigningBase58, keyPair) => { - return signArbitraryWithFee(arbitraryBytesBase58, arbitraryBytesForSigningBase58, keyPair) +export const signArbitraryWithFeeTransaction = (arbitraryBytesBase58, arbitraryBytesForSigningBase58, keyPair) => { + return signArbitraryWithFee(arbitraryBytesBase58, arbitraryBytesForSigningBase58, keyPair) } // Process Transactions diff --git a/crypto/api/createWallet.js b/crypto/api/createWallet.js index 1b05c93c..c9057af9 100644 --- a/crypto/api/createWallet.js +++ b/crypto/api/createWallet.js @@ -1,7 +1,7 @@ -import {kdf} from './kdf.js' -import PhraseWallet from './PhraseWallet.js' -import Base58 from './deps/Base58.js' -import {decryptStoredWallet} from './decryptStoredWallet.js' +import { kdf } from './kdf' +import PhraseWallet from './PhraseWallet' +import Base58 from './deps/Base58' +import { decryptStoredWallet } from './decryptStoredWallet' export const createWallet = async (sourceType, source, statusUpdateFn) => { let version, seed diff --git a/crypto/api/decryptStoredWallet.js b/crypto/api/decryptStoredWallet.js index ec8c8281..8fab5092 100644 --- a/crypto/api/decryptStoredWallet.js +++ b/crypto/api/decryptStoredWallet.js @@ -1,10 +1,10 @@ -import Base58 from './deps/Base58.js' -import {kdf} from './kdf.js' -import {AES_CBC, HmacSha512} from 'asmcrypto.js' -import {get, registerTranslateConfig} from '../../core/translate' +import Base58 from './deps/Base58' +import { kdf } from './kdf' +import { AES_CBC, HmacSha512 } from 'asmcrypto.js' +import { get, registerTranslateConfig } from '../../core/translate' registerTranslateConfig({ - loader: lang => fetch(`/language/${lang}.json`).then(res => res.json()) + loader: lang => fetch(`/language/${lang}.json`).then(res => res.json()) }) export const decryptStoredWallet = async (password, wallet, statusFn = () => { }) => { diff --git a/crypto/api/deps/Base58.js b/crypto/api/deps/Base58.js index c0caaca4..b5ac86ae 100644 --- a/crypto/api/deps/Base58.js +++ b/crypto/api/deps/Base58.js @@ -1,10 +1,6 @@ // Generated by CoffeeScript 1.8.0 // == Changed for ES6 modules == // -//(function() { -//var ALPHABET, ALPHABET_MAP, Base58, i; - -//const Base58 = (typeof module !== "undefined" && module !== null ? module.exports : void 0) || (window.Base58 = {}); const Base58 = {}; const ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"; @@ -14,95 +10,92 @@ const ALPHABET_MAP = {}; let i = 0; while (i < ALPHABET.length) { -ALPHABET_MAP[ALPHABET.charAt(i)] = i; -i++; + ALPHABET_MAP[ALPHABET.charAt(i)] = i; + i++; } -Base58.encode = function(buffer) { -buffer = new Uint8Array(buffer); -var carry, digits, j; -if (buffer.length === 0) { - return ""; -} -i = void 0; -j = void 0; -digits = [0]; -i = 0; -while (i < buffer.length) { - j = 0; - while (j < digits.length) { - digits[j] <<= 8; - j++; - } - digits[0] += buffer[i]; - carry = 0; - j = 0; - while (j < digits.length) { - digits[j] += carry; - carry = (digits[j] / 58) | 0; - digits[j] %= 58; - ++j; - } - while (carry) { - digits.push(carry % 58); - carry = (carry / 58) | 0; - } - i++; -} -i = 0; -while (buffer[i] === 0 && i < buffer.length - 1) { - digits.push(0); - i++; -} -return digits.reverse().map(function(digit) { - return ALPHABET[digit]; -}).join(""); +Base58.encode = function (buffer) { + buffer = new Uint8Array(buffer); + var carry, digits, j; + if (buffer.length === 0) { + return ""; + } + i = void 0; + j = void 0; + digits = [0]; + i = 0; + while (i < buffer.length) { + j = 0; + while (j < digits.length) { + digits[j] <<= 8; + j++; + } + digits[0] += buffer[i]; + carry = 0; + j = 0; + while (j < digits.length) { + digits[j] += carry; + carry = (digits[j] / 58) | 0; + digits[j] %= 58; + ++j; + } + while (carry) { + digits.push(carry % 58); + carry = (carry / 58) | 0; + } + i++; + } + i = 0; + while (buffer[i] === 0 && i < buffer.length - 1) { + digits.push(0); + i++; + } + return digits.reverse().map(function (digit) { + return ALPHABET[digit]; + }).join(""); }; -Base58.decode = function(string) { -var bytes, c, carry, j; -if (string.length === 0) { - return new (typeof Uint8Array !== "undefined" && Uint8Array !== null ? Uint8Array : Buffer)(0); -} -i = void 0; -j = void 0; -bytes = [0]; -i = 0; -while (i < string.length) { - c = string[i]; - if (!(c in ALPHABET_MAP)) { - throw "Base58.decode received unacceptable input. Character '" + c + "' is not in the Base58 alphabet."; - } - j = 0; - while (j < bytes.length) { - bytes[j] *= 58; - j++; - } - bytes[0] += ALPHABET_MAP[c]; - carry = 0; - j = 0; - while (j < bytes.length) { - bytes[j] += carry; - carry = bytes[j] >> 8; - bytes[j] &= 0xff; - ++j; - } - while (carry) { - bytes.push(carry & 0xff); - carry >>= 8; - } - i++; -} -i = 0; -while (string[i] === "1" && i < string.length - 1) { - bytes.push(0); - i++; -} -return new (typeof Uint8Array !== "undefined" && Uint8Array !== null ? Uint8Array : Buffer)(bytes.reverse()); +Base58.decode = function (string) { + var bytes, c, carry, j; + if (string.length === 0) { + return new (typeof Uint8Array !== "undefined" && Uint8Array !== null ? Uint8Array : Buffer)(0); + } + i = void 0; + j = void 0; + bytes = [0]; + i = 0; + while (i < string.length) { + c = string[i]; + if (!(c in ALPHABET_MAP)) { + throw "Base58.decode received unacceptable input. Character '" + c + "' is not in the Base58 alphabet."; + } + j = 0; + while (j < bytes.length) { + bytes[j] *= 58; + j++; + } + bytes[0] += ALPHABET_MAP[c]; + carry = 0; + j = 0; + while (j < bytes.length) { + bytes[j] += carry; + carry = bytes[j] >> 8; + bytes[j] &= 0xff; + ++j; + } + while (carry) { + bytes.push(carry & 0xff); + carry >>= 8; + } + i++; + } + i = 0; + while (string[i] === "1" && i < string.length - 1) { + bytes.push(0); + i++; + } + return new (typeof Uint8Array !== "undefined" && Uint8Array !== null ? Uint8Array : Buffer)(bytes.reverse()); }; - // == Changed for ES6 modules == // -//}).call(this); - -export default Base58; \ No newline at end of file +export default Base58; diff --git a/crypto/api/deps/Base64.js b/crypto/api/deps/Base64.js index 1697dd6a..b97b3848 100644 --- a/crypto/api/deps/Base64.js +++ b/crypto/api/deps/Base64.js @@ -1,23 +1,18 @@ const Base64 = {}; - - Base64.decode = function (string) { - const binaryString = atob(string); - const binaryLength = binaryString.length; - const bytes = new Uint8Array(binaryLength); + const binaryString = atob(string); + const binaryLength = binaryString.length; + const bytes = new Uint8Array(binaryLength); - for (let i = 0; i < binaryLength; i++) { - bytes[i] = binaryString.charCodeAt(i); - } + for (let i = 0; i < binaryLength; i++) { + bytes[i] = binaryString.charCodeAt(i); + } - const decoder = new TextDecoder(); + const decoder = new TextDecoder(); return decoder.decode(bytes); }; - - - export default Base64; diff --git a/crypto/api/deps/bcrypt.js b/crypto/api/deps/bcrypt.js index b067a2fa..ce9e3ce9 100644 --- a/crypto/api/deps/bcrypt.js +++ b/crypto/api/deps/bcrypt.js @@ -31,1349 +31,1351 @@ * Released under the Apache License, Version 2.0 * see: https://github.com/dcodeIO/bcrypt.js for details */ -(function(global, factory) { +(function (global, factory) { /* AMD */ if (typeof define === 'function' && define["amd"]) - define([], factory); + define([], factory); /* CommonJS */ else if (typeof require === 'function' && typeof module === "object" && module && module["exports"]) - module["exports"] = factory(); + module["exports"] = factory(); /* Global */ else - (global["dcodeIO"] = global["dcodeIO"] || {})["bcrypt"] = factory(); + (global["dcodeIO"] = global["dcodeIO"] || {})["bcrypt"] = factory(); -}(this, function() { - "use strict"; +}(this, function () { + // == Changed for ESM support == // + // "use strict"; - /** - * bcrypt namespace. - * @type {Object.} - */ - var bcrypt = {}; + /** + * bcrypt namespace. + * @type {Object.} + */ + var bcrypt = {}; - /** - * The random implementation to use as a fallback. - * @type {?function(number):!Array.} - * @inner - */ - var randomFallback = null; + /** + * The random implementation to use as a fallback. + * @type {?function(number):!Array.} + * @inner + */ + var randomFallback = null; - /** - * Generates cryptographically secure random bytes. - * @function - * @param {number} len Bytes length - * @returns {!Array.} Random bytes - * @throws {Error} If no random implementation is available - * @inner - */ - function random(len) { + /** + * Generates cryptographically secure random bytes. + * @function + * @param {number} len Bytes length + * @returns {!Array.} Random bytes + * @throws {Error} If no random implementation is available + * @inner + */ + function random(len) { /* node */ if (typeof module !== 'undefined' && module && module['exports']) - try { - return require("crypto")['randomBytes'](len); - } catch (e) {} + try { + return require("crypto")['randomBytes'](len); + } catch (e) { } /* WCA */ try { - var a; (self['crypto']||self['msCrypto'])['getRandomValues'](a = new Uint32Array(len)); - return Array.prototype.slice.call(a); - } catch (e) {} + var a; (self['crypto'] || self['msCrypto'])['getRandomValues'](a = new Uint32Array(len)); + return Array.prototype.slice.call(a); + } catch (e) { } /* fallback */ if (!randomFallback) - throw Error("Neither WebCryptoAPI nor a crypto module is available. Use bcrypt.setRandomFallback to set an alternative"); - return randomFallback(len); - } - - // Test if any secure randomness source is available - var randomAvailable = false; - try { - random(1); - randomAvailable = true; - } catch (e) {} - - // Default fallback, if any - randomFallback = null; - /** - * Sets the pseudo random number generator to use as a fallback if neither node's `crypto` module nor the Web Crypto - * API is available. Please note: It is highly important that the PRNG used is cryptographically secure and that it - * is seeded properly! - * @param {?function(number):!Array.} random Function taking the number of bytes to generate as its - * sole argument, returning the corresponding array of cryptographically secure random byte values. - * @see http://nodejs.org/api/crypto.html - * @see http://www.w3.org/TR/WebCryptoAPI/ - */ - bcrypt.setRandomFallback = function(random) { - randomFallback = random; - }; - - /** - * Synchronously generates a salt. - * @param {number=} rounds Number of rounds to use, defaults to 10 if omitted - * @param {number=} seed_length Not supported. - * @returns {string} Resulting salt - * @throws {Error} If a random fallback is required but not set - * @expose - */ - bcrypt.genSaltSync = function(rounds, seed_length) { - rounds = rounds || GENSALT_DEFAULT_LOG2_ROUNDS; - if (typeof rounds !== 'number') - throw Error("Illegal arguments: "+(typeof rounds)+", "+(typeof seed_length)); - if (rounds < 4) - rounds = 4; - else if (rounds > 31) - rounds = 31; - var salt = []; - salt.push("$2a$"); - if (rounds < 10) - salt.push("0"); - salt.push(rounds.toString()); - salt.push('$'); - salt.push(base64_encode(random(BCRYPT_SALT_LEN), BCRYPT_SALT_LEN)); // May throw - return salt.join(''); - }; - - /** - * Asynchronously generates a salt. - * @param {(number|function(Error, string=))=} rounds Number of rounds to use, defaults to 10 if omitted - * @param {(number|function(Error, string=))=} seed_length Not supported. - * @param {function(Error, string=)=} callback Callback receiving the error, if any, and the resulting salt - * @returns {!Promise} If `callback` has been omitted - * @throws {Error} If `callback` is present but not a function - * @expose - */ - bcrypt.genSalt = function(rounds, seed_length, callback) { - if (typeof seed_length === 'function') - callback = seed_length, - seed_length = undefined; // Not supported. - if (typeof rounds === 'function') - callback = rounds, - rounds = undefined; - if (typeof rounds === 'undefined') - rounds = GENSALT_DEFAULT_LOG2_ROUNDS; - else if (typeof rounds !== 'number') - throw Error("illegal arguments: "+(typeof rounds)); - - function _async(callback) { - nextTick(function() { // Pretty thin, but salting is fast enough - try { - callback(null, bcrypt.genSaltSync(rounds)); - } catch (err) { - callback(err); - } - }); - } - - if (callback) { - if (typeof callback !== 'function') - throw Error("Illegal callback: "+typeof(callback)); - _async(callback); - } else - return new Promise(function(resolve, reject) { - _async(function(err, res) { - if (err) { - reject(err); - return; - } - resolve(res); - }); - }); - }; - - /** - * Synchronously generates a hash for the given string. - * @param {string} s String to hash - * @param {(number|string)=} salt Salt length to generate or salt to use, default to 10 - * @returns {string} Resulting hash - * @expose - */ - bcrypt.hashSync = function(s, salt) { - if (typeof salt === 'undefined') - salt = GENSALT_DEFAULT_LOG2_ROUNDS; - if (typeof salt === 'number') - salt = bcrypt.genSaltSync(salt); - if (typeof s !== 'string' || typeof salt !== 'string') - throw Error("Illegal arguments: "+(typeof s)+', '+(typeof salt)); - return _hash(s, salt); - }; - - /** - * Asynchronously generates a hash for the given string. - * @param {string} s String to hash - * @param {number|string} salt Salt length to generate or salt to use - * @param {function(Error, string=)=} callback Callback receiving the error, if any, and the resulting hash - * @param {function(number)=} progressCallback Callback successively called with the percentage of rounds completed - * (0.0 - 1.0), maximally once per `MAX_EXECUTION_TIME = 100` ms. - * @returns {!Promise} If `callback` has been omitted - * @throws {Error} If `callback` is present but not a function - * @expose - */ - bcrypt.hash = function(s, salt, callback, progressCallback) { - - function _async(callback) { - if (typeof s === 'string' && typeof salt === 'number') - bcrypt.genSalt(salt, function(err, salt) { - _hash(s, salt, callback, progressCallback); - }); - else if (typeof s === 'string' && typeof salt === 'string') - _hash(s, salt, callback, progressCallback); - else - nextTick(callback.bind(this, Error("Illegal arguments: "+(typeof s)+', '+(typeof salt)))); - } - - if (callback) { - if (typeof callback !== 'function') - throw Error("Illegal callback: "+typeof(callback)); - _async(callback); - } else - return new Promise(function(resolve, reject) { - _async(function(err, res) { - if (err) { - reject(err); - return; - } - resolve(res); - }); - }); - }; - - /** - * Compares two strings of the same length in constant time. - * @param {string} known Must be of the correct length - * @param {string} unknown Must be the same length as `known` - * @returns {boolean} - * @inner - */ - function safeStringCompare(known, unknown) { - var right = 0, - wrong = 0; - for (var i=0, k=known.length; i} UTF8 bytes - * @inner - */ - function stringToBytes(str) { - var out = [], - i = 0; - utfx.encodeUTF16toUTF8(function() { - if (i >= str.length) return null; - return str.charCodeAt(i++); - }, function(b) { - out.push(b); - }); - return out; - } - - // A base64 implementation for the bcrypt algorithm. This is partly non-standard. - - /** - * bcrypt's own non-standard base64 dictionary. - * @type {!Array.} - * @const - * @inner - **/ - var BASE64_CODE = "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789".split(''); - - /** - * @type {!Array.} - * @const - * @inner - **/ - var BASE64_INDEX = [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, - 1, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, -1, -1, -1, -1, -1, -1, - -1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, - 20, 21, 22, 23, 24, 25, 26, 27, -1, -1, -1, -1, -1, -1, 28, 29, 30, - 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, -1, -1, -1, -1, -1]; - - /** - * @type {!function(...number):string} - * @inner - */ - var stringFromCharCode = String.fromCharCode; - - /** - * Encodes a byte array to base64 with up to len bytes of input. - * @param {!Array.} b Byte array - * @param {number} len Maximum input length - * @returns {string} - * @inner - */ - function base64_encode(b, len) { - var off = 0, - rs = [], - c1, c2; - if (len <= 0 || len > b.length) - throw Error("Illegal len: "+len); - while (off < len) { - c1 = b[off++] & 0xff; - rs.push(BASE64_CODE[(c1 >> 2) & 0x3f]); - c1 = (c1 & 0x03) << 4; - if (off >= len) { - rs.push(BASE64_CODE[c1 & 0x3f]); - break; - } - c2 = b[off++] & 0xff; - c1 |= (c2 >> 4) & 0x0f; - rs.push(BASE64_CODE[c1 & 0x3f]); - c1 = (c2 & 0x0f) << 2; - if (off >= len) { - rs.push(BASE64_CODE[c1 & 0x3f]); - break; - } - c2 = b[off++] & 0xff; - c1 |= (c2 >> 6) & 0x03; - rs.push(BASE64_CODE[c1 & 0x3f]); - rs.push(BASE64_CODE[c2 & 0x3f]); - } - return rs.join(''); - } - - /** - * Decodes a base64 encoded string to up to len bytes of output. - * @param {string} s String to decode - * @param {number} len Maximum output length - * @returns {!Array.} - * @inner - */ - function base64_decode(s, len) { - var off = 0, - slen = s.length, - olen = 0, - rs = [], - c1, c2, c3, c4, o, code; - if (len <= 0) - throw Error("Illegal len: "+len); - while (off < slen - 1 && olen < len) { - code = s.charCodeAt(off++); - c1 = code < BASE64_INDEX.length ? BASE64_INDEX[code] : -1; - code = s.charCodeAt(off++); - c2 = code < BASE64_INDEX.length ? BASE64_INDEX[code] : -1; - if (c1 == -1 || c2 == -1) - break; - o = (c1 << 2) >>> 0; - o |= (c2 & 0x30) >> 4; - rs.push(stringFromCharCode(o)); - if (++olen >= len || off >= slen) - break; - code = s.charCodeAt(off++); - c3 = code < BASE64_INDEX.length ? BASE64_INDEX[code] : -1; - if (c3 == -1) - break; - o = ((c2 & 0x0f) << 4) >>> 0; - o |= (c3 & 0x3c) >> 2; - rs.push(stringFromCharCode(o)); - if (++olen >= len || off >= slen) - break; - code = s.charCodeAt(off++); - c4 = code < BASE64_INDEX.length ? BASE64_INDEX[code] : -1; - o = ((c3 & 0x03) << 6) >>> 0; - o |= c4; - rs.push(stringFromCharCode(o)); - ++olen; - } - var res = []; - for (off = 0; off - * Released under the Apache License, Version 2.0 - * see: https://github.com/dcodeIO/utfx for details - */ - var utfx = function() { - "use strict"; - - /** - * utfx namespace. - * @inner - * @type {!Object.} - */ - var utfx = {}; - - /** - * Maximum valid code point. - * @type {number} - * @const - */ - utfx.MAX_CODEPOINT = 0x10FFFF; - - /** - * Encodes UTF8 code points to UTF8 bytes. - * @param {(!function():number|null) | number} src Code points source, either as a function returning the next code point - * respectively `null` if there are no more code points left or a single numeric code point. - * @param {!function(number)} dst Bytes destination as a function successively called with the next byte - */ - utfx.encodeUTF8 = function(src, dst) { - var cp = null; - if (typeof src === 'number') - cp = src, - src = function() { return null; }; - while (cp !== null || (cp = src()) !== null) { - if (cp < 0x80) - dst(cp&0x7F); - else if (cp < 0x800) - dst(((cp>>6)&0x1F)|0xC0), - dst((cp&0x3F)|0x80); - else if (cp < 0x10000) - dst(((cp>>12)&0x0F)|0xE0), - dst(((cp>>6)&0x3F)|0x80), - dst((cp&0x3F)|0x80); - else - dst(((cp>>18)&0x07)|0xF0), - dst(((cp>>12)&0x3F)|0x80), - dst(((cp>>6)&0x3F)|0x80), - dst((cp&0x3F)|0x80); - cp = null; - } - }; - - /** - * Decodes UTF8 bytes to UTF8 code points. - * @param {!function():number|null} src Bytes source as a function returning the next byte respectively `null` if there - * are no more bytes left. - * @param {!function(number)} dst Code points destination as a function successively called with each decoded code point. - * @throws {RangeError} If a starting byte is invalid in UTF8 - * @throws {Error} If the last sequence is truncated. Has an array property `bytes` holding the - * remaining bytes. - */ - utfx.decodeUTF8 = function(src, dst) { - var a, b, c, d, fail = function(b) { - b = b.slice(0, b.indexOf(null)); - var err = Error(b.toString()); - err.name = "TruncatedError"; - err['bytes'] = b; - throw err; - }; - while ((a = src()) !== null) { - if ((a&0x80) === 0) - dst(a); - else if ((a&0xE0) === 0xC0) - ((b = src()) === null) && fail([a, b]), - dst(((a&0x1F)<<6) | (b&0x3F)); - else if ((a&0xF0) === 0xE0) - ((b=src()) === null || (c=src()) === null) && fail([a, b, c]), - dst(((a&0x0F)<<12) | ((b&0x3F)<<6) | (c&0x3F)); - else if ((a&0xF8) === 0xF0) - ((b=src()) === null || (c=src()) === null || (d=src()) === null) && fail([a, b, c ,d]), - dst(((a&0x07)<<18) | ((b&0x3F)<<12) | ((c&0x3F)<<6) | (d&0x3F)); - else throw RangeError("Illegal starting byte: "+a); - } - }; - - /** - * Converts UTF16 characters to UTF8 code points. - * @param {!function():number|null} src Characters source as a function returning the next char code respectively - * `null` if there are no more characters left. - * @param {!function(number)} dst Code points destination as a function successively called with each converted code - * point. - */ - utfx.UTF16toUTF8 = function(src, dst) { - var c1, c2 = null; - while (true) { - if ((c1 = c2 !== null ? c2 : src()) === null) - break; - if (c1 >= 0xD800 && c1 <= 0xDFFF) { - if ((c2 = src()) !== null) { - if (c2 >= 0xDC00 && c2 <= 0xDFFF) { - dst((c1-0xD800)*0x400+c2-0xDC00+0x10000); - c2 = null; continue; - } - } - } - dst(c1); - } - if (false) dst(c2); - }; - - /** - * Converts UTF8 code points to UTF16 characters. - * @param {(!function():number|null) | number} src Code points source, either as a function returning the next code point - * respectively `null` if there are no more code points left or a single numeric code point. - * @param {!function(number)} dst Characters destination as a function successively called with each converted char code. - * @throws {RangeError} If a code point is out of range - */ - utfx.UTF8toUTF16 = function(src, dst) { - var cp = null; - if (typeof src === 'number') - cp = src, src = function() { return null; }; - while (cp !== null || (cp = src()) !== null) { - if (cp <= 0xFFFF) - dst(cp); - else - cp -= 0x10000, - dst((cp>>10)+0xD800), - dst((cp%0x400)+0xDC00); - cp = null; - } - }; - - /** - * Converts and encodes UTF16 characters to UTF8 bytes. - * @param {!function():number|null} src Characters source as a function returning the next char code respectively `null` - * if there are no more characters left. - * @param {!function(number)} dst Bytes destination as a function successively called with the next byte. - */ - utfx.encodeUTF16toUTF8 = function(src, dst) { - utfx.UTF16toUTF8(src, function(cp) { - utfx.encodeUTF8(cp, dst); - }); - }; - - /** - * Decodes and converts UTF8 bytes to UTF16 characters. - * @param {!function():number|null} src Bytes source as a function returning the next byte respectively `null` if there - * are no more bytes left. - * @param {!function(number)} dst Characters destination as a function successively called with each converted char code. - * @throws {RangeError} If a starting byte is invalid in UTF8 - * @throws {Error} If the last sequence is truncated. Has an array property `bytes` holding the remaining bytes. - */ - utfx.decodeUTF8toUTF16 = function(src, dst) { - utfx.decodeUTF8(src, function(cp) { - utfx.UTF8toUTF16(cp, dst); - }); - }; - - /** - * Calculates the byte length of an UTF8 code point. - * @param {number} cp UTF8 code point - * @returns {number} Byte length - */ - utfx.calculateCodePoint = function(cp) { - return (cp < 0x80) ? 1 : (cp < 0x800) ? 2 : (cp < 0x10000) ? 3 : 4; - }; - - /** - * Calculates the number of UTF8 bytes required to store UTF8 code points. - * @param {(!function():number|null)} src Code points source as a function returning the next code point respectively - * `null` if there are no more code points left. - * @returns {number} The number of UTF8 bytes required - */ - utfx.calculateUTF8 = function(src) { - var cp, l=0; - while ((cp = src()) !== null) - l += utfx.calculateCodePoint(cp); - return l; - }; - - /** - * Calculates the number of UTF8 code points respectively UTF8 bytes required to store UTF16 char codes. - * @param {(!function():number|null)} src Characters source as a function returning the next char code respectively - * `null` if there are no more characters left. - * @returns {!Array.} The number of UTF8 code points at index 0 and the number of UTF8 bytes required at index 1. - */ - utfx.calculateUTF16asUTF8 = function(src) { - var n=0, l=0; - utfx.UTF16toUTF8(src, function(cp) { - ++n; l += utfx.calculateCodePoint(cp); - }); - return [n,l]; - }; - - return utfx; - }(); - - Date.now = Date.now || function() { return +new Date; }; - - /** - * @type {number} - * @const - * @inner - */ - var BCRYPT_SALT_LEN = 16; - - /** - * @type {number} - * @const - * @inner - */ - var GENSALT_DEFAULT_LOG2_ROUNDS = 10; - - /** - * @type {number} - * @const - * @inner - */ - var BLOWFISH_NUM_ROUNDS = 16; - - /** - * @type {number} - * @const - * @inner - */ - var MAX_EXECUTION_TIME = 100; - - /** - * @type {Array.} - * @const - * @inner - */ - var P_ORIG = [ - 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, 0xa4093822, - 0x299f31d0, 0x082efa98, 0xec4e6c89, 0x452821e6, 0x38d01377, - 0xbe5466cf, 0x34e90c6c, 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, - 0xb5470917, 0x9216d5d9, 0x8979fb1b - ]; - - /** - * @type {Array.} - * @const - * @inner - */ - var S_ORIG = [ - 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, 0xb8e1afed, - 0x6a267e96, 0xba7c9045, 0xf12c7f99, 0x24a19947, 0xb3916cf7, - 0x0801f2e2, 0x858efc16, 0x636920d8, 0x71574e69, 0xa458fea3, - 0xf4933d7e, 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee, - 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013, 0xc5d1b023, - 0x286085f0, 0xca417918, 0xb8db38ef, 0x8e79dcb0, 0x603a180e, - 0x6c9e0e8b, 0xb01e8a3e, 0xd71577c1, 0xbd314b27, 0x78af2fda, - 0x55605c60, 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440, - 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce, 0xa15486af, - 0x7c72e993, 0xb3ee1411, 0x636fbc2a, 0x2ba9c55d, 0x741831f6, - 0xce5c3e16, 0x9b87931e, 0xafd6ba33, 0x6c24cf5c, 0x7a325381, - 0x28958677, 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193, - 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032, 0xef845d5d, - 0xe98575b1, 0xdc262302, 0xeb651b88, 0x23893e81, 0xd396acc5, - 0x0f6d6ff3, 0x83f44239, 0x2e0b4482, 0xa4842004, 0x69c8f04a, - 0x9e1f9b5e, 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0, - 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3, 0x6eef0b6c, - 0x137a3be4, 0xba3bf050, 0x7efb2a98, 0xa1f1651d, 0x39af0176, - 0x66ca593e, 0x82430e88, 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, - 0x3b8b5ebe, 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, - 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d, 0x37d0d724, - 0xd00a1248, 0xdb0fead3, 0x49f1c09b, 0x075372c9, 0x80991b7b, - 0x25d479d8, 0xf6e8def7, 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, - 0x04c006ba, 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463, - 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, 0x6dfc511f, - 0x9b30952c, 0xcc814544, 0xaf5ebd09, 0xbee3d004, 0xde334afd, - 0x660f2807, 0x192e4bb3, 0xc0cba857, 0x45c8740f, 0xd20b5f39, - 0xb9d3fbdb, 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279, - 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8, 0x3c7516df, - 0xfd616b15, 0x2f501ec8, 0xad0552ab, 0x323db5fa, 0xfd238760, - 0x53317b48, 0x3e00df82, 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, - 0xdf1769db, 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573, - 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0, 0x10fa3d98, - 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b, 0x9a53e479, 0xb6f84565, - 0xd28e49bc, 0x4bfb9790, 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, - 0xcee4c6e8, 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4, - 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0, 0xd08ed1d0, - 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7, 0x8ff6e2fb, 0xf2122b64, - 0x8888b812, 0x900df01c, 0x4fad5ea0, 0x688fc31c, 0xd1cff191, - 0xb3a8c1ad, 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1, - 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299, 0xb4a84fe0, - 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9, 0x165fa266, 0x80957705, - 0x93cc7314, 0x211a1477, 0xe6ad2065, 0x77b5fa86, 0xc75442f5, - 0xfb9d35cf, 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, - 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af, 0x2464369b, - 0xf009b91e, 0x5563911d, 0x59dfa6aa, 0x78c14389, 0xd95a537f, - 0x207d5ba2, 0x02e5b9c5, 0x83260376, 0x6295cfa9, 0x11c81968, - 0x4e734a41, 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915, - 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, 0x08ba6fb5, - 0x571be91f, 0xf296ec6b, 0x2a0dd915, 0xb6636521, 0xe7b9f9b6, - 0xff34052e, 0xc5855664, 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, - 0x6e85076a, 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, - 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266, 0xecaa8c71, - 0x699a17ff, 0x5664526c, 0xc2b19ee1, 0x193602a5, 0x75094c29, - 0xa0591340, 0xe4183a3e, 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, - 0x99f73fd6, 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1, - 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, 0x09686b3f, - 0x3ebaefc9, 0x3c971814, 0x6b6a70a1, 0x687f3584, 0x52a0e286, - 0xb79c5305, 0xaa500737, 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, - 0x5716f2b8, 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff, - 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd, 0xd19113f9, - 0x7ca92ff6, 0x94324773, 0x22f54701, 0x3ae5e581, 0x37c2dadc, - 0xc8b57634, 0x9af3dda7, 0xa9446146, 0x0fd0030e, 0xecc8c73e, - 0xa4751e41, 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331, - 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf, 0x2cb81290, - 0x24977c79, 0x5679b072, 0xbcaf89af, 0xde9a771f, 0xd9930810, - 0xb38bae12, 0xdccf3f2e, 0x5512721f, 0x2e6b7124, 0x501adde6, - 0x9f84cd87, 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c, - 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2, 0xef1c1847, - 0x3215d908, 0xdd433b37, 0x24c2ba16, 0x12a14d43, 0x2a65c451, - 0x50940002, 0x133ae4dd, 0x71dff89e, 0x10314e55, 0x81ac77d6, - 0x5f11199b, 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509, - 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, 0x86e34570, - 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3, 0x771fe71c, 0x4e3d06fa, - 0x2965dcb9, 0x99e71d0f, 0x803e89d6, 0x5266c825, 0x2e4cc978, - 0x9c10b36a, 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, - 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960, 0x5223a708, - 0xf71312b6, 0xebadfe6e, 0xeac31f66, 0xe3bc4595, 0xa67bc883, - 0xb17f37d1, 0x018cff28, 0xc332ddef, 0xbe6c5aa5, 0x65582185, - 0x68ab9802, 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84, - 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, 0x13cca830, - 0xeb61bd96, 0x0334fe1e, 0xaa0363cf, 0xb5735c90, 0x4c70a239, - 0xd59e9e0b, 0xcbaade14, 0xeecc86bc, 0x60622ca7, 0x9cab5cab, - 0xb2f3846e, 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50, - 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7, 0x9b540b19, - 0x875fa099, 0x95f7997e, 0x623d7da8, 0xf837889a, 0x97e32d77, - 0x11ed935f, 0x16681281, 0x0e358829, 0xc7e61fd6, 0x96dedfa1, - 0x7858ba99, 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696, - 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128, 0x58ebf2ef, - 0x34c6ffea, 0xfe28ed61, 0xee7c3c73, 0x5d4a14d9, 0xe864b7e3, - 0x42105d14, 0x203e13e0, 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, - 0xfacb4fd0, 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105, - 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250, 0xcf62a1f2, - 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3, 0x7f1524c3, 0x69cb7492, - 0x47848a0b, 0x5692b285, 0x095bbf00, 0xad19489d, 0x1462b174, - 0x23820e00, 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061, - 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb, 0x7cde3759, - 0xcbee7460, 0x4085f2a7, 0xce77326e, 0xa6078084, 0x19f8509e, - 0xe8efd855, 0x61d99735, 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, - 0x800bcadc, 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, - 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340, 0xc5c43465, - 0x713e38d8, 0x3d28f89e, 0xf16dff20, 0x153e21e7, 0x8fb03d4a, - 0xe6e39f2b, 0xdb83adf7, 0xe93d5a68, 0x948140f7, 0xf64c261c, - 0x94692934, 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068, - 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af, 0x1e39f62e, - 0x97244546, 0x14214f74, 0xbf8b8840, 0x4d95fc1d, 0x96b591af, - 0x70f4ddd3, 0x66a02f45, 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, - 0x31cb8504, 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, - 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb, 0x68dc1462, - 0xd7486900, 0x680ec0a4, 0x27a18dee, 0x4f3ffea2, 0xe887ad8c, - 0xb58ce006, 0x7af4d6b6, 0xaace1e7c, 0xd3375fec, 0xce78a399, - 0x406b2a42, 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b, - 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, 0x3a6efa74, - 0xdd5b4332, 0x6841e7f7, 0xca7820fb, 0xfb0af54e, 0xd8feb397, - 0x454056ac, 0xba489527, 0x55533a3a, 0x20838d87, 0xfe6ba9b7, - 0xd096954b, 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33, - 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c, 0xfdf8e802, - 0x04272f70, 0x80bb155c, 0x05282ce3, 0x95c11548, 0xe4c66d22, - 0x48c1133f, 0xc70f86dc, 0x07f9c9ee, 0x41041f0f, 0x404779a4, - 0x5d886e17, 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564, - 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b, 0x0e12b4c2, - 0x02e1329e, 0xaf664fd1, 0xcad18115, 0x6b2395e0, 0x333e92e1, - 0x3b240b62, 0xeebeb922, 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, - 0x2da2f728, 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0, - 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e, 0x0a476341, - 0x992eff74, 0x3a6f6eab, 0xf4f8fd37, 0xa812dc60, 0xa1ebddf8, - 0x991be14c, 0xdb6e6b0d, 0xc67b5510, 0x6d672c37, 0x2765d43b, - 0xdcd0e804, 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b, - 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3, 0xbb132f88, - 0x515bad24, 0x7b9479bf, 0x763bd6eb, 0x37392eb3, 0xcc115979, - 0x8026e297, 0xf42e312d, 0x6842ada7, 0xc66a2b3b, 0x12754ccc, - 0x782ef11c, 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, - 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9, 0x44421659, - 0x0a121386, 0xd90cec6e, 0xd5abea2a, 0x64af674e, 0xda86a85f, - 0xbebfe988, 0x64e4c3fe, 0x9dbc8057, 0xf0f7c086, 0x60787bf8, - 0x6003604d, 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc, - 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, 0x77a057be, - 0xbde8ae24, 0x55464299, 0xbf582e61, 0x4e58f48f, 0xf2ddfda2, - 0xf474ef38, 0x8789bdc2, 0x5366f9c3, 0xc8b38e74, 0xb475f255, - 0x46fcd9b9, 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2, - 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c, 0xb90bace1, - 0xbb8205d0, 0x11a86248, 0x7574a99e, 0xb77f19b6, 0xe0a9dc09, - 0x662d09a1, 0xc4324633, 0xe85a1f02, 0x09f0be8c, 0x4a99a025, - 0x1d6efe10, 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169, - 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52, 0x50115e01, - 0xa70683fa, 0xa002b5c4, 0x0de6d027, 0x9af88c27, 0x773f8641, - 0xc3604c06, 0x61a806b5, 0xf0177a28, 0xc0f586e0, 0x006058aa, - 0x30dc7d62, 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634, - 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76, 0x6f05e409, - 0x4b7c0188, 0x39720a3d, 0x7c927c24, 0x86e3725f, 0x724d9db9, - 0x1ac15bb4, 0xd39eb8fc, 0xed545578, 0x08fca5b5, 0xd83d7cd3, - 0x4dad0fc4, 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c, - 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837, 0xd79a3234, - 0x92638212, 0x670efa8e, 0x406000e0, 0x3a39ce37, 0xd3faf5cf, - 0xabc27737, 0x5ac52d1b, 0x5cb0679e, 0x4fa33742, 0xd3822740, - 0x99bc9bbe, 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b, - 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4, 0x5748ab2f, - 0xbc946e79, 0xc6a376d2, 0x6549c2c8, 0x530ff8ee, 0x468dde7d, - 0xd5730a1d, 0x4cd04dc6, 0x2939bbdb, 0xa9ba4650, 0xac9526e8, - 0xbe5ee304, 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22, - 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4, 0x83c061ba, - 0x9be96a4d, 0x8fe51550, 0xba645bd6, 0x2826a2f9, 0xa73a3ae1, - 0x4ba99586, 0xef5562e9, 0xc72fefd3, 0xf752f7da, 0x3f046f69, - 0x77fa0a59, 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, - 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51, 0x96d5ac3a, - 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28, 0x1f9f25cf, 0xadf2b89b, - 0x5ad6b472, 0x5a88f54c, 0xe029ac71, 0xe019a5e6, 0x47b0acfd, - 0xed93fa9b, 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28, - 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, 0x15056dd4, - 0x88f46dba, 0x03a16125, 0x0564f0bd, 0xc3eb9e15, 0x3c9057a2, - 0x97271aec, 0xa93a072a, 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, - 0x26dcf319, 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb, - 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f, 0x4de81751, - 0x3830dc8e, 0x379d5862, 0x9320f991, 0xea7a90c2, 0xfb3e7bce, - 0x5121ce64, 0x774fbe32, 0xa8b6e37e, 0xc3293d46, 0x48de5369, - 0x6413e680, 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166, - 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae, 0x5bbef7dd, - 0x1b588d40, 0xccd2017f, 0x6bb4e3bb, 0xdda26a7e, 0x3a59ff45, - 0x3e350a44, 0xbcb4cdd5, 0x72eacea8, 0xfa6484bb, 0x8d6612ae, - 0xbf3c6f47, 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370, - 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d, 0x4040cb08, - 0x4eb4e2cc, 0x34d2466a, 0x0115af84, 0xe1b00428, 0x95983a1d, - 0x06b89fb4, 0xce6ea048, 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, - 0x277227f8, 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd, - 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9, 0xe01cc87e, - 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7, 0x1a908749, 0xd44fbd9a, - 0xd0dadecb, 0xd50ada38, 0x0339c32a, 0xc6913667, 0x8df9317c, - 0xe0b12b4f, 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, - 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525, 0xfae59361, - 0xceb69ceb, 0xc2a86459, 0x12baa8d1, 0xb6c1075e, 0xe3056a0c, - 0x10d25065, 0xcb03a442, 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, - 0x3278e964, 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e, - 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, 0xdf359f8d, - 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d, 0xe54cda54, 0x1edad891, - 0xce6279cf, 0xcd3e7e6f, 0x1618b166, 0xfd2c1d05, 0x848fd2c5, - 0xf6fb2299, 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02, - 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc, 0xde966292, - 0x81b949d0, 0x4c50901b, 0x71c65614, 0xe6c6c7bd, 0x327a140a, - 0x45e1d006, 0xc3f27b9a, 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, - 0x35bdd2f6, 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b, - 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0, 0xba38209c, - 0xf746ce76, 0x77afa1c5, 0x20756060, 0x85cbfe4e, 0x8ae88dd8, - 0x7aaaf9b0, 0x4cf9aa7e, 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, - 0xd6ebe1f9, 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f, - 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6 - ]; - - /** - * @type {Array.} - * @const - * @inner - */ - var C_ORIG = [ - 0x4f727068, 0x65616e42, 0x65686f6c, 0x64657253, 0x63727944, - 0x6f756274 - ]; - - /** - * @param {Array.} lr - * @param {number} off - * @param {Array.} P - * @param {Array.} S - * @returns {Array.} - * @inner - */ - function _encipher(lr, off, P, S) { // This is our bottleneck: 1714/1905 ticks / 90% - see profile.txt - var n, - l = lr[off], - r = lr[off + 1]; - - l ^= P[0]; - - /* - for (var i=0, k=BLOWFISH_NUM_ROUNDS-2; i<=k;) - // Feistel substitution on left word - n = S[l >>> 24], - n += S[0x100 | ((l >> 16) & 0xff)], - n ^= S[0x200 | ((l >> 8) & 0xff)], - n += S[0x300 | (l & 0xff)], - r ^= n ^ P[++i], - // Feistel substitution on right word - n = S[r >>> 24], - n += S[0x100 | ((r >> 16) & 0xff)], - n ^= S[0x200 | ((r >> 8) & 0xff)], - n += S[0x300 | (r & 0xff)], - l ^= n ^ P[++i]; - */ - - //The following is an unrolled version of the above loop. - //Iteration 0 - n = S[l >>> 24]; - n += S[0x100 | ((l >> 16) & 0xff)]; - n ^= S[0x200 | ((l >> 8) & 0xff)]; - n += S[0x300 | (l & 0xff)]; - r ^= n ^ P[1]; - n = S[r >>> 24]; - n += S[0x100 | ((r >> 16) & 0xff)]; - n ^= S[0x200 | ((r >> 8) & 0xff)]; - n += S[0x300 | (r & 0xff)]; - l ^= n ^ P[2]; - //Iteration 1 - n = S[l >>> 24]; - n += S[0x100 | ((l >> 16) & 0xff)]; - n ^= S[0x200 | ((l >> 8) & 0xff)]; - n += S[0x300 | (l & 0xff)]; - r ^= n ^ P[3]; - n = S[r >>> 24]; - n += S[0x100 | ((r >> 16) & 0xff)]; - n ^= S[0x200 | ((r >> 8) & 0xff)]; - n += S[0x300 | (r & 0xff)]; - l ^= n ^ P[4]; - //Iteration 2 - n = S[l >>> 24]; - n += S[0x100 | ((l >> 16) & 0xff)]; - n ^= S[0x200 | ((l >> 8) & 0xff)]; - n += S[0x300 | (l & 0xff)]; - r ^= n ^ P[5]; - n = S[r >>> 24]; - n += S[0x100 | ((r >> 16) & 0xff)]; - n ^= S[0x200 | ((r >> 8) & 0xff)]; - n += S[0x300 | (r & 0xff)]; - l ^= n ^ P[6]; - //Iteration 3 - n = S[l >>> 24]; - n += S[0x100 | ((l >> 16) & 0xff)]; - n ^= S[0x200 | ((l >> 8) & 0xff)]; - n += S[0x300 | (l & 0xff)]; - r ^= n ^ P[7]; - n = S[r >>> 24]; - n += S[0x100 | ((r >> 16) & 0xff)]; - n ^= S[0x200 | ((r >> 8) & 0xff)]; - n += S[0x300 | (r & 0xff)]; - l ^= n ^ P[8]; - //Iteration 4 - n = S[l >>> 24]; - n += S[0x100 | ((l >> 16) & 0xff)]; - n ^= S[0x200 | ((l >> 8) & 0xff)]; - n += S[0x300 | (l & 0xff)]; - r ^= n ^ P[9]; - n = S[r >>> 24]; - n += S[0x100 | ((r >> 16) & 0xff)]; - n ^= S[0x200 | ((r >> 8) & 0xff)]; - n += S[0x300 | (r & 0xff)]; - l ^= n ^ P[10]; - //Iteration 5 - n = S[l >>> 24]; - n += S[0x100 | ((l >> 16) & 0xff)]; - n ^= S[0x200 | ((l >> 8) & 0xff)]; - n += S[0x300 | (l & 0xff)]; - r ^= n ^ P[11]; - n = S[r >>> 24]; - n += S[0x100 | ((r >> 16) & 0xff)]; - n ^= S[0x200 | ((r >> 8) & 0xff)]; - n += S[0x300 | (r & 0xff)]; - l ^= n ^ P[12]; - //Iteration 6 - n = S[l >>> 24]; - n += S[0x100 | ((l >> 16) & 0xff)]; - n ^= S[0x200 | ((l >> 8) & 0xff)]; - n += S[0x300 | (l & 0xff)]; - r ^= n ^ P[13]; - n = S[r >>> 24]; - n += S[0x100 | ((r >> 16) & 0xff)]; - n ^= S[0x200 | ((r >> 8) & 0xff)]; - n += S[0x300 | (r & 0xff)]; - l ^= n ^ P[14]; - //Iteration 7 - n = S[l >>> 24]; - n += S[0x100 | ((l >> 16) & 0xff)]; - n ^= S[0x200 | ((l >> 8) & 0xff)]; - n += S[0x300 | (l & 0xff)]; - r ^= n ^ P[15]; - n = S[r >>> 24]; - n += S[0x100 | ((r >> 16) & 0xff)]; - n ^= S[0x200 | ((r >> 8) & 0xff)]; - n += S[0x300 | (r & 0xff)]; - l ^= n ^ P[16]; - - lr[off] = r ^ P[BLOWFISH_NUM_ROUNDS + 1]; - lr[off + 1] = l; - return lr; - } - - /** - * @param {Array.} data - * @param {number} offp - * @returns {{key: number, offp: number}} - * @inner - */ - function _streamtoword(data, offp) { - for (var i = 0, word = 0; i < 4; ++i) - word = (word << 8) | (data[offp] & 0xff), - offp = (offp + 1) % data.length; - return { key: word, offp: offp }; - } - - /** - * @param {Array.} key - * @param {Array.} P - * @param {Array.} S - * @inner - */ - function _key(key, P, S) { - var offset = 0, - lr = [0, 0], - plen = P.length, - slen = S.length, - sw; - for (var i = 0; i < plen; i++) - sw = _streamtoword(key, offset), - offset = sw.offp, - P[i] = P[i] ^ sw.key; - for (i = 0; i < plen; i += 2) - lr = _encipher(lr, 0, P, S), - P[i] = lr[0], - P[i + 1] = lr[1]; - for (i = 0; i < slen; i += 2) - lr = _encipher(lr, 0, P, S), - S[i] = lr[0], - S[i + 1] = lr[1]; - } - - /** - * Expensive key schedule Blowfish. - * @param {Array.} data - * @param {Array.} key - * @param {Array.} P - * @param {Array.} S - * @inner - */ - function _ekskey(data, key, P, S) { - var offp = 0, - lr = [0, 0], - plen = P.length, - slen = S.length, - sw; - for (var i = 0; i < plen; i++) - sw = _streamtoword(key, offp), - offp = sw.offp, - P[i] = P[i] ^ sw.key; - offp = 0; - for (i = 0; i < plen; i += 2) - sw = _streamtoword(data, offp), - offp = sw.offp, - lr[0] ^= sw.key, - sw = _streamtoword(data, offp), - offp = sw.offp, - lr[1] ^= sw.key, - lr = _encipher(lr, 0, P, S), - P[i] = lr[0], - P[i + 1] = lr[1]; - for (i = 0; i < slen; i += 2) - sw = _streamtoword(data, offp), - offp = sw.offp, - lr[0] ^= sw.key, - sw = _streamtoword(data, offp), - offp = sw.offp, - lr[1] ^= sw.key, - lr = _encipher(lr, 0, P, S), - S[i] = lr[0], - S[i + 1] = lr[1]; - } - - /** - * Internaly crypts a string. - * @param {Array.} b Bytes to crypt - * @param {Array.} salt Salt bytes to use - * @param {number} rounds Number of rounds - * @param {function(Error, Array.=)=} callback Callback receiving the error, if any, and the resulting bytes. If - * omitted, the operation will be performed synchronously. - * @param {function(number)=} progressCallback Callback called with the current progress - * @returns {!Array.|undefined} Resulting bytes if callback has been omitted, otherwise `undefined` - * @inner - */ - function _crypt(b, salt, rounds, callback, progressCallback) { - var cdata = C_ORIG.slice(), - clen = cdata.length, - err; - - // Validate - if (rounds < 4 || rounds > 31) { - err = Error("Illegal number of rounds (4-31): "+rounds); - if (callback) { - nextTick(callback.bind(this, err)); - return; - } else - throw err; - } - if (salt.length !== BCRYPT_SALT_LEN) { - err =Error("Illegal salt length: "+salt.length+" != "+BCRYPT_SALT_LEN); - if (callback) { - nextTick(callback.bind(this, err)); - return; - } else - throw err; - } - rounds = (1 << rounds) >>> 0; - - var P, S, i = 0, j; - - //Use typed arrays when available - huge speedup! - if (Int32Array) { - P = new Int32Array(P_ORIG); - S = new Int32Array(S_ORIG); - } else { - P = P_ORIG.slice(); - S = S_ORIG.slice(); - } - - _ekskey(salt, b, P, S); - - /** - * Calcualtes the next round. - * @returns {Array.|undefined} Resulting array if callback has been omitted, otherwise `undefined` - * @inner - */ - function next() { - if (progressCallback) - progressCallback(i / rounds); - if (i < rounds) { - var start = Date.now(); - for (; i < rounds;) { - i = i + 1; - _key(b, P, S); - _key(salt, P, S); - if (Date.now() - start > MAX_EXECUTION_TIME) - break; - } - } else { - for (i = 0; i < 64; i++) - for (j = 0; j < (clen >> 1); j++) - _encipher(cdata, j << 1, P, S); - var ret = []; - for (i = 0; i < clen; i++) - ret.push(((cdata[i] >> 24) & 0xff) >>> 0), - ret.push(((cdata[i] >> 16) & 0xff) >>> 0), - ret.push(((cdata[i] >> 8) & 0xff) >>> 0), - ret.push((cdata[i] & 0xff) >>> 0); - if (callback) { - callback(null, ret); - return; - } else - return ret; - } - if (callback) - nextTick(next); - } - - // Async - if (typeof callback !== 'undefined') { - next(); - - // Sync - } else { - var res; - while (true) - if (typeof(res = next()) !== 'undefined') - return res || []; - } - } - - /** - * Internally hashes a string. - * @param {string} s String to hash - * @param {?string} salt Salt to use, actually never null - * @param {function(Error, string=)=} callback Callback receiving the error, if any, and the resulting hash. If omitted, - * hashing is perormed synchronously. - * @param {function(number)=} progressCallback Callback called with the current progress - * @returns {string|undefined} Resulting hash if callback has been omitted, otherwise `undefined` - * @inner - */ - function _hash(s, salt, callback, progressCallback) { - var err; - if (typeof s !== 'string' || typeof salt !== 'string') { - err = Error("Invalid string / salt: Not a string"); - if (callback) { - nextTick(callback.bind(this, err)); - return; - } - else - throw err; - } - - // Validate the salt - var minor, offset; - if (salt.charAt(0) !== '$' || salt.charAt(1) !== '2') { - err = Error("Invalid salt version: "+salt.substring(0,2)); - if (callback) { - nextTick(callback.bind(this, err)); - return; - } - else - throw err; - } - if (salt.charAt(2) === '$') - minor = String.fromCharCode(0), - offset = 3; - else { - minor = salt.charAt(2); - if ((minor !== 'a' && minor !== 'b' && minor !== 'y') || salt.charAt(3) !== '$') { - err = Error("Invalid salt revision: "+salt.substring(2,4)); - if (callback) { - nextTick(callback.bind(this, err)); - return; - } else - throw err; - } - offset = 4; - } - - // Extract number of rounds - if (salt.charAt(offset + 2) > '$') { - err = Error("Missing salt rounds"); - if (callback) { - nextTick(callback.bind(this, err)); - return; - } else - throw err; - } - var r1 = parseInt(salt.substring(offset, offset + 1), 10) * 10, - r2 = parseInt(salt.substring(offset + 1, offset + 2), 10), - rounds = r1 + r2, - real_salt = salt.substring(offset + 3, offset + 25); - s += minor >= 'a' ? "\x00" : ""; - - var passwordb = stringToBytes(s), - saltb = base64_decode(real_salt, BCRYPT_SALT_LEN); - - /** - * Finishes hashing. - * @param {Array.} bytes Byte array - * @returns {string} - * @inner - */ - function finish(bytes) { - var res = []; - res.push("$2"); - if (minor >= 'a') - res.push(minor); - res.push("$"); - if (rounds < 10) - res.push("0"); - res.push(rounds.toString()); - res.push("$"); - res.push(base64_encode(saltb, saltb.length)); - res.push(base64_encode(bytes, C_ORIG.length * 4 - 1)); - return res.join(''); - } - - // Sync - if (typeof callback == 'undefined') - return finish(_crypt(passwordb, saltb, rounds)); - - // Async - else { - _crypt(passwordb, saltb, rounds, function(err, bytes) { - if (err) - callback(err, null); - else - callback(null, finish(bytes)); - }, progressCallback); - } - } - - /** - * Encodes a byte array to base64 with up to len bytes of input, using the custom bcrypt alphabet. - * @function - * @param {!Array.} b Byte array - * @param {number} len Maximum input length - * @returns {string} - * @expose - */ - bcrypt.encodeBase64 = base64_encode; - - /** - * Decodes a base64 encoded string to up to len bytes of output, using the custom bcrypt alphabet. - * @function - * @param {string} s String to decode - * @param {number} len Maximum output length - * @returns {!Array.} - * @expose - */ - bcrypt.decodeBase64 = base64_decode; - - return bcrypt; + throw Error("Neither WebCryptoAPI nor a crypto module is available. Use bcrypt.setRandomFallback to set an alternative"); + return randomFallback(len); + } + + // Test if any secure randomness source is available + var randomAvailable = false; + try { + random(1); + randomAvailable = true; + } catch (e) { } + + // Default fallback, if any + randomFallback = null; + /** + * Sets the pseudo random number generator to use as a fallback if neither node's `crypto` module nor the Web Crypto + * API is available. Please note: It is highly important that the PRNG used is cryptographically secure and that it + * is seeded properly! + * @param {?function(number):!Array.} random Function taking the number of bytes to generate as its + * sole argument, returning the corresponding array of cryptographically secure random byte values. + * @see http://nodejs.org/api/crypto.html + * @see http://www.w3.org/TR/WebCryptoAPI/ + */ + bcrypt.setRandomFallback = function (random) { + randomFallback = random; + }; + + /** + * Synchronously generates a salt. + * @param {number=} rounds Number of rounds to use, defaults to 10 if omitted + * @param {number=} seed_length Not supported. + * @returns {string} Resulting salt + * @throws {Error} If a random fallback is required but not set + * @expose + */ + bcrypt.genSaltSync = function (rounds, seed_length) { + rounds = rounds || GENSALT_DEFAULT_LOG2_ROUNDS; + if (typeof rounds !== 'number') + throw Error("Illegal arguments: " + (typeof rounds) + ", " + (typeof seed_length)); + if (rounds < 4) + rounds = 4; + else if (rounds > 31) + rounds = 31; + var salt = []; + salt.push("$2a$"); + if (rounds < 10) + salt.push("0"); + salt.push(rounds.toString()); + salt.push('$'); + salt.push(base64_encode(random(BCRYPT_SALT_LEN), BCRYPT_SALT_LEN)); // May throw + return salt.join(''); + }; + + /** + * Asynchronously generates a salt. + * @param {(number|function(Error, string=))=} rounds Number of rounds to use, defaults to 10 if omitted + * @param {(number|function(Error, string=))=} seed_length Not supported. + * @param {function(Error, string=)=} callback Callback receiving the error, if any, and the resulting salt + * @returns {!Promise} If `callback` has been omitted + * @throws {Error} If `callback` is present but not a function + * @expose + */ + bcrypt.genSalt = function (rounds, seed_length, callback) { + if (typeof seed_length === 'function') + callback = seed_length, + seed_length = undefined; // Not supported. + if (typeof rounds === 'function') + callback = rounds, + rounds = undefined; + if (typeof rounds === 'undefined') + rounds = GENSALT_DEFAULT_LOG2_ROUNDS; + else if (typeof rounds !== 'number') + throw Error("illegal arguments: " + (typeof rounds)); + + function _async(callback) { + nextTick(function () { // Pretty thin, but salting is fast enough + try { + callback(null, bcrypt.genSaltSync(rounds)); + } catch (err) { + callback(err); + } + }); + } + + if (callback) { + if (typeof callback !== 'function') + throw Error("Illegal callback: " + typeof (callback)); + _async(callback); + } else + return new Promise(function (resolve, reject) { + _async(function (err, res) { + if (err) { + reject(err); + return; + } + resolve(res); + }); + }); + }; + + /** + * Synchronously generates a hash for the given string. + * @param {string} s String to hash + * @param {(number|string)=} salt Salt length to generate or salt to use, default to 10 + * @returns {string} Resulting hash + * @expose + */ + bcrypt.hashSync = function (s, salt) { + if (typeof salt === 'undefined') + salt = GENSALT_DEFAULT_LOG2_ROUNDS; + if (typeof salt === 'number') + salt = bcrypt.genSaltSync(salt); + if (typeof s !== 'string' || typeof salt !== 'string') + throw Error("Illegal arguments: " + (typeof s) + ', ' + (typeof salt)); + return _hash(s, salt); + }; + + /** + * Asynchronously generates a hash for the given string. + * @param {string} s String to hash + * @param {number|string} salt Salt length to generate or salt to use + * @param {function(Error, string=)=} callback Callback receiving the error, if any, and the resulting hash + * @param {function(number)=} progressCallback Callback successively called with the percentage of rounds completed + * (0.0 - 1.0), maximally once per `MAX_EXECUTION_TIME = 100` ms. + * @returns {!Promise} If `callback` has been omitted + * @throws {Error} If `callback` is present but not a function + * @expose + */ + bcrypt.hash = function (s, salt, callback, progressCallback) { + + function _async(callback) { + if (typeof s === 'string' && typeof salt === 'number') + bcrypt.genSalt(salt, function (err, salt) { + _hash(s, salt, callback, progressCallback); + }); + else if (typeof s === 'string' && typeof salt === 'string') + _hash(s, salt, callback, progressCallback); + else + nextTick(callback.bind(this, Error("Illegal arguments: " + (typeof s) + ', ' + (typeof salt)))); + } + + if (callback) { + if (typeof callback !== 'function') + throw Error("Illegal callback: " + typeof (callback)); + _async(callback); + } else + return new Promise(function (resolve, reject) { + _async(function (err, res) { + if (err) { + reject(err); + return; + } + resolve(res); + }); + }); + }; + + /** + * Compares two strings of the same length in constant time. + * @param {string} known Must be of the correct length + * @param {string} unknown Must be the same length as `known` + * @returns {boolean} + * @inner + */ + function safeStringCompare(known, unknown) { + var right = 0, + wrong = 0; + for (var i = 0, k = known.length; i < k; ++i) { + if (known.charCodeAt(i) === unknown.charCodeAt(i)) + ++right; + else + ++wrong; + } + // Prevent removal of unused variables (never true, actually) + if (right < 0) + return false; + return wrong === 0; + } + + /** + * Synchronously tests a string against a hash. + * @param {string} s String to compare + * @param {string} hash Hash to test against + * @returns {boolean} true if matching, otherwise false + * @throws {Error} If an argument is illegal + * @expose + */ + bcrypt.compareSync = function (s, hash) { + if (typeof s !== "string" || typeof hash !== "string") + throw Error("Illegal arguments: " + (typeof s) + ', ' + (typeof hash)); + if (hash.length !== 60) + return false; + return safeStringCompare(bcrypt.hashSync(s, hash.substr(0, hash.length - 31)), hash); + }; + + /** + * Asynchronously compares the given data against the given hash. + * @param {string} s Data to compare + * @param {string} hash Data to be compared to + * @param {function(Error, boolean)=} callback Callback receiving the error, if any, otherwise the result + * @param {function(number)=} progressCallback Callback successively called with the percentage of rounds completed + * (0.0 - 1.0), maximally once per `MAX_EXECUTION_TIME = 100` ms. + * @returns {!Promise} If `callback` has been omitted + * @throws {Error} If `callback` is present but not a function + * @expose + */ + bcrypt.compare = function (s, hash, callback, progressCallback) { + + function _async(callback) { + if (typeof s !== "string" || typeof hash !== "string") { + nextTick(callback.bind(this, Error("Illegal arguments: " + (typeof s) + ', ' + (typeof hash)))); + return; + } + if (hash.length !== 60) { + nextTick(callback.bind(this, null, false)); + return; + } + bcrypt.hash(s, hash.substr(0, 29), function (err, comp) { + if (err) + callback(err); + else + callback(null, safeStringCompare(comp, hash)); + }, progressCallback); + } + + if (callback) { + if (typeof callback !== 'function') + throw Error("Illegal callback: " + typeof (callback)); + _async(callback); + } else + return new Promise(function (resolve, reject) { + _async(function (err, res) { + if (err) { + reject(err); + return; + } + resolve(res); + }); + }); + }; + + /** + * Gets the number of rounds used to encrypt the specified hash. + * @param {string} hash Hash to extract the used number of rounds from + * @returns {number} Number of rounds used + * @throws {Error} If `hash` is not a string + * @expose + */ + bcrypt.getRounds = function (hash) { + if (typeof hash !== "string") + throw Error("Illegal arguments: " + (typeof hash)); + return parseInt(hash.split("$")[2], 10); + }; + + /** + * Gets the salt portion from a hash. Does not validate the hash. + * @param {string} hash Hash to extract the salt from + * @returns {string} Extracted salt part + * @throws {Error} If `hash` is not a string or otherwise invalid + * @expose + */ + bcrypt.getSalt = function (hash) { + if (typeof hash !== 'string') + throw Error("Illegal arguments: " + (typeof hash)); + if (hash.length !== 60) + throw Error("Illegal hash length: " + hash.length + " != 60"); + return hash.substring(0, 29); + }; + + /** + * Continues with the callback on the next tick. + * @function + * @param {function(...[*])} callback Callback to execute + * @inner + */ + var nextTick = typeof process !== 'undefined' && process && typeof process.nextTick === 'function' + ? (typeof setImmediate === 'function' ? setImmediate : process.nextTick) + : setTimeout; + + /** + * Converts a JavaScript string to UTF8 bytes. + * @param {string} str String + * @returns {!Array.} UTF8 bytes + * @inner + */ + function stringToBytes(str) { + var out = [], + i = 0; + utfx.encodeUTF16toUTF8(function () { + if (i >= str.length) return null; + return str.charCodeAt(i++); + }, function (b) { + out.push(b); + }); + return out; + } + + // A base64 implementation for the bcrypt algorithm. This is partly non-standard. + + /** + * bcrypt's own non-standard base64 dictionary. + * @type {!Array.} + * @const + * @inner + **/ + var BASE64_CODE = "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789".split(''); + + /** + * @type {!Array.} + * @const + * @inner + **/ + var BASE64_INDEX = [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, + 1, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, -1, -1, -1, -1, -1, -1, + -1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, -1, -1, -1, -1, -1, -1, 28, 29, 30, + 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, -1, -1, -1, -1, -1]; + + /** + * @type {!function(...number):string} + * @inner + */ + var stringFromCharCode = String.fromCharCode; + + /** + * Encodes a byte array to base64 with up to len bytes of input. + * @param {!Array.} b Byte array + * @param {number} len Maximum input length + * @returns {string} + * @inner + */ + function base64_encode(b, len) { + var off = 0, + rs = [], + c1, c2; + if (len <= 0 || len > b.length) + throw Error("Illegal len: " + len); + while (off < len) { + c1 = b[off++] & 0xff; + rs.push(BASE64_CODE[(c1 >> 2) & 0x3f]); + c1 = (c1 & 0x03) << 4; + if (off >= len) { + rs.push(BASE64_CODE[c1 & 0x3f]); + break; + } + c2 = b[off++] & 0xff; + c1 |= (c2 >> 4) & 0x0f; + rs.push(BASE64_CODE[c1 & 0x3f]); + c1 = (c2 & 0x0f) << 2; + if (off >= len) { + rs.push(BASE64_CODE[c1 & 0x3f]); + break; + } + c2 = b[off++] & 0xff; + c1 |= (c2 >> 6) & 0x03; + rs.push(BASE64_CODE[c1 & 0x3f]); + rs.push(BASE64_CODE[c2 & 0x3f]); + } + return rs.join(''); + } + + /** + * Decodes a base64 encoded string to up to len bytes of output. + * @param {string} s String to decode + * @param {number} len Maximum output length + * @returns {!Array.} + * @inner + */ + function base64_decode(s, len) { + var off = 0, + slen = s.length, + olen = 0, + rs = [], + c1, c2, c3, c4, o, code; + if (len <= 0) + throw Error("Illegal len: " + len); + while (off < slen - 1 && olen < len) { + code = s.charCodeAt(off++); + c1 = code < BASE64_INDEX.length ? BASE64_INDEX[code] : -1; + code = s.charCodeAt(off++); + c2 = code < BASE64_INDEX.length ? BASE64_INDEX[code] : -1; + if (c1 == -1 || c2 == -1) + break; + o = (c1 << 2) >>> 0; + o |= (c2 & 0x30) >> 4; + rs.push(stringFromCharCode(o)); + if (++olen >= len || off >= slen) + break; + code = s.charCodeAt(off++); + c3 = code < BASE64_INDEX.length ? BASE64_INDEX[code] : -1; + if (c3 == -1) + break; + o = ((c2 & 0x0f) << 4) >>> 0; + o |= (c3 & 0x3c) >> 2; + rs.push(stringFromCharCode(o)); + if (++olen >= len || off >= slen) + break; + code = s.charCodeAt(off++); + c4 = code < BASE64_INDEX.length ? BASE64_INDEX[code] : -1; + o = ((c3 & 0x03) << 6) >>> 0; + o |= c4; + rs.push(stringFromCharCode(o)); + ++olen; + } + var res = []; + for (off = 0; off < olen; off++) + res.push(rs[off].charCodeAt(0)); + return res; + } + + /** + * utfx-embeddable (c) 2014 Daniel Wirtz + * Released under the Apache License, Version 2.0 + * see: https://github.com/dcodeIO/utfx for details + */ + var utfx = function () { + // == Changed for ESM support == // + // "use strict"; + + /** + * utfx namespace. + * @inner + * @type {!Object.} + */ + var utfx = {}; + + /** + * Maximum valid code point. + * @type {number} + * @const + */ + utfx.MAX_CODEPOINT = 0x10FFFF; + + /** + * Encodes UTF8 code points to UTF8 bytes. + * @param {(!function():number|null) | number} src Code points source, either as a function returning the next code point + * respectively `null` if there are no more code points left or a single numeric code point. + * @param {!function(number)} dst Bytes destination as a function successively called with the next byte + */ + utfx.encodeUTF8 = function (src, dst) { + var cp = null; + if (typeof src === 'number') + cp = src, + src = function () { return null; }; + while (cp !== null || (cp = src()) !== null) { + if (cp < 0x80) + dst(cp & 0x7F); + else if (cp < 0x800) + dst(((cp >> 6) & 0x1F) | 0xC0), + dst((cp & 0x3F) | 0x80); + else if (cp < 0x10000) + dst(((cp >> 12) & 0x0F) | 0xE0), + dst(((cp >> 6) & 0x3F) | 0x80), + dst((cp & 0x3F) | 0x80); + else + dst(((cp >> 18) & 0x07) | 0xF0), + dst(((cp >> 12) & 0x3F) | 0x80), + dst(((cp >> 6) & 0x3F) | 0x80), + dst((cp & 0x3F) | 0x80); + cp = null; + } + }; + + /** + * Decodes UTF8 bytes to UTF8 code points. + * @param {!function():number|null} src Bytes source as a function returning the next byte respectively `null` if there + * are no more bytes left. + * @param {!function(number)} dst Code points destination as a function successively called with each decoded code point. + * @throws {RangeError} If a starting byte is invalid in UTF8 + * @throws {Error} If the last sequence is truncated. Has an array property `bytes` holding the + * remaining bytes. + */ + utfx.decodeUTF8 = function (src, dst) { + var a, b, c, d, fail = function (b) { + b = b.slice(0, b.indexOf(null)); + var err = Error(b.toString()); + err.name = "TruncatedError"; + err['bytes'] = b; + throw err; + }; + while ((a = src()) !== null) { + if ((a & 0x80) === 0) + dst(a); + else if ((a & 0xE0) === 0xC0) + ((b = src()) === null) && fail([a, b]), + dst(((a & 0x1F) << 6) | (b & 0x3F)); + else if ((a & 0xF0) === 0xE0) + ((b = src()) === null || (c = src()) === null) && fail([a, b, c]), + dst(((a & 0x0F) << 12) | ((b & 0x3F) << 6) | (c & 0x3F)); + else if ((a & 0xF8) === 0xF0) + ((b = src()) === null || (c = src()) === null || (d = src()) === null) && fail([a, b, c, d]), + dst(((a & 0x07) << 18) | ((b & 0x3F) << 12) | ((c & 0x3F) << 6) | (d & 0x3F)); + else throw RangeError("Illegal starting byte: " + a); + } + }; + + /** + * Converts UTF16 characters to UTF8 code points. + * @param {!function():number|null} src Characters source as a function returning the next char code respectively + * `null` if there are no more characters left. + * @param {!function(number)} dst Code points destination as a function successively called with each converted code + * point. + */ + utfx.UTF16toUTF8 = function (src, dst) { + var c1, c2 = null; + while (true) { + if ((c1 = c2 !== null ? c2 : src()) === null) + break; + if (c1 >= 0xD800 && c1 <= 0xDFFF) { + if ((c2 = src()) !== null) { + if (c2 >= 0xDC00 && c2 <= 0xDFFF) { + dst((c1 - 0xD800) * 0x400 + c2 - 0xDC00 + 0x10000); + c2 = null; continue; + } + } + } + dst(c1); + } + if (false) dst(c2); + }; + + /** + * Converts UTF8 code points to UTF16 characters. + * @param {(!function():number|null) | number} src Code points source, either as a function returning the next code point + * respectively `null` if there are no more code points left or a single numeric code point. + * @param {!function(number)} dst Characters destination as a function successively called with each converted char code. + * @throws {RangeError} If a code point is out of range + */ + utfx.UTF8toUTF16 = function (src, dst) { + var cp = null; + if (typeof src === 'number') + cp = src, src = function () { return null; }; + while (cp !== null || (cp = src()) !== null) { + if (cp <= 0xFFFF) + dst(cp); + else + cp -= 0x10000, + dst((cp >> 10) + 0xD800), + dst((cp % 0x400) + 0xDC00); + cp = null; + } + }; + + /** + * Converts and encodes UTF16 characters to UTF8 bytes. + * @param {!function():number|null} src Characters source as a function returning the next char code respectively `null` + * if there are no more characters left. + * @param {!function(number)} dst Bytes destination as a function successively called with the next byte. + */ + utfx.encodeUTF16toUTF8 = function (src, dst) { + utfx.UTF16toUTF8(src, function (cp) { + utfx.encodeUTF8(cp, dst); + }); + }; + + /** + * Decodes and converts UTF8 bytes to UTF16 characters. + * @param {!function():number|null} src Bytes source as a function returning the next byte respectively `null` if there + * are no more bytes left. + * @param {!function(number)} dst Characters destination as a function successively called with each converted char code. + * @throws {RangeError} If a starting byte is invalid in UTF8 + * @throws {Error} If the last sequence is truncated. Has an array property `bytes` holding the remaining bytes. + */ + utfx.decodeUTF8toUTF16 = function (src, dst) { + utfx.decodeUTF8(src, function (cp) { + utfx.UTF8toUTF16(cp, dst); + }); + }; + + /** + * Calculates the byte length of an UTF8 code point. + * @param {number} cp UTF8 code point + * @returns {number} Byte length + */ + utfx.calculateCodePoint = function (cp) { + return (cp < 0x80) ? 1 : (cp < 0x800) ? 2 : (cp < 0x10000) ? 3 : 4; + }; + + /** + * Calculates the number of UTF8 bytes required to store UTF8 code points. + * @param {(!function():number|null)} src Code points source as a function returning the next code point respectively + * `null` if there are no more code points left. + * @returns {number} The number of UTF8 bytes required + */ + utfx.calculateUTF8 = function (src) { + var cp, l = 0; + while ((cp = src()) !== null) + l += utfx.calculateCodePoint(cp); + return l; + }; + + /** + * Calculates the number of UTF8 code points respectively UTF8 bytes required to store UTF16 char codes. + * @param {(!function():number|null)} src Characters source as a function returning the next char code respectively + * `null` if there are no more characters left. + * @returns {!Array.} The number of UTF8 code points at index 0 and the number of UTF8 bytes required at index 1. + */ + utfx.calculateUTF16asUTF8 = function (src) { + var n = 0, l = 0; + utfx.UTF16toUTF8(src, function (cp) { + ++n; l += utfx.calculateCodePoint(cp); + }); + return [n, l]; + }; + + return utfx; + }(); + + Date.now = Date.now || function () { return +new Date; }; + + /** + * @type {number} + * @const + * @inner + */ + var BCRYPT_SALT_LEN = 16; + + /** + * @type {number} + * @const + * @inner + */ + var GENSALT_DEFAULT_LOG2_ROUNDS = 10; + + /** + * @type {number} + * @const + * @inner + */ + var BLOWFISH_NUM_ROUNDS = 16; + + /** + * @type {number} + * @const + * @inner + */ + var MAX_EXECUTION_TIME = 100; + + /** + * @type {Array.} + * @const + * @inner + */ + var P_ORIG = [ + 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, 0xa4093822, + 0x299f31d0, 0x082efa98, 0xec4e6c89, 0x452821e6, 0x38d01377, + 0xbe5466cf, 0x34e90c6c, 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, + 0xb5470917, 0x9216d5d9, 0x8979fb1b + ]; + + /** + * @type {Array.} + * @const + * @inner + */ + var S_ORIG = [ + 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, 0xb8e1afed, + 0x6a267e96, 0xba7c9045, 0xf12c7f99, 0x24a19947, 0xb3916cf7, + 0x0801f2e2, 0x858efc16, 0x636920d8, 0x71574e69, 0xa458fea3, + 0xf4933d7e, 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee, + 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013, 0xc5d1b023, + 0x286085f0, 0xca417918, 0xb8db38ef, 0x8e79dcb0, 0x603a180e, + 0x6c9e0e8b, 0xb01e8a3e, 0xd71577c1, 0xbd314b27, 0x78af2fda, + 0x55605c60, 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440, + 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce, 0xa15486af, + 0x7c72e993, 0xb3ee1411, 0x636fbc2a, 0x2ba9c55d, 0x741831f6, + 0xce5c3e16, 0x9b87931e, 0xafd6ba33, 0x6c24cf5c, 0x7a325381, + 0x28958677, 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193, + 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032, 0xef845d5d, + 0xe98575b1, 0xdc262302, 0xeb651b88, 0x23893e81, 0xd396acc5, + 0x0f6d6ff3, 0x83f44239, 0x2e0b4482, 0xa4842004, 0x69c8f04a, + 0x9e1f9b5e, 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0, + 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3, 0x6eef0b6c, + 0x137a3be4, 0xba3bf050, 0x7efb2a98, 0xa1f1651d, 0x39af0176, + 0x66ca593e, 0x82430e88, 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, + 0x3b8b5ebe, 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, + 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d, 0x37d0d724, + 0xd00a1248, 0xdb0fead3, 0x49f1c09b, 0x075372c9, 0x80991b7b, + 0x25d479d8, 0xf6e8def7, 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, + 0x04c006ba, 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463, + 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, 0x6dfc511f, + 0x9b30952c, 0xcc814544, 0xaf5ebd09, 0xbee3d004, 0xde334afd, + 0x660f2807, 0x192e4bb3, 0xc0cba857, 0x45c8740f, 0xd20b5f39, + 0xb9d3fbdb, 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279, + 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8, 0x3c7516df, + 0xfd616b15, 0x2f501ec8, 0xad0552ab, 0x323db5fa, 0xfd238760, + 0x53317b48, 0x3e00df82, 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, + 0xdf1769db, 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573, + 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0, 0x10fa3d98, + 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b, 0x9a53e479, 0xb6f84565, + 0xd28e49bc, 0x4bfb9790, 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, + 0xcee4c6e8, 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4, + 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0, 0xd08ed1d0, + 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7, 0x8ff6e2fb, 0xf2122b64, + 0x8888b812, 0x900df01c, 0x4fad5ea0, 0x688fc31c, 0xd1cff191, + 0xb3a8c1ad, 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1, + 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299, 0xb4a84fe0, + 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9, 0x165fa266, 0x80957705, + 0x93cc7314, 0x211a1477, 0xe6ad2065, 0x77b5fa86, 0xc75442f5, + 0xfb9d35cf, 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, + 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af, 0x2464369b, + 0xf009b91e, 0x5563911d, 0x59dfa6aa, 0x78c14389, 0xd95a537f, + 0x207d5ba2, 0x02e5b9c5, 0x83260376, 0x6295cfa9, 0x11c81968, + 0x4e734a41, 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915, + 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, 0x08ba6fb5, + 0x571be91f, 0xf296ec6b, 0x2a0dd915, 0xb6636521, 0xe7b9f9b6, + 0xff34052e, 0xc5855664, 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, + 0x6e85076a, 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, + 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266, 0xecaa8c71, + 0x699a17ff, 0x5664526c, 0xc2b19ee1, 0x193602a5, 0x75094c29, + 0xa0591340, 0xe4183a3e, 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, + 0x99f73fd6, 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1, + 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, 0x09686b3f, + 0x3ebaefc9, 0x3c971814, 0x6b6a70a1, 0x687f3584, 0x52a0e286, + 0xb79c5305, 0xaa500737, 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, + 0x5716f2b8, 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff, + 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd, 0xd19113f9, + 0x7ca92ff6, 0x94324773, 0x22f54701, 0x3ae5e581, 0x37c2dadc, + 0xc8b57634, 0x9af3dda7, 0xa9446146, 0x0fd0030e, 0xecc8c73e, + 0xa4751e41, 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331, + 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf, 0x2cb81290, + 0x24977c79, 0x5679b072, 0xbcaf89af, 0xde9a771f, 0xd9930810, + 0xb38bae12, 0xdccf3f2e, 0x5512721f, 0x2e6b7124, 0x501adde6, + 0x9f84cd87, 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c, + 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2, 0xef1c1847, + 0x3215d908, 0xdd433b37, 0x24c2ba16, 0x12a14d43, 0x2a65c451, + 0x50940002, 0x133ae4dd, 0x71dff89e, 0x10314e55, 0x81ac77d6, + 0x5f11199b, 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509, + 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, 0x86e34570, + 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3, 0x771fe71c, 0x4e3d06fa, + 0x2965dcb9, 0x99e71d0f, 0x803e89d6, 0x5266c825, 0x2e4cc978, + 0x9c10b36a, 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, + 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960, 0x5223a708, + 0xf71312b6, 0xebadfe6e, 0xeac31f66, 0xe3bc4595, 0xa67bc883, + 0xb17f37d1, 0x018cff28, 0xc332ddef, 0xbe6c5aa5, 0x65582185, + 0x68ab9802, 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84, + 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, 0x13cca830, + 0xeb61bd96, 0x0334fe1e, 0xaa0363cf, 0xb5735c90, 0x4c70a239, + 0xd59e9e0b, 0xcbaade14, 0xeecc86bc, 0x60622ca7, 0x9cab5cab, + 0xb2f3846e, 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50, + 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7, 0x9b540b19, + 0x875fa099, 0x95f7997e, 0x623d7da8, 0xf837889a, 0x97e32d77, + 0x11ed935f, 0x16681281, 0x0e358829, 0xc7e61fd6, 0x96dedfa1, + 0x7858ba99, 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696, + 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128, 0x58ebf2ef, + 0x34c6ffea, 0xfe28ed61, 0xee7c3c73, 0x5d4a14d9, 0xe864b7e3, + 0x42105d14, 0x203e13e0, 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, + 0xfacb4fd0, 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105, + 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250, 0xcf62a1f2, + 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3, 0x7f1524c3, 0x69cb7492, + 0x47848a0b, 0x5692b285, 0x095bbf00, 0xad19489d, 0x1462b174, + 0x23820e00, 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061, + 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb, 0x7cde3759, + 0xcbee7460, 0x4085f2a7, 0xce77326e, 0xa6078084, 0x19f8509e, + 0xe8efd855, 0x61d99735, 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, + 0x800bcadc, 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, + 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340, 0xc5c43465, + 0x713e38d8, 0x3d28f89e, 0xf16dff20, 0x153e21e7, 0x8fb03d4a, + 0xe6e39f2b, 0xdb83adf7, 0xe93d5a68, 0x948140f7, 0xf64c261c, + 0x94692934, 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068, + 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af, 0x1e39f62e, + 0x97244546, 0x14214f74, 0xbf8b8840, 0x4d95fc1d, 0x96b591af, + 0x70f4ddd3, 0x66a02f45, 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, + 0x31cb8504, 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, + 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb, 0x68dc1462, + 0xd7486900, 0x680ec0a4, 0x27a18dee, 0x4f3ffea2, 0xe887ad8c, + 0xb58ce006, 0x7af4d6b6, 0xaace1e7c, 0xd3375fec, 0xce78a399, + 0x406b2a42, 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b, + 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, 0x3a6efa74, + 0xdd5b4332, 0x6841e7f7, 0xca7820fb, 0xfb0af54e, 0xd8feb397, + 0x454056ac, 0xba489527, 0x55533a3a, 0x20838d87, 0xfe6ba9b7, + 0xd096954b, 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33, + 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c, 0xfdf8e802, + 0x04272f70, 0x80bb155c, 0x05282ce3, 0x95c11548, 0xe4c66d22, + 0x48c1133f, 0xc70f86dc, 0x07f9c9ee, 0x41041f0f, 0x404779a4, + 0x5d886e17, 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564, + 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b, 0x0e12b4c2, + 0x02e1329e, 0xaf664fd1, 0xcad18115, 0x6b2395e0, 0x333e92e1, + 0x3b240b62, 0xeebeb922, 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, + 0x2da2f728, 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0, + 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e, 0x0a476341, + 0x992eff74, 0x3a6f6eab, 0xf4f8fd37, 0xa812dc60, 0xa1ebddf8, + 0x991be14c, 0xdb6e6b0d, 0xc67b5510, 0x6d672c37, 0x2765d43b, + 0xdcd0e804, 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b, + 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3, 0xbb132f88, + 0x515bad24, 0x7b9479bf, 0x763bd6eb, 0x37392eb3, 0xcc115979, + 0x8026e297, 0xf42e312d, 0x6842ada7, 0xc66a2b3b, 0x12754ccc, + 0x782ef11c, 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, + 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9, 0x44421659, + 0x0a121386, 0xd90cec6e, 0xd5abea2a, 0x64af674e, 0xda86a85f, + 0xbebfe988, 0x64e4c3fe, 0x9dbc8057, 0xf0f7c086, 0x60787bf8, + 0x6003604d, 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc, + 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, 0x77a057be, + 0xbde8ae24, 0x55464299, 0xbf582e61, 0x4e58f48f, 0xf2ddfda2, + 0xf474ef38, 0x8789bdc2, 0x5366f9c3, 0xc8b38e74, 0xb475f255, + 0x46fcd9b9, 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2, + 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c, 0xb90bace1, + 0xbb8205d0, 0x11a86248, 0x7574a99e, 0xb77f19b6, 0xe0a9dc09, + 0x662d09a1, 0xc4324633, 0xe85a1f02, 0x09f0be8c, 0x4a99a025, + 0x1d6efe10, 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169, + 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52, 0x50115e01, + 0xa70683fa, 0xa002b5c4, 0x0de6d027, 0x9af88c27, 0x773f8641, + 0xc3604c06, 0x61a806b5, 0xf0177a28, 0xc0f586e0, 0x006058aa, + 0x30dc7d62, 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634, + 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76, 0x6f05e409, + 0x4b7c0188, 0x39720a3d, 0x7c927c24, 0x86e3725f, 0x724d9db9, + 0x1ac15bb4, 0xd39eb8fc, 0xed545578, 0x08fca5b5, 0xd83d7cd3, + 0x4dad0fc4, 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c, + 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837, 0xd79a3234, + 0x92638212, 0x670efa8e, 0x406000e0, 0x3a39ce37, 0xd3faf5cf, + 0xabc27737, 0x5ac52d1b, 0x5cb0679e, 0x4fa33742, 0xd3822740, + 0x99bc9bbe, 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b, + 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4, 0x5748ab2f, + 0xbc946e79, 0xc6a376d2, 0x6549c2c8, 0x530ff8ee, 0x468dde7d, + 0xd5730a1d, 0x4cd04dc6, 0x2939bbdb, 0xa9ba4650, 0xac9526e8, + 0xbe5ee304, 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22, + 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4, 0x83c061ba, + 0x9be96a4d, 0x8fe51550, 0xba645bd6, 0x2826a2f9, 0xa73a3ae1, + 0x4ba99586, 0xef5562e9, 0xc72fefd3, 0xf752f7da, 0x3f046f69, + 0x77fa0a59, 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, + 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51, 0x96d5ac3a, + 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28, 0x1f9f25cf, 0xadf2b89b, + 0x5ad6b472, 0x5a88f54c, 0xe029ac71, 0xe019a5e6, 0x47b0acfd, + 0xed93fa9b, 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28, + 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, 0x15056dd4, + 0x88f46dba, 0x03a16125, 0x0564f0bd, 0xc3eb9e15, 0x3c9057a2, + 0x97271aec, 0xa93a072a, 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, + 0x26dcf319, 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb, + 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f, 0x4de81751, + 0x3830dc8e, 0x379d5862, 0x9320f991, 0xea7a90c2, 0xfb3e7bce, + 0x5121ce64, 0x774fbe32, 0xa8b6e37e, 0xc3293d46, 0x48de5369, + 0x6413e680, 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166, + 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae, 0x5bbef7dd, + 0x1b588d40, 0xccd2017f, 0x6bb4e3bb, 0xdda26a7e, 0x3a59ff45, + 0x3e350a44, 0xbcb4cdd5, 0x72eacea8, 0xfa6484bb, 0x8d6612ae, + 0xbf3c6f47, 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370, + 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d, 0x4040cb08, + 0x4eb4e2cc, 0x34d2466a, 0x0115af84, 0xe1b00428, 0x95983a1d, + 0x06b89fb4, 0xce6ea048, 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, + 0x277227f8, 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd, + 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9, 0xe01cc87e, + 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7, 0x1a908749, 0xd44fbd9a, + 0xd0dadecb, 0xd50ada38, 0x0339c32a, 0xc6913667, 0x8df9317c, + 0xe0b12b4f, 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, + 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525, 0xfae59361, + 0xceb69ceb, 0xc2a86459, 0x12baa8d1, 0xb6c1075e, 0xe3056a0c, + 0x10d25065, 0xcb03a442, 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, + 0x3278e964, 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e, + 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, 0xdf359f8d, + 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d, 0xe54cda54, 0x1edad891, + 0xce6279cf, 0xcd3e7e6f, 0x1618b166, 0xfd2c1d05, 0x848fd2c5, + 0xf6fb2299, 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02, + 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc, 0xde966292, + 0x81b949d0, 0x4c50901b, 0x71c65614, 0xe6c6c7bd, 0x327a140a, + 0x45e1d006, 0xc3f27b9a, 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, + 0x35bdd2f6, 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b, + 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0, 0xba38209c, + 0xf746ce76, 0x77afa1c5, 0x20756060, 0x85cbfe4e, 0x8ae88dd8, + 0x7aaaf9b0, 0x4cf9aa7e, 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, + 0xd6ebe1f9, 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f, + 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6 + ]; + + /** + * @type {Array.} + * @const + * @inner + */ + var C_ORIG = [ + 0x4f727068, 0x65616e42, 0x65686f6c, 0x64657253, 0x63727944, + 0x6f756274 + ]; + + /** + * @param {Array.} lr + * @param {number} off + * @param {Array.} P + * @param {Array.} S + * @returns {Array.} + * @inner + */ + function _encipher(lr, off, P, S) { // This is our bottleneck: 1714/1905 ticks / 90% - see profile.txt + var n, + l = lr[off], + r = lr[off + 1]; + + l ^= P[0]; + + /* + for (var i=0, k=BLOWFISH_NUM_ROUNDS-2; i<=k;) + // Feistel substitution on left word + n = S[l >>> 24], + n += S[0x100 | ((l >> 16) & 0xff)], + n ^= S[0x200 | ((l >> 8) & 0xff)], + n += S[0x300 | (l & 0xff)], + r ^= n ^ P[++i], + // Feistel substitution on right word + n = S[r >>> 24], + n += S[0x100 | ((r >> 16) & 0xff)], + n ^= S[0x200 | ((r >> 8) & 0xff)], + n += S[0x300 | (r & 0xff)], + l ^= n ^ P[++i]; + */ + + //The following is an unrolled version of the above loop. + //Iteration 0 + n = S[l >>> 24]; + n += S[0x100 | ((l >> 16) & 0xff)]; + n ^= S[0x200 | ((l >> 8) & 0xff)]; + n += S[0x300 | (l & 0xff)]; + r ^= n ^ P[1]; + n = S[r >>> 24]; + n += S[0x100 | ((r >> 16) & 0xff)]; + n ^= S[0x200 | ((r >> 8) & 0xff)]; + n += S[0x300 | (r & 0xff)]; + l ^= n ^ P[2]; + //Iteration 1 + n = S[l >>> 24]; + n += S[0x100 | ((l >> 16) & 0xff)]; + n ^= S[0x200 | ((l >> 8) & 0xff)]; + n += S[0x300 | (l & 0xff)]; + r ^= n ^ P[3]; + n = S[r >>> 24]; + n += S[0x100 | ((r >> 16) & 0xff)]; + n ^= S[0x200 | ((r >> 8) & 0xff)]; + n += S[0x300 | (r & 0xff)]; + l ^= n ^ P[4]; + //Iteration 2 + n = S[l >>> 24]; + n += S[0x100 | ((l >> 16) & 0xff)]; + n ^= S[0x200 | ((l >> 8) & 0xff)]; + n += S[0x300 | (l & 0xff)]; + r ^= n ^ P[5]; + n = S[r >>> 24]; + n += S[0x100 | ((r >> 16) & 0xff)]; + n ^= S[0x200 | ((r >> 8) & 0xff)]; + n += S[0x300 | (r & 0xff)]; + l ^= n ^ P[6]; + //Iteration 3 + n = S[l >>> 24]; + n += S[0x100 | ((l >> 16) & 0xff)]; + n ^= S[0x200 | ((l >> 8) & 0xff)]; + n += S[0x300 | (l & 0xff)]; + r ^= n ^ P[7]; + n = S[r >>> 24]; + n += S[0x100 | ((r >> 16) & 0xff)]; + n ^= S[0x200 | ((r >> 8) & 0xff)]; + n += S[0x300 | (r & 0xff)]; + l ^= n ^ P[8]; + //Iteration 4 + n = S[l >>> 24]; + n += S[0x100 | ((l >> 16) & 0xff)]; + n ^= S[0x200 | ((l >> 8) & 0xff)]; + n += S[0x300 | (l & 0xff)]; + r ^= n ^ P[9]; + n = S[r >>> 24]; + n += S[0x100 | ((r >> 16) & 0xff)]; + n ^= S[0x200 | ((r >> 8) & 0xff)]; + n += S[0x300 | (r & 0xff)]; + l ^= n ^ P[10]; + //Iteration 5 + n = S[l >>> 24]; + n += S[0x100 | ((l >> 16) & 0xff)]; + n ^= S[0x200 | ((l >> 8) & 0xff)]; + n += S[0x300 | (l & 0xff)]; + r ^= n ^ P[11]; + n = S[r >>> 24]; + n += S[0x100 | ((r >> 16) & 0xff)]; + n ^= S[0x200 | ((r >> 8) & 0xff)]; + n += S[0x300 | (r & 0xff)]; + l ^= n ^ P[12]; + //Iteration 6 + n = S[l >>> 24]; + n += S[0x100 | ((l >> 16) & 0xff)]; + n ^= S[0x200 | ((l >> 8) & 0xff)]; + n += S[0x300 | (l & 0xff)]; + r ^= n ^ P[13]; + n = S[r >>> 24]; + n += S[0x100 | ((r >> 16) & 0xff)]; + n ^= S[0x200 | ((r >> 8) & 0xff)]; + n += S[0x300 | (r & 0xff)]; + l ^= n ^ P[14]; + //Iteration 7 + n = S[l >>> 24]; + n += S[0x100 | ((l >> 16) & 0xff)]; + n ^= S[0x200 | ((l >> 8) & 0xff)]; + n += S[0x300 | (l & 0xff)]; + r ^= n ^ P[15]; + n = S[r >>> 24]; + n += S[0x100 | ((r >> 16) & 0xff)]; + n ^= S[0x200 | ((r >> 8) & 0xff)]; + n += S[0x300 | (r & 0xff)]; + l ^= n ^ P[16]; + + lr[off] = r ^ P[BLOWFISH_NUM_ROUNDS + 1]; + lr[off + 1] = l; + return lr; + } + + /** + * @param {Array.} data + * @param {number} offp + * @returns {{key: number, offp: number}} + * @inner + */ + function _streamtoword(data, offp) { + for (var i = 0, word = 0; i < 4; ++i) + word = (word << 8) | (data[offp] & 0xff), + offp = (offp + 1) % data.length; + return { key: word, offp: offp }; + } + + /** + * @param {Array.} key + * @param {Array.} P + * @param {Array.} S + * @inner + */ + function _key(key, P, S) { + var offset = 0, + lr = [0, 0], + plen = P.length, + slen = S.length, + sw; + for (var i = 0; i < plen; i++) + sw = _streamtoword(key, offset), + offset = sw.offp, + P[i] = P[i] ^ sw.key; + for (i = 0; i < plen; i += 2) + lr = _encipher(lr, 0, P, S), + P[i] = lr[0], + P[i + 1] = lr[1]; + for (i = 0; i < slen; i += 2) + lr = _encipher(lr, 0, P, S), + S[i] = lr[0], + S[i + 1] = lr[1]; + } + + /** + * Expensive key schedule Blowfish. + * @param {Array.} data + * @param {Array.} key + * @param {Array.} P + * @param {Array.} S + * @inner + */ + function _ekskey(data, key, P, S) { + var offp = 0, + lr = [0, 0], + plen = P.length, + slen = S.length, + sw; + for (var i = 0; i < plen; i++) + sw = _streamtoword(key, offp), + offp = sw.offp, + P[i] = P[i] ^ sw.key; + offp = 0; + for (i = 0; i < plen; i += 2) + sw = _streamtoword(data, offp), + offp = sw.offp, + lr[0] ^= sw.key, + sw = _streamtoword(data, offp), + offp = sw.offp, + lr[1] ^= sw.key, + lr = _encipher(lr, 0, P, S), + P[i] = lr[0], + P[i + 1] = lr[1]; + for (i = 0; i < slen; i += 2) + sw = _streamtoword(data, offp), + offp = sw.offp, + lr[0] ^= sw.key, + sw = _streamtoword(data, offp), + offp = sw.offp, + lr[1] ^= sw.key, + lr = _encipher(lr, 0, P, S), + S[i] = lr[0], + S[i + 1] = lr[1]; + } + + /** + * Internaly crypts a string. + * @param {Array.} b Bytes to crypt + * @param {Array.} salt Salt bytes to use + * @param {number} rounds Number of rounds + * @param {function(Error, Array.=)=} callback Callback receiving the error, if any, and the resulting bytes. If + * omitted, the operation will be performed synchronously. + * @param {function(number)=} progressCallback Callback called with the current progress + * @returns {!Array.|undefined} Resulting bytes if callback has been omitted, otherwise `undefined` + * @inner + */ + function _crypt(b, salt, rounds, callback, progressCallback) { + var cdata = C_ORIG.slice(), + clen = cdata.length, + err; + + // Validate + if (rounds < 4 || rounds > 31) { + err = Error("Illegal number of rounds (4-31): " + rounds); + if (callback) { + nextTick(callback.bind(this, err)); + return; + } else + throw err; + } + if (salt.length !== BCRYPT_SALT_LEN) { + err = Error("Illegal salt length: " + salt.length + " != " + BCRYPT_SALT_LEN); + if (callback) { + nextTick(callback.bind(this, err)); + return; + } else + throw err; + } + rounds = (1 << rounds) >>> 0; + + var P, S, i = 0, j; + + //Use typed arrays when available - huge speedup! + if (Int32Array) { + P = new Int32Array(P_ORIG); + S = new Int32Array(S_ORIG); + } else { + P = P_ORIG.slice(); + S = S_ORIG.slice(); + } + + _ekskey(salt, b, P, S); + + /** + * Calcualtes the next round. + * @returns {Array.|undefined} Resulting array if callback has been omitted, otherwise `undefined` + * @inner + */ + function next() { + if (progressCallback) + progressCallback(i / rounds); + if (i < rounds) { + var start = Date.now(); + for (; i < rounds;) { + i = i + 1; + _key(b, P, S); + _key(salt, P, S); + if (Date.now() - start > MAX_EXECUTION_TIME) + break; + } + } else { + for (i = 0; i < 64; i++) + for (j = 0; j < (clen >> 1); j++) + _encipher(cdata, j << 1, P, S); + var ret = []; + for (i = 0; i < clen; i++) + ret.push(((cdata[i] >> 24) & 0xff) >>> 0), + ret.push(((cdata[i] >> 16) & 0xff) >>> 0), + ret.push(((cdata[i] >> 8) & 0xff) >>> 0), + ret.push((cdata[i] & 0xff) >>> 0); + if (callback) { + callback(null, ret); + return; + } else + return ret; + } + if (callback) + nextTick(next); + } + + // Async + if (typeof callback !== 'undefined') { + next(); + + // Sync + } else { + var res; + while (true) + if (typeof (res = next()) !== 'undefined') + return res || []; + } + } + + /** + * Internally hashes a string. + * @param {string} s String to hash + * @param {?string} salt Salt to use, actually never null + * @param {function(Error, string=)=} callback Callback receiving the error, if any, and the resulting hash. If omitted, + * hashing is perormed synchronously. + * @param {function(number)=} progressCallback Callback called with the current progress + * @returns {string|undefined} Resulting hash if callback has been omitted, otherwise `undefined` + * @inner + */ + function _hash(s, salt, callback, progressCallback) { + var err; + if (typeof s !== 'string' || typeof salt !== 'string') { + err = Error("Invalid string / salt: Not a string"); + if (callback) { + nextTick(callback.bind(this, err)); + return; + } + else + throw err; + } + + // Validate the salt + var minor, offset; + if (salt.charAt(0) !== '$' || salt.charAt(1) !== '2') { + err = Error("Invalid salt version: " + salt.substring(0, 2)); + if (callback) { + nextTick(callback.bind(this, err)); + return; + } + else + throw err; + } + if (salt.charAt(2) === '$') + minor = String.fromCharCode(0), + offset = 3; + else { + minor = salt.charAt(2); + if ((minor !== 'a' && minor !== 'b' && minor !== 'y') || salt.charAt(3) !== '$') { + err = Error("Invalid salt revision: " + salt.substring(2, 4)); + if (callback) { + nextTick(callback.bind(this, err)); + return; + } else + throw err; + } + offset = 4; + } + + // Extract number of rounds + if (salt.charAt(offset + 2) > '$') { + err = Error("Missing salt rounds"); + if (callback) { + nextTick(callback.bind(this, err)); + return; + } else + throw err; + } + var r1 = parseInt(salt.substring(offset, offset + 1), 10) * 10, + r2 = parseInt(salt.substring(offset + 1, offset + 2), 10), + rounds = r1 + r2, + real_salt = salt.substring(offset + 3, offset + 25); + s += minor >= 'a' ? "\x00" : ""; + + var passwordb = stringToBytes(s), + saltb = base64_decode(real_salt, BCRYPT_SALT_LEN); + + /** + * Finishes hashing. + * @param {Array.} bytes Byte array + * @returns {string} + * @inner + */ + function finish(bytes) { + var res = []; + res.push("$2"); + if (minor >= 'a') + res.push(minor); + res.push("$"); + if (rounds < 10) + res.push("0"); + res.push(rounds.toString()); + res.push("$"); + res.push(base64_encode(saltb, saltb.length)); + res.push(base64_encode(bytes, C_ORIG.length * 4 - 1)); + return res.join(''); + } + + // Sync + if (typeof callback == 'undefined') + return finish(_crypt(passwordb, saltb, rounds)); + + // Async + else { + _crypt(passwordb, saltb, rounds, function (err, bytes) { + if (err) + callback(err, null); + else + callback(null, finish(bytes)); + }, progressCallback); + } + } + + /** + * Encodes a byte array to base64 with up to len bytes of input, using the custom bcrypt alphabet. + * @function + * @param {!Array.} b Byte array + * @param {number} len Maximum input length + * @returns {string} + * @expose + */ + bcrypt.encodeBase64 = base64_encode; + + /** + * Decodes a base64 encoded string to up to len bytes of output, using the custom bcrypt alphabet. + * @function + * @param {string} s String to decode + * @param {number} len Maximum output length + * @returns {!Array.} + * @expose + */ + bcrypt.decodeBase64 = base64_decode; + + return bcrypt; })); diff --git a/crypto/api/deps/broken-ripemd160.js b/crypto/api/deps/broken-ripemd160.js index 9045ef21..1f266194 100644 --- a/crypto/api/deps/broken-ripemd160.js +++ b/crypto/api/deps/broken-ripemd160.js @@ -1,180 +1,179 @@ // "Generated from Java with JSweet 1.0.0 - http://www.jsweet.org"; // BAD IMPLEMENTATION. BROKEN, BUT MUST KEEP CAUSE OF NETWORK -//const RIPEMD160 = (function () { // == Convert to ES6 module for export == // const RIPEMD160 = (function () { - function RIPEMD160() { - this.MDbuf = []; - this.MDbuf[0] = 1732584193; - this.MDbuf[1] = -271733879; - this.MDbuf[2] = -1732584194; - this.MDbuf[3] = 271733878; - this.MDbuf[4] = -1009589776; - this.working = new Int32Array(16); + function RIPEMD160() { + this.MDbuf = []; + this.MDbuf[0] = 1732584193; + this.MDbuf[1] = -271733879; + this.MDbuf[2] = -1732584194; + this.MDbuf[3] = 271733878; + this.MDbuf[4] = -1009589776; + this.working = new Int32Array(16); - this.working_ptr = 0; - this.msglen = 0; - } - RIPEMD160.prototype.reset = function () { - this.MDbuf = []; - this.MDbuf[0] = 1732584193; - this.MDbuf[1] = -271733879; - this.MDbuf[2] = -1732584194; - this.MDbuf[3] = 271733878; - this.MDbuf[4] = -1009589776; - this.working = new Int32Array(16); - this.working_ptr = 0; - this.msglen = 0; - }; - RIPEMD160.prototype.compress = function (X) { - var index = 0; - var a; - var b; - var c; - var d; - var e; - var A; - var B; - var C; - var D; - var E; - var temp; - var s; - A = a = this.MDbuf[0]; - B = b = this.MDbuf[1]; - C = c = this.MDbuf[2]; - D = d = this.MDbuf[3]; - E = e = this.MDbuf[4]; - for (; index < 16; index++) { - temp = a + (b ^ c ^ d) + X[RIPEMD160.IndexArray[0][index]]; - a = e; - e = d; - d = (c << 10) | (c >>> 22); - c = b; - s = RIPEMD160.ArgArray[0][index]; - b = ((temp << s) | (temp >>> (32 - s))) + a; - temp = A + (B ^ (C | ~D)) + X[RIPEMD160.IndexArray[1][index]] + 1352829926; - A = E; - E = D; - D = (C << 10) | (C >>> 22); - C = B; - s = RIPEMD160.ArgArray[1][index]; - B = ((temp << s) | (temp >>> (32 - s))) + A; - } - for (; index < 32; index++) { - temp = a + ((b & c) | (~b & d)) + X[RIPEMD160.IndexArray[0][index]] + 1518500249; - a = e; - e = d; - d = (c << 10) | (c >>> 22); - c = b; - s = RIPEMD160.ArgArray[0][index]; - b = ((temp << s) | (temp >>> (32 - s))) + a; - temp = A + ((B & D) | (C & ~D)) + X[RIPEMD160.IndexArray[1][index]] + 1548603684; - A = E; - E = D; - D = (C << 10) | (C >>> 22); - C = B; - s = RIPEMD160.ArgArray[1][index]; - B = ((temp << s) | (temp >>> (32 - s))) + A; - } - for (; index < 48; index++) { - temp = a + ((b | ~c) ^ d) + X[RIPEMD160.IndexArray[0][index]] + 1859775393; - a = e; - e = d; - d = (c << 10) | (c >>> 22); - c = b; - s = RIPEMD160.ArgArray[0][index]; - b = ((temp << s) | (temp >>> (32 - s))) + a; - temp = A + ((B | ~C) ^ D) + X[RIPEMD160.IndexArray[1][index]] + 1836072691; - A = E; - E = D; - D = (C << 10) | (C >>> 22); - C = B; - s = RIPEMD160.ArgArray[1][index]; - B = ((temp << s) | (temp >>> (32 - s))) + A; - } - for (; index < 64; index++) { - temp = a + ((b & d) | (c & ~d)) + X[RIPEMD160.IndexArray[0][index]] + -1894007588; - a = e; - e = d; - d = (c << 10) | (c >>> 22); - c = b; - s = RIPEMD160.ArgArray[0][index]; - b = ((temp << s) | (temp >>> (32 - s))) + a; - temp = A + ((B & C) | (~B & D)) + X[RIPEMD160.IndexArray[1][index]] + 2053994217; - A = E; - E = D; - D = (C << 10) | (C >>> 22); - C = B; - s = RIPEMD160.ArgArray[1][index]; - B = ((temp << s) | (temp >>> (32 - s))) + A; - } - for (; index < 80; index++) { - temp = a + (b ^ (c | ~d)) + X[RIPEMD160.IndexArray[0][index]] + -1454113458; - a = e; - e = d; - d = (c << 10) | (c >>> 22); - c = b; - s = RIPEMD160.ArgArray[0][index]; - b = ((temp << s) | (temp >>> (32 - s))) + a; - temp = A + (B ^ C ^ D) + X[RIPEMD160.IndexArray[1][index]]; - A = E; - E = D; - D = (C << 10) | (C >>> 22); - C = B; - s = RIPEMD160.ArgArray[1][index]; - B = ((temp << s) | (temp >>> (32 - s))) + A; - } - D += c + this.MDbuf[1]; - this.MDbuf[1] = this.MDbuf[2] + d + E; - this.MDbuf[2] = this.MDbuf[3] + e + A; - this.MDbuf[3] = this.MDbuf[4] + a + B; - this.MDbuf[4] = this.MDbuf[0] + b + C; - this.MDbuf[0] = D; - }; - RIPEMD160.prototype.MDfinish = function (array, lswlen, mswlen) { - var X = array; - X[(lswlen >> 2) & 15] ^= 1 << (((lswlen & 3) << 3) + 7); - if (((lswlen & 63) > 55)) { - this.compress(X); - for (var i = 0; i < 14; i++) { - X[i] = 0; - } - } - X[14] = lswlen << 3; - X[15] = (lswlen >> 29) | (mswlen << 3); - this.compress(X); - }; - RIPEMD160.prototype.update = function (input) { - for (var i = 0; i < input.length; i++) { - this.working[this.working_ptr >> 2] ^= input[i] << ((this.working_ptr & 3) << 3); - this.working_ptr++; - if ((this.working_ptr == 64)) { - this.compress(this.working); - for (var j = 0; j < 16; j++) { - this.working[j] = 0; - } - this.working_ptr = 0; - } - } - this.msglen += input.length; - }; - RIPEMD160.prototype.digestBin = function () { - this.MDfinish(this.working, this.msglen, 0); - //var res = new Int8Array(); - var res = []; - for (var i = 0; i < 20; i++) { - res[i] = ((this.MDbuf[i >> 2] >>> ((i & 3) << 3)) & 255); - } - return new Uint8Array(res); - }; - RIPEMD160.prototype.digest = function (input) { - this.update(new Int8Array(input)); - return this.digestBin(); - }; - RIPEMD160.ArgArray = [[11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8, 7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12, 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5, 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12, 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6], [8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6, 9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11, 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5, 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8, 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11]]; - RIPEMD160.IndexArray = [[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8, 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12, 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2, 4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13], [5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12, 6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2, 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13, 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14, 12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11]]; - return RIPEMD160; + this.working_ptr = 0; + this.msglen = 0; + } + RIPEMD160.prototype.reset = function () { + this.MDbuf = []; + this.MDbuf[0] = 1732584193; + this.MDbuf[1] = -271733879; + this.MDbuf[2] = -1732584194; + this.MDbuf[3] = 271733878; + this.MDbuf[4] = -1009589776; + this.working = new Int32Array(16); + this.working_ptr = 0; + this.msglen = 0; + }; + RIPEMD160.prototype.compress = function (X) { + var index = 0; + var a; + var b; + var c; + var d; + var e; + var A; + var B; + var C; + var D; + var E; + var temp; + var s; + A = a = this.MDbuf[0]; + B = b = this.MDbuf[1]; + C = c = this.MDbuf[2]; + D = d = this.MDbuf[3]; + E = e = this.MDbuf[4]; + for (; index < 16; index++) { + temp = a + (b ^ c ^ d) + X[RIPEMD160.IndexArray[0][index]]; + a = e; + e = d; + d = (c << 10) | (c >>> 22); + c = b; + s = RIPEMD160.ArgArray[0][index]; + b = ((temp << s) | (temp >>> (32 - s))) + a; + temp = A + (B ^ (C | ~D)) + X[RIPEMD160.IndexArray[1][index]] + 1352829926; + A = E; + E = D; + D = (C << 10) | (C >>> 22); + C = B; + s = RIPEMD160.ArgArray[1][index]; + B = ((temp << s) | (temp >>> (32 - s))) + A; + } + for (; index < 32; index++) { + temp = a + ((b & c) | (~b & d)) + X[RIPEMD160.IndexArray[0][index]] + 1518500249; + a = e; + e = d; + d = (c << 10) | (c >>> 22); + c = b; + s = RIPEMD160.ArgArray[0][index]; + b = ((temp << s) | (temp >>> (32 - s))) + a; + temp = A + ((B & D) | (C & ~D)) + X[RIPEMD160.IndexArray[1][index]] + 1548603684; + A = E; + E = D; + D = (C << 10) | (C >>> 22); + C = B; + s = RIPEMD160.ArgArray[1][index]; + B = ((temp << s) | (temp >>> (32 - s))) + A; + } + for (; index < 48; index++) { + temp = a + ((b | ~c) ^ d) + X[RIPEMD160.IndexArray[0][index]] + 1859775393; + a = e; + e = d; + d = (c << 10) | (c >>> 22); + c = b; + s = RIPEMD160.ArgArray[0][index]; + b = ((temp << s) | (temp >>> (32 - s))) + a; + temp = A + ((B | ~C) ^ D) + X[RIPEMD160.IndexArray[1][index]] + 1836072691; + A = E; + E = D; + D = (C << 10) | (C >>> 22); + C = B; + s = RIPEMD160.ArgArray[1][index]; + B = ((temp << s) | (temp >>> (32 - s))) + A; + } + for (; index < 64; index++) { + temp = a + ((b & d) | (c & ~d)) + X[RIPEMD160.IndexArray[0][index]] + -1894007588; + a = e; + e = d; + d = (c << 10) | (c >>> 22); + c = b; + s = RIPEMD160.ArgArray[0][index]; + b = ((temp << s) | (temp >>> (32 - s))) + a; + temp = A + ((B & C) | (~B & D)) + X[RIPEMD160.IndexArray[1][index]] + 2053994217; + A = E; + E = D; + D = (C << 10) | (C >>> 22); + C = B; + s = RIPEMD160.ArgArray[1][index]; + B = ((temp << s) | (temp >>> (32 - s))) + A; + } + for (; index < 80; index++) { + temp = a + (b ^ (c | ~d)) + X[RIPEMD160.IndexArray[0][index]] + -1454113458; + a = e; + e = d; + d = (c << 10) | (c >>> 22); + c = b; + s = RIPEMD160.ArgArray[0][index]; + b = ((temp << s) | (temp >>> (32 - s))) + a; + temp = A + (B ^ C ^ D) + X[RIPEMD160.IndexArray[1][index]]; + A = E; + E = D; + D = (C << 10) | (C >>> 22); + C = B; + s = RIPEMD160.ArgArray[1][index]; + B = ((temp << s) | (temp >>> (32 - s))) + A; + } + D += c + this.MDbuf[1]; + this.MDbuf[1] = this.MDbuf[2] + d + E; + this.MDbuf[2] = this.MDbuf[3] + e + A; + this.MDbuf[3] = this.MDbuf[4] + a + B; + this.MDbuf[4] = this.MDbuf[0] + b + C; + this.MDbuf[0] = D; + }; + RIPEMD160.prototype.MDfinish = function (array, lswlen, mswlen) { + var X = array; + X[(lswlen >> 2) & 15] ^= 1 << (((lswlen & 3) << 3) + 7); + if (((lswlen & 63) > 55)) { + this.compress(X); + for (var i = 0; i < 14; i++) { + X[i] = 0; + } + } + X[14] = lswlen << 3; + X[15] = (lswlen >> 29) | (mswlen << 3); + this.compress(X); + }; + RIPEMD160.prototype.update = function (input) { + for (var i = 0; i < input.length; i++) { + this.working[this.working_ptr >> 2] ^= input[i] << ((this.working_ptr & 3) << 3); + this.working_ptr++; + if ((this.working_ptr == 64)) { + this.compress(this.working); + for (var j = 0; j < 16; j++) { + this.working[j] = 0; + } + this.working_ptr = 0; + } + } + this.msglen += input.length; + }; + RIPEMD160.prototype.digestBin = function () { + this.MDfinish(this.working, this.msglen, 0); + //var res = new Int8Array(); + var res = []; + for (var i = 0; i < 20; i++) { + res[i] = ((this.MDbuf[i >> 2] >>> ((i & 3) << 3)) & 255); + } + return new Uint8Array(res); + }; + RIPEMD160.prototype.digest = function (input) { + this.update(new Int8Array(input)); + return this.digestBin(); + }; + RIPEMD160.ArgArray = [[11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8, 7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12, 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5, 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12, 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6], [8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6, 9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11, 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5, 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8, 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11]]; + RIPEMD160.IndexArray = [[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8, 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12, 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2, 4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13], [5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12, 6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2, 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13, 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14, 12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11]]; + return RIPEMD160; })(); export default RIPEMD160 diff --git a/crypto/api/deps/deps.js b/crypto/api/deps/deps.js index 48eb8130..331f6ad0 100644 --- a/crypto/api/deps/deps.js +++ b/crypto/api/deps/deps.js @@ -1,3 +1,2 @@ -export { default as Base58 } from './Base58.js' - -export { default as utils } from './utils.js' +export { default as Base58 } from './Base58' +export { default as utils } from './utils' diff --git a/crypto/api/deps/ed2curve.js b/crypto/api/deps/ed2curve.js index e7ede3d0..1fcabdea 100644 --- a/crypto/api/deps/ed2curve.js +++ b/crypto/api/deps/ed2curve.js @@ -10,255 +10,239 @@ Change to es6 import/export */ -import nacl from './nacl-fast.js' +import nacl from './nacl-fast' -// (function(root, f) { -// 'use strict'; -// if (typeof module !== 'undefined' && module.exports) module.exports = f(require('tweetnacl')); -// else root.ed2curve = f(root.nacl); -// }(this, function(nacl) { -// 'use strict'; -// if (!nacl) throw new Error('tweetnacl not loaded'); +// -- Operations copied from TweetNaCl.js. -- - // -- Operations copied from TweetNaCl.js. -- +var gf = function (init) { + var i, r = new Float64Array(16); + if (init) for (i = 0; i < init.length; i++) r[i] = init[i]; + return r; +}; - var gf = function(init) { - var i, r = new Float64Array(16); - if (init) for (i = 0; i < init.length; i++) r[i] = init[i]; - return r; - }; +var gf0 = gf(), + gf1 = gf([1]), + D = gf([0x78a3, 0x1359, 0x4dca, 0x75eb, 0xd8ab, 0x4141, 0x0a4d, 0x0070, 0xe898, 0x7779, 0x4079, 0x8cc7, 0xfe73, 0x2b6f, 0x6cee, 0x5203]), + I = gf([0xa0b0, 0x4a0e, 0x1b27, 0xc4ee, 0xe478, 0xad2f, 0x1806, 0x2f43, 0xd7a7, 0x3dfb, 0x0099, 0x2b4d, 0xdf0b, 0x4fc1, 0x2480, 0x2b83]); - var gf0 = gf(), - gf1 = gf([1]), - D = gf([0x78a3, 0x1359, 0x4dca, 0x75eb, 0xd8ab, 0x4141, 0x0a4d, 0x0070, 0xe898, 0x7779, 0x4079, 0x8cc7, 0xfe73, 0x2b6f, 0x6cee, 0x5203]), - I = gf([0xa0b0, 0x4a0e, 0x1b27, 0xc4ee, 0xe478, 0xad2f, 0x1806, 0x2f43, 0xd7a7, 0x3dfb, 0x0099, 0x2b4d, 0xdf0b, 0x4fc1, 0x2480, 0x2b83]); - - function car25519(o) { - var c; - var i; - for (i = 0; i < 16; i++) { - o[i] += 65536; - c = Math.floor(o[i] / 65536); - o[(i+1)*(i<15?1:0)] += c - 1 + 37 * (c-1) * (i===15?1:0); - o[i] -= (c * 65536); - } - } - - function sel25519(p, q, b) { - var t, c = ~(b-1); - for (var i = 0; i < 16; i++) { - t = c & (p[i] ^ q[i]); - p[i] ^= t; - q[i] ^= t; - } - } - - function unpack25519(o, n) { - var i; - for (i = 0; i < 16; i++) o[i] = n[2*i] + (n[2*i+1] << 8); - o[15] &= 0x7fff; - } - - // addition - function A(o, a, b) { - var i; - for (i = 0; i < 16; i++) o[i] = (a[i] + b[i])|0; - } - - // subtraction - function Z(o, a, b) { - var i; - for (i = 0; i < 16; i++) o[i] = (a[i] - b[i])|0; - } - - // multiplication - function M(o, a, b) { - var i, j, t = new Float64Array(31); - for (i = 0; i < 31; i++) t[i] = 0; - for (i = 0; i < 16; i++) { - for (j = 0; j < 16; j++) { - t[i+j] += a[i] * b[j]; - } - } - for (i = 0; i < 15; i++) { - t[i] += 38 * t[i+16]; - } - for (i = 0; i < 16; i++) o[i] = t[i]; - car25519(o); - car25519(o); - } - - // squaring - function S(o, a) { - M(o, a, a); - } - - // inversion - function inv25519(o, i) { - var c = gf(); - var a; - for (a = 0; a < 16; a++) c[a] = i[a]; - for (a = 253; a >= 0; a--) { - S(c, c); - if(a !== 2 && a !== 4) M(c, c, i); - } - for (a = 0; a < 16; a++) o[a] = c[a]; - } - - function pack25519(o, n) { - var i, j, b; - var m = gf(), t = gf(); - for (i = 0; i < 16; i++) t[i] = n[i]; - car25519(t); - car25519(t); - car25519(t); - for (j = 0; j < 2; j++) { - m[0] = t[0] - 0xffed; - for (i = 1; i < 15; i++) { - m[i] = t[i] - 0xffff - ((m[i-1]>>16) & 1); - m[i-1] &= 0xffff; - } - m[15] = t[15] - 0x7fff - ((m[14]>>16) & 1); - b = (m[15]>>16) & 1; - m[14] &= 0xffff; - sel25519(t, m, 1-b); - } - for (i = 0; i < 16; i++) { - o[2*i] = t[i] & 0xff; - o[2*i+1] = t[i] >> 8; - } - } - - function par25519(a) { - var d = new Uint8Array(32); - pack25519(d, a); - return d[0] & 1; - } - - function vn(x, xi, y, yi, n) { - var i, d = 0; - for (i = 0; i < n; i++) d |= x[xi + i] ^ y[yi + i]; - return (1 & ((d - 1) >>> 8)) - 1; - } - - function crypto_verify_32(x, xi, y, yi) { - return vn(x, xi, y, yi, 32); - } - - function neq25519(a, b) { - var c = new Uint8Array(32), d = new Uint8Array(32); - pack25519(c, a); - pack25519(d, b); - return crypto_verify_32(c, 0, d, 0); - } - - function pow2523(o, i) { - var c = gf(); - var a; - for (a = 0; a < 16; a++) c[a] = i[a]; - for (a = 250; a >= 0; a--) { - S(c, c); - if (a !== 1) M(c, c, i); - } - for (a = 0; a < 16; a++) o[a] = c[a]; - } - - function set25519(r, a) { - var i; - for (i = 0; i < 16; i++) r[i] = a[i] | 0; - } - - function unpackneg(r, p) { - var t = gf(), chk = gf(), num = gf(), - den = gf(), den2 = gf(), den4 = gf(), - den6 = gf(); - - set25519(r[2], gf1); - unpack25519(r[1], p); - S(num, r[1]); - M(den, num, D); - Z(num, num, r[2]); - A(den, r[2], den); - - S(den2, den); - S(den4, den2); - M(den6, den4, den2); - M(t, den6, num); - M(t, t, den); - - pow2523(t, t); - M(t, t, num); - M(t, t, den); - M(t, t, den); - M(r[0], t, den); - - S(chk, r[0]); - M(chk, chk, den); - if (neq25519(chk, num)) M(r[0], r[0], I); - - S(chk, r[0]); - M(chk, chk, den); - if (neq25519(chk, num)) return -1; - - if (par25519(r[0]) === (p[31] >> 7)) Z(r[0], gf0, r[0]); - - M(r[3], r[0], r[1]); - return 0; - } - - // ---- - - // Converts Ed25519 public key to Curve25519 public key. - // montgomeryX = (edwardsY + 1)*inverse(1 - edwardsY) mod p - function convertPublicKey(pk) { - var z = new Uint8Array(32), - q = [gf(), gf(), gf(), gf()], - a = gf(), b = gf(); - - if (unpackneg(q, pk)) return null; // reject invalid key - - var y = q[1]; - - A(a, gf1, y); - Z(b, gf1, y); - inv25519(b, b); - M(a, a, b); - - pack25519(z, a); - return z; - } - - // Converts Ed25519 secret key to Curve25519 secret key. - function convertSecretKey(sk) { - var d = new Uint8Array(64), o = new Uint8Array(32), i; - nacl.lowlevel.crypto_hash(d, sk, 32); - d[0] &= 248; - d[31] &= 127; - d[31] |= 64; - for (i = 0; i < 32; i++) o[i] = d[i]; - for (i = 0; i < 64; i++) d[i] = 0; - return o; - } - - function convertKeyPair(edKeyPair) { - var publicKey = convertPublicKey(edKeyPair.publicKey); - if (!publicKey) return null; - return { - publicKey: publicKey, - secretKey: convertSecretKey(edKeyPair.secretKey) - }; - } - -// return { -// convertPublicKey: convertPublicKey, -// convertSecretKey: convertSecretKey, -// convertKeyPair: convertKeyPair, -// }; - -export default { - convertPublicKey: convertPublicKey, - convertSecretKey: convertSecretKey, - convertKeyPair: convertKeyPair, +function car25519(o) { + var c; + var i; + for (i = 0; i < 16; i++) { + o[i] += 65536; + c = Math.floor(o[i] / 65536); + o[(i + 1) * (i < 15 ? 1 : 0)] += c - 1 + 37 * (c - 1) * (i === 15 ? 1 : 0); + o[i] -= (c * 65536); + } } -// })); +function sel25519(p, q, b) { + var t, c = ~(b - 1); + for (var i = 0; i < 16; i++) { + t = c & (p[i] ^ q[i]); + p[i] ^= t; + q[i] ^= t; + } +} + +function unpack25519(o, n) { + var i; + for (i = 0; i < 16; i++) o[i] = n[2 * i] + (n[2 * i + 1] << 8); + o[15] &= 0x7fff; +} + +// addition +function A(o, a, b) { + var i; + for (i = 0; i < 16; i++) o[i] = (a[i] + b[i]) | 0; +} + +// subtraction +function Z(o, a, b) { + var i; + for (i = 0; i < 16; i++) o[i] = (a[i] - b[i]) | 0; +} + +// multiplication +function M(o, a, b) { + var i, j, t = new Float64Array(31); + for (i = 0; i < 31; i++) t[i] = 0; + for (i = 0; i < 16; i++) { + for (j = 0; j < 16; j++) { + t[i + j] += a[i] * b[j]; + } + } + for (i = 0; i < 15; i++) { + t[i] += 38 * t[i + 16]; + } + for (i = 0; i < 16; i++) o[i] = t[i]; + car25519(o); + car25519(o); +} + +// squaring +function S(o, a) { + M(o, a, a); +} + +// inversion +function inv25519(o, i) { + var c = gf(); + var a; + for (a = 0; a < 16; a++) c[a] = i[a]; + for (a = 253; a >= 0; a--) { + S(c, c); + if (a !== 2 && a !== 4) M(c, c, i); + } + for (a = 0; a < 16; a++) o[a] = c[a]; +} + +function pack25519(o, n) { + var i, j, b; + var m = gf(), t = gf(); + for (i = 0; i < 16; i++) t[i] = n[i]; + car25519(t); + car25519(t); + car25519(t); + for (j = 0; j < 2; j++) { + m[0] = t[0] - 0xffed; + for (i = 1; i < 15; i++) { + m[i] = t[i] - 0xffff - ((m[i - 1] >> 16) & 1); + m[i - 1] &= 0xffff; + } + m[15] = t[15] - 0x7fff - ((m[14] >> 16) & 1); + b = (m[15] >> 16) & 1; + m[14] &= 0xffff; + sel25519(t, m, 1 - b); + } + for (i = 0; i < 16; i++) { + o[2 * i] = t[i] & 0xff; + o[2 * i + 1] = t[i] >> 8; + } +} + +function par25519(a) { + var d = new Uint8Array(32); + pack25519(d, a); + return d[0] & 1; +} + +function vn(x, xi, y, yi, n) { + var i, d = 0; + for (i = 0; i < n; i++) d |= x[xi + i] ^ y[yi + i]; + return (1 & ((d - 1) >>> 8)) - 1; +} + +function crypto_verify_32(x, xi, y, yi) { + return vn(x, xi, y, yi, 32); +} + +function neq25519(a, b) { + var c = new Uint8Array(32), d = new Uint8Array(32); + pack25519(c, a); + pack25519(d, b); + return crypto_verify_32(c, 0, d, 0); +} + +function pow2523(o, i) { + var c = gf(); + var a; + for (a = 0; a < 16; a++) c[a] = i[a]; + for (a = 250; a >= 0; a--) { + S(c, c); + if (a !== 1) M(c, c, i); + } + for (a = 0; a < 16; a++) o[a] = c[a]; +} + +function set25519(r, a) { + var i; + for (i = 0; i < 16; i++) r[i] = a[i] | 0; +} + +function unpackneg(r, p) { + var t = gf(), chk = gf(), num = gf(), + den = gf(), den2 = gf(), den4 = gf(), + den6 = gf(); + + set25519(r[2], gf1); + unpack25519(r[1], p); + S(num, r[1]); + M(den, num, D); + Z(num, num, r[2]); + A(den, r[2], den); + + S(den2, den); + S(den4, den2); + M(den6, den4, den2); + M(t, den6, num); + M(t, t, den); + + pow2523(t, t); + M(t, t, num); + M(t, t, den); + M(t, t, den); + M(r[0], t, den); + + S(chk, r[0]); + M(chk, chk, den); + if (neq25519(chk, num)) M(r[0], r[0], I); + + S(chk, r[0]); + M(chk, chk, den); + if (neq25519(chk, num)) return -1; + + if (par25519(r[0]) === (p[31] >> 7)) Z(r[0], gf0, r[0]); + + M(r[3], r[0], r[1]); + return 0; +} + +// ---- + +// Converts Ed25519 public key to Curve25519 public key. +// montgomeryX = (edwardsY + 1)*inverse(1 - edwardsY) mod p +function convertPublicKey(pk) { + var z = new Uint8Array(32), + q = [gf(), gf(), gf(), gf()], + a = gf(), b = gf(); + + if (unpackneg(q, pk)) return null; // reject invalid key + + var y = q[1]; + + A(a, gf1, y); + Z(b, gf1, y); + inv25519(b, b); + M(a, a, b); + + pack25519(z, a); + return z; +} + +// Converts Ed25519 secret key to Curve25519 secret key. +function convertSecretKey(sk) { + var d = new Uint8Array(64), o = new Uint8Array(32), i; + nacl.lowlevel.crypto_hash(d, sk, 32); + d[0] &= 248; + d[31] &= 127; + d[31] |= 64; + for (i = 0; i < 32; i++) o[i] = d[i]; + for (i = 0; i < 64; i++) d[i] = 0; + return o; +} + +function convertKeyPair(edKeyPair) { + var publicKey = convertPublicKey(edKeyPair.publicKey); + if (!publicKey) return null; + return { + publicKey: publicKey, + secretKey: convertSecretKey(edKeyPair.secretKey) + }; +} + +export default { + convertPublicKey: convertPublicKey, + convertSecretKey: convertSecretKey, + convertKeyPair: convertKeyPair, +} diff --git a/crypto/api/deps/nacl-fast.js b/crypto/api/deps/nacl-fast.js index b2fd186f..6693543b 100644 --- a/crypto/api/deps/nacl-fast.js +++ b/crypto/api/deps/nacl-fast.js @@ -1,7 +1,5 @@ // == CHANGE TO ES6 EXPORT == // const nacl = {} -//(function(nacl) { -'use strict'; // Ported in 2014 by Dmitry Chestnykh and Devi Mandiri. // Public domain. @@ -9,456 +7,456 @@ const nacl = {} // Implementation derived from TweetNaCl version 20140427. // See for details: http://tweetnacl.cr.yp.to/ -var gf = function(init) { - var i, r = new Float64Array(16); - if (init) for (i = 0; i < init.length; i++) r[i] = init[i]; - return r; +var gf = function (init) { + var i, r = new Float64Array(16); + if (init) for (i = 0; i < init.length; i++) r[i] = init[i]; + return r; }; // Pluggable, initialized in high-level API below. -var randombytes = function(/* x, n */) { throw new Error('no PRNG'); }; +var randombytes = function (/* x, n */) { throw new Error('no PRNG'); }; var _0 = new Uint8Array(16); var _9 = new Uint8Array(32); _9[0] = 9; var gf0 = gf(), - gf1 = gf([1]), - _121665 = gf([0xdb41, 1]), - D = gf([0x78a3, 0x1359, 0x4dca, 0x75eb, 0xd8ab, 0x4141, 0x0a4d, 0x0070, 0xe898, 0x7779, 0x4079, 0x8cc7, 0xfe73, 0x2b6f, 0x6cee, 0x5203]), - D2 = gf([0xf159, 0x26b2, 0x9b94, 0xebd6, 0xb156, 0x8283, 0x149a, 0x00e0, 0xd130, 0xeef3, 0x80f2, 0x198e, 0xfce7, 0x56df, 0xd9dc, 0x2406]), - X = gf([0xd51a, 0x8f25, 0x2d60, 0xc956, 0xa7b2, 0x9525, 0xc760, 0x692c, 0xdc5c, 0xfdd6, 0xe231, 0xc0a4, 0x53fe, 0xcd6e, 0x36d3, 0x2169]), - Y = gf([0x6658, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666]), - I = gf([0xa0b0, 0x4a0e, 0x1b27, 0xc4ee, 0xe478, 0xad2f, 0x1806, 0x2f43, 0xd7a7, 0x3dfb, 0x0099, 0x2b4d, 0xdf0b, 0x4fc1, 0x2480, 0x2b83]); + gf1 = gf([1]), + _121665 = gf([0xdb41, 1]), + D = gf([0x78a3, 0x1359, 0x4dca, 0x75eb, 0xd8ab, 0x4141, 0x0a4d, 0x0070, 0xe898, 0x7779, 0x4079, 0x8cc7, 0xfe73, 0x2b6f, 0x6cee, 0x5203]), + D2 = gf([0xf159, 0x26b2, 0x9b94, 0xebd6, 0xb156, 0x8283, 0x149a, 0x00e0, 0xd130, 0xeef3, 0x80f2, 0x198e, 0xfce7, 0x56df, 0xd9dc, 0x2406]), + X = gf([0xd51a, 0x8f25, 0x2d60, 0xc956, 0xa7b2, 0x9525, 0xc760, 0x692c, 0xdc5c, 0xfdd6, 0xe231, 0xc0a4, 0x53fe, 0xcd6e, 0x36d3, 0x2169]), + Y = gf([0x6658, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666]), + I = gf([0xa0b0, 0x4a0e, 0x1b27, 0xc4ee, 0xe478, 0xad2f, 0x1806, 0x2f43, 0xd7a7, 0x3dfb, 0x0099, 0x2b4d, 0xdf0b, 0x4fc1, 0x2480, 0x2b83]); function ts64(x, i, h, l) { - x[i] = (h >> 24) & 0xff; - x[i+1] = (h >> 16) & 0xff; - x[i+2] = (h >> 8) & 0xff; - x[i+3] = h & 0xff; - x[i+4] = (l >> 24) & 0xff; - x[i+5] = (l >> 16) & 0xff; - x[i+6] = (l >> 8) & 0xff; - x[i+7] = l & 0xff; + x[i] = (h >> 24) & 0xff; + x[i + 1] = (h >> 16) & 0xff; + x[i + 2] = (h >> 8) & 0xff; + x[i + 3] = h & 0xff; + x[i + 4] = (l >> 24) & 0xff; + x[i + 5] = (l >> 16) & 0xff; + x[i + 6] = (l >> 8) & 0xff; + x[i + 7] = l & 0xff; } function vn(x, xi, y, yi, n) { - var i,d = 0; - for (i = 0; i < n; i++) d |= x[xi+i]^y[yi+i]; - return (1 & ((d - 1) >>> 8)) - 1; + var i, d = 0; + for (i = 0; i < n; i++) d |= x[xi + i] ^ y[yi + i]; + return (1 & ((d - 1) >>> 8)) - 1; } function crypto_verify_16(x, xi, y, yi) { - return vn(x,xi,y,yi,16); + return vn(x, xi, y, yi, 16); } function crypto_verify_32(x, xi, y, yi) { - return vn(x,xi,y,yi,32); + return vn(x, xi, y, yi, 32); } function core_salsa20(o, p, k, c) { - var j0 = c[ 0] & 0xff | (c[ 1] & 0xff)<<8 | (c[ 2] & 0xff)<<16 | (c[ 3] & 0xff)<<24, - j1 = k[ 0] & 0xff | (k[ 1] & 0xff)<<8 | (k[ 2] & 0xff)<<16 | (k[ 3] & 0xff)<<24, - j2 = k[ 4] & 0xff | (k[ 5] & 0xff)<<8 | (k[ 6] & 0xff)<<16 | (k[ 7] & 0xff)<<24, - j3 = k[ 8] & 0xff | (k[ 9] & 0xff)<<8 | (k[10] & 0xff)<<16 | (k[11] & 0xff)<<24, - j4 = k[12] & 0xff | (k[13] & 0xff)<<8 | (k[14] & 0xff)<<16 | (k[15] & 0xff)<<24, - j5 = c[ 4] & 0xff | (c[ 5] & 0xff)<<8 | (c[ 6] & 0xff)<<16 | (c[ 7] & 0xff)<<24, - j6 = p[ 0] & 0xff | (p[ 1] & 0xff)<<8 | (p[ 2] & 0xff)<<16 | (p[ 3] & 0xff)<<24, - j7 = p[ 4] & 0xff | (p[ 5] & 0xff)<<8 | (p[ 6] & 0xff)<<16 | (p[ 7] & 0xff)<<24, - j8 = p[ 8] & 0xff | (p[ 9] & 0xff)<<8 | (p[10] & 0xff)<<16 | (p[11] & 0xff)<<24, - j9 = p[12] & 0xff | (p[13] & 0xff)<<8 | (p[14] & 0xff)<<16 | (p[15] & 0xff)<<24, - j10 = c[ 8] & 0xff | (c[ 9] & 0xff)<<8 | (c[10] & 0xff)<<16 | (c[11] & 0xff)<<24, - j11 = k[16] & 0xff | (k[17] & 0xff)<<8 | (k[18] & 0xff)<<16 | (k[19] & 0xff)<<24, - j12 = k[20] & 0xff | (k[21] & 0xff)<<8 | (k[22] & 0xff)<<16 | (k[23] & 0xff)<<24, - j13 = k[24] & 0xff | (k[25] & 0xff)<<8 | (k[26] & 0xff)<<16 | (k[27] & 0xff)<<24, - j14 = k[28] & 0xff | (k[29] & 0xff)<<8 | (k[30] & 0xff)<<16 | (k[31] & 0xff)<<24, - j15 = c[12] & 0xff | (c[13] & 0xff)<<8 | (c[14] & 0xff)<<16 | (c[15] & 0xff)<<24; + var j0 = c[0] & 0xff | (c[1] & 0xff) << 8 | (c[2] & 0xff) << 16 | (c[3] & 0xff) << 24, + j1 = k[0] & 0xff | (k[1] & 0xff) << 8 | (k[2] & 0xff) << 16 | (k[3] & 0xff) << 24, + j2 = k[4] & 0xff | (k[5] & 0xff) << 8 | (k[6] & 0xff) << 16 | (k[7] & 0xff) << 24, + j3 = k[8] & 0xff | (k[9] & 0xff) << 8 | (k[10] & 0xff) << 16 | (k[11] & 0xff) << 24, + j4 = k[12] & 0xff | (k[13] & 0xff) << 8 | (k[14] & 0xff) << 16 | (k[15] & 0xff) << 24, + j5 = c[4] & 0xff | (c[5] & 0xff) << 8 | (c[6] & 0xff) << 16 | (c[7] & 0xff) << 24, + j6 = p[0] & 0xff | (p[1] & 0xff) << 8 | (p[2] & 0xff) << 16 | (p[3] & 0xff) << 24, + j7 = p[4] & 0xff | (p[5] & 0xff) << 8 | (p[6] & 0xff) << 16 | (p[7] & 0xff) << 24, + j8 = p[8] & 0xff | (p[9] & 0xff) << 8 | (p[10] & 0xff) << 16 | (p[11] & 0xff) << 24, + j9 = p[12] & 0xff | (p[13] & 0xff) << 8 | (p[14] & 0xff) << 16 | (p[15] & 0xff) << 24, + j10 = c[8] & 0xff | (c[9] & 0xff) << 8 | (c[10] & 0xff) << 16 | (c[11] & 0xff) << 24, + j11 = k[16] & 0xff | (k[17] & 0xff) << 8 | (k[18] & 0xff) << 16 | (k[19] & 0xff) << 24, + j12 = k[20] & 0xff | (k[21] & 0xff) << 8 | (k[22] & 0xff) << 16 | (k[23] & 0xff) << 24, + j13 = k[24] & 0xff | (k[25] & 0xff) << 8 | (k[26] & 0xff) << 16 | (k[27] & 0xff) << 24, + j14 = k[28] & 0xff | (k[29] & 0xff) << 8 | (k[30] & 0xff) << 16 | (k[31] & 0xff) << 24, + j15 = c[12] & 0xff | (c[13] & 0xff) << 8 | (c[14] & 0xff) << 16 | (c[15] & 0xff) << 24; - var x0 = j0, x1 = j1, x2 = j2, x3 = j3, x4 = j4, x5 = j5, x6 = j6, x7 = j7, - x8 = j8, x9 = j9, x10 = j10, x11 = j11, x12 = j12, x13 = j13, x14 = j14, - x15 = j15, u; + var x0 = j0, x1 = j1, x2 = j2, x3 = j3, x4 = j4, x5 = j5, x6 = j6, x7 = j7, + x8 = j8, x9 = j9, x10 = j10, x11 = j11, x12 = j12, x13 = j13, x14 = j14, + x15 = j15, u; - for (var i = 0; i < 20; i += 2) { - u = x0 + x12 | 0; - x4 ^= u<<7 | u>>>(32-7); - u = x4 + x0 | 0; - x8 ^= u<<9 | u>>>(32-9); - u = x8 + x4 | 0; - x12 ^= u<<13 | u>>>(32-13); - u = x12 + x8 | 0; - x0 ^= u<<18 | u>>>(32-18); + for (var i = 0; i < 20; i += 2) { + u = x0 + x12 | 0; + x4 ^= u << 7 | u >>> (32 - 7); + u = x4 + x0 | 0; + x8 ^= u << 9 | u >>> (32 - 9); + u = x8 + x4 | 0; + x12 ^= u << 13 | u >>> (32 - 13); + u = x12 + x8 | 0; + x0 ^= u << 18 | u >>> (32 - 18); - u = x5 + x1 | 0; - x9 ^= u<<7 | u>>>(32-7); - u = x9 + x5 | 0; - x13 ^= u<<9 | u>>>(32-9); - u = x13 + x9 | 0; - x1 ^= u<<13 | u>>>(32-13); - u = x1 + x13 | 0; - x5 ^= u<<18 | u>>>(32-18); + u = x5 + x1 | 0; + x9 ^= u << 7 | u >>> (32 - 7); + u = x9 + x5 | 0; + x13 ^= u << 9 | u >>> (32 - 9); + u = x13 + x9 | 0; + x1 ^= u << 13 | u >>> (32 - 13); + u = x1 + x13 | 0; + x5 ^= u << 18 | u >>> (32 - 18); - u = x10 + x6 | 0; - x14 ^= u<<7 | u>>>(32-7); - u = x14 + x10 | 0; - x2 ^= u<<9 | u>>>(32-9); - u = x2 + x14 | 0; - x6 ^= u<<13 | u>>>(32-13); - u = x6 + x2 | 0; - x10 ^= u<<18 | u>>>(32-18); + u = x10 + x6 | 0; + x14 ^= u << 7 | u >>> (32 - 7); + u = x14 + x10 | 0; + x2 ^= u << 9 | u >>> (32 - 9); + u = x2 + x14 | 0; + x6 ^= u << 13 | u >>> (32 - 13); + u = x6 + x2 | 0; + x10 ^= u << 18 | u >>> (32 - 18); - u = x15 + x11 | 0; - x3 ^= u<<7 | u>>>(32-7); - u = x3 + x15 | 0; - x7 ^= u<<9 | u>>>(32-9); - u = x7 + x3 | 0; - x11 ^= u<<13 | u>>>(32-13); - u = x11 + x7 | 0; - x15 ^= u<<18 | u>>>(32-18); + u = x15 + x11 | 0; + x3 ^= u << 7 | u >>> (32 - 7); + u = x3 + x15 | 0; + x7 ^= u << 9 | u >>> (32 - 9); + u = x7 + x3 | 0; + x11 ^= u << 13 | u >>> (32 - 13); + u = x11 + x7 | 0; + x15 ^= u << 18 | u >>> (32 - 18); - u = x0 + x3 | 0; - x1 ^= u<<7 | u>>>(32-7); - u = x1 + x0 | 0; - x2 ^= u<<9 | u>>>(32-9); - u = x2 + x1 | 0; - x3 ^= u<<13 | u>>>(32-13); - u = x3 + x2 | 0; - x0 ^= u<<18 | u>>>(32-18); + u = x0 + x3 | 0; + x1 ^= u << 7 | u >>> (32 - 7); + u = x1 + x0 | 0; + x2 ^= u << 9 | u >>> (32 - 9); + u = x2 + x1 | 0; + x3 ^= u << 13 | u >>> (32 - 13); + u = x3 + x2 | 0; + x0 ^= u << 18 | u >>> (32 - 18); - u = x5 + x4 | 0; - x6 ^= u<<7 | u>>>(32-7); - u = x6 + x5 | 0; - x7 ^= u<<9 | u>>>(32-9); - u = x7 + x6 | 0; - x4 ^= u<<13 | u>>>(32-13); - u = x4 + x7 | 0; - x5 ^= u<<18 | u>>>(32-18); + u = x5 + x4 | 0; + x6 ^= u << 7 | u >>> (32 - 7); + u = x6 + x5 | 0; + x7 ^= u << 9 | u >>> (32 - 9); + u = x7 + x6 | 0; + x4 ^= u << 13 | u >>> (32 - 13); + u = x4 + x7 | 0; + x5 ^= u << 18 | u >>> (32 - 18); - u = x10 + x9 | 0; - x11 ^= u<<7 | u>>>(32-7); - u = x11 + x10 | 0; - x8 ^= u<<9 | u>>>(32-9); - u = x8 + x11 | 0; - x9 ^= u<<13 | u>>>(32-13); - u = x9 + x8 | 0; - x10 ^= u<<18 | u>>>(32-18); + u = x10 + x9 | 0; + x11 ^= u << 7 | u >>> (32 - 7); + u = x11 + x10 | 0; + x8 ^= u << 9 | u >>> (32 - 9); + u = x8 + x11 | 0; + x9 ^= u << 13 | u >>> (32 - 13); + u = x9 + x8 | 0; + x10 ^= u << 18 | u >>> (32 - 18); - u = x15 + x14 | 0; - x12 ^= u<<7 | u>>>(32-7); - u = x12 + x15 | 0; - x13 ^= u<<9 | u>>>(32-9); - u = x13 + x12 | 0; - x14 ^= u<<13 | u>>>(32-13); - u = x14 + x13 | 0; - x15 ^= u<<18 | u>>>(32-18); - } - x0 = x0 + j0 | 0; - x1 = x1 + j1 | 0; - x2 = x2 + j2 | 0; - x3 = x3 + j3 | 0; - x4 = x4 + j4 | 0; - x5 = x5 + j5 | 0; - x6 = x6 + j6 | 0; - x7 = x7 + j7 | 0; - x8 = x8 + j8 | 0; - x9 = x9 + j9 | 0; - x10 = x10 + j10 | 0; - x11 = x11 + j11 | 0; - x12 = x12 + j12 | 0; - x13 = x13 + j13 | 0; - x14 = x14 + j14 | 0; - x15 = x15 + j15 | 0; + u = x15 + x14 | 0; + x12 ^= u << 7 | u >>> (32 - 7); + u = x12 + x15 | 0; + x13 ^= u << 9 | u >>> (32 - 9); + u = x13 + x12 | 0; + x14 ^= u << 13 | u >>> (32 - 13); + u = x14 + x13 | 0; + x15 ^= u << 18 | u >>> (32 - 18); + } + x0 = x0 + j0 | 0; + x1 = x1 + j1 | 0; + x2 = x2 + j2 | 0; + x3 = x3 + j3 | 0; + x4 = x4 + j4 | 0; + x5 = x5 + j5 | 0; + x6 = x6 + j6 | 0; + x7 = x7 + j7 | 0; + x8 = x8 + j8 | 0; + x9 = x9 + j9 | 0; + x10 = x10 + j10 | 0; + x11 = x11 + j11 | 0; + x12 = x12 + j12 | 0; + x13 = x13 + j13 | 0; + x14 = x14 + j14 | 0; + x15 = x15 + j15 | 0; - o[ 0] = x0 >>> 0 & 0xff; - o[ 1] = x0 >>> 8 & 0xff; - o[ 2] = x0 >>> 16 & 0xff; - o[ 3] = x0 >>> 24 & 0xff; + o[0] = x0 >>> 0 & 0xff; + o[1] = x0 >>> 8 & 0xff; + o[2] = x0 >>> 16 & 0xff; + o[3] = x0 >>> 24 & 0xff; - o[ 4] = x1 >>> 0 & 0xff; - o[ 5] = x1 >>> 8 & 0xff; - o[ 6] = x1 >>> 16 & 0xff; - o[ 7] = x1 >>> 24 & 0xff; + o[4] = x1 >>> 0 & 0xff; + o[5] = x1 >>> 8 & 0xff; + o[6] = x1 >>> 16 & 0xff; + o[7] = x1 >>> 24 & 0xff; - o[ 8] = x2 >>> 0 & 0xff; - o[ 9] = x2 >>> 8 & 0xff; - o[10] = x2 >>> 16 & 0xff; - o[11] = x2 >>> 24 & 0xff; + o[8] = x2 >>> 0 & 0xff; + o[9] = x2 >>> 8 & 0xff; + o[10] = x2 >>> 16 & 0xff; + o[11] = x2 >>> 24 & 0xff; - o[12] = x3 >>> 0 & 0xff; - o[13] = x3 >>> 8 & 0xff; - o[14] = x3 >>> 16 & 0xff; - o[15] = x3 >>> 24 & 0xff; + o[12] = x3 >>> 0 & 0xff; + o[13] = x3 >>> 8 & 0xff; + o[14] = x3 >>> 16 & 0xff; + o[15] = x3 >>> 24 & 0xff; - o[16] = x4 >>> 0 & 0xff; - o[17] = x4 >>> 8 & 0xff; - o[18] = x4 >>> 16 & 0xff; - o[19] = x4 >>> 24 & 0xff; + o[16] = x4 >>> 0 & 0xff; + o[17] = x4 >>> 8 & 0xff; + o[18] = x4 >>> 16 & 0xff; + o[19] = x4 >>> 24 & 0xff; - o[20] = x5 >>> 0 & 0xff; - o[21] = x5 >>> 8 & 0xff; - o[22] = x5 >>> 16 & 0xff; - o[23] = x5 >>> 24 & 0xff; + o[20] = x5 >>> 0 & 0xff; + o[21] = x5 >>> 8 & 0xff; + o[22] = x5 >>> 16 & 0xff; + o[23] = x5 >>> 24 & 0xff; - o[24] = x6 >>> 0 & 0xff; - o[25] = x6 >>> 8 & 0xff; - o[26] = x6 >>> 16 & 0xff; - o[27] = x6 >>> 24 & 0xff; + o[24] = x6 >>> 0 & 0xff; + o[25] = x6 >>> 8 & 0xff; + o[26] = x6 >>> 16 & 0xff; + o[27] = x6 >>> 24 & 0xff; - o[28] = x7 >>> 0 & 0xff; - o[29] = x7 >>> 8 & 0xff; - o[30] = x7 >>> 16 & 0xff; - o[31] = x7 >>> 24 & 0xff; + o[28] = x7 >>> 0 & 0xff; + o[29] = x7 >>> 8 & 0xff; + o[30] = x7 >>> 16 & 0xff; + o[31] = x7 >>> 24 & 0xff; - o[32] = x8 >>> 0 & 0xff; - o[33] = x8 >>> 8 & 0xff; - o[34] = x8 >>> 16 & 0xff; - o[35] = x8 >>> 24 & 0xff; + o[32] = x8 >>> 0 & 0xff; + o[33] = x8 >>> 8 & 0xff; + o[34] = x8 >>> 16 & 0xff; + o[35] = x8 >>> 24 & 0xff; - o[36] = x9 >>> 0 & 0xff; - o[37] = x9 >>> 8 & 0xff; - o[38] = x9 >>> 16 & 0xff; - o[39] = x9 >>> 24 & 0xff; + o[36] = x9 >>> 0 & 0xff; + o[37] = x9 >>> 8 & 0xff; + o[38] = x9 >>> 16 & 0xff; + o[39] = x9 >>> 24 & 0xff; - o[40] = x10 >>> 0 & 0xff; - o[41] = x10 >>> 8 & 0xff; - o[42] = x10 >>> 16 & 0xff; - o[43] = x10 >>> 24 & 0xff; + o[40] = x10 >>> 0 & 0xff; + o[41] = x10 >>> 8 & 0xff; + o[42] = x10 >>> 16 & 0xff; + o[43] = x10 >>> 24 & 0xff; - o[44] = x11 >>> 0 & 0xff; - o[45] = x11 >>> 8 & 0xff; - o[46] = x11 >>> 16 & 0xff; - o[47] = x11 >>> 24 & 0xff; + o[44] = x11 >>> 0 & 0xff; + o[45] = x11 >>> 8 & 0xff; + o[46] = x11 >>> 16 & 0xff; + o[47] = x11 >>> 24 & 0xff; - o[48] = x12 >>> 0 & 0xff; - o[49] = x12 >>> 8 & 0xff; - o[50] = x12 >>> 16 & 0xff; - o[51] = x12 >>> 24 & 0xff; + o[48] = x12 >>> 0 & 0xff; + o[49] = x12 >>> 8 & 0xff; + o[50] = x12 >>> 16 & 0xff; + o[51] = x12 >>> 24 & 0xff; - o[52] = x13 >>> 0 & 0xff; - o[53] = x13 >>> 8 & 0xff; - o[54] = x13 >>> 16 & 0xff; - o[55] = x13 >>> 24 & 0xff; + o[52] = x13 >>> 0 & 0xff; + o[53] = x13 >>> 8 & 0xff; + o[54] = x13 >>> 16 & 0xff; + o[55] = x13 >>> 24 & 0xff; - o[56] = x14 >>> 0 & 0xff; - o[57] = x14 >>> 8 & 0xff; - o[58] = x14 >>> 16 & 0xff; - o[59] = x14 >>> 24 & 0xff; + o[56] = x14 >>> 0 & 0xff; + o[57] = x14 >>> 8 & 0xff; + o[58] = x14 >>> 16 & 0xff; + o[59] = x14 >>> 24 & 0xff; - o[60] = x15 >>> 0 & 0xff; - o[61] = x15 >>> 8 & 0xff; - o[62] = x15 >>> 16 & 0xff; - o[63] = x15 >>> 24 & 0xff; + o[60] = x15 >>> 0 & 0xff; + o[61] = x15 >>> 8 & 0xff; + o[62] = x15 >>> 16 & 0xff; + o[63] = x15 >>> 24 & 0xff; } -function core_hsalsa20(o,p,k,c) { - var j0 = c[ 0] & 0xff | (c[ 1] & 0xff)<<8 | (c[ 2] & 0xff)<<16 | (c[ 3] & 0xff)<<24, - j1 = k[ 0] & 0xff | (k[ 1] & 0xff)<<8 | (k[ 2] & 0xff)<<16 | (k[ 3] & 0xff)<<24, - j2 = k[ 4] & 0xff | (k[ 5] & 0xff)<<8 | (k[ 6] & 0xff)<<16 | (k[ 7] & 0xff)<<24, - j3 = k[ 8] & 0xff | (k[ 9] & 0xff)<<8 | (k[10] & 0xff)<<16 | (k[11] & 0xff)<<24, - j4 = k[12] & 0xff | (k[13] & 0xff)<<8 | (k[14] & 0xff)<<16 | (k[15] & 0xff)<<24, - j5 = c[ 4] & 0xff | (c[ 5] & 0xff)<<8 | (c[ 6] & 0xff)<<16 | (c[ 7] & 0xff)<<24, - j6 = p[ 0] & 0xff | (p[ 1] & 0xff)<<8 | (p[ 2] & 0xff)<<16 | (p[ 3] & 0xff)<<24, - j7 = p[ 4] & 0xff | (p[ 5] & 0xff)<<8 | (p[ 6] & 0xff)<<16 | (p[ 7] & 0xff)<<24, - j8 = p[ 8] & 0xff | (p[ 9] & 0xff)<<8 | (p[10] & 0xff)<<16 | (p[11] & 0xff)<<24, - j9 = p[12] & 0xff | (p[13] & 0xff)<<8 | (p[14] & 0xff)<<16 | (p[15] & 0xff)<<24, - j10 = c[ 8] & 0xff | (c[ 9] & 0xff)<<8 | (c[10] & 0xff)<<16 | (c[11] & 0xff)<<24, - j11 = k[16] & 0xff | (k[17] & 0xff)<<8 | (k[18] & 0xff)<<16 | (k[19] & 0xff)<<24, - j12 = k[20] & 0xff | (k[21] & 0xff)<<8 | (k[22] & 0xff)<<16 | (k[23] & 0xff)<<24, - j13 = k[24] & 0xff | (k[25] & 0xff)<<8 | (k[26] & 0xff)<<16 | (k[27] & 0xff)<<24, - j14 = k[28] & 0xff | (k[29] & 0xff)<<8 | (k[30] & 0xff)<<16 | (k[31] & 0xff)<<24, - j15 = c[12] & 0xff | (c[13] & 0xff)<<8 | (c[14] & 0xff)<<16 | (c[15] & 0xff)<<24; +function core_hsalsa20(o, p, k, c) { + var j0 = c[0] & 0xff | (c[1] & 0xff) << 8 | (c[2] & 0xff) << 16 | (c[3] & 0xff) << 24, + j1 = k[0] & 0xff | (k[1] & 0xff) << 8 | (k[2] & 0xff) << 16 | (k[3] & 0xff) << 24, + j2 = k[4] & 0xff | (k[5] & 0xff) << 8 | (k[6] & 0xff) << 16 | (k[7] & 0xff) << 24, + j3 = k[8] & 0xff | (k[9] & 0xff) << 8 | (k[10] & 0xff) << 16 | (k[11] & 0xff) << 24, + j4 = k[12] & 0xff | (k[13] & 0xff) << 8 | (k[14] & 0xff) << 16 | (k[15] & 0xff) << 24, + j5 = c[4] & 0xff | (c[5] & 0xff) << 8 | (c[6] & 0xff) << 16 | (c[7] & 0xff) << 24, + j6 = p[0] & 0xff | (p[1] & 0xff) << 8 | (p[2] & 0xff) << 16 | (p[3] & 0xff) << 24, + j7 = p[4] & 0xff | (p[5] & 0xff) << 8 | (p[6] & 0xff) << 16 | (p[7] & 0xff) << 24, + j8 = p[8] & 0xff | (p[9] & 0xff) << 8 | (p[10] & 0xff) << 16 | (p[11] & 0xff) << 24, + j9 = p[12] & 0xff | (p[13] & 0xff) << 8 | (p[14] & 0xff) << 16 | (p[15] & 0xff) << 24, + j10 = c[8] & 0xff | (c[9] & 0xff) << 8 | (c[10] & 0xff) << 16 | (c[11] & 0xff) << 24, + j11 = k[16] & 0xff | (k[17] & 0xff) << 8 | (k[18] & 0xff) << 16 | (k[19] & 0xff) << 24, + j12 = k[20] & 0xff | (k[21] & 0xff) << 8 | (k[22] & 0xff) << 16 | (k[23] & 0xff) << 24, + j13 = k[24] & 0xff | (k[25] & 0xff) << 8 | (k[26] & 0xff) << 16 | (k[27] & 0xff) << 24, + j14 = k[28] & 0xff | (k[29] & 0xff) << 8 | (k[30] & 0xff) << 16 | (k[31] & 0xff) << 24, + j15 = c[12] & 0xff | (c[13] & 0xff) << 8 | (c[14] & 0xff) << 16 | (c[15] & 0xff) << 24; - var x0 = j0, x1 = j1, x2 = j2, x3 = j3, x4 = j4, x5 = j5, x6 = j6, x7 = j7, - x8 = j8, x9 = j9, x10 = j10, x11 = j11, x12 = j12, x13 = j13, x14 = j14, - x15 = j15, u; + var x0 = j0, x1 = j1, x2 = j2, x3 = j3, x4 = j4, x5 = j5, x6 = j6, x7 = j7, + x8 = j8, x9 = j9, x10 = j10, x11 = j11, x12 = j12, x13 = j13, x14 = j14, + x15 = j15, u; - for (var i = 0; i < 20; i += 2) { - u = x0 + x12 | 0; - x4 ^= u<<7 | u>>>(32-7); - u = x4 + x0 | 0; - x8 ^= u<<9 | u>>>(32-9); - u = x8 + x4 | 0; - x12 ^= u<<13 | u>>>(32-13); - u = x12 + x8 | 0; - x0 ^= u<<18 | u>>>(32-18); + for (var i = 0; i < 20; i += 2) { + u = x0 + x12 | 0; + x4 ^= u << 7 | u >>> (32 - 7); + u = x4 + x0 | 0; + x8 ^= u << 9 | u >>> (32 - 9); + u = x8 + x4 | 0; + x12 ^= u << 13 | u >>> (32 - 13); + u = x12 + x8 | 0; + x0 ^= u << 18 | u >>> (32 - 18); - u = x5 + x1 | 0; - x9 ^= u<<7 | u>>>(32-7); - u = x9 + x5 | 0; - x13 ^= u<<9 | u>>>(32-9); - u = x13 + x9 | 0; - x1 ^= u<<13 | u>>>(32-13); - u = x1 + x13 | 0; - x5 ^= u<<18 | u>>>(32-18); + u = x5 + x1 | 0; + x9 ^= u << 7 | u >>> (32 - 7); + u = x9 + x5 | 0; + x13 ^= u << 9 | u >>> (32 - 9); + u = x13 + x9 | 0; + x1 ^= u << 13 | u >>> (32 - 13); + u = x1 + x13 | 0; + x5 ^= u << 18 | u >>> (32 - 18); - u = x10 + x6 | 0; - x14 ^= u<<7 | u>>>(32-7); - u = x14 + x10 | 0; - x2 ^= u<<9 | u>>>(32-9); - u = x2 + x14 | 0; - x6 ^= u<<13 | u>>>(32-13); - u = x6 + x2 | 0; - x10 ^= u<<18 | u>>>(32-18); + u = x10 + x6 | 0; + x14 ^= u << 7 | u >>> (32 - 7); + u = x14 + x10 | 0; + x2 ^= u << 9 | u >>> (32 - 9); + u = x2 + x14 | 0; + x6 ^= u << 13 | u >>> (32 - 13); + u = x6 + x2 | 0; + x10 ^= u << 18 | u >>> (32 - 18); - u = x15 + x11 | 0; - x3 ^= u<<7 | u>>>(32-7); - u = x3 + x15 | 0; - x7 ^= u<<9 | u>>>(32-9); - u = x7 + x3 | 0; - x11 ^= u<<13 | u>>>(32-13); - u = x11 + x7 | 0; - x15 ^= u<<18 | u>>>(32-18); + u = x15 + x11 | 0; + x3 ^= u << 7 | u >>> (32 - 7); + u = x3 + x15 | 0; + x7 ^= u << 9 | u >>> (32 - 9); + u = x7 + x3 | 0; + x11 ^= u << 13 | u >>> (32 - 13); + u = x11 + x7 | 0; + x15 ^= u << 18 | u >>> (32 - 18); - u = x0 + x3 | 0; - x1 ^= u<<7 | u>>>(32-7); - u = x1 + x0 | 0; - x2 ^= u<<9 | u>>>(32-9); - u = x2 + x1 | 0; - x3 ^= u<<13 | u>>>(32-13); - u = x3 + x2 | 0; - x0 ^= u<<18 | u>>>(32-18); + u = x0 + x3 | 0; + x1 ^= u << 7 | u >>> (32 - 7); + u = x1 + x0 | 0; + x2 ^= u << 9 | u >>> (32 - 9); + u = x2 + x1 | 0; + x3 ^= u << 13 | u >>> (32 - 13); + u = x3 + x2 | 0; + x0 ^= u << 18 | u >>> (32 - 18); - u = x5 + x4 | 0; - x6 ^= u<<7 | u>>>(32-7); - u = x6 + x5 | 0; - x7 ^= u<<9 | u>>>(32-9); - u = x7 + x6 | 0; - x4 ^= u<<13 | u>>>(32-13); - u = x4 + x7 | 0; - x5 ^= u<<18 | u>>>(32-18); + u = x5 + x4 | 0; + x6 ^= u << 7 | u >>> (32 - 7); + u = x6 + x5 | 0; + x7 ^= u << 9 | u >>> (32 - 9); + u = x7 + x6 | 0; + x4 ^= u << 13 | u >>> (32 - 13); + u = x4 + x7 | 0; + x5 ^= u << 18 | u >>> (32 - 18); - u = x10 + x9 | 0; - x11 ^= u<<7 | u>>>(32-7); - u = x11 + x10 | 0; - x8 ^= u<<9 | u>>>(32-9); - u = x8 + x11 | 0; - x9 ^= u<<13 | u>>>(32-13); - u = x9 + x8 | 0; - x10 ^= u<<18 | u>>>(32-18); + u = x10 + x9 | 0; + x11 ^= u << 7 | u >>> (32 - 7); + u = x11 + x10 | 0; + x8 ^= u << 9 | u >>> (32 - 9); + u = x8 + x11 | 0; + x9 ^= u << 13 | u >>> (32 - 13); + u = x9 + x8 | 0; + x10 ^= u << 18 | u >>> (32 - 18); - u = x15 + x14 | 0; - x12 ^= u<<7 | u>>>(32-7); - u = x12 + x15 | 0; - x13 ^= u<<9 | u>>>(32-9); - u = x13 + x12 | 0; - x14 ^= u<<13 | u>>>(32-13); - u = x14 + x13 | 0; - x15 ^= u<<18 | u>>>(32-18); - } + u = x15 + x14 | 0; + x12 ^= u << 7 | u >>> (32 - 7); + u = x12 + x15 | 0; + x13 ^= u << 9 | u >>> (32 - 9); + u = x13 + x12 | 0; + x14 ^= u << 13 | u >>> (32 - 13); + u = x14 + x13 | 0; + x15 ^= u << 18 | u >>> (32 - 18); + } - o[ 0] = x0 >>> 0 & 0xff; - o[ 1] = x0 >>> 8 & 0xff; - o[ 2] = x0 >>> 16 & 0xff; - o[ 3] = x0 >>> 24 & 0xff; + o[0] = x0 >>> 0 & 0xff; + o[1] = x0 >>> 8 & 0xff; + o[2] = x0 >>> 16 & 0xff; + o[3] = x0 >>> 24 & 0xff; - o[ 4] = x5 >>> 0 & 0xff; - o[ 5] = x5 >>> 8 & 0xff; - o[ 6] = x5 >>> 16 & 0xff; - o[ 7] = x5 >>> 24 & 0xff; + o[4] = x5 >>> 0 & 0xff; + o[5] = x5 >>> 8 & 0xff; + o[6] = x5 >>> 16 & 0xff; + o[7] = x5 >>> 24 & 0xff; - o[ 8] = x10 >>> 0 & 0xff; - o[ 9] = x10 >>> 8 & 0xff; - o[10] = x10 >>> 16 & 0xff; - o[11] = x10 >>> 24 & 0xff; + o[8] = x10 >>> 0 & 0xff; + o[9] = x10 >>> 8 & 0xff; + o[10] = x10 >>> 16 & 0xff; + o[11] = x10 >>> 24 & 0xff; - o[12] = x15 >>> 0 & 0xff; - o[13] = x15 >>> 8 & 0xff; - o[14] = x15 >>> 16 & 0xff; - o[15] = x15 >>> 24 & 0xff; + o[12] = x15 >>> 0 & 0xff; + o[13] = x15 >>> 8 & 0xff; + o[14] = x15 >>> 16 & 0xff; + o[15] = x15 >>> 24 & 0xff; - o[16] = x6 >>> 0 & 0xff; - o[17] = x6 >>> 8 & 0xff; - o[18] = x6 >>> 16 & 0xff; - o[19] = x6 >>> 24 & 0xff; + o[16] = x6 >>> 0 & 0xff; + o[17] = x6 >>> 8 & 0xff; + o[18] = x6 >>> 16 & 0xff; + o[19] = x6 >>> 24 & 0xff; - o[20] = x7 >>> 0 & 0xff; - o[21] = x7 >>> 8 & 0xff; - o[22] = x7 >>> 16 & 0xff; - o[23] = x7 >>> 24 & 0xff; + o[20] = x7 >>> 0 & 0xff; + o[21] = x7 >>> 8 & 0xff; + o[22] = x7 >>> 16 & 0xff; + o[23] = x7 >>> 24 & 0xff; - o[24] = x8 >>> 0 & 0xff; - o[25] = x8 >>> 8 & 0xff; - o[26] = x8 >>> 16 & 0xff; - o[27] = x8 >>> 24 & 0xff; + o[24] = x8 >>> 0 & 0xff; + o[25] = x8 >>> 8 & 0xff; + o[26] = x8 >>> 16 & 0xff; + o[27] = x8 >>> 24 & 0xff; - o[28] = x9 >>> 0 & 0xff; - o[29] = x9 >>> 8 & 0xff; - o[30] = x9 >>> 16 & 0xff; - o[31] = x9 >>> 24 & 0xff; + o[28] = x9 >>> 0 & 0xff; + o[29] = x9 >>> 8 & 0xff; + o[30] = x9 >>> 16 & 0xff; + o[31] = x9 >>> 24 & 0xff; } -function crypto_core_salsa20(out,inp,k,c) { - core_salsa20(out,inp,k,c); +function crypto_core_salsa20(out, inp, k, c) { + core_salsa20(out, inp, k, c); } -function crypto_core_hsalsa20(out,inp,k,c) { - core_hsalsa20(out,inp,k,c); +function crypto_core_hsalsa20(out, inp, k, c) { + core_hsalsa20(out, inp, k, c); } var sigma = new Uint8Array([101, 120, 112, 97, 110, 100, 32, 51, 50, 45, 98, 121, 116, 101, 32, 107]); - // "expand 32-byte k" +// "expand 32-byte k" -function crypto_stream_salsa20_xor(c,cpos,m,mpos,b,n,k) { - var z = new Uint8Array(16), x = new Uint8Array(64); - var u, i; - for (i = 0; i < 16; i++) z[i] = 0; - for (i = 0; i < 8; i++) z[i] = n[i]; - while (b >= 64) { - crypto_core_salsa20(x,z,k,sigma); - for (i = 0; i < 64; i++) c[cpos+i] = m[mpos+i] ^ x[i]; - u = 1; - for (i = 8; i < 16; i++) { - u = u + (z[i] & 0xff) | 0; - z[i] = u & 0xff; - u >>>= 8; - } - b -= 64; - cpos += 64; - mpos += 64; - } - if (b > 0) { - crypto_core_salsa20(x,z,k,sigma); - for (i = 0; i < b; i++) c[cpos+i] = m[mpos+i] ^ x[i]; - } - return 0; +function crypto_stream_salsa20_xor(c, cpos, m, mpos, b, n, k) { + var z = new Uint8Array(16), x = new Uint8Array(64); + var u, i; + for (i = 0; i < 16; i++) z[i] = 0; + for (i = 0; i < 8; i++) z[i] = n[i]; + while (b >= 64) { + crypto_core_salsa20(x, z, k, sigma); + for (i = 0; i < 64; i++) c[cpos + i] = m[mpos + i] ^ x[i]; + u = 1; + for (i = 8; i < 16; i++) { + u = u + (z[i] & 0xff) | 0; + z[i] = u & 0xff; + u >>>= 8; + } + b -= 64; + cpos += 64; + mpos += 64; + } + if (b > 0) { + crypto_core_salsa20(x, z, k, sigma); + for (i = 0; i < b; i++) c[cpos + i] = m[mpos + i] ^ x[i]; + } + return 0; } -function crypto_stream_salsa20(c,cpos,b,n,k) { - var z = new Uint8Array(16), x = new Uint8Array(64); - var u, i; - for (i = 0; i < 16; i++) z[i] = 0; - for (i = 0; i < 8; i++) z[i] = n[i]; - while (b >= 64) { - crypto_core_salsa20(x,z,k,sigma); - for (i = 0; i < 64; i++) c[cpos+i] = x[i]; - u = 1; - for (i = 8; i < 16; i++) { - u = u + (z[i] & 0xff) | 0; - z[i] = u & 0xff; - u >>>= 8; - } - b -= 64; - cpos += 64; - } - if (b > 0) { - crypto_core_salsa20(x,z,k,sigma); - for (i = 0; i < b; i++) c[cpos+i] = x[i]; - } - return 0; +function crypto_stream_salsa20(c, cpos, b, n, k) { + var z = new Uint8Array(16), x = new Uint8Array(64); + var u, i; + for (i = 0; i < 16; i++) z[i] = 0; + for (i = 0; i < 8; i++) z[i] = n[i]; + while (b >= 64) { + crypto_core_salsa20(x, z, k, sigma); + for (i = 0; i < 64; i++) c[cpos + i] = x[i]; + u = 1; + for (i = 8; i < 16; i++) { + u = u + (z[i] & 0xff) | 0; + z[i] = u & 0xff; + u >>>= 8; + } + b -= 64; + cpos += 64; + } + if (b > 0) { + crypto_core_salsa20(x, z, k, sigma); + for (i = 0; i < b; i++) c[cpos + i] = x[i]; + } + return 0; } -function crypto_stream(c,cpos,d,n,k) { - var s = new Uint8Array(32); - crypto_core_hsalsa20(s,n,k,sigma); - var sn = new Uint8Array(8); - for (var i = 0; i < 8; i++) sn[i] = n[i+16]; - return crypto_stream_salsa20(c,cpos,d,sn,s); +function crypto_stream(c, cpos, d, n, k) { + var s = new Uint8Array(32); + crypto_core_hsalsa20(s, n, k, sigma); + var sn = new Uint8Array(8); + for (var i = 0; i < 8; i++) sn[i] = n[i + 16]; + return crypto_stream_salsa20(c, cpos, d, sn, s); } -function crypto_stream_xor(c,cpos,m,mpos,d,n,k) { - var s = new Uint8Array(32); - crypto_core_hsalsa20(s,n,k,sigma); - var sn = new Uint8Array(8); - for (var i = 0; i < 8; i++) sn[i] = n[i+16]; - return crypto_stream_salsa20_xor(c,cpos,m,mpos,d,sn,s); +function crypto_stream_xor(c, cpos, m, mpos, d, n, k) { + var s = new Uint8Array(32); + crypto_core_hsalsa20(s, n, k, sigma); + var sn = new Uint8Array(8); + for (var i = 0; i < 8; i++) sn[i] = n[i + 16]; + return crypto_stream_salsa20_xor(c, cpos, m, mpos, d, sn, s); } /* @@ -466,1820 +464,1820 @@ function crypto_stream_xor(c,cpos,m,mpos,d,n,k) { * https://github.com/floodyberry/poly1305-donna */ -var poly1305 = function(key) { - this.buffer = new Uint8Array(16); - this.r = new Uint16Array(10); - this.h = new Uint16Array(10); - this.pad = new Uint16Array(8); - this.leftover = 0; - this.fin = 0; +var poly1305 = function (key) { + this.buffer = new Uint8Array(16); + this.r = new Uint16Array(10); + this.h = new Uint16Array(10); + this.pad = new Uint16Array(8); + this.leftover = 0; + this.fin = 0; - var t0, t1, t2, t3, t4, t5, t6, t7; + var t0, t1, t2, t3, t4, t5, t6, t7; - t0 = key[ 0] & 0xff | (key[ 1] & 0xff) << 8; this.r[0] = ( t0 ) & 0x1fff; - t1 = key[ 2] & 0xff | (key[ 3] & 0xff) << 8; this.r[1] = ((t0 >>> 13) | (t1 << 3)) & 0x1fff; - t2 = key[ 4] & 0xff | (key[ 5] & 0xff) << 8; this.r[2] = ((t1 >>> 10) | (t2 << 6)) & 0x1f03; - t3 = key[ 6] & 0xff | (key[ 7] & 0xff) << 8; this.r[3] = ((t2 >>> 7) | (t3 << 9)) & 0x1fff; - t4 = key[ 8] & 0xff | (key[ 9] & 0xff) << 8; this.r[4] = ((t3 >>> 4) | (t4 << 12)) & 0x00ff; - this.r[5] = ((t4 >>> 1)) & 0x1ffe; - t5 = key[10] & 0xff | (key[11] & 0xff) << 8; this.r[6] = ((t4 >>> 14) | (t5 << 2)) & 0x1fff; - t6 = key[12] & 0xff | (key[13] & 0xff) << 8; this.r[7] = ((t5 >>> 11) | (t6 << 5)) & 0x1f81; - t7 = key[14] & 0xff | (key[15] & 0xff) << 8; this.r[8] = ((t6 >>> 8) | (t7 << 8)) & 0x1fff; - this.r[9] = ((t7 >>> 5)) & 0x007f; + t0 = key[0] & 0xff | (key[1] & 0xff) << 8; this.r[0] = (t0) & 0x1fff; + t1 = key[2] & 0xff | (key[3] & 0xff) << 8; this.r[1] = ((t0 >>> 13) | (t1 << 3)) & 0x1fff; + t2 = key[4] & 0xff | (key[5] & 0xff) << 8; this.r[2] = ((t1 >>> 10) | (t2 << 6)) & 0x1f03; + t3 = key[6] & 0xff | (key[7] & 0xff) << 8; this.r[3] = ((t2 >>> 7) | (t3 << 9)) & 0x1fff; + t4 = key[8] & 0xff | (key[9] & 0xff) << 8; this.r[4] = ((t3 >>> 4) | (t4 << 12)) & 0x00ff; + this.r[5] = ((t4 >>> 1)) & 0x1ffe; + t5 = key[10] & 0xff | (key[11] & 0xff) << 8; this.r[6] = ((t4 >>> 14) | (t5 << 2)) & 0x1fff; + t6 = key[12] & 0xff | (key[13] & 0xff) << 8; this.r[7] = ((t5 >>> 11) | (t6 << 5)) & 0x1f81; + t7 = key[14] & 0xff | (key[15] & 0xff) << 8; this.r[8] = ((t6 >>> 8) | (t7 << 8)) & 0x1fff; + this.r[9] = ((t7 >>> 5)) & 0x007f; - this.pad[0] = key[16] & 0xff | (key[17] & 0xff) << 8; - this.pad[1] = key[18] & 0xff | (key[19] & 0xff) << 8; - this.pad[2] = key[20] & 0xff | (key[21] & 0xff) << 8; - this.pad[3] = key[22] & 0xff | (key[23] & 0xff) << 8; - this.pad[4] = key[24] & 0xff | (key[25] & 0xff) << 8; - this.pad[5] = key[26] & 0xff | (key[27] & 0xff) << 8; - this.pad[6] = key[28] & 0xff | (key[29] & 0xff) << 8; - this.pad[7] = key[30] & 0xff | (key[31] & 0xff) << 8; + this.pad[0] = key[16] & 0xff | (key[17] & 0xff) << 8; + this.pad[1] = key[18] & 0xff | (key[19] & 0xff) << 8; + this.pad[2] = key[20] & 0xff | (key[21] & 0xff) << 8; + this.pad[3] = key[22] & 0xff | (key[23] & 0xff) << 8; + this.pad[4] = key[24] & 0xff | (key[25] & 0xff) << 8; + this.pad[5] = key[26] & 0xff | (key[27] & 0xff) << 8; + this.pad[6] = key[28] & 0xff | (key[29] & 0xff) << 8; + this.pad[7] = key[30] & 0xff | (key[31] & 0xff) << 8; }; -poly1305.prototype.blocks = function(m, mpos, bytes) { - var hibit = this.fin ? 0 : (1 << 11); - var t0, t1, t2, t3, t4, t5, t6, t7, c; - var d0, d1, d2, d3, d4, d5, d6, d7, d8, d9; +poly1305.prototype.blocks = function (m, mpos, bytes) { + var hibit = this.fin ? 0 : (1 << 11); + var t0, t1, t2, t3, t4, t5, t6, t7, c; + var d0, d1, d2, d3, d4, d5, d6, d7, d8, d9; - var h0 = this.h[0], - h1 = this.h[1], - h2 = this.h[2], - h3 = this.h[3], - h4 = this.h[4], - h5 = this.h[5], - h6 = this.h[6], - h7 = this.h[7], - h8 = this.h[8], - h9 = this.h[9]; + var h0 = this.h[0], + h1 = this.h[1], + h2 = this.h[2], + h3 = this.h[3], + h4 = this.h[4], + h5 = this.h[5], + h6 = this.h[6], + h7 = this.h[7], + h8 = this.h[8], + h9 = this.h[9]; - var r0 = this.r[0], - r1 = this.r[1], - r2 = this.r[2], - r3 = this.r[3], - r4 = this.r[4], - r5 = this.r[5], - r6 = this.r[6], - r7 = this.r[7], - r8 = this.r[8], - r9 = this.r[9]; + var r0 = this.r[0], + r1 = this.r[1], + r2 = this.r[2], + r3 = this.r[3], + r4 = this.r[4], + r5 = this.r[5], + r6 = this.r[6], + r7 = this.r[7], + r8 = this.r[8], + r9 = this.r[9]; - while (bytes >= 16) { - t0 = m[mpos+ 0] & 0xff | (m[mpos+ 1] & 0xff) << 8; h0 += ( t0 ) & 0x1fff; - t1 = m[mpos+ 2] & 0xff | (m[mpos+ 3] & 0xff) << 8; h1 += ((t0 >>> 13) | (t1 << 3)) & 0x1fff; - t2 = m[mpos+ 4] & 0xff | (m[mpos+ 5] & 0xff) << 8; h2 += ((t1 >>> 10) | (t2 << 6)) & 0x1fff; - t3 = m[mpos+ 6] & 0xff | (m[mpos+ 7] & 0xff) << 8; h3 += ((t2 >>> 7) | (t3 << 9)) & 0x1fff; - t4 = m[mpos+ 8] & 0xff | (m[mpos+ 9] & 0xff) << 8; h4 += ((t3 >>> 4) | (t4 << 12)) & 0x1fff; - h5 += ((t4 >>> 1)) & 0x1fff; - t5 = m[mpos+10] & 0xff | (m[mpos+11] & 0xff) << 8; h6 += ((t4 >>> 14) | (t5 << 2)) & 0x1fff; - t6 = m[mpos+12] & 0xff | (m[mpos+13] & 0xff) << 8; h7 += ((t5 >>> 11) | (t6 << 5)) & 0x1fff; - t7 = m[mpos+14] & 0xff | (m[mpos+15] & 0xff) << 8; h8 += ((t6 >>> 8) | (t7 << 8)) & 0x1fff; - h9 += ((t7 >>> 5)) | hibit; + while (bytes >= 16) { + t0 = m[mpos + 0] & 0xff | (m[mpos + 1] & 0xff) << 8; h0 += (t0) & 0x1fff; + t1 = m[mpos + 2] & 0xff | (m[mpos + 3] & 0xff) << 8; h1 += ((t0 >>> 13) | (t1 << 3)) & 0x1fff; + t2 = m[mpos + 4] & 0xff | (m[mpos + 5] & 0xff) << 8; h2 += ((t1 >>> 10) | (t2 << 6)) & 0x1fff; + t3 = m[mpos + 6] & 0xff | (m[mpos + 7] & 0xff) << 8; h3 += ((t2 >>> 7) | (t3 << 9)) & 0x1fff; + t4 = m[mpos + 8] & 0xff | (m[mpos + 9] & 0xff) << 8; h4 += ((t3 >>> 4) | (t4 << 12)) & 0x1fff; + h5 += ((t4 >>> 1)) & 0x1fff; + t5 = m[mpos + 10] & 0xff | (m[mpos + 11] & 0xff) << 8; h6 += ((t4 >>> 14) | (t5 << 2)) & 0x1fff; + t6 = m[mpos + 12] & 0xff | (m[mpos + 13] & 0xff) << 8; h7 += ((t5 >>> 11) | (t6 << 5)) & 0x1fff; + t7 = m[mpos + 14] & 0xff | (m[mpos + 15] & 0xff) << 8; h8 += ((t6 >>> 8) | (t7 << 8)) & 0x1fff; + h9 += ((t7 >>> 5)) | hibit; - c = 0; + c = 0; - d0 = c; - d0 += h0 * r0; - d0 += h1 * (5 * r9); - d0 += h2 * (5 * r8); - d0 += h3 * (5 * r7); - d0 += h4 * (5 * r6); - c = (d0 >>> 13); d0 &= 0x1fff; - d0 += h5 * (5 * r5); - d0 += h6 * (5 * r4); - d0 += h7 * (5 * r3); - d0 += h8 * (5 * r2); - d0 += h9 * (5 * r1); - c += (d0 >>> 13); d0 &= 0x1fff; + d0 = c; + d0 += h0 * r0; + d0 += h1 * (5 * r9); + d0 += h2 * (5 * r8); + d0 += h3 * (5 * r7); + d0 += h4 * (5 * r6); + c = (d0 >>> 13); d0 &= 0x1fff; + d0 += h5 * (5 * r5); + d0 += h6 * (5 * r4); + d0 += h7 * (5 * r3); + d0 += h8 * (5 * r2); + d0 += h9 * (5 * r1); + c += (d0 >>> 13); d0 &= 0x1fff; - d1 = c; - d1 += h0 * r1; - d1 += h1 * r0; - d1 += h2 * (5 * r9); - d1 += h3 * (5 * r8); - d1 += h4 * (5 * r7); - c = (d1 >>> 13); d1 &= 0x1fff; - d1 += h5 * (5 * r6); - d1 += h6 * (5 * r5); - d1 += h7 * (5 * r4); - d1 += h8 * (5 * r3); - d1 += h9 * (5 * r2); - c += (d1 >>> 13); d1 &= 0x1fff; + d1 = c; + d1 += h0 * r1; + d1 += h1 * r0; + d1 += h2 * (5 * r9); + d1 += h3 * (5 * r8); + d1 += h4 * (5 * r7); + c = (d1 >>> 13); d1 &= 0x1fff; + d1 += h5 * (5 * r6); + d1 += h6 * (5 * r5); + d1 += h7 * (5 * r4); + d1 += h8 * (5 * r3); + d1 += h9 * (5 * r2); + c += (d1 >>> 13); d1 &= 0x1fff; - d2 = c; - d2 += h0 * r2; - d2 += h1 * r1; - d2 += h2 * r0; - d2 += h3 * (5 * r9); - d2 += h4 * (5 * r8); - c = (d2 >>> 13); d2 &= 0x1fff; - d2 += h5 * (5 * r7); - d2 += h6 * (5 * r6); - d2 += h7 * (5 * r5); - d2 += h8 * (5 * r4); - d2 += h9 * (5 * r3); - c += (d2 >>> 13); d2 &= 0x1fff; + d2 = c; + d2 += h0 * r2; + d2 += h1 * r1; + d2 += h2 * r0; + d2 += h3 * (5 * r9); + d2 += h4 * (5 * r8); + c = (d2 >>> 13); d2 &= 0x1fff; + d2 += h5 * (5 * r7); + d2 += h6 * (5 * r6); + d2 += h7 * (5 * r5); + d2 += h8 * (5 * r4); + d2 += h9 * (5 * r3); + c += (d2 >>> 13); d2 &= 0x1fff; - d3 = c; - d3 += h0 * r3; - d3 += h1 * r2; - d3 += h2 * r1; - d3 += h3 * r0; - d3 += h4 * (5 * r9); - c = (d3 >>> 13); d3 &= 0x1fff; - d3 += h5 * (5 * r8); - d3 += h6 * (5 * r7); - d3 += h7 * (5 * r6); - d3 += h8 * (5 * r5); - d3 += h9 * (5 * r4); - c += (d3 >>> 13); d3 &= 0x1fff; + d3 = c; + d3 += h0 * r3; + d3 += h1 * r2; + d3 += h2 * r1; + d3 += h3 * r0; + d3 += h4 * (5 * r9); + c = (d3 >>> 13); d3 &= 0x1fff; + d3 += h5 * (5 * r8); + d3 += h6 * (5 * r7); + d3 += h7 * (5 * r6); + d3 += h8 * (5 * r5); + d3 += h9 * (5 * r4); + c += (d3 >>> 13); d3 &= 0x1fff; - d4 = c; - d4 += h0 * r4; - d4 += h1 * r3; - d4 += h2 * r2; - d4 += h3 * r1; - d4 += h4 * r0; - c = (d4 >>> 13); d4 &= 0x1fff; - d4 += h5 * (5 * r9); - d4 += h6 * (5 * r8); - d4 += h7 * (5 * r7); - d4 += h8 * (5 * r6); - d4 += h9 * (5 * r5); - c += (d4 >>> 13); d4 &= 0x1fff; + d4 = c; + d4 += h0 * r4; + d4 += h1 * r3; + d4 += h2 * r2; + d4 += h3 * r1; + d4 += h4 * r0; + c = (d4 >>> 13); d4 &= 0x1fff; + d4 += h5 * (5 * r9); + d4 += h6 * (5 * r8); + d4 += h7 * (5 * r7); + d4 += h8 * (5 * r6); + d4 += h9 * (5 * r5); + c += (d4 >>> 13); d4 &= 0x1fff; - d5 = c; - d5 += h0 * r5; - d5 += h1 * r4; - d5 += h2 * r3; - d5 += h3 * r2; - d5 += h4 * r1; - c = (d5 >>> 13); d5 &= 0x1fff; - d5 += h5 * r0; - d5 += h6 * (5 * r9); - d5 += h7 * (5 * r8); - d5 += h8 * (5 * r7); - d5 += h9 * (5 * r6); - c += (d5 >>> 13); d5 &= 0x1fff; + d5 = c; + d5 += h0 * r5; + d5 += h1 * r4; + d5 += h2 * r3; + d5 += h3 * r2; + d5 += h4 * r1; + c = (d5 >>> 13); d5 &= 0x1fff; + d5 += h5 * r0; + d5 += h6 * (5 * r9); + d5 += h7 * (5 * r8); + d5 += h8 * (5 * r7); + d5 += h9 * (5 * r6); + c += (d5 >>> 13); d5 &= 0x1fff; - d6 = c; - d6 += h0 * r6; - d6 += h1 * r5; - d6 += h2 * r4; - d6 += h3 * r3; - d6 += h4 * r2; - c = (d6 >>> 13); d6 &= 0x1fff; - d6 += h5 * r1; - d6 += h6 * r0; - d6 += h7 * (5 * r9); - d6 += h8 * (5 * r8); - d6 += h9 * (5 * r7); - c += (d6 >>> 13); d6 &= 0x1fff; + d6 = c; + d6 += h0 * r6; + d6 += h1 * r5; + d6 += h2 * r4; + d6 += h3 * r3; + d6 += h4 * r2; + c = (d6 >>> 13); d6 &= 0x1fff; + d6 += h5 * r1; + d6 += h6 * r0; + d6 += h7 * (5 * r9); + d6 += h8 * (5 * r8); + d6 += h9 * (5 * r7); + c += (d6 >>> 13); d6 &= 0x1fff; - d7 = c; - d7 += h0 * r7; - d7 += h1 * r6; - d7 += h2 * r5; - d7 += h3 * r4; - d7 += h4 * r3; - c = (d7 >>> 13); d7 &= 0x1fff; - d7 += h5 * r2; - d7 += h6 * r1; - d7 += h7 * r0; - d7 += h8 * (5 * r9); - d7 += h9 * (5 * r8); - c += (d7 >>> 13); d7 &= 0x1fff; + d7 = c; + d7 += h0 * r7; + d7 += h1 * r6; + d7 += h2 * r5; + d7 += h3 * r4; + d7 += h4 * r3; + c = (d7 >>> 13); d7 &= 0x1fff; + d7 += h5 * r2; + d7 += h6 * r1; + d7 += h7 * r0; + d7 += h8 * (5 * r9); + d7 += h9 * (5 * r8); + c += (d7 >>> 13); d7 &= 0x1fff; - d8 = c; - d8 += h0 * r8; - d8 += h1 * r7; - d8 += h2 * r6; - d8 += h3 * r5; - d8 += h4 * r4; - c = (d8 >>> 13); d8 &= 0x1fff; - d8 += h5 * r3; - d8 += h6 * r2; - d8 += h7 * r1; - d8 += h8 * r0; - d8 += h9 * (5 * r9); - c += (d8 >>> 13); d8 &= 0x1fff; + d8 = c; + d8 += h0 * r8; + d8 += h1 * r7; + d8 += h2 * r6; + d8 += h3 * r5; + d8 += h4 * r4; + c = (d8 >>> 13); d8 &= 0x1fff; + d8 += h5 * r3; + d8 += h6 * r2; + d8 += h7 * r1; + d8 += h8 * r0; + d8 += h9 * (5 * r9); + c += (d8 >>> 13); d8 &= 0x1fff; - d9 = c; - d9 += h0 * r9; - d9 += h1 * r8; - d9 += h2 * r7; - d9 += h3 * r6; - d9 += h4 * r5; - c = (d9 >>> 13); d9 &= 0x1fff; - d9 += h5 * r4; - d9 += h6 * r3; - d9 += h7 * r2; - d9 += h8 * r1; - d9 += h9 * r0; - c += (d9 >>> 13); d9 &= 0x1fff; + d9 = c; + d9 += h0 * r9; + d9 += h1 * r8; + d9 += h2 * r7; + d9 += h3 * r6; + d9 += h4 * r5; + c = (d9 >>> 13); d9 &= 0x1fff; + d9 += h5 * r4; + d9 += h6 * r3; + d9 += h7 * r2; + d9 += h8 * r1; + d9 += h9 * r0; + c += (d9 >>> 13); d9 &= 0x1fff; - c = (((c << 2) + c)) | 0; - c = (c + d0) | 0; - d0 = c & 0x1fff; - c = (c >>> 13); - d1 += c; + c = (((c << 2) + c)) | 0; + c = (c + d0) | 0; + d0 = c & 0x1fff; + c = (c >>> 13); + d1 += c; - h0 = d0; - h1 = d1; - h2 = d2; - h3 = d3; - h4 = d4; - h5 = d5; - h6 = d6; - h7 = d7; - h8 = d8; - h9 = d9; + h0 = d0; + h1 = d1; + h2 = d2; + h3 = d3; + h4 = d4; + h5 = d5; + h6 = d6; + h7 = d7; + h8 = d8; + h9 = d9; - mpos += 16; - bytes -= 16; - } - this.h[0] = h0; - this.h[1] = h1; - this.h[2] = h2; - this.h[3] = h3; - this.h[4] = h4; - this.h[5] = h5; - this.h[6] = h6; - this.h[7] = h7; - this.h[8] = h8; - this.h[9] = h9; + mpos += 16; + bytes -= 16; + } + this.h[0] = h0; + this.h[1] = h1; + this.h[2] = h2; + this.h[3] = h3; + this.h[4] = h4; + this.h[5] = h5; + this.h[6] = h6; + this.h[7] = h7; + this.h[8] = h8; + this.h[9] = h9; }; -poly1305.prototype.finish = function(mac, macpos) { - var g = new Uint16Array(10); - var c, mask, f, i; +poly1305.prototype.finish = function (mac, macpos) { + var g = new Uint16Array(10); + var c, mask, f, i; - if (this.leftover) { - i = this.leftover; - this.buffer[i++] = 1; - for (; i < 16; i++) this.buffer[i] = 0; - this.fin = 1; - this.blocks(this.buffer, 0, 16); - } + if (this.leftover) { + i = this.leftover; + this.buffer[i++] = 1; + for (; i < 16; i++) this.buffer[i] = 0; + this.fin = 1; + this.blocks(this.buffer, 0, 16); + } - c = this.h[1] >>> 13; - this.h[1] &= 0x1fff; - for (i = 2; i < 10; i++) { - this.h[i] += c; - c = this.h[i] >>> 13; - this.h[i] &= 0x1fff; - } - this.h[0] += (c * 5); - c = this.h[0] >>> 13; - this.h[0] &= 0x1fff; - this.h[1] += c; - c = this.h[1] >>> 13; - this.h[1] &= 0x1fff; - this.h[2] += c; + c = this.h[1] >>> 13; + this.h[1] &= 0x1fff; + for (i = 2; i < 10; i++) { + this.h[i] += c; + c = this.h[i] >>> 13; + this.h[i] &= 0x1fff; + } + this.h[0] += (c * 5); + c = this.h[0] >>> 13; + this.h[0] &= 0x1fff; + this.h[1] += c; + c = this.h[1] >>> 13; + this.h[1] &= 0x1fff; + this.h[2] += c; - g[0] = this.h[0] + 5; - c = g[0] >>> 13; - g[0] &= 0x1fff; - for (i = 1; i < 10; i++) { - g[i] = this.h[i] + c; - c = g[i] >>> 13; - g[i] &= 0x1fff; - } - g[9] -= (1 << 13); + g[0] = this.h[0] + 5; + c = g[0] >>> 13; + g[0] &= 0x1fff; + for (i = 1; i < 10; i++) { + g[i] = this.h[i] + c; + c = g[i] >>> 13; + g[i] &= 0x1fff; + } + g[9] -= (1 << 13); - mask = (g[9] >>> ((2 * 8) - 1)) - 1; - for (i = 0; i < 10; i++) g[i] &= mask; - mask = ~mask; - for (i = 0; i < 10; i++) this.h[i] = (this.h[i] & mask) | g[i]; + mask = (g[9] >>> ((2 * 8) - 1)) - 1; + for (i = 0; i < 10; i++) g[i] &= mask; + mask = ~mask; + for (i = 0; i < 10; i++) this.h[i] = (this.h[i] & mask) | g[i]; - this.h[0] = ((this.h[0] ) | (this.h[1] << 13) ) & 0xffff; - this.h[1] = ((this.h[1] >>> 3) | (this.h[2] << 10) ) & 0xffff; - this.h[2] = ((this.h[2] >>> 6) | (this.h[3] << 7) ) & 0xffff; - this.h[3] = ((this.h[3] >>> 9) | (this.h[4] << 4) ) & 0xffff; - this.h[4] = ((this.h[4] >>> 12) | (this.h[5] << 1) | (this.h[6] << 14)) & 0xffff; - this.h[5] = ((this.h[6] >>> 2) | (this.h[7] << 11) ) & 0xffff; - this.h[6] = ((this.h[7] >>> 5) | (this.h[8] << 8) ) & 0xffff; - this.h[7] = ((this.h[8] >>> 8) | (this.h[9] << 5) ) & 0xffff; + this.h[0] = ((this.h[0]) | (this.h[1] << 13)) & 0xffff; + this.h[1] = ((this.h[1] >>> 3) | (this.h[2] << 10)) & 0xffff; + this.h[2] = ((this.h[2] >>> 6) | (this.h[3] << 7)) & 0xffff; + this.h[3] = ((this.h[3] >>> 9) | (this.h[4] << 4)) & 0xffff; + this.h[4] = ((this.h[4] >>> 12) | (this.h[5] << 1) | (this.h[6] << 14)) & 0xffff; + this.h[5] = ((this.h[6] >>> 2) | (this.h[7] << 11)) & 0xffff; + this.h[6] = ((this.h[7] >>> 5) | (this.h[8] << 8)) & 0xffff; + this.h[7] = ((this.h[8] >>> 8) | (this.h[9] << 5)) & 0xffff; - f = this.h[0] + this.pad[0]; - this.h[0] = f & 0xffff; - for (i = 1; i < 8; i++) { - f = (((this.h[i] + this.pad[i]) | 0) + (f >>> 16)) | 0; - this.h[i] = f & 0xffff; - } + f = this.h[0] + this.pad[0]; + this.h[0] = f & 0xffff; + for (i = 1; i < 8; i++) { + f = (((this.h[i] + this.pad[i]) | 0) + (f >>> 16)) | 0; + this.h[i] = f & 0xffff; + } - mac[macpos+ 0] = (this.h[0] >>> 0) & 0xff; - mac[macpos+ 1] = (this.h[0] >>> 8) & 0xff; - mac[macpos+ 2] = (this.h[1] >>> 0) & 0xff; - mac[macpos+ 3] = (this.h[1] >>> 8) & 0xff; - mac[macpos+ 4] = (this.h[2] >>> 0) & 0xff; - mac[macpos+ 5] = (this.h[2] >>> 8) & 0xff; - mac[macpos+ 6] = (this.h[3] >>> 0) & 0xff; - mac[macpos+ 7] = (this.h[3] >>> 8) & 0xff; - mac[macpos+ 8] = (this.h[4] >>> 0) & 0xff; - mac[macpos+ 9] = (this.h[4] >>> 8) & 0xff; - mac[macpos+10] = (this.h[5] >>> 0) & 0xff; - mac[macpos+11] = (this.h[5] >>> 8) & 0xff; - mac[macpos+12] = (this.h[6] >>> 0) & 0xff; - mac[macpos+13] = (this.h[6] >>> 8) & 0xff; - mac[macpos+14] = (this.h[7] >>> 0) & 0xff; - mac[macpos+15] = (this.h[7] >>> 8) & 0xff; + mac[macpos + 0] = (this.h[0] >>> 0) & 0xff; + mac[macpos + 1] = (this.h[0] >>> 8) & 0xff; + mac[macpos + 2] = (this.h[1] >>> 0) & 0xff; + mac[macpos + 3] = (this.h[1] >>> 8) & 0xff; + mac[macpos + 4] = (this.h[2] >>> 0) & 0xff; + mac[macpos + 5] = (this.h[2] >>> 8) & 0xff; + mac[macpos + 6] = (this.h[3] >>> 0) & 0xff; + mac[macpos + 7] = (this.h[3] >>> 8) & 0xff; + mac[macpos + 8] = (this.h[4] >>> 0) & 0xff; + mac[macpos + 9] = (this.h[4] >>> 8) & 0xff; + mac[macpos + 10] = (this.h[5] >>> 0) & 0xff; + mac[macpos + 11] = (this.h[5] >>> 8) & 0xff; + mac[macpos + 12] = (this.h[6] >>> 0) & 0xff; + mac[macpos + 13] = (this.h[6] >>> 8) & 0xff; + mac[macpos + 14] = (this.h[7] >>> 0) & 0xff; + mac[macpos + 15] = (this.h[7] >>> 8) & 0xff; }; -poly1305.prototype.update = function(m, mpos, bytes) { - var i, want; +poly1305.prototype.update = function (m, mpos, bytes) { + var i, want; - if (this.leftover) { - want = (16 - this.leftover); - if (want > bytes) - want = bytes; - for (i = 0; i < want; i++) - this.buffer[this.leftover + i] = m[mpos+i]; - bytes -= want; - mpos += want; - this.leftover += want; - if (this.leftover < 16) - return; - this.blocks(this.buffer, 0, 16); - this.leftover = 0; - } + if (this.leftover) { + want = (16 - this.leftover); + if (want > bytes) + want = bytes; + for (i = 0; i < want; i++) + this.buffer[this.leftover + i] = m[mpos + i]; + bytes -= want; + mpos += want; + this.leftover += want; + if (this.leftover < 16) + return; + this.blocks(this.buffer, 0, 16); + this.leftover = 0; + } - if (bytes >= 16) { - want = bytes - (bytes % 16); - this.blocks(m, mpos, want); - mpos += want; - bytes -= want; - } + if (bytes >= 16) { + want = bytes - (bytes % 16); + this.blocks(m, mpos, want); + mpos += want; + bytes -= want; + } - if (bytes) { - for (i = 0; i < bytes; i++) - this.buffer[this.leftover + i] = m[mpos+i]; - this.leftover += bytes; - } + if (bytes) { + for (i = 0; i < bytes; i++) + this.buffer[this.leftover + i] = m[mpos + i]; + this.leftover += bytes; + } }; function crypto_onetimeauth(out, outpos, m, mpos, n, k) { - var s = new poly1305(k); - s.update(m, mpos, n); - s.finish(out, outpos); - return 0; + var s = new poly1305(k); + s.update(m, mpos, n); + s.finish(out, outpos); + return 0; } function crypto_onetimeauth_verify(h, hpos, m, mpos, n, k) { - var x = new Uint8Array(16); - crypto_onetimeauth(x,0,m,mpos,n,k); - return crypto_verify_16(h,hpos,x,0); + var x = new Uint8Array(16); + crypto_onetimeauth(x, 0, m, mpos, n, k); + return crypto_verify_16(h, hpos, x, 0); } -function crypto_secretbox(c,m,d,n,k) { - var i; - if (d < 32) return -1; - crypto_stream_xor(c,0,m,0,d,n,k); - crypto_onetimeauth(c, 16, c, 32, d - 32, c); - for (i = 0; i < 16; i++) c[i] = 0; - return 0; +function crypto_secretbox(c, m, d, n, k) { + var i; + if (d < 32) return -1; + crypto_stream_xor(c, 0, m, 0, d, n, k); + crypto_onetimeauth(c, 16, c, 32, d - 32, c); + for (i = 0; i < 16; i++) c[i] = 0; + return 0; } -function crypto_secretbox_open(m,c,d,n,k) { - var i; - var x = new Uint8Array(32); - if (d < 32) return -1; - crypto_stream(x,0,32,n,k); - if (crypto_onetimeauth_verify(c, 16,c, 32,d - 32,x) !== 0) return -1; - crypto_stream_xor(m,0,c,0,d,n,k); - for (i = 0; i < 32; i++) m[i] = 0; - return 0; +function crypto_secretbox_open(m, c, d, n, k) { + var i; + var x = new Uint8Array(32); + if (d < 32) return -1; + crypto_stream(x, 0, 32, n, k); + if (crypto_onetimeauth_verify(c, 16, c, 32, d - 32, x) !== 0) return -1; + crypto_stream_xor(m, 0, c, 0, d, n, k); + for (i = 0; i < 32; i++) m[i] = 0; + return 0; } function set25519(r, a) { - var i; - for (i = 0; i < 16; i++) r[i] = a[i]|0; + var i; + for (i = 0; i < 16; i++) r[i] = a[i] | 0; } function car25519(o) { - var i, v, c = 1; - for (i = 0; i < 16; i++) { - v = o[i] + c + 65535; - c = Math.floor(v / 65536); - o[i] = v - c * 65536; - } - o[0] += c-1 + 37 * (c-1); + var i, v, c = 1; + for (i = 0; i < 16; i++) { + v = o[i] + c + 65535; + c = Math.floor(v / 65536); + o[i] = v - c * 65536; + } + o[0] += c - 1 + 37 * (c - 1); } function sel25519(p, q, b) { - var t, c = ~(b-1); - for (var i = 0; i < 16; i++) { - t = c & (p[i] ^ q[i]); - p[i] ^= t; - q[i] ^= t; - } + var t, c = ~(b - 1); + for (var i = 0; i < 16; i++) { + t = c & (p[i] ^ q[i]); + p[i] ^= t; + q[i] ^= t; + } } function pack25519(o, n) { - var i, j, b; - var m = gf(), t = gf(); - for (i = 0; i < 16; i++) t[i] = n[i]; - car25519(t); - car25519(t); - car25519(t); - for (j = 0; j < 2; j++) { - m[0] = t[0] - 0xffed; - for (i = 1; i < 15; i++) { - m[i] = t[i] - 0xffff - ((m[i-1]>>16) & 1); - m[i-1] &= 0xffff; - } - m[15] = t[15] - 0x7fff - ((m[14]>>16) & 1); - b = (m[15]>>16) & 1; - m[14] &= 0xffff; - sel25519(t, m, 1-b); - } - for (i = 0; i < 16; i++) { - o[2*i] = t[i] & 0xff; - o[2*i+1] = t[i]>>8; - } + var i, j, b; + var m = gf(), t = gf(); + for (i = 0; i < 16; i++) t[i] = n[i]; + car25519(t); + car25519(t); + car25519(t); + for (j = 0; j < 2; j++) { + m[0] = t[0] - 0xffed; + for (i = 1; i < 15; i++) { + m[i] = t[i] - 0xffff - ((m[i - 1] >> 16) & 1); + m[i - 1] &= 0xffff; + } + m[15] = t[15] - 0x7fff - ((m[14] >> 16) & 1); + b = (m[15] >> 16) & 1; + m[14] &= 0xffff; + sel25519(t, m, 1 - b); + } + for (i = 0; i < 16; i++) { + o[2 * i] = t[i] & 0xff; + o[2 * i + 1] = t[i] >> 8; + } } function neq25519(a, b) { - var c = new Uint8Array(32), d = new Uint8Array(32); - pack25519(c, a); - pack25519(d, b); - return crypto_verify_32(c, 0, d, 0); + var c = new Uint8Array(32), d = new Uint8Array(32); + pack25519(c, a); + pack25519(d, b); + return crypto_verify_32(c, 0, d, 0); } function par25519(a) { - var d = new Uint8Array(32); - pack25519(d, a); - return d[0] & 1; + var d = new Uint8Array(32); + pack25519(d, a); + return d[0] & 1; } function unpack25519(o, n) { - var i; - for (i = 0; i < 16; i++) o[i] = n[2*i] + (n[2*i+1] << 8); - o[15] &= 0x7fff; + var i; + for (i = 0; i < 16; i++) o[i] = n[2 * i] + (n[2 * i + 1] << 8); + o[15] &= 0x7fff; } function A(o, a, b) { - for (var i = 0; i < 16; i++) o[i] = a[i] + b[i]; + for (var i = 0; i < 16; i++) o[i] = a[i] + b[i]; } function Z(o, a, b) { - for (var i = 0; i < 16; i++) o[i] = a[i] - b[i]; + for (var i = 0; i < 16; i++) o[i] = a[i] - b[i]; } function M(o, a, b) { - var v, c, - t0 = 0, t1 = 0, t2 = 0, t3 = 0, t4 = 0, t5 = 0, t6 = 0, t7 = 0, - t8 = 0, t9 = 0, t10 = 0, t11 = 0, t12 = 0, t13 = 0, t14 = 0, t15 = 0, - t16 = 0, t17 = 0, t18 = 0, t19 = 0, t20 = 0, t21 = 0, t22 = 0, t23 = 0, - t24 = 0, t25 = 0, t26 = 0, t27 = 0, t28 = 0, t29 = 0, t30 = 0, - b0 = b[0], - b1 = b[1], - b2 = b[2], - b3 = b[3], - b4 = b[4], - b5 = b[5], - b6 = b[6], - b7 = b[7], - b8 = b[8], - b9 = b[9], - b10 = b[10], - b11 = b[11], - b12 = b[12], - b13 = b[13], - b14 = b[14], - b15 = b[15]; + var v, c, + t0 = 0, t1 = 0, t2 = 0, t3 = 0, t4 = 0, t5 = 0, t6 = 0, t7 = 0, + t8 = 0, t9 = 0, t10 = 0, t11 = 0, t12 = 0, t13 = 0, t14 = 0, t15 = 0, + t16 = 0, t17 = 0, t18 = 0, t19 = 0, t20 = 0, t21 = 0, t22 = 0, t23 = 0, + t24 = 0, t25 = 0, t26 = 0, t27 = 0, t28 = 0, t29 = 0, t30 = 0, + b0 = b[0], + b1 = b[1], + b2 = b[2], + b3 = b[3], + b4 = b[4], + b5 = b[5], + b6 = b[6], + b7 = b[7], + b8 = b[8], + b9 = b[9], + b10 = b[10], + b11 = b[11], + b12 = b[12], + b13 = b[13], + b14 = b[14], + b15 = b[15]; - v = a[0]; - t0 += v * b0; - t1 += v * b1; - t2 += v * b2; - t3 += v * b3; - t4 += v * b4; - t5 += v * b5; - t6 += v * b6; - t7 += v * b7; - t8 += v * b8; - t9 += v * b9; - t10 += v * b10; - t11 += v * b11; - t12 += v * b12; - t13 += v * b13; - t14 += v * b14; - t15 += v * b15; - v = a[1]; - t1 += v * b0; - t2 += v * b1; - t3 += v * b2; - t4 += v * b3; - t5 += v * b4; - t6 += v * b5; - t7 += v * b6; - t8 += v * b7; - t9 += v * b8; - t10 += v * b9; - t11 += v * b10; - t12 += v * b11; - t13 += v * b12; - t14 += v * b13; - t15 += v * b14; - t16 += v * b15; - v = a[2]; - t2 += v * b0; - t3 += v * b1; - t4 += v * b2; - t5 += v * b3; - t6 += v * b4; - t7 += v * b5; - t8 += v * b6; - t9 += v * b7; - t10 += v * b8; - t11 += v * b9; - t12 += v * b10; - t13 += v * b11; - t14 += v * b12; - t15 += v * b13; - t16 += v * b14; - t17 += v * b15; - v = a[3]; - t3 += v * b0; - t4 += v * b1; - t5 += v * b2; - t6 += v * b3; - t7 += v * b4; - t8 += v * b5; - t9 += v * b6; - t10 += v * b7; - t11 += v * b8; - t12 += v * b9; - t13 += v * b10; - t14 += v * b11; - t15 += v * b12; - t16 += v * b13; - t17 += v * b14; - t18 += v * b15; - v = a[4]; - t4 += v * b0; - t5 += v * b1; - t6 += v * b2; - t7 += v * b3; - t8 += v * b4; - t9 += v * b5; - t10 += v * b6; - t11 += v * b7; - t12 += v * b8; - t13 += v * b9; - t14 += v * b10; - t15 += v * b11; - t16 += v * b12; - t17 += v * b13; - t18 += v * b14; - t19 += v * b15; - v = a[5]; - t5 += v * b0; - t6 += v * b1; - t7 += v * b2; - t8 += v * b3; - t9 += v * b4; - t10 += v * b5; - t11 += v * b6; - t12 += v * b7; - t13 += v * b8; - t14 += v * b9; - t15 += v * b10; - t16 += v * b11; - t17 += v * b12; - t18 += v * b13; - t19 += v * b14; - t20 += v * b15; - v = a[6]; - t6 += v * b0; - t7 += v * b1; - t8 += v * b2; - t9 += v * b3; - t10 += v * b4; - t11 += v * b5; - t12 += v * b6; - t13 += v * b7; - t14 += v * b8; - t15 += v * b9; - t16 += v * b10; - t17 += v * b11; - t18 += v * b12; - t19 += v * b13; - t20 += v * b14; - t21 += v * b15; - v = a[7]; - t7 += v * b0; - t8 += v * b1; - t9 += v * b2; - t10 += v * b3; - t11 += v * b4; - t12 += v * b5; - t13 += v * b6; - t14 += v * b7; - t15 += v * b8; - t16 += v * b9; - t17 += v * b10; - t18 += v * b11; - t19 += v * b12; - t20 += v * b13; - t21 += v * b14; - t22 += v * b15; - v = a[8]; - t8 += v * b0; - t9 += v * b1; - t10 += v * b2; - t11 += v * b3; - t12 += v * b4; - t13 += v * b5; - t14 += v * b6; - t15 += v * b7; - t16 += v * b8; - t17 += v * b9; - t18 += v * b10; - t19 += v * b11; - t20 += v * b12; - t21 += v * b13; - t22 += v * b14; - t23 += v * b15; - v = a[9]; - t9 += v * b0; - t10 += v * b1; - t11 += v * b2; - t12 += v * b3; - t13 += v * b4; - t14 += v * b5; - t15 += v * b6; - t16 += v * b7; - t17 += v * b8; - t18 += v * b9; - t19 += v * b10; - t20 += v * b11; - t21 += v * b12; - t22 += v * b13; - t23 += v * b14; - t24 += v * b15; - v = a[10]; - t10 += v * b0; - t11 += v * b1; - t12 += v * b2; - t13 += v * b3; - t14 += v * b4; - t15 += v * b5; - t16 += v * b6; - t17 += v * b7; - t18 += v * b8; - t19 += v * b9; - t20 += v * b10; - t21 += v * b11; - t22 += v * b12; - t23 += v * b13; - t24 += v * b14; - t25 += v * b15; - v = a[11]; - t11 += v * b0; - t12 += v * b1; - t13 += v * b2; - t14 += v * b3; - t15 += v * b4; - t16 += v * b5; - t17 += v * b6; - t18 += v * b7; - t19 += v * b8; - t20 += v * b9; - t21 += v * b10; - t22 += v * b11; - t23 += v * b12; - t24 += v * b13; - t25 += v * b14; - t26 += v * b15; - v = a[12]; - t12 += v * b0; - t13 += v * b1; - t14 += v * b2; - t15 += v * b3; - t16 += v * b4; - t17 += v * b5; - t18 += v * b6; - t19 += v * b7; - t20 += v * b8; - t21 += v * b9; - t22 += v * b10; - t23 += v * b11; - t24 += v * b12; - t25 += v * b13; - t26 += v * b14; - t27 += v * b15; - v = a[13]; - t13 += v * b0; - t14 += v * b1; - t15 += v * b2; - t16 += v * b3; - t17 += v * b4; - t18 += v * b5; - t19 += v * b6; - t20 += v * b7; - t21 += v * b8; - t22 += v * b9; - t23 += v * b10; - t24 += v * b11; - t25 += v * b12; - t26 += v * b13; - t27 += v * b14; - t28 += v * b15; - v = a[14]; - t14 += v * b0; - t15 += v * b1; - t16 += v * b2; - t17 += v * b3; - t18 += v * b4; - t19 += v * b5; - t20 += v * b6; - t21 += v * b7; - t22 += v * b8; - t23 += v * b9; - t24 += v * b10; - t25 += v * b11; - t26 += v * b12; - t27 += v * b13; - t28 += v * b14; - t29 += v * b15; - v = a[15]; - t15 += v * b0; - t16 += v * b1; - t17 += v * b2; - t18 += v * b3; - t19 += v * b4; - t20 += v * b5; - t21 += v * b6; - t22 += v * b7; - t23 += v * b8; - t24 += v * b9; - t25 += v * b10; - t26 += v * b11; - t27 += v * b12; - t28 += v * b13; - t29 += v * b14; - t30 += v * b15; + v = a[0]; + t0 += v * b0; + t1 += v * b1; + t2 += v * b2; + t3 += v * b3; + t4 += v * b4; + t5 += v * b5; + t6 += v * b6; + t7 += v * b7; + t8 += v * b8; + t9 += v * b9; + t10 += v * b10; + t11 += v * b11; + t12 += v * b12; + t13 += v * b13; + t14 += v * b14; + t15 += v * b15; + v = a[1]; + t1 += v * b0; + t2 += v * b1; + t3 += v * b2; + t4 += v * b3; + t5 += v * b4; + t6 += v * b5; + t7 += v * b6; + t8 += v * b7; + t9 += v * b8; + t10 += v * b9; + t11 += v * b10; + t12 += v * b11; + t13 += v * b12; + t14 += v * b13; + t15 += v * b14; + t16 += v * b15; + v = a[2]; + t2 += v * b0; + t3 += v * b1; + t4 += v * b2; + t5 += v * b3; + t6 += v * b4; + t7 += v * b5; + t8 += v * b6; + t9 += v * b7; + t10 += v * b8; + t11 += v * b9; + t12 += v * b10; + t13 += v * b11; + t14 += v * b12; + t15 += v * b13; + t16 += v * b14; + t17 += v * b15; + v = a[3]; + t3 += v * b0; + t4 += v * b1; + t5 += v * b2; + t6 += v * b3; + t7 += v * b4; + t8 += v * b5; + t9 += v * b6; + t10 += v * b7; + t11 += v * b8; + t12 += v * b9; + t13 += v * b10; + t14 += v * b11; + t15 += v * b12; + t16 += v * b13; + t17 += v * b14; + t18 += v * b15; + v = a[4]; + t4 += v * b0; + t5 += v * b1; + t6 += v * b2; + t7 += v * b3; + t8 += v * b4; + t9 += v * b5; + t10 += v * b6; + t11 += v * b7; + t12 += v * b8; + t13 += v * b9; + t14 += v * b10; + t15 += v * b11; + t16 += v * b12; + t17 += v * b13; + t18 += v * b14; + t19 += v * b15; + v = a[5]; + t5 += v * b0; + t6 += v * b1; + t7 += v * b2; + t8 += v * b3; + t9 += v * b4; + t10 += v * b5; + t11 += v * b6; + t12 += v * b7; + t13 += v * b8; + t14 += v * b9; + t15 += v * b10; + t16 += v * b11; + t17 += v * b12; + t18 += v * b13; + t19 += v * b14; + t20 += v * b15; + v = a[6]; + t6 += v * b0; + t7 += v * b1; + t8 += v * b2; + t9 += v * b3; + t10 += v * b4; + t11 += v * b5; + t12 += v * b6; + t13 += v * b7; + t14 += v * b8; + t15 += v * b9; + t16 += v * b10; + t17 += v * b11; + t18 += v * b12; + t19 += v * b13; + t20 += v * b14; + t21 += v * b15; + v = a[7]; + t7 += v * b0; + t8 += v * b1; + t9 += v * b2; + t10 += v * b3; + t11 += v * b4; + t12 += v * b5; + t13 += v * b6; + t14 += v * b7; + t15 += v * b8; + t16 += v * b9; + t17 += v * b10; + t18 += v * b11; + t19 += v * b12; + t20 += v * b13; + t21 += v * b14; + t22 += v * b15; + v = a[8]; + t8 += v * b0; + t9 += v * b1; + t10 += v * b2; + t11 += v * b3; + t12 += v * b4; + t13 += v * b5; + t14 += v * b6; + t15 += v * b7; + t16 += v * b8; + t17 += v * b9; + t18 += v * b10; + t19 += v * b11; + t20 += v * b12; + t21 += v * b13; + t22 += v * b14; + t23 += v * b15; + v = a[9]; + t9 += v * b0; + t10 += v * b1; + t11 += v * b2; + t12 += v * b3; + t13 += v * b4; + t14 += v * b5; + t15 += v * b6; + t16 += v * b7; + t17 += v * b8; + t18 += v * b9; + t19 += v * b10; + t20 += v * b11; + t21 += v * b12; + t22 += v * b13; + t23 += v * b14; + t24 += v * b15; + v = a[10]; + t10 += v * b0; + t11 += v * b1; + t12 += v * b2; + t13 += v * b3; + t14 += v * b4; + t15 += v * b5; + t16 += v * b6; + t17 += v * b7; + t18 += v * b8; + t19 += v * b9; + t20 += v * b10; + t21 += v * b11; + t22 += v * b12; + t23 += v * b13; + t24 += v * b14; + t25 += v * b15; + v = a[11]; + t11 += v * b0; + t12 += v * b1; + t13 += v * b2; + t14 += v * b3; + t15 += v * b4; + t16 += v * b5; + t17 += v * b6; + t18 += v * b7; + t19 += v * b8; + t20 += v * b9; + t21 += v * b10; + t22 += v * b11; + t23 += v * b12; + t24 += v * b13; + t25 += v * b14; + t26 += v * b15; + v = a[12]; + t12 += v * b0; + t13 += v * b1; + t14 += v * b2; + t15 += v * b3; + t16 += v * b4; + t17 += v * b5; + t18 += v * b6; + t19 += v * b7; + t20 += v * b8; + t21 += v * b9; + t22 += v * b10; + t23 += v * b11; + t24 += v * b12; + t25 += v * b13; + t26 += v * b14; + t27 += v * b15; + v = a[13]; + t13 += v * b0; + t14 += v * b1; + t15 += v * b2; + t16 += v * b3; + t17 += v * b4; + t18 += v * b5; + t19 += v * b6; + t20 += v * b7; + t21 += v * b8; + t22 += v * b9; + t23 += v * b10; + t24 += v * b11; + t25 += v * b12; + t26 += v * b13; + t27 += v * b14; + t28 += v * b15; + v = a[14]; + t14 += v * b0; + t15 += v * b1; + t16 += v * b2; + t17 += v * b3; + t18 += v * b4; + t19 += v * b5; + t20 += v * b6; + t21 += v * b7; + t22 += v * b8; + t23 += v * b9; + t24 += v * b10; + t25 += v * b11; + t26 += v * b12; + t27 += v * b13; + t28 += v * b14; + t29 += v * b15; + v = a[15]; + t15 += v * b0; + t16 += v * b1; + t17 += v * b2; + t18 += v * b3; + t19 += v * b4; + t20 += v * b5; + t21 += v * b6; + t22 += v * b7; + t23 += v * b8; + t24 += v * b9; + t25 += v * b10; + t26 += v * b11; + t27 += v * b12; + t28 += v * b13; + t29 += v * b14; + t30 += v * b15; - t0 += 38 * t16; - t1 += 38 * t17; - t2 += 38 * t18; - t3 += 38 * t19; - t4 += 38 * t20; - t5 += 38 * t21; - t6 += 38 * t22; - t7 += 38 * t23; - t8 += 38 * t24; - t9 += 38 * t25; - t10 += 38 * t26; - t11 += 38 * t27; - t12 += 38 * t28; - t13 += 38 * t29; - t14 += 38 * t30; - // t15 left as is + t0 += 38 * t16; + t1 += 38 * t17; + t2 += 38 * t18; + t3 += 38 * t19; + t4 += 38 * t20; + t5 += 38 * t21; + t6 += 38 * t22; + t7 += 38 * t23; + t8 += 38 * t24; + t9 += 38 * t25; + t10 += 38 * t26; + t11 += 38 * t27; + t12 += 38 * t28; + t13 += 38 * t29; + t14 += 38 * t30; + // t15 left as is - // first car - c = 1; - v = t0 + c + 65535; c = Math.floor(v / 65536); t0 = v - c * 65536; - v = t1 + c + 65535; c = Math.floor(v / 65536); t1 = v - c * 65536; - v = t2 + c + 65535; c = Math.floor(v / 65536); t2 = v - c * 65536; - v = t3 + c + 65535; c = Math.floor(v / 65536); t3 = v - c * 65536; - v = t4 + c + 65535; c = Math.floor(v / 65536); t4 = v - c * 65536; - v = t5 + c + 65535; c = Math.floor(v / 65536); t5 = v - c * 65536; - v = t6 + c + 65535; c = Math.floor(v / 65536); t6 = v - c * 65536; - v = t7 + c + 65535; c = Math.floor(v / 65536); t7 = v - c * 65536; - v = t8 + c + 65535; c = Math.floor(v / 65536); t8 = v - c * 65536; - v = t9 + c + 65535; c = Math.floor(v / 65536); t9 = v - c * 65536; - v = t10 + c + 65535; c = Math.floor(v / 65536); t10 = v - c * 65536; - v = t11 + c + 65535; c = Math.floor(v / 65536); t11 = v - c * 65536; - v = t12 + c + 65535; c = Math.floor(v / 65536); t12 = v - c * 65536; - v = t13 + c + 65535; c = Math.floor(v / 65536); t13 = v - c * 65536; - v = t14 + c + 65535; c = Math.floor(v / 65536); t14 = v - c * 65536; - v = t15 + c + 65535; c = Math.floor(v / 65536); t15 = v - c * 65536; - t0 += c-1 + 37 * (c-1); + // first car + c = 1; + v = t0 + c + 65535; c = Math.floor(v / 65536); t0 = v - c * 65536; + v = t1 + c + 65535; c = Math.floor(v / 65536); t1 = v - c * 65536; + v = t2 + c + 65535; c = Math.floor(v / 65536); t2 = v - c * 65536; + v = t3 + c + 65535; c = Math.floor(v / 65536); t3 = v - c * 65536; + v = t4 + c + 65535; c = Math.floor(v / 65536); t4 = v - c * 65536; + v = t5 + c + 65535; c = Math.floor(v / 65536); t5 = v - c * 65536; + v = t6 + c + 65535; c = Math.floor(v / 65536); t6 = v - c * 65536; + v = t7 + c + 65535; c = Math.floor(v / 65536); t7 = v - c * 65536; + v = t8 + c + 65535; c = Math.floor(v / 65536); t8 = v - c * 65536; + v = t9 + c + 65535; c = Math.floor(v / 65536); t9 = v - c * 65536; + v = t10 + c + 65535; c = Math.floor(v / 65536); t10 = v - c * 65536; + v = t11 + c + 65535; c = Math.floor(v / 65536); t11 = v - c * 65536; + v = t12 + c + 65535; c = Math.floor(v / 65536); t12 = v - c * 65536; + v = t13 + c + 65535; c = Math.floor(v / 65536); t13 = v - c * 65536; + v = t14 + c + 65535; c = Math.floor(v / 65536); t14 = v - c * 65536; + v = t15 + c + 65535; c = Math.floor(v / 65536); t15 = v - c * 65536; + t0 += c - 1 + 37 * (c - 1); - // second car - c = 1; - v = t0 + c + 65535; c = Math.floor(v / 65536); t0 = v - c * 65536; - v = t1 + c + 65535; c = Math.floor(v / 65536); t1 = v - c * 65536; - v = t2 + c + 65535; c = Math.floor(v / 65536); t2 = v - c * 65536; - v = t3 + c + 65535; c = Math.floor(v / 65536); t3 = v - c * 65536; - v = t4 + c + 65535; c = Math.floor(v / 65536); t4 = v - c * 65536; - v = t5 + c + 65535; c = Math.floor(v / 65536); t5 = v - c * 65536; - v = t6 + c + 65535; c = Math.floor(v / 65536); t6 = v - c * 65536; - v = t7 + c + 65535; c = Math.floor(v / 65536); t7 = v - c * 65536; - v = t8 + c + 65535; c = Math.floor(v / 65536); t8 = v - c * 65536; - v = t9 + c + 65535; c = Math.floor(v / 65536); t9 = v - c * 65536; - v = t10 + c + 65535; c = Math.floor(v / 65536); t10 = v - c * 65536; - v = t11 + c + 65535; c = Math.floor(v / 65536); t11 = v - c * 65536; - v = t12 + c + 65535; c = Math.floor(v / 65536); t12 = v - c * 65536; - v = t13 + c + 65535; c = Math.floor(v / 65536); t13 = v - c * 65536; - v = t14 + c + 65535; c = Math.floor(v / 65536); t14 = v - c * 65536; - v = t15 + c + 65535; c = Math.floor(v / 65536); t15 = v - c * 65536; - t0 += c-1 + 37 * (c-1); + // second car + c = 1; + v = t0 + c + 65535; c = Math.floor(v / 65536); t0 = v - c * 65536; + v = t1 + c + 65535; c = Math.floor(v / 65536); t1 = v - c * 65536; + v = t2 + c + 65535; c = Math.floor(v / 65536); t2 = v - c * 65536; + v = t3 + c + 65535; c = Math.floor(v / 65536); t3 = v - c * 65536; + v = t4 + c + 65535; c = Math.floor(v / 65536); t4 = v - c * 65536; + v = t5 + c + 65535; c = Math.floor(v / 65536); t5 = v - c * 65536; + v = t6 + c + 65535; c = Math.floor(v / 65536); t6 = v - c * 65536; + v = t7 + c + 65535; c = Math.floor(v / 65536); t7 = v - c * 65536; + v = t8 + c + 65535; c = Math.floor(v / 65536); t8 = v - c * 65536; + v = t9 + c + 65535; c = Math.floor(v / 65536); t9 = v - c * 65536; + v = t10 + c + 65535; c = Math.floor(v / 65536); t10 = v - c * 65536; + v = t11 + c + 65535; c = Math.floor(v / 65536); t11 = v - c * 65536; + v = t12 + c + 65535; c = Math.floor(v / 65536); t12 = v - c * 65536; + v = t13 + c + 65535; c = Math.floor(v / 65536); t13 = v - c * 65536; + v = t14 + c + 65535; c = Math.floor(v / 65536); t14 = v - c * 65536; + v = t15 + c + 65535; c = Math.floor(v / 65536); t15 = v - c * 65536; + t0 += c - 1 + 37 * (c - 1); - o[ 0] = t0; - o[ 1] = t1; - o[ 2] = t2; - o[ 3] = t3; - o[ 4] = t4; - o[ 5] = t5; - o[ 6] = t6; - o[ 7] = t7; - o[ 8] = t8; - o[ 9] = t9; - o[10] = t10; - o[11] = t11; - o[12] = t12; - o[13] = t13; - o[14] = t14; - o[15] = t15; + o[0] = t0; + o[1] = t1; + o[2] = t2; + o[3] = t3; + o[4] = t4; + o[5] = t5; + o[6] = t6; + o[7] = t7; + o[8] = t8; + o[9] = t9; + o[10] = t10; + o[11] = t11; + o[12] = t12; + o[13] = t13; + o[14] = t14; + o[15] = t15; } function S(o, a) { - M(o, a, a); + M(o, a, a); } function inv25519(o, i) { - var c = gf(); - var a; - for (a = 0; a < 16; a++) c[a] = i[a]; - for (a = 253; a >= 0; a--) { - S(c, c); - if(a !== 2 && a !== 4) M(c, c, i); - } - for (a = 0; a < 16; a++) o[a] = c[a]; + var c = gf(); + var a; + for (a = 0; a < 16; a++) c[a] = i[a]; + for (a = 253; a >= 0; a--) { + S(c, c); + if (a !== 2 && a !== 4) M(c, c, i); + } + for (a = 0; a < 16; a++) o[a] = c[a]; } function pow2523(o, i) { - var c = gf(); - var a; - for (a = 0; a < 16; a++) c[a] = i[a]; - for (a = 250; a >= 0; a--) { - S(c, c); - if(a !== 1) M(c, c, i); - } - for (a = 0; a < 16; a++) o[a] = c[a]; + var c = gf(); + var a; + for (a = 0; a < 16; a++) c[a] = i[a]; + for (a = 250; a >= 0; a--) { + S(c, c); + if (a !== 1) M(c, c, i); + } + for (a = 0; a < 16; a++) o[a] = c[a]; } function crypto_scalarmult(q, n, p) { - var z = new Uint8Array(32); - var x = new Float64Array(80), r, i; - var a = gf(), b = gf(), c = gf(), - d = gf(), e = gf(), f = gf(); - for (i = 0; i < 31; i++) z[i] = n[i]; - z[31]=(n[31]&127)|64; - z[0]&=248; - unpack25519(x,p); - for (i = 0; i < 16; i++) { - b[i]=x[i]; - d[i]=a[i]=c[i]=0; - } - a[0]=d[0]=1; - for (i=254; i>=0; --i) { - r=(z[i>>>3]>>>(i&7))&1; - sel25519(a,b,r); - sel25519(c,d,r); - A(e,a,c); - Z(a,a,c); - A(c,b,d); - Z(b,b,d); - S(d,e); - S(f,a); - M(a,c,a); - M(c,b,e); - A(e,a,c); - Z(a,a,c); - S(b,a); - Z(c,d,f); - M(a,c,_121665); - A(a,a,d); - M(c,c,a); - M(a,d,f); - M(d,b,x); - S(b,e); - sel25519(a,b,r); - sel25519(c,d,r); - } - for (i = 0; i < 16; i++) { - x[i+16]=a[i]; - x[i+32]=c[i]; - x[i+48]=b[i]; - x[i+64]=d[i]; - } - var x32 = x.subarray(32); - var x16 = x.subarray(16); - inv25519(x32,x32); - M(x16,x16,x32); - pack25519(q,x16); - return 0; + var z = new Uint8Array(32); + var x = new Float64Array(80), r, i; + var a = gf(), b = gf(), c = gf(), + d = gf(), e = gf(), f = gf(); + for (i = 0; i < 31; i++) z[i] = n[i]; + z[31] = (n[31] & 127) | 64; + z[0] &= 248; + unpack25519(x, p); + for (i = 0; i < 16; i++) { + b[i] = x[i]; + d[i] = a[i] = c[i] = 0; + } + a[0] = d[0] = 1; + for (i = 254; i >= 0; --i) { + r = (z[i >>> 3] >>> (i & 7)) & 1; + sel25519(a, b, r); + sel25519(c, d, r); + A(e, a, c); + Z(a, a, c); + A(c, b, d); + Z(b, b, d); + S(d, e); + S(f, a); + M(a, c, a); + M(c, b, e); + A(e, a, c); + Z(a, a, c); + S(b, a); + Z(c, d, f); + M(a, c, _121665); + A(a, a, d); + M(c, c, a); + M(a, d, f); + M(d, b, x); + S(b, e); + sel25519(a, b, r); + sel25519(c, d, r); + } + for (i = 0; i < 16; i++) { + x[i + 16] = a[i]; + x[i + 32] = c[i]; + x[i + 48] = b[i]; + x[i + 64] = d[i]; + } + var x32 = x.subarray(32); + var x16 = x.subarray(16); + inv25519(x32, x32); + M(x16, x16, x32); + pack25519(q, x16); + return 0; } function crypto_scalarmult_base(q, n) { - return crypto_scalarmult(q, n, _9); + return crypto_scalarmult(q, n, _9); } function crypto_box_keypair(y, x) { - randombytes(x, 32); - return crypto_scalarmult_base(y, x); + randombytes(x, 32); + return crypto_scalarmult_base(y, x); } function crypto_box_beforenm(k, y, x) { - var s = new Uint8Array(32); - crypto_scalarmult(s, x, y); - return crypto_core_hsalsa20(k, _0, s, sigma); + var s = new Uint8Array(32); + crypto_scalarmult(s, x, y); + return crypto_core_hsalsa20(k, _0, s, sigma); } var crypto_box_afternm = crypto_secretbox; var crypto_box_open_afternm = crypto_secretbox_open; function crypto_box(c, m, d, n, y, x) { - var k = new Uint8Array(32); - crypto_box_beforenm(k, y, x); - return crypto_box_afternm(c, m, d, n, k); + var k = new Uint8Array(32); + crypto_box_beforenm(k, y, x); + return crypto_box_afternm(c, m, d, n, k); } function crypto_box_open(m, c, d, n, y, x) { - var k = new Uint8Array(32); - crypto_box_beforenm(k, y, x); - return crypto_box_open_afternm(m, c, d, n, k); + var k = new Uint8Array(32); + crypto_box_beforenm(k, y, x); + return crypto_box_open_afternm(m, c, d, n, k); } var K = [ - 0x428a2f98, 0xd728ae22, 0x71374491, 0x23ef65cd, - 0xb5c0fbcf, 0xec4d3b2f, 0xe9b5dba5, 0x8189dbbc, - 0x3956c25b, 0xf348b538, 0x59f111f1, 0xb605d019, - 0x923f82a4, 0xaf194f9b, 0xab1c5ed5, 0xda6d8118, - 0xd807aa98, 0xa3030242, 0x12835b01, 0x45706fbe, - 0x243185be, 0x4ee4b28c, 0x550c7dc3, 0xd5ffb4e2, - 0x72be5d74, 0xf27b896f, 0x80deb1fe, 0x3b1696b1, - 0x9bdc06a7, 0x25c71235, 0xc19bf174, 0xcf692694, - 0xe49b69c1, 0x9ef14ad2, 0xefbe4786, 0x384f25e3, - 0x0fc19dc6, 0x8b8cd5b5, 0x240ca1cc, 0x77ac9c65, - 0x2de92c6f, 0x592b0275, 0x4a7484aa, 0x6ea6e483, - 0x5cb0a9dc, 0xbd41fbd4, 0x76f988da, 0x831153b5, - 0x983e5152, 0xee66dfab, 0xa831c66d, 0x2db43210, - 0xb00327c8, 0x98fb213f, 0xbf597fc7, 0xbeef0ee4, - 0xc6e00bf3, 0x3da88fc2, 0xd5a79147, 0x930aa725, - 0x06ca6351, 0xe003826f, 0x14292967, 0x0a0e6e70, - 0x27b70a85, 0x46d22ffc, 0x2e1b2138, 0x5c26c926, - 0x4d2c6dfc, 0x5ac42aed, 0x53380d13, 0x9d95b3df, - 0x650a7354, 0x8baf63de, 0x766a0abb, 0x3c77b2a8, - 0x81c2c92e, 0x47edaee6, 0x92722c85, 0x1482353b, - 0xa2bfe8a1, 0x4cf10364, 0xa81a664b, 0xbc423001, - 0xc24b8b70, 0xd0f89791, 0xc76c51a3, 0x0654be30, - 0xd192e819, 0xd6ef5218, 0xd6990624, 0x5565a910, - 0xf40e3585, 0x5771202a, 0x106aa070, 0x32bbd1b8, - 0x19a4c116, 0xb8d2d0c8, 0x1e376c08, 0x5141ab53, - 0x2748774c, 0xdf8eeb99, 0x34b0bcb5, 0xe19b48a8, - 0x391c0cb3, 0xc5c95a63, 0x4ed8aa4a, 0xe3418acb, - 0x5b9cca4f, 0x7763e373, 0x682e6ff3, 0xd6b2b8a3, - 0x748f82ee, 0x5defb2fc, 0x78a5636f, 0x43172f60, - 0x84c87814, 0xa1f0ab72, 0x8cc70208, 0x1a6439ec, - 0x90befffa, 0x23631e28, 0xa4506ceb, 0xde82bde9, - 0xbef9a3f7, 0xb2c67915, 0xc67178f2, 0xe372532b, - 0xca273ece, 0xea26619c, 0xd186b8c7, 0x21c0c207, - 0xeada7dd6, 0xcde0eb1e, 0xf57d4f7f, 0xee6ed178, - 0x06f067aa, 0x72176fba, 0x0a637dc5, 0xa2c898a6, - 0x113f9804, 0xbef90dae, 0x1b710b35, 0x131c471b, - 0x28db77f5, 0x23047d84, 0x32caab7b, 0x40c72493, - 0x3c9ebe0a, 0x15c9bebc, 0x431d67c4, 0x9c100d4c, - 0x4cc5d4be, 0xcb3e42b6, 0x597f299c, 0xfc657e2a, - 0x5fcb6fab, 0x3ad6faec, 0x6c44198c, 0x4a475817 + 0x428a2f98, 0xd728ae22, 0x71374491, 0x23ef65cd, + 0xb5c0fbcf, 0xec4d3b2f, 0xe9b5dba5, 0x8189dbbc, + 0x3956c25b, 0xf348b538, 0x59f111f1, 0xb605d019, + 0x923f82a4, 0xaf194f9b, 0xab1c5ed5, 0xda6d8118, + 0xd807aa98, 0xa3030242, 0x12835b01, 0x45706fbe, + 0x243185be, 0x4ee4b28c, 0x550c7dc3, 0xd5ffb4e2, + 0x72be5d74, 0xf27b896f, 0x80deb1fe, 0x3b1696b1, + 0x9bdc06a7, 0x25c71235, 0xc19bf174, 0xcf692694, + 0xe49b69c1, 0x9ef14ad2, 0xefbe4786, 0x384f25e3, + 0x0fc19dc6, 0x8b8cd5b5, 0x240ca1cc, 0x77ac9c65, + 0x2de92c6f, 0x592b0275, 0x4a7484aa, 0x6ea6e483, + 0x5cb0a9dc, 0xbd41fbd4, 0x76f988da, 0x831153b5, + 0x983e5152, 0xee66dfab, 0xa831c66d, 0x2db43210, + 0xb00327c8, 0x98fb213f, 0xbf597fc7, 0xbeef0ee4, + 0xc6e00bf3, 0x3da88fc2, 0xd5a79147, 0x930aa725, + 0x06ca6351, 0xe003826f, 0x14292967, 0x0a0e6e70, + 0x27b70a85, 0x46d22ffc, 0x2e1b2138, 0x5c26c926, + 0x4d2c6dfc, 0x5ac42aed, 0x53380d13, 0x9d95b3df, + 0x650a7354, 0x8baf63de, 0x766a0abb, 0x3c77b2a8, + 0x81c2c92e, 0x47edaee6, 0x92722c85, 0x1482353b, + 0xa2bfe8a1, 0x4cf10364, 0xa81a664b, 0xbc423001, + 0xc24b8b70, 0xd0f89791, 0xc76c51a3, 0x0654be30, + 0xd192e819, 0xd6ef5218, 0xd6990624, 0x5565a910, + 0xf40e3585, 0x5771202a, 0x106aa070, 0x32bbd1b8, + 0x19a4c116, 0xb8d2d0c8, 0x1e376c08, 0x5141ab53, + 0x2748774c, 0xdf8eeb99, 0x34b0bcb5, 0xe19b48a8, + 0x391c0cb3, 0xc5c95a63, 0x4ed8aa4a, 0xe3418acb, + 0x5b9cca4f, 0x7763e373, 0x682e6ff3, 0xd6b2b8a3, + 0x748f82ee, 0x5defb2fc, 0x78a5636f, 0x43172f60, + 0x84c87814, 0xa1f0ab72, 0x8cc70208, 0x1a6439ec, + 0x90befffa, 0x23631e28, 0xa4506ceb, 0xde82bde9, + 0xbef9a3f7, 0xb2c67915, 0xc67178f2, 0xe372532b, + 0xca273ece, 0xea26619c, 0xd186b8c7, 0x21c0c207, + 0xeada7dd6, 0xcde0eb1e, 0xf57d4f7f, 0xee6ed178, + 0x06f067aa, 0x72176fba, 0x0a637dc5, 0xa2c898a6, + 0x113f9804, 0xbef90dae, 0x1b710b35, 0x131c471b, + 0x28db77f5, 0x23047d84, 0x32caab7b, 0x40c72493, + 0x3c9ebe0a, 0x15c9bebc, 0x431d67c4, 0x9c100d4c, + 0x4cc5d4be, 0xcb3e42b6, 0x597f299c, 0xfc657e2a, + 0x5fcb6fab, 0x3ad6faec, 0x6c44198c, 0x4a475817 ]; function crypto_hashblocks_hl(hh, hl, m, n) { - var wh = new Int32Array(16), wl = new Int32Array(16), - bh0, bh1, bh2, bh3, bh4, bh5, bh6, bh7, - bl0, bl1, bl2, bl3, bl4, bl5, bl6, bl7, - th, tl, i, j, h, l, a, b, c, d; - - var ah0 = hh[0], - ah1 = hh[1], - ah2 = hh[2], - ah3 = hh[3], - ah4 = hh[4], - ah5 = hh[5], - ah6 = hh[6], - ah7 = hh[7], - - al0 = hl[0], - al1 = hl[1], - al2 = hl[2], - al3 = hl[3], - al4 = hl[4], - al5 = hl[5], - al6 = hl[6], - al7 = hl[7]; - - var pos = 0; - while (n >= 128) { - for (i = 0; i < 16; i++) { - j = 8 * i + pos; - wh[i] = (m[j+0] << 24) | (m[j+1] << 16) | (m[j+2] << 8) | m[j+3]; - wl[i] = (m[j+4] << 24) | (m[j+5] << 16) | (m[j+6] << 8) | m[j+7]; - } - for (i = 0; i < 80; i++) { - bh0 = ah0; - bh1 = ah1; - bh2 = ah2; - bh3 = ah3; - bh4 = ah4; - bh5 = ah5; - bh6 = ah6; - bh7 = ah7; - - bl0 = al0; - bl1 = al1; - bl2 = al2; - bl3 = al3; - bl4 = al4; - bl5 = al5; - bl6 = al6; - bl7 = al7; - - // add - h = ah7; - l = al7; - - a = l & 0xffff; b = l >>> 16; - c = h & 0xffff; d = h >>> 16; - - // Sigma1 - h = ((ah4 >>> 14) | (al4 << (32-14))) ^ ((ah4 >>> 18) | (al4 << (32-18))) ^ ((al4 >>> (41-32)) | (ah4 << (32-(41-32)))); - l = ((al4 >>> 14) | (ah4 << (32-14))) ^ ((al4 >>> 18) | (ah4 << (32-18))) ^ ((ah4 >>> (41-32)) | (al4 << (32-(41-32)))); - - a += l & 0xffff; b += l >>> 16; - c += h & 0xffff; d += h >>> 16; - - // Ch - h = (ah4 & ah5) ^ (~ah4 & ah6); - l = (al4 & al5) ^ (~al4 & al6); - - a += l & 0xffff; b += l >>> 16; - c += h & 0xffff; d += h >>> 16; - - // K - h = K[i*2]; - l = K[i*2+1]; - - a += l & 0xffff; b += l >>> 16; - c += h & 0xffff; d += h >>> 16; - - // w - h = wh[i%16]; - l = wl[i%16]; - - a += l & 0xffff; b += l >>> 16; - c += h & 0xffff; d += h >>> 16; - - b += a >>> 16; - c += b >>> 16; - d += c >>> 16; - - th = c & 0xffff | d << 16; - tl = a & 0xffff | b << 16; - - // add - h = th; - l = tl; - - a = l & 0xffff; b = l >>> 16; - c = h & 0xffff; d = h >>> 16; - - // Sigma0 - h = ((ah0 >>> 28) | (al0 << (32-28))) ^ ((al0 >>> (34-32)) | (ah0 << (32-(34-32)))) ^ ((al0 >>> (39-32)) | (ah0 << (32-(39-32)))); - l = ((al0 >>> 28) | (ah0 << (32-28))) ^ ((ah0 >>> (34-32)) | (al0 << (32-(34-32)))) ^ ((ah0 >>> (39-32)) | (al0 << (32-(39-32)))); - - a += l & 0xffff; b += l >>> 16; - c += h & 0xffff; d += h >>> 16; - - // Maj - h = (ah0 & ah1) ^ (ah0 & ah2) ^ (ah1 & ah2); - l = (al0 & al1) ^ (al0 & al2) ^ (al1 & al2); - - a += l & 0xffff; b += l >>> 16; - c += h & 0xffff; d += h >>> 16; - - b += a >>> 16; - c += b >>> 16; - d += c >>> 16; - - bh7 = (c & 0xffff) | (d << 16); - bl7 = (a & 0xffff) | (b << 16); - - // add - h = bh3; - l = bl3; - - a = l & 0xffff; b = l >>> 16; - c = h & 0xffff; d = h >>> 16; - - h = th; - l = tl; - - a += l & 0xffff; b += l >>> 16; - c += h & 0xffff; d += h >>> 16; + var wh = new Int32Array(16), wl = new Int32Array(16), + bh0, bh1, bh2, bh3, bh4, bh5, bh6, bh7, + bl0, bl1, bl2, bl3, bl4, bl5, bl6, bl7, + th, tl, i, j, h, l, a, b, c, d; + + var ah0 = hh[0], + ah1 = hh[1], + ah2 = hh[2], + ah3 = hh[3], + ah4 = hh[4], + ah5 = hh[5], + ah6 = hh[6], + ah7 = hh[7], + + al0 = hl[0], + al1 = hl[1], + al2 = hl[2], + al3 = hl[3], + al4 = hl[4], + al5 = hl[5], + al6 = hl[6], + al7 = hl[7]; + + var pos = 0; + while (n >= 128) { + for (i = 0; i < 16; i++) { + j = 8 * i + pos; + wh[i] = (m[j + 0] << 24) | (m[j + 1] << 16) | (m[j + 2] << 8) | m[j + 3]; + wl[i] = (m[j + 4] << 24) | (m[j + 5] << 16) | (m[j + 6] << 8) | m[j + 7]; + } + for (i = 0; i < 80; i++) { + bh0 = ah0; + bh1 = ah1; + bh2 = ah2; + bh3 = ah3; + bh4 = ah4; + bh5 = ah5; + bh6 = ah6; + bh7 = ah7; + + bl0 = al0; + bl1 = al1; + bl2 = al2; + bl3 = al3; + bl4 = al4; + bl5 = al5; + bl6 = al6; + bl7 = al7; + + // add + h = ah7; + l = al7; + + a = l & 0xffff; b = l >>> 16; + c = h & 0xffff; d = h >>> 16; + + // Sigma1 + h = ((ah4 >>> 14) | (al4 << (32 - 14))) ^ ((ah4 >>> 18) | (al4 << (32 - 18))) ^ ((al4 >>> (41 - 32)) | (ah4 << (32 - (41 - 32)))); + l = ((al4 >>> 14) | (ah4 << (32 - 14))) ^ ((al4 >>> 18) | (ah4 << (32 - 18))) ^ ((ah4 >>> (41 - 32)) | (al4 << (32 - (41 - 32)))); + + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; + + // Ch + h = (ah4 & ah5) ^ (~ah4 & ah6); + l = (al4 & al5) ^ (~al4 & al6); + + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; + + // K + h = K[i * 2]; + l = K[i * 2 + 1]; + + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; + + // w + h = wh[i % 16]; + l = wl[i % 16]; + + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; + + b += a >>> 16; + c += b >>> 16; + d += c >>> 16; + + th = c & 0xffff | d << 16; + tl = a & 0xffff | b << 16; + + // add + h = th; + l = tl; + + a = l & 0xffff; b = l >>> 16; + c = h & 0xffff; d = h >>> 16; + + // Sigma0 + h = ((ah0 >>> 28) | (al0 << (32 - 28))) ^ ((al0 >>> (34 - 32)) | (ah0 << (32 - (34 - 32)))) ^ ((al0 >>> (39 - 32)) | (ah0 << (32 - (39 - 32)))); + l = ((al0 >>> 28) | (ah0 << (32 - 28))) ^ ((ah0 >>> (34 - 32)) | (al0 << (32 - (34 - 32)))) ^ ((ah0 >>> (39 - 32)) | (al0 << (32 - (39 - 32)))); + + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; + + // Maj + h = (ah0 & ah1) ^ (ah0 & ah2) ^ (ah1 & ah2); + l = (al0 & al1) ^ (al0 & al2) ^ (al1 & al2); + + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; + + b += a >>> 16; + c += b >>> 16; + d += c >>> 16; + + bh7 = (c & 0xffff) | (d << 16); + bl7 = (a & 0xffff) | (b << 16); + + // add + h = bh3; + l = bl3; + + a = l & 0xffff; b = l >>> 16; + c = h & 0xffff; d = h >>> 16; + + h = th; + l = tl; + + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; - b += a >>> 16; - c += b >>> 16; - d += c >>> 16; + b += a >>> 16; + c += b >>> 16; + d += c >>> 16; - bh3 = (c & 0xffff) | (d << 16); - bl3 = (a & 0xffff) | (b << 16); + bh3 = (c & 0xffff) | (d << 16); + bl3 = (a & 0xffff) | (b << 16); - ah1 = bh0; - ah2 = bh1; - ah3 = bh2; - ah4 = bh3; - ah5 = bh4; - ah6 = bh5; - ah7 = bh6; - ah0 = bh7; + ah1 = bh0; + ah2 = bh1; + ah3 = bh2; + ah4 = bh3; + ah5 = bh4; + ah6 = bh5; + ah7 = bh6; + ah0 = bh7; - al1 = bl0; - al2 = bl1; - al3 = bl2; - al4 = bl3; - al5 = bl4; - al6 = bl5; - al7 = bl6; - al0 = bl7; + al1 = bl0; + al2 = bl1; + al3 = bl2; + al4 = bl3; + al5 = bl4; + al6 = bl5; + al7 = bl6; + al0 = bl7; - if (i%16 === 15) { - for (j = 0; j < 16; j++) { - // add - h = wh[j]; - l = wl[j]; + if (i % 16 === 15) { + for (j = 0; j < 16; j++) { + // add + h = wh[j]; + l = wl[j]; - a = l & 0xffff; b = l >>> 16; - c = h & 0xffff; d = h >>> 16; + a = l & 0xffff; b = l >>> 16; + c = h & 0xffff; d = h >>> 16; - h = wh[(j+9)%16]; - l = wl[(j+9)%16]; + h = wh[(j + 9) % 16]; + l = wl[(j + 9) % 16]; - a += l & 0xffff; b += l >>> 16; - c += h & 0xffff; d += h >>> 16; + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; - // sigma0 - th = wh[(j+1)%16]; - tl = wl[(j+1)%16]; - h = ((th >>> 1) | (tl << (32-1))) ^ ((th >>> 8) | (tl << (32-8))) ^ (th >>> 7); - l = ((tl >>> 1) | (th << (32-1))) ^ ((tl >>> 8) | (th << (32-8))) ^ ((tl >>> 7) | (th << (32-7))); + // sigma0 + th = wh[(j + 1) % 16]; + tl = wl[(j + 1) % 16]; + h = ((th >>> 1) | (tl << (32 - 1))) ^ ((th >>> 8) | (tl << (32 - 8))) ^ (th >>> 7); + l = ((tl >>> 1) | (th << (32 - 1))) ^ ((tl >>> 8) | (th << (32 - 8))) ^ ((tl >>> 7) | (th << (32 - 7))); - a += l & 0xffff; b += l >>> 16; - c += h & 0xffff; d += h >>> 16; + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; - // sigma1 - th = wh[(j+14)%16]; - tl = wl[(j+14)%16]; - h = ((th >>> 19) | (tl << (32-19))) ^ ((tl >>> (61-32)) | (th << (32-(61-32)))) ^ (th >>> 6); - l = ((tl >>> 19) | (th << (32-19))) ^ ((th >>> (61-32)) | (tl << (32-(61-32)))) ^ ((tl >>> 6) | (th << (32-6))); + // sigma1 + th = wh[(j + 14) % 16]; + tl = wl[(j + 14) % 16]; + h = ((th >>> 19) | (tl << (32 - 19))) ^ ((tl >>> (61 - 32)) | (th << (32 - (61 - 32)))) ^ (th >>> 6); + l = ((tl >>> 19) | (th << (32 - 19))) ^ ((th >>> (61 - 32)) | (tl << (32 - (61 - 32)))) ^ ((tl >>> 6) | (th << (32 - 6))); - a += l & 0xffff; b += l >>> 16; - c += h & 0xffff; d += h >>> 16; + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; - b += a >>> 16; - c += b >>> 16; - d += c >>> 16; + b += a >>> 16; + c += b >>> 16; + d += c >>> 16; - wh[j] = (c & 0xffff) | (d << 16); - wl[j] = (a & 0xffff) | (b << 16); - } - } - } + wh[j] = (c & 0xffff) | (d << 16); + wl[j] = (a & 0xffff) | (b << 16); + } + } + } - // add - h = ah0; - l = al0; + // add + h = ah0; + l = al0; - a = l & 0xffff; b = l >>> 16; - c = h & 0xffff; d = h >>> 16; + a = l & 0xffff; b = l >>> 16; + c = h & 0xffff; d = h >>> 16; - h = hh[0]; - l = hl[0]; + h = hh[0]; + l = hl[0]; - a += l & 0xffff; b += l >>> 16; - c += h & 0xffff; d += h >>> 16; + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; - b += a >>> 16; - c += b >>> 16; - d += c >>> 16; + b += a >>> 16; + c += b >>> 16; + d += c >>> 16; - hh[0] = ah0 = (c & 0xffff) | (d << 16); - hl[0] = al0 = (a & 0xffff) | (b << 16); + hh[0] = ah0 = (c & 0xffff) | (d << 16); + hl[0] = al0 = (a & 0xffff) | (b << 16); - h = ah1; - l = al1; + h = ah1; + l = al1; - a = l & 0xffff; b = l >>> 16; - c = h & 0xffff; d = h >>> 16; + a = l & 0xffff; b = l >>> 16; + c = h & 0xffff; d = h >>> 16; - h = hh[1]; - l = hl[1]; + h = hh[1]; + l = hl[1]; - a += l & 0xffff; b += l >>> 16; - c += h & 0xffff; d += h >>> 16; + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; - b += a >>> 16; - c += b >>> 16; - d += c >>> 16; + b += a >>> 16; + c += b >>> 16; + d += c >>> 16; - hh[1] = ah1 = (c & 0xffff) | (d << 16); - hl[1] = al1 = (a & 0xffff) | (b << 16); + hh[1] = ah1 = (c & 0xffff) | (d << 16); + hl[1] = al1 = (a & 0xffff) | (b << 16); - h = ah2; - l = al2; + h = ah2; + l = al2; - a = l & 0xffff; b = l >>> 16; - c = h & 0xffff; d = h >>> 16; + a = l & 0xffff; b = l >>> 16; + c = h & 0xffff; d = h >>> 16; - h = hh[2]; - l = hl[2]; + h = hh[2]; + l = hl[2]; - a += l & 0xffff; b += l >>> 16; - c += h & 0xffff; d += h >>> 16; + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; - b += a >>> 16; - c += b >>> 16; - d += c >>> 16; + b += a >>> 16; + c += b >>> 16; + d += c >>> 16; - hh[2] = ah2 = (c & 0xffff) | (d << 16); - hl[2] = al2 = (a & 0xffff) | (b << 16); + hh[2] = ah2 = (c & 0xffff) | (d << 16); + hl[2] = al2 = (a & 0xffff) | (b << 16); - h = ah3; - l = al3; + h = ah3; + l = al3; - a = l & 0xffff; b = l >>> 16; - c = h & 0xffff; d = h >>> 16; + a = l & 0xffff; b = l >>> 16; + c = h & 0xffff; d = h >>> 16; - h = hh[3]; - l = hl[3]; + h = hh[3]; + l = hl[3]; - a += l & 0xffff; b += l >>> 16; - c += h & 0xffff; d += h >>> 16; + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; - b += a >>> 16; - c += b >>> 16; - d += c >>> 16; + b += a >>> 16; + c += b >>> 16; + d += c >>> 16; - hh[3] = ah3 = (c & 0xffff) | (d << 16); - hl[3] = al3 = (a & 0xffff) | (b << 16); + hh[3] = ah3 = (c & 0xffff) | (d << 16); + hl[3] = al3 = (a & 0xffff) | (b << 16); - h = ah4; - l = al4; + h = ah4; + l = al4; - a = l & 0xffff; b = l >>> 16; - c = h & 0xffff; d = h >>> 16; + a = l & 0xffff; b = l >>> 16; + c = h & 0xffff; d = h >>> 16; - h = hh[4]; - l = hl[4]; + h = hh[4]; + l = hl[4]; - a += l & 0xffff; b += l >>> 16; - c += h & 0xffff; d += h >>> 16; + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; - b += a >>> 16; - c += b >>> 16; - d += c >>> 16; + b += a >>> 16; + c += b >>> 16; + d += c >>> 16; - hh[4] = ah4 = (c & 0xffff) | (d << 16); - hl[4] = al4 = (a & 0xffff) | (b << 16); + hh[4] = ah4 = (c & 0xffff) | (d << 16); + hl[4] = al4 = (a & 0xffff) | (b << 16); - h = ah5; - l = al5; + h = ah5; + l = al5; - a = l & 0xffff; b = l >>> 16; - c = h & 0xffff; d = h >>> 16; + a = l & 0xffff; b = l >>> 16; + c = h & 0xffff; d = h >>> 16; - h = hh[5]; - l = hl[5]; + h = hh[5]; + l = hl[5]; - a += l & 0xffff; b += l >>> 16; - c += h & 0xffff; d += h >>> 16; + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; - b += a >>> 16; - c += b >>> 16; - d += c >>> 16; + b += a >>> 16; + c += b >>> 16; + d += c >>> 16; - hh[5] = ah5 = (c & 0xffff) | (d << 16); - hl[5] = al5 = (a & 0xffff) | (b << 16); + hh[5] = ah5 = (c & 0xffff) | (d << 16); + hl[5] = al5 = (a & 0xffff) | (b << 16); - h = ah6; - l = al6; + h = ah6; + l = al6; - a = l & 0xffff; b = l >>> 16; - c = h & 0xffff; d = h >>> 16; + a = l & 0xffff; b = l >>> 16; + c = h & 0xffff; d = h >>> 16; - h = hh[6]; - l = hl[6]; + h = hh[6]; + l = hl[6]; - a += l & 0xffff; b += l >>> 16; - c += h & 0xffff; d += h >>> 16; + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; - b += a >>> 16; - c += b >>> 16; - d += c >>> 16; + b += a >>> 16; + c += b >>> 16; + d += c >>> 16; - hh[6] = ah6 = (c & 0xffff) | (d << 16); - hl[6] = al6 = (a & 0xffff) | (b << 16); + hh[6] = ah6 = (c & 0xffff) | (d << 16); + hl[6] = al6 = (a & 0xffff) | (b << 16); - h = ah7; - l = al7; + h = ah7; + l = al7; - a = l & 0xffff; b = l >>> 16; - c = h & 0xffff; d = h >>> 16; + a = l & 0xffff; b = l >>> 16; + c = h & 0xffff; d = h >>> 16; - h = hh[7]; - l = hl[7]; + h = hh[7]; + l = hl[7]; - a += l & 0xffff; b += l >>> 16; - c += h & 0xffff; d += h >>> 16; + a += l & 0xffff; b += l >>> 16; + c += h & 0xffff; d += h >>> 16; - b += a >>> 16; - c += b >>> 16; - d += c >>> 16; + b += a >>> 16; + c += b >>> 16; + d += c >>> 16; - hh[7] = ah7 = (c & 0xffff) | (d << 16); - hl[7] = al7 = (a & 0xffff) | (b << 16); + hh[7] = ah7 = (c & 0xffff) | (d << 16); + hl[7] = al7 = (a & 0xffff) | (b << 16); - pos += 128; - n -= 128; - } + pos += 128; + n -= 128; + } - return n; + return n; } function crypto_hash(out, m, n) { - var hh = new Int32Array(8), - hl = new Int32Array(8), - x = new Uint8Array(256), - i, b = n; + var hh = new Int32Array(8), + hl = new Int32Array(8), + x = new Uint8Array(256), + i, b = n; - hh[0] = 0x6a09e667; - hh[1] = 0xbb67ae85; - hh[2] = 0x3c6ef372; - hh[3] = 0xa54ff53a; - hh[4] = 0x510e527f; - hh[5] = 0x9b05688c; - hh[6] = 0x1f83d9ab; - hh[7] = 0x5be0cd19; + hh[0] = 0x6a09e667; + hh[1] = 0xbb67ae85; + hh[2] = 0x3c6ef372; + hh[3] = 0xa54ff53a; + hh[4] = 0x510e527f; + hh[5] = 0x9b05688c; + hh[6] = 0x1f83d9ab; + hh[7] = 0x5be0cd19; - hl[0] = 0xf3bcc908; - hl[1] = 0x84caa73b; - hl[2] = 0xfe94f82b; - hl[3] = 0x5f1d36f1; - hl[4] = 0xade682d1; - hl[5] = 0x2b3e6c1f; - hl[6] = 0xfb41bd6b; - hl[7] = 0x137e2179; + hl[0] = 0xf3bcc908; + hl[1] = 0x84caa73b; + hl[2] = 0xfe94f82b; + hl[3] = 0x5f1d36f1; + hl[4] = 0xade682d1; + hl[5] = 0x2b3e6c1f; + hl[6] = 0xfb41bd6b; + hl[7] = 0x137e2179; - crypto_hashblocks_hl(hh, hl, m, n); - n %= 128; + crypto_hashblocks_hl(hh, hl, m, n); + n %= 128; - for (i = 0; i < n; i++) x[i] = m[b-n+i]; - x[n] = 128; + for (i = 0; i < n; i++) x[i] = m[b - n + i]; + x[n] = 128; - n = 256-128*(n<112?1:0); - x[n-9] = 0; - ts64(x, n-8, (b / 0x20000000) | 0, b << 3); - crypto_hashblocks_hl(hh, hl, x, n); + n = 256 - 128 * (n < 112 ? 1 : 0); + x[n - 9] = 0; + ts64(x, n - 8, (b / 0x20000000) | 0, b << 3); + crypto_hashblocks_hl(hh, hl, x, n); - for (i = 0; i < 8; i++) ts64(out, 8*i, hh[i], hl[i]); + for (i = 0; i < 8; i++) ts64(out, 8 * i, hh[i], hl[i]); - return 0; + return 0; } function add(p, q) { - var a = gf(), b = gf(), c = gf(), - d = gf(), e = gf(), f = gf(), - g = gf(), h = gf(), t = gf(); + var a = gf(), b = gf(), c = gf(), + d = gf(), e = gf(), f = gf(), + g = gf(), h = gf(), t = gf(); - Z(a, p[1], p[0]); - Z(t, q[1], q[0]); - M(a, a, t); - A(b, p[0], p[1]); - A(t, q[0], q[1]); - M(b, b, t); - M(c, p[3], q[3]); - M(c, c, D2); - M(d, p[2], q[2]); - A(d, d, d); - Z(e, b, a); - Z(f, d, c); - A(g, d, c); - A(h, b, a); + Z(a, p[1], p[0]); + Z(t, q[1], q[0]); + M(a, a, t); + A(b, p[0], p[1]); + A(t, q[0], q[1]); + M(b, b, t); + M(c, p[3], q[3]); + M(c, c, D2); + M(d, p[2], q[2]); + A(d, d, d); + Z(e, b, a); + Z(f, d, c); + A(g, d, c); + A(h, b, a); - M(p[0], e, f); - M(p[1], h, g); - M(p[2], g, f); - M(p[3], e, h); + M(p[0], e, f); + M(p[1], h, g); + M(p[2], g, f); + M(p[3], e, h); } function cswap(p, q, b) { - var i; - for (i = 0; i < 4; i++) { - sel25519(p[i], q[i], b); - } + var i; + for (i = 0; i < 4; i++) { + sel25519(p[i], q[i], b); + } } function pack(r, p) { - var tx = gf(), ty = gf(), zi = gf(); - inv25519(zi, p[2]); - M(tx, p[0], zi); - M(ty, p[1], zi); - pack25519(r, ty); - r[31] ^= par25519(tx) << 7; + var tx = gf(), ty = gf(), zi = gf(); + inv25519(zi, p[2]); + M(tx, p[0], zi); + M(ty, p[1], zi); + pack25519(r, ty); + r[31] ^= par25519(tx) << 7; } function scalarmult(p, q, s) { - var b, i; - set25519(p[0], gf0); - set25519(p[1], gf1); - set25519(p[2], gf1); - set25519(p[3], gf0); - for (i = 255; i >= 0; --i) { - b = (s[(i/8)|0] >> (i&7)) & 1; - cswap(p, q, b); - add(q, p); - add(p, p); - cswap(p, q, b); - } + var b, i; + set25519(p[0], gf0); + set25519(p[1], gf1); + set25519(p[2], gf1); + set25519(p[3], gf0); + for (i = 255; i >= 0; --i) { + b = (s[(i / 8) | 0] >> (i & 7)) & 1; + cswap(p, q, b); + add(q, p); + add(p, p); + cswap(p, q, b); + } } function scalarbase(p, s) { - var q = [gf(), gf(), gf(), gf()]; - set25519(q[0], X); - set25519(q[1], Y); - set25519(q[2], gf1); - M(q[3], X, Y); - scalarmult(p, q, s); + var q = [gf(), gf(), gf(), gf()]; + set25519(q[0], X); + set25519(q[1], Y); + set25519(q[2], gf1); + M(q[3], X, Y); + scalarmult(p, q, s); } function crypto_sign_keypair(pk, sk, seeded) { - var d = new Uint8Array(64); - var p = [gf(), gf(), gf(), gf()]; - var i; + var d = new Uint8Array(64); + var p = [gf(), gf(), gf(), gf()]; + var i; - if (!seeded) randombytes(sk, 32); - crypto_hash(d, sk, 32); - d[0] &= 248; - d[31] &= 127; - d[31] |= 64; + if (!seeded) randombytes(sk, 32); + crypto_hash(d, sk, 32); + d[0] &= 248; + d[31] &= 127; + d[31] |= 64; - scalarbase(p, d); - pack(pk, p); + scalarbase(p, d); + pack(pk, p); - for (i = 0; i < 32; i++) sk[i+32] = pk[i]; - return 0; + for (i = 0; i < 32; i++) sk[i + 32] = pk[i]; + return 0; } var L = new Float64Array([0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x10]); function modL(r, x) { - var carry, i, j, k; - for (i = 63; i >= 32; --i) { - carry = 0; - for (j = i - 32, k = i - 12; j < k; ++j) { - x[j] += carry - 16 * x[i] * L[j - (i - 32)]; - carry = (x[j] + 128) >> 8; - x[j] -= carry * 256; - } - x[j] += carry; - x[i] = 0; - } - carry = 0; - for (j = 0; j < 32; j++) { - x[j] += carry - (x[31] >> 4) * L[j]; - carry = x[j] >> 8; - x[j] &= 255; - } - for (j = 0; j < 32; j++) x[j] -= carry * L[j]; - for (i = 0; i < 32; i++) { - x[i+1] += x[i] >> 8; - r[i] = x[i] & 255; - } + var carry, i, j, k; + for (i = 63; i >= 32; --i) { + carry = 0; + for (j = i - 32, k = i - 12; j < k; ++j) { + x[j] += carry - 16 * x[i] * L[j - (i - 32)]; + carry = (x[j] + 128) >> 8; + x[j] -= carry * 256; + } + x[j] += carry; + x[i] = 0; + } + carry = 0; + for (j = 0; j < 32; j++) { + x[j] += carry - (x[31] >> 4) * L[j]; + carry = x[j] >> 8; + x[j] &= 255; + } + for (j = 0; j < 32; j++) x[j] -= carry * L[j]; + for (i = 0; i < 32; i++) { + x[i + 1] += x[i] >> 8; + r[i] = x[i] & 255; + } } function reduce(r) { - var x = new Float64Array(64), i; - for (i = 0; i < 64; i++) x[i] = r[i]; - for (i = 0; i < 64; i++) r[i] = 0; - modL(r, x); + var x = new Float64Array(64), i; + for (i = 0; i < 64; i++) x[i] = r[i]; + for (i = 0; i < 64; i++) r[i] = 0; + modL(r, x); } // Note: difference from C - smlen returned, not passed as argument. function crypto_sign(sm, m, n, sk) { - var d = new Uint8Array(64), h = new Uint8Array(64), r = new Uint8Array(64); - var i, j, x = new Float64Array(64); - var p = [gf(), gf(), gf(), gf()]; + var d = new Uint8Array(64), h = new Uint8Array(64), r = new Uint8Array(64); + var i, j, x = new Float64Array(64); + var p = [gf(), gf(), gf(), gf()]; - crypto_hash(d, sk, 32); - d[0] &= 248; - d[31] &= 127; - d[31] |= 64; + crypto_hash(d, sk, 32); + d[0] &= 248; + d[31] &= 127; + d[31] |= 64; - var smlen = n + 64; - for (i = 0; i < n; i++) sm[64 + i] = m[i]; - for (i = 0; i < 32; i++) sm[32 + i] = d[32 + i]; + var smlen = n + 64; + for (i = 0; i < n; i++) sm[64 + i] = m[i]; + for (i = 0; i < 32; i++) sm[32 + i] = d[32 + i]; - crypto_hash(r, sm.subarray(32), n+32); - reduce(r); - scalarbase(p, r); - pack(sm, p); + crypto_hash(r, sm.subarray(32), n + 32); + reduce(r); + scalarbase(p, r); + pack(sm, p); - for (i = 32; i < 64; i++) sm[i] = sk[i]; - crypto_hash(h, sm, n + 64); - reduce(h); + for (i = 32; i < 64; i++) sm[i] = sk[i]; + crypto_hash(h, sm, n + 64); + reduce(h); - for (i = 0; i < 64; i++) x[i] = 0; - for (i = 0; i < 32; i++) x[i] = r[i]; - for (i = 0; i < 32; i++) { - for (j = 0; j < 32; j++) { - x[i+j] += h[i] * d[j]; - } - } + for (i = 0; i < 64; i++) x[i] = 0; + for (i = 0; i < 32; i++) x[i] = r[i]; + for (i = 0; i < 32; i++) { + for (j = 0; j < 32; j++) { + x[i + j] += h[i] * d[j]; + } + } - modL(sm.subarray(32), x); - return smlen; + modL(sm.subarray(32), x); + return smlen; } function unpackneg(r, p) { - var t = gf(), chk = gf(), num = gf(), - den = gf(), den2 = gf(), den4 = gf(), - den6 = gf(); + var t = gf(), chk = gf(), num = gf(), + den = gf(), den2 = gf(), den4 = gf(), + den6 = gf(); - set25519(r[2], gf1); - unpack25519(r[1], p); - S(num, r[1]); - M(den, num, D); - Z(num, num, r[2]); - A(den, r[2], den); + set25519(r[2], gf1); + unpack25519(r[1], p); + S(num, r[1]); + M(den, num, D); + Z(num, num, r[2]); + A(den, r[2], den); - S(den2, den); - S(den4, den2); - M(den6, den4, den2); - M(t, den6, num); - M(t, t, den); + S(den2, den); + S(den4, den2); + M(den6, den4, den2); + M(t, den6, num); + M(t, t, den); - pow2523(t, t); - M(t, t, num); - M(t, t, den); - M(t, t, den); - M(r[0], t, den); + pow2523(t, t); + M(t, t, num); + M(t, t, den); + M(t, t, den); + M(r[0], t, den); - S(chk, r[0]); - M(chk, chk, den); - if (neq25519(chk, num)) M(r[0], r[0], I); + S(chk, r[0]); + M(chk, chk, den); + if (neq25519(chk, num)) M(r[0], r[0], I); - S(chk, r[0]); - M(chk, chk, den); - if (neq25519(chk, num)) return -1; + S(chk, r[0]); + M(chk, chk, den); + if (neq25519(chk, num)) return -1; - if (par25519(r[0]) === (p[31]>>7)) Z(r[0], gf0, r[0]); + if (par25519(r[0]) === (p[31] >> 7)) Z(r[0], gf0, r[0]); - M(r[3], r[0], r[1]); - return 0; + M(r[3], r[0], r[1]); + return 0; } function crypto_sign_open(m, sm, n, pk) { - var i, mlen; - var t = new Uint8Array(32), h = new Uint8Array(64); - var p = [gf(), gf(), gf(), gf()], - q = [gf(), gf(), gf(), gf()]; + var i, mlen; + var t = new Uint8Array(32), h = new Uint8Array(64); + var p = [gf(), gf(), gf(), gf()], + q = [gf(), gf(), gf(), gf()]; - mlen = -1; - if (n < 64) return -1; + mlen = -1; + if (n < 64) return -1; - if (unpackneg(q, pk)) return -1; + if (unpackneg(q, pk)) return -1; - for (i = 0; i < n; i++) m[i] = sm[i]; - for (i = 0; i < 32; i++) m[i+32] = pk[i]; - crypto_hash(h, m, n); - reduce(h); - scalarmult(p, q, h); + for (i = 0; i < n; i++) m[i] = sm[i]; + for (i = 0; i < 32; i++) m[i + 32] = pk[i]; + crypto_hash(h, m, n); + reduce(h); + scalarmult(p, q, h); - scalarbase(q, sm.subarray(32)); - add(p, q); - pack(t, p); + scalarbase(q, sm.subarray(32)); + add(p, q); + pack(t, p); - n -= 64; - if (crypto_verify_32(sm, 0, t, 0)) { - for (i = 0; i < n; i++) m[i] = 0; - return -1; - } + n -= 64; + if (crypto_verify_32(sm, 0, t, 0)) { + for (i = 0; i < n; i++) m[i] = 0; + return -1; + } - for (i = 0; i < n; i++) m[i] = sm[i + 64]; - mlen = n; - return mlen; + for (i = 0; i < n; i++) m[i] = sm[i + 64]; + mlen = n; + return mlen; } var crypto_secretbox_KEYBYTES = 32, - crypto_secretbox_NONCEBYTES = 24, - crypto_secretbox_ZEROBYTES = 32, - crypto_secretbox_BOXZEROBYTES = 16, - crypto_scalarmult_BYTES = 32, - crypto_scalarmult_SCALARBYTES = 32, - crypto_box_PUBLICKEYBYTES = 32, - crypto_box_SECRETKEYBYTES = 32, - crypto_box_BEFORENMBYTES = 32, - crypto_box_NONCEBYTES = crypto_secretbox_NONCEBYTES, - crypto_box_ZEROBYTES = crypto_secretbox_ZEROBYTES, - crypto_box_BOXZEROBYTES = crypto_secretbox_BOXZEROBYTES, - crypto_sign_BYTES = 64, - crypto_sign_PUBLICKEYBYTES = 32, - crypto_sign_SECRETKEYBYTES = 64, - crypto_sign_SEEDBYTES = 32, - crypto_hash_BYTES = 64; + crypto_secretbox_NONCEBYTES = 24, + crypto_secretbox_ZEROBYTES = 32, + crypto_secretbox_BOXZEROBYTES = 16, + crypto_scalarmult_BYTES = 32, + crypto_scalarmult_SCALARBYTES = 32, + crypto_box_PUBLICKEYBYTES = 32, + crypto_box_SECRETKEYBYTES = 32, + crypto_box_BEFORENMBYTES = 32, + crypto_box_NONCEBYTES = crypto_secretbox_NONCEBYTES, + crypto_box_ZEROBYTES = crypto_secretbox_ZEROBYTES, + crypto_box_BOXZEROBYTES = crypto_secretbox_BOXZEROBYTES, + crypto_sign_BYTES = 64, + crypto_sign_PUBLICKEYBYTES = 32, + crypto_sign_SECRETKEYBYTES = 64, + crypto_sign_SEEDBYTES = 32, + crypto_hash_BYTES = 64; nacl.lowlevel = { - crypto_core_hsalsa20: crypto_core_hsalsa20, - crypto_stream_xor: crypto_stream_xor, - crypto_stream: crypto_stream, - crypto_stream_salsa20_xor: crypto_stream_salsa20_xor, - crypto_stream_salsa20: crypto_stream_salsa20, - crypto_onetimeauth: crypto_onetimeauth, - crypto_onetimeauth_verify: crypto_onetimeauth_verify, - crypto_verify_16: crypto_verify_16, - crypto_verify_32: crypto_verify_32, - crypto_secretbox: crypto_secretbox, - crypto_secretbox_open: crypto_secretbox_open, - crypto_scalarmult: crypto_scalarmult, - crypto_scalarmult_base: crypto_scalarmult_base, - crypto_box_beforenm: crypto_box_beforenm, - crypto_box_afternm: crypto_box_afternm, - crypto_box: crypto_box, - crypto_box_open: crypto_box_open, - crypto_box_keypair: crypto_box_keypair, - crypto_hash: crypto_hash, - crypto_sign: crypto_sign, - crypto_sign_keypair: crypto_sign_keypair, - crypto_sign_open: crypto_sign_open, + crypto_core_hsalsa20: crypto_core_hsalsa20, + crypto_stream_xor: crypto_stream_xor, + crypto_stream: crypto_stream, + crypto_stream_salsa20_xor: crypto_stream_salsa20_xor, + crypto_stream_salsa20: crypto_stream_salsa20, + crypto_onetimeauth: crypto_onetimeauth, + crypto_onetimeauth_verify: crypto_onetimeauth_verify, + crypto_verify_16: crypto_verify_16, + crypto_verify_32: crypto_verify_32, + crypto_secretbox: crypto_secretbox, + crypto_secretbox_open: crypto_secretbox_open, + crypto_scalarmult: crypto_scalarmult, + crypto_scalarmult_base: crypto_scalarmult_base, + crypto_box_beforenm: crypto_box_beforenm, + crypto_box_afternm: crypto_box_afternm, + crypto_box: crypto_box, + crypto_box_open: crypto_box_open, + crypto_box_keypair: crypto_box_keypair, + crypto_hash: crypto_hash, + crypto_sign: crypto_sign, + crypto_sign_keypair: crypto_sign_keypair, + crypto_sign_open: crypto_sign_open, - crypto_secretbox_KEYBYTES: crypto_secretbox_KEYBYTES, - crypto_secretbox_NONCEBYTES: crypto_secretbox_NONCEBYTES, - crypto_secretbox_ZEROBYTES: crypto_secretbox_ZEROBYTES, - crypto_secretbox_BOXZEROBYTES: crypto_secretbox_BOXZEROBYTES, - crypto_scalarmult_BYTES: crypto_scalarmult_BYTES, - crypto_scalarmult_SCALARBYTES: crypto_scalarmult_SCALARBYTES, - crypto_box_PUBLICKEYBYTES: crypto_box_PUBLICKEYBYTES, - crypto_box_SECRETKEYBYTES: crypto_box_SECRETKEYBYTES, - crypto_box_BEFORENMBYTES: crypto_box_BEFORENMBYTES, - crypto_box_NONCEBYTES: crypto_box_NONCEBYTES, - crypto_box_ZEROBYTES: crypto_box_ZEROBYTES, - crypto_box_BOXZEROBYTES: crypto_box_BOXZEROBYTES, - crypto_sign_BYTES: crypto_sign_BYTES, - crypto_sign_PUBLICKEYBYTES: crypto_sign_PUBLICKEYBYTES, - crypto_sign_SECRETKEYBYTES: crypto_sign_SECRETKEYBYTES, - crypto_sign_SEEDBYTES: crypto_sign_SEEDBYTES, - crypto_hash_BYTES: crypto_hash_BYTES + crypto_secretbox_KEYBYTES: crypto_secretbox_KEYBYTES, + crypto_secretbox_NONCEBYTES: crypto_secretbox_NONCEBYTES, + crypto_secretbox_ZEROBYTES: crypto_secretbox_ZEROBYTES, + crypto_secretbox_BOXZEROBYTES: crypto_secretbox_BOXZEROBYTES, + crypto_scalarmult_BYTES: crypto_scalarmult_BYTES, + crypto_scalarmult_SCALARBYTES: crypto_scalarmult_SCALARBYTES, + crypto_box_PUBLICKEYBYTES: crypto_box_PUBLICKEYBYTES, + crypto_box_SECRETKEYBYTES: crypto_box_SECRETKEYBYTES, + crypto_box_BEFORENMBYTES: crypto_box_BEFORENMBYTES, + crypto_box_NONCEBYTES: crypto_box_NONCEBYTES, + crypto_box_ZEROBYTES: crypto_box_ZEROBYTES, + crypto_box_BOXZEROBYTES: crypto_box_BOXZEROBYTES, + crypto_sign_BYTES: crypto_sign_BYTES, + crypto_sign_PUBLICKEYBYTES: crypto_sign_PUBLICKEYBYTES, + crypto_sign_SECRETKEYBYTES: crypto_sign_SECRETKEYBYTES, + crypto_sign_SEEDBYTES: crypto_sign_SEEDBYTES, + crypto_hash_BYTES: crypto_hash_BYTES }; /* High-level API */ function checkLengths(k, n) { - if (k.length !== crypto_secretbox_KEYBYTES) throw new Error('bad key size'); - if (n.length !== crypto_secretbox_NONCEBYTES) throw new Error('bad nonce size'); + if (k.length !== crypto_secretbox_KEYBYTES) throw new Error('bad key size'); + if (n.length !== crypto_secretbox_NONCEBYTES) throw new Error('bad nonce size'); } function checkBoxLengths(pk, sk) { - if (pk.length !== crypto_box_PUBLICKEYBYTES) throw new Error('bad public key size'); - if (sk.length !== crypto_box_SECRETKEYBYTES) throw new Error('bad secret key size'); + if (pk.length !== crypto_box_PUBLICKEYBYTES) throw new Error('bad public key size'); + if (sk.length !== crypto_box_SECRETKEYBYTES) throw new Error('bad secret key size'); } function checkArrayTypes() { - var t, i; - for (i = 0; i < arguments.length; i++) { - if ((t = Object.prototype.toString.call(arguments[i])) !== '[object Uint8Array]') - throw new TypeError('unexpected type ' + t + ', use Uint8Array'); - } + var t, i; + for (i = 0; i < arguments.length; i++) { + if ((t = Object.prototype.toString.call(arguments[i])) !== '[object Uint8Array]') + throw new TypeError('unexpected type ' + t + ', use Uint8Array'); + } } function cleanup(arr) { - for (var i = 0; i < arr.length; i++) arr[i] = 0; + for (var i = 0; i < arr.length; i++) arr[i] = 0; } nacl.util = {}; -nacl.util.decodeUTF8 = function(s) { - var i, d = unescape(encodeURIComponent(s)), b = new Uint8Array(d.length); - for (i = 0; i < d.length; i++) b[i] = d.charCodeAt(i); - return b; +nacl.util.decodeUTF8 = function (s) { + var i, d = unescape(encodeURIComponent(s)), b = new Uint8Array(d.length); + for (i = 0; i < d.length; i++) b[i] = d.charCodeAt(i); + return b; }; -nacl.util.encodeUTF8 = function(arr) { - var i, s = []; - for (i = 0; i < arr.length; i++) s.push(String.fromCharCode(arr[i])); - return decodeURIComponent(escape(s.join(''))); +nacl.util.encodeUTF8 = function (arr) { + var i, s = []; + for (i = 0; i < arr.length; i++) s.push(String.fromCharCode(arr[i])); + return decodeURIComponent(escape(s.join(''))); }; -nacl.util.encodeBase64 = function(arr) { - if (typeof btoa === 'undefined') { - return (new Buffer(arr)).toString('base64'); - } else { - var i, s = [], len = arr.length; - for (i = 0; i < len; i++) s.push(String.fromCharCode(arr[i])); - return btoa(s.join('')); - } +nacl.util.encodeBase64 = function (arr) { + if (typeof btoa === 'undefined') { + return (new Buffer(arr)).toString('base64'); + } else { + var i, s = [], len = arr.length; + for (i = 0; i < len; i++) s.push(String.fromCharCode(arr[i])); + return btoa(s.join('')); + } }; -nacl.util.decodeBase64 = function(s) { - if (typeof atob === 'undefined') { - return new Uint8Array(Array.prototype.slice.call(new Buffer(s, 'base64'), 0)); - } else { - var i, d = atob(s), b = new Uint8Array(d.length); - for (i = 0; i < d.length; i++) b[i] = d.charCodeAt(i); - return b; - } +nacl.util.decodeBase64 = function (s) { + if (typeof atob === 'undefined') { + return new Uint8Array(Array.prototype.slice.call(new Buffer(s, 'base64'), 0)); + } else { + var i, d = atob(s), b = new Uint8Array(d.length); + for (i = 0; i < d.length; i++) b[i] = d.charCodeAt(i); + return b; + } }; -nacl.randomBytes = function(n) { - var b = new Uint8Array(n); - randombytes(b, n); - return b; +nacl.randomBytes = function (n) { + var b = new Uint8Array(n); + randombytes(b, n); + return b; }; -nacl.secretbox = function(msg, nonce, key) { - checkArrayTypes(msg, nonce, key); - checkLengths(key, nonce); - var m = new Uint8Array(crypto_secretbox_ZEROBYTES + msg.length); - var c = new Uint8Array(m.length); - for (var i = 0; i < msg.length; i++) m[i+crypto_secretbox_ZEROBYTES] = msg[i]; - crypto_secretbox(c, m, m.length, nonce, key); - return c.subarray(crypto_secretbox_BOXZEROBYTES); +nacl.secretbox = function (msg, nonce, key) { + checkArrayTypes(msg, nonce, key); + checkLengths(key, nonce); + var m = new Uint8Array(crypto_secretbox_ZEROBYTES + msg.length); + var c = new Uint8Array(m.length); + for (var i = 0; i < msg.length; i++) m[i + crypto_secretbox_ZEROBYTES] = msg[i]; + crypto_secretbox(c, m, m.length, nonce, key); + return c.subarray(crypto_secretbox_BOXZEROBYTES); }; -nacl.secretbox.open = function(box, nonce, key) { - checkArrayTypes(box, nonce, key); - checkLengths(key, nonce); - var c = new Uint8Array(crypto_secretbox_BOXZEROBYTES + box.length); - var m = new Uint8Array(c.length); - for (var i = 0; i < box.length; i++) c[i+crypto_secretbox_BOXZEROBYTES] = box[i]; - if (c.length < 32) return false; - if (crypto_secretbox_open(m, c, c.length, nonce, key) !== 0) return false; - return m.subarray(crypto_secretbox_ZEROBYTES); +nacl.secretbox.open = function (box, nonce, key) { + checkArrayTypes(box, nonce, key); + checkLengths(key, nonce); + var c = new Uint8Array(crypto_secretbox_BOXZEROBYTES + box.length); + var m = new Uint8Array(c.length); + for (var i = 0; i < box.length; i++) c[i + crypto_secretbox_BOXZEROBYTES] = box[i]; + if (c.length < 32) return false; + if (crypto_secretbox_open(m, c, c.length, nonce, key) !== 0) return false; + return m.subarray(crypto_secretbox_ZEROBYTES); }; nacl.secretbox.keyLength = crypto_secretbox_KEYBYTES; nacl.secretbox.nonceLength = crypto_secretbox_NONCEBYTES; nacl.secretbox.overheadLength = crypto_secretbox_BOXZEROBYTES; -nacl.scalarMult = function(n, p) { - checkArrayTypes(n, p); - if (n.length !== crypto_scalarmult_SCALARBYTES) throw new Error('bad n size'); - if (p.length !== crypto_scalarmult_BYTES) throw new Error('bad p size'); - var q = new Uint8Array(crypto_scalarmult_BYTES); - crypto_scalarmult(q, n, p); - return q; +nacl.scalarMult = function (n, p) { + checkArrayTypes(n, p); + if (n.length !== crypto_scalarmult_SCALARBYTES) throw new Error('bad n size'); + if (p.length !== crypto_scalarmult_BYTES) throw new Error('bad p size'); + var q = new Uint8Array(crypto_scalarmult_BYTES); + crypto_scalarmult(q, n, p); + return q; }; -nacl.scalarMult.base = function(n) { - checkArrayTypes(n); - if (n.length !== crypto_scalarmult_SCALARBYTES) throw new Error('bad n size'); - var q = new Uint8Array(crypto_scalarmult_BYTES); - crypto_scalarmult_base(q, n); - return q; +nacl.scalarMult.base = function (n) { + checkArrayTypes(n); + if (n.length !== crypto_scalarmult_SCALARBYTES) throw new Error('bad n size'); + var q = new Uint8Array(crypto_scalarmult_BYTES); + crypto_scalarmult_base(q, n); + return q; }; nacl.scalarMult.scalarLength = crypto_scalarmult_SCALARBYTES; nacl.scalarMult.groupElementLength = crypto_scalarmult_BYTES; -nacl.box = function(msg, nonce, publicKey, secretKey) { - var k = nacl.box.before(publicKey, secretKey); - return nacl.secretbox(msg, nonce, k); +nacl.box = function (msg, nonce, publicKey, secretKey) { + var k = nacl.box.before(publicKey, secretKey); + return nacl.secretbox(msg, nonce, k); }; -nacl.box.before = function(publicKey, secretKey) { - checkArrayTypes(publicKey, secretKey); - checkBoxLengths(publicKey, secretKey); - var k = new Uint8Array(crypto_box_BEFORENMBYTES); - crypto_box_beforenm(k, publicKey, secretKey); - return k; +nacl.box.before = function (publicKey, secretKey) { + checkArrayTypes(publicKey, secretKey); + checkBoxLengths(publicKey, secretKey); + var k = new Uint8Array(crypto_box_BEFORENMBYTES); + crypto_box_beforenm(k, publicKey, secretKey); + return k; }; nacl.box.after = nacl.secretbox; -nacl.box.open = function(msg, nonce, publicKey, secretKey) { - var k = nacl.box.before(publicKey, secretKey); - return nacl.secretbox.open(msg, nonce, k); +nacl.box.open = function (msg, nonce, publicKey, secretKey) { + var k = nacl.box.before(publicKey, secretKey); + return nacl.secretbox.open(msg, nonce, k); }; nacl.box.open.after = nacl.secretbox.open; -nacl.box.keyPair = function() { - var pk = new Uint8Array(crypto_box_PUBLICKEYBYTES); - var sk = new Uint8Array(crypto_box_SECRETKEYBYTES); - crypto_box_keypair(pk, sk); - return {publicKey: pk, secretKey: sk}; +nacl.box.keyPair = function () { + var pk = new Uint8Array(crypto_box_PUBLICKEYBYTES); + var sk = new Uint8Array(crypto_box_SECRETKEYBYTES); + crypto_box_keypair(pk, sk); + return { publicKey: pk, secretKey: sk }; }; -nacl.box.keyPair.fromSecretKey = function(secretKey) { - checkArrayTypes(secretKey); - if (secretKey.length !== crypto_box_SECRETKEYBYTES) - throw new Error('bad secret key size'); - var pk = new Uint8Array(crypto_box_PUBLICKEYBYTES); - crypto_scalarmult_base(pk, secretKey); - return {publicKey: pk, secretKey: new Uint8Array(secretKey)}; +nacl.box.keyPair.fromSecretKey = function (secretKey) { + checkArrayTypes(secretKey); + if (secretKey.length !== crypto_box_SECRETKEYBYTES) + throw new Error('bad secret key size'); + var pk = new Uint8Array(crypto_box_PUBLICKEYBYTES); + crypto_scalarmult_base(pk, secretKey); + return { publicKey: pk, secretKey: new Uint8Array(secretKey) }; }; nacl.box.publicKeyLength = crypto_box_PUBLICKEYBYTES; @@ -2288,75 +2286,75 @@ nacl.box.sharedKeyLength = crypto_box_BEFORENMBYTES; nacl.box.nonceLength = crypto_box_NONCEBYTES; nacl.box.overheadLength = nacl.secretbox.overheadLength; -nacl.sign = function(msg, secretKey) { - checkArrayTypes(msg, secretKey); - if (secretKey.length !== crypto_sign_SECRETKEYBYTES) - throw new Error('bad secret key size'); - var signedMsg = new Uint8Array(crypto_sign_BYTES+msg.length); - crypto_sign(signedMsg, msg, msg.length, secretKey); - return signedMsg; +nacl.sign = function (msg, secretKey) { + checkArrayTypes(msg, secretKey); + if (secretKey.length !== crypto_sign_SECRETKEYBYTES) + throw new Error('bad secret key size'); + var signedMsg = new Uint8Array(crypto_sign_BYTES + msg.length); + crypto_sign(signedMsg, msg, msg.length, secretKey); + return signedMsg; }; -nacl.sign.open = function(signedMsg, publicKey) { - if (arguments.length !== 2) - throw new Error('nacl.sign.open accepts 2 arguments; did you mean to use nacl.sign.detached.verify?'); - checkArrayTypes(signedMsg, publicKey); - if (publicKey.length !== crypto_sign_PUBLICKEYBYTES) - throw new Error('bad public key size'); - var tmp = new Uint8Array(signedMsg.length); - var mlen = crypto_sign_open(tmp, signedMsg, signedMsg.length, publicKey); - if (mlen < 0) return null; - var m = new Uint8Array(mlen); - for (var i = 0; i < m.length; i++) m[i] = tmp[i]; - return m; +nacl.sign.open = function (signedMsg, publicKey) { + if (arguments.length !== 2) + throw new Error('nacl.sign.open accepts 2 arguments; did you mean to use nacl.sign.detached.verify?'); + checkArrayTypes(signedMsg, publicKey); + if (publicKey.length !== crypto_sign_PUBLICKEYBYTES) + throw new Error('bad public key size'); + var tmp = new Uint8Array(signedMsg.length); + var mlen = crypto_sign_open(tmp, signedMsg, signedMsg.length, publicKey); + if (mlen < 0) return null; + var m = new Uint8Array(mlen); + for (var i = 0; i < m.length; i++) m[i] = tmp[i]; + return m; }; -nacl.sign.detached = function(msg, secretKey) { - var signedMsg = nacl.sign(msg, secretKey); - var sig = new Uint8Array(crypto_sign_BYTES); - for (var i = 0; i < sig.length; i++) sig[i] = signedMsg[i]; - return sig; +nacl.sign.detached = function (msg, secretKey) { + var signedMsg = nacl.sign(msg, secretKey); + var sig = new Uint8Array(crypto_sign_BYTES); + for (var i = 0; i < sig.length; i++) sig[i] = signedMsg[i]; + return sig; }; -nacl.sign.detached.verify = function(msg, sig, publicKey) { - checkArrayTypes(msg, sig, publicKey); - if (sig.length !== crypto_sign_BYTES) - throw new Error('bad signature size'); - if (publicKey.length !== crypto_sign_PUBLICKEYBYTES) - throw new Error('bad public key size'); - var sm = new Uint8Array(crypto_sign_BYTES + msg.length); - var m = new Uint8Array(crypto_sign_BYTES + msg.length); - var i; - for (i = 0; i < crypto_sign_BYTES; i++) sm[i] = sig[i]; - for (i = 0; i < msg.length; i++) sm[i+crypto_sign_BYTES] = msg[i]; - return (crypto_sign_open(m, sm, sm.length, publicKey) >= 0); +nacl.sign.detached.verify = function (msg, sig, publicKey) { + checkArrayTypes(msg, sig, publicKey); + if (sig.length !== crypto_sign_BYTES) + throw new Error('bad signature size'); + if (publicKey.length !== crypto_sign_PUBLICKEYBYTES) + throw new Error('bad public key size'); + var sm = new Uint8Array(crypto_sign_BYTES + msg.length); + var m = new Uint8Array(crypto_sign_BYTES + msg.length); + var i; + for (i = 0; i < crypto_sign_BYTES; i++) sm[i] = sig[i]; + for (i = 0; i < msg.length; i++) sm[i + crypto_sign_BYTES] = msg[i]; + return (crypto_sign_open(m, sm, sm.length, publicKey) >= 0); }; -nacl.sign.keyPair = function() { - var pk = new Uint8Array(crypto_sign_PUBLICKEYBYTES); - var sk = new Uint8Array(crypto_sign_SECRETKEYBYTES); - crypto_sign_keypair(pk, sk); - return {publicKey: pk, secretKey: sk}; +nacl.sign.keyPair = function () { + var pk = new Uint8Array(crypto_sign_PUBLICKEYBYTES); + var sk = new Uint8Array(crypto_sign_SECRETKEYBYTES); + crypto_sign_keypair(pk, sk); + return { publicKey: pk, secretKey: sk }; }; -nacl.sign.keyPair.fromSecretKey = function(secretKey) { - checkArrayTypes(secretKey); - if (secretKey.length !== crypto_sign_SECRETKEYBYTES) - throw new Error('bad secret key size'); - var pk = new Uint8Array(crypto_sign_PUBLICKEYBYTES); - for (var i = 0; i < pk.length; i++) pk[i] = secretKey[32+i]; - return {publicKey: pk, secretKey: new Uint8Array(secretKey)}; +nacl.sign.keyPair.fromSecretKey = function (secretKey) { + checkArrayTypes(secretKey); + if (secretKey.length !== crypto_sign_SECRETKEYBYTES) + throw new Error('bad secret key size'); + var pk = new Uint8Array(crypto_sign_PUBLICKEYBYTES); + for (var i = 0; i < pk.length; i++) pk[i] = secretKey[32 + i]; + return { publicKey: pk, secretKey: new Uint8Array(secretKey) }; }; -nacl.sign.keyPair.fromSeed = function(seed) { - checkArrayTypes(seed); - if (seed.length !== crypto_sign_SEEDBYTES) - throw new Error('bad seed size'); - var pk = new Uint8Array(crypto_sign_PUBLICKEYBYTES); - var sk = new Uint8Array(crypto_sign_SECRETKEYBYTES); - for (var i = 0; i < 32; i++) sk[i] = seed[i]; - crypto_sign_keypair(pk, sk, true); - return {publicKey: pk, secretKey: sk}; +nacl.sign.keyPair.fromSeed = function (seed) { + checkArrayTypes(seed); + if (seed.length !== crypto_sign_SEEDBYTES) + throw new Error('bad seed size'); + var pk = new Uint8Array(crypto_sign_PUBLICKEYBYTES); + var sk = new Uint8Array(crypto_sign_SECRETKEYBYTES); + for (var i = 0; i < 32; i++) sk[i] = seed[i]; + crypto_sign_keypair(pk, sk, true); + return { publicKey: pk, secretKey: sk }; }; nacl.sign.publicKeyLength = crypto_sign_PUBLICKEYBYTES; @@ -2364,59 +2362,58 @@ nacl.sign.secretKeyLength = crypto_sign_SECRETKEYBYTES; nacl.sign.seedLength = crypto_sign_SEEDBYTES; nacl.sign.signatureLength = crypto_sign_BYTES; -nacl.hash = function(msg) { - checkArrayTypes(msg); - var h = new Uint8Array(crypto_hash_BYTES); - crypto_hash(h, msg, msg.length); - return h; +nacl.hash = function (msg) { + checkArrayTypes(msg); + var h = new Uint8Array(crypto_hash_BYTES); + crypto_hash(h, msg, msg.length); + return h; }; nacl.hash.hashLength = crypto_hash_BYTES; -nacl.verify = function(x, y) { - checkArrayTypes(x, y); - // Zero length arguments are considered not equal. - if (x.length === 0 || y.length === 0) return false; - if (x.length !== y.length) return false; - return (vn(x, 0, y, 0, x.length) === 0); +nacl.verify = function (x, y) { + checkArrayTypes(x, y); + // Zero length arguments are considered not equal. + if (x.length === 0 || y.length === 0) return false; + if (x.length !== y.length) return false; + return (vn(x, 0, y, 0, x.length) === 0); }; -nacl.setPRNG = function(fn) { - randombytes = fn; +nacl.setPRNG = function (fn) { + randombytes = fn; }; -(function() { - // Initialize PRNG if environment provides CSPRNG. - // If not, methods calling randombytes will throw. - var crypto; - if (typeof window !== 'undefined') { - // Browser. - if (window.crypto && window.crypto.getRandomValues) { - crypto = window.crypto; // Standard - } else if (window.msCrypto && window.msCrypto.getRandomValues) { - crypto = window.msCrypto; // Internet Explorer 11+ - } - if (crypto) { - nacl.setPRNG(function(x, n) { - var i, v = new Uint8Array(n); - crypto.getRandomValues(v); - for (i = 0; i < n; i++) x[i] = v[i]; - cleanup(v); - }); - } - } else if (typeof require !== 'undefined') { - // Node.js. - crypto = require('crypto'); - if (crypto) { - nacl.setPRNG(function(x, n) { - var i, v = crypto.randomBytes(n); - for (i = 0; i < n; i++) x[i] = v[i]; - cleanup(v); - }); - } - } +(function () { + // Initialize PRNG if environment provides CSPRNG. + // If not, methods calling randombytes will throw. + var crypto; + if (typeof window !== 'undefined') { + // Browser. + if (window.crypto && window.crypto.getRandomValues) { + crypto = window.crypto; // Standard + } else if (window.msCrypto && window.msCrypto.getRandomValues) { + crypto = window.msCrypto; // Internet Explorer 11+ + } + if (crypto) { + nacl.setPRNG(function (x, n) { + var i, v = new Uint8Array(n); + crypto.getRandomValues(v); + for (i = 0; i < n; i++) x[i] = v[i]; + cleanup(v); + }); + } + } else if (typeof require !== 'undefined') { + // Node.js. + crypto = require('crypto'); + if (crypto) { + nacl.setPRNG(function (x, n) { + var i, v = crypto.randomBytes(n); + for (i = 0; i < n; i++) x[i] = v[i]; + cleanup(v); + }); + } + } })(); // == CHANGE TO ES6 EXPORT == // -//})(typeof module !== 'undefined' && module.exports ? module.exports : (window.nacl = window.nacl || {})); export default nacl diff --git a/crypto/api/deps/qora.js b/crypto/api/deps/qora.js index 5c52ec44..bc385942 100644 --- a/crypto/api/deps/qora.js +++ b/crypto/api/deps/qora.js @@ -26,9 +26,8 @@ const TYPES = { MESSAGE_TRANSACTION: 17 }; -function getKeyPairFromSeed(seed, returnBase58) -{ - if(typeof(seed) == "string") { +function getKeyPairFromSeed(seed, returnBase58) { + if (typeof (seed) == "string") { seed = new Uint8Array(Base58.decode(seed)); } @@ -36,7 +35,7 @@ function getKeyPairFromSeed(seed, returnBase58) var base58privateKey = Base58.encode(keyPair.secretKey); var base58publicKey = Base58.encode(keyPair.publicKey); - if(returnBase58) { + if (returnBase58) { return { privateKey: Base58.encode(keyPair.secretKey), publicKey: Base58.encode(keyPair.publicKey) @@ -51,16 +50,16 @@ function getKeyPairFromSeed(seed, returnBase58) function stringtoUTF8Array(message) { if (typeof message == 'string') { - var s = unescape(encodeURIComponent(message)); // UTF-8 - message = new Uint8Array(s.length); - for (var i = 0; i < s.length; i++) { + var s = unescape(encodeURIComponent(message)); // UTF-8 + message = new Uint8Array(s.length); + for (var i = 0; i < s.length; i++) { message[i] = s.charCodeAt(i) & 0xff; } } return message; } -function int32ToBytes (word) { +function int32ToBytes(word) { var byteArray = []; for (var b = 0; b < 32; b += 8) { byteArray.push((word >>> (24 - b % 32)) & 0xFF); @@ -68,20 +67,20 @@ function int32ToBytes (word) { return byteArray; } -function int64ToBytes (int64) { - // we want to represent the input as a 8-bytes array - var byteArray = [0, 0, 0, 0, 0, 0, 0, 0]; +function int64ToBytes(int64) { + // we want to represent the input as a 8-bytes array + var byteArray = [0, 0, 0, 0, 0, 0, 0, 0]; - for ( var index = 0; index < byteArray.length; index ++ ) { - var byte = int64 & 0xff; - byteArray [ byteArray.length - index - 1 ] = byte; - int64 = (int64 - byte) / 256 ; - } + for (var index = 0; index < byteArray.length; index++) { + var byte = int64 & 0xff; + byteArray[byteArray.length - index - 1] = byte; + int64 = (int64 - byte) / 256; + } - return byteArray; + return byteArray; } -function appendBuffer (buffer1, buffer2) { +function appendBuffer(buffer1, buffer2) { buffer1 = new Uint8Array(buffer1); buffer2 = new Uint8Array(buffer2); var tmp = new Uint8Array(buffer1.byteLength + buffer2.byteLength); @@ -90,21 +89,18 @@ function appendBuffer (buffer1, buffer2) { return tmp; } -function equal (buf1, buf2) -{ - if (buf1.byteLength != buf2.byteLength) return false; - var dv1 = new Uint8Array(buf1); - var dv2 = new Uint8Array(buf2); - for (var i = 0; i != buf1.byteLength; i++) - { - if (dv1[i] != dv2[i]) return false; - } - return true; +function equal(buf1, buf2) { + if (buf1.byteLength != buf2.byteLength) return false; + var dv1 = new Uint8Array(buf1); + var dv2 = new Uint8Array(buf2); + for (var i = 0; i != buf1.byteLength; i++) { + if (dv1[i] != dv2[i]) return false; + } + return true; } -function generateAccountSeed(seed, nonce, returnBase58) -{ - if(typeof(seed) == "string") { +function generateAccountSeed(seed, nonce, returnBase58) { + if (typeof (seed) == "string") { seed = Base58.decode(seed); } @@ -116,7 +112,7 @@ function generateAccountSeed(seed, nonce, returnBase58) resultSeed = appendBuffer(resultSeed, seed); resultSeed = appendBuffer(resultSeed, nonceBytes); - if(returnBase58) { + if (returnBase58) { return Base58.encode(SHA256.digest(SHA256.digest(resultSeed))); } else { return new SHA256.digest(SHA256.digest(resultSeed)); @@ -124,11 +120,10 @@ function generateAccountSeed(seed, nonce, returnBase58) } -function getAccountAddressFromPublicKey(publicKey) -{ +function getAccountAddressFromPublicKey(publicKey) { var ADDRESS_VERSION = 58; // Q - if(typeof(publicKey) == "string") { + if (typeof (publicKey) == "string") { publicKey = Base58.decode(publicKey); } @@ -150,13 +145,12 @@ function getAccountAddressFromPublicKey(publicKey) return Base58.encode(addressArray); } -function getAccountAddressType(address) -{ +function getAccountAddressType(address) { try { var ADDRESS_VERSION = 58; // Q var AT_ADDRESS_VERSION = 23; // A - if(typeof(address) == "string") { + if (typeof (address) == "string") { address = Base58.decode(address); } @@ -166,14 +160,11 @@ function getAccountAddressType(address) var checkSumTwo = SHA256.digest(SHA256.digest(addressWitoutChecksum)); checkSumTwo = checkSumTwo.subarray(0, 4); - if (equal(checkSum, checkSumTwo)) - { - if(address[0] == ADDRESS_VERSION) - { + if (equal(checkSum, checkSumTwo)) { + if (address[0] == ADDRESS_VERSION) { return "standard"; } - if(address[0] == AT_ADDRESS_VERSION) - { + if (address[0] == AT_ADDRESS_VERSION) { return "at"; } } @@ -185,8 +176,7 @@ function getAccountAddressType(address) } } -function isValidAddress(address) -{ +function isValidAddress(address) { return (getAccountAddressType(address) != "invalid"); } @@ -307,8 +297,8 @@ function generateSignatureRegisterNameTransaction(keyPair, lastReference, owner, } function generateRegisterNameTransaction(keyPair, lastReference, owner, name, value, fee, timestamp, signature) { - return appendBuffer( generateRegisterNameTransactionBase(keyPair.publicKey, lastReference, owner, name, value, fee, timestamp), - signature ); + return appendBuffer(generateRegisterNameTransactionBase(keyPair.publicKey, lastReference, owner, name, value, fee, timestamp), + signature); } function generateRegisterNameTransactionBase(publicKey, lastReference, owner, name, value, fee, timestamp) { @@ -333,4 +323,4 @@ function generateRegisterNameTransactionBase(publicKey, lastReference, owner, na data = appendBuffer(data, feeBytes); return data; -} \ No newline at end of file +} diff --git a/crypto/api/deps/ripemd160.js b/crypto/api/deps/ripemd160.js index a50d0035..88f72c31 100644 --- a/crypto/api/deps/ripemd160.js +++ b/crypto/api/deps/ripemd160.js @@ -1,5 +1,7 @@ // Extracted from https://github.com/crypto-browserify/ripemd160 + const ARRAY16 = new Array(16); + const zl = initU8Array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8, diff --git a/crypto/api/deps/sha256.js b/crypto/api/deps/sha256.js index e4f718f4..4b1fcb93 100644 --- a/crypto/api/deps/sha256.js +++ b/crypto/api/deps/sha256.js @@ -3,140 +3,139 @@ const SHA256 = {}; SHA256.K = [ - 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, - 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, - 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, - 0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, - 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152, - 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, - 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, - 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, - 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, - 0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116, 0x1e376c08, - 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, - 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, - 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 + 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, + 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, + 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, + 0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, + 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152, + 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, + 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, + 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, + 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, + 0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116, 0x1e376c08, + 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, + 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, + 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 ]; // The digest function returns the hash value (digest) // as a 32 byte (typed) array. // message: the string or byte array to hash -SHA256.digest = function(message) { - var h0 = 0x6a09e667; - var h1 = 0xbb67ae85; - var h2 = 0x3c6ef372; - var h3 = 0xa54ff53a; - var h4 = 0x510e527f; - var h5 = 0x9b05688c; - var h6 = 0x1f83d9ab; - var h7 = 0x5be0cd19; - var K = SHA256.K; - if (typeof message == 'string') { - var s = unescape(encodeURIComponent(message)); // UTF-8 - message = new Uint8Array(s.length); - for (var i = 0; i < s.length; i++) { - message[i] = s.charCodeAt(i) & 0xff; - } - } - var length = message.length; - var byteLength = Math.floor((length + 72) / 64) * 64; - var wordLength = byteLength / 4; - var bitLength = length * 8; - var m = new Uint8Array(byteLength); - m.set(message); - m[length] = 0x80; - m[byteLength - 4] = bitLength >>> 24; - m[byteLength - 3] = (bitLength >>> 16) & 0xff; - m[byteLength - 2] = (bitLength >>> 8) & 0xff; - m[byteLength - 1] = bitLength & 0xff; - var words = new Int32Array(wordLength); - var byteIndex = 0; - for (var i = 0; i < words.length; i++) { - var word = m[byteIndex++] << 24; - word |= m[byteIndex++] << 16; - word |= m[byteIndex++] << 8; - word |= m[byteIndex++]; - words[i] = word; - } - var w = new Int32Array(64); - for (var j = 0; j < wordLength; j += 16) { - for (i = 0; i < 16; i++) { - w[i] = words[j + i]; - } - for (i = 16; i < 64; i++) { - var v = w[i - 15]; - var s0 = (v >>> 7) | (v << 25); - s0 ^= (v >>> 18) | (v << 14); - s0 ^= (v >>> 3); - v = w[i - 2]; - var s1 = (v >>> 17) | (v << 15); - s1 ^= (v >>> 19) | (v << 13); - s1 ^= (v >>> 10); - w[i] = (w[i - 16] + s0 + w[i - 7] + s1) & 0xffffffff; - } - var a = h0; - var b = h1; - var c = h2; - var d = h3; - var e = h4; - var f = h5; - var g = h6; - var h = h7; - for (i = 0; i < 64; i++) { - s1 = (e >>> 6) | (e << 26); - s1 ^= (e >>> 11) | (e << 21); - s1 ^= (e >>> 25) | (e << 7); - var ch = (e & f) ^ (~e & g); - var temp1 = (h + s1 + ch + K[i] + w[i]) & 0xffffffff; - s0 = (a >>> 2) | (a << 30); - s0 ^= (a >>> 13) | (a << 19); - s0 ^= (a >>> 22) | (a << 10); - var maj = (a & b) ^ (a & c) ^ (b & c); - var temp2 = (s0 + maj) & 0xffffffff; - h = g - g = f - f = e - e = (d + temp1) & 0xffffffff; - d = c; - c = b; - b = a; - a = (temp1 + temp2) & 0xffffffff; - } - h0 = (h0 + a) & 0xffffffff; - h1 = (h1 + b) & 0xffffffff; - h2 = (h2 + c) & 0xffffffff; - h3 = (h3 + d) & 0xffffffff; - h4 = (h4 + e) & 0xffffffff; - h5 = (h5 + f) & 0xffffffff; - h6 = (h6 + g) & 0xffffffff; - h7 = (h7 + h) & 0xffffffff; - } - var hash = new Uint8Array(32); - for (var i = 0; i < 4; i++) { - hash[i] = (h0 >>> (8 * (3 - i))) & 0xff; - hash[i + 4] = (h1 >>> (8 * (3 - i))) & 0xff; - hash[i + 8] = (h2 >>> (8 * (3 - i))) & 0xff; - hash[i + 12] = (h3 >>> (8 * (3 - i))) & 0xff; - hash[i + 16] = (h4 >>> (8 * (3 - i))) & 0xff; - hash[i + 20] = (h5 >>> (8 * (3 - i))) & 0xff; - hash[i + 24] = (h6 >>> (8 * (3 - i))) & 0xff; - hash[i + 28] = (h7 >>> (8 * (3 - i))) & 0xff; - } - return hash; -} +SHA256.digest = function (message) { + var h0 = 0x6a09e667; + var h1 = 0xbb67ae85; + var h2 = 0x3c6ef372; + var h3 = 0xa54ff53a; + var h4 = 0x510e527f; + var h5 = 0x9b05688c; + var h6 = 0x1f83d9ab; + var h7 = 0x5be0cd19; + var K = SHA256.K; + if (typeof message == 'string') { + var s = unescape(encodeURIComponent(message)); // UTF-8 + message = new Uint8Array(s.length); + for (var i = 0; i < s.length; i++) { + message[i] = s.charCodeAt(i) & 0xff; + } + } + var length = message.length; + var byteLength = Math.floor((length + 72) / 64) * 64; + var wordLength = byteLength / 4; + var bitLength = length * 8; + var m = new Uint8Array(byteLength); + m.set(message); + m[length] = 0x80; + m[byteLength - 4] = bitLength >>> 24; + m[byteLength - 3] = (bitLength >>> 16) & 0xff; + m[byteLength - 2] = (bitLength >>> 8) & 0xff; + m[byteLength - 1] = bitLength & 0xff; + var words = new Int32Array(wordLength); + var byteIndex = 0; + for (var i = 0; i < words.length; i++) { + var word = m[byteIndex++] << 24; + word |= m[byteIndex++] << 16; + word |= m[byteIndex++] << 8; + word |= m[byteIndex++]; + words[i] = word; + } + var w = new Int32Array(64); + for (var j = 0; j < wordLength; j += 16) { + for (i = 0; i < 16; i++) { + w[i] = words[j + i]; + } + for (i = 16; i < 64; i++) { + var v = w[i - 15]; + var s0 = (v >>> 7) | (v << 25); + s0 ^= (v >>> 18) | (v << 14); + s0 ^= (v >>> 3); + v = w[i - 2]; + var s1 = (v >>> 17) | (v << 15); + s1 ^= (v >>> 19) | (v << 13); + s1 ^= (v >>> 10); + w[i] = (w[i - 16] + s0 + w[i - 7] + s1) & 0xffffffff; + } + var a = h0; + var b = h1; + var c = h2; + var d = h3; + var e = h4; + var f = h5; + var g = h6; + var h = h7; + for (i = 0; i < 64; i++) { + s1 = (e >>> 6) | (e << 26); + s1 ^= (e >>> 11) | (e << 21); + s1 ^= (e >>> 25) | (e << 7); + var ch = (e & f) ^ (~e & g); + var temp1 = (h + s1 + ch + K[i] + w[i]) & 0xffffffff; + s0 = (a >>> 2) | (a << 30); + s0 ^= (a >>> 13) | (a << 19); + s0 ^= (a >>> 22) | (a << 10); + var maj = (a & b) ^ (a & c) ^ (b & c); + var temp2 = (s0 + maj) & 0xffffffff; + h = g + g = f + f = e + e = (d + temp1) & 0xffffffff; + d = c; + c = b; + b = a; + a = (temp1 + temp2) & 0xffffffff; + } + h0 = (h0 + a) & 0xffffffff; + h1 = (h1 + b) & 0xffffffff; + h2 = (h2 + c) & 0xffffffff; + h3 = (h3 + d) & 0xffffffff; + h4 = (h4 + e) & 0xffffffff; + h5 = (h5 + f) & 0xffffffff; + h6 = (h6 + g) & 0xffffffff; + h7 = (h7 + h) & 0xffffffff; + } + var hash = new Uint8Array(32); + for (var i = 0; i < 4; i++) { + hash[i] = (h0 >>> (8 * (3 - i))) & 0xff; + hash[i + 4] = (h1 >>> (8 * (3 - i))) & 0xff; + hash[i + 8] = (h2 >>> (8 * (3 - i))) & 0xff; + hash[i + 12] = (h3 >>> (8 * (3 - i))) & 0xff; + hash[i + 16] = (h4 >>> (8 * (3 - i))) & 0xff; + hash[i + 20] = (h5 >>> (8 * (3 - i))) & 0xff; + hash[i + 24] = (h6 >>> (8 * (3 - i))) & 0xff; + hash[i + 28] = (h7 >>> (8 * (3 - i))) & 0xff; + } + return hash; +} // The hash function returns the hash value as a hex string. // message: the string or byte array to hash -SHA256.hash = function(message) { - var digest = SHA256.digest(message); - var hex = ''; +SHA256.hash = function (message) { + var digest = SHA256.digest(message); + var hex = ''; for (var i = 0; i < digest.length; i++) { var s = '0' + digest[i].toString(16); - hex += s.length > 2 ? s.substring(1) : s; + hex += s.length > 2 ? s.substring(1) : s; } - return hex; + return hex; } - // == Convert to ES6 Module == // -export default SHA256; \ No newline at end of file +export default SHA256; diff --git a/crypto/api/deps/utils.js b/crypto/api/deps/utils.js index 20715934..ae83d18d 100644 --- a/crypto/api/deps/utils.js +++ b/crypto/api/deps/utils.js @@ -1,74 +1,73 @@ -'use strict' const utils = { - int32ToBytes(word) { - var byteArray = [] - for (var b = 0; b < 32; b += 8) { - byteArray.push((word >>> (24 - b % 32)) & 0xFF) - } - return byteArray - }, + int32ToBytes(word) { + var byteArray = [] + for (var b = 0; b < 32; b += 8) { + byteArray.push((word >>> (24 - b % 32)) & 0xFF) + } + return byteArray + }, - stringtoUTF8Array(message) { - if (typeof message === 'string') { - var s = unescape(encodeURIComponent(message)) // UTF-8 - message = new Uint8Array(s.length) - for (var i = 0; i < s.length; i++) { - message[i] = s.charCodeAt(i) & 0xff - } - } - return message - }, - // ...buffers then buffers.foreach and append to buffer1 - appendBuffer(buffer1, buffer2) { - buffer1 = new Uint8Array(buffer1) - buffer2 = new Uint8Array(buffer2) - let tmp = new Uint8Array(buffer1.byteLength + buffer2.byteLength) - tmp.set(buffer1, 0) - tmp.set(buffer2, buffer1.byteLength) - return tmp - }, + stringtoUTF8Array(message) { + if (typeof message === 'string') { + var s = unescape(encodeURIComponent(message)) // UTF-8 + message = new Uint8Array(s.length) + for (var i = 0; i < s.length; i++) { + message[i] = s.charCodeAt(i) & 0xff + } + } + return message + }, + // ...buffers then buffers.foreach and append to buffer1 + appendBuffer(buffer1, buffer2) { + buffer1 = new Uint8Array(buffer1) + buffer2 = new Uint8Array(buffer2) + let tmp = new Uint8Array(buffer1.byteLength + buffer2.byteLength) + tmp.set(buffer1, 0) + tmp.set(buffer2, buffer1.byteLength) + return tmp + }, - int64ToBytes(int64) { - // we want to represent the input as a 8-bytes array - var byteArray = [0, 0, 0, 0, 0, 0, 0, 0] + int64ToBytes(int64) { + // we want to represent the input as a 8-bytes array + var byteArray = [0, 0, 0, 0, 0, 0, 0, 0] - for (var index = 0; index < byteArray.length; index++) { - var byte = int64 & 0xff - byteArray[byteArray.length - index - 1] = byte - int64 = (int64 - byte) / 256 - } + for (var index = 0; index < byteArray.length; index++) { + var byte = int64 & 0xff + byteArray[byteArray.length - index - 1] = byte + int64 = (int64 - byte) / 256 + } - return byteArray - }, + return byteArray + }, - hexToBytes(hexString) { - return new Uint8Array(hexString.match(/.{1,2}/g).map(byte => parseInt(byte, 16))) - }, + hexToBytes(hexString) { + return new Uint8Array(hexString.match(/.{1,2}/g).map(byte => parseInt(byte, 16))) + }, - stringToHex(bytes) { - return bytes.reduce((str, byte) => str + byte.toString(16).padStart(2, '0'), '') - }, + stringToHex(bytes) { + return bytes.reduce((str, byte) => str + byte.toString(16).padStart(2, '0'), '') + }, - equal(buf1, buf2) { - if (buf1.byteLength != buf2.byteLength) return false - var dv1 = new Uint8Array(buf1) - var dv2 = new Uint8Array(buf2) - for (var i = 0; i != buf1.byteLength; i++) { - if (dv1[i] != dv2[i]) return false - } - return true - }, + equal(buf1, buf2) { + if (buf1.byteLength != buf2.byteLength) return false + var dv1 = new Uint8Array(buf1) + var dv2 = new Uint8Array(buf2) + for (var i = 0; i != buf1.byteLength; i++) { + if (dv1[i] != dv2[i]) return false + } + return true + }, - bytesToHex(byteArray) { - var _byteArrayToHex = [] + bytesToHex(byteArray) { + var _byteArrayToHex = [] - for (var index = 0; index < byteArray.length; index++) { - _byteArrayToHex.push((byteArray[index] >>> 4).toString(16)) - _byteArrayToHex.push((byteArray[index] & 15).toString(16)); - } + for (var index = 0; index < byteArray.length; index++) { + _byteArrayToHex.push((byteArray[index] >>> 4).toString(16)) + _byteArrayToHex.push((byteArray[index] & 15).toString(16)); + } - return _byteArrayToHex.join("") - } + return _byteArrayToHex.join("") + } } export default utils diff --git a/crypto/api/fetch-request.js b/crypto/api/fetch-request.js index 6adab74c..7c0201ee 100644 --- a/crypto/api/fetch-request.js +++ b/crypto/api/fetch-request.js @@ -1,4 +1,4 @@ -import {waitForConfig, watchConfig} from '../config.js' +import { waitForConfig, watchConfig } from '../config' let config = {} diff --git a/crypto/api/kdf.js b/crypto/api/kdf.js index 2c64d5d9..c71ef89e 100644 --- a/crypto/api/kdf.js +++ b/crypto/api/kdf.js @@ -1,11 +1,11 @@ -import {store} from '../api_deps.js' -import {stateAwait} from './utils/stateAwait.js' -import {Sha512} from 'asmcrypto.js' -import utils from '../api/deps/utils.js' -import {get, registerTranslateConfig} from '../../core/translate' +import { store } from '../api_deps' +import { stateAwait } from './utils/stateAwait' +import { Sha512 } from 'asmcrypto.js' +import utils from '../api/deps/utils' +import { get, registerTranslateConfig } from '../../core/translate' registerTranslateConfig({ - loader: lang => fetch(`/language/${lang}.json`).then(res => res.json()) + loader: lang => fetch(`/language/${lang}.json`).then(res => res.json()) }) export const kdf = async (seed, salt, status = () => { }) => { diff --git a/crypto/api/registerUsername.js b/crypto/api/registerUsername.js index 1092e756..377e7d15 100644 --- a/crypto/api/registerUsername.js +++ b/crypto/api/registerUsername.js @@ -1,7 +1,7 @@ /** * Not to be confused with register name...this is a special use case */ -import {createTransaction, processTransaction, request} from './api.js' +import { createTransaction, processTransaction, request } from './api' const TX_TYPE = 3 // NAME_REGISTRATION const CHECK_LAST_REF_INTERVAL = 30 * 1000 // err 30 seconds diff --git a/crypto/api/storeWallet.js b/crypto/api/storeWallet.js index f63a2ce2..6e9061a6 100644 --- a/crypto/api/storeWallet.js +++ b/crypto/api/storeWallet.js @@ -1,6 +1,6 @@ -import {AES_CBC, HmacSha512} from 'asmcrypto.js' -import {kdf} from './kdf.js' -import Base58 from './deps/Base58.js' +import { AES_CBC, HmacSha512 } from 'asmcrypto.js' +import { kdf } from './kdf' +import Base58 from './deps/Base58' const getRandomValues = window.crypto ? window.crypto.getRandomValues.bind(window.crypto) : window.msCrypto.getRandomValues.bind(window.msCrypto) diff --git a/crypto/api/tradeRequest.js b/crypto/api/tradeRequest.js index 892c1318..447244f0 100644 --- a/crypto/api/tradeRequest.js +++ b/crypto/api/tradeRequest.js @@ -1,9 +1,9 @@ // Trade Bot -import TradeBotCreateRequest from './transactions/trade-portal/tradebot/TradeBotCreateRequest.js' -import TradeBotRespondRequest from './transactions/trade-portal/tradebot/TradeBotRespondRequest.js' -import signTradeBotTransaction from './transactions/trade-portal/tradebot/signTradeBotTransaction.js' -import DeleteTradeOffer from './transactions/trade-portal/tradeoffer/DeleteTradeOffer.js' -import {request} from './fetch-request' +import TradeBotCreateRequest from './transactions/trade-portal/tradebot/TradeBotCreateRequest' +import TradeBotRespondRequest from './transactions/trade-portal/tradebot/TradeBotRespondRequest' +import signTradeBotTransaction from './transactions/trade-portal/tradebot/signTradeBotTransaction' +import DeleteTradeOffer from './transactions/trade-portal/tradeoffer/DeleteTradeOffer' +import { request } from './fetch-request' // TradeBotCreateRequest export const tradeBotCreateRequest = (requestObject) => { diff --git a/crypto/api/transactions/AirdropTransaction.js b/crypto/api/transactions/AirdropTransaction.js index 04aa8acf..007ed7ff 100644 --- a/crypto/api/transactions/AirdropTransaction.js +++ b/crypto/api/transactions/AirdropTransaction.js @@ -1,5 +1,5 @@ import TransactionBase from './TransactionBase' -import {QORT_DECIMALS} from '../constants' +import { QORT_DECIMALS } from '../constants' export default class PaymentTransaction extends TransactionBase { constructor() { diff --git a/crypto/api/transactions/DeployAtTransaction.js b/crypto/api/transactions/DeployAtTransaction.js index 4b77f21e..2ebfe957 100644 --- a/crypto/api/transactions/DeployAtTransaction.js +++ b/crypto/api/transactions/DeployAtTransaction.js @@ -1,6 +1,6 @@ import TransactionBase from './TransactionBase' -import {store} from '../../api' -import {QORT_DECIMALS} from '../constants' +import { store } from '../../api' +import { QORT_DECIMALS } from '../constants' export default class DeployAtTransaction extends TransactionBase { constructor() { diff --git a/crypto/api/transactions/PaymentTransaction.js b/crypto/api/transactions/PaymentTransaction.js index ad3c023b..df11e5b5 100644 --- a/crypto/api/transactions/PaymentTransaction.js +++ b/crypto/api/transactions/PaymentTransaction.js @@ -1,6 +1,6 @@ import TransactionBase from './TransactionBase' import Base58 from '../deps/Base58' -import {store} from '../../api' +import { store } from '../../api' export default class PaymentTransaction extends TransactionBase { constructor() { diff --git a/crypto/api/transactions/PublicizeTransaction.js b/crypto/api/transactions/PublicizeTransaction.js index 42e5ba50..44660da1 100644 --- a/crypto/api/transactions/PublicizeTransaction.js +++ b/crypto/api/transactions/PublicizeTransaction.js @@ -1,5 +1,5 @@ import ChatBase from './chat/ChatBase' -import {QORT_DECIMALS} from '../constants' +import { QORT_DECIMALS } from '../constants' export default class PublicizeTransaction extends ChatBase { constructor() { @@ -8,21 +8,21 @@ export default class PublicizeTransaction extends ChatBase { this.fee = 0 } - set proofOfWorkNonce(proofOfWorkNonce) { - this._proofOfWorkNonce = this.constructor.utils.int32ToBytes(proofOfWorkNonce) - } + set proofOfWorkNonce(proofOfWorkNonce) { + this._proofOfWorkNonce = this.constructor.utils.int32ToBytes(proofOfWorkNonce) + } - set fee(fee) { - this._fee = fee * QORT_DECIMALS - this._feeBytes = this.constructor.utils.int64ToBytes(this._fee) - } + set fee(fee) { + this._fee = fee * QORT_DECIMALS + this._feeBytes = this.constructor.utils.int64ToBytes(this._fee) + } - get params() { - const params = super.params - params.push( - this._proofOfWorkNonce, - this._feeBytes - ) - return params - } + get params() { + const params = super.params + params.push( + this._proofOfWorkNonce, + this._feeBytes + ) + return params + } } diff --git a/crypto/api/transactions/TransactionBase.js b/crypto/api/transactions/TransactionBase.js index c5a96068..5e327116 100644 --- a/crypto/api/transactions/TransactionBase.js +++ b/crypto/api/transactions/TransactionBase.js @@ -1,4 +1,4 @@ -import {QORT_DECIMALS, TX_TYPES} from '../constants' +import { QORT_DECIMALS, TX_TYPES } from '../constants' import nacl from '../deps/nacl-fast' import Base58 from '../deps/Base58' import utils from '../deps/utils' diff --git a/crypto/api/transactions/TransferPrivsTransaction.js b/crypto/api/transactions/TransferPrivsTransaction.js index b9eaf809..6aaff1b9 100644 --- a/crypto/api/transactions/TransferPrivsTransaction.js +++ b/crypto/api/transactions/TransferPrivsTransaction.js @@ -1,6 +1,6 @@ import TransactionBase from './TransactionBase' -import {store} from '../../api' -import {QORT_DECIMALS} from '../constants' +import { store } from '../../api' +import { QORT_DECIMALS } from '../constants' export default class TransferPrivsTransaction extends TransactionBase { constructor() { diff --git a/crypto/api/transactions/arbitraryV3.js b/crypto/api/transactions/arbitraryV3.js index dd871aac..515b4044 100644 --- a/crypto/api/transactions/arbitraryV3.js +++ b/crypto/api/transactions/arbitraryV3.js @@ -1,38 +1,36 @@ -'use strict' +(function () { + function generateSignatureArbitraryTransactionV3(keyPair, lastReference, service, arbitraryData, fee, timestamp) => { + const data = generateArbitraryTransactionV3Base(keyPair.publicKey, lastReference, service, arbitraryData, fee, timestamp) + return nacl.sign.detached(data, keyPair.privateKey) + } - (function () { - function generateSignatureArbitraryTransactionV3(keyPair, lastReference, service, arbitraryData, fee, timestamp) => { - const data = generateArbitraryTransactionV3Base(keyPair.publicKey, lastReference, service, arbitraryData, fee, timestamp) - return nacl.sign.detached(data, keyPair.privateKey) - } + function generateArbitraryTransactionV3(keyPair, lastReference, service, arbitraryData, fee, timestamp, signature) => { + return appendBuffer(generateArbitraryTransactionV3Base(keyPair.publicKey, lastReference, service, arbitraryData, fee, timestamp), signature) + } - function generateArbitraryTransactionV3(keyPair, lastReference, service, arbitraryData, fee, timestamp, signature) => { - return appendBuffer(generateArbitraryTransactionV3Base(keyPair.publicKey, lastReference, service, arbitraryData, fee, timestamp), signature) - } + function generateArbitraryTransactionV3Base(publicKey, lastReference, service, arbitraryData, fee, timestamp) => { + const txType = TYPES.ARBITRARY_TRANSACTION + const typeBytes = int32ToBytes(txType) + const timestampBytes = int64ToBytes(timestamp) + const feeBytes = int64ToBytes(fee * 100000000) + const serviceBytes = int32ToBytes(service) + const dataSizeBytes = int32ToBytes(arbitraryData.length) + const paymentsLengthBytes = int32ToBytes(0) // Support payments - not yet. - function generateArbitraryTransactionV3Base(publicKey, lastReference, service, arbitraryData, fee, timestamp) => { - const txType = TYPES.ARBITRARY_TRANSACTION - const typeBytes = int32ToBytes(txType) - const timestampBytes = int64ToBytes(timestamp) - const feeBytes = int64ToBytes(fee * 100000000) - const serviceBytes = int32ToBytes(service) - const dataSizeBytes = int32ToBytes(arbitraryData.length) - const paymentsLengthBytes = int32ToBytes(0) // Support payments - not yet. + var data = new Uint8Array() - var data = new Uint8Array() + data = appendBuffer(data, typeBytes) + data = appendBuffer(data, timestampBytes) + data = appendBuffer(data, lastReference) + data = appendBuffer(data, publicKey) + data = appendBuffer(data, paymentsLengthBytes) - data = appendBuffer(data, typeBytes) - data = appendBuffer(data, timestampBytes) - data = appendBuffer(data, lastReference) - data = appendBuffer(data, publicKey) - data = appendBuffer(data, paymentsLengthBytes) + // Here it is necessary to insert the payments, if there are + data = appendBuffer(data, serviceBytes) + data = appendBuffer(data, dataSizeBytes) + data = appendBuffer(data, arbitraryData) + data = appendBuffer(data, feeBytes) - // Here it is necessary to insert the payments, if there are - data = appendBuffer(data, serviceBytes) - data = appendBuffer(data, dataSizeBytes) - data = appendBuffer(data, arbitraryData) - data = appendBuffer(data, feeBytes) - - return data - } - }()) + return data + } +}()) diff --git a/crypto/api/transactions/chat/ChatBase.js b/crypto/api/transactions/chat/ChatBase.js index fe1b26f5..48429c27 100644 --- a/crypto/api/transactions/chat/ChatBase.js +++ b/crypto/api/transactions/chat/ChatBase.js @@ -1,143 +1,143 @@ -import {QORT_DECIMALS, TX_TYPES} from '../../constants' +import { QORT_DECIMALS, TX_TYPES } from '../../constants' import nacl from '../../deps/nacl-fast' import Base58 from '../../deps/Base58' import utils from '../../deps/utils' export default class ChatBase { - static get utils() { - return utils - } + static get utils() { + return utils + } - static get nacl() { - return nacl - } + static get nacl() { + return nacl + } - static get Base58() { - return Base58 - } + static get Base58() { + return Base58 + } - constructor() { - this.fee = 0 - this.groupID = 0 - this.tests = [ - () => { - if (!(this._type >= 1 && this._type in TX_TYPES)) { - return 'Invalid type: ' + this.type - } - return true - }, - () => { - if (this._fee < 0) { - return 'Invalid fee: ' + this._fee / QORT_DECIMALS - } - return true - }, - () => { - if (this._groupID < 0 || !Number.isInteger(this._groupID)) { - return 'Invalid groupID: ' + this._groupID - } - return true - }, - () => { - if (!(new Date(this._timestamp)).getTime() > 0) { - return 'Invalid timestamp: ' + this._timestamp - } - return true - }, - () => { - if (!(this._lastReference instanceof Uint8Array && this._lastReference.byteLength == 64)) { - return 'Invalid last reference: ' + this._lastReference - } - return true - }, - () => { - if (!(this._keyPair)) { - return 'keyPair must be specified' - } - if (!(this._keyPair.publicKey instanceof Uint8Array && this._keyPair.publicKey.byteLength === 32)) { - return 'Invalid publicKey' - } - if (!(this._keyPair.privateKey instanceof Uint8Array && this._keyPair.privateKey.byteLength === 64)) { - return 'Invalid privateKey' - } - return true - } - ] - } + constructor() { + this.fee = 0 + this.groupID = 0 + this.tests = [ + () => { + if (!(this._type >= 1 && this._type in TX_TYPES)) { + return 'Invalid type: ' + this.type + } + return true + }, + () => { + if (this._fee < 0) { + return 'Invalid fee: ' + this._fee / QORT_DECIMALS + } + return true + }, + () => { + if (this._groupID < 0 || !Number.isInteger(this._groupID)) { + return 'Invalid groupID: ' + this._groupID + } + return true + }, + () => { + if (!(new Date(this._timestamp)).getTime() > 0) { + return 'Invalid timestamp: ' + this._timestamp + } + return true + }, + () => { + if (!(this._lastReference instanceof Uint8Array && this._lastReference.byteLength == 64)) { + return 'Invalid last reference: ' + this._lastReference + } + return true + }, + () => { + if (!(this._keyPair)) { + return 'keyPair must be specified' + } + if (!(this._keyPair.publicKey instanceof Uint8Array && this._keyPair.publicKey.byteLength === 32)) { + return 'Invalid publicKey' + } + if (!(this._keyPair.privateKey instanceof Uint8Array && this._keyPair.privateKey.byteLength === 64)) { + return 'Invalid privateKey' + } + return true + } + ] + } - set keyPair(keyPair) { - this._keyPair = keyPair - } + set keyPair(keyPair) { + this._keyPair = keyPair + } - set type(type) { - this.typeText = TX_TYPES[type] - this._type = type - this._typeBytes = this.constructor.utils.int32ToBytes(this._type) - } + set type(type) { + this.typeText = TX_TYPES[type] + this._type = type + this._typeBytes = this.constructor.utils.int32ToBytes(this._type) + } - set groupID(groupID) { - this._groupID = groupID - this._groupIDBytes = this.constructor.utils.int32ToBytes(this._groupID) - } + set groupID(groupID) { + this._groupID = groupID + this._groupIDBytes = this.constructor.utils.int32ToBytes(this._groupID) + } - set timestamp(timestamp) { - this._timestamp = timestamp - this._timestampBytes = this.constructor.utils.int64ToBytes(this._timestamp) - } + set timestamp(timestamp) { + this._timestamp = timestamp + this._timestampBytes = this.constructor.utils.int64ToBytes(this._timestamp) + } - set fee(fee) { - this._fee = fee * QORT_DECIMALS - this._feeBytes = this.constructor.utils.int64ToBytes(this._fee) - } + set fee(fee) { + this._fee = fee * QORT_DECIMALS + this._feeBytes = this.constructor.utils.int64ToBytes(this._fee) + } - set lastReference(lastReference) { - this._lastReference = lastReference instanceof Uint8Array ? lastReference : this.constructor.Base58.decode(lastReference) - } + set lastReference(lastReference) { + this._lastReference = lastReference instanceof Uint8Array ? lastReference : this.constructor.Base58.decode(lastReference) + } - get params() { - return [ - this._typeBytes, - this._timestampBytes, - this._groupIDBytes, - this._lastReference, - this._keyPair.publicKey - ] - } + get params() { + return [ + this._typeBytes, + this._timestampBytes, + this._groupIDBytes, + this._lastReference, + this._keyPair.publicKey + ] + } - get chatBytes() { - const isValid = this.validParams() - if (!isValid.valid) { - throw new Error(isValid.message) - } + get chatBytes() { + const isValid = this.validParams() + if (!isValid.valid) { + throw new Error(isValid.message) + } - let result = new Uint8Array() + let result = new Uint8Array() - this.params.forEach(item => { - result = this.constructor.utils.appendBuffer(result, item) - }) + this.params.forEach(item => { + result = this.constructor.utils.appendBuffer(result, item) + }) - this._chatBytes = result + this._chatBytes = result - return this._chatBytes - } + return this._chatBytes + } - validParams() { - let finalResult = { - valid: true - } + validParams() { + let finalResult = { + valid: true + } - this.tests.some(test => { - const result = test() - if (result !== true) { - finalResult = { - valid: false, - message: result - } - return true - } - }) + this.tests.some(test => { + const result = test() + if (result !== true) { + finalResult = { + valid: false, + message: result + } + return true + } + }) - return finalResult - } + return finalResult + } } diff --git a/crypto/api/transactions/chat/ChatTransaction.js b/crypto/api/transactions/chat/ChatTransaction.js index 1b048aa3..96ac6471 100644 --- a/crypto/api/transactions/chat/ChatTransaction.js +++ b/crypto/api/transactions/chat/ChatTransaction.js @@ -1,8 +1,8 @@ import ChatBase from './ChatBase' import nacl from '../../deps/nacl-fast' import ed2curve from '../../deps/ed2curve' -import {Sha256} from 'asmcrypto.js' -import {CHAT_REFERENCE_FEATURE_TRIGGER_TIMESTAMP} from '../../constants' +import { Sha256 } from 'asmcrypto.js' +import { CHAT_REFERENCE_FEATURE_TRIGGER_TIMESTAMP } from '../../constants' export default class ChatTransaction extends ChatBase { constructor() { diff --git a/crypto/api/transactions/chat/GroupChatTransaction.js b/crypto/api/transactions/chat/GroupChatTransaction.js index bb69f442..e58bc1d0 100644 --- a/crypto/api/transactions/chat/GroupChatTransaction.js +++ b/crypto/api/transactions/chat/GroupChatTransaction.js @@ -1,5 +1,5 @@ import ChatBase from './ChatBase' -import {CHAT_REFERENCE_FEATURE_TRIGGER_TIMESTAMP} from '../../constants' +import { CHAT_REFERENCE_FEATURE_TRIGGER_TIMESTAMP } from '../../constants' export default class GroupChatTransaction extends ChatBase { constructor() { diff --git a/crypto/api/transactions/chat/decryptChatMessage.js b/crypto/api/transactions/chat/decryptChatMessage.js index 8f4b05df..0a88b697 100644 --- a/crypto/api/transactions/chat/decryptChatMessage.js +++ b/crypto/api/transactions/chat/decryptChatMessage.js @@ -1,7 +1,7 @@ import nacl from '../../deps/nacl-fast' import Base58 from '../../deps/Base58' import ed2curve from '../../deps/ed2curve' -import {Sha256} from 'asmcrypto.js' +import { Sha256 } from 'asmcrypto.js' export const decryptChatMessage = (encryptedMessage, privateKey, recipientPublicKey, lastReference) => { let _encryptedMessage = Base58.decode(encryptedMessage) diff --git a/crypto/api/transactions/groups/AddGroupAdminTransaction.js b/crypto/api/transactions/groups/AddGroupAdminTransaction.js index 761e0029..003100aa 100644 --- a/crypto/api/transactions/groups/AddGroupAdminTransaction.js +++ b/crypto/api/transactions/groups/AddGroupAdminTransaction.js @@ -1,5 +1,5 @@ import TransactionBase from '../TransactionBase' -import {QORT_DECIMALS} from '../../constants' +import { QORT_DECIMALS } from '../../constants' export default class AddGroupAdminTransaction extends TransactionBase { constructor() { diff --git a/crypto/api/transactions/groups/CancelGroupBanTransaction.js b/crypto/api/transactions/groups/CancelGroupBanTransaction.js index f0b11fa1..604a5f8c 100644 --- a/crypto/api/transactions/groups/CancelGroupBanTransaction.js +++ b/crypto/api/transactions/groups/CancelGroupBanTransaction.js @@ -1,5 +1,5 @@ import TransactionBase from '../TransactionBase' -import {QORT_DECIMALS} from '../../constants' +import { QORT_DECIMALS } from '../../constants' export default class CancelGroupBanTransaction extends TransactionBase { constructor() { diff --git a/crypto/api/transactions/groups/CancelGroupInviteTransaction.js b/crypto/api/transactions/groups/CancelGroupInviteTransaction.js index 8dccb6fa..a3023eb4 100644 --- a/crypto/api/transactions/groups/CancelGroupInviteTransaction.js +++ b/crypto/api/transactions/groups/CancelGroupInviteTransaction.js @@ -1,5 +1,5 @@ import TransactionBase from '../TransactionBase' -import {QORT_DECIMALS} from '../../constants' +import { QORT_DECIMALS } from '../../constants' export default class CancelGroupInviteTransaction extends TransactionBase { constructor() { diff --git a/crypto/api/transactions/groups/CreateGroupTransaction.js b/crypto/api/transactions/groups/CreateGroupTransaction.js index b81e47ee..13c8220c 100644 --- a/crypto/api/transactions/groups/CreateGroupTransaction.js +++ b/crypto/api/transactions/groups/CreateGroupTransaction.js @@ -1,5 +1,5 @@ import TransactionBase from '../TransactionBase' -import {QORT_DECIMALS} from '../../constants' +import { QORT_DECIMALS } from '../../constants' export default class CreateGroupTransaction extends TransactionBase { constructor() { diff --git a/crypto/api/transactions/groups/GroupBanTransaction.js b/crypto/api/transactions/groups/GroupBanTransaction.js index ab679f7a..6bd88b87 100644 --- a/crypto/api/transactions/groups/GroupBanTransaction.js +++ b/crypto/api/transactions/groups/GroupBanTransaction.js @@ -1,5 +1,5 @@ import TransactionBase from '../TransactionBase' -import {QORT_DECIMALS} from '../../constants' +import { QORT_DECIMALS } from '../../constants' export default class GroupBanTransaction extends TransactionBase { constructor() { diff --git a/crypto/api/transactions/groups/GroupInviteTransaction.js b/crypto/api/transactions/groups/GroupInviteTransaction.js index 20ce9bed..8e3823a6 100644 --- a/crypto/api/transactions/groups/GroupInviteTransaction.js +++ b/crypto/api/transactions/groups/GroupInviteTransaction.js @@ -1,5 +1,5 @@ import TransactionBase from '../TransactionBase' -import {QORT_DECIMALS} from '../../constants' +import { QORT_DECIMALS } from '../../constants' export default class GroupInviteTransaction extends TransactionBase { constructor() { diff --git a/crypto/api/transactions/groups/GroupKickTransaction.js b/crypto/api/transactions/groups/GroupKickTransaction.js index 77391943..6c755ac0 100644 --- a/crypto/api/transactions/groups/GroupKickTransaction.js +++ b/crypto/api/transactions/groups/GroupKickTransaction.js @@ -1,5 +1,5 @@ import TransactionBase from '../TransactionBase' -import {QORT_DECIMALS} from '../../constants' +import { QORT_DECIMALS } from '../../constants' export default class GroupKickTransaction extends TransactionBase { constructor() { diff --git a/crypto/api/transactions/groups/JoinGroupTransaction.js b/crypto/api/transactions/groups/JoinGroupTransaction.js index 4db9cb73..7c715b65 100644 --- a/crypto/api/transactions/groups/JoinGroupTransaction.js +++ b/crypto/api/transactions/groups/JoinGroupTransaction.js @@ -1,5 +1,5 @@ import TransactionBase from '../TransactionBase' -import {QORT_DECIMALS} from '../../constants' +import { QORT_DECIMALS } from '../../constants' export default class JoinGroupTransaction extends TransactionBase { constructor() { diff --git a/crypto/api/transactions/groups/LeaveGroupTransaction.js b/crypto/api/transactions/groups/LeaveGroupTransaction.js index 104cb9fe..aa8303a5 100644 --- a/crypto/api/transactions/groups/LeaveGroupTransaction.js +++ b/crypto/api/transactions/groups/LeaveGroupTransaction.js @@ -1,5 +1,5 @@ import TransactionBase from '../TransactionBase' -import {QORT_DECIMALS} from '../../constants' +import { QORT_DECIMALS } from '../../constants' export default class LeaveGroupTransaction extends TransactionBase { constructor() { diff --git a/crypto/api/transactions/groups/RemoveGroupAdminTransaction.js b/crypto/api/transactions/groups/RemoveGroupAdminTransaction.js index d0aff6a3..a648ae6f 100644 --- a/crypto/api/transactions/groups/RemoveGroupAdminTransaction.js +++ b/crypto/api/transactions/groups/RemoveGroupAdminTransaction.js @@ -1,5 +1,5 @@ import TransactionBase from '../TransactionBase' -import {QORT_DECIMALS} from '../../constants' +import { QORT_DECIMALS } from '../../constants' export default class RemoveGroupAdminTransaction extends TransactionBase { constructor() { diff --git a/crypto/api/transactions/groups/UpdateGroupTransaction.js b/crypto/api/transactions/groups/UpdateGroupTransaction.js index d080c24f..43926245 100644 --- a/crypto/api/transactions/groups/UpdateGroupTransaction.js +++ b/crypto/api/transactions/groups/UpdateGroupTransaction.js @@ -1,5 +1,5 @@ import TransactionBase from '../TransactionBase' -import {QORT_DECIMALS} from '../../constants' +import { QORT_DECIMALS } from '../../constants' export default class UpdateGroupTransaction extends TransactionBase { constructor() { diff --git a/crypto/api/transactions/names/BuyNameTransacion.js b/crypto/api/transactions/names/BuyNameTransacion.js index d41a7ab8..7e18834d 100644 --- a/crypto/api/transactions/names/BuyNameTransacion.js +++ b/crypto/api/transactions/names/BuyNameTransacion.js @@ -1,5 +1,5 @@ import TransactionBase from '../TransactionBase' -import {QORT_DECIMALS} from '../../constants' +import { QORT_DECIMALS } from '../../constants' export default class BuyNameTransacion extends TransactionBase { constructor() { diff --git a/crypto/api/transactions/names/CancelSellNameTransacion.js b/crypto/api/transactions/names/CancelSellNameTransacion.js index 5d53b3a7..483b6982 100644 --- a/crypto/api/transactions/names/CancelSellNameTransacion.js +++ b/crypto/api/transactions/names/CancelSellNameTransacion.js @@ -1,5 +1,5 @@ import TransactionBase from '../TransactionBase' -import {QORT_DECIMALS} from '../../constants' +import { QORT_DECIMALS } from '../../constants' export default class CancelSellNameTransacion extends TransactionBase { constructor() { diff --git a/crypto/api/transactions/names/RegisterNameTransaction.js b/crypto/api/transactions/names/RegisterNameTransaction.js index 7240e281..7929d367 100644 --- a/crypto/api/transactions/names/RegisterNameTransaction.js +++ b/crypto/api/transactions/names/RegisterNameTransaction.js @@ -1,5 +1,5 @@ import TransactionBase from '../TransactionBase' -import {QORT_DECIMALS} from '../../constants' +import { QORT_DECIMALS } from '../../constants' export default class RegisterNameTransaction extends TransactionBase { constructor() { diff --git a/crypto/api/transactions/names/SellNameTransacion.js b/crypto/api/transactions/names/SellNameTransacion.js index f93ea901..38db5a81 100644 --- a/crypto/api/transactions/names/SellNameTransacion.js +++ b/crypto/api/transactions/names/SellNameTransacion.js @@ -1,5 +1,5 @@ import TransactionBase from '../TransactionBase' -import {QORT_DECIMALS} from '../../constants' +import { QORT_DECIMALS } from '../../constants' export default class SellNameTransacion extends TransactionBase { constructor() { diff --git a/crypto/api/transactions/names/UpdateNameTransaction.js b/crypto/api/transactions/names/UpdateNameTransaction.js index c9f5aebe..89faf7d2 100644 --- a/crypto/api/transactions/names/UpdateNameTransaction.js +++ b/crypto/api/transactions/names/UpdateNameTransaction.js @@ -1,5 +1,5 @@ import TransactionBase from '../TransactionBase' -import {QORT_DECIMALS} from '../../constants' +import { QORT_DECIMALS } from '../../constants' export default class UpdateNameTransaction extends TransactionBase { constructor() { diff --git a/crypto/api/transactions/polls/CreatePollTransaction.js b/crypto/api/transactions/polls/CreatePollTransaction.js index fa01e9b1..07815458 100644 --- a/crypto/api/transactions/polls/CreatePollTransaction.js +++ b/crypto/api/transactions/polls/CreatePollTransaction.js @@ -1,5 +1,5 @@ import TransactionBase from '../TransactionBase' -import {QORT_DECIMALS} from '../../constants' +import { QORT_DECIMALS } from '../../constants' export default class CreatePollTransaction extends TransactionBase { constructor() { @@ -35,7 +35,7 @@ export default class CreatePollTransaction extends TransactionBase { this._options.push({ length: optionLength, bytes: optionBytes }) } - set feeDialog(feeDialog){ + set feeDialog(feeDialog) { this._feeDialog = feeDialog } @@ -106,7 +106,7 @@ export default class CreatePollTransaction extends TransactionBase { params.push(this._options[i].length, this._options[i].bytes) } - params.push(this._feeBytes); + params.push(this._feeBytes) return params } diff --git a/crypto/api/transactions/polls/VoteOnPollTransaction.js b/crypto/api/transactions/polls/VoteOnPollTransaction.js index 83a7eda9..21ce36e6 100644 --- a/crypto/api/transactions/polls/VoteOnPollTransaction.js +++ b/crypto/api/transactions/polls/VoteOnPollTransaction.js @@ -1,5 +1,5 @@ import TransactionBase from '../TransactionBase' -import {QORT_DECIMALS} from '../../constants' +import { QORT_DECIMALS } from '../../constants' export default class VoteOnPollTransaction extends TransactionBase { constructor() { @@ -20,7 +20,7 @@ export default class VoteOnPollTransaction extends TransactionBase { ` } - set feeDialog(feeDialog){ + set feeDialog(feeDialog) { this._feeDialog = feeDialog } diff --git a/crypto/api/transactions/registerName_dnsthing.js b/crypto/api/transactions/registerName_dnsthing.js index 06210cc4..c32be3a2 100644 --- a/crypto/api/transactions/registerName_dnsthing.js +++ b/crypto/api/transactions/registerName_dnsthing.js @@ -1,36 +1,34 @@ -'use strict' +(function () { + function generateSignatureRegisterNameTransaction(keyPair, lastReference, owner, name, value, fee, timestamp) => { + const data = generateRegisterNameTransactionBase(keyPair.publicKey, lastReference, owner, name, value, fee, timestamp) + return nacl.sign.detached(data, keyPair.privateKey) + } - (function () { - function generateSignatureRegisterNameTransaction(keyPair, lastReference, owner, name, value, fee, timestamp) => { - const data = generateRegisterNameTransactionBase(keyPair.publicKey, lastReference, owner, name, value, fee, timestamp) - return nacl.sign.detached(data, keyPair.privateKey) - } + function generateRegisterNameTransaction(keyPair, lastReference, owner, name, value, fee, timestamp, signature) => { + return appendBuffer(generateRegisterNameTransactionBase(keyPair.publicKey, lastReference, owner, name, value, fee, timestamp), signature) + } - function generateRegisterNameTransaction(keyPair, lastReference, owner, name, value, fee, timestamp, signature) => { - return appendBuffer(generateRegisterNameTransactionBase(keyPair.publicKey, lastReference, owner, name, value, fee, timestamp), signature) - } + function generateRegisterNameTransactionBase(publicKey, lastReference, owner, name, value, fee, timestamp) => { + const txType = TYPES.REGISTER_NAME_TRANSACTION + const typeBytes = int32ToBytes(txType) + const timestampBytes = int64ToBytes(timestamp) + const feeBytes = int64ToBytes(fee * 100000000) + const nameSizeBytes = int32ToBytes(name.length) + const valueSizeBytes = int32ToBytes(value.length) - function generateRegisterNameTransactionBase(publicKey, lastReference, owner, name, value, fee, timestamp) => { - const txType = TYPES.REGISTER_NAME_TRANSACTION - const typeBytes = int32ToBytes(txType) - const timestampBytes = int64ToBytes(timestamp) - const feeBytes = int64ToBytes(fee * 100000000) - const nameSizeBytes = int32ToBytes(name.length) - const valueSizeBytes = int32ToBytes(value.length) + let data = new Uint8Array() - let data = new Uint8Array() + data = appendBuffer(data, typeBytes) + data = appendBuffer(data, timestampBytes) + data = appendBuffer(data, lastReference) + data = appendBuffer(data, publicKey) + data = appendBuffer(data, owner) + data = appendBuffer(data, nameSizeBytes) + data = appendBuffer(data, name) + data = appendBuffer(data, valueSizeBytes) + data = appendBuffer(data, value) + data = appendBuffer(data, feeBytes) - data = appendBuffer(data, typeBytes) - data = appendBuffer(data, timestampBytes) - data = appendBuffer(data, lastReference) - data = appendBuffer(data, publicKey) - data = appendBuffer(data, owner) - data = appendBuffer(data, nameSizeBytes) - data = appendBuffer(data, name) - data = appendBuffer(data, valueSizeBytes) - data = appendBuffer(data, value) - data = appendBuffer(data, feeBytes) - - return data - } - }()) + return data + } +}()) diff --git a/crypto/api/transactions/reward-share/RemoveRewardShareTransaction.js b/crypto/api/transactions/reward-share/RemoveRewardShareTransaction.js index d16ff579..fe4ecc98 100644 --- a/crypto/api/transactions/reward-share/RemoveRewardShareTransaction.js +++ b/crypto/api/transactions/reward-share/RemoveRewardShareTransaction.js @@ -1,7 +1,7 @@ import TransactionBase from '../TransactionBase' import publicKeyToAddress from '../../wallet/publicKeyToAddress' -import {Base58} from '../../deps/deps' -import {DYNAMIC_FEE_TIMESTAMP} from '../../constants' +import { Base58 } from '../../deps/deps' +import { DYNAMIC_FEE_TIMESTAMP } from '../../constants' export default class RemoveRewardShareTransaction extends TransactionBase { constructor() { diff --git a/crypto/api/transactions/reward-share/RewardShareTransaction.js b/crypto/api/transactions/reward-share/RewardShareTransaction.js index 7033417e..b31e24e0 100644 --- a/crypto/api/transactions/reward-share/RewardShareTransaction.js +++ b/crypto/api/transactions/reward-share/RewardShareTransaction.js @@ -2,8 +2,8 @@ import publicKeyToAddress from '../../wallet/publicKeyToAddress' import TransactionBase from '../TransactionBase' import nacl from '../../deps/nacl-fast' import ed2curve from '../../deps/ed2curve' -import {Sha256} from 'asmcrypto.js' -import {DYNAMIC_FEE_TIMESTAMP} from '../../constants' +import { Sha256 } from 'asmcrypto.js' +import { DYNAMIC_FEE_TIMESTAMP } from '../../constants' export default class RewardShareTransaction extends TransactionBase { constructor() { diff --git a/crypto/api/utils/randomBase58Generator.js b/crypto/api/utils/randomBase58Generator.js index 57e6b0aa..1cc21c7a 100644 --- a/crypto/api/utils/randomBase58Generator.js +++ b/crypto/api/utils/randomBase58Generator.js @@ -1,11 +1,11 @@ export const randomBase58Generator = (digits) => { - digits = digits || 0 - let base58 = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'.split('') - let result = '' - let char - while (result.length < digits) { - char = base58[Math.random() * 57 >> 0] - if (result.indexOf(char) === -1) result += char - } - return result + digits = digits || 0 + let base58 = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'.split('') + let result = '' + let char + while (result.length < digits) { + char = base58[Math.random() * 57 >> 0] + if (result.indexOf(char) === -1) result += char + } + return result } diff --git a/crypto/api/utils/stateAwait.js b/crypto/api/utils/stateAwait.js index 666eb0db..800663b5 100644 --- a/crypto/api/utils/stateAwait.js +++ b/crypto/api/utils/stateAwait.js @@ -1,31 +1,31 @@ -import {store} from '../../api.js' +import { store } from '../../api' let subscriptions = [] // Have to wait with init because something import stateAwait before the store gets initialized let initialized = false const init = () => { - initialized = true - store.subscribe(() => { - const state = store.getState() + initialized = true + store.subscribe(() => { + const state = store.getState() - subscriptions = subscriptions.filter(fn => fn(state)) - }) + subscriptions = subscriptions.filter(fn => fn(state)) + }) } export const stateAwait = fn => { - return new Promise((resolve, reject) => { - // Check immediately...then if not true store it - if (!initialized) { - init() - } - if (fn(store.getState())) resolve() - subscriptions.push(state => { - if (fn(state)) { - resolve() - return true - } - return false - }) - }) + return new Promise((resolve, reject) => { + // Check immediately...then if not true store it + if (!initialized) { + init() + } + if (fn(store.getState())) resolve() + subscriptions.push(state => { + if (fn(state)) { + resolve() + return true + } + return false + }) + }) } diff --git a/crypto/api/wallet/base58PublicKeyToAddress.js b/crypto/api/wallet/base58PublicKeyToAddress.js index 6ed36383..8b20cb51 100644 --- a/crypto/api/wallet/base58PublicKeyToAddress.js +++ b/crypto/api/wallet/base58PublicKeyToAddress.js @@ -1,5 +1,5 @@ import publicKeyToAddress from './publicKeyToAddress' -import Base58 from '../deps/Base58.js' +import Base58 from '../deps/Base58' export const base58PublicKeyToAddress = (base58pubkey, qora = false) => { const decodePubKey = Base58.decode(base58pubkey) diff --git a/crypto/api/wallet/publicKeyToAddress.js b/crypto/api/wallet/publicKeyToAddress.js index 67954a0a..7852393f 100644 --- a/crypto/api/wallet/publicKeyToAddress.js +++ b/crypto/api/wallet/publicKeyToAddress.js @@ -1,10 +1,10 @@ -import Base58 from '../deps/Base58.js' -import BROKEN_RIPEMD160 from '../deps/broken-ripemd160.js' -import RIPEMD160 from '../deps/ripemd160.js' -import utils from '../deps/utils.js' -import {ADDRESS_VERSION} from '../constants.js' -import {Buffer} from 'buffer' -import {Sha256} from 'asmcrypto.js' +import Base58 from '../deps/Base58' +import BROKEN_RIPEMD160 from '../deps/broken-ripemd160' +import RIPEMD160 from '../deps/ripemd160' +import utils from '../deps/utils' +import { ADDRESS_VERSION } from '../constants' +import { Buffer } from 'buffer' +import { Sha256 } from 'asmcrypto.js' const repeatSHA256 = (passphrase, hashes) => { let hash = passphrase diff --git a/crypto/api/wallet/validateAddress.js b/crypto/api/wallet/validateAddress.js index 59d016cc..1dc9b1b5 100644 --- a/crypto/api/wallet/validateAddress.js +++ b/crypto/api/wallet/validateAddress.js @@ -1,8 +1,8 @@ -import Base58 from '../deps/Base58.js' +import Base58 from '../deps/Base58' export const validateAddress = (address) => { const decodePubKey = Base58.decode(address) - return decodePubKey instanceof Uint8Array && decodePubKey.length == 25; + return decodePubKey instanceof Uint8Array && decodePubKey.length == 25 } diff --git a/crypto/config.js b/crypto/config.js index 375b5bd8..bedeca43 100644 --- a/crypto/config.js +++ b/crypto/config.js @@ -1,4 +1,4 @@ -import {store} from './api.js' +import { store } from './api' let config = false let loaded = false From 36866d3cf1f16254339f963c4e8fa503c8f5a668 Mon Sep 17 00:00:00 2001 From: AlphaX-Projects <77661270+AlphaX-Projects@users.noreply.github.com> Date: Sat, 11 May 2024 11:48:12 +0200 Subject: [PATCH 11/11] Update electron.js and dependencies Removed require for esm support from package json Removed dark mode toogle from new ui instance --- electron.js | 22 +---- package-lock.json | 206 +++++++++++++++++++++++----------------------- package.json | 8 +- 3 files changed, 111 insertions(+), 125 deletions(-) diff --git a/electron.js b/electron.js index ee9b47c7..ad6c3d72 100644 --- a/electron.js +++ b/electron.js @@ -38,16 +38,16 @@ crashReporter.start({ }) if (myMemory > 16000000000) { - app.commandLine.appendSwitch('js-flags', '--max-executable-size=192 --max-old-space-size=8192 --max-semi-space-size=2') + app.commandLine.appendSwitch('js-flags', '--max-old-space-size=8192') log.info("Memory Size Is 16GB Using JS Memory Heap Size 8GB") } else if (myMemory > 12000000000) { - app.commandLine.appendSwitch('js-flags', '--max-executable-size=192 --max-old-space-size=6144 --max-semi-space-size=2') + app.commandLine.appendSwitch('js-flags', '--max-old-space-size=6144') log.info("Memory Size Is 12GB Using JS Memory Heap Size 6GB") } else if (myMemory > 7000000000) { - app.commandLine.appendSwitch('js-flags', '--max-executable-size=192 --max-old-space-size=4096 --max-semi-space-size=2') + app.commandLine.appendSwitch('js-flags', '--max-old-space-size=4096') log.info("Memory Size Is 8GB Using JS Memory Heap Size 4GB") } else { - app.commandLine.appendSwitch('js-flags', '--max-executable-size=192 --max-old-space-size=2048 --max-semi-space-size=2') + app.commandLine.appendSwitch('js-flags', '--max-old-space-size=2048') log.info("Memory Size Is 4GB Using JS Memory Heap Size 2GB") } @@ -1194,20 +1194,6 @@ function createNewWindow() { newWindow.on('closed', function () { newWindow = null }) - - ipcMain.handle('dark-mode:toggle', () => { - if (nativeTheme.shouldUseDarkColors) { - nativeTheme.themeSource = 'light' - } else { - nativeTheme.themeSource = 'dark' - } - - return nativeTheme.shouldUseDarkColors - }) - - ipcMain.handle('dark-mode:system', () => { - nativeTheme.themeSource = 'system' - }) } const createTray = () => { diff --git a/package-lock.json b/package-lock.json index 792fc709..26ea2990 100644 --- a/package-lock.json +++ b/package-lock.json @@ -28,7 +28,7 @@ "crypto-js": "4.2.0", "driver.js": "1.3.1", "electron-dl": "3.5.2", - "electron-log": "5.1.2", + "electron-log": "5.1.4", "electron-store": "8.2.0", "electron-updater": "6.1.8", "emoji-picker-js": "https://github.com/Qortal/emoji-picker-js", @@ -47,7 +47,7 @@ "prosemirror-state": "1.4.3", "prosemirror-transform": "1.9.0", "prosemirror-view": "1.33.6", - "sass": "1.77.0", + "sass": "1.77.1", "short-unique-id": "5.2.0", "xhr2": "0.2.1" }, @@ -104,7 +104,7 @@ "@vaadin/tooltip": "24.2.9", "@zip.js/zip.js": "2.7.44", "axios": "1.6.8", - "electron": "30.0.2", + "electron": "30.0.3", "electron-builder": "24.13.3", "epml": "0.3.3", "eslint": "8.57.0", @@ -619,9 +619,9 @@ } }, "node_modules/@electron/packager/node_modules/semver": { - "version": "7.6.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.1.tgz", - "integrity": "sha512-f/vbBsu+fOiYt+lmwZV0rVwJScl46HppnOA1ZvIuBWKOTlllpyJ3bfVax76/OrhCH38dyxoDIA8K7uB963IYgA==", + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", "dev": true, "bin": { "semver": "bin/semver.js" @@ -3277,9 +3277,9 @@ } }, "node_modules/@tiptap/extension-blockquote": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/@tiptap/extension-blockquote/-/extension-blockquote-2.3.1.tgz", - "integrity": "sha512-eyw3/Zn/XbIP2Yo11iE4vYcJ0471aBPMLD56YOyUC0PIF7D5tvPutDesSg95R+BDa5Tq/Id2zV5pZerw1dwwOQ==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-blockquote/-/extension-blockquote-2.3.2.tgz", + "integrity": "sha512-dyXx1hHAW/0BSxCUNWcxc8UN+s0wRTdtH46u6IEf91z+IOWjJwmSxT00+UMYh6hdOYDDsJYxPe9gcuSWYCIkCg==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -3289,9 +3289,9 @@ } }, "node_modules/@tiptap/extension-bold": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/@tiptap/extension-bold/-/extension-bold-2.3.1.tgz", - "integrity": "sha512-szHDXKOQfrlCzsys401zBtPWE5gyY3LcpPlrn2zBRrBmzU2U/1A7Y3HkoqZo3SSrTY37eG1Vr2J2aHySK6Uj/w==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-bold/-/extension-bold-2.3.2.tgz", + "integrity": "sha512-Mdc0qOPeJxxt5kSYKpNs7TzbQHeVpbpxwafUrxrvfD2iOnJlwlNxVWsVulc1t5EA8NpbTqYJTPmAtv2h/qmsfw==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -3301,9 +3301,9 @@ } }, "node_modules/@tiptap/extension-bullet-list": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/@tiptap/extension-bullet-list/-/extension-bullet-list-2.3.1.tgz", - "integrity": "sha512-pif0AB4MUoA1Xm26y1ovH7vfXaV19T9EEQH4tgN2g2eTfdFnQWDmKI0r3XRxudtg40RstBJRa81N9xEO79o8ag==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-bullet-list/-/extension-bullet-list-2.3.2.tgz", + "integrity": "sha512-nzvXSGxJuuZdQ6NE0gJ2GC+0gjXZTgU2+Z8TEKi7TYLUAjAoiU1Iniz1XA97cuFwVrNKp031IF1LivK085NqQA==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -3313,9 +3313,9 @@ } }, "node_modules/@tiptap/extension-code": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/@tiptap/extension-code/-/extension-code-2.3.1.tgz", - "integrity": "sha512-bVX0EnDZoRXnoA7dyoZe7w2gdRjxmFEcsatHLkcr3R3x4k9oSgZXLe1C2jGbjJWr4j32tYXZ1cpKte6f1WUKzg==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-code/-/extension-code-2.3.2.tgz", + "integrity": "sha512-LyIRBFJCxbgi96ejoeewESvfUf5igfngamZJK+uegfTcznimP0AjSWs3whJwZ9QXUsQrB9tIrWIG4GBtatp6qw==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -3325,9 +3325,9 @@ } }, "node_modules/@tiptap/extension-code-block": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/@tiptap/extension-code-block/-/extension-code-block-2.3.1.tgz", - "integrity": "sha512-rM7T+DWuOShariPl5vknNFMesPOFQrhMjmms9Ql636sSxOcnkb0d39NFbUpI/r5noFDC6Km+lAebF0Rx2MxpKQ==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-code-block/-/extension-code-block-2.3.2.tgz", + "integrity": "sha512-Ng5dh8+FMD3pxaqZEDSRxTjgjPCNdEEVUTJnuljZXQ9ZxI9wVsKsGs53Hunpita4Qgk0DYhlfAvGUKCM0nCH4A==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -3338,9 +3338,9 @@ } }, "node_modules/@tiptap/extension-document": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/@tiptap/extension-document/-/extension-document-2.3.1.tgz", - "integrity": "sha512-uWYbzAV95JnetFBduWRI9n2QbQfmznQ7I6XzfZxuTAO2KcWGvHPBS7F00COO9Y67FZAPMbuQ1njtCJK0nClOPw==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-document/-/extension-document-2.3.2.tgz", + "integrity": "sha512-EQcfkvA7lkZPKllhGo2jiEYLJyXhBFK7++oRatgbfgHEJ2uLBGv6ys7WLCeRA/ntcaWTH3rlS+HR/Y8/nnyQYg==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -3350,9 +3350,9 @@ } }, "node_modules/@tiptap/extension-dropcursor": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/@tiptap/extension-dropcursor/-/extension-dropcursor-2.3.1.tgz", - "integrity": "sha512-xDG1Z01ftRI4mIOY+bPuG53xZ9FfVd6hzjNchwFHRlU3E+/2O+DsEBy/pJuHmpnFx1B/1ANbssoidGvK3LIPYw==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-dropcursor/-/extension-dropcursor-2.3.2.tgz", + "integrity": "sha512-r7JJn9dEnIRDdbnTCAUFCWX4OPsR48+4OEm5eGlysEaD2h4z0G1AaK5XXwOoQhP3WP2LHHjL4LahlYZvltzFzw==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -3363,9 +3363,9 @@ } }, "node_modules/@tiptap/extension-gapcursor": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/@tiptap/extension-gapcursor/-/extension-gapcursor-2.3.1.tgz", - "integrity": "sha512-jhMw0LtEV/HVovUDRdoH0QLnBWLDyw4Su7UZ0bkMtsnCO9MujLKths3SKsPstuAckZQKR5smokEytxDHH0aglg==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-gapcursor/-/extension-gapcursor-2.3.2.tgz", + "integrity": "sha512-PSry4JHUIOhXytvYUQGtYgfIKCIhnmbKksZ8/CfCaKgGJpjOpnzqRG5FnYXZB7NiqouABreM7+IgkH0mOLq6HQ==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -3376,9 +3376,9 @@ } }, "node_modules/@tiptap/extension-hard-break": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/@tiptap/extension-hard-break/-/extension-hard-break-2.3.1.tgz", - "integrity": "sha512-HO47iS2KQJLxhZM4ghZz5t2qgESH6D/mKJbjO7jM0eCYEyUfPyYJwV2VgjQP7x+1axcvsrhpzkJrjSg5+KqtQQ==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-hard-break/-/extension-hard-break-2.3.2.tgz", + "integrity": "sha512-Oy/Dj75kw/tyNyrcFf97r872NZggISfvabTptH8j1gFPg/XzT5ERcT2fvgpbsBx0WWlXOaFkC1owta6kS6MZpg==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -3388,9 +3388,9 @@ } }, "node_modules/@tiptap/extension-heading": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/@tiptap/extension-heading/-/extension-heading-2.3.1.tgz", - "integrity": "sha512-epdIrg1xpuk5ApnNyM/NJO1dhVZgD7kDPem6QH4fug5UJtCueze942yNzUhCuvckmIegfdferAb1p4ug4674ig==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-heading/-/extension-heading-2.3.2.tgz", + "integrity": "sha512-KBew4QCnYASBPEJlZ4vKQnm4R9B206H8kE5+hq8OOyF3FVkR6FgF/AbY/E/4/+2blx82PGp+9gvPUVpEv36ifQ==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -3412,9 +3412,9 @@ } }, "node_modules/@tiptap/extension-history": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/@tiptap/extension-history/-/extension-history-2.3.1.tgz", - "integrity": "sha512-m+W6qTP4V0PHqqKnXw/ma18a62O0Cqp5FDWtSarOuxx6W4FpVr4A3Uxfbp4RigZEYanLcX4UJOWL4nWsFdYWHw==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-history/-/extension-history-2.3.2.tgz", + "integrity": "sha512-LTon7ys+C6wLmN/nXYkr1pDxIiIv0Czn4US7I/1b8Ws2N6PU+nMm4r7Uj8hKrDYL8yPQUaS4gIs1hhOwJ8UjtA==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -3425,9 +3425,9 @@ } }, "node_modules/@tiptap/extension-horizontal-rule": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/@tiptap/extension-horizontal-rule/-/extension-horizontal-rule-2.3.1.tgz", - "integrity": "sha512-IPgCFkiT6Y5BSFBQMTXS6gq2Ust6otMzRwddoI0RC8tl/tMftFBEPqYKADWVQeQb4C6AQydRjUbmAwHpBH31Eg==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-horizontal-rule/-/extension-horizontal-rule-2.3.2.tgz", + "integrity": "sha512-nz4GcYvZmJOX20GAjR5ymZgzQCbhnK/rmcunQf4zkl4LA5sXm70P70I9bDtrT/mgmz5dnBUTkVAkLTtKbovdDQ==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -3450,9 +3450,9 @@ } }, "node_modules/@tiptap/extension-italic": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/@tiptap/extension-italic/-/extension-italic-2.3.1.tgz", - "integrity": "sha512-yEAn0dT1LH1vAULmZv3L1fs7M1Fn/8wZCw7LDGw2/E+VYbDeXgy7XwMPyzhrzV1oV9Z+3gugCbYV0IJ4PBwudA==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-italic/-/extension-italic-2.3.2.tgz", + "integrity": "sha512-6RJmexu/E+JP2+lhzJLV+5KZJiTrJE+p/hnDk13CBK2VgiwcJYmcZSVk+Yk6Suwrb1qTAosu8paKIwVJa/VMUg==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -3462,9 +3462,9 @@ } }, "node_modules/@tiptap/extension-list-item": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/@tiptap/extension-list-item/-/extension-list-item-2.3.1.tgz", - "integrity": "sha512-GyHLNoXVo9u29NVqijwZPBcv9MzXMGyIiQiO5FxRpuT4Ei4ZmsaJrJ2dmhO3KZhX0HdTSc65/omM2XBr6PDoLA==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-list-item/-/extension-list-item-2.3.2.tgz", + "integrity": "sha512-vgT7tkSZd99xAEph9quPlVdRkgPU4GJp9K7bNS8Y7GnSLU0KkDHbtDpb0pyz76HVpeOnt/QGmtqF14Il9T2IPQ==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -3474,9 +3474,9 @@ } }, "node_modules/@tiptap/extension-ordered-list": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/@tiptap/extension-ordered-list/-/extension-ordered-list-2.3.1.tgz", - "integrity": "sha512-+6I76b7fu0FghUtzB0LyIC5GB0xfrpAKtXjbrmeUGsOEL7jxKsE6+A5RoTrgQTfuP7oItdCZGTSC/8WtGbtEMg==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-ordered-list/-/extension-ordered-list-2.3.2.tgz", + "integrity": "sha512-eMnQDgWpaQ3sdlFg1M85oziFYl2h/GRBjUt4JhF5kyWpHOYDj1/bX1fndZOBQ5xaoNlbcaeEkIc53xVX4ZV9tw==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -3486,9 +3486,9 @@ } }, "node_modules/@tiptap/extension-paragraph": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/@tiptap/extension-paragraph/-/extension-paragraph-2.3.1.tgz", - "integrity": "sha512-bHkkHU012clwCrpzmEHGuF8fwLuFL3x9MJ17wnhwanoIM3MG6ZCdeb9copjDvUpZXLKTUYKotoPGNhxmOrP2bQ==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-paragraph/-/extension-paragraph-2.3.2.tgz", + "integrity": "sha512-bKzL4NXp0pDM/Q5ZCpjLxjQU4DwoWc6CDww1M4B4dp1sfiXiE2P7EOCMM2TfJOqNPUFpp5RcFKKcxC2Suj8W4w==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -3511,9 +3511,9 @@ } }, "node_modules/@tiptap/extension-strike": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/@tiptap/extension-strike/-/extension-strike-2.3.1.tgz", - "integrity": "sha512-fpsVewcnaYk37TAF4JHkwH9O6Ml7JooF1v/Eh9p7PSItNcEfg/3RLlJL3c53RzLWdlunjgptM/M0alPV0Zyq4A==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-strike/-/extension-strike-2.3.2.tgz", + "integrity": "sha512-gi16YtLnXKPubxafvcGSAELac4i8S6Eb9Av0AaH6QH9H9zzSHN7qOrX930Tp2Pod5a/a82kk7kN7IB6htAeaYA==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -3523,9 +3523,9 @@ } }, "node_modules/@tiptap/extension-text": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/@tiptap/extension-text/-/extension-text-2.3.1.tgz", - "integrity": "sha512-ZM+Bpty9jChEN/VjUP/fX1Fvoz0Z3YLdjj9+pFA0H7woli+TmxWY6yUUTA2SBDb2mJ52yNOUfRE/sYx6gkDuBQ==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-text/-/extension-text-2.3.2.tgz", + "integrity": "sha512-a3whwDyyOsrmOQbfeY+Fm5XypSRgT3IGqWgz0r4U7oko57/X6Env08F1Ie2e2UkQw9B1MoW9cm3dC6jvrdzzYA==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -3691,9 +3691,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.12.10", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.10.tgz", - "integrity": "sha512-Eem5pH9pmWBHoGAT8Dr5fdc5rYA+4NAovdM4EktRPVAAiJhmWWfQrA0cFhAbOsQdSfIHjAud6YdkbL69+zSKjw==", + "version": "20.12.11", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.11.tgz", + "integrity": "sha512-vDg9PZ/zi+Nqp6boSOT7plNuthRugEKixDv5sFTIpkE89MmNtEArAShI4mxuX2+UrLEe9pxC1vm2cjm9YlWbJw==", "devOptional": true, "dependencies": { "undici-types": "~5.26.4" @@ -4456,9 +4456,9 @@ } }, "node_modules/app-builder-lib/node_modules/semver": { - "version": "7.6.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.1.tgz", - "integrity": "sha512-f/vbBsu+fOiYt+lmwZV0rVwJScl46HppnOA1ZvIuBWKOTlllpyJ3bfVax76/OrhCH38dyxoDIA8K7uB963IYgA==", + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", "dev": true, "bin": { "semver": "bin/semver.js" @@ -5018,9 +5018,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001616", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001616.tgz", - "integrity": "sha512-RHVYKov7IcdNjVHJFNY/78RdG4oGVjbayxv8u5IO74Wv7Hlq4PnJE6mo/OjFijjVFNy5ijnCt6H3IIo4t+wfEw==", + "version": "1.0.30001617", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001617.tgz", + "integrity": "sha512-mLyjzNI9I+Pix8zwcrpxEbGlfqOkF9kM3ptzmKNw5tizSyYwMe+nGLTqMK9cO+0E+Bh6TsBxNAaHWEM8xwSsmA==", "dev": true, "funding": [ { @@ -5284,9 +5284,9 @@ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" }, "node_modules/conf/node_modules/semver": { - "version": "7.6.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.1.tgz", - "integrity": "sha512-f/vbBsu+fOiYt+lmwZV0rVwJScl46HppnOA1ZvIuBWKOTlllpyJ3bfVax76/OrhCH38dyxoDIA8K7uB963IYgA==", + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", "bin": { "semver": "bin/semver.js" }, @@ -5314,16 +5314,16 @@ } }, "node_modules/config-file-ts/node_modules/glob": { - "version": "10.3.12", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.12.tgz", - "integrity": "sha512-TCNv8vJ+xz4QiqTpfOJA7HvYv+tNIRHKfUWw/q+v2jdgN4ebz+KY9tGx5J4rHP0o84mNP+ApH66HRX8us3Khqg==", + "version": "10.3.14", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.14.tgz", + "integrity": "sha512-4fkAqu93xe9Mk7le9v0y3VrPDqLKHarNi2s4Pv7f2yOvfhWfhc7hRPHC/JyqMqb8B/Dt/eGS4n7ykwf3fOsl8g==", "dev": true, "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^2.3.6", "minimatch": "^9.0.1", "minipass": "^7.0.4", - "path-scurry": "^1.10.2" + "path-scurry": "^1.11.0" }, "bin": { "glob": "dist/esm/bin.mjs" @@ -5351,9 +5351,9 @@ } }, "node_modules/config-file-ts/node_modules/minipass": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.0.tgz", - "integrity": "sha512-oGZRv2OT1lO2UF1zUcwdTb3wqUwI0kBGTgt/T7OdSj6M6N5m3o5uPf0AIW6lVxGGoiWUR7e2AwTE+xiwK8WQig==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.1.tgz", + "integrity": "sha512-UZ7eQ+h8ywIRAW1hIEl2AqdwzJucU/Kp59+8kkZeSvafXhZjul247BvIJjEVFVeON6d7lM46XX1HXCduKAS8VA==", "dev": true, "engines": { "node": ">=16 || 14 >=14.17" @@ -5741,9 +5741,9 @@ } }, "node_modules/electron": { - "version": "30.0.2", - "resolved": "https://registry.npmjs.org/electron/-/electron-30.0.2.tgz", - "integrity": "sha512-zv7T+GG89J/hyWVkQsLH4Y/rVEfqJG5M/wOBIGNaDdqd8UV9/YZPdS7CuFeaIj0H9LhCt95xkIQNpYB/3svOkQ==", + "version": "30.0.3", + "resolved": "https://registry.npmjs.org/electron/-/electron-30.0.3.tgz", + "integrity": "sha512-h+suwx6e0fnv/9wi0/cmCMtG+4LrPzJZa+3DEEpxcPcP+pcWnBI70t8QspxgMNIh2wzXLMD9XVqrLkEbiBAInw==", "dev": true, "hasInstallScript": true, "dependencies": { @@ -5913,9 +5913,9 @@ } }, "node_modules/electron-log": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/electron-log/-/electron-log-5.1.2.tgz", - "integrity": "sha512-Cpg4hAZ27yM9wzE77c4TvgzxzavZ+dVltCczParXN+Vb3jocojCSAuSMCVOI9fhFuuOR+iuu3tZLX1cu0y0kgQ==", + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/electron-log/-/electron-log-5.1.4.tgz", + "integrity": "sha512-P0RSXnwT3z+e89Z5uAcZDeN85/QjIgv764a93kqCi+wh2Jm22CCbc3AGDt4S8rsxAHWHB4Q0PGsQl3fw1AN0kQ==", "engines": { "node": ">= 14" } @@ -6032,9 +6032,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.4.758", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.758.tgz", - "integrity": "sha512-/o9x6TCdrYZBMdGeTifAP3wlF/gVT+TtWJe3BSmtNh92Mw81U9hrYwW9OAGUh+sEOX/yz5e34sksqRruZbjYrw==", + "version": "1.4.763", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.763.tgz", + "integrity": "sha512-k4J8NrtJ9QrvHLRo8Q18OncqBCB7tIUyqxRcJnlonQ0ioHKYB988GcDFF3ZePmnb8eHEopDs/wPHR/iGAFgoUQ==", "dev": true }, "node_modules/electron-updater": { @@ -6078,9 +6078,9 @@ } }, "node_modules/electron-updater/node_modules/semver": { - "version": "7.6.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.1.tgz", - "integrity": "sha512-f/vbBsu+fOiYt+lmwZV0rVwJScl46HppnOA1ZvIuBWKOTlllpyJ3bfVax76/OrhCH38dyxoDIA8K7uB963IYgA==", + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", "bin": { "semver": "bin/semver.js" }, @@ -7124,9 +7124,9 @@ } }, "node_modules/global-agent/node_modules/semver": { - "version": "7.6.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.1.tgz", - "integrity": "sha512-f/vbBsu+fOiYt+lmwZV0rVwJScl46HppnOA1ZvIuBWKOTlllpyJ3bfVax76/OrhCH38dyxoDIA8K7uB963IYgA==", + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", "dev": true, "optional": true, "bin": { @@ -8686,9 +8686,9 @@ "dev": true }, "node_modules/path-scurry": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.2.tgz", - "integrity": "sha512-7xTavNy5RQXnsjANvVvMkEjvloOinkAjv/Z6Ildz9v2RinZ4SBKTWFOVRbaF8p0vpHnyjV/UwNDdKuUv6M5qcA==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.0.tgz", + "integrity": "sha512-LNHTaVkzaYaLGlO+0u3rQTz7QrHTFOuKyba9JMTQutkmtNew8dw8wOD7mTU/5fCPZzCWpfW0XnQKzY61P0aTaw==", "dev": true, "dependencies": { "lru-cache": "^10.2.0", @@ -9701,9 +9701,9 @@ } }, "node_modules/sass": { - "version": "1.77.0", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.77.0.tgz", - "integrity": "sha512-eGj4HNfXqBWtSnvItNkn7B6icqH14i3CiCGbzMKs3BAPTq62pp9NBYsBgyN4cA+qssqo9r26lW4JSvlaUUWbgw==", + "version": "1.77.1", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.77.1.tgz", + "integrity": "sha512-OMEyfirt9XEfyvocduUIOlUSkWOXS/LAt6oblR/ISXCTukyavjex+zQNm51pPCOiFKY1QpWvEH1EeCkgyV3I6w==", "dependencies": { "chokidar": ">=3.0.0 <4.0.0", "immutable": "^4.0.0", @@ -9838,9 +9838,9 @@ } }, "node_modules/simple-update-notifier/node_modules/semver": { - "version": "7.6.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.1.tgz", - "integrity": "sha512-f/vbBsu+fOiYt+lmwZV0rVwJScl46HppnOA1ZvIuBWKOTlllpyJ3bfVax76/OrhCH38dyxoDIA8K7uB963IYgA==", + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", "dev": true, "bin": { "semver": "bin/semver.js" diff --git a/package.json b/package.json index 019ccee1..c588627e 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "license": "GPL-3.0", "scripts": { "dev": "node server.js", - "prebuild": "node -p \"'export const UI_VERSION = ' + JSON.stringify(require('./package.json').version)\" > core/src/redux/app/version.js", + "prebuild": "node -p \"'export const UI_VERSION = ' + JSON.stringify(process.env.npm_package_version)\" > core/src/redux/app/version.js", "build-dev": "node --max-old-space-size=8192 build.js", "build": "NODE_ENV=production node build.js", "server": "NODE_ENV=production node --max-old-space-size=8192 server.js", @@ -50,7 +50,7 @@ "crypto-js": "4.2.0", "driver.js": "1.3.1", "electron-dl": "3.5.2", - "electron-log": "5.1.2", + "electron-log": "5.1.4", "electron-store": "8.2.0", "electron-updater": "6.1.8", "emoji-picker-js": "https://github.com/Qortal/emoji-picker-js", @@ -69,7 +69,7 @@ "prosemirror-state": "1.4.3", "prosemirror-transform": "1.9.0", "prosemirror-view": "1.33.6", - "sass": "1.77.0", + "sass": "1.77.1", "short-unique-id": "5.2.0", "xhr2": "0.2.1" }, @@ -126,7 +126,7 @@ "@vaadin/tooltip": "24.2.9", "@zip.js/zip.js": "2.7.44", "axios": "1.6.8", - "electron": "30.0.2", + "electron": "30.0.3", "electron-builder": "24.13.3", "epml": "0.3.3", "eslint": "8.57.0",