@@ -321,8 +322,8 @@ class WebBrowser extends LitElement {
console.log('UI received event: ' + JSON.stringify(data));
switch (data.action) {
- case 'GET_USER_ACCOUNT':
- case actions.GET_USER_ACCOUNT:
+ case 'GET_USER_ACCOUNT':
+ case actions.GET_USER_ACCOUNT:
const res1 = await showModalAndWait(
actions.GET_USER_ACCOUNT
);
@@ -418,12 +419,159 @@ class WebBrowser extends LitElement {
// If they decline, send back JSON that includes an `error` key, such as `{"error": "User declined request"}`
break;
- case 'SEND_CHAT_MESSAGE':
+ case 'SEND_CHAT_MESSAGE': {
+ const message = data.message;
+ const recipient = data.destinationAddress;
+ const sendMessage = async (messageText, chatReference) => {
+ this.loader.show();
+ let _reference = new Uint8Array(64);
+ window.crypto.getRandomValues(_reference);
+ let reference = window.parent.Base58.encode(_reference);
+ const sendMessageRequest = async () => {
+ let chatResponse = await parentEpml.request('chat', {
+ type: 18,
+ nonce: this.selectedAddress.nonce,
+ params: {
+ timestamp: Date.now(),
+ recipient: recipient,
+ recipientPublicKey: this._publicKey.key,
+ hasChatReference: 0,
+ chatReference: chatReference,
+ message: messageText,
+ lastReference: reference,
+ proofOfWorkNonce: 0,
+ isEncrypted: 1,
+ isText: 1
+ }
+ });
+ const msgResponse = await _computePow(chatResponse)
+ return msgResponse;
+ };
+
+ const _computePow = async (chatBytes) => {
+ const difficulty = 8;
+ const path = window.parent.location.origin + '/memory-pow/memory-pow.wasm.full'
+ const worker = new WebWorkerChat();
+ let nonce = null;
+ let chatBytesArray = null;
+
+ await new Promise((res) => {
+ worker.postMessage({chatBytes, path, difficulty});
+ worker.onmessage = e => {
+ chatBytesArray = e.data.chatBytesArray;
+ nonce = e.data.nonce;
+ res();
+ }
+ });
+
+ let _response = await parentEpml.request('sign_chat', {
+ nonce: this.selectedAddress.nonce,
+ chatBytesArray: chatBytesArray,
+ chatNonce: nonce
+ });
+
+ const chatResponse = getSendChatResponse(_response);
+ return chatResponse;
+ };
+
+ const getSendChatResponse = (res) => {
+ if (res === true) {
+ let successString = get("browserpage.bchange23");
+ parentEpml.request('showSnackBar', `${successString}`);
+ } else if (res.error) {
+ parentEpml.request('showSnackBar', res.message);
+ }
+ this.loader.hide();
+ return res;
+ };
+
+ const chatResponse = await sendMessageRequest();
+ return chatResponse;
+ }
+
+ const result = await showModalAndWait(
+ actions.SEND_CHAT_MESSAGE
+ );
+ if (result.action === "accept") {
+ let hasPublicKey = true;
+ const res = await parentEpml.request('apiCall', {
+ type: 'api',
+ url: `/addresses/publickey/${recipient}`
+ });
+
+ if (res.error === 102) {
+ this._publicKey.key = ''
+ this._publicKey.hasPubKey = false
+ hasPublicKey = false;
+ } else if (res !== false) {
+ this._publicKey.key = res
+ this._publicKey.hasPubKey = true
+ } else {
+ this._publicKey.key = ''
+ this._publicKey.hasPubKey = false
+ hasPublicKey = false;
+ }
+
+ if (!hasPublicKey) {
+ let err4string = get("chatpage.cchange39");
+ parentEpml.request('showSnackBar', `${err4string}`)
+ return
+ }
+
+ this.loader.show();
+
+ const tiptapJson = {
+ type: 'doc',
+ content: [
+ {
+ type: 'paragraph',
+ content: [
+ {
+ type: 'text',
+ text: message,
+ },
+
+ ],
+ },
+ ],
+ }
+
+ const messageObject = {
+ messageText: tiptapJson,
+ images: [''],
+ repliedTo: '',
+ version: 2
+ };
+
+ const stringifyMessageObject = JSON.stringify(messageObject);
+ // if (this.balance < 4) {
+ // this.myTrimmedMeassage = ''
+ // this.myTrimmedMeassage = stringifyMessageObject
+ // this.shadowRoot.getElementById('confirmDialog').open()
+ // } else {
+ // this.sendMessage(stringifyMessageObject, typeMessage);
+ // }
+ try {
+ const msgResponse = await sendMessage(stringifyMessageObject);
+ response = msgResponse;
+ } catch (error) {
+ console.error(error);
+ return '{"error": "Request could not be fulfilled"}';
+ } finally {
+ this.loader.hide();
+ console.log("Case completed.");
+ }
+
+ } else {
+ response = '{"error": "User declined request"}';
+ }
+ // this.loader.show();
// Params: data.groupId, data.destinationAddress, data.message
// TODO: prompt user to send chat message. If they confirm, sign+process a CHAT transaction
// then set the response string from the core to the `response` variable (defined above)
// If they decline, send back JSON that includes an `error` key, such as `{"error": "User declined request"}`
break;
+ }
case actions.JOIN_GROUP:
const groupId = data.groupId;
@@ -450,8 +598,7 @@ class WebBrowser extends LitElement {
// TODO: prompt user to share wallet balance. If they confirm, call `GET /crosschain/:coin/walletbalance`, or for QORT, call `GET /addresses/balance/:address`
// then set the response string from the core to the `response` variable (defined above)
// If they decline, send back JSON that includes an `error` key, such as `{"error": "User declined request"}`
- console.log({data});
- const res3 = await showModalAndWait(
+ const res3 = await showModalAndWait(
actions.GET_WALLET_BALANCE
);
if (res3.action === 'accept') {
@@ -463,7 +610,6 @@ class WebBrowser extends LitElement {
const QORTBalance = await parentEpml.request('apiCall', {
url: `/addresses/balance/${qortAddress}?apiKey=${this.getApiKey()}`,
})
- console.log({QORTBalance})
return QORTBalance;
} catch (error) {
console.error(error);
@@ -504,19 +650,21 @@ class WebBrowser extends LitElement {
break
}
try {
- this.loader.show()
- await parentEpml.request('apiCall', {
+ this.loader.show();
+ const res = await parentEpml.request('apiCall', {
url: _url,
method: 'POST',
body: _body,
- }).then((res) => {
- if (isNaN(Number(res))) {
- throw new Error(get("browserpage.bchange21"));
- } else {
- console.log((Number(res) / 1e8).toFixed(8), "other wallet balance here");
- return (Number(res) / 1e8).toFixed(8)
- }
})
+ if (isNaN(Number(res))) {
+ const data = {};
+ const errorMsg = error.message || get("browserpage.bchange21");
+ data['error'] = errorMsg;
+ response = JSON.stringify(data);
+ return;
+ } else {
+ response = (Number(res) / 1e8).toFixed(8);
+ }
} catch (error) {
console.error(error);
const data = {};
@@ -534,7 +682,6 @@ class WebBrowser extends LitElement {
break;
case 'SEND_COIN':
- console.log({data});
// Params: data.coin, data.destinationAddress, data.amount, data.fee
// TODO: prompt user to send. If they confirm, call `POST /crosschain/:coin/send`, or for QORT, broadcast a PAYMENT transaction
// then set the response string from the core to the `response` variable (defined above)
@@ -697,12 +844,12 @@ class WebBrowser extends LitElement {
} finally {
console.log("Case completed.");
}
- break;
+ break;
- default:
- console.log('Unhandled message: ' + JSON.stringify(data));
- return;
- }
+ default:
+ console.log('Unhandled message: ' + JSON.stringify(data));
+ return;
+ }
// Parse response
let responseObj;
@@ -712,7 +859,6 @@ class WebBrowser extends LitElement {
// Not all responses will be JSON
responseObj = response;
}
-
// Respond to app
if (responseObj.error != null) {
event.ports[0].postMessage({
@@ -1050,6 +1196,7 @@ async function showModalAndWait(type, data) {
${type === actions.GET_USER_ACCOUNT ? `
${get("browserpage.bchange18")}
` : ''}
${type === actions.PUBLISH_QDN_RESOURCE ? `
${get("browserpage.bchange19")}
` : ''}
${type === actions.GET_WALLET_BALANCE ? `
${get("browserpage.bchange20")}
` : ''}
+ ${type === actions.SEND_CHAT_MESSAGE ? `
${get("browserpage.bchange22")}
` : ''}
+ ${this._groupdialog6}
+ `
+ }
+
+ set atDeployDialog1(atDeployDialog1) {
+ this._atDeployDialog1 = atDeployDialog1
+ }
+ set atDeployDialog2(atDeployDialog2) {
+ this._atDeployDialog2 = atDeployDialog2
+ }
+
+ set fee(fee) {
+ this._fee = fee
+ this._feeBytes = this.constructor.utils.int64ToBytes(this._fee)
+ }
+ set rAmount(rAmount) {
+ this._rAmount = rAmount
+ this._rAmountBytes = this.constructor.utils.int64ToBytes(this._rAmount)
+ }
+
+ set rName(rName) {
+ this._rName = rName
+ this._rNameBytes = this.constructor.utils.stringtoUTF8Array(this._rName.toLocaleLowerCase())
+ this._rNameLength = this.constructor.utils.int32ToBytes(this._rNameBytes.length)
+ }
+
+ set rDescription(rDescription) {
+ this._rDescription = rDescription
+ this._rDescriptionBytes = this.constructor.utils.stringtoUTF8Array(this._rDescription.toLocaleLowerCase())
+ this._rDescriptionLength = this.constructor.utils.int32ToBytes(this._rDescriptionBytes.length)
+ }
+ set atType(atType) {
+ this._atType = atType
+ this._atTypeBytes = this.constructor.utils.stringtoUTF8Array(this._atType)
+ this._atTypeLength = this.constructor.utils.int32ToBytes(this._atTypeBytes.length)
+ }
+ set rTags(rTags) {
+ this._rTags = rTags
+ this._rTagsBytes = this.constructor.utils.stringtoUTF8Array(this._rTags.toLocaleLowerCase())
+ this._rTagsLength = this.constructor.utils.int32ToBytes(this._rTagsBytes.length)
+ }
+ set rCreationBytes(rCreationBytes) {
+ const decode = this.constructor.Base58.decode(rCreationBytes)
+ console.log({decode})
+ this._rCreationBytes = this.constructor.utils.stringtoUTF8Array(decode)
+ this._rCreationBytesLength = this.constructor.utils.int32ToBytes(this._rCreationBytes.length)
+ }
+ set rAssetId(rAssetId) {
+ this._rAssetId = this.constructor.utils.int64ToBytes(rAssetId)
+ }
+
+
+ get params() {
+ const params = super.params
+ params.push(
+ this._rNameLength,
+ this._rNameBytes,
+ this._rDescriptionLength,
+ this._rDescriptionBytes,
+ this._atTypeLength,
+ this._atTypeBytes,
+ this._rTagsLength,
+ this._rTagsBytes,
+ this._rCreationBytesLength,
+ this._rCreationBytes,
+ this._rAmountBytes,
+ this._rAssetId,
+ this._feeBytes
+ )
+ return params
+ }
+}
diff --git a/qortal-ui-crypto/api/transactions/transactions.js b/qortal-ui-crypto/api/transactions/transactions.js
index 9fa87e99..0423d3ae 100644
--- a/qortal-ui-crypto/api/transactions/transactions.js
+++ b/qortal-ui-crypto/api/transactions/transactions.js
@@ -22,6 +22,7 @@ import LeaveGroupTransaction from './groups/LeaveGroupTransaction.js'
import RewardShareTransaction from './reward-share/RewardShareTransaction.js'
import RemoveRewardShareTransaction from './reward-share/RemoveRewardShareTransaction.js'
import TransferPrivsTransaction from './TransferPrivsTransaction.js'
+import DeployAtTransaction from './DeployAtTransaction.js'
export const transactionTypes = {
2: PaymentTransaction,
@@ -30,6 +31,7 @@ export const transactionTypes = {
5: SellNameTransacion,
6: CancelSellNameTransacion,
7: BuyNameTransacion,
+ 16: DeployAtTransaction,
17: MessageTransaction,
18: ChatTransaction,
181: GroupChatTransaction,
diff --git a/qortal-ui-plugins/plugins/core/qdn/browser/browser.src.js b/qortal-ui-plugins/plugins/core/qdn/browser/browser.src.js
index 2f58042b..8266c5db 100644
--- a/qortal-ui-plugins/plugins/core/qdn/browser/browser.src.js
+++ b/qortal-ui-plugins/plugins/core/qdn/browser/browser.src.js
@@ -119,7 +119,7 @@ class WebBrowser extends LitElement {
this.path =
urlParams.get('path') != null
? (urlParams.get('path').startsWith('/') ? '' : '/') +
- urlParams.get('path')
+ urlParams.get('path')
: '';
this.followedNames = [];
this.blockedNames = [];
@@ -166,23 +166,20 @@ class WebBrowser extends LitElement {
const render = () => {
const myNode =
window.parent.reduxStore.getState().app.nodeConfig.knownNodes[
- window.parent.reduxStore.getState().app.nodeConfig.node
+ window.parent.reduxStore.getState().app.nodeConfig.node
];
const nodeUrl =
myNode.protocol + '://' + myNode.domain + ':' + myNode.port;
- this.url = `${nodeUrl}/render/${this.service}/${this.name}${
- this.path != null ? this.path : ''
- }?theme=${this.theme}&identifier=${
- this.identifier != null ? this.identifier : ''
- }`;
+ this.url = `${nodeUrl}/render/${this.service}/${this.name}${this.path != null ? this.path : ''
+ }?theme=${this.theme}&identifier=${this.identifier != null ? this.identifier : ''
+ }`;
};
const authorizeAndRender = () => {
parentEpml
.request('apiCall', {
- url: `/render/authorize/${
- this.name
- }?apiKey=${this.getApiKey()}`,
+ url: `/render/authorize/${this.name
+ }?apiKey=${this.getApiKey()}`,
method: 'POST',
})
.then((res) => {
@@ -231,7 +228,6 @@ class WebBrowser extends LitElement {
}
render() {
- console.log(2, 'browser page here');
return html`
@@ -273,6 +267,142 @@ class WebBrowser extends LitElement {
`;
}
+ async unitJoinFee() {
+ const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]
+ const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port
+ const url = `${nodeUrl}/transactions/unitfee?txType=JOIN_GROUP`
+ const response = await fetch(url)
+ if (!response.ok) {
+ throw new Error('Error when fetching join fee');
+ }
+
+ const data = await response.json()
+ const joinFee = (Number(data) / 1e8).toFixed(8)
+ return joinFee
+ }
+
+ async deployAtFee() {
+ const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]
+ const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port
+ const url = `${nodeUrl}/transactions/unitfee?txType=DEPLOY_AT`
+ const response = await fetch(url)
+ if (!response.ok) {
+ throw new Error('Error when fetching join fee');
+ }
+
+ const data = await response.json()
+ const joinFee = data
+ return joinFee
+ }
+
+ async _joinGroup(groupId, groupName) {
+ const joinFeeInput = await this.unitJoinFee()
+ const getLastRef = async () => {
+ let myRef = await parentEpml.request('apiCall', {
+ type: 'api',
+ url: `/addresses/lastreference/${this.selectedAddress.address}`
+ })
+ return myRef
+ };
+
+ const validateReceiver = async () => {
+ let lastRef = await getLastRef();
+ let myTransaction = await makeTransactionRequest(lastRef)
+ const res = getTxnRequestResponse(myTransaction)
+ return res
+ }
+
+ const makeTransactionRequest = async (lastRef) => {
+ let groupdialog1 = get("transactions.groupdialog1")
+ let groupdialog2 = get("transactions.groupdialog2")
+ let myTxnrequest = await parentEpml.request('transaction', {
+ type: 31,
+ nonce: this.selectedAddress.nonce,
+ params: {
+ fee: joinFeeInput,
+ registrantAddress: this.selectedAddress.address,
+ rGroupName: groupName,
+ rGroupId: groupId,
+ lastReference: lastRef,
+ groupdialog1: groupdialog1,
+ groupdialog2: groupdialog2
+ }
+ })
+ return myTxnrequest
+ }
+
+ const getTxnRequestResponse = (txnResponse) => {
+ if (txnResponse.success === false && txnResponse.message) {
+ throw new Error(txnResponse.message)
+ } else if (txnResponse.success === true && !txnResponse.data.error) {
+ return txnResponse.data
+ } else if (txnResponse.data && txnResponse.data.message) {
+ throw new Error(txnResponse.data.message)
+ } else {
+ throw new Error('Server error. Could not perform action.')
+ }
+ }
+ const groupRes = await validateReceiver()
+ return groupRes
+
+ }
+
+ async _deployAt(name, description, tags, creationBytes, amount, assetId, fee, atType) {
+ const deployAtFee = await this.deployAtFee()
+ const getLastRef = async () => {
+ let myRef = await parentEpml.request('apiCall', {
+ type: 'api',
+ url: `/addresses/lastreference/${this.selectedAddress.address}`
+ })
+ return myRef
+ };
+
+ const validateReceiver = async () => {
+ let lastRef = await getLastRef();
+ let myTransaction = await makeTransactionRequest(lastRef)
+ const res = getTxnRequestResponse(myTransaction)
+ return res
+ }
+
+ const makeTransactionRequest = async (lastRef) => {
+ let groupdialog1 = get("transactions.groupdialog1")
+ let groupdialog2 = get("transactions.groupdialog2")
+ let myTxnrequest = await parentEpml.request('transaction', {
+ type: 16,
+ nonce: this.selectedAddress.nonce,
+ params: {
+ fee: fee || deployAtFee,
+ rName: name,
+ rDescription: description,
+ rTags: tags,
+ rAmount: amount,
+ rAssetId: assetId,
+ rCreationBytes: creationBytes,
+ atType: atType,
+ lastReference: lastRef,
+ atDeployDialog1: groupdialog1,
+ atDeployDialog2: groupdialog2
+ }
+ })
+ return myTxnrequest
+ }
+
+ const getTxnRequestResponse = (txnResponse) => {
+ if (txnResponse.success === false && txnResponse.message) {
+ throw new Error(txnResponse.message)
+ } else if (txnResponse.success === true && !txnResponse.data.error) {
+ return txnResponse.data
+ } else if (txnResponse.data && txnResponse.data.message) {
+ throw new Error(txnResponse.data.message)
+ } else {
+ throw new Error('Server error. Could not perform action.')
+ }
+ }
+ const groupRes = await validateReceiver()
+ return groupRes
+
+ }
+
firstUpdated() {
this.changeTheme();
this.changeLanguage();
@@ -320,9 +450,9 @@ class WebBrowser extends LitElement {
let data = event.data;
console.log('UI received event: ' + JSON.stringify(data));
- switch (data.action) {
- case 'GET_USER_ACCOUNT':
- case actions.GET_USER_ACCOUNT:
+ switch (data.action) {
+ case 'GET_USER_ACCOUNT':
+ case actions.GET_USER_ACCOUNT:
const res1 = await showModalAndWait(
actions.GET_USER_ACCOUNT
);
@@ -338,7 +468,7 @@ class WebBrowser extends LitElement {
const errorMsg = get('browserpage.bchange17');
data['error'] = errorMsg;
response = JSON.stringify(data);
- return;
+ break;
}
case 'LINK_TO_QDN_RESOURCE':
case actions.QDN_RESOURCE_DISPLAYED:
@@ -363,16 +493,29 @@ class WebBrowser extends LitElement {
this.displayUrl = url;
return;
- case actions.PUBLISH_QDN_RESOURCE:
+ case actions.PUBLISH_QDN_RESOURCE: {
+ const requiredFields = ['service', 'name', 'data64'];
+ const missingFields = [];
+
+ requiredFields.forEach((field) => {
+ if (!data[field]) {
+ missingFields.push(field);
+ }
+ });
+
+ if (missingFields.length > 0) {
+ const missingFieldsString = missingFields.join(', ');
+ const errorMsg = `Missing fields: ${missingFieldsString}`
+ let data = {};
+ data['error'] = errorMsg;
+ response = JSON.stringify(data);
+ break
+ }
// Use "default" if user hasn't specified an identifer
const service = data.service;
const name = data.name;
let identifier = data.identifier;
const data64 = data.data64;
-
- if (!service || !name || !data64) {
- return;
- }
if (data.identifier == null) {
identifier = 'default';
}
@@ -394,17 +537,16 @@ class WebBrowser extends LitElement {
worker: worker,
isBase64: true,
});
- let data = {};
- data['data'] = resPublish;
- response = JSON.stringify(data);
+
+ response = JSON.stringify(resPublish);
worker.terminate();
} catch (error) {
worker.terminate();
- const data = {};
+ const obj = {};
const errorMsg = error.message || 'Upload failed';
- data['error'] = errorMsg;
- response = JSON.stringify(data);
- console.error(error);
+ obj['error'] = errorMsg;
+ response = JSON.stringify(obj);
+ console.error(error);
return;
} finally {
this.loader.hide();
@@ -417,6 +559,8 @@ class WebBrowser extends LitElement {
// then set the response string from the core to the `response` variable (defined above)
// If they decline, send back JSON that includes an `error` key, such as `{"error": "User declined request"}`
break;
+ }
+
case 'SEND_CHAT_MESSAGE':
// Params: data.groupId, data.destinationAddress, data.message
@@ -425,11 +569,60 @@ class WebBrowser extends LitElement {
// If they decline, send back JSON that includes an `error` key, such as `{"error": "User declined request"}`
break;
- case actions.JOIN_GROUP:
+ case actions.JOIN_GROUP: {
+ const requiredFields = ['groupId'];
+ const missingFields = [];
+
+ requiredFields.forEach((field) => {
+ if (!data[field]) {
+ missingFields.push(field);
+ }
+ });
+
+ if (missingFields.length > 0) {
+ const missingFieldsString = missingFields.join(', ');
+ const errorMsg = `Missing fields: ${missingFieldsString}`
+ let data = {};
+ data['error'] = errorMsg;
+ response = JSON.stringify(data);
+ break
+ }
const groupId = data.groupId;
- if (!groupId) {
- return;
+
+ let groupInfo = null
+ try {
+ groupInfo = await parentEpml.request("apiCall", {
+ type: "api",
+ url: `/groups/${groupId}`,
+ });
+ } catch (error) {
+ const errorMsg = (error && error.message) || 'Group not found';
+ let obj = {};
+ obj['error'] = errorMsg;
+ response = JSON.stringify(obj);
+ break
+ }
+
+ if (!groupInfo || groupInfo.error) {
+ const errorMsg = (groupInfo && groupInfo.message) || 'Group not found';
+ let obj = {};
+ obj['error'] = errorMsg;
+ response = JSON.stringify(obj);
+ break
+ }
+
+ try {
+ this.loader.show();
+ const resJoinGroup = await this._joinGroup(groupId, groupInfo.groupName)
+ response = JSON.stringify(resJoinGroup);
+ } catch (error) {
+ const obj = {};
+ const errorMsg = error.message || 'Failed to join the group.';
+ obj['error'] = errorMsg;
+ response = JSON.stringify(obj);
+ } finally {
+ this.loader.hide();
}
// Params: data.groupId
@@ -437,99 +630,132 @@ class WebBrowser extends LitElement {
// then set the response string from the core to the `response` variable (defined above)
// If they decline, send back JSON that includes an `error` key, such as `{"error": "User declined request"}`
break;
+ }
- case 'DEPLOY_AT':
+ case 'DEPLOY_AT': {
+ const requiredFields = ['name', 'description', 'tags', 'creationBytes', 'amount', 'assetId', 'type'];
+ const missingFields = [];
+
+ requiredFields.forEach((field) => {
+ if (!data[field]) {
+ missingFields.push(field);
+ }
+ });
+
+ if (missingFields.length > 0) {
+ const missingFieldsString = missingFields.join(', ');
+ const errorMsg = `Missing fields: ${missingFieldsString}`
+ let data = {};
+ data['error'] = errorMsg;
+ response = JSON.stringify(data);
+ break
+ }
+
+
+ try {
+ this.loader.show();
+ const fee = data.fee || undefined
+ const resJoinGroup = await this._deployAt(data.name, data.description, data.tags, data.creationBytes, data.amount, data.assetId, fee, data.type)
+ response = JSON.stringify(resJoinGroup);
+ } catch (error) {
+ const obj = {};
+ const errorMsg = error.message || 'Failed to join the group.';
+ obj['error'] = errorMsg;
+ response = JSON.stringify(obj);
+ } finally {
+ this.loader.hide();
+ }
// Params: data.creationBytes, data.name, data.description, data.type, data.tags, data.amount, data.assetId, data.fee
// TODO: prompt user to deploy an AT. If they confirm, sign+process a DEPLOY_AT transaction
// then set the response string from the core to the `response` variable (defined above)
// If they decline, send back JSON that includes an `error` key, such as `{"error": "User declined request"}`
break;
+ }
+
case 'GET_WALLET_BALANCE':
// Params: data.coin (QORT / LTC / DOGE / DGB / C / ARRR)
// TODO: prompt user to share wallet balance. If they confirm, call `GET /crosschain/:coin/walletbalance`, or for QORT, call `GET /addresses/balance/:address`
// then set the response string from the core to the `response` variable (defined above)
// If they decline, send back JSON that includes an `error` key, such as `{"error": "User declined request"}`
- console.log('case passed here');
- console.log(data.coin, "data coin here");
- const res3 = await showModalAndWait(
+
+ const res3 = await showModalAndWait(
actions.GET_WALLET_BALANCE
);
if (res3.action === 'accept') {
- let coin = data.coin;
- if (coin === "QORT") {
- let qortAddress = window.parent.reduxStore.getState().app.selectedAddress.address
- try {
- this.loader.show();
- const QORTBalance = await parentEpml.request('apiCall', {
- url: `/addresses/balance/${qortAddress}?apiKey=${this.getApiKey()}`,
- })
- console.log({QORTBalance})
- return QORTBalance;
- } catch (error) {
- console.error(error);
- const data = {};
- const errorMsg = error.message || get("browserpage.bchange21");
- data['error'] = errorMsg;
- response = JSON.stringify(data);
- return;
- } finally {
- this.loader.hide();
- }
- } else {
- let _url = ``
- let _body = null
+ let coin = data.coin;
+ if (coin === "QORT") {
+ let qortAddress = window.parent.reduxStore.getState().app.selectedAddress.address
+ try {
+ this.loader.show();
+ const QORTBalance = await parentEpml.request('apiCall', {
+ url: `/addresses/balance/${qortAddress}?apiKey=${this.getApiKey()}`,
+ })
+ return QORTBalance;
+ } catch (error) {
+ console.error(error);
+ const data = {};
+ const errorMsg = error.message || get("browserpage.bchange21");
+ data['error'] = errorMsg;
+ response = JSON.stringify(data);
+ return;
+ } finally {
+ this.loader.hide();
+ }
+ } else {
+ let _url = ``
+ let _body = null
- switch (coin) {
- case 'LTC':
- _url = `/crosschain/ltc/walletbalance?apiKey=${this.getApiKey()}`
- _body = window.parent.reduxStore.getState().app.selectedAddress.ltcWallet.derivedMasterPublicKey
- break
- case 'DOGE':
- _url = `/crosschain/doge/walletbalance?apiKey=${this.getApiKey()}`
- _body = window.parent.reduxStore.getState().app.selectedAddress.dogeWallet.derivedMasterPublicKey
- break
- case 'DGB':
- _url = `/crosschain/dgb/walletbalance?apiKey=${this.getApiKey()}`
- _body = window.parent.reduxStore.getState().app.selectedAddress.dgbWallet.derivedMasterPublicKey
- break
- case 'RVN':
- _url = `/crosschain/rvn/walletbalance?apiKey=${this.getApiKey()}`
- _body = window.parent.reduxStore.getState().app.selectedAddress.rvnWallet.derivedMasterPublicKey
- break
- case 'ARRR':
- _url = `/crosschain/arrr/walletbalance?apiKey=${this.getApiKey()}`
- _body = window.parent.reduxStore.getState().app.selectedAddress.arrrWallet.seed58
- break
- default:
- break
- }
- try {
- this.loader.show()
- await parentEpml.request('apiCall', {
- url: _url,
- method: 'POST',
- body: _body,
- }).then((res) => {
- if (isNaN(Number(res))) {
- throw new Error(get("browserpage.bchange21"));
- } else {
- console.log((Number(res) / 1e8).toFixed(8), "other wallet balance here");
- return (Number(res) / 1e8).toFixed(8)
- }
- })
- } catch (error) {
- console.error(error);
- const data = {};
- const errorMsg = error.message || get("browserpage.bchange21");
- data['error'] = errorMsg;
- response = JSON.stringify(data);
- return;
- } finally {
- this.loader.hide()
- }
- }
- } else if (res3.action === 'reject') {
+ switch (coin) {
+ case 'LTC':
+ _url = `/crosschain/ltc/walletbalance?apiKey=${this.getApiKey()}`
+ _body = window.parent.reduxStore.getState().app.selectedAddress.ltcWallet.derivedMasterPublicKey
+ break
+ case 'DOGE':
+ _url = `/crosschain/doge/walletbalance?apiKey=${this.getApiKey()}`
+ _body = window.parent.reduxStore.getState().app.selectedAddress.dogeWallet.derivedMasterPublicKey
+ break
+ case 'DGB':
+ _url = `/crosschain/dgb/walletbalance?apiKey=${this.getApiKey()}`
+ _body = window.parent.reduxStore.getState().app.selectedAddress.dgbWallet.derivedMasterPublicKey
+ break
+ case 'RVN':
+ _url = `/crosschain/rvn/walletbalance?apiKey=${this.getApiKey()}`
+ _body = window.parent.reduxStore.getState().app.selectedAddress.rvnWallet.derivedMasterPublicKey
+ break
+ case 'ARRR':
+ _url = `/crosschain/arrr/walletbalance?apiKey=${this.getApiKey()}`
+ _body = window.parent.reduxStore.getState().app.selectedAddress.arrrWallet.seed58
+ break
+ default:
+ break
+ }
+ try {
+ this.loader.show()
+ await parentEpml.request('apiCall', {
+ url: _url,
+ method: 'POST',
+ body: _body,
+ }).then((res) => {
+ if (isNaN(Number(res))) {
+ throw new Error(get("browserpage.bchange21"));
+ } else {
+ console.log((Number(res) / 1e8).toFixed(8), "other wallet balance here");
+ return (Number(res) / 1e8).toFixed(8)
+ }
+ })
+ } catch (error) {
+ console.error(error);
+ const data = {};
+ const errorMsg = error.message || get("browserpage.bchange21");
+ data['error'] = errorMsg;
+ response = JSON.stringify(data);
+ return;
+ } finally {
+ this.loader.hide()
+ }
+ }
+ } else if (res3.action === 'reject') {
response = '{"error": "User declined request"}';
}
break;
@@ -554,14 +780,16 @@ class WebBrowser extends LitElement {
// Not all responses will be JSON
responseObj = response;
}
-
+ console.log({ responseObj })
// Respond to app
if (responseObj.error != null) {
+ console.log('hello error')
event.ports[0].postMessage({
result: null,
error: responseObj,
});
} else {
+ console.log('hello success')
event.ports[0].postMessage({
result: responseObj,
error: null,
@@ -654,15 +882,13 @@ class WebBrowser extends LitElement {
refresh() {
const myNode =
window.parent.reduxStore.getState().app.nodeConfig.knownNodes[
- window.parent.reduxStore.getState().app.nodeConfig.node
+ window.parent.reduxStore.getState().app.nodeConfig.node
];
const nodeUrl =
myNode.protocol + '://' + myNode.domain + ':' + myNode.port;
- this.url = `${nodeUrl}/render/${this.service}/${this.name}${
- this.path != null ? this.path : ''
- }?theme=${this.theme}&identifier=${
- this.identifier != null ? this.identifier : ''
- }`;
+ this.url = `${nodeUrl}/render/${this.service}/${this.name}${this.path != null ? this.path : ''
+ }?theme=${this.theme}&identifier=${this.identifier != null ? this.identifier : ''
+ }`;
}
goBackToList() {
@@ -811,9 +1037,8 @@ class WebBrowser extends LitElement {
this.identifier == null ? 'default' : resource.identifier;
let ret = await parentEpml.request('apiCall', {
- url: `/arbitrary/resource/${this.service}/${
- this.name
- }/${identifier}?apiKey=${this.getApiKey()}`,
+ url: `/arbitrary/resource/${this.service}/${this.name
+ }/${identifier}?apiKey=${this.getApiKey()}`,
method: 'DELETE',
});
@@ -864,7 +1089,7 @@ class WebBrowser extends LitElement {
getApiKey() {
const myNode =
window.parent.reduxStore.getState().app.nodeConfig.knownNodes[
- window.parent.reduxStore.getState().app.nodeConfig.node
+ window.parent.reduxStore.getState().app.nodeConfig.node
];
let apiKey = myNode.apiKey;
return apiKey;
@@ -883,10 +1108,10 @@ async function showModalAndWait(type, data) {
return new Promise((resolve) => {
// Create the modal and add it to the DOM
const modal = document.createElement('div');
- modal.id = "backdrop"
- modal.classList.add("backdrop");
- modal.innerHTML =
- `
+ modal.id = "backdrop"
+ modal.classList.add("backdrop");
+ modal.innerHTML =
+ `
${type === actions.GET_USER_ACCOUNT ? `
${get("browserpage.bchange18")}
` : ''}
@@ -900,30 +1125,30 @@ async function showModalAndWait(type, data) {
`;
- document.body.appendChild(modal);
+ document.body.appendChild(modal);
// Add click event listeners to the buttons
const okButton = modal.querySelector('#ok-button');
okButton.addEventListener('click', () => {
const userData = {};
- if (modal.parentNode === document.body) {
- document.body.removeChild(modal);
- }
+ if (modal.parentNode === document.body) {
+ document.body.removeChild(modal);
+ }
resolve({ action: 'accept', userData });
});
- const backdropClick = document.getElementById('backdrop');
+ const backdropClick = document.getElementById('backdrop');
backdropClick.addEventListener('click', () => {
- if (modal.parentNode === document.body) {
- document.body.removeChild(modal);
- }
- resolve({ action: 'reject' });
+ if (modal.parentNode === document.body) {
+ document.body.removeChild(modal);
+ }
+ resolve({ action: 'reject' });
});
const cancelButton = modal.querySelector('#cancel-button');
cancelButton.addEventListener('click', () => {
- if (modal.parentNode === document.body) {
- document.body.removeChild(modal);
- }
- resolve({ action: 'reject' });
+ if (modal.parentNode === document.body) {
+ document.body.removeChild(modal);
+ }
+ resolve({ action: 'reject' });
});
});
}
diff --git a/qortal-ui-plugins/plugins/utils/publish-image.js b/qortal-ui-plugins/plugins/utils/publish-image.js
index 69f4861e..56668e23 100644
--- a/qortal-ui-plugins/plugins/utils/publish-image.js
+++ b/qortal-ui-plugins/plugins/utils/publish-image.js
@@ -148,7 +148,8 @@ export const publishData = async ({
}
}
try {
- await validate()
+ const validateRes = await validate()
+ return validateRes
} catch (error) {
throw new Error(error.message)
}
From a58eecfebe10b5a6190d91863eec4c6ab4b14958 Mon Sep 17 00:00:00 2001
From: Phillip
Date: Thu, 23 Feb 2023 23:21:25 +0000
Subject: [PATCH 16/25] comment-out deploy_at
---
.../plugins/core/qdn/browser/browser.src.js | 66 +++++++++----------
1 file changed, 31 insertions(+), 35 deletions(-)
diff --git a/qortal-ui-plugins/plugins/core/qdn/browser/browser.src.js b/qortal-ui-plugins/plugins/core/qdn/browser/browser.src.js
index 8266c5db..78bb881b 100644
--- a/qortal-ui-plugins/plugins/core/qdn/browser/browser.src.js
+++ b/qortal-ui-plugins/plugins/core/qdn/browser/browser.src.js
@@ -632,45 +632,41 @@ class WebBrowser extends LitElement {
break;
}
- case 'DEPLOY_AT': {
- const requiredFields = ['name', 'description', 'tags', 'creationBytes', 'amount', 'assetId', 'type'];
- const missingFields = [];
+ // case 'DEPLOY_AT': {
+ // const requiredFields = ['name', 'description', 'tags', 'creationBytes', 'amount', 'assetId', 'type'];
+ // const missingFields = [];
- requiredFields.forEach((field) => {
- if (!data[field]) {
- missingFields.push(field);
- }
- });
+ // requiredFields.forEach((field) => {
+ // if (!data[field]) {
+ // missingFields.push(field);
+ // }
+ // });
- if (missingFields.length > 0) {
- const missingFieldsString = missingFields.join(', ');
- const errorMsg = `Missing fields: ${missingFieldsString}`
- let data = {};
- data['error'] = errorMsg;
- response = JSON.stringify(data);
- break
- }
+ // if (missingFields.length > 0) {
+ // const missingFieldsString = missingFields.join(', ');
+ // const errorMsg = `Missing fields: ${missingFieldsString}`
+ // let data = {};
+ // data['error'] = errorMsg;
+ // response = JSON.stringify(data);
+ // break
+ // }
- try {
- this.loader.show();
- const fee = data.fee || undefined
- const resJoinGroup = await this._deployAt(data.name, data.description, data.tags, data.creationBytes, data.amount, data.assetId, fee, data.type)
- response = JSON.stringify(resJoinGroup);
- } catch (error) {
- const obj = {};
- const errorMsg = error.message || 'Failed to join the group.';
- obj['error'] = errorMsg;
- response = JSON.stringify(obj);
- } finally {
- this.loader.hide();
- }
- // Params: data.creationBytes, data.name, data.description, data.type, data.tags, data.amount, data.assetId, data.fee
- // TODO: prompt user to deploy an AT. If they confirm, sign+process a DEPLOY_AT transaction
- // then set the response string from the core to the `response` variable (defined above)
- // If they decline, send back JSON that includes an `error` key, such as `{"error": "User declined request"}`
- break;
- }
+ // try {
+ // this.loader.show();
+ // const fee = data.fee || undefined
+ // const resJoinGroup = await this._deployAt(data.name, data.description, data.tags, data.creationBytes, data.amount, data.assetId, fee, data.type)
+ // response = JSON.stringify(resJoinGroup);
+ // } catch (error) {
+ // const obj = {};
+ // const errorMsg = error.message || 'Failed to join the group.';
+ // obj['error'] = errorMsg;
+ // response = JSON.stringify(obj);
+ // } finally {
+ // this.loader.hide();
+ // }
+ // break;
+ // }
case 'GET_WALLET_BALANCE':
From fb9da8d1d4a344088ec66948b0c4e6ce751c8bff Mon Sep 17 00:00:00 2001
From: Phillip
Date: Thu, 23 Feb 2023 23:24:43 +0000
Subject: [PATCH 17/25] format file
---
.../plugins/core/qdn/browser/browser.src.js | 712 +++++++++---------
1 file changed, 356 insertions(+), 356 deletions(-)
diff --git a/qortal-ui-plugins/plugins/core/qdn/browser/browser.src.js b/qortal-ui-plugins/plugins/core/qdn/browser/browser.src.js
index 52c17de5..c9c9b401 100644
--- a/qortal-ui-plugins/plugins/core/qdn/browser/browser.src.js
+++ b/qortal-ui-plugins/plugins/core/qdn/browser/browser.src.js
@@ -452,9 +452,9 @@ class WebBrowser extends LitElement {
let data = event.data;
console.log('UI received event: ' + JSON.stringify(data));
- switch (data.action) {
- case 'GET_USER_ACCOUNT':
- case actions.GET_USER_ACCOUNT:
+ switch (data.action) {
+ case 'GET_USER_ACCOUNT':
+ case actions.GET_USER_ACCOUNT:
const res1 = await showModalAndWait(
actions.GET_USER_ACCOUNT
);
@@ -573,140 +573,140 @@ class WebBrowser extends LitElement {
window.crypto.getRandomValues(_reference);
let reference = window.parent.Base58.encode(_reference);
const sendMessageRequest = async () => {
- let chatResponse = await parentEpml.request('chat', {
- type: 18,
- nonce: this.selectedAddress.nonce,
- params: {
- timestamp: Date.now(),
- recipient: recipient,
- recipientPublicKey: this._publicKey.key,
- hasChatReference: 0,
- chatReference: chatReference,
- message: messageText,
- lastReference: reference,
- proofOfWorkNonce: 0,
- isEncrypted: 1,
- isText: 1
- }
- });
- const msgResponse = await _computePow(chatResponse)
- return msgResponse;
+ let chatResponse = await parentEpml.request('chat', {
+ type: 18,
+ nonce: this.selectedAddress.nonce,
+ params: {
+ timestamp: Date.now(),
+ recipient: recipient,
+ recipientPublicKey: this._publicKey.key,
+ hasChatReference: 0,
+ chatReference: chatReference,
+ message: messageText,
+ lastReference: reference,
+ proofOfWorkNonce: 0,
+ isEncrypted: 1,
+ isText: 1
+ }
+ });
+ const msgResponse = await _computePow(chatResponse)
+ return msgResponse;
};
-
+
const _computePow = async (chatBytes) => {
- const difficulty = 8;
- const path = window.parent.location.origin + '/memory-pow/memory-pow.wasm.full'
- const worker = new WebWorkerChat();
- let nonce = null;
- let chatBytesArray = null;
-
- await new Promise((res) => {
- worker.postMessage({chatBytes, path, difficulty});
- worker.onmessage = e => {
- chatBytesArray = e.data.chatBytesArray;
- nonce = e.data.nonce;
- res();
- }
- });
-
- let _response = await parentEpml.request('sign_chat', {
- nonce: this.selectedAddress.nonce,
- chatBytesArray: chatBytesArray,
- chatNonce: nonce
- });
-
- const chatResponse = getSendChatResponse(_response);
+ const difficulty = 8;
+ const path = window.parent.location.origin + '/memory-pow/memory-pow.wasm.full'
+ const worker = new WebWorkerChat();
+ let nonce = null;
+ let chatBytesArray = null;
+
+ await new Promise((res) => {
+ worker.postMessage({ chatBytes, path, difficulty });
+ worker.onmessage = e => {
+ chatBytesArray = e.data.chatBytesArray;
+ nonce = e.data.nonce;
+ res();
+ }
+ });
+
+ let _response = await parentEpml.request('sign_chat', {
+ nonce: this.selectedAddress.nonce,
+ chatBytesArray: chatBytesArray,
+ chatNonce: nonce
+ });
+
+ const chatResponse = getSendChatResponse(_response);
return chatResponse;
};
-
+
const getSendChatResponse = (res) => {
- if (res === true) {
- let successString = get("browserpage.bchange23");
- parentEpml.request('showSnackBar', `${successString}`);
- } else if (res.error) {
- parentEpml.request('showSnackBar', res.message);
- }
- this.loader.hide();
- return res;
+ if (res === true) {
+ let successString = get("browserpage.bchange23");
+ parentEpml.request('showSnackBar', `${successString}`);
+ } else if (res.error) {
+ parentEpml.request('showSnackBar', res.message);
+ }
+ this.loader.hide();
+ return res;
};
-
+
const chatResponse = await sendMessageRequest();
return chatResponse;
- }
+ }
const result = await showModalAndWait(
actions.SEND_CHAT_MESSAGE
);
if (result.action === "accept") {
- let hasPublicKey = true;
- const res = await parentEpml.request('apiCall', {
- type: 'api',
- url: `/addresses/publickey/${recipient}`
- });
+ let hasPublicKey = true;
+ const res = await parentEpml.request('apiCall', {
+ type: 'api',
+ url: `/addresses/publickey/${recipient}`
+ });
- if (res.error === 102) {
- this._publicKey.key = ''
- this._publicKey.hasPubKey = false
- hasPublicKey = false;
- } else if (res !== false) {
- this._publicKey.key = res
- this._publicKey.hasPubKey = true
- } else {
- this._publicKey.key = ''
- this._publicKey.hasPubKey = false
- hasPublicKey = false;
- }
+ if (res.error === 102) {
+ this._publicKey.key = ''
+ this._publicKey.hasPubKey = false
+ hasPublicKey = false;
+ } else if (res !== false) {
+ this._publicKey.key = res
+ this._publicKey.hasPubKey = true
+ } else {
+ this._publicKey.key = ''
+ this._publicKey.hasPubKey = false
+ hasPublicKey = false;
+ }
- if (!hasPublicKey) {
- let err4string = get("chatpage.cchange39");
- parentEpml.request('showSnackBar', `${err4string}`)
- return
- }
+ if (!hasPublicKey) {
+ let err4string = get("chatpage.cchange39");
+ parentEpml.request('showSnackBar', `${err4string}`)
+ return
+ }
- this.loader.show();
+ this.loader.show();
- const tiptapJson = {
- type: 'doc',
- content: [
- {
- type: 'paragraph',
- content: [
- {
- type: 'text',
- text: message,
- },
-
- ],
- },
- ],
- }
+ const tiptapJson = {
+ type: 'doc',
+ content: [
+ {
+ type: 'paragraph',
+ content: [
+ {
+ type: 'text',
+ text: message,
+ },
- const messageObject = {
- messageText: tiptapJson,
- images: [''],
- repliedTo: '',
- version: 2
- };
+ ],
+ },
+ ],
+ }
+
+ const messageObject = {
+ messageText: tiptapJson,
+ images: [''],
+ repliedTo: '',
+ version: 2
+ };
+
+ const stringifyMessageObject = JSON.stringify(messageObject);
+ // if (this.balance < 4) {
+ // this.myTrimmedMeassage = ''
+ // this.myTrimmedMeassage = stringifyMessageObject
+ // this.shadowRoot.getElementById('confirmDialog').open()
+ // } else {
+ // this.sendMessage(stringifyMessageObject, typeMessage);
+ // }
+ try {
+ const msgResponse = await sendMessage(stringifyMessageObject);
+ response = msgResponse;
+ } catch (error) {
+ console.error(error);
+ return '{"error": "Request could not be fulfilled"}';
+ } finally {
+ this.loader.hide();
+ console.log("Case completed.");
+ }
- const stringifyMessageObject = JSON.stringify(messageObject);
- // if (this.balance < 4) {
- // this.myTrimmedMeassage = ''
- // this.myTrimmedMeassage = stringifyMessageObject
- // this.shadowRoot.getElementById('confirmDialog').open()
- // } else {
- // this.sendMessage(stringifyMessageObject, typeMessage);
- // }
- try {
- const msgResponse = await sendMessage(stringifyMessageObject);
- response = msgResponse;
- } catch (error) {
- console.error(error);
- return '{"error": "Request could not be fulfilled"}';
- } finally {
- this.loader.hide();
- console.log("Case completed.");
- }
-
} else {
response = '{"error": "User declined request"}';
}
@@ -738,7 +738,7 @@ class WebBrowser extends LitElement {
}
const groupId = data.groupId;
-
+
let groupInfo = null
try {
groupInfo = await parentEpml.request("apiCall", {
@@ -799,8 +799,8 @@ class WebBrowser extends LitElement {
// response = JSON.stringify(data);
// break
// }
-
-
+
+
// try {
// this.loader.show();
// const fee = data.fee || undefined
@@ -823,85 +823,85 @@ class WebBrowser extends LitElement {
// TODO: prompt user to share wallet balance. If they confirm, call `GET /crosschain/:coin/walletbalance`, or for QORT, call `GET /addresses/balance/:address`
// then set the response string from the core to the `response` variable (defined above)
// If they decline, send back JSON that includes an `error` key, such as `{"error": "User declined request"}`
- const res3 = await showModalAndWait(
+ const res3 = await showModalAndWait(
actions.GET_WALLET_BALANCE
);
if (res3.action === 'accept') {
- let coin = data.coin;
- if (coin === "QORT") {
- let qortAddress = window.parent.reduxStore.getState().app.selectedAddress.address
- try {
- this.loader.show();
- const QORTBalance = await parentEpml.request('apiCall', {
- url: `/addresses/balance/${qortAddress}?apiKey=${this.getApiKey()}`,
- })
- return QORTBalance;
- } catch (error) {
- console.error(error);
- const data = {};
- const errorMsg = error.message || get("browserpage.bchange21");
- data['error'] = errorMsg;
- response = JSON.stringify(data);
- return;
- } finally {
- this.loader.hide();
- }
- } else {
- let _url = ``
- let _body = null
+ let coin = data.coin;
+ if (coin === "QORT") {
+ let qortAddress = window.parent.reduxStore.getState().app.selectedAddress.address
+ try {
+ this.loader.show();
+ const QORTBalance = await parentEpml.request('apiCall', {
+ url: `/addresses/balance/${qortAddress}?apiKey=${this.getApiKey()}`,
+ })
+ return QORTBalance;
+ } catch (error) {
+ console.error(error);
+ const data = {};
+ const errorMsg = error.message || get("browserpage.bchange21");
+ data['error'] = errorMsg;
+ response = JSON.stringify(data);
+ return;
+ } finally {
+ this.loader.hide();
+ }
+ } else {
+ let _url = ``
+ let _body = null
- switch (coin) {
- case 'LTC':
- _url = `/crosschain/ltc/walletbalance?apiKey=${this.getApiKey()}`
- _body = window.parent.reduxStore.getState().app.selectedAddress.ltcWallet.derivedMasterPublicKey
- break
- case 'DOGE':
- _url = `/crosschain/doge/walletbalance?apiKey=${this.getApiKey()}`
- _body = window.parent.reduxStore.getState().app.selectedAddress.dogeWallet.derivedMasterPublicKey
- break
- case 'DGB':
- _url = `/crosschain/dgb/walletbalance?apiKey=${this.getApiKey()}`
- _body = window.parent.reduxStore.getState().app.selectedAddress.dgbWallet.derivedMasterPublicKey
- break
- case 'RVN':
- _url = `/crosschain/rvn/walletbalance?apiKey=${this.getApiKey()}`
- _body = window.parent.reduxStore.getState().app.selectedAddress.rvnWallet.derivedMasterPublicKey
- break
- case 'ARRR':
- _url = `/crosschain/arrr/walletbalance?apiKey=${this.getApiKey()}`
- _body = window.parent.reduxStore.getState().app.selectedAddress.arrrWallet.seed58
- break
- default:
- break
- }
- try {
- this.loader.show();
- const res = await parentEpml.request('apiCall', {
- url: _url,
- method: 'POST',
- body: _body,
- })
- if (isNaN(Number(res))) {
- const data = {};
- const errorMsg = error.message || get("browserpage.bchange21");
- data['error'] = errorMsg;
- response = JSON.stringify(data);
- return;
- } else {
- response = (Number(res) / 1e8).toFixed(8);
- }
- } catch (error) {
- console.error(error);
- const data = {};
- const errorMsg = error.message || get("browserpage.bchange21");
- data['error'] = errorMsg;
- response = JSON.stringify(data);
- return;
- } finally {
- this.loader.hide()
- }
- }
- } else if (res3.action === 'reject') {
+ switch (coin) {
+ case 'LTC':
+ _url = `/crosschain/ltc/walletbalance?apiKey=${this.getApiKey()}`
+ _body = window.parent.reduxStore.getState().app.selectedAddress.ltcWallet.derivedMasterPublicKey
+ break
+ case 'DOGE':
+ _url = `/crosschain/doge/walletbalance?apiKey=${this.getApiKey()}`
+ _body = window.parent.reduxStore.getState().app.selectedAddress.dogeWallet.derivedMasterPublicKey
+ break
+ case 'DGB':
+ _url = `/crosschain/dgb/walletbalance?apiKey=${this.getApiKey()}`
+ _body = window.parent.reduxStore.getState().app.selectedAddress.dgbWallet.derivedMasterPublicKey
+ break
+ case 'RVN':
+ _url = `/crosschain/rvn/walletbalance?apiKey=${this.getApiKey()}`
+ _body = window.parent.reduxStore.getState().app.selectedAddress.rvnWallet.derivedMasterPublicKey
+ break
+ case 'ARRR':
+ _url = `/crosschain/arrr/walletbalance?apiKey=${this.getApiKey()}`
+ _body = window.parent.reduxStore.getState().app.selectedAddress.arrrWallet.seed58
+ break
+ default:
+ break
+ }
+ try {
+ this.loader.show();
+ const res = await parentEpml.request('apiCall', {
+ url: _url,
+ method: 'POST',
+ body: _body,
+ })
+ if (isNaN(Number(res))) {
+ const data = {};
+ const errorMsg = error.message || get("browserpage.bchange21");
+ data['error'] = errorMsg;
+ response = JSON.stringify(data);
+ return;
+ } else {
+ response = (Number(res) / 1e8).toFixed(8);
+ }
+ } catch (error) {
+ console.error(error);
+ const data = {};
+ const errorMsg = error.message || get("browserpage.bchange21");
+ data['error'] = errorMsg;
+ response = JSON.stringify(data);
+ return;
+ } finally {
+ this.loader.hide()
+ }
+ }
+ } else if (res3.action === 'reject') {
response = '{"error": "User declined request"}';
}
break;
@@ -911,170 +911,170 @@ class WebBrowser extends LitElement {
// TODO: prompt user to send. If they confirm, call `POST /crosschain/:coin/send`, or for QORT, broadcast a PAYMENT transaction
// then set the response string from the core to the `response` variable (defined above)
// If they decline, send back JSON that includes an `error` key, such as `{"error": "User declined request"}`
- const amount = data.amount;
- let recipient = data.destinationAddress;
- const fee = data.fee
- this.loader.show();
+ const amount = data.amount;
+ let recipient = data.destinationAddress;
+ const fee = data.fee
+ this.loader.show();
- const walletBalance = await parentEpml.request('apiCall', {
- url: `/addresses/balance/${this.myAddress.address}?apiKey=${this.getApiKey()}`,
- }).then((res) => {
- if (isNaN(Number(res))) {
- let snack4string = get("chatpage.cchange48")
- parentEpml.request('showSnackBar', `${snack4string}`)
- return;
- } else {
- return Number(res).toFixed(8);
- }
- })
+ const walletBalance = await parentEpml.request('apiCall', {
+ url: `/addresses/balance/${this.myAddress.address}?apiKey=${this.getApiKey()}`,
+ }).then((res) => {
+ if (isNaN(Number(res))) {
+ let snack4string = get("chatpage.cchange48")
+ parentEpml.request('showSnackBar', `${snack4string}`)
+ return;
+ } else {
+ return Number(res).toFixed(8);
+ }
+ })
- const myRef = await parentEpml.request("apiCall", {
- type: "api",
- url: `/addresses/lastreference/${this.myAddress.address}`,
- })
+ const myRef = await parentEpml.request("apiCall", {
+ type: "api",
+ url: `/addresses/lastreference/${this.myAddress.address}`,
+ })
- if (parseFloat(amount) + parseFloat(data.fee) > parseFloat(walletBalance)) {
- this.loader.hide();
- let snack1string = get("chatpage.cchange51");
- parentEpml.request('showSnackBar', `${snack1string}`);
- return false;
- }
-
- if (parseFloat(amount) <= 0) {
- this.loader.hide();
- let snack2string = get("chatpage.cchange52");
- parentEpml.request('showSnackBar', `${snack2string}`);
- return false;
- }
-
- if (recipient.length === 0) {
- this.loader.hide();
- let snack3string = get("chatpage.cchange53");
- parentEpml.request('showSnackBar', `${snack3string}`);
- return false;
- }
-
- const validateName = async (receiverName) => {
- let myRes;
- let myNameRes = await parentEpml.request('apiCall', {
- type: 'api',
- url: `/names/${receiverName}`,
- })
-
- if (myNameRes.error === 401) {
- myRes = false;
- } else {
- myRes = myNameRes;
- }
- return myRes;
- }
-
- const validateAddress = async (receiverAddress) => {
- let myAddress = await window.parent.validateAddress(receiverAddress);
- return myAddress;
- }
-
- const validateReceiver = async (recipient) => {
- let lastRef = myRef;
- let isAddress;
-
- try {
- isAddress = await validateAddress(recipient);
- } catch (err) {
- isAddress = false;
- }
-
- if (isAddress) {
- let myTransaction = await makeTransactionRequest(recipient, lastRef);
- return getTxnRequestResponse(myTransaction);
- } else {
- let myNameRes = await validateName(recipient);
- if (myNameRes !== false) {
- let myNameAddress = myNameRes.owner
- let myTransaction = await makeTransactionRequest(myNameAddress, lastRef)
- return getTxnRequestResponse(myTransaction)
- } else {
- console.error(`${translate("chatpage.cchange54")}`)
- parentEpml.request('showSnackBar', `${translate("chatpage.cchange54")}`)
- this.loader.hide();
- }
- }
- }
-
- const getName = async (recipient)=> {
- try {
- const getNames = await parentEpml.request("apiCall", {
- type: "api",
- url: `/names/address/${recipient}`,
- });
-
- if (getNames.length > 0 ) {
- return getNames[0].name;
- } else {
- return '';
- }
- } catch (error) {
- return "";
- }
- }
-
- const makeTransactionRequest = async (receiver, lastRef) => {
- let myReceiver = receiver;
- let mylastRef = lastRef;
- let dialogamount = get("transactions.amount");
- let dialogAddress = get("login.address");
- let dialogName = get("login.name");
- let dialogto = get("transactions.to");
- let recipientName = await getName(myReceiver);
- let myTxnrequest = await parentEpml.request('transaction', {
- type: 2,
- nonce: this.myAddress.nonce,
- params: {
- recipient: myReceiver,
- recipientName: recipientName,
- amount: amount,
- lastReference: mylastRef,
- fee: fee,
- dialogamount: dialogamount,
- dialogto: dialogto,
- dialogAddress,
- dialogName
- },
- })
- return myTxnrequest;
- }
-
- const getTxnRequestResponse = (txnResponse) => {
- if (txnResponse.success === false && txnResponse.message) {
- parentEpml.request('showSnackBar', `${txnResponse.message}`);
- this.loader.hide();
- throw new Error(txnResponse);
- } else if (txnResponse.success === true && !txnResponse.data.error) {
- parentEpml.request('showSnackBar', `${get("chatpage.cchange55")}`)
- this.loader.hide();
- } else {
- parentEpml.request('showSnackBar', `${txnResponse.data.message}`);
- this.loader.hide();
- throw new Error(txnResponse);
- }
- }
- try {
- const result = await validateReceiver(recipient);
- if (result) {
- return result;
- }
- } catch (error) {
- console.error(error);
- return '{"error": "Request could not be fulfilled"}';
- } finally {
- console.log("Case completed.");
- }
- break;
+ if (parseFloat(amount) + parseFloat(data.fee) > parseFloat(walletBalance)) {
+ this.loader.hide();
+ let snack1string = get("chatpage.cchange51");
+ parentEpml.request('showSnackBar', `${snack1string}`);
+ return false;
+ }
- default:
- console.log('Unhandled message: ' + JSON.stringify(data));
- return;
- }
+ if (parseFloat(amount) <= 0) {
+ this.loader.hide();
+ let snack2string = get("chatpage.cchange52");
+ parentEpml.request('showSnackBar', `${snack2string}`);
+ return false;
+ }
+
+ if (recipient.length === 0) {
+ this.loader.hide();
+ let snack3string = get("chatpage.cchange53");
+ parentEpml.request('showSnackBar', `${snack3string}`);
+ return false;
+ }
+
+ const validateName = async (receiverName) => {
+ let myRes;
+ let myNameRes = await parentEpml.request('apiCall', {
+ type: 'api',
+ url: `/names/${receiverName}`,
+ })
+
+ if (myNameRes.error === 401) {
+ myRes = false;
+ } else {
+ myRes = myNameRes;
+ }
+ return myRes;
+ }
+
+ const validateAddress = async (receiverAddress) => {
+ let myAddress = await window.parent.validateAddress(receiverAddress);
+ return myAddress;
+ }
+
+ const validateReceiver = async (recipient) => {
+ let lastRef = myRef;
+ let isAddress;
+
+ try {
+ isAddress = await validateAddress(recipient);
+ } catch (err) {
+ isAddress = false;
+ }
+
+ if (isAddress) {
+ let myTransaction = await makeTransactionRequest(recipient, lastRef);
+ return getTxnRequestResponse(myTransaction);
+ } else {
+ let myNameRes = await validateName(recipient);
+ if (myNameRes !== false) {
+ let myNameAddress = myNameRes.owner
+ let myTransaction = await makeTransactionRequest(myNameAddress, lastRef)
+ return getTxnRequestResponse(myTransaction)
+ } else {
+ console.error(`${translate("chatpage.cchange54")}`)
+ parentEpml.request('showSnackBar', `${translate("chatpage.cchange54")}`)
+ this.loader.hide();
+ }
+ }
+ }
+
+ const getName = async (recipient) => {
+ try {
+ const getNames = await parentEpml.request("apiCall", {
+ type: "api",
+ url: `/names/address/${recipient}`,
+ });
+
+ if (getNames.length > 0) {
+ return getNames[0].name;
+ } else {
+ return '';
+ }
+ } catch (error) {
+ return "";
+ }
+ }
+
+ const makeTransactionRequest = async (receiver, lastRef) => {
+ let myReceiver = receiver;
+ let mylastRef = lastRef;
+ let dialogamount = get("transactions.amount");
+ let dialogAddress = get("login.address");
+ let dialogName = get("login.name");
+ let dialogto = get("transactions.to");
+ let recipientName = await getName(myReceiver);
+ let myTxnrequest = await parentEpml.request('transaction', {
+ type: 2,
+ nonce: this.myAddress.nonce,
+ params: {
+ recipient: myReceiver,
+ recipientName: recipientName,
+ amount: amount,
+ lastReference: mylastRef,
+ fee: fee,
+ dialogamount: dialogamount,
+ dialogto: dialogto,
+ dialogAddress,
+ dialogName
+ },
+ })
+ return myTxnrequest;
+ }
+
+ const getTxnRequestResponse = (txnResponse) => {
+ if (txnResponse.success === false && txnResponse.message) {
+ parentEpml.request('showSnackBar', `${txnResponse.message}`);
+ this.loader.hide();
+ throw new Error(txnResponse);
+ } else if (txnResponse.success === true && !txnResponse.data.error) {
+ parentEpml.request('showSnackBar', `${get("chatpage.cchange55")}`)
+ this.loader.hide();
+ } else {
+ parentEpml.request('showSnackBar', `${txnResponse.data.message}`);
+ this.loader.hide();
+ throw new Error(txnResponse);
+ }
+ }
+ try {
+ const result = await validateReceiver(recipient);
+ if (result) {
+ return result;
+ }
+ } catch (error) {
+ console.error(error);
+ return '{"error": "Request could not be fulfilled"}';
+ } finally {
+ console.log("Case completed.");
+ }
+ break;
+
+ default:
+ console.log('Unhandled message: ' + JSON.stringify(data));
+ return;
+ }
// Parse response
let responseObj;
From 697157c79fdca2a59a9416f37553824df2ce7bd3 Mon Sep 17 00:00:00 2001
From: Phillip
Date: Fri, 24 Feb 2023 00:53:25 +0000
Subject: [PATCH 18/25] fixes
---
.../plugins/core/qdn/browser/browser.src.js | 53 +++++++++++++------
1 file changed, 38 insertions(+), 15 deletions(-)
diff --git a/qortal-ui-plugins/plugins/core/qdn/browser/browser.src.js b/qortal-ui-plugins/plugins/core/qdn/browser/browser.src.js
index c9c9b401..6f405459 100644
--- a/qortal-ui-plugins/plugins/core/qdn/browser/browser.src.js
+++ b/qortal-ui-plugins/plugins/core/qdn/browser/browser.src.js
@@ -19,6 +19,7 @@ import WebWorker from 'web-worker:./computePowWorkerFile.src.js';
import WebWorkerChat from 'web-worker:./computePowWorker.src.js';
import { publishData } from '../../../utils/publish-image.js';
import { Loader } from '../../../utils/loader.js';
+import { QORT_DECIMALS } from 'qortal-ui-crypto/api/constants';
const parentEpml = new Epml({ type: 'WINDOW', source: window.parent });
class WebBrowser extends LitElement {
@@ -818,7 +819,24 @@ class WebBrowser extends LitElement {
// }
- case 'GET_WALLET_BALANCE':
+ case 'GET_WALLET_BALANCE': {
+ const requiredFields = ['coin'];
+ const missingFields = [];
+
+ requiredFields.forEach((field) => {
+ if (!data[field]) {
+ missingFields.push(field);
+ }
+ });
+
+ if (missingFields.length > 0) {
+ const missingFieldsString = missingFields.join(', ');
+ const errorMsg = `Missing fields: ${missingFieldsString}`
+ let data = {};
+ data['error'] = errorMsg;
+ response = JSON.stringify(data);
+ break
+ }
// Params: data.coin (QORT / LTC / DOGE / DGB / C / ARRR)
// TODO: prompt user to share wallet balance. If they confirm, call `GET /crosschain/:coin/walletbalance`, or for QORT, call `GET /addresses/balance/:address`
// then set the response string from the core to the `response` variable (defined above)
@@ -826,6 +844,7 @@ class WebBrowser extends LitElement {
const res3 = await showModalAndWait(
actions.GET_WALLET_BALANCE
);
+
if (res3.action === 'accept') {
let coin = data.coin;
if (coin === "QORT") {
@@ -835,14 +854,16 @@ class WebBrowser extends LitElement {
const QORTBalance = await parentEpml.request('apiCall', {
url: `/addresses/balance/${qortAddress}?apiKey=${this.getApiKey()}`,
})
- return QORTBalance;
+ response = QORTBalance
+
+
} catch (error) {
console.error(error);
const data = {};
const errorMsg = error.message || get("browserpage.bchange21");
data['error'] = errorMsg;
response = JSON.stringify(data);
- return;
+
} finally {
this.loader.hide();
}
@@ -904,36 +925,39 @@ class WebBrowser extends LitElement {
} else if (res3.action === 'reject') {
response = '{"error": "User declined request"}';
}
+
break;
+ }
+
case 'SEND_COIN':
// Params: data.coin, data.destinationAddress, data.amount, data.fee
// TODO: prompt user to send. If they confirm, call `POST /crosschain/:coin/send`, or for QORT, broadcast a PAYMENT transaction
// then set the response string from the core to the `response` variable (defined above)
// If they decline, send back JSON that includes an `error` key, such as `{"error": "User declined request"}`
- const amount = data.amount;
+ const amount = data.amount
let recipient = data.destinationAddress;
const fee = data.fee
this.loader.show();
const walletBalance = await parentEpml.request('apiCall', {
url: `/addresses/balance/${this.myAddress.address}?apiKey=${this.getApiKey()}`,
- }).then((res) => {
- if (isNaN(Number(res))) {
- let snack4string = get("chatpage.cchange48")
- parentEpml.request('showSnackBar', `${snack4string}`)
- return;
- } else {
- return Number(res).toFixed(8);
- }
})
+ if (isNaN(Number(walletBalance))) {
+ let snack4string = get("chatpage.cchange48")
+ parentEpml.request('showSnackBar', `${snack4string}`)
+ return;
+ }
+
const myRef = await parentEpml.request("apiCall", {
type: "api",
url: `/addresses/lastreference/${this.myAddress.address}`,
})
- if (parseFloat(amount) + parseFloat(data.fee) > parseFloat(walletBalance)) {
+ const walletBalanceDecimals = parseFloat(walletBalance) * QORT_DECIMALS;
+
+ if (parseFloat(amount) + parseFloat(data.fee) > parseFloat(walletBalanceDecimals)) {
this.loader.hide();
let snack1string = get("chatpage.cchange51");
parentEpml.request('showSnackBar', `${snack1string}`);
@@ -1084,15 +1108,14 @@ class WebBrowser extends LitElement {
// Not all responses will be JSON
responseObj = response;
}
+
// Respond to app
if (responseObj.error != null) {
- console.log('hello error')
event.ports[0].postMessage({
result: null,
error: responseObj,
});
} else {
- console.log('hello success')
event.ports[0].postMessage({
result: responseObj,
error: null,
From 353943cbf9dea480a1d135eed824bf3797484ad2 Mon Sep 17 00:00:00 2001
From: Justin Ferrari
Date: Thu, 23 Feb 2023 21:26:14 -0500
Subject: [PATCH 19/25] Added response return to SEND_QORT
---
.../plugins/core/qdn/browser/browser.src.js | 17 ++++++++---------
1 file changed, 8 insertions(+), 9 deletions(-)
diff --git a/qortal-ui-plugins/plugins/core/qdn/browser/browser.src.js b/qortal-ui-plugins/plugins/core/qdn/browser/browser.src.js
index 6f405459..443d2d00 100644
--- a/qortal-ui-plugins/plugins/core/qdn/browser/browser.src.js
+++ b/qortal-ui-plugins/plugins/core/qdn/browser/browser.src.js
@@ -231,6 +231,7 @@ class WebBrowser extends LitElement {
}
render() {
+ console.log(1, "browser page here");
return html`
@@ -949,7 +950,6 @@ class WebBrowser extends LitElement {
return;
}
-
const myRef = await parentEpml.request("apiCall", {
type: "api",
url: `/addresses/lastreference/${this.myAddress.address}`,
@@ -1010,13 +1010,15 @@ class WebBrowser extends LitElement {
if (isAddress) {
let myTransaction = await makeTransactionRequest(recipient, lastRef);
- return getTxnRequestResponse(myTransaction);
+ const res = getTxnRequestResponse(myTransaction)
+ return res;
} else {
let myNameRes = await validateName(recipient);
if (myNameRes !== false) {
let myNameAddress = myNameRes.owner
let myTransaction = await makeTransactionRequest(myNameAddress, lastRef)
- return getTxnRequestResponse(myTransaction)
+ const res = getTxnRequestResponse(myTransaction)
+ return res;
} else {
console.error(`${translate("chatpage.cchange54")}`)
parentEpml.request('showSnackBar', `${translate("chatpage.cchange54")}`)
@@ -1070,23 +1072,20 @@ class WebBrowser extends LitElement {
const getTxnRequestResponse = (txnResponse) => {
if (txnResponse.success === false && txnResponse.message) {
- parentEpml.request('showSnackBar', `${txnResponse.message}`);
this.loader.hide();
throw new Error(txnResponse);
} else if (txnResponse.success === true && !txnResponse.data.error) {
- parentEpml.request('showSnackBar', `${get("chatpage.cchange55")}`)
this.loader.hide();
} else {
- parentEpml.request('showSnackBar', `${txnResponse.data.message}`);
this.loader.hide();
throw new Error(txnResponse);
}
+ return txnResponse;
}
+
try {
const result = await validateReceiver(recipient);
- if (result) {
- return result;
- }
+ response = result;
} catch (error) {
console.error(error);
return '{"error": "Request could not be fulfilled"}';
From abe7be473deae6ee9464f46bd8a5520be3dfc5bd Mon Sep 17 00:00:00 2001
From: Phillip
Date: Fri, 24 Feb 2023 13:02:05 +0000
Subject: [PATCH 20/25] fix issues
---
.../api/transactions/DeployAtTransaction.js | 4 +-
.../plugins/core/qdn/browser/browser.src.js | 132 ++++++++++++------
2 files changed, 89 insertions(+), 47 deletions(-)
diff --git a/qortal-ui-crypto/api/transactions/DeployAtTransaction.js b/qortal-ui-crypto/api/transactions/DeployAtTransaction.js
index c3eb20e4..a9b3ad5f 100644
--- a/qortal-ui-crypto/api/transactions/DeployAtTransaction.js
+++ b/qortal-ui-crypto/api/transactions/DeployAtTransaction.js
@@ -1,5 +1,6 @@
'use strict'
import TransactionBase from './TransactionBase.js'
+import { store } from '../../api.js'
export default class DeployAtTransaction extends TransactionBase {
constructor() {
@@ -33,7 +34,7 @@ export default class DeployAtTransaction extends TransactionBase {
this._feeBytes = this.constructor.utils.int64ToBytes(this._fee)
}
set rAmount(rAmount) {
- this._rAmount = rAmount
+ this._rAmount = Math.round(rAmount * store.getState().config.coin.decimals)
this._rAmountBytes = this.constructor.utils.int64ToBytes(this._rAmount)
}
@@ -60,7 +61,6 @@ export default class DeployAtTransaction extends TransactionBase {
}
set rCreationBytes(rCreationBytes) {
const decode = this.constructor.Base58.decode(rCreationBytes)
- console.log({decode})
this._rCreationBytes = this.constructor.utils.stringtoUTF8Array(decode)
this._rCreationBytesLength = this.constructor.utils.int32ToBytes(this._rCreationBytes.length)
}
diff --git a/qortal-ui-plugins/plugins/core/qdn/browser/browser.src.js b/qortal-ui-plugins/plugins/core/qdn/browser/browser.src.js
index 443d2d00..2ae43c96 100644
--- a/qortal-ui-plugins/plugins/core/qdn/browser/browser.src.js
+++ b/qortal-ui-plugins/plugins/core/qdn/browser/browser.src.js
@@ -231,7 +231,6 @@ class WebBrowser extends LitElement {
}
render() {
- console.log(1, "browser page here");
return html`
@@ -295,7 +294,20 @@ class WebBrowser extends LitElement {
}
const data = await response.json()
- const joinFee = data
+ const joinFee = (Number(data) / 1e8).toFixed(8)
+ return joinFee
+ }
+ async sendQortFee() {
+ const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]
+ const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port
+ const url = `${nodeUrl}/transactions/unitfee?txType=PAYMENT`
+ const response = await fetch(url)
+ if (!response.ok) {
+ throw new Error('Error when fetching join fee');
+ }
+
+ const data = await response.json()
+ const joinFee = (Number(data) / 1e8).toFixed(8)
return joinFee
}
@@ -452,10 +464,8 @@ class WebBrowser extends LitElement {
let response = '{"error": "Request could not be fulfilled"}';
let data = event.data;
- console.log('UI received event: ' + JSON.stringify(data));
switch (data.action) {
- case 'GET_USER_ACCOUNT':
case actions.GET_USER_ACCOUNT:
const res1 = await showModalAndWait(
actions.GET_USER_ACCOUNT
@@ -469,12 +479,12 @@ class WebBrowser extends LitElement {
break;
} else {
const data = {};
- const errorMsg = get('browserpage.bchange17');
+ const errorMsg = "User declined to share account details"
data['error'] = errorMsg;
response = JSON.stringify(data);
break;
}
- case 'LINK_TO_QDN_RESOURCE':
+ case actions.LINK_TO_QDN_RESOURCE:
case actions.QDN_RESOURCE_DISPLAYED:
// Links are handled by the core, but the UI also listens for these actions in order to update the address bar.
// Note: don't update this.url here, as we don't want to force reload the iframe each time.
@@ -566,11 +576,11 @@ class WebBrowser extends LitElement {
}
- case 'SEND_CHAT_MESSAGE': {
+ case actions.SEND_CHAT_MESSAGE: {
const message = data.message;
const recipient = data.destinationAddress;
const sendMessage = async (messageText, chatReference) => {
- this.loader.show();
+
let _reference = new Uint8Array(64);
window.crypto.getRandomValues(_reference);
let reference = window.parent.Base58.encode(_reference);
@@ -623,13 +633,13 @@ class WebBrowser extends LitElement {
const getSendChatResponse = (res) => {
if (res === true) {
- let successString = get("browserpage.bchange23");
- parentEpml.request('showSnackBar', `${successString}`);
+ return res
} else if (res.error) {
- parentEpml.request('showSnackBar', res.message);
+ throw new Error(res.message);
+ } else {
+ throw new Error('ERROR: Could not send message');
}
- this.loader.hide();
- return res;
+
};
const chatResponse = await sendMessageRequest();
@@ -665,7 +675,7 @@ class WebBrowser extends LitElement {
return
}
- this.loader.show();
+
const tiptapJson = {
type: 'doc',
@@ -699,14 +709,15 @@ class WebBrowser extends LitElement {
// this.sendMessage(stringifyMessageObject, typeMessage);
// }
try {
+ this.loader.show();
const msgResponse = await sendMessage(stringifyMessageObject);
response = msgResponse;
} catch (error) {
console.error(error);
- return '{"error": "Request could not be fulfilled"}';
+ response = '{"error": "Request could not be fulfilled"}';
} finally {
this.loader.hide();
- console.log("Case completed.");
+
}
} else {
@@ -820,7 +831,7 @@ class WebBrowser extends LitElement {
// }
- case 'GET_WALLET_BALANCE': {
+ case actions.GET_WALLET_BALANCE: {
const requiredFields = ['coin'];
const missingFields = [];
@@ -931,23 +942,43 @@ class WebBrowser extends LitElement {
}
- case 'SEND_COIN':
+ case actions.SEND_COIN: {
+ const requiredFields = ['coin', 'destinationAddress', 'amount'];
+ const missingFields = [];
+
+ requiredFields.forEach((field) => {
+ if (!data[field]) {
+ missingFields.push(field);
+ }
+ });
+
+ if (missingFields.length > 0) {
+ this.loader.hide();
+ const missingFieldsString = missingFields.join(', ');
+ const errorMsg = `Missing fields: ${missingFieldsString}`
+ let data = {};
+ data['error'] = errorMsg;
+ response = JSON.stringify(data);
+ break
+ }
// Params: data.coin, data.destinationAddress, data.amount, data.fee
// TODO: prompt user to send. If they confirm, call `POST /crosschain/:coin/send`, or for QORT, broadcast a PAYMENT transaction
// then set the response string from the core to the `response` variable (defined above)
// If they decline, send back JSON that includes an `error` key, such as `{"error": "User declined request"}`
- const amount = data.amount
+ const amount = Number(data.amount)
let recipient = data.destinationAddress;
- const fee = data.fee
this.loader.show();
const walletBalance = await parentEpml.request('apiCall', {
url: `/addresses/balance/${this.myAddress.address}?apiKey=${this.getApiKey()}`,
})
if (isNaN(Number(walletBalance))) {
- let snack4string = get("chatpage.cchange48")
- parentEpml.request('showSnackBar', `${snack4string}`)
- return;
+ this.loader.hide();
+ let errorMsg = "Failed to Fetch QORT Balance. Try again!"
+ let obj = {};
+ obj['error'] = errorMsg;
+ response = JSON.stringify(obj);
+ break;
}
const myRef = await parentEpml.request("apiCall", {
@@ -955,27 +986,35 @@ class WebBrowser extends LitElement {
url: `/addresses/lastreference/${this.myAddress.address}`,
})
- const walletBalanceDecimals = parseFloat(walletBalance) * QORT_DECIMALS;
-
- if (parseFloat(amount) + parseFloat(data.fee) > parseFloat(walletBalanceDecimals)) {
+ const walletBalanceDecimals = Number(walletBalance) * QORT_DECIMALS;
+ const amountDecimals = Number(amount) * QORT_DECIMALS
+ const fee = await this.sendQortFee()
+ // TODO fee
+ if (amountDecimals + (fee * QORT_DECIMALS) > walletBalanceDecimals) {
this.loader.hide();
- let snack1string = get("chatpage.cchange51");
- parentEpml.request('showSnackBar', `${snack1string}`);
- return false;
+ let errorMsg = "Insufficient Funds!"
+ let obj = {};
+ obj['error'] = errorMsg;
+ response = JSON.stringify(obj);
+ break;
}
- if (parseFloat(amount) <= 0) {
+ if (amount <= 0) {
this.loader.hide();
- let snack2string = get("chatpage.cchange52");
- parentEpml.request('showSnackBar', `${snack2string}`);
- return false;
+ let errorMsg = "Invalid Amount!"
+ let obj = {};
+ obj['error'] = errorMsg;
+ response = JSON.stringify(obj);
+ break;
}
if (recipient.length === 0) {
this.loader.hide();
- let snack3string = get("chatpage.cchange53");
- parentEpml.request('showSnackBar', `${snack3string}`);
- return false;
+ let errorMsg = "Receiver cannot be empty!"
+ let obj = {};
+ obj['error'] = errorMsg;
+ response = JSON.stringify(obj);
+ break;
}
const validateName = async (receiverName) => {
@@ -1020,9 +1059,10 @@ class WebBrowser extends LitElement {
const res = getTxnRequestResponse(myTransaction)
return res;
} else {
- console.error(`${translate("chatpage.cchange54")}`)
- parentEpml.request('showSnackBar', `${translate("chatpage.cchange54")}`)
- this.loader.hide();
+
+ let errorMsg = "Invalid Receiver!"
+ throw new Error(errorMsg)
+
}
}
}
@@ -1073,14 +1113,15 @@ class WebBrowser extends LitElement {
const getTxnRequestResponse = (txnResponse) => {
if (txnResponse.success === false && txnResponse.message) {
this.loader.hide();
- throw new Error(txnResponse);
+ throw new Error(txnResponse.message);
} else if (txnResponse.success === true && !txnResponse.data.error) {
this.loader.hide();
+ return txnResponse.data;
} else {
this.loader.hide();
- throw new Error(txnResponse);
+ throw new Error('Error: could not send coin');
}
- return txnResponse;
+
}
try {
@@ -1088,11 +1129,13 @@ class WebBrowser extends LitElement {
response = result;
} catch (error) {
console.error(error);
- return '{"error": "Request could not be fulfilled"}';
+ response = '{"error": "Request could not be fulfilled"}';
} finally {
- console.log("Case completed.");
+ this.loader.hide();
}
break;
+ }
+
default:
console.log('Unhandled message: ' + JSON.stringify(data));
@@ -1107,7 +1150,6 @@ class WebBrowser extends LitElement {
// Not all responses will be JSON
responseObj = response;
}
-
// Respond to app
if (responseObj.error != null) {
event.ports[0].postMessage({
From f08fb36fdcbd472b836ba14953c029641bf37bf5 Mon Sep 17 00:00:00 2001
From: Phillip
Date: Fri, 24 Feb 2023 13:14:02 +0000
Subject: [PATCH 21/25] add translations
---
qortal-ui-core/language/us.json | 4 +++-
qortal-ui-plugins/plugins/core/qdn/browser/browser.src.js | 4 ++--
2 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/qortal-ui-core/language/us.json b/qortal-ui-core/language/us.json
index e0892920..be5010f8 100644
--- a/qortal-ui-core/language/us.json
+++ b/qortal-ui-core/language/us.json
@@ -500,7 +500,9 @@
"bchange20": "Do you give this application permission to get your wallet balance?",
"bchange21": "Fetch Wallet Failed. Please try again!",
"bchange22": "Do you give this application permission to send a chat message?",
- "bchange23": "Message Sent!"
+ "bchange23": "Message Sent!",
+ "bchange24": "Reject",
+ "bchange25": "Accept"
},
"datapage": {
"dchange1": "Data Management",
diff --git a/qortal-ui-plugins/plugins/core/qdn/browser/browser.src.js b/qortal-ui-plugins/plugins/core/qdn/browser/browser.src.js
index 2ae43c96..5a423b8f 100644
--- a/qortal-ui-plugins/plugins/core/qdn/browser/browser.src.js
+++ b/qortal-ui-plugins/plugins/core/qdn/browser/browser.src.js
@@ -1487,8 +1487,8 @@ async function showModalAndWait(type, data) {
${type === actions.SEND_CHAT_MESSAGE ? `${get("browserpage.bchange22")}
` : ''}
-
-
+
+
From 8f9498b4c9b7c7a63f9bbff5bf54ec05c84787b9 Mon Sep 17 00:00:00 2001
From: Phillip
Date: Fri, 24 Feb 2023 14:56:52 +0000
Subject: [PATCH 22/25] version 2 api transaction for q-app
---
qortal-ui-core/src/plugins/routes.js | 60 ++++++++++++++++---
qortal-ui-crypto/api/api.js | 2 +-
qortal-ui-crypto/api/createTransaction.js | 6 ++
.../plugins/core/qdn/browser/browser.src.js | 11 +++-
.../plugins/utils/publish-image.js | 4 +-
5 files changed, 71 insertions(+), 12 deletions(-)
diff --git a/qortal-ui-core/src/plugins/routes.js b/qortal-ui-core/src/plugins/routes.js
index f51001f8..ac83416b 100644
--- a/qortal-ui-core/src/plugins/routes.js
+++ b/qortal-ui-core/src/plugins/routes.js
@@ -22,6 +22,7 @@ import framePasteMenu from '../functional-components/frame-paste-menu.js';
const createTransaction = api.createTransaction;
const processTransaction = api.processTransaction;
+const processTransactionVersion2 = api.processTransactionVersion2;
const signChatTransaction = api.signChatTransaction;
const signArbitraryTransaction = api.signArbitraryTransaction;
const tradeBotCreateRequest = api.tradeBotCreateRequest;
@@ -144,8 +145,16 @@ export const routes = {
if (!req.disableModal && !req.data.disableModal) {
await requestTransactionDialog.requestTransaction(tx);
}
-
- const res = await processTransaction(tx.signedBytes);
+
+ let res
+
+ if(req.data.apiVersion && req.data.apiVersion === 2){
+ res = await processTransactionVersion2(tx.signedBytes)
+ }
+ if(!req.data.apiVersion){
+ res = await processTransaction(tx.signedBytes);
+ }
+
let extraData = {}
if(req.data.type === 38 && tx && tx._rewardShareKeyPair && tx._rewardShareKeyPair.secretKey){
extraData.rewardSharePrivateKey = Base58.encode(tx._rewardShareKeyPair.secretKey)
@@ -191,7 +200,16 @@ export const routes = {
_keyPair,
req.data.params
);
- const res = await processTransaction(tx.signedBytes);
+ let res
+
+ if(req.data.apiVersion && req.data.apiVersion === 2){
+ res = await processTransactionVersion2(tx.signedBytes)
+ }
+ if(!req.data.apiVersion){
+ res = await processTransaction(tx.signedBytes);
+ }
+
+
response = {
success: true,
data: res,
@@ -242,8 +260,16 @@ export const routes = {
req.data.chatNonce,
store.getState().app.wallet._addresses[req.data.nonce].keyPair
);
+
+ let res
- const res = await processTransaction(signedChatBytes);
+ if(req.data.apiVersion && req.data.apiVersion === 2){
+ res = await processTransactionVersion2(signedChatBytes)
+ }
+ if(!req.data.apiVersion){
+ res = await processTransaction(signedChatBytes);
+ }
+
response = res;
} catch (e) {
console.error(e);
@@ -262,8 +288,15 @@ export const routes = {
req.data.arbitraryNonce,
store.getState().app.wallet._addresses[req.data.nonce].keyPair
);
+ let res
- const res = await processTransaction(signedArbitraryBytes);
+ if(req.data.apiVersion && req.data.apiVersion === 2){
+ res = await processTransactionVersion2(signedArbitraryBytes)
+ }
+ if(!req.data.apiVersion){
+ res = await processTransaction(signedArbitraryBytes);
+ }
+
response = res;
} catch (e) {
console.error(e);
@@ -293,8 +326,14 @@ export const routes = {
unsignedTxn,
store.getState().app.selectedAddress.keyPair
);
+ let res
- const res = await processTransaction(signedTxnBytes);
+ if(req.data.apiVersion && req.data.apiVersion === 2){
+ res = await processTransactionVersion2(signedTxnBytes)
+ }
+ if(!req.data.apiVersion){
+ res = await processTransaction(signedTxnBytes);
+ }
response = res;
} catch (e) {
console.error(e);
@@ -327,8 +366,15 @@ export const routes = {
unsignedTxn,
store.getState().app.selectedAddress.keyPair
);
+
+ let res
- const res = await processTransaction(signedTxnBytes);
+ if(req.data.apiVersion && req.data.apiVersion === 2){
+ res = await processTransactionVersion2(signedTxnBytes)
+ }
+ if(!req.data.apiVersion){
+ res = await processTransaction(signedTxnBytes);
+ }
response = res;
} catch (e) {
diff --git a/qortal-ui-crypto/api/api.js b/qortal-ui-crypto/api/api.js
index 98da919b..e8e156dd 100644
--- a/qortal-ui-crypto/api/api.js
+++ b/qortal-ui-crypto/api/api.js
@@ -1,5 +1,5 @@
export { request } from './fetch-request.js'
export { transactionTypes as transactions } from './transactions/transactions.js'
-export { processTransaction, createTransaction, computeChatNonce, signChatTransaction, signArbitraryTransaction } from './createTransaction.js'
+export { processTransaction, processTransactionVersion2, createTransaction, computeChatNonce, signChatTransaction, signArbitraryTransaction } from './createTransaction.js'
export { tradeBotCreateRequest, tradeBotRespondRequest, signTradeBotTxn, deleteTradeOffer, sendBtc, sendLtc, sendDoge, sendDgb, sendRvn, sendArrr } from './tradeRequest.js'
export { cancelAllOffers } from './transactions/trade-portal/tradeoffer/cancelAllOffers.js'
diff --git a/qortal-ui-crypto/api/createTransaction.js b/qortal-ui-crypto/api/createTransaction.js
index 2a56aa56..169561dd 100644
--- a/qortal-ui-crypto/api/createTransaction.js
+++ b/qortal-ui-crypto/api/createTransaction.js
@@ -36,3 +36,9 @@ export const processTransaction = bytes => request('/transactions/process', {
method: 'POST',
body: Base58.encode(bytes)
})
+
+export const processTransactionVersion2 = bytes => request('/transactions/process?apiVersion=2', {
+ method: 'POST',
+ body: Base58.encode(bytes)
+})
+
diff --git a/qortal-ui-plugins/plugins/core/qdn/browser/browser.src.js b/qortal-ui-plugins/plugins/core/qdn/browser/browser.src.js
index 5a423b8f..8f695dbf 100644
--- a/qortal-ui-plugins/plugins/core/qdn/browser/browser.src.js
+++ b/qortal-ui-plugins/plugins/core/qdn/browser/browser.src.js
@@ -342,7 +342,8 @@ class WebBrowser extends LitElement {
lastReference: lastRef,
groupdialog1: groupdialog1,
groupdialog2: groupdialog2
- }
+ },
+ apiVersion: 2
})
return myTxnrequest
}
@@ -398,7 +399,8 @@ class WebBrowser extends LitElement {
lastReference: lastRef,
atDeployDialog1: groupdialog1,
atDeployDialog2: groupdialog2
- }
+ },
+ apiVersion: 2
})
return myTxnrequest
}
@@ -550,6 +552,7 @@ class WebBrowser extends LitElement {
selectedAddress: this.selectedAddress,
worker: worker,
isBase64: true,
+ apiVersion: 2
});
response = JSON.stringify(resPublish);
@@ -624,7 +627,8 @@ class WebBrowser extends LitElement {
let _response = await parentEpml.request('sign_chat', {
nonce: this.selectedAddress.nonce,
chatBytesArray: chatBytesArray,
- chatNonce: nonce
+ chatNonce: nonce,
+ apiVersion: 2
});
const chatResponse = getSendChatResponse(_response);
@@ -1106,6 +1110,7 @@ class WebBrowser extends LitElement {
dialogAddress,
dialogName
},
+ apiVersion: 2
})
return myTxnrequest;
}
diff --git a/qortal-ui-plugins/plugins/utils/publish-image.js b/qortal-ui-plugins/plugins/utils/publish-image.js
index 56668e23..11aed013 100644
--- a/qortal-ui-plugins/plugins/utils/publish-image.js
+++ b/qortal-ui-plugins/plugins/utils/publish-image.js
@@ -18,7 +18,8 @@ export const publishData = async ({
selectedAddress,
worker,
isBase64,
- metaData
+ metaData,
+ apiVersion
}) => {
const validateName = async (receiverName) => {
let nameRes = await parentEpml.request("apiCall", {
@@ -71,6 +72,7 @@ export const publishData = async ({
arbitraryBytesBase58: transactionBytesBase58,
arbitraryBytesForSigningBase58: convertedBytesBase58,
arbitraryNonce: nonce,
+ apiVersion: apiVersion ? apiVersion : null
})
let myResponse = { error: "" }
if (response === false) {
From 21951f3ebee3544f3b3b39fd9e648ce17da74b5f Mon Sep 17 00:00:00 2001
From: Justin Ferrari
Date: Fri, 24 Feb 2023 17:46:43 -0500
Subject: [PATCH 23/25] Added auth modal to q-apps
---
.../src/components/login-view/login-view.js | 7 +-
.../src/redux/app/actions/app-core.js | 16 ++++-
.../src/redux/app/app-action-types.js | 2 +
qortal-ui-core/src/redux/app/app-reducer.js | 20 +++++-
.../plugins/core/qdn/browser/browser.src.js | 69 +++++++++++++++++--
5 files changed, 103 insertions(+), 11 deletions(-)
diff --git a/qortal-ui-core/src/components/login-view/login-view.js b/qortal-ui-core/src/components/login-view/login-view.js
index ebdf31f2..257bbf36 100644
--- a/qortal-ui-core/src/components/login-view/login-view.js
+++ b/qortal-ui-core/src/components/login-view/login-view.js
@@ -14,14 +14,15 @@ import './login-section.js'
import '../qort-theme-toggle.js'
import settings from '../../functional-components/settings-page.js'
-import { addAutoLoadImageChat, removeAutoLoadImageChat, addChatLastSeen } from '../../redux/app/app-actions.js'
+import { addAutoLoadImageChat, removeAutoLoadImageChat, addChatLastSeen, allowQAPPAutoAuth, removeQAPPAutoAuth } from '../../redux/app/app-actions.js'
window.reduxStore = store
window.reduxAction = {
addAutoLoadImageChat: addAutoLoadImageChat,
removeAutoLoadImageChat: removeAutoLoadImageChat,
- addChatLastSeen: addChatLastSeen
-
+ addChatLastSeen: addChatLastSeen,
+ allowQAPPAutoAuth: allowQAPPAutoAuth,
+ removeQAPPAutoAuth: removeQAPPAutoAuth
}
const animationDuration = 0.7 // Seconds
diff --git a/qortal-ui-core/src/redux/app/actions/app-core.js b/qortal-ui-core/src/redux/app/actions/app-core.js
index 894f2c2e..43d5d57a 100644
--- a/qortal-ui-core/src/redux/app/actions/app-core.js
+++ b/qortal-ui-core/src/redux/app/actions/app-core.js
@@ -1,5 +1,5 @@
// Core App Actions here...
-import { UPDATE_BLOCK_INFO, UPDATE_NODE_STATUS, UPDATE_NODE_INFO, CHAT_HEADS, ACCOUNT_INFO, COPY_MENU_SWITCH, PASTE_MENU_SWITCH, FRAME_PASTE_MENU_SWITCH, ADD_AUTO_LOAD_IMAGES_CHAT, REMOVE_AUTO_LOAD_IMAGES_CHAT, SET_CHAT_LAST_SEEN, ADD_CHAT_LAST_SEEN } from '../app-action-types.js'
+import { UPDATE_BLOCK_INFO, UPDATE_NODE_STATUS, UPDATE_NODE_INFO, CHAT_HEADS, ACCOUNT_INFO, COPY_MENU_SWITCH, PASTE_MENU_SWITCH, FRAME_PASTE_MENU_SWITCH, ADD_AUTO_LOAD_IMAGES_CHAT, REMOVE_AUTO_LOAD_IMAGES_CHAT, ALLOW_QAPP_AUTO_AUTH, REMOVE_QAPP_AUTO_AUTH, SET_CHAT_LAST_SEEN, ADD_CHAT_LAST_SEEN } from '../app-action-types.js'
export const doUpdateBlockInfo = (blockObj) => {
return (dispatch, getState) => {
@@ -120,6 +120,20 @@ export const removeAutoLoadImageChat = (payload) => {
}
}
+export const allowQAPPAutoAuth = (payload) => {
+ return {
+ type: ALLOW_QAPP_AUTO_AUTH,
+ payload
+ }
+}
+
+export const removeQAPPAutoAuth = (payload) => {
+ return {
+ type: REMOVE_QAPP_AUTO_AUTH,
+ payload
+ }
+}
+
export const setChatLastSeen = (payload) => {
return {
type: SET_CHAT_LAST_SEEN,
diff --git a/qortal-ui-core/src/redux/app/app-action-types.js b/qortal-ui-core/src/redux/app/app-action-types.js
index 518d4cd7..4125e6b1 100644
--- a/qortal-ui-core/src/redux/app/app-action-types.js
+++ b/qortal-ui-core/src/redux/app/app-action-types.js
@@ -22,5 +22,7 @@ export const PASTE_MENU_SWITCH = 'PASTE_MENU_SWITCH'
export const FRAME_PASTE_MENU_SWITCH = 'FRAME_PASTE_MENU_SWITCH'
export const ADD_AUTO_LOAD_IMAGES_CHAT = 'ADD_AUTO_LOAD_IMAGES_CHAT'
export const REMOVE_AUTO_LOAD_IMAGES_CHAT = 'REMOVE_AUTO_LOAD_IMAGES_CHAT'
+export const ALLOW_QAPP_AUTO_AUTH = 'ALLOW_QAPP_AUTO_AUTH'
+export const REMOVE_QAPP_AUTO_AUTH = 'REMOVE_QAPP_AUTO_AUTH'
export const SET_CHAT_LAST_SEEN = 'SET_CHAT_LAST_SEEN'
export const ADD_CHAT_LAST_SEEN = 'ADD_CHAT_LAST_SEEN'
diff --git a/qortal-ui-core/src/redux/app/app-reducer.js b/qortal-ui-core/src/redux/app/app-reducer.js
index 68a48675..6e3849d1 100644
--- a/qortal-ui-core/src/redux/app/app-reducer.js
+++ b/qortal-ui-core/src/redux/app/app-reducer.js
@@ -1,6 +1,6 @@
// Loading state, login state, isNavDrawOpen state etc. None of this needs to be saved to localstorage.
import { loadStateFromLocalStorage, saveStateToLocalStorage } from '../../localStorageHelpers.js'
-import { LOG_IN, LOG_OUT, NETWORK_CONNECTION_STATUS, INIT_WORKERS, ADD_PLUGIN_URL, ADD_PLUGIN, ADD_NEW_PLUGIN_URL, NAVIGATE, SELECT_ADDRESS, ACCOUNT_INFO, CHAT_HEADS, UPDATE_BLOCK_INFO, UPDATE_NODE_STATUS, UPDATE_NODE_INFO, LOAD_NODE_CONFIG, SET_NODE, ADD_NODE, PAGE_URL, COPY_MENU_SWITCH, PASTE_MENU_SWITCH, FRAME_PASTE_MENU_SWITCH, ADD_AUTO_LOAD_IMAGES_CHAT, REMOVE_AUTO_LOAD_IMAGES_CHAT, SET_CHAT_LAST_SEEN, ADD_CHAT_LAST_SEEN } from './app-action-types.js'
+import { LOG_IN, LOG_OUT, NETWORK_CONNECTION_STATUS, INIT_WORKERS, ADD_PLUGIN_URL, ADD_PLUGIN, ADD_NEW_PLUGIN_URL, NAVIGATE, SELECT_ADDRESS, ACCOUNT_INFO, CHAT_HEADS, UPDATE_BLOCK_INFO, UPDATE_NODE_STATUS, UPDATE_NODE_INFO, LOAD_NODE_CONFIG, SET_NODE, ADD_NODE, PAGE_URL, COPY_MENU_SWITCH, PASTE_MENU_SWITCH, FRAME_PASTE_MENU_SWITCH, ADD_AUTO_LOAD_IMAGES_CHAT, REMOVE_AUTO_LOAD_IMAGES_CHAT, ALLOW_QAPP_AUTO_AUTH, REMOVE_QAPP_AUTO_AUTH, SET_CHAT_LAST_SEEN, ADD_CHAT_LAST_SEEN } from './app-action-types.js'
import { initWorkersReducer } from './reducers/init-workers.js'
import { loginReducer } from './reducers/login-reducer.js'
import { setNode, addNode } from './reducers/manage-node.js'
@@ -50,6 +50,7 @@ const INITIAL_STATE = {
elementId: ''
},
autoLoadImageChats: loadStateFromLocalStorage('autoLoadImageChats') || [],
+ qAPPAutoAuth: loadStateFromLocalStorage('qAPPAutoAuth') || false,
chatLastSeen: []
}
@@ -175,6 +176,23 @@ export default (state = INITIAL_STATE, action) => {
autoLoadImageChats: updatedState
}
}
+
+ case ALLOW_QAPP_AUTO_AUTH: {
+ saveStateToLocalStorage("qAPPAutoAuth", true)
+ return {
+ ...state,
+ qAPPAutoAuth: action.payload
+ }
+ }
+
+ case REMOVE_QAPP_AUTO_AUTH: {
+ saveStateToLocalStorage("qAPPAutoAuth", false)
+ return {
+ ...state,
+ qAPPAutoAuth: action.payload
+ }
+ }
+
case SET_CHAT_LAST_SEEN: {
return {
...state,
diff --git a/qortal-ui-plugins/plugins/core/qdn/browser/browser.src.js b/qortal-ui-plugins/plugins/core/qdn/browser/browser.src.js
index 443d2d00..dc32aaaa 100644
--- a/qortal-ui-plugins/plugins/core/qdn/browser/browser.src.js
+++ b/qortal-ui-plugins/plugins/core/qdn/browser/browser.src.js
@@ -15,6 +15,7 @@ registerTranslateConfig({
import '@material/mwc-button';
import '@material/mwc-icon';
+import '@material/mwc-checkbox'
import WebWorker from 'web-worker:./computePowWorkerFile.src.js';
import WebWorkerChat from 'web-worker:./computePowWorker.src.js';
import { publishData } from '../../../utils/publish-image.js';
@@ -231,7 +232,6 @@ class WebBrowser extends LitElement {
}
render() {
- console.log(1, "browser page here");
return html`
@@ -457,10 +457,21 @@ class WebBrowser extends LitElement {
switch (data.action) {
case 'GET_USER_ACCOUNT':
case actions.GET_USER_ACCOUNT:
- const res1 = await showModalAndWait(
- actions.GET_USER_ACCOUNT
- );
- if (res1.action === 'accept') {
+ let skip = false;
+ if (window.parent.reduxStore.getState().app.qAPPAutoAuth) {
+ skip = true;
+ }
+ let res1;
+ if (!skip) {
+ res1 = await showModalAndWait(
+ actions.GET_USER_ACCOUNT,
+ {
+ service: this.service,
+ name: this.name
+ }
+ );
+ };
+ if ((res1 && res1.action === 'accept') || skip) {
let account = {};
account['address'] = this.selectedAddress.address;
account['publicKey'] =
@@ -1439,7 +1450,21 @@ async function showModalAndWait(type, data) {
`
- ${type === actions.GET_USER_ACCOUNT ? `
${get("browserpage.bchange18")}
` : ''}
+ ${type === actions.GET_USER_ACCOUNT ? `
+
+
${`${data.service} ${data.name} ${get("browserpage.bchange18")}`}
+
${get("browserpage.bchange24")} ${data.service}
+
${get("browserpage.bchange25")}
+
+
+
+
+
+
+ ` : ''}
${type === actions.PUBLISH_QDN_RESOURCE ? `
${get("browserpage.bchange19")}
` : ''}
${type === actions.GET_WALLET_BALANCE ? `
${get("browserpage.bchange20")}
` : ''}
${type === actions.SEND_CHAT_MESSAGE ? `
${get("browserpage.bchange22")}
` : ''}
@@ -1462,6 +1487,11 @@ async function showModalAndWait(type, data) {
}
resolve({ action: 'accept', userData });
});
+ const modalContent = modal.querySelector('.modal-content');
+ modalContent.addEventListener('click', (e) => {
+ e.stopPropagation();
+ return;
+ });
const backdropClick = document.getElementById('backdrop');
backdropClick.addEventListener('click', () => {
if (modal.parentNode === document.body) {
@@ -1476,6 +1506,18 @@ async function showModalAndWait(type, data) {
}
resolve({ action: 'reject' });
});
+ const labelButton = modal.querySelector('#authButtonLabel');
+ labelButton.addEventListener('click', () => {
+ this.shadowRoot.getElementById('authButton').click();
+ })
+ const checkbox = modal.querySelector('#authButton');
+ checkbox.addEventListener('click', (e) => {
+ if (e.target.checked) {
+ window.parent.reduxStore.dispatch( window.parent.reduxAction.removeQAPPAutoAuth(false))
+ return
+ }
+ window.parent.reduxStore.dispatch( window.parent.reduxAction.allowQAPPAutoAuth(true))
+ })
});
}
@@ -1553,6 +1595,13 @@ justify-content: space-between;
padding: 25px;
}
+.modal-subcontainer {
+ display: flex;
+ flex-direction: column;
+ align-items: flex-start;
+ gap: 15px;
+}
+
.modal-paragraph {
font-family: Roboto, sans-serif;
font-size: 18px;
@@ -1562,6 +1611,14 @@ color: black;
margin: 0;
}
+.checkbox-row {
+ display: flex;
+ align-items: center;
+ font-family: Montserrat, sans-serif;
+ font-weight: 600;
+ color: black;
+}
+
.modal-buttons {
display: flex;
justify-content: space-between;
From 10d4489ba42afe2480d60ea5f1deabf144b2a46b Mon Sep 17 00:00:00 2001
From: Justin Ferrari
Date: Fri, 24 Feb 2023 17:47:07 -0500
Subject: [PATCH 24/25] Added translations
---
qortal-ui-core/language/us.json | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/qortal-ui-core/language/us.json b/qortal-ui-core/language/us.json
index e0892920..f2b65bb9 100644
--- a/qortal-ui-core/language/us.json
+++ b/qortal-ui-core/language/us.json
@@ -495,12 +495,15 @@
"bchange15": "Can't delete data from followed names. Please unfollow first.",
"bchange16": "Error occurred when trying to delete this resource. Please try again!",
"bchange17": "User declined to share account details",
- "bchange18": "Do you give this application permission to get your user address?",
+ "bchange18": "has requested authentication. Would you like to authenticate?",
"bchange19": "Do you give this application permission to publish to QDN?",
"bchange20": "Do you give this application permission to get your wallet balance?",
"bchange21": "Fetch Wallet Failed. Please try again!",
"bchange22": "Do you give this application permission to send a chat message?",
- "bchange23": "Message Sent!"
+ "bchange23": "Message Sent!",
+ "bchange24": "This shares your QORT address and allows your account to interact with the",
+ "bchange25": "No sensitive data is shared.",
+ "bchange26": "Always authenticate automatically"
},
"datapage": {
"dchange1": "Data Management",
From bd6cf70b2fadfc16c1eeb19e5e3eb88a5c93c4cd Mon Sep 17 00:00:00 2001
From: Justin Ferrari
Date: Sat, 25 Feb 2023 20:56:39 -0500
Subject: [PATCH 25/25] Removed other coins in SEND_COIN & fixed bug
---
.../plugins/core/qdn/browser/browser.src.js | 133 +++++++++---------
1 file changed, 69 insertions(+), 64 deletions(-)
diff --git a/qortal-ui-plugins/plugins/core/qdn/browser/browser.src.js b/qortal-ui-plugins/plugins/core/qdn/browser/browser.src.js
index 53ab4001..eae796af 100644
--- a/qortal-ui-plugins/plugins/core/qdn/browser/browser.src.js
+++ b/qortal-ui-plugins/plugins/core/qdn/browser/browser.src.js
@@ -895,61 +895,62 @@ class WebBrowser extends LitElement {
} finally {
this.loader.hide();
}
- } else {
- let _url = ``
- let _body = null
+ }
+ // else {
+ // let _url = ``
+ // let _body = null
- switch (coin) {
- case 'LTC':
- _url = `/crosschain/ltc/walletbalance?apiKey=${this.getApiKey()}`
- _body = window.parent.reduxStore.getState().app.selectedAddress.ltcWallet.derivedMasterPublicKey
- break
- case 'DOGE':
- _url = `/crosschain/doge/walletbalance?apiKey=${this.getApiKey()}`
- _body = window.parent.reduxStore.getState().app.selectedAddress.dogeWallet.derivedMasterPublicKey
- break
- case 'DGB':
- _url = `/crosschain/dgb/walletbalance?apiKey=${this.getApiKey()}`
- _body = window.parent.reduxStore.getState().app.selectedAddress.dgbWallet.derivedMasterPublicKey
- break
- case 'RVN':
- _url = `/crosschain/rvn/walletbalance?apiKey=${this.getApiKey()}`
- _body = window.parent.reduxStore.getState().app.selectedAddress.rvnWallet.derivedMasterPublicKey
- break
- case 'ARRR':
- _url = `/crosschain/arrr/walletbalance?apiKey=${this.getApiKey()}`
- _body = window.parent.reduxStore.getState().app.selectedAddress.arrrWallet.seed58
- break
- default:
- break
- }
- try {
- this.loader.show();
- const res = await parentEpml.request('apiCall', {
- url: _url,
- method: 'POST',
- body: _body,
- })
- if (isNaN(Number(res))) {
- const data = {};
- const errorMsg = error.message || get("browserpage.bchange21");
- data['error'] = errorMsg;
- response = JSON.stringify(data);
- return;
- } else {
- response = (Number(res) / 1e8).toFixed(8);
- }
- } catch (error) {
- console.error(error);
- const data = {};
- const errorMsg = error.message || get("browserpage.bchange21");
- data['error'] = errorMsg;
- response = JSON.stringify(data);
- return;
- } finally {
- this.loader.hide()
- }
- }
+ // switch (coin) {
+ // case 'LTC':
+ // _url = `/crosschain/ltc/walletbalance?apiKey=${this.getApiKey()}`
+ // _body = window.parent.reduxStore.getState().app.selectedAddress.ltcWallet.derivedMasterPublicKey
+ // break
+ // case 'DOGE':
+ // _url = `/crosschain/doge/walletbalance?apiKey=${this.getApiKey()}`
+ // _body = window.parent.reduxStore.getState().app.selectedAddress.dogeWallet.derivedMasterPublicKey
+ // break
+ // case 'DGB':
+ // _url = `/crosschain/dgb/walletbalance?apiKey=${this.getApiKey()}`
+ // _body = window.parent.reduxStore.getState().app.selectedAddress.dgbWallet.derivedMasterPublicKey
+ // break
+ // case 'RVN':
+ // _url = `/crosschain/rvn/walletbalance?apiKey=${this.getApiKey()}`
+ // _body = window.parent.reduxStore.getState().app.selectedAddress.rvnWallet.derivedMasterPublicKey
+ // break
+ // case 'ARRR':
+ // _url = `/crosschain/arrr/walletbalance?apiKey=${this.getApiKey()}`
+ // _body = window.parent.reduxStore.getState().app.selectedAddress.arrrWallet.seed58
+ // break
+ // default:
+ // break
+ // }
+ // try {
+ // this.loader.show();
+ // const res = await parentEpml.request('apiCall', {
+ // url: _url,
+ // method: 'POST',
+ // body: _body,
+ // })
+ // if (isNaN(Number(res))) {
+ // const data = {};
+ // const errorMsg = error.message || get("browserpage.bchange21");
+ // data['error'] = errorMsg;
+ // response = JSON.stringify(data);
+ // return;
+ // } else {
+ // response = (Number(res) / 1e8).toFixed(8);
+ // }
+ // } catch (error) {
+ // console.error(error);
+ // const data = {};
+ // const errorMsg = error.message || get("browserpage.bchange21");
+ // data['error'] = errorMsg;
+ // response = JSON.stringify(data);
+ // return;
+ // } finally {
+ // this.loader.hide()
+ // }
+ // }
} else if (res3.action === 'reject') {
response = '{"error": "User declined request"}';
}
@@ -1555,17 +1556,21 @@ async function showModalAndWait(type, data) {
resolve({ action: 'reject' });
});
const labelButton = modal.querySelector('#authButtonLabel');
- labelButton.addEventListener('click', () => {
- this.shadowRoot.getElementById('authButton').click();
- })
+ if (labelButton) {
+ labelButton.addEventListener('click', () => {
+ this.shadowRoot.getElementById('authButton').click();
+ })
+ }
const checkbox = modal.querySelector('#authButton');
- checkbox.addEventListener('click', (e) => {
- if (e.target.checked) {
- window.parent.reduxStore.dispatch( window.parent.reduxAction.removeQAPPAutoAuth(false))
- return
- }
- window.parent.reduxStore.dispatch( window.parent.reduxAction.allowQAPPAutoAuth(true))
- })
+ if (checkbox) {
+ checkbox.addEventListener('click', (e) => {
+ if (e.target.checked) {
+ window.parent.reduxStore.dispatch( window.parent.reduxAction.removeQAPPAutoAuth(false))
+ return
+ }
+ window.parent.reduxStore.dispatch( window.parent.reduxAction.allowQAPPAutoAuth(true))
+ })
+ }
});
}