From 48af282ba05a8134cb5faf80424530b8b587ed8c Mon Sep 17 00:00:00 2001 From: Phillip Date: Sat, 18 Feb 2023 19:17:50 +0200 Subject: [PATCH] add publish-data function --- .../plugins/core/qdn/browser/browser.src.js | 34 ++++++- .../qdn/browser/computePowWorkerFile.src.js | 92 +++++++++++++++++++ .../plugins/utils/publish-image.js | 18 +++- 3 files changed, 140 insertions(+), 4 deletions(-) create mode 100644 qortal-ui-plugins/plugins/core/qdn/browser/computePowWorkerFile.src.js 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 c8aae815..8bb465b0 100644 --- a/qortal-ui-plugins/plugins/core/qdn/browser/browser.src.js +++ b/qortal-ui-plugins/plugins/core/qdn/browser/browser.src.js @@ -9,6 +9,8 @@ registerTranslateConfig({ import '@material/mwc-button' import '@material/mwc-icon' +import WebWorker from 'web-worker:./computePowWorkerFile.src.js'; +import {publishData} from '../../../utils/publish-image.js'; const parentEpml = new Epml({ type: 'WINDOW', source: window.parent }) @@ -277,12 +279,42 @@ class WebBrowser extends LitElement { case actions.PUBLISH_QDN_RESOURCE: // 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) { - data.identifier = "default"; + identifier = "default"; } + console.log('hello') const result = await showModalAndWait(actions.PUBLISH_QDN_RESOURCE); + console.log({result}) if (result.action === 'accept') { + const worker = new WebWorker(); + console.log({worker}) + try { + await publishData({ + registeredName: name, + file: data64, + service: service, + identifier: identifier, + parentEpml, + uploadType: 'file', + selectedAddress: this.selectedAddress, + worker: worker, + isBase64: true, + }); + + worker.terminate(); + } catch (error) { + worker.terminate(); + return + } + console.log('User accepted:', result.userData); } else if (result.action === 'reject') { console.log('User rejected'); diff --git a/qortal-ui-plugins/plugins/core/qdn/browser/computePowWorkerFile.src.js b/qortal-ui-plugins/plugins/core/qdn/browser/computePowWorkerFile.src.js new file mode 100644 index 00000000..d9f5f662 --- /dev/null +++ b/qortal-ui-plugins/plugins/core/qdn/browser/computePowWorkerFile.src.js @@ -0,0 +1,92 @@ +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.convertedBytes, e.data.path) + postMessage(response) + +}) + + +const memory = new WebAssembly.Memory({ initial: 256, maximum: 256 }) +const heap = new Uint8Array(memory.buffer) + + + +const computePow = async (convertedBytes, path) => { + + + let response = null + + await new Promise((resolve, reject)=> { + + const _convertedBytesArray = Object.keys(convertedBytes).map( + function (key) { + return convertedBytes[key] + } +) +const convertedBytesArray = new Uint8Array(_convertedBytesArray) +const convertedBytesHash = new Sha256() + .process(convertedBytesArray) + .finish().result +const hashPtr = sbrk(32, heap) +const hashAry = new Uint8Array( + memory.buffer, + hashPtr, + 32 +) + +hashAry.set(convertedBytesHash) +const difficulty = 14 +const workBufferLength = 8 * 1024 * 1024 +const workBufferPtr = sbrk( + workBufferLength, + heap +) + + const importObject = { + env: { + memory: memory + }, + }; + + function loadWebAssembly(filename, imports) { + return fetch(filename) + .then(response => response.arrayBuffer()) + .then(buffer => WebAssembly.compile(buffer)) + .then(module => { + return new WebAssembly.Instance(module, importObject); + }); +} + + +loadWebAssembly(path) + .then(wasmModule => { + response = { + nonce : wasmModule.exports.compute2(hashPtr, workBufferPtr, workBufferLength, difficulty), + + } + resolve() + + }); + + + }) + + return response +} \ No newline at end of file diff --git a/qortal-ui-plugins/plugins/utils/publish-image.js b/qortal-ui-plugins/plugins/utils/publish-image.js index 05594d1c..9f03644a 100644 --- a/qortal-ui-plugins/plugins/utils/publish-image.js +++ b/qortal-ui-plugins/plugins/utils/publish-image.js @@ -16,7 +16,9 @@ export const publishData = async ({ parentEpml, uploadType, selectedAddress, - worker + worker, + isBase64, + metaData }) => { const validateName = async (receiverName) => { let nameRes = await parentEpml.request("apiCall", { @@ -115,16 +117,26 @@ export const publishData = async ({ } // Base64 encode the file to work around compatibility issues between javascript and java byte arrays + if(isBase64){ + postBody = file + } + if(!isBase64){ let fileBuffer = new Uint8Array(await file.arrayBuffer()) postBody = Buffer.from(fileBuffer).toString("base64") + } + } - - let uploadDataUrl = `/arbitrary/${service}/${registeredName}${urlSuffix}?apiKey=${getApiKey()}` if (identifier != null && identifier.trim().length > 0) { uploadDataUrl = `/arbitrary/${service}/${registeredName}/${identifier}${urlSuffix}?apiKey=${getApiKey()}` + + if(metaData){ + uploadDataUrl = `/arbitrary/${service}/${registeredName}/${identifier}${urlSuffix}?${metaData}&apiKey=${getApiKey()}` + + } } + let uploadDataRes = await parentEpml.request("apiCall", { type: "api", method: "POST",