forked from Qortal/qortal-ui
Fixed SEND_CHAT_MESSAGE bugs
This commit is contained in:
parent
2d276d583f
commit
9a7cf9e4d4
@ -498,7 +498,9 @@
|
|||||||
"bchange18": "Do you give this application permission to get your user address?",
|
"bchange18": "Do you give this application permission to get your user address?",
|
||||||
"bchange19": "Do you give this application permission to publish to QDN?",
|
"bchange19": "Do you give this application permission to publish to QDN?",
|
||||||
"bchange20": "Do you give this application permission to get your wallet balance?",
|
"bchange20": "Do you give this application permission to get your wallet balance?",
|
||||||
"bchange21": "Fetch Wallet Failed. Please try again!"
|
"bchange21": "Fetch Wallet Failed. Please try again!",
|
||||||
|
"bchange22": "Do you give this application permission to send a chat message?",
|
||||||
|
"bchange23": "Message Sent!"
|
||||||
},
|
},
|
||||||
"datapage": {
|
"datapage": {
|
||||||
"dchange1": "Data Management",
|
"dchange1": "Data Management",
|
||||||
|
@ -16,6 +16,7 @@ registerTranslateConfig({
|
|||||||
import '@material/mwc-button';
|
import '@material/mwc-button';
|
||||||
import '@material/mwc-icon';
|
import '@material/mwc-icon';
|
||||||
import WebWorker from 'web-worker:./computePowWorkerFile.src.js';
|
import WebWorker from 'web-worker:./computePowWorkerFile.src.js';
|
||||||
|
import WebWorkerChat from 'web-worker:./computePowWorker.src.js';
|
||||||
import { publishData } from '../../../utils/publish-image.js';
|
import { publishData } from '../../../utils/publish-image.js';
|
||||||
import { Loader } from '../../../utils/loader.js';
|
import { Loader } from '../../../utils/loader.js';
|
||||||
const parentEpml = new Epml({ type: 'WINDOW', source: window.parent });
|
const parentEpml = new Epml({ type: 'WINDOW', source: window.parent });
|
||||||
@ -109,6 +110,7 @@ class WebBrowser extends LitElement {
|
|||||||
super();
|
super();
|
||||||
this.url = 'about:blank';
|
this.url = 'about:blank';
|
||||||
this.myAddress = window.parent.reduxStore.getState().app.selectedAddress;
|
this.myAddress = window.parent.reduxStore.getState().app.selectedAddress;
|
||||||
|
this._publicKey = { key: '', hasPubKey: false };
|
||||||
const urlParams = new URLSearchParams(window.location.search);
|
const urlParams = new URLSearchParams(window.location.search);
|
||||||
this.name = urlParams.get('name');
|
this.name = urlParams.get('name');
|
||||||
this.service = urlParams.get('service');
|
this.service = urlParams.get('service');
|
||||||
@ -231,7 +233,6 @@ class WebBrowser extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
console.log(3, 'browser page here');
|
|
||||||
return html`
|
return html`
|
||||||
<div id="websitesWrapper" style="width:auto; padding:10px; background: var(--white);">
|
<div id="websitesWrapper" style="width:auto; padding:10px; background: var(--white);">
|
||||||
<div class="layout horizontal center">
|
<div class="layout horizontal center">
|
||||||
@ -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"}`
|
// If they decline, send back JSON that includes an `error` key, such as `{"error": "User declined request"}`
|
||||||
break;
|
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
|
// Params: data.groupId, data.destinationAddress, data.message
|
||||||
// TODO: prompt user to send chat message. If they confirm, sign+process a CHAT transaction
|
// 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)
|
// 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"}`
|
// If they decline, send back JSON that includes an `error` key, such as `{"error": "User declined request"}`
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case actions.JOIN_GROUP:
|
case actions.JOIN_GROUP:
|
||||||
const groupId = data.groupId;
|
const groupId = data.groupId;
|
||||||
@ -450,7 +598,6 @@ 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`
|
// 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)
|
// 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"}`
|
// 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
|
actions.GET_WALLET_BALANCE
|
||||||
);
|
);
|
||||||
@ -463,7 +610,6 @@ class WebBrowser extends LitElement {
|
|||||||
const QORTBalance = await parentEpml.request('apiCall', {
|
const QORTBalance = await parentEpml.request('apiCall', {
|
||||||
url: `/addresses/balance/${qortAddress}?apiKey=${this.getApiKey()}`,
|
url: `/addresses/balance/${qortAddress}?apiKey=${this.getApiKey()}`,
|
||||||
})
|
})
|
||||||
console.log({QORTBalance})
|
|
||||||
return QORTBalance;
|
return QORTBalance;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
@ -504,19 +650,21 @@ class WebBrowser extends LitElement {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
this.loader.show()
|
this.loader.show();
|
||||||
await parentEpml.request('apiCall', {
|
const res = await parentEpml.request('apiCall', {
|
||||||
url: _url,
|
url: _url,
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: _body,
|
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) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
const data = {};
|
const data = {};
|
||||||
@ -534,7 +682,6 @@ class WebBrowser extends LitElement {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'SEND_COIN':
|
case 'SEND_COIN':
|
||||||
console.log({data});
|
|
||||||
// Params: data.coin, data.destinationAddress, data.amount, data.fee
|
// 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
|
// 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)
|
// then set the response string from the core to the `response` variable (defined above)
|
||||||
@ -712,7 +859,6 @@ class WebBrowser extends LitElement {
|
|||||||
// Not all responses will be JSON
|
// Not all responses will be JSON
|
||||||
responseObj = response;
|
responseObj = response;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Respond to app
|
// Respond to app
|
||||||
if (responseObj.error != null) {
|
if (responseObj.error != null) {
|
||||||
event.ports[0].postMessage({
|
event.ports[0].postMessage({
|
||||||
@ -1050,6 +1196,7 @@ async function showModalAndWait(type, data) {
|
|||||||
${type === actions.GET_USER_ACCOUNT ? `<p class="modal-paragraph">${get("browserpage.bchange18")}</p>` : ''}
|
${type === actions.GET_USER_ACCOUNT ? `<p class="modal-paragraph">${get("browserpage.bchange18")}</p>` : ''}
|
||||||
${type === actions.PUBLISH_QDN_RESOURCE ? `<p class="modal-paragraph">${get("browserpage.bchange19")}</p>` : ''}
|
${type === actions.PUBLISH_QDN_RESOURCE ? `<p class="modal-paragraph">${get("browserpage.bchange19")}</p>` : ''}
|
||||||
${type === actions.GET_WALLET_BALANCE ? `<p class="modal-paragraph">${get("browserpage.bchange20")}</p>` : ''}
|
${type === actions.GET_WALLET_BALANCE ? `<p class="modal-paragraph">${get("browserpage.bchange20")}</p>` : ''}
|
||||||
|
${type === actions.SEND_CHAT_MESSAGE ? `<p class="modal-paragraph">${get("browserpage.bchange22")}</p>` : ''}
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-buttons">
|
<div class="modal-buttons">
|
||||||
<button id="cancel-button">Reject</button>
|
<button id="cancel-button">Reject</button>
|
||||||
|
@ -0,0 +1,82 @@
|
|||||||
|
import { Sha256 } from 'asmcrypto.js'
|
||||||
|
|
||||||
|
|
||||||
|
function sbrk(size, heap){
|
||||||
|
let brk = 512 * 1024 // stack top
|
||||||
|
let old = brk
|
||||||
|
brk += size
|
||||||
|
|
||||||
|
if (brk > heap.length)
|
||||||
|
throw new Error('heap exhausted')
|
||||||
|
|
||||||
|
return old
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
self.addEventListener('message', async e => {
|
||||||
|
const response = await computePow(e.data.chatBytes, e.data.path, e.data.difficulty)
|
||||||
|
postMessage(response)
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
const memory = new WebAssembly.Memory({ initial: 256, maximum: 256 })
|
||||||
|
const heap = new Uint8Array(memory.buffer)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const computePow = async (chatBytes, path, difficulty) => {
|
||||||
|
|
||||||
|
let response = null
|
||||||
|
|
||||||
|
await new Promise((resolve, reject)=> {
|
||||||
|
|
||||||
|
const _chatBytesArray = Object.keys(chatBytes).map(function (key) { return chatBytes[key]; });
|
||||||
|
const chatBytesArray = new Uint8Array(_chatBytesArray);
|
||||||
|
const chatBytesHash = new Sha256().process(chatBytesArray).finish().result;
|
||||||
|
const hashPtr = sbrk(32, heap);
|
||||||
|
const hashAry = new Uint8Array(memory.buffer, hashPtr, 32);
|
||||||
|
hashAry.set(chatBytesHash);
|
||||||
|
|
||||||
|
|
||||||
|
const workBufferLength = 8 * 1024 * 1024;
|
||||||
|
const workBufferPtr = sbrk(workBufferLength, heap);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const importObject = {
|
||||||
|
env: {
|
||||||
|
memory: memory
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
function loadWebAssembly(filename, imports) {
|
||||||
|
// Fetch the file and compile it
|
||||||
|
return fetch(filename)
|
||||||
|
.then(response => response.arrayBuffer())
|
||||||
|
.then(buffer => WebAssembly.compile(buffer))
|
||||||
|
.then(module => {
|
||||||
|
|
||||||
|
// Create the instance.
|
||||||
|
return new WebAssembly.Instance(module, importObject);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
loadWebAssembly(path)
|
||||||
|
.then(wasmModule => {
|
||||||
|
response = {
|
||||||
|
nonce : wasmModule.exports.compute2(hashPtr, workBufferPtr, workBufferLength, difficulty),
|
||||||
|
chatBytesArray
|
||||||
|
}
|
||||||
|
|
||||||
|
resolve()
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
return response
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user