From 00d8e456aaa00fecee24bae8ea282ca413306169 Mon Sep 17 00:00:00 2001 From: AlphaX-Projects <77661270+AlphaX-Projects@users.noreply.github.com> Date: Tue, 15 Mar 2022 18:53:31 +0100 Subject: [PATCH] New Wallets page --- .../plugins/core/wallet/wallet-app.src.js | 2175 ++++++++++++----- 1 file changed, 1541 insertions(+), 634 deletions(-) diff --git a/qortal-ui-plugins/plugins/core/wallet/wallet-app.src.js b/qortal-ui-plugins/plugins/core/wallet/wallet-app.src.js index e21beca0..55142a20 100644 --- a/qortal-ui-plugins/plugins/core/wallet/wallet-app.src.js +++ b/qortal-ui-plugins/plugins/core/wallet/wallet-app.src.js @@ -3,11 +3,19 @@ import { render } from 'lit/html.js' import { Epml } from '../../../epml.js' import '../components/ButtonIconCopy' -import '@material/mwc-icon' import '@material/mwc-button' +import '@material/mwc-checkbox' import '@material/mwc-dialog' +import '@material/mwc-formfield' +import '@material/mwc-icon' +import '@material/mwc-textfield' +import '@polymer/paper-progress/paper-progress.js' +import '@polymer/paper-slider/paper-slider.js' import '@polymer/paper-spinner/paper-spinner-lite.js' +import '@vaadin/button' import '@vaadin/grid' +import '@vaadin/icon' +import '@vaadin/icons' import '@github/time-elements' const parentEpml = new Epml({ type: 'WINDOW', source: window.parent }) @@ -25,486 +33,499 @@ class MultiWallet extends LitElement { wallets: { type: Map }, _selectedWallet: 'qort', 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 }, + errorMessage: { type: String }, + successMessage: { type: String }, + sendMoneyLoading: { type: Boolean }, + btnDisable: { type: Boolean }, + isValidAmount: { type: Boolean }, + balance: { type: Number }, + btcFeePerByte: { type: Number }, + ltcFeePerByte: { type: Number }, + dogeFeePerByte: { type: Number }, balanceString: 'Fetching balance ...' } } + static get observers() { + return ['_kmxKeyUp(amount)'] + } + static get styles() { - return [ - css` - * { - box-sizing: border-box; - --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-grid-border-color: var(--border); - --_lumo-grid-secondary-border-color: var(--border2); - } + 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-dialog-content-ink-color: var(--black); + --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-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 { + 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 { + 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: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[selected] { + font-weight: bold; + color: var(--white); + background-color: #ccc; + } - #pages > button[disabled] { - opacity: 0.5; - cursor: default; - } + #pages > button[disabled] { + opacity: 0.5; + cursor: default; + } - .red { - color: var(--paper-red-500); - } + 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); + } - .green { - color: var(--paper-green-500); - } + paper-progress { + --paper-progress-active-color: var(--mdc-theme-primary); + } - paper-spinner-lite { - height: 75px; - width: 75px; - --paper-spinner-color: var(--primary-color); - --paper-spinner-stroke-width: 2px; - } + .red { + --mdc-theme-primary: #F44336; + } - .unconfirmed { - font-style: italic; - } + .green { + color: var(--paper-green-500); + } - .roboto { - font-family: 'Roboto', sans-serif; - } + paper-spinner-lite { + height: 75px; + width: 75px; + --paper-spinner-color: var(--mdc-theme-primary); + --paper-spinner-stroke-width: 3px; + } - .mono { - font-family: 'Roboto Mono', monospace; - } + .unconfirmed { + font-style: italic; + } - .weight-100 { - font-weight: 100; - } + .roboto { + font-family: 'Roboto', sans-serif; + } + + .mono { + font-family: 'Roboto Mono', monospace; + } + + .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; + } + + .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; + } - .text-white-primary { - color: var(--white); - } + h2 { + margin: 0; + font-weight: 400; + font: 24px/24px 'Open Sans', sans-serif; + } - .text-white-secondary { - color: var(--white-secondary); - } - .text-white-disabled { - color: var(--white-disabled); - } - .text-white-hint { - color: var(--white-divider); - } + h3 { + margin: 0 0 5px; + font-weight: 600; + font-size: 18px; + line-height: 18px; + } - table { - border: none; - } + @media (min-width: 765px) { + .wrapper { + display: grid; + grid-template-columns: 0.5fr 3.5fr; + } + } - table td, - th { - white-space: nowrap; - text-align: left; - font-size: 14px; - padding: 0 12px; - font-family: 'Roboto', sans-serif; - color: var(--black); - background: var(--white); - } + .wrapper { + margin: 0 auto; + height: 100%; + overflow: hidden; + border-radius: 8px; + background-color: var(--white); + } - table tr { - height: 48px; - } + .wallet { + width: 170px; + height: 100vh; + border-top-left-radius: inherit; + border-bottom-left-radius: inherit; + border-right: 1px solid var(--border); + } - table tr:hover td { - background: #eee; - } + .transactions-wrapper { + width: 100%; + padding: 50px 0 0 0; + height: 100%; + } - table tr th { - color: #666; - font-size: 12px; - } + .wallet-header { + margin: 0 20px; + color: var(--black); + } - table tr td { - margin: 0; - } + .wallet-address { + display: flex; + align-items: center; + font-size: 18px; + color: var(--black); + margin: 4px 0 20px; + } - .white-bg { - height: 100vh; - background: var(--white); - } + .wallet-balance { + display: inline-block; + font-weight: 600; + font-size: 32px; + color: var(--black); + } - span { - font-size: 18px; - word-break: break-all; - } + #transactions { + margin-top: 60px; + margin-left: 20px; + margin-right: 20px; + border-top: 1px solid var(--border); + padding-top: 0px; + height: 100%; + } - .title { - font-weight: 600; - font-size: 12px; - line-height: 32px; - opacity: 0.66; - } + .show { + animation: fade-in 0.3s 1; + } - #transactionList { - padding: 0; - } + .transaction-item { + display: flex; + justify-content: space-between; + position: relative; + padding-left: 40px; + margin-bottom: 45px; + margin-right: 50px; + } - #transactionList > * { - } + .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; + } - .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; - } + .credit::before { + content: '+'; + font-size: 25px; + line-height: 19px; + padding: 0 4px 0; + } - .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; - } + .debit::before { + content: '-'; + font-size: 20px; + line-height: 21px; + padding: 0 5px; + } - body { - margin: 0; - padding: 0; - background: var(--white); - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; - } + .transaction-item .details { + font-size: 14px; + line-height: 14px; + color: #999; + } - h2 { - margin: 0; - font-weight: 400; - color: var(--black); - font: 24px/24px 'Open Sans', sans-serif; - } + .transaction-item_details { + width: 270px; + } - h3 { - margin: 0 0 5px; - font-weight: 600; - font-size: 18px; - line-height: 18px; - } + .transaction-item_amount .amount { + font-weight: 600; + font-size: 18px; + line-height: 45px; + position: relative; + margin: 0; + display: inline-block; + } - /* Styles for Larger Screen Sizes */ - @media (min-width: 765px) { - .wrapper { - display: grid; - grid-template-columns: 0.5fr 3.5fr; - } - } + .currency-box { + display: flex; + background-color: var(--white); + text-align: center; + padding: 12px; + cursor: pointer; + transition: 0.1s ease-in-out; + } - .wrapper { - margin: 0 auto; - height: 100%; - overflow: hidden; - border-radius: 8px; - background-color: var(--white); - } + .currency-box:not(:last-child) { + border-bottom: var(--border); + } - .wallet { - width: 170px; - height: 100vh; - border-top-left-radius: inherit; - border-bottom-left-radius: inherit; - border-right: 1px solid var(--border); - } + .active { + background: var(--menuactive); + } - .transactions-wrapper { - width: 100%; - padding: 50px 0 0 0; - height: 100%; - } + .currency-image { + display: inline-block; + height: 42px; + width: 42px; + background-repeat: no-repeat; + background-size: cover; + border-radius: 3px; + filter: grayscale(100%); + } - .wallet-header { - margin: 0 20px; - } + .currency-box.active .currency-image, + .currency-box:hover .currency-image { + filter: none; + } - .wallet-address { - display: flex; - align-items: center; - font-size: 18px; - color: var(--black); - margin: 4px 0 20px; - } + .currency-box:hover { + background: var(--menuhover); + } - .wallet-balance { - display: inline-block; - font-weight: 600; - font-size: 32px; - color: var(--black); - } - - #transactions { - margin-top: 60px; - 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; - } - - .currency-box { - display: flex; - background-color: var(--white); - text-align: center; - padding: 12px; - cursor: pointer; - transition: 0.1s ease-in-out; - } - - .currency-box:not(:last-child) { - border-bottom: var(--border); - } - - .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%); - } - - .currency-box.active .currency-image, - .currency-box:hover .currency-image { - filter: none; - } - - .currency-box:hover { - background: var(--menuhover); - } - - .currency-box.active, - .currency-box:hover .currency-text { - font-weight: 500; - } + .currency-box.active, + .currency-box:hover .currency-text { + font-weight: 500; + } - .currency-text { - margin: auto 0; - margin-left: 8px; - font-size: 20px; - color: var(--black); - } + .currency-text { + margin: auto 0; + margin-left: 8px; + font-size: 20px; + color: var(--black); + } - .qort .currency-image { - background-image: url('/img/qort.png'); - } + .qort .currency-image { + background-image: url('/img/qort.png'); + } - .btc .currency-image { - background-image: url('/img/btc.png'); - } + .btc .currency-image { + background-image: url('/img/btc.png'); + } - .ltc .currency-image { - background-image: url('/img/ltc.png'); - } + .ltc .currency-image { + background-image: url('/img/ltc.png'); + } - .doge .currency-image { - background-image: url('/img/doge.png'); - } + .doge .currency-image { + background-image: url('/img/doge.png'); + } - .card-list { - margin-top: 20px; - } + .card-list { + margin-top: 20px; + } - .card-list .currency-image { - cursor: pointer; - margin-right: 15px; - transition: 0.1s; - } + .card-list .currency-image { + cursor: pointer; + margin-right: 15px; + transition: 0.1s; + } - .card-list .currency-image:hover { - transform: scale(1.1); - } + .card-list .currency-image:hover { + transform: scale(1.1); + } - /* animations */ - @keyframes fade-in { - 0% { - opacity: 0; - } - 100% { - opacity: 1; - } - } + .buttons { + width: auto !important; + } - /* media queries */ - @media (max-width: 863px) { - .wallet { - width: 100%; - height: max-content; - border-top-right-radius: inherit; - padding-bottom: 25px; - } - .cards { - margin-top: 25px; - } - .currency-box:nth-of-type(2) { - margin-right: 0; - } - } + .send-coin-dialog { + min-height: 300px; + min-width: 300px; + box-sizing: border-box; + position: relative; + } - @media (max-width: 764px) { - .wallet { - width: 100%; - height: max-content; - border-top-right-radius: inherit; - padding-bottom: 25px; - } - .cards { - margin-top: 25px; - } - .currency-box { - width: calc(50% - 25px); - max-width: 260px; - display: inline-block; - margin-right: 25px; - margin-bottom: 25px; - } - .currency-box:nth-of-type(2) { - margin-right: 0; - } - } + @keyframes fade-in { + 0% { + opacity: 0; + } + 100% { + opacity: 1; + } + } - @media (max-width: 530px) { - h3 { - line-height: 24px; - } - .cards { - text-align: center; - } - .currency-box { - width: calc(100% - 25px); - max-width: 260px; - } - .currency-box:nth-of-type(2) { - margin-right: 25px; - } - .currency-box:last-of-type { - margin-bottom: 0; - } - .wallet-balance { - font-size: 22px; - } - } + @media (max-width: 863px) { + .wallet { + width: 100%; + height: max-content; + border-top-right-radius: inherit; + padding-bottom: 25px; + } + .cards { + margin-top: 25px; + } + .currency-box:nth-of-type(2) { + margin-right: 0; + } + } - @media (max-width: 390px) { - .wallet { - height: max-content; - padding: 50px 25px; - } - .transactions-wrapper { - padding: 50px 25px; - } - h2 { - font: 18px/24px 'Open Sans', sans-serif; - } - } - `, - ] + .checkboxLabel:hover{ + cursor: pointer; + } + + @media (max-width: 764px) { + .wallet { + width: 100%; + height: max-content; + border-top-right-radius: inherit; + padding-bottom: 25px; + } + .cards { + margin-top: 25px; + } + .currency-box { + width: calc(50% - 25px); + max-width: 260px; + display: inline-block; + margin-right: 25px; + margin-bottom: 25px; + } + .currency-box:nth-of-type(2) { + margin-right: 0; + } + } + + @media (max-width: 530px) { + h3 { + line-height: 24px; + } + .cards { + text-align: center; + } + .currency-box { + width: calc(100% - 25px); + max-width: 260px; + } + .currency-box:nth-of-type(2) { + margin-right: 25px; + } + .currency-box:last-of-type { + margin-bottom: 0; + } + .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; + } + } + ` } constructor() { @@ -514,7 +535,6 @@ class MultiWallet extends LitElement { height: 0, } - this.selectedTransaction = {} this.isTextMenuOpen = false this.loading = true @@ -523,7 +543,32 @@ class MultiWallet extends LitElement { this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light'; + this.recipient = '' + this.btcRecipient = '' + this.ltcRecipient = '' + this.dogeRecipient = '' + this.errorMessage = '' + this.successMessage = '' + this.sendMoneyLoading = false + this.isValidAmount = false + this.btnDisable = false + this.balance = 0 + this.amount = 0 + this.btcAmount = 0 + this.ltcAmount = 0 + this.dogeAmount = 0 + 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.wallets = new Map() + let coinProp = { balance: 0, wallet: null, @@ -531,6 +576,7 @@ class MultiWallet extends LitElement { fetchingWalletBalance: false, fetchingWalletTransactions: false } + coinsNames.forEach((c, i) => { this.wallets.set(c, { ...coinProp }) }, this) @@ -564,98 +610,390 @@ class MultiWallet extends LitElement { render() { return html` -
-
-
Wallets
-
-
-
-
Qort
-
-
-
-
Bitcoin
-
-
-
-
Litecoin
-
-
-
-
Dogecoin
-
-
-
+
+
+
Wallets
+
+
+
+
Qort
+
+
+
+
Bitcoin
+
+
+
+
Litecoin
+
+
+
+
Dogecoin
+
+
+
-
-

- Current Wallet -
- ${this.getSelectedWalletAddress()} - - -
- ${this.balanceString} -

-
- ${this.loading ? html`` : ''} -
-
-
+
+

+ Current Wallet +
+ ${this.getSelectedWalletAddress()} + + +
+ + ${this.balanceString}

+ ${this.renderSendButton()} +
+

+
+ ${this.loading ? html`` : ''} +
+
+
-
- -
-

Transaction Details

-
-
-
- Transaction Type -
-
- ${this.selectedTransaction.type} - ${this.selectedTransaction.txnFlow === 'OUT' ? html`OUT` : html`IN`} -
- Sender -
-
${this.selectedTransaction.creatorAddress}
- Receiver -
-
${this.selectedTransaction.recipient}
- ${!this.selectedTransaction.amount ? '' : html` - Amount -
-
${this.selectedTransaction.amount} QORT
- `} - Transaction Fee -
-
${this.selectedTransaction.fee}
+ +
+

Transaction Details

+
+
+
+ Transaction Type +
+
+ ${this.selectedTransaction.type} + ${this.selectedTransaction.txnFlow === 'OUT' ? html`OUT` : html`IN`} +
+ Sender +
+
${this.selectedTransaction.creatorAddress}
+ Receiver +
+
${this.selectedTransaction.recipient}
+ ${!this.selectedTransaction.amount ? '' : html` + Amount +
+
${this.selectedTransaction.amount} QORT
+ `} + Transaction Fee +
+
${this.selectedTransaction.fee}
+ Block +
+
${this.selectedTransaction.blockHeight}
+ Time +
+
${new Date(this.selectedTransaction.timestamp).toString()}
+ Transaction Signature +
+
${this.selectedTransaction.signature}
+
+ + Close + +
- Block -
-
${this.selectedTransaction.blockHeight}
+ +
+
+ +

Send QORT

+
+
+

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

+

+ Available balance:
+ ${this.balanceString} +

+

+ + +

+

+ + +

+
+

Current static fee: 0.001 QORT

+
+

${this.errorMessage}

+

${this.successMessage}

+ ${this.sendMoneyLoading ? html` ` : ''} +
+
+ this.sendQort()}> + + Send QORT + +
+
+
+ + Close + +
- Time -
-
${new Date(this.selectedTransaction.timestamp).toString()}
+ +
+
+ +

Send BTC

+
+
+

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

+

+ Available balance:
+ ${this.balanceString} +

+

+ + +

+

+ + +

+
+

Current fee per byte: ${(this.btcFeePerByte / 1e8).toFixed(8)} BTC
Low fees may result in slow or unconfirmed transactions.

+ + +
+

${this.errorMessage}

+

${this.successMessage}

+ ${this.sendMoneyLoading ? html` ` : ''} +
+
+ this.sendBtc()}> + + Send BTC + +
+
+
+ + Close + +
- Transaction Signature -
-
${this.selectedTransaction.signature}
-
-
-
-
- ` + +
+
+ +

Send LTC

+
+
+

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

+

+ Available balance:
+ ${this.balanceString} +

+

+ + +

+

+ + +

+
+

Current fee per byte: ${(this.ltcFeePerByte / 1e8).toFixed(8)} LTC
Low fees may result in slow or unconfirmed transactions.

+ + +
+

${this.errorMessage}

+

${this.successMessage}

+ ${this.sendMoneyLoading ? html` ` : ''} +
+
+ this.sendLtc()}> + + Send LTC + +
+
+
+ + Close + +
+ + +
+
+ +

Send DOGE

+
+
+

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

+

+ Available balance:
+ ${this.balanceString} +

+

+ + +

+

+ + +

+
+

+ Current fee per byte: ${(this.dogeFeePerByte / 1e8).toFixed(8)} DOGE
Low fees may result in slow or unconfirmed transactions. +

+ + +
+

${this.errorMessage}

+

${this.successMessage}

+ ${this.sendMoneyLoading ? html` ` : ''} +
+
+ this.sendDoge()}> + + Send DOGE + +
+
+
+ + Close + +
+
+ ` } firstUpdated() { @@ -666,11 +1004,17 @@ class MultiWallet extends LitElement { this.changeTheme(); }, 100) - // DOM refs + setInterval(() => { + this.errorMessage = ''; + }, 5000) + + setInterval(() => { + this.successMessage = ''; + }, 5000) + this.currencyBoxes = this.shadowRoot.querySelectorAll('.currency-box') this.transactionsDOM = this.shadowRoot.getElementById('transactionsDOM') - // Attach eventlisteners to the cuurency boxes this.currencyBoxes.forEach((currencyBox) => { currencyBox.addEventListener('click', this.selectWallet) }) @@ -682,16 +1026,202 @@ class MultiWallet extends LitElement { this.isTextMenuOpen = true this._textMenu(event) }) + window.addEventListener('click', () => { if (this.isTextMenuOpen) { parentEpml.request('closeCopyTextMenu', null) } }) + window.onkeyup = (e) => { if (e.keyCode === 27) { parentEpml.request('closeCopyTextMenu', null) } } + + this.shadowRoot.getElementById('amountInput').addEventListener('contextmenu', (event) => { + const getSelectedText = () => { + var text = '' + if (typeof window.getSelection != 'undefined') { + text = window.getSelection().toString() + } else if (typeof this.shadowRoot.selection != 'undefined' && this.shadowRoot.selection.type == 'Text') { + text = this.shadowRoot.selection.createRange().text + } + return text + } + const checkSelectedTextAndShowMenu = () => { + let selectedText = getSelectedText() + if (selectedText && typeof selectedText === 'string') { + } else { + this.pasteMenu(event, 'amountInput') + this.isPasteMenuOpen = true + event.preventDefault() + event.stopPropagation() + } + } + checkSelectedTextAndShowMenu() + }) + + this.shadowRoot.getElementById('recipient').addEventListener('contextmenu', (event) => { + const getSelectedText = () => { + var text = '' + if (typeof window.getSelection != 'undefined') { + text = window.getSelection().toString() + } else if (typeof this.shadowRoot.selection != 'undefined' && this.shadowRoot.selection.type == 'Text') { + text = this.shadowRoot.selection.createRange().text + } + return text + } + const checkSelectedTextAndShowMenu = () => { + let selectedText = getSelectedText() + if (selectedText && typeof selectedText === 'string') { + } else { + this.pasteMenu(event, 'recipient') + this.isPasteMenuOpen = true + event.preventDefault() + event.stopPropagation() + } + } + checkSelectedTextAndShowMenu() + }) + + this.shadowRoot.getElementById('btcAmountInput').addEventListener('contextmenu', (event) => { + const getSelectedText = () => { + var text = '' + if (typeof window.getSelection != 'undefined') { + text = window.getSelection().toString() + } else if (typeof this.shadowRoot.selection != 'undefined' && this.shadowRoot.selection.type == 'Text') { + text = this.shadowRoot.selection.createRange().text + } + return text + } + const checkSelectedTextAndShowMenu = () => { + let selectedText = getSelectedText() + if (selectedText && typeof selectedText === 'string') { + } else { + this.pasteMenu(event, 'btcAmountInput') + this.isPasteMenuOpen = true + event.preventDefault() + event.stopPropagation() + } + } + checkSelectedTextAndShowMenu() + }) + + this.shadowRoot.getElementById('btcRecipient').addEventListener('contextmenu', (event) => { + const getSelectedText = () => { + var text = '' + if (typeof window.getSelection != 'undefined') { + text = window.getSelection().toString() + } else if (typeof this.shadowRoot.selection != 'undefined' && this.shadowRoot.selection.type == 'Text') { + text = this.shadowRoot.selection.createRange().text + } + return text + } + const checkSelectedTextAndShowMenu = () => { + let selectedText = getSelectedText() + if (selectedText && typeof selectedText === 'string') { + } else { + this.pasteMenu(event, 'btcRecipient') + this.isPasteMenuOpen = true + event.preventDefault() + event.stopPropagation() + } + } + checkSelectedTextAndShowMenu() + }) + + this.shadowRoot.getElementById('ltcAmountInput').addEventListener('contextmenu', (event) => { + const getSelectedText = () => { + var text = '' + if (typeof window.getSelection != 'undefined') { + text = window.getSelection().toString() + } else if (typeof this.shadowRoot.selection != 'undefined' && this.shadowRoot.selection.type == 'Text') { + text = this.shadowRoot.selection.createRange().text + } + return text + } + const checkSelectedTextAndShowMenu = () => { + let selectedText = getSelectedText() + if (selectedText && typeof selectedText === 'string') { + } else { + this.pasteMenu(event, 'ltcAmountInput') + this.isPasteMenuOpen = true + event.preventDefault() + event.stopPropagation() + } + } + checkSelectedTextAndShowMenu() + }) + + this.shadowRoot.getElementById('ltcRecipient').addEventListener('contextmenu', (event) => { + const getSelectedText = () => { + var text = '' + if (typeof window.getSelection != 'undefined') { + text = window.getSelection().toString() + } else if (typeof this.shadowRoot.selection != 'undefined' && this.shadowRoot.selection.type == 'Text') { + text = this.shadowRoot.selection.createRange().text + } + return text + } + const checkSelectedTextAndShowMenu = () => { + let selectedText = getSelectedText() + if (selectedText && typeof selectedText === 'string') { + } else { + this.pasteMenu(event, 'ltcRecipient') + this.isPasteMenuOpen = true + event.preventDefault() + event.stopPropagation() + } + } + checkSelectedTextAndShowMenu() + }) + + this.shadowRoot.getElementById('dogeAmountInput').addEventListener('contextmenu', (event) => { + const getSelectedText = () => { + var text = '' + if (typeof window.getSelection != 'undefined') { + text = window.getSelection().toString() + } else if (typeof this.shadowRoot.selection != 'undefined' && this.shadowRoot.selection.type == 'Text') { + text = this.shadowRoot.selection.createRange().text + } + return text + } + const checkSelectedTextAndShowMenu = () => { + let selectedText = getSelectedText() + if (selectedText && typeof selectedText === 'string') { + } else { + this.pasteMenu(event, 'dogeAmountInput') + this.isPasteMenuOpen = true + event.preventDefault() + event.stopPropagation() + } + } + checkSelectedTextAndShowMenu() + }) + + this.shadowRoot.getElementById('dogeRecipient').addEventListener('contextmenu', (event) => { + const getSelectedText = () => { + var text = '' + if (typeof window.getSelection != 'undefined') { + text = window.getSelection().toString() + } else if (typeof this.shadowRoot.selection != 'undefined' && this.shadowRoot.selection.type == 'Text') { + text = this.shadowRoot.selection.createRange().text + } + return text + } + const checkSelectedTextAndShowMenu = () => { + let selectedText = getSelectedText() + if (selectedText && typeof selectedText === 'string') { + } else { + this.pasteMenu(event, 'dogeRecipient') + this.isPasteMenuOpen = true + event.preventDefault() + event.stopPropagation() + } + } + checkSelectedTextAndShowMenu() + }) } selectWallet(event) { @@ -699,9 +1229,6 @@ class MultiWallet extends LitElement { const target = event.currentTarget - // if (target.classList.contains('active')) return - // removed to allow one click wallet refresh - this.currencyBoxes.forEach((currencyBox) => { if (currencyBox.classList.contains('active')) { currencyBox.classList.remove('active') @@ -712,13 +1239,337 @@ class MultiWallet extends LitElement { this.showWallet() } + _checkAmount(e) { + const targetAmount = e.target.value + const target = e.target + + if (targetAmount.length === 0) { + this.isValidAmount = false + this.btnDisable = true + + e.target.blur() + e.target.focus() + + e.target.invalid = true + e.target.validationMessage = 'Invalid Amount!' + } else { + this.btnDisable = false + } + + e.target.blur() + e.target.focus() + + e.target.validityTransform = (newValue, nativeValidity) => { + if (newValue.includes('-') === true) { + this.btnDisable = true + target.validationMessage = 'Invalid Amount!' + + 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 = 'Invalid Amount!' + } else { + return { + valid: true, + } + } + } + } else { + this.btnDisable = false + } + } + } + + pasteToTextBox(elementId) { + window.focus() + navigator.clipboard.readText().then((clipboardText) => { + let element = this.shadowRoot.getElementById(elementId) + element.value += clipboardText + element.focus() + }) + } + + pasteMenu(event, elementId) { + let eventObject = { pageX: event.pageX, pageY: event.pageY, clientX: event.clientX, clientY: event.clientY, elementId } + parentEpml.request('openFramePasteMenu', eventObject) + } + + async sendQort() { + const amount = this.shadowRoot.getElementById('amountInput').value + let recipient = this.shadowRoot.getElementById('recipient').value + + this.sendMoneyLoading = true + this.btnDisable = true + + if (parseFloat(amount) + parseFloat(0.001) > parseFloat(this.balance)) { + this.sendMoneyLoading = false + this.btnDisable = false + parentEpml.request('showSnackBar', 'Insufficient Funds!') + return false + } + + if (parseFloat(amount) <= 0) { + this.sendMoneyLoading = false + this.btnDisable = false + parentEpml.request('showSnackBar', 'Invalid Amount!') + return false + } + + if (recipient.length === 0) { + this.sendMoneyLoading = false + this.btnDisable = false + parentEpml.request('showSnackBar', 'Receiver cannot be empty!') + return false + } + + const getLastRef = async () => { + let myRef = await parentEpml.request('apiCall', { + type: 'api', + url: `/addresses/lastreference/${this.getSelectedWalletAddress()}`, + }) + return myRef + } + + 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 + } + + const validateAddress = async (receiverAddress) => { + let myAddress = await window.parent.validateAddress(receiverAddress) + return myAddress + } + + const validateReceiver = async (recipient) => { + let lastRef = await getLastRef() + let isAddress + + 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('INVALID_RECEIVER') + this.errorMessage = 'INVALID_RECEIVER' + this.sendMoneyLoading = false + this.btnDisable = false + } + } + } + + const makeTransactionRequest = async (receiver, lastRef) => { + let myReceiver = receiver + let mylastRef = lastRef + + let myTxnrequest = await parentEpml.request('transaction', { + type: 2, + nonce: this.wallets.get(this._selectedWallet).wallet.nonce, + params: { + recipient: myReceiver, + amount: amount, + lastReference: mylastRef, + fee: 0.001, + }, + }) + return myTxnrequest + } + + 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 = 'Transaction Successful!' + this.sendMoneyLoading = false + this.btnDisable = false + } else { + this.errorMessage = txnResponse.data.message + this.sendMoneyLoading = false + this.btnDisable = false + throw new Error(txnResponse) + } + } + validateReceiver(recipient) + 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 + + this.sendMoneyLoading = true + this.btnDisable = true + + const makeRequest = async () => { + const opts = { + xprv58: xprv58, + receivingAddress: btcRecipient, + bitcoinAmount: btcAmount, + feePerByte: (this.btcFeePerByte / 1e8).toFixed(8), + } + const response = await parentEpml.request('sendBtc', opts) + return response + } + + 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 = 'Transaction Successful!' + this.sendMoneyLoading = false + this.btnDisable = false + } else if (response === false) { + this.errorMessage = 'Transaction Failed!' + 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) + 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 + + this.sendMoneyLoading = true + this.btnDisable = true + + const makeRequest = async () => { + const opts = { + xprv58: xprv58, + receivingAddress: ltcRecipient, + litecoinAmount: ltcAmount, + feePerByte: (this.ltcFeePerByte / 1e8).toFixed(8), + } + const response = await parentEpml.request('sendLtc', opts) + return response + } + + 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 = 'Transaction Successful!' + this.sendMoneyLoading = false + this.btnDisable = false + } else if (response === false) { + this.errorMessage = 'Transaction Failed!' + 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) + 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 + + this.sendMoneyLoading = true + this.btnDisable = true + + const makeRequest = async () => { + const opts = { + xprv58: xprv58, + receivingAddress: dogeRecipient, + dogecoinAmount: dogeAmount, + feePerByte: (this.dogeFeePerByte / 1e8).toFixed(8), + } + const response = await parentEpml.request('sendDoge', opts) + return response + } + + 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 = 'Transaction Successful!' + this.sendMoneyLoading = false + this.btnDisable = false + } else if (response === false) { + this.errorMessage = 'Transaction Failed!' + 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) + this.showWallet() + } + async showWallet() { this.transactionsDOM.hidden = true this.loading = true if (this._selectedWallet == 'qort') { if (!window.parent.reduxStore.getState().app.blockInfo.height) { - // we make sure that `blockHeight` is set before rendering QORT transactions await parentEpml.request('apiCall', { url: `/blocks/height`, type: 'api' }) .then(height => parentEpml.request('updateBlockInfo', { height })) } @@ -726,7 +1577,6 @@ class MultiWallet extends LitElement { const coin = this._selectedWallet await this.fetchWalletDetails(this._selectedWallet) if (this._selectedWallet == coin) { - //if the wallet didn't switch await this.renderTransactions() await this.getTransactionGrid(this._selectedWallet) await this.updateItemsFromPage(1, true) @@ -734,66 +1584,63 @@ class MultiWallet extends LitElement { this.transactionsDOM.hidden = false } } + async fetchWalletDetails(coin) { - //this function will fetch the balance and transactions of the given wallet this.balanceString = "Fetching balance ..." switch (coin) { case 'qort': - //fetching the qort balance - parentEpml - .request('apiCall', { - url: `/addresses/balance/${this.wallets.get('qort').wallet.address}?apiKey=${this.getApiKey()}`, - }) - .then((res) => { - if (isNaN(Number(res))) { - parentEpml.request('showSnackBar', `Failed to Fetch QORT Balance. Try again!`) - } else { - if (this._selectedWallet == coin) { - //check if we are still fetching wallet balance ... - this.wallets.get(coin).balance = res - this.balanceString = this.wallets.get(this._selectedWallet).balance + " " + this._selectedWallet.toLocaleUpperCase() - } + parentEpml.request('apiCall', { + url: `/addresses/balance/${this.wallets.get('qort').wallet.address}?apiKey=${this.getApiKey()}`, + }) + .then((res) => { + if (isNaN(Number(res))) { + parentEpml.request('showSnackBar', `Failed to Fetch QORT Balance. Try again!`) + } else { + if (this._selectedWallet == coin) { + this.wallets.get(coin).balance = res + this.balanceString = this.wallets.get(this._selectedWallet).balance + " " + this._selectedWallet.toLocaleUpperCase() + this.balance = this.wallets.get(this._selectedWallet).balance } - }) - //fetching the qort transactions + } + }) const txsQort = await parentEpml.request('apiCall', { url: `/transactions/search?address=${this.wallets.get('qort').wallet.address}&confirmationStatus=CONFIRMED&reverse=true`, }) - if (this._selectedWallet == coin) + if (this._selectedWallet == coin) { this.wallets.get(coin).transactions = txsQort - + } break case 'btc': case 'ltc': case 'doge': - //fetching the balance 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))) { - parentEpml.request('showSnackBar', `Failed to Fetch ${coin.toLocaleUpperCase()} Balance. Try again!`) - } else { - if (this._selectedWallet == coin) { - //check if we are still fetching wallet balance ... - this.wallets.get(this._selectedWallet).balance = (Number(res) / 1e8).toFixed(8) - this.balanceString = this.wallets.get(this._selectedWallet).balance + " " + this._selectedWallet.toLocaleUpperCase() - } + 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))) { + parentEpml.request('showSnackBar', `Failed to Fetch ${coin.toLocaleUpperCase()} Balance. Try again!`) + } 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 } - }) - //fetching transactions + } + }) + 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) { @@ -805,6 +1652,36 @@ class MultiWallet extends LitElement { } } + renderSendButton() { + if ( this._selectedWallet === "qort" ) { + return html` this.openSendQort()}> Send QORT` + } else if ( this._selectedWallet === "btc" ) { + return html` this.openSendBtc()}> Send BTC` + } else if ( this._selectedWallet === "ltc" ) { + return html` this.openSendLtc()}> Send LTC` + } else if ( this._selectedWallet === "doge" ) { + return html` this.openSendDoge()}> Send DOGE` + } 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(); + } + changeTheme() { const checkTheme = localStorage.getItem('qortalTheme') if (checkTheme === 'dark') { @@ -847,8 +1724,7 @@ class MultiWallet extends LitElement { } renderQortTransactions(transactions, coin) { - const requiredConfirmations = 3 // arbitrary value - // initially `currentBlockHeight` might not be set in the store + const requiredConfirmations = 3 const currentBlockHeight = window.parent.reduxStore.getState().app.blockInfo.height if (Array.isArray(transactions)) { transactions = transactions.map(tx => { @@ -858,79 +1734,115 @@ class MultiWallet extends LitElement { } return html` -
Address has no transactions yet.
- - { - if (!currentBlockHeight) { - return render(html``, root) - } - const confirmed = data.item.confirmations >= requiredConfirmations - if (confirmed) { - render(html`check`, root) - } else { - render(html`schedule`, root) - } - }} - > - - { - render(html` ${data.item.type} ${data.item.creatorAddress === this.wallets.get('qort').wallet.address ? html`OUT` : html`IN`} `, root) - }} - > - - - - - - { - const time = new Date(data.item.timestamp) - render(html` `, root) - }} - > - - -
- ` +
Address has no transactions yet.
+ + { + if (!currentBlockHeight) { + return render(html``, root) + } + const confirmed = data.item.confirmations >= requiredConfirmations + if (confirmed) { + render(html`check`, root) + } else { + render(html`schedule`, root) + } + }} + > + + { + render(html` ${data.item.type} ${data.item.creatorAddress === this.wallets.get('qort').wallet.address ? html`OUT` : html`IN`} `, root) + }} + > + + + + + + { + const time = new Date(data.item.timestamp) + render(html` `, root) + }} + > + + +
+ ` } renderBTCLikeTransactions(transactions, coin) { return html` -
Address has no transactions yet.
- - - { - const amount = (Number(data.item.totalAmount) / 1e8).toFixed(8) - render(html`${amount}`, root) - }} - > - - { - const time = new Date(data.item.timestamp * 1000) - render(html` `, root) - }} - > - - -
- ` +
Address has no transactions yet.
+ + { + render(html`check`, root) + }} + > + + { + render(html` PAYMENT ${data.item.inputs[0].address === this.wallets.get(this._selectedWallet).wallet.address ? html`OUT` : html`IN`} `, 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 * 1000) + render(html` `, root) + }} + > + + +
+ ` } async updateItemsFromPage(page, changeWallet = false) { @@ -1012,6 +1924,7 @@ class MultiWallet extends LitElement { } return text } + const checkSelectedTextAndShowMenu = () => { let selectedText = getSelectedText() if (selectedText && typeof selectedText === 'string') { @@ -1022,7 +1935,6 @@ class MultiWallet extends LitElement { parentEpml.request('openCopyTextMenu', textMenuObject) } } - checkSelectedTextAndShowMenu() } @@ -1054,7 +1966,6 @@ class MultiWallet extends LitElement { showTransactionDetails(myTransaction, allTransactions) { allTransactions.forEach((transaction) => { if (myTransaction.signature === transaction.signature) { - // Do something... let txnFlow = myTransaction.creatorAddress === this.wallets.get('qort').wallet.address ? 'OUT' : 'IN' this.selectedTransaction = { ...transaction, txnFlow } if (this.selectedTransaction.signature.length != 0) { @@ -1078,7 +1989,6 @@ class MultiWallet extends LitElement { decimals(num) { num = parseFloat(num) - // So that conversion to string can get rid of insignificant zeros return num % 1 > 0 ? (num + '').split('.')[1] : '0' } @@ -1094,9 +2004,6 @@ class MultiWallet extends LitElement { return num.toLocaleString() } - textColor(color) { - return color === 'light' ? 'rgba(255,255,255,0.7)' : 'rgba(0,0,0,0.87)' - } _unconfirmedClass(unconfirmed) { return unconfirmed ? 'unconfirmed' : '' }