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

View File

@ -22,6 +22,7 @@
},
"sidemenu": {
"mintingdetails": "MINTING DETAILS",
"becomeAMinter": "BECOME A MINTER",
"wallets": "WALLETS",
"tradeportal": "TRADE PORTAL",
"rewardshare": "REWARD SHARE",
@ -175,6 +176,27 @@
"mchange37": "Simply reach out to a minter in Qortal who is high enough level to issue a sponsorship key, obtain that key, then come back here and input the key to begin your minting journey !",
"mchange38": "in"
},
"becomeMinterPage": {
"bchange1": "Become A Minter",
"bchange2": "Introduction",
"bchange3": "In Qortal, in order to become a minter and begin earning QORT rewards with your increase in Minter Level, you must first become 'sponsored'. A sponsor in Qortal is any other minter of level 5 or higher, or a Qortal Founder. You will obtain a sponsorship key from the sponsor, and use that key to get to level 1. Once you have reached level 1, you will be able to create your own minting key and start earning rewards for helping secure the Qortal Blockchain.",
"bchange4": "Sponsorship",
"bchange5": "Your sponsor will issue you a 'Sponsorship Key' which you will use to add to your node, and begin minting (for no rewards until reaching level 1.) Once you reach level 1, you create/assign your own 'Minting Key' and begin earning rewards. You have XXXX blocks remaining in your sponsorship period.",
"bchange6": "Simply reach out to a minter in Qortal who is high enough level to issue a sponsorship key, obtain that key, then come back here and input the key to begin your minting journey!",
"bchange7": "Enter Sponsorship Key",
"bchange8": "Input key from your sponsor here",
"bchange9": "Submit",
"bchange10": "Current Sponsorship Status",
"bchange11": "Status",
"bchange12": "Minting with sponsor key",
"bchange13": "Blocks Remaining in Sponsorship Period",
"bchange14": "blocks",
"bchange15": "Sponsorship Relationship",
"bchange16": "Sponsor Account",
"bchange17": "Copy Sponsorship Key",
"bchange18": "Start Minting",
"bchange19": "Success! You are currently minting."
},
"walletpage": {
"wchange1": "Fetching balance ...",
"wchange2": "Current Wallet",

View File

@ -1,23 +1,25 @@
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 }
}
theme: { type: String, reflect: true },
addressInfo: { type: Object },
};
}
static get styles() {
@ -31,7 +33,9 @@ class SidenavMenu extends connect(store)(LitElement) {
--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);
--item-border-selected-color: var(
--nav-border-selected-color
);
}
.s-menu {
@ -43,117 +47,224 @@ class SidenavMenu extends connect(store)(LitElement) {
border-top: 1px solid var(--border);
outline: none;
}
`
]
.start-minting-wrapper {
position: absolute;
bottom: 130px;
left: 50%;
transform: translateX(calc(-50% - 10px));
}
`,
];
}
constructor() {
super()
this.urls = []
this.nodeType = ''
this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light'
super();
this.urls = [];
this.nodeType = '';
this.theme = localStorage.getItem('qortalTheme')
? localStorage.getItem('qortalTheme')
: 'light';
this.addressInfo = {};
}
render() {
return html`
<div class="s-menu">
<side-menu>
${this.renderNodeTypeMenu()}
${this.renderNodeManagement()}
${this.renderNodeTypeMenu()} ${this.renderNodeManagement()}
</side-menu>
</div>
`
<start-minting></start-minting>
`;
}
firstUpdated() {
this.getNodeType()
this.getNodeType();
}
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`
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((response) => {
return response.json();
})
.then(data => {
this.nodeType = data.type
.then((data) => {
this.nodeType = data.type;
})
.catch(err => {
.catch((err) => {
console.error('Request failed', err);
})
});
}
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>
<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
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
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">
<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>
${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
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
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
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
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
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">
<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">
<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
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) {
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">
<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``
return html``;
}
}
stateChanged(state) {
this.config = state.config
this.urls = state.app.registeredUrls
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)
}
return _array
_array.set([obj[i]], i);
}
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,13 +1,13 @@
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 = {};
@ -16,7 +16,7 @@ const generateRollupConfig = (inputFile, outputFile) => {
inputOptions: {
onwarn: (warning, rollupWarn) => {
if (warning.code !== 'CIRCULAR_DEPENDENCY') {
rollupWarn(warning)
rollupWarn(warning);
}
},
input: inputFile,
@ -31,30 +31,30 @@ const generateRollupConfig = (inputFile, outputFile) => {
}),
nodeResolve({
preferBuiltins: false,
mainFields: ['module', 'browser']
mainFields: ['module', 'browser'],
}),
replace({
preventAssignment: true,
"process.env.NODE_ENV": JSON.stringify("production"),
'process.env.NODE_ENV': JSON.stringify('production'),
}),
commonjs(),
globals(),
progress(),
babel.babel({
babelHelpers: 'bundled',
exclude: "node_modules/**",
exclude: 'node_modules/**',
}),
terser({
compress: true,
output: {
comments: false,
},
})
}),
],
},
outputOptions: {
file: outputFile,
format: "umd",
format: 'umd',
},
};
};
@ -62,69 +62,73 @@ const generateRollupConfig = (inputFile, outputFile) => {
const generateForPlugins = () => {
const configs = [
{
in: "plugins/core/main.src.js",
out: "plugins/core/main.js",
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/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/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/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/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/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/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/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/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/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/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/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/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/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/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",
}
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),

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,9 +1,8 @@
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
@ -15,7 +14,16 @@ parentEpml.ready().then(() => {
title: 'Minting Details',
icon: 'vaadin:info-circle',
menus: [],
parent: false
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',
@ -24,7 +32,7 @@ parentEpml.ready().then(() => {
title: 'Wallet',
icon: 'vaadin:wallet',
menus: [],
parent: false
parent: false,
},
{
url: 'trade-portal',
@ -33,7 +41,7 @@ parentEpml.ready().then(() => {
title: 'Trade Portal',
icon: 'vaadin:bullets',
menus: [],
parent: false
parent: false,
},
{
url: 'reward-share',
@ -42,7 +50,7 @@ parentEpml.ready().then(() => {
title: 'Reward Share',
icon: 'vaadin:share-square',
menus: [],
parent: false
parent: false,
},
{
url: 'name-registration',
@ -51,7 +59,7 @@ parentEpml.ready().then(() => {
title: 'Name Registration',
icon: 'vaadin:user-check',
menus: [],
parent: false
parent: false,
},
{
url: 'websites',
@ -60,7 +68,7 @@ parentEpml.ready().then(() => {
title: 'Websites',
icon: 'vaadin:desktop',
menus: [],
parent: false
parent: false,
},
{
url: 'data-management',
@ -69,7 +77,7 @@ parentEpml.ready().then(() => {
title: 'Data Management',
icon: 'vaadin:database',
menus: [],
parent: false
parent: false,
},
{
url: 'q-chat',
@ -78,7 +86,7 @@ parentEpml.ready().then(() => {
title: 'Q-Chat',
icon: 'vaadin:chat',
menus: [],
parent: false
parent: false,
},
{
url: 'group-management',
@ -87,7 +95,7 @@ parentEpml.ready().then(() => {
title: 'Group Management',
icon: 'vaadin:group',
menus: [],
parent: false
parent: false,
},
{
url: 'puzzles',
@ -96,22 +104,25 @@ parentEpml.ready().then(() => {
title: 'Puzzles',
icon: 'vaadin:puzzle-piece',
menus: [],
parent: false
}
]
parent: false,
},
];
const registerPlugins = (pluginInfo) => {
parentEpml.request('registerUrl', 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
haveRegisteredNodeManagement = true;
let nodeManagementConf = {
url: 'node-management',
@ -120,13 +131,13 @@ parentEpml.ready().then(() => {
title: 'Node Management',
icon: 'vaadin:cloud',
menus: [],
parent: false
}
parent: false,
};
let _pluginUrlsConf = [...pluginUrlsConf, nodeManagementConf]
registerPlugins(_pluginUrlsConf)
let _pluginUrlsConf = [...pluginUrlsConf, nodeManagementConf];
registerPlugins(_pluginUrlsConf);
} else {
registerPlugins(pluginUrlsConf)
registerPlugins(pluginUrlsConf);
}
})
})
});
});