4
1
mirror of https://github.com/Qortal/qortal-ui.git synced 2025-02-11 17:55:51 +00:00

Merge pull request #50 from PhillipLangMartinez/Feature/become-minter

Added new plugin - Become a minter
This commit is contained in:
AlphaX-Projects 2022-08-11 09:00:28 +02:00 committed by GitHub
commit 2840a9dd89
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 2408 additions and 1156 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,159 +1,270 @@
import { LitElement, html, css } from 'lit'
import { connect } from 'pwa-helpers'
import { store } from '../store.js'
import { translate, translateUnsafeHTML } from 'lit-translate'
import { LitElement, html, css } from 'lit';
import { connect } from 'pwa-helpers';
import { store } from '../store.js';
import { translate, translateUnsafeHTML } from 'lit-translate';
import '@polymer/paper-ripple'
import '@vaadin/icon'
import '@vaadin/icons'
import '../functional-components/side-menu.js'
import '../functional-components/side-menu-item.js'
import '@polymer/paper-ripple';
import '@vaadin/icon';
import '@vaadin/icons';
import '../functional-components/side-menu.js';
import '../functional-components/side-menu-item.js';
import '../functional-components/my-button.js';
import './start-minting';
class SidenavMenu extends connect(store)(LitElement) {
static get properties() {
return {
config: { type: Object },
urls: { type: Object },
nodeType: { type: String, reflect: true },
theme: { type: String, reflect: true }
}
}
static get properties() {
return {
config: { type: Object },
urls: { type: Object },
nodeType: { type: String, reflect: true },
theme: { type: String, reflect: true },
addressInfo: { type: Object },
};
}
static get styles() {
return [
css`
* {
--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 [
css`
* {
--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
);
}
.s-menu {
list-style: none;
padding: 0px 0px;
background: var(--sidetopbar);
border-radius: 2px;
width: 100%;
border-top: 1px solid var(--border);
outline: none;
}
`
]
}
.s-menu {
list-style: none;
padding: 0px 0px;
background: var(--sidetopbar);
border-radius: 2px;
width: 100%;
border-top: 1px solid var(--border);
outline: none;
}
constructor() {
super()
this.urls = []
this.nodeType = ''
this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light'
}
.start-minting-wrapper {
position: absolute;
bottom: 130px;
left: 50%;
transform: translateX(calc(-50% - 10px));
}
`,
];
}
render() {
return html`
<div class="s-menu">
<side-menu>
${this.renderNodeTypeMenu()}
${this.renderNodeManagement()}
</side-menu>
</div>
`
}
constructor() {
super();
this.urls = [];
this.nodeType = '';
this.theme = localStorage.getItem('qortalTheme')
? localStorage.getItem('qortalTheme')
: 'light';
this.addressInfo = {};
}
firstUpdated() {
this.getNodeType()
}
render() {
return html`
<div class="s-menu">
<side-menu>
${this.renderNodeTypeMenu()} ${this.renderNodeManagement()}
</side-menu>
</div>
async getNodeType() {
const myNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node]
const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port
const url = `${nodeUrl}/admin/info`
await fetch(url)
.then(response => {
return response.json()
})
.then(data => {
this.nodeType = data.type
})
.catch(err => {
console.error('Request failed', err);
})
}
<start-minting></start-minting>
`;
}
renderNodeTypeMenu() {
if (this.nodeType === 'lite') {
return html`
<side-menu-item label="${translate("sidemenu.wallets")}" href="/app/wallet" selected>
<vaadin-icon icon="vaadin:wallet" slot="icon"></vaadin-icon>
</side-menu-item>
<side-menu-item label="${translate("sidemenu.nameregistration")}" href="/app/name-registration">
<vaadin-icon icon="vaadin:user-check" slot="icon"></vaadin-icon>
</side-menu-item>
<side-menu-item label="${translate("sidemenu.datamanagement")}" href="/app/data-management">
<vaadin-icon icon="vaadin:database" slot="icon"></vaadin-icon>
</side-menu-item>
<side-menu-item label="${translate("sidemenu.qchat")}" href="/app/q-chat">
<vaadin-icon icon="vaadin:chat" slot="icon"></vaadin-icon>
</side-menu-item>
`
} else {
return html`
<side-menu-item label="${translate("sidemenu.mintingdetails")}" href="/app/minting">
<vaadin-icon icon="vaadin:info-circle" slot="icon"></vaadin-icon>
</side-menu-item>
<side-menu-item label="${translate("sidemenu.wallets")}" href="/app/wallet" selected>
<vaadin-icon icon="vaadin:wallet" slot="icon"></vaadin-icon>
</side-menu-item>
<side-menu-item label="${translate("sidemenu.tradeportal")}" href="/app/trade-portal">
<vaadin-icon icon="vaadin:bullets" slot="icon"></vaadin-icon>
</side-menu-item>
<side-menu-item label="${translate("sidemenu.rewardshare")}" href="/app/reward-share">
<vaadin-icon icon="vaadin:share-square" slot="icon"></vaadin-icon>
</side-menu-item>
<side-menu-item label="${translate("sidemenu.nameregistration")}" href="/app/name-registration">
<vaadin-icon icon="vaadin:user-check" slot="icon"></vaadin-icon>
</side-menu-item>
<side-menu-item label="${translate("sidemenu.websites")}" href="/app/websites">
<vaadin-icon icon="vaadin:desktop" slot="icon"></vaadin-icon>
</side-menu-item>
<side-menu-item label="${translate("sidemenu.datamanagement")}" href="/app/data-management">
<vaadin-icon icon="vaadin:database" slot="icon"></vaadin-icon>
</side-menu-item>
<side-menu-item label="${translate("sidemenu.qchat")}" href="/app/q-chat">
<vaadin-icon icon="vaadin:chat" slot="icon"></vaadin-icon>
</side-menu-item>
<side-menu-item label="${translate("sidemenu.groupmanagement")}" href="/app/group-management">
<vaadin-icon icon="vaadin:group" slot="icon"></vaadin-icon>
</side-menu-item>
<side-menu-item label="${translate("sidemenu.puzzles")}" href="/app/puzzles">
<vaadin-icon icon="vaadin:puzzle-piece" slot="icon"></vaadin-icon>
</side-menu-item>
`
}
}
firstUpdated() {
this.getNodeType();
}
renderNodeManagement() {
const checkNodeManagement = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node]
if (checkNodeManagement.enableManagement = true) {
return html`
<side-menu-item label="${translate("sidemenu.nodemanagement")}" href="/app/node-management">
<vaadin-icon icon="vaadin:cloud" slot="icon"></vaadin-icon>
</side-menu-item>
`
} else {
return html``
}
}
async getNodeType() {
const myNode =
store.getState().app.nodeConfig.knownNodes[
store.getState().app.nodeConfig.node
];
const nodeUrl =
myNode.protocol + '://' + myNode.domain + ':' + myNode.port;
const url = `${nodeUrl}/admin/info`;
await fetch(url)
.then((response) => {
return response.json();
})
.then((data) => {
this.nodeType = data.type;
})
.catch((err) => {
console.error('Request failed', err);
});
}
stateChanged(state) {
this.config = state.config
this.urls = state.app.registeredUrls
}
renderNodeTypeMenu() {
const addressInfo = this.addressInfo;
const isMinter = addressInfo?.error !== 124 && +addressInfo?.level > 0;
if (this.nodeType === 'lite') {
return html`
<side-menu-item
label="${translate('sidemenu.wallets')}"
href="/app/wallet"
selected
>
<vaadin-icon icon="vaadin:wallet" slot="icon"></vaadin-icon>
</side-menu-item>
<side-menu-item
label="${translate('sidemenu.nameregistration')}"
href="/app/name-registration"
>
<vaadin-icon
icon="vaadin:user-check"
slot="icon"
></vaadin-icon>
</side-menu-item>
<side-menu-item
label="${translate('sidemenu.datamanagement')}"
href="/app/data-management"
>
<vaadin-icon
icon="vaadin:database"
slot="icon"
></vaadin-icon>
</side-menu-item>
<side-menu-item
label="${translate('sidemenu.qchat')}"
href="/app/q-chat"
>
<vaadin-icon icon="vaadin:chat" slot="icon"></vaadin-icon>
</side-menu-item>
`;
} else {
return html`
${isMinter
? html`<side-menu-item
label="${translate('sidemenu.mintingdetails')}"
href="/app/minting"
>
<vaadin-icon
icon="vaadin:info-circle"
slot="icon"
></vaadin-icon>
</side-menu-item>`
: html`<side-menu-item
label="${translate('sidemenu.becomeAMinter')}"
href="/app/become-minter"
>
<vaadin-icon
icon="vaadin:info-circle"
slot="icon"
></vaadin-icon>
</side-menu-item>`}
<side-menu-item
label="${translate('sidemenu.wallets')}"
href="/app/wallet"
selected
>
<vaadin-icon icon="vaadin:wallet" slot="icon"></vaadin-icon>
</side-menu-item>
<side-menu-item
label="${translate('sidemenu.tradeportal')}"
href="/app/trade-portal"
>
<vaadin-icon
icon="vaadin:bullets"
slot="icon"
></vaadin-icon>
</side-menu-item>
<side-menu-item
label="${translate('sidemenu.rewardshare')}"
href="/app/reward-share"
>
<vaadin-icon
icon="vaadin:share-square"
slot="icon"
></vaadin-icon>
</side-menu-item>
<side-menu-item
label="${translate('sidemenu.nameregistration')}"
href="/app/name-registration"
>
<vaadin-icon
icon="vaadin:user-check"
slot="icon"
></vaadin-icon>
</side-menu-item>
<side-menu-item
label="${translate('sidemenu.websites')}"
href="/app/websites"
>
<vaadin-icon
icon="vaadin:desktop"
slot="icon"
></vaadin-icon>
</side-menu-item>
<side-menu-item
label="${translate('sidemenu.datamanagement')}"
href="/app/data-management"
>
<vaadin-icon
icon="vaadin:database"
slot="icon"
></vaadin-icon>
</side-menu-item>
<side-menu-item
label="${translate('sidemenu.qchat')}"
href="/app/q-chat"
>
<vaadin-icon icon="vaadin:chat" slot="icon"></vaadin-icon>
</side-menu-item>
<side-menu-item
label="${translate('sidemenu.groupmanagement')}"
href="/app/group-management"
>
<vaadin-icon icon="vaadin:group" slot="icon"></vaadin-icon>
</side-menu-item>
<side-menu-item
label="${translate('sidemenu.puzzles')}"
href="/app/puzzles"
>
<vaadin-icon
icon="vaadin:puzzle-piece"
slot="icon"
></vaadin-icon>
</side-menu-item>
`;
}
}
renderNodeManagement() {
const checkNodeManagement =
store.getState().app.nodeConfig.knownNodes[
store.getState().app.nodeConfig.node
];
if ((checkNodeManagement.enableManagement = true)) {
return html`
<side-menu-item
label="${translate('sidemenu.nodemanagement')}"
href="/app/node-management"
>
<vaadin-icon icon="vaadin:cloud" slot="icon"></vaadin-icon>
</side-menu-item>
`;
} else {
return html``;
}
}
stateChanged(state) {
this.config = state.config;
this.urls = state.app.registeredUrls;
this.addressInfo = state.app.accountInfo.addressInfo;
}
}
window.customElements.define('sidenav-menu', SidenavMenu)
window.customElements.define('sidenav-menu', SidenavMenu);

View File

@ -0,0 +1,261 @@
import { LitElement, html, css } from 'lit';
import { connect } from 'pwa-helpers';
import { store } from '../store.js';
import { translate, get } from 'lit-translate';
import '../functional-components/my-button.js';
import { routes } from '../plugins/routes.js';
class StartMinting extends connect(store)(LitElement) {
static get properties() {
return {
addressInfo: { type: Object },
mintingAccountData: { type: Array },
errorMsg: { type: String },
};
}
static get styles() {
return [
css`
.start-minting-wrapper {
position: absolute;
bottom: 130px;
left: 50%;
transform: translateX(calc(-50% - 10px));
}
`,
];
}
constructor() {
super();
this.addressInfo = {};
this.mintingAccountData = [];
this.errorMsg = '';
}
render() {
return html` ${this.renderStartMintingButton()} `;
}
firstUpdated() {
this.getMintingAcccounts();
}
async getMintingAcccounts() {
const myNode =
store.getState().app.nodeConfig.knownNodes[
store.getState().app.nodeConfig.node
];
const nodeUrl =
myNode.protocol + '://' + myNode.domain + ':' + myNode.port;
const url = `${nodeUrl}/admin/mintingaccounts`;
try {
const res = await fetch(url);
const mintingAccountData = await res.json();
this.mintingAccountData = mintingAccountData;
} catch (error) {
this.errorMsg = 'Cannot fetch minting accounts';
}
}
renderStartMintingButton() {
const myNode =
store.getState().app.nodeConfig.knownNodes[
store.getState().app.nodeConfig.node
];
const nodeUrl =
myNode.protocol + '://' + myNode.domain + ':' + myNode.port;
const mintingAccountData = this.mintingAccountData;
const addressInfo = this.addressInfo;
const rewardShares = async (minterAddr) => {
const url = `${nodeUrl}/addresses/rewardshares?minters=${minterAddr}&recipients=${minterAddr}`;
const res = await fetch(url);
const data = await res.json();
return data;
};
const address =
window.parent.reduxStore.getState().app?.selectedAddress?.address;
const nonce =
window.parent.reduxStore.getState().app?.selectedAddress?.nonce;
const publicAddress =
window.parent.reduxStore.getState().app?.selectedAddress
?.base58PublicKey;
const findMintingAccount = mintingAccountData.find((ma) =>
ma.publicKey.includes(publicAddress)
);
const isMinterButKeyMintingKeyNotAssigned =
addressInfo?.error !== 124 &&
addressInfo?.level === 1 &&
!findMintingAccount;
const removeMintingAccount = async (publicKey) => {
const url = `${nodeUrl}/admin/mintingaccounts?apiKey=${myNode.apiKey}`;
return await fetch(url, {
method: 'DELETE',
body: publicKey,
});
};
const makeTransactionRequest = async (lastRef) => {
let mylastRef = lastRef;
let rewarddialog1 = get('transactions.rewarddialog1');
let rewarddialog2 = get('transactions.rewarddialog2');
let rewarddialog3 = get('transactions.rewarddialog3');
let rewarddialog4 = get('transactions.rewarddialog4');
let myTxnrequest = await routes.transaction({
data: {
type: 38,
nonce: nonce,
params: {
recipientPublicKey: publicAddress,
percentageShare: 0,
lastReference: mylastRef,
rewarddialog1: rewarddialog1,
rewarddialog2: rewarddialog2,
rewarddialog3: rewarddialog3,
rewarddialog4: rewarddialog4,
},
},
disableModal: true,
});
return myTxnrequest;
};
const getTxnRequestResponse = (txnResponse) => {
if (txnResponse.success === false && txnResponse.message) {
throw new Error(txnResponse);
} else if (
txnResponse.success === true &&
!txnResponse.data.error
) {
let err6string = get('rewardsharepage.rchange21');
return err6string;
} else {
throw new Error(txnResponse);
}
};
const createSponsorshipKey = async () => {
let lastRef = await getLastRef();
let myTransaction = await makeTransactionRequest(lastRef);
getTxnRequestResponse(myTransaction);
return myTransaction.data;
};
const addMintingAccount = async (sponsorshipKeyValue) => {
const url = `${nodeUrl}/admin/mintingaccounts?apiKey=${myNode.apiKey}`;
return await fetch(url, {
method: 'POST',
body: sponsorshipKeyValue,
});
};
const getLastRef = async () => {
const url = `${nodeUrl}/addresses/lastreference/${address}`;
const res = await fetch(url);
const data = await res.text();
return data;
};
const startMinting = async () => {
this.errorMsg = '';
let rewardSharesList;
try {
rewardSharesList = await rewardShares(address);
} catch (error) {
this.errorMsg = 'Cannot fetch reward shares';
return;
}
// check to see if self-share exists
const findRewardShareData = rewardSharesList.find(
(rs) =>
rs?.mintingAccount === address && rs?.recipient === address
);
let sponsorshipKeyValue = null;
try {
if (!findRewardShareData) {
// if no self-share exits, create one.
sponsorshipKeyValue = await createSponsorshipKey();
} else {
sponsorshipKeyValue =
findRewardShareData.rewardSharePublicKey;
}
} catch (error) {
this.errorMsg = 'Cannot create sponsorship key';
return;
}
// Check to see if a sponsorship key on a newly-level 1 minter exists. If it does, remove it.
const findMintingAccountFromOtherUser = mintingAccountData.find(
(ma) => !ma.publicKey.includes(publicAddress)
);
try {
if (
findMintingAccountFromOtherUser &&
findMintingAccountFromOtherUser?.publicKey[0]
) {
await removeMintingAccount(
findMintingAccountFromOtherUser?.publicKey[0]
);
}
} catch (error) {
this.errorMsg = 'Failed to remove key';
return;
}
try {
await addMintingAccount(sponsorshipKeyValue);
routes.showSnackBar({
data: translate('becomeMinterPage.bchange19'),
});
this.getMintingAcccounts();
} catch (error) {
this.errorMsg = 'Failed to add minting key';
return;
}
};
return html`
${isMinterButKeyMintingKeyNotAssigned
? html`
<div class="start-minting-wrapper">
<my-button
label="${translate(
'becomeMinterPage.bchange18'
)}"
?isLoading=${false}
.onClick=${async () => {
await startMinting();
if (this.errorMsg) {
routes.showSnackBar({
data: this.errorMsg,
});
}
}}
></my-button>
</div>
`
: ''}
`;
}
stateChanged(state) {
this.addressInfo = state.app.accountInfo.addressInfo;
}
}
window.customElements.define('start-minting', StartMinting);

View File

@ -0,0 +1,48 @@
import { LitElement, html, css } from 'lit';
import '@vaadin/button';
import '@polymer/paper-spinner/paper-spinner-lite.js';
export class MyButton extends LitElement {
static properties = {
onClick: { type: Function },
isLoading: { type: Boolean },
label: { type: String },
};
static styles = css`
vaadin-button {
height: 100%;
margin: 0;
cursor: pointer;
min-width: 80px;
background-color: #03a9f4;
color: white;
}
vaadin-button:hover {
opacity: 0.8;
}
`;
constructor() {
super();
this.onClick = () => {};
this.isLoading = false;
this.label = '';
}
render() {
return html`
<vaadin-button
?disabled="${this.isLoading}"
@click="${this.onClick}"
>
${this.isLoading === false
? html`${this.label}`
: html`<paper-spinner-lite active></paper-spinner-lite>`}
</vaadin-button>
`;
}
}
customElements.define('my-button', MyButton);

View File

@ -1,83 +1,95 @@
import { store } from '../store.js'
import { doAddPluginUrl, doUpdateBlockInfo, doUpdateNodeStatus, doUpdateNodeInfo, doSetNode, doPageUrl, doSetChatHeads, doUpdateAccountInfo } from '../redux/app/app-actions.js'
import * as api from 'qortal-ui-crypto'
import { requestTransactionDialog } from '../functional-components/confirm-transaction-dialog.js'
import { doNewMessage } from '../notifications/controller.js'
import snackbar from '../functional-components/snackbar.js'
import { loadStateFromLocalStorage, saveStateToLocalStorage } from '../localStorageHelpers.js'
import copyTextMenu from '../functional-components/copy-text-menu.js'
import framePasteMenu from '../functional-components/frame-paste-menu.js'
import { store } from '../store.js';
import {
doAddPluginUrl,
doUpdateBlockInfo,
doUpdateNodeStatus,
doUpdateNodeInfo,
doSetNode,
doPageUrl,
doSetChatHeads,
doUpdateAccountInfo,
} from '../redux/app/app-actions.js';
import * as api from 'qortal-ui-crypto';
import { requestTransactionDialog } from '../functional-components/confirm-transaction-dialog.js';
import { doNewMessage } from '../notifications/controller.js';
import snackbar from '../functional-components/snackbar.js';
import {
loadStateFromLocalStorage,
saveStateToLocalStorage,
} from '../localStorageHelpers.js';
import copyTextMenu from '../functional-components/copy-text-menu.js';
import framePasteMenu from '../functional-components/frame-paste-menu.js';
const createTransaction = api.createTransaction
const processTransaction = api.processTransaction
const signChatTransaction = api.signChatTransaction
const signArbitraryTransaction = api.signArbitraryTransaction
const tradeBotCreateRequest = api.tradeBotCreateRequest
const tradeBotRespondRequest = api.tradeBotRespondRequest
const signTradeBotTxn = api.signTradeBotTxn
const deleteTradeOffer = api.deleteTradeOffer
const cancelAllOffers = api.cancelAllOffers
const sendBtc = api.sendBtc
const sendLtc = api.sendLtc
const sendDoge = api.sendDoge
const sendDgb = api.sendDgb
const sendRvn = api.sendRvn
const createTransaction = api.createTransaction;
const processTransaction = api.processTransaction;
const signChatTransaction = api.signChatTransaction;
const signArbitraryTransaction = api.signArbitraryTransaction;
const tradeBotCreateRequest = api.tradeBotCreateRequest;
const tradeBotRespondRequest = api.tradeBotRespondRequest;
const signTradeBotTxn = api.signTradeBotTxn;
const deleteTradeOffer = api.deleteTradeOffer;
const cancelAllOffers = api.cancelAllOffers;
const sendBtc = api.sendBtc;
const sendLtc = api.sendLtc;
const sendDoge = api.sendDoge;
const sendDgb = api.sendDgb;
const sendRvn = api.sendRvn;
export const routes = {
hello: async (req) => {
return 'Hello from awesomeness'
return 'Hello from awesomeness';
},
registerUrl: async (req) => {
store.dispatch(doAddPluginUrl(req.data))
store.dispatch(doAddPluginUrl(req.data));
},
setAccountInfo: async (req) => {
store.dispatch(doUpdateAccountInfo(req.data))
store.dispatch(doUpdateAccountInfo(req.data));
},
getAccountInfo: async (req) => {
return store.getState().app.accountInfo
return store.getState().app.accountInfo;
},
setChatHeads: async (req) => {
return store.dispatch(doSetChatHeads(req.data))
return store.dispatch(doSetChatHeads(req.data));
},
getChatHeads: async (req) => {
return store.getState().app.chatHeads
return store.getState().app.chatHeads;
},
updateBlockInfo: async (req) => {
store.dispatch(doUpdateBlockInfo(req.data))
store.dispatch(doUpdateBlockInfo(req.data));
},
updateNodeStatus: async (req) => {
store.dispatch(doUpdateNodeStatus(req.data))
store.dispatch(doUpdateNodeStatus(req.data));
},
updateNodeInfo: async (req) => {
store.dispatch(doUpdateNodeInfo(req.data))
store.dispatch(doUpdateNodeInfo(req.data));
},
setNode: async (req) => {
store.dispatch(doSetNode(req.data))
store.dispatch(doSetNode(req.data));
},
getNodeConfig: async (req) => {
return store.getState().app.nodeConfig
return store.getState().app.nodeConfig;
},
setPageUrl: async (req) => {
return store.dispatch(doPageUrl(req.data))
return store.dispatch(doPageUrl(req.data));
},
getLocalStorage: async (req) => {
return loadStateFromLocalStorage(req.data)
return loadStateFromLocalStorage(req.data);
},
setLocalStorage: async (req) => {
return saveStateToLocalStorage(req.data.key, req.data.dataObj)
return saveStateToLocalStorage(req.data.key, req.data.dataObj);
},
openCopyTextMenu: async (req) => {
@ -85,26 +97,26 @@ export const routes = {
selectedText: req.data.selectedText,
eventObject: req.data.eventObject,
isFrame: req.data.isFrame,
}
copyTextMenu.open(textMenuObject)
};
copyTextMenu.open(textMenuObject);
},
closeCopyTextMenu: async (req) => {
copyTextMenu.close()
copyTextMenu.close();
},
openFramePasteMenu: async (req) => {
framePasteMenu.open(req.data)
framePasteMenu.open(req.data);
},
closeFramePasteMenu: async (req) => {
framePasteMenu.close()
framePasteMenu.close();
},
apiCall: async (req) => {
const url = req.data.url
delete req.data.url
return api.request(url, req.data)
const url = req.data.url;
delete req.data.url;
return api.request(url, req.data);
},
addresses: async (req) => {
@ -115,250 +127,288 @@ export const routes = {
nonce: address.nonce,
textColor: address.textColor,
base58PublicKey: address.base58PublicKey,
}
})
};
});
},
transaction: async (req) => {
let response
let response;
try {
const tx = createTransaction(req.data.type, store.getState().app.wallet._addresses[req.data.nonce].keyPair, req.data.params)
await requestTransactionDialog.requestTransaction(tx)
const res = await processTransaction(tx.signedBytes)
const tx = createTransaction(
req.data.type,
store.getState().app.wallet._addresses[req.data.nonce].keyPair,
req.data.params
);
if (!req.disableModal) {
await requestTransactionDialog.requestTransaction(tx);
}
const res = await processTransaction(tx.signedBytes);
response = {
success: true,
data: res,
}
};
} catch (e) {
console.error(e)
console.error(e.message)
console.error(e);
console.error(e.message);
response = {
success: false,
message: e.message,
}
};
}
return response
return response;
},
standaloneTransaction: async (req) => {
const rebuildUint8Array = (obj) => {
let _array = new Uint8Array(Object.keys(obj).length)
let _array = new Uint8Array(Object.keys(obj).length);
for (let i = 0; i < _array.byteLength; ++i) {
_array.set([obj[i]], i)
_array.set([obj[i]], i);
}
return _array
}
return _array;
};
let response
let response;
try {
// req.data.keyPair unfortunately "prepared" into horrible object so we need to convert back
let _keyPair = {};
for (let _keyName in req.data.keyPair) {
_keyPair[_keyName] = rebuildUint8Array(req.data.keyPair[_keyName])
_keyPair[_keyName] = rebuildUint8Array(
req.data.keyPair[_keyName]
);
}
const tx = createTransaction(req.data.type, _keyPair, req.data.params)
const res = await processTransaction(tx.signedBytes)
const tx = createTransaction(
req.data.type,
_keyPair,
req.data.params
);
const res = await processTransaction(tx.signedBytes);
response = {
success: true,
data: res,
}
};
} catch (e) {
console.error(e)
console.error(e.message)
console.error(e);
console.error(e.message);
response = {
success: false,
message: e.message,
}
};
}
return response
return response;
},
username: async (req) => {
const state = store.getState()
const username = state.user.storedWallets[state.app.wallet.addresses[0].address].name
const state = store.getState();
const username =
state.user.storedWallets[state.app.wallet.addresses[0].address]
.name;
return username
return username;
},
chat: async (req) => {
let response
let response;
try {
const tx = createTransaction(req.data.type, store.getState().app.wallet._addresses[req.data.nonce].keyPair, req.data.params)
const tx = createTransaction(
req.data.type,
store.getState().app.wallet._addresses[req.data.nonce].keyPair,
req.data.params
);
response = tx.chatBytes
response = tx.chatBytes;
} catch (e) {
console.error(e)
console.error(e.message)
response = false
console.error(e);
console.error(e.message);
response = false;
}
return response
return response;
},
sign_chat: async (req) => {
let response
let response;
try {
const signedChatBytes = await signChatTransaction(req.data.chatBytesArray, req.data.chatNonce, store.getState().app.wallet._addresses[req.data.nonce].keyPair)
const signedChatBytes = await signChatTransaction(
req.data.chatBytesArray,
req.data.chatNonce,
store.getState().app.wallet._addresses[req.data.nonce].keyPair
);
const res = await processTransaction(signedChatBytes)
response = res
const res = await processTransaction(signedChatBytes);
response = res;
} catch (e) {
console.error(e)
console.error(e.message)
response = false
console.error(e);
console.error(e.message);
response = false;
}
return response
return response;
},
sign_arbitrary: async (req) => {
let response
let response;
try {
const signedArbitraryBytes = await signArbitraryTransaction(req.data.arbitraryBytesBase58, req.data.arbitraryBytesForSigningBase58, req.data.arbitraryNonce, store.getState().app.wallet._addresses[req.data.nonce].keyPair)
const signedArbitraryBytes = await signArbitraryTransaction(
req.data.arbitraryBytesBase58,
req.data.arbitraryBytesForSigningBase58,
req.data.arbitraryNonce,
store.getState().app.wallet._addresses[req.data.nonce].keyPair
);
const res = await processTransaction(signedArbitraryBytes)
response = res
const res = await processTransaction(signedArbitraryBytes);
response = res;
} catch (e) {
console.error(e)
console.error(e.message)
response = false
console.error(e);
console.error(e.message);
response = false;
}
return response
return response;
},
showNotification: async (req) => {
doNewMessage(req.data)
doNewMessage(req.data);
},
showSnackBar: async (req) => {
snackbar.add({
labelText: req.data,
dismiss: true,
})
});
},
tradeBotCreateRequest: async (req) => {
let response
let response;
try {
const unsignedTxn = await tradeBotCreateRequest(req.data)
const unsignedTxn = await tradeBotCreateRequest(req.data);
const signedTxnBytes = await signTradeBotTxn(unsignedTxn, store.getState().app.selectedAddress.keyPair)
const signedTxnBytes = await signTradeBotTxn(
unsignedTxn,
store.getState().app.selectedAddress.keyPair
);
const res = await processTransaction(signedTxnBytes)
response = res
const res = await processTransaction(signedTxnBytes);
response = res;
} catch (e) {
console.error(e)
console.error(e.message)
response = e.message
console.error(e);
console.error(e.message);
response = e.message;
}
return response
return response;
},
tradeBotRespondRequest: async (req) => {
let response
let response;
try {
const res = await tradeBotRespondRequest(req.data)
const res = await tradeBotRespondRequest(req.data);
response = res
response = res;
} catch (e) {
console.error(e)
console.error(e.message)
response = e.message
console.error(e);
console.error(e.message);
response = e.message;
}
return response
return response;
},
deleteTradeOffer: async (req) => {
let response
let response;
try {
const unsignedTxn = await deleteTradeOffer(req.data)
const unsignedTxn = await deleteTradeOffer(req.data);
const signedTxnBytes = await signTradeBotTxn(unsignedTxn, store.getState().app.selectedAddress.keyPair)
const signedTxnBytes = await signTradeBotTxn(
unsignedTxn,
store.getState().app.selectedAddress.keyPair
);
const res = await processTransaction(signedTxnBytes)
const res = await processTransaction(signedTxnBytes);
response = res
response = res;
} catch (e) {
console.error(e)
console.error(e.message)
response = e.message
console.error(e);
console.error(e.message);
response = e.message;
}
return response
return response;
},
cancelAllOffers: async (req) => {
let response
let response;
try {
const res = await cancelAllOffers(store.getState().app.selectedAddress)
response = res
const res = await cancelAllOffers(
store.getState().app.selectedAddress
);
response = res;
} catch (e) {
console.error(e)
console.error(e.message)
response = e.message
console.error(e);
console.error(e.message);
response = e.message;
}
return response
return response;
},
sendBtc: async (req) => {
let response
let response;
try {
const res = await sendBtc(req.data)
response = res
const res = await sendBtc(req.data);
response = res;
} catch (e) {
console.error(e)
console.error(e.message)
response = e.message
console.error(e);
console.error(e.message);
response = e.message;
}
return response
return response;
},
sendLtc: async (req) => {
let response
let response;
try {
const res = await sendLtc(req.data)
response = res
const res = await sendLtc(req.data);
response = res;
} catch (e) {
console.error(e)
console.error(e.message)
response = e.message
console.error(e);
console.error(e.message);
response = e.message;
}
return response
return response;
},
sendDoge: async (req) => {
let response
let response;
try {
const res = await sendDoge(req.data)
response = res
const res = await sendDoge(req.data);
response = res;
} catch (e) {
console.error(e)
console.error(e.message)
response = e.message
console.error(e);
console.error(e.message);
response = e.message;
}
return response
return response;
},
sendDgb: async (req) => {
let response
let response;
try {
const res = await sendDgb(req.data)
response = res
const res = await sendDgb(req.data);
response = res;
} catch (e) {
console.error(e)
console.error(e.message)
response = e.message
console.error(e);
console.error(e.message);
response = e.message;
}
return response
return response;
},
sendRvn: async (req) => {
let response
let response;
try {
const res = await sendRvn(req.data)
response = res
const res = await sendRvn(req.data);
response = res;
} catch (e) {
console.error(e)
console.error(e.message)
response = e.message
console.error(e);
console.error(e.message);
response = e.message;
}
return response
return response;
},
}
};

View File

@ -1,137 +1,141 @@
require('events').EventEmitter.defaultMaxListeners = 0
const path = require("path");
const { nodeResolve } = require("@rollup/plugin-node-resolve");
const progress = require("rollup-plugin-progress");
require('events').EventEmitter.defaultMaxListeners = 0;
const path = require('path');
const { nodeResolve } = require('@rollup/plugin-node-resolve');
const progress = require('rollup-plugin-progress');
const replace = require('@rollup/plugin-replace');
const globals = require("rollup-plugin-node-globals");
const commonjs = require("@rollup/plugin-commonjs");
const alias = require("@rollup/plugin-alias");
const globals = require('rollup-plugin-node-globals');
const commonjs = require('@rollup/plugin-commonjs');
const alias = require('@rollup/plugin-alias');
const { terser } = require('rollup-plugin-terser');
const babel = require("@rollup/plugin-babel");
const babel = require('@rollup/plugin-babel');
const aliases = {};
const generateRollupConfig = (inputFile, outputFile) => {
return {
inputOptions: {
onwarn: (warning, rollupWarn) => {
if (warning.code !== 'CIRCULAR_DEPENDENCY') {
rollupWarn(warning)
}
},
input: inputFile,
plugins: [
alias({
entries: Object.keys(aliases).map((find) => {
return {
find,
replacement: aliases[find],
};
}),
}),
nodeResolve({
preferBuiltins: false,
mainFields: ['module', 'browser']
}),
replace({
preventAssignment: true,
"process.env.NODE_ENV": JSON.stringify("production"),
}),
commonjs(),
globals(),
progress(),
babel.babel({
babelHelpers: 'bundled',
exclude: "node_modules/**",
}),
terser({
compress: true,
output: {
comments: false,
},
})
],
},
outputOptions: {
file: outputFile,
format: "umd",
},
};
return {
inputOptions: {
onwarn: (warning, rollupWarn) => {
if (warning.code !== 'CIRCULAR_DEPENDENCY') {
rollupWarn(warning);
}
},
input: inputFile,
plugins: [
alias({
entries: Object.keys(aliases).map((find) => {
return {
find,
replacement: aliases[find],
};
}),
}),
nodeResolve({
preferBuiltins: false,
mainFields: ['module', 'browser'],
}),
replace({
preventAssignment: true,
'process.env.NODE_ENV': JSON.stringify('production'),
}),
commonjs(),
globals(),
progress(),
babel.babel({
babelHelpers: 'bundled',
exclude: 'node_modules/**',
}),
terser({
compress: true,
output: {
comments: false,
},
}),
],
},
outputOptions: {
file: outputFile,
format: 'umd',
},
};
};
const generateForPlugins = () => {
const configs = [
{
in: "plugins/core/main.src.js",
out: "plugins/core/main.js",
},
{
in: "plugins/core/trade-portal/trade-portal.src.js",
out: "plugins/core/trade-portal/trade-portal.js",
},
{
in: "plugins/core/wallet/wallet-app.src.js",
out: "plugins/core/wallet/wallet-app.js",
},
{
in: "plugins/core/reward-share/reward-share.src.js",
out: "plugins/core/reward-share/reward-share.js",
},
{
in: "plugins/core/node-management/node-management.src.js",
out: "plugins/core/node-management/node-management.js",
},
{
in: "plugins/core/group-management/group-management.src.js",
out: "plugins/core/group-management/group-management.js",
},
{
in: "plugins/core/name-registration/name-registration.src.js",
out: "plugins/core/name-registration/name-registration.js",
},
{
in: "plugins/core/qdn/websites.src.js",
out: "plugins/core/qdn/websites.js",
},
{
in: "plugins/core/qdn/publish/publish.src.js",
out: "plugins/core/qdn/publish/publish.js",
},
{
in: "plugins/core/qdn/browser/browser.src.js",
out: "plugins/core/qdn/browser/browser.js",
},
{
in: "plugins/core/qdn/data-management/data-management.src.js",
out: "plugins/core/qdn/data-management/data-management.js",
},
{
in: "plugins/core/messaging/messaging.src.js",
out: "plugins/core/messaging/messaging.js",
},
{
in: "plugins/core/messaging/chain-messaging/chain-messaging.src.js",
out: "plugins/core/messaging/chain-messaging/chain-messaging.js",
},
{
in: "plugins/core/messaging/q-chat/q-chat.src.js",
out: "plugins/core/messaging/q-chat/q-chat.js",
},
{
in: "plugins/core/minting/minting-info.src.js",
out: "plugins/core/minting/minting-info.js",
},
{
in: "plugins/core/puzzles/puzzles.src.js",
out: "plugins/core/puzzles/puzzles.js",
}
].map((file) => {
return generateRollupConfig(
path.join(__dirname, file.in),
path.join(__dirname, file.out)
);
});
return configs;
const configs = [
{
in: 'plugins/core/main.src.js',
out: 'plugins/core/main.js',
},
{
in: 'plugins/core/trade-portal/trade-portal.src.js',
out: 'plugins/core/trade-portal/trade-portal.js',
},
{
in: 'plugins/core/wallet/wallet-app.src.js',
out: 'plugins/core/wallet/wallet-app.js',
},
{
in: 'plugins/core/reward-share/reward-share.src.js',
out: 'plugins/core/reward-share/reward-share.js',
},
{
in: 'plugins/core/node-management/node-management.src.js',
out: 'plugins/core/node-management/node-management.js',
},
{
in: 'plugins/core/group-management/group-management.src.js',
out: 'plugins/core/group-management/group-management.js',
},
{
in: 'plugins/core/name-registration/name-registration.src.js',
out: 'plugins/core/name-registration/name-registration.js',
},
{
in: 'plugins/core/qdn/websites.src.js',
out: 'plugins/core/qdn/websites.js',
},
{
in: 'plugins/core/qdn/publish/publish.src.js',
out: 'plugins/core/qdn/publish/publish.js',
},
{
in: 'plugins/core/qdn/browser/browser.src.js',
out: 'plugins/core/qdn/browser/browser.js',
},
{
in: 'plugins/core/qdn/data-management/data-management.src.js',
out: 'plugins/core/qdn/data-management/data-management.js',
},
{
in: 'plugins/core/messaging/messaging.src.js',
out: 'plugins/core/messaging/messaging.js',
},
{
in: 'plugins/core/messaging/chain-messaging/chain-messaging.src.js',
out: 'plugins/core/messaging/chain-messaging/chain-messaging.js',
},
{
in: 'plugins/core/messaging/q-chat/q-chat.src.js',
out: 'plugins/core/messaging/q-chat/q-chat.js',
},
{
in: 'plugins/core/minting/minting-info.src.js',
out: 'plugins/core/minting/minting-info.js',
},
{
in: 'plugins/core/become-minter/become-minter.src.js',
out: 'plugins/core/become-minter/become-minter.js',
},
{
in: 'plugins/core/puzzles/puzzles.src.js',
out: 'plugins/core/puzzles/puzzles.js',
},
].map((file) => {
return generateRollupConfig(
path.join(__dirname, file.in),
path.join(__dirname, file.out)
);
});
return configs;
};
module.exports = generateForPlugins;

View File

@ -0,0 +1,229 @@
import { css } from 'lit';
export const pageStyles = css`
* {
--mdc-theme-surface: var(--white);
--mdc-dialog-content-ink-color: var(--black);
}
.header-title {
font-size: 40px;
color: var(--black);
font-weight: 400;
text-align: center;
}
.divider {
color: #eee;
border-radius: 80%;
margin-bottom: 2rem;
}
.fullWidth {
width: 100%;
}
.page-container {
display: flex;
align-items: center;
flex-direction: column;
margin-bottom: 75px;
width: 100%;
}
.inner-container {
display: flex;
align-items: center;
flex-direction: column;
width: 100%;
}
.description {
color: var(--black);
}
.message {
color: var(--gray);
}
.sub-main {
width: 95%;
display: flex;
flex-direction: column;
max-width: 800px;
}
.level-black {
font-size: 32px;
color: var(--black);
font-weight: 400;
text-align: center;
margin-top: 2rem;
}
.form-wrapper {
display: flex;
align-items: center;
width: 100%;
height: 50px;
}
.row {
display: flex;
width: 100%;
}
.column {
display: flex;
flex-direction: column;
width: 100%;
}
.column-center {
align-items: center;
}
.no-margin {
margin: 0;
}
.no-wrap {
flex-wrap: nowrap !important;
}
.row-center {
justify-content: center;
flex-wrap: wrap;
}
.form-item {
display: flex;
height: 100%;
}
.form-item--button {
flex-grow: 0;
}
.form-item--input {
flex-grow: 1;
margin-right: 25px;
}
.center-box {
position: absolute;
width: 100%;
top: 50%;
left: 50%;
transform: translate(-50%, 0%);
text-align: center;
}
.content-box {
border: 1px solid var(--border);
border-radius: 10px;
padding: 10px 25px;
text-align: center;
display: inline-block;
margin-bottom: 5px;
flex-basis: 250px;
}
.gap {
gap: 10px;
}
.level-black {
font-size: 32px;
color: var(--black);
font-weight: 400;
text-align: center;
margin-top: 2rem;
text-align: center;
}
.title {
font-weight: 600;
font-size: 20px;
line-height: 28px;
opacity: 0.66;
color: var(--switchborder);
}
.address {
overflow-wrap: anywhere;
color: var(--black);
}
h4 {
font-weight: 600;
font-size: 20px;
line-height: 28px;
color: var(--black);
}
mwc-textfield {
width: 100%;
}
vaadin-button {
height: 100%;
margin: 0;
cursor: pointer;
outline: 1px var(--black) solid;
min-width: 80px;
}
.loader,
.loader:after {
border-radius: 50%;
width: 10em;
height: 10em;
}
.loadingContainer {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 10;
}
.backdrop {
height: 100vh;
width: 100vw;
opacity: 0.6;
background-color: var(--border);
z-index: 9;
position: fixed;
}
.loading,
.loading:after {
border-radius: 50%;
width: 5em;
height: 5em;
}
.loading {
margin: 10px auto;
border-width: 0.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;
}
@-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);
}
}
`;

View File

@ -0,0 +1,200 @@
import { LitElement, html } from 'lit';
import { Epml } from '../../../epml.js';
import '../components/ButtonIconCopy.js';
import { use, translate, registerTranslateConfig } from 'lit-translate';
import { blocksNeed } from './utils/blocks-needed.js';
registerTranslateConfig({
loader: (lang) => fetch(`/language/${lang}.json`).then((res) => res.json()),
});
import '@polymer/paper-spinner/paper-spinner-lite.js';
import '@material/mwc-button';
import '@material/mwc-textfield';
import '@vaadin/button';
import { pageStyles } from './become-minter-css.src.js';
import './components/not-sponsored.src';
import './components/yes-sponsored.src';
const parentEpml = new Epml({ type: 'WINDOW', source: window.parent });
class BecomeMinter extends LitElement {
static get properties() {
return {
theme: { type: String, reflect: true },
sponsorshipKeyValue: { type: String },
nodeInfo: { type: Object },
isPageLoading: { type: Boolean },
addressInfo: { type: Object },
rewardSharePublicKey: { type: String },
mintingAccountData: { type: Array },
};
}
static styles = [pageStyles];
constructor() {
super();
this.theme = localStorage.getItem('qortalTheme')
? localStorage.getItem('qortalTheme')
: 'light';
this.sponsorshipKeyValue = '';
this.isPageLoading = true;
this.nodeInfo = {};
this.addressInfo = {};
this.rewardSharePublicKey = '';
this.mintingAccountData = null;
}
changeLanguage() {
const checkLanguage = localStorage.getItem('qortalLanguage');
if (checkLanguage === null || checkLanguage.length === 0) {
localStorage.setItem('qortalLanguage', 'us');
use('us');
} else {
use(checkLanguage);
}
}
_handleStorage() {
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);
}
connectedCallback() {
super.connectedCallback();
window.addEventListener('storage', this._handleStorage);
}
disconnectedCallback() {
window.removeEventListener('storage', this._handleStorage);
super.disconnectedCallback();
}
async getNodeInfo() {
const nodeInfo = await parentEpml.request('apiCall', {
url: `/admin/status`,
});
return nodeInfo;
}
async getMintingAcccounts() {
const mintingAccountData = await parentEpml.request('apiCall', {
url: `/admin/mintingaccounts`,
});
return mintingAccountData;
}
async atMount() {
this.changeLanguage();
this.addressInfo =
window.parent.reduxStore.getState().app.accountInfo.addressInfo;
this.isPageLoading = true;
try {
const [nodeInfo, myRewardShareArray, mintingaccounts] =
await Promise.all([
this.getNodeInfo(),
this.getRewardShareRelationship(
window.parent.reduxStore.getState().app?.selectedAddress
?.address
),
this.getMintingAcccounts(),
]);
this.nodeInfo = nodeInfo;
this.rewardSharePublicKey =
myRewardShareArray[0]?.rewardSharePublicKey;
this.isPageLoading = false;
this.mintingAccountData = mintingaccounts;
} catch (error) {
console.error(error);
this.isPageLoading = false;
}
}
async firstUpdated() {
await this.atMount();
}
async getRewardShareRelationship(recipientAddress) {
const myRewardShareArray = await parentEpml.request('apiCall', {
type: 'api',
url: `/addresses/rewardshares?recipients=${recipientAddress}`,
});
return myRewardShareArray;
}
_levelUpBlocks() {
let countBlocksString = (
blocksNeed(0) -
(this.addressInfo?.blocksMinted +
this.addressInfo?.blocksMintedAdjustment)
).toString();
return countBlocksString;
}
render() {
console.log({ mintingAccountData: this.mintingAccountData });
const findMintingAccount = this.mintingAccountData?.find(
(ma) => !!ma.publicKey
);
const isAlreadySponsored =
this.addressInfo?.error !== 124 &&
this.addressInfo?.level === 0 &&
findMintingAccount;
return html`
${this.isPageLoading
? html`
<div class="loadingContainer">
<div class="loading"></div>
</div>
<div class="backdrop"></div>
`
: ''}
<div class="page-container">
<h1 class="header-title">
${translate('becomeMinterPage.bchange1')}
</h1>
<div class="fullWidth">
<hr class="divider" />
</div>
${isAlreadySponsored
? ''
: html`
<not-sponsored
.atMount="${() => this.atMount()}"
></not-sponsored>
`}
${!isAlreadySponsored
? ''
: html`
<yes-sponsored
.rewardSharePublicKey=${this
.rewardSharePublicKey}
.addressInfo=${this.addressInfo}
></yes-sponsored>
`}
</div>
`;
}
}
window.customElements.define('become-minter', BecomeMinter);

View File

@ -0,0 +1,140 @@
import { LitElement, html } from 'lit';
import { Epml } from '../../../../epml.js';
import '../../components/ButtonIconCopy.js';
import { use, translate, registerTranslateConfig } from 'lit-translate';
registerTranslateConfig({
loader: (lang) => fetch(`/language/${lang}.json`).then((res) => res.json()),
});
import '@polymer/paper-spinner/paper-spinner-lite.js';
import '@material/mwc-button';
import '@material/mwc-textfield';
import '@vaadin/button';
import { pageStyles } from '../become-minter-css.src.js';
const parentEpml = new Epml({ type: 'WINDOW', source: window.parent });
// hello
class NotSponsored extends LitElement {
static properties = {
atMount: { type: Function },
isLoadingSponsorshipKeySubmit: { type: Boolean },
sponsorshipKeyValue: { type: String },
addMintingAccountMessage: { type: String },
};
static styles = [pageStyles];
constructor() {
super();
this.isLoadingSponsorshipKeySubmit = false;
this.sponsorshipKeyValue = '';
this.addMintingAccountMessage = '';
this.atMount = () => {};
}
renderErr1Text() {
return html`${translate('nodepage.nchange27')}`;
}
renderErr2Text() {
return html`${translate('nodepage.nchange28')}`;
}
getApiKey() {
const myNode =
window.parent.reduxStore.getState().app.nodeConfig.knownNodes[
window.parent.reduxStore.getState().app.nodeConfig.node
];
let apiKey = myNode.apiKey;
return apiKey;
}
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;
}
render() {
return html`
<div class="inner-container">
<div class="sub-main">
<h2 class="level-black">
${translate('becomeMinterPage.bchange2')}
</h2>
<p class="description">
${translate('becomeMinterPage.bchange3')}
</p>
<h2 class="level-black">
${translate('becomeMinterPage.bchange4')}
</h2>
<p class="description">
${translate('becomeMinterPage.bchange5')}
</p>
<p class="description">
${translate('becomeMinterPage.bchange6')}
</p>
<p class="message">${this.addMintingAccountMessage}</p>
<div class="form-wrapper">
<div class="form-item form-item--input">
<mwc-textfield
?disabled="${this
.isLoadingSponsorshipKeySubmit}"
label="${translate(
'becomeMinterPage.bchange8'
)}"
id="addSponsorshipKey"
@input="${this.inputHandler}"
.value="${this.sponsorshipKeyValue || ''}"
fullWidth
>
</mwc-textfield>
</div>
<div class="form-item form-item--button">
<vaadin-button
?disabled="${this
.isLoadingSponsorshipKeySubmit}"
@click="${this.addMintingAccount}"
>
${this.isLoadingSponsorshipKeySubmit === false
? html`${translate(
'becomeMinterPage.bchange9'
)}`
: html`<paper-spinner-lite
active
></paper-spinner-lite>`}
</vaadin-button>
</div>
</div>
</div>
</div>
`;
}
}
window.customElements.define('not-sponsored', NotSponsored);

View File

@ -0,0 +1,123 @@
import { LitElement, html } from 'lit';
import { Epml } from '../../../../epml.js';
import '../../components/ButtonIconCopy.js';
import { use, translate, registerTranslateConfig } from 'lit-translate';
registerTranslateConfig({
loader: (lang) => fetch(`/language/${lang}.json`).then((res) => res.json()),
});
import '@polymer/paper-spinner/paper-spinner-lite.js';
import '@material/mwc-button';
import '@material/mwc-textfield';
import '@vaadin/button';
import { blocksNeed } from '../utils/blocks-needed.js';
import { pageStyles } from '../become-minter-css.src.js';
class YesSponsored extends LitElement {
static get properties() {
return {
addressInfo: { type: Object },
rewardSharePublicKey: { type: String },
};
}
constructor() {
super();
this.addressInfo = {};
this.rewardSharePublicKey = '';
}
static styles = [pageStyles];
_levelUpBlocks() {
let countBlocksString = (
blocksNeed(0) -
(this.addressInfo?.blocksMinted +
this.addressInfo?.blocksMintedAdjustment)
).toString();
return countBlocksString;
}
render() {
return html`
<div class="inner-container">
<div class="column column-center">
<div class="column column-center">
<span class="level-black"
>${translate('becomeMinterPage.bchange10')}</span
>
<hr
style="width: 50%; color: #eee; border-radius: 80%; margin-bottom: 2rem;"
/>
</div>
<br />
<div class="row row-center gap">
<div class="content-box">
<span class="title"
>${translate(
'becomeMinterPage.bchange11'
)}</span
>
<hr
style="color: #eee; border-radius: 90%; margin-bottom: 1rem;"
/>
<h4>${translate('becomeMinterPage.bchange12')}</h4>
</div>
<div class="content-box">
<span class="title"
>${translate(
'becomeMinterPage.bchange13'
)}</span
>
<hr
style="color: #eee; border-radius: 90%; margin-bottom: 1rem;"
/>
<h4>
${this._levelUpBlocks()}
${translate('becomeMinterPage.bchange14')}
</h4>
</div>
<div class="content-box">
<span class="title"
>${translate(
'becomeMinterPage.bchange15'
)}</span
>
<hr
style="color: #eee; border-radius: 90%; margin-bottom: 1rem;"
/>
<h4 class="no-margin">
${translate('becomeMinterPage.bchange16')}
</h4>
<div class="row row-center column-center no-wrap">
<p class="address">
${this.rewardSharePublicKey}
</p>
<button-icon-copy
title="${translate('walletpage.wchange3')}"
onSuccessMessage="${translate(
'walletpage.wchange4'
)}"
onErrorMessage="${translate(
'walletpage.wchange39'
)}"
textToCopy=${this.rewardSharePublicKey}
buttonSize="28px"
iconSize="16px"
color="var(--copybutton)"
offsetLeft="4px"
>
</button-icon-copy>
</div>
</div>
</div>
<br />
</div>
</div>
`;
}
}
window.customElements.define('yes-sponsored', YesSponsored);

View File

@ -0,0 +1,53 @@
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="/font/material-icons.css" />
<link rel="stylesheet" href="/font/switch-theme.css" />
<script>
const checkBack = localStorage.getItem('qortalTheme');
if (checkBack === 'dark') {
newtheme = 'dark';
} else {
newtheme = 'light';
}
document.querySelector('html').setAttribute('theme', newtheme);
</script>
<style>
html {
--scrollbarBG: #a1a1a1;
--thumbBG: #6a6c75;
}
*::-webkit-scrollbar {
width: 11px;
}
* {
scrollbar-width: thin;
scrollbar-color: var(--thumbBG) var(--scrollbarBG);
}
*::-webkit-scrollbar-track {
background: var(--scrollbarBG);
}
*::-webkit-scrollbar-thumb {
background-color: var(--thumbBG);
border-radius: 6px;
border: 3px solid var(--scrollbarBG);
}
html,
body {
margin: 0;
font-family: 'Roboto', sans-serif;
background: var(--plugback);
}
</style>
</head>
<body>
<become-minter></become-minter>
<script src="become-minter.js"></script>
</body>
</html>

View File

@ -1,132 +1,143 @@
import { parentEpml } from './connect.js'
import './streams/streams.js'
let config = {}
let haveRegisteredNodeManagement = false
import { parentEpml } from './connect.js';
import './streams/streams.js';
let config = {};
let haveRegisteredNodeManagement = false;
parentEpml.ready().then(() => {
// pluginUrlsConf
let pluginUrlsConf = [
{
url: 'minting',
domain: 'core',
page: 'minting/index.html',
title: 'Minting Details',
icon: 'vaadin:info-circle',
menus: [],
parent: false
},
{
url: 'wallet',
domain: 'core',
page: 'wallet/index.html',
title: 'Wallet',
icon: 'vaadin:wallet',
menus: [],
parent: false
},
{
url: 'trade-portal',
domain: 'core',
page: 'trade-portal/index.html',
title: 'Trade Portal',
icon: 'vaadin:bullets',
menus: [],
parent: false
},
{
url: 'reward-share',
domain: 'core',
page: 'reward-share/index.html',
title: 'Reward Share',
icon: 'vaadin:share-square',
menus: [],
parent: false
},
{
url: 'name-registration',
domain: 'core',
page: 'name-registration/index.html',
title: 'Name Registration',
icon: 'vaadin:user-check',
menus: [],
parent: false
},
{
url: 'websites',
domain: 'core',
page: 'qdn/index.html',
title: 'Websites',
icon: 'vaadin:desktop',
menus: [],
parent: false
},
{
url: 'data-management',
domain: 'core',
page: 'qdn/data-management/index.html',
title: 'Data Management',
icon: 'vaadin:database',
menus: [],
parent: false
},
{
url: 'q-chat',
domain: 'core',
page: 'messaging/q-chat/index.html',
title: 'Q-Chat',
icon: 'vaadin:chat',
menus: [],
parent: false
},
{
url: 'group-management',
domain: 'core',
page: 'group-management/index.html',
title: 'Group Management',
icon: 'vaadin:group',
menus: [],
parent: false
},
{
url: 'puzzles',
domain: 'core',
page: 'puzzles/index.html',
title: 'Puzzles',
icon: 'vaadin:puzzle-piece',
menus: [],
parent: false
}
]
// pluginUrlsConf
let pluginUrlsConf = [
{
url: 'minting',
domain: 'core',
page: 'minting/index.html',
title: 'Minting Details',
icon: 'vaadin:info-circle',
menus: [],
parent: false,
},
{
url: 'become-minter',
domain: 'core',
page: 'become-minter/index.html',
title: 'Become a Minter',
icon: 'vaadin:info-circle',
menus: [],
parent: false,
},
{
url: 'wallet',
domain: 'core',
page: 'wallet/index.html',
title: 'Wallet',
icon: 'vaadin:wallet',
menus: [],
parent: false,
},
{
url: 'trade-portal',
domain: 'core',
page: 'trade-portal/index.html',
title: 'Trade Portal',
icon: 'vaadin:bullets',
menus: [],
parent: false,
},
{
url: 'reward-share',
domain: 'core',
page: 'reward-share/index.html',
title: 'Reward Share',
icon: 'vaadin:share-square',
menus: [],
parent: false,
},
{
url: 'name-registration',
domain: 'core',
page: 'name-registration/index.html',
title: 'Name Registration',
icon: 'vaadin:user-check',
menus: [],
parent: false,
},
{
url: 'websites',
domain: 'core',
page: 'qdn/index.html',
title: 'Websites',
icon: 'vaadin:desktop',
menus: [],
parent: false,
},
{
url: 'data-management',
domain: 'core',
page: 'qdn/data-management/index.html',
title: 'Data Management',
icon: 'vaadin:database',
menus: [],
parent: false,
},
{
url: 'q-chat',
domain: 'core',
page: 'messaging/q-chat/index.html',
title: 'Q-Chat',
icon: 'vaadin:chat',
menus: [],
parent: false,
},
{
url: 'group-management',
domain: 'core',
page: 'group-management/index.html',
title: 'Group Management',
icon: 'vaadin:group',
menus: [],
parent: false,
},
{
url: 'puzzles',
domain: 'core',
page: 'puzzles/index.html',
title: 'Puzzles',
icon: 'vaadin:puzzle-piece',
menus: [],
parent: false,
},
];
const registerPlugins = (pluginInfo) => {
parentEpml.request('registerUrl', pluginInfo)
}
const registerPlugins = (pluginInfo) => {
parentEpml.request('registerUrl', pluginInfo);
};
const checkNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]
const checkNode =
window.parent.reduxStore.getState().app.nodeConfig.knownNodes[
window.parent.reduxStore.getState().app.nodeConfig.node
];
parentEpml.subscribe('config', c => {
config = JSON.parse(c)
parentEpml.subscribe('config', (c) => {
config = JSON.parse(c);
// Only register node management if node management is enabled and it hasn't already been registered
if (!haveRegisteredNodeManagement && checkNode.enableManagement) {
haveRegisteredNodeManagement = true
// Only register node management if node management is enabled and it hasn't already been registered
if (!haveRegisteredNodeManagement && checkNode.enableManagement) {
haveRegisteredNodeManagement = true;
let nodeManagementConf = {
url: 'node-management',
domain: 'core',
page: 'node-management/index.html',
title: 'Node Management',
icon: 'vaadin:cloud',
menus: [],
parent: false
}
let nodeManagementConf = {
url: 'node-management',
domain: 'core',
page: 'node-management/index.html',
title: 'Node Management',
icon: 'vaadin:cloud',
menus: [],
parent: false,
};
let _pluginUrlsConf = [...pluginUrlsConf, nodeManagementConf]
registerPlugins(_pluginUrlsConf)
} else {
registerPlugins(pluginUrlsConf)
}
})
})
let _pluginUrlsConf = [...pluginUrlsConf, nodeManagementConf];
registerPlugins(_pluginUrlsConf);
} else {
registerPlugins(pluginUrlsConf);
}
});
});