From 902a35253c6b424727c3dad19bfe636ebcd087a4 Mon Sep 17 00:00:00 2001 From: Paul Shapiro Date: Sat, 4 Aug 2018 22:32:43 -0400 Subject: [PATCH] updated MyMoneroCoreCpp.js build; cryptonote_utils: extracted destination formatting and money amount formatting to sendingFunds_utils and money_format_utils respectively, and added IPCsafe (string instead of JSBigInt params) create_transaction variant to support call from electron renderer procs etc, and added more complete load readiness waiting interface, and added locateFile impl for passing as emscripten Module template to locate wasm file in various environments; monero_cryptonote_utils_instance: detecting electron renderer and exposing via electron.remote call (will this cause issues with anyone's build systems trying to include electron\?); commenting logs --- cryptonote_utils/MyMoneroCoreCpp.js | 15 +- cryptonote_utils/cryptonote_utils.js | 293 ++++++++---------- cryptonote_utils/money_format_utils.js | 123 ++++++++ hostAPI/response_parser_utils.js | 28 +- monero_utils/monero_amount_format_utils.js | 35 +++ .../monero_cryptonote_utils_instance.js | 27 +- monero_utils/monero_sendingFunds_utils.js | 120 +++++-- tests/emjs/MyMoneroCoreCpp_int.node.js | 2 - tests/emjs/cryptonote_utils__int.node.js | 41 +++ tests/emjs/dummy-test-utils.js | 8 +- 10 files changed, 464 insertions(+), 228 deletions(-) create mode 100644 cryptonote_utils/money_format_utils.js create mode 100644 monero_utils/monero_amount_format_utils.js create mode 100644 tests/emjs/cryptonote_utils__int.node.js diff --git a/cryptonote_utils/MyMoneroCoreCpp.js b/cryptonote_utils/MyMoneroCoreCpp.js index 567afd3..94d9116 100644 --- a/cryptonote_utils/MyMoneroCoreCpp.js +++ b/cryptonote_utils/MyMoneroCoreCpp.js @@ -1,17 +1,20 @@ -var MyMoneroCoreCpp = function(MyMoneroCoreCpp) { + +var MyMoneroCoreCpp = (function() { + var _scriptDir = typeof document !== 'undefined' && document.currentScript ? document.currentScript.src : undefined; + return ( +function(MyMoneroCoreCpp) { MyMoneroCoreCpp = MyMoneroCoreCpp || {}; -var Module=typeof MyMoneroCoreCpp!=="undefined"?MyMoneroCoreCpp:{};var moduleOverrides={};var key;for(key in Module){if(Module.hasOwnProperty(key)){moduleOverrides[key]=Module[key]}}Module["arguments"]=[];Module["thisProgram"]="./this.program";Module["quit"]=(function(status,toThrow){throw toThrow});Module["preRun"]=[];Module["postRun"]=[];var ENVIRONMENT_IS_WEB=false;var ENVIRONMENT_IS_WORKER=false;var ENVIRONMENT_IS_NODE=false;var ENVIRONMENT_IS_SHELL=false;ENVIRONMENT_IS_WEB=typeof window==="object";ENVIRONMENT_IS_WORKER=typeof importScripts==="function";ENVIRONMENT_IS_NODE=typeof process==="object"&&typeof require==="function"&&!ENVIRONMENT_IS_WEB&&!ENVIRONMENT_IS_WORKER;ENVIRONMENT_IS_SHELL=!ENVIRONMENT_IS_WEB&&!ENVIRONMENT_IS_NODE&&!ENVIRONMENT_IS_WORKER;if(Module["ENVIRONMENT"]){throw new Error("Module.ENVIRONMENT has been deprecated. To force the environment, use the ENVIRONMENT compile-time option (for example, -s ENVIRONMENT=web or -s ENVIRONMENT=node)")}assert(typeof Module["memoryInitializerPrefixURL"]==="undefined","Module.memoryInitializerPrefixURL option was removed, use Module.locateFile instead");assert(typeof Module["pthreadMainPrefixURL"]==="undefined","Module.pthreadMainPrefixURL option was removed, use Module.locateFile instead");assert(typeof Module["cdInitializerPrefixURL"]==="undefined","Module.cdInitializerPrefixURL option was removed, use Module.locateFile instead");assert(typeof Module["filePackagePrefixURL"]==="undefined","Module.filePackagePrefixURL option was removed, use Module.locateFile instead");var scriptDirectory="";if(ENVIRONMENT_IS_NODE){scriptDirectory=__dirname+"/"}if(ENVIRONMENT_IS_WEB){var currentScript=this["_currentScript"]||document.currentScript;if(currentScript.src.indexOf("blob:")!==0){scriptDirectory=currentScript.src.split("/").slice(0,-1).join("/")+"/"}}else if(ENVIRONMENT_IS_WORKER){scriptDirectory=self.location.href.split("/").slice(0,-1).join("/")+"/"}Module._locateFile=(function(path){if(Module["locateFile"]){return Module["locateFile"](path,scriptDirectory)}else{return scriptDirectory+path}});if(ENVIRONMENT_IS_NODE){var nodeFS;var nodePath;Module["read"]=function shell_read(filename,binary){var ret;if(!nodeFS)nodeFS=require("fs");if(!nodePath)nodePath=require("path");filename=nodePath["normalize"](filename);ret=nodeFS["readFileSync"](filename);return binary?ret:ret.toString()};Module["readBinary"]=function readBinary(filename){var ret=Module["read"](filename,true);if(!ret.buffer){ret=new Uint8Array(ret)}assert(ret.buffer);return ret};if(process["argv"].length>1){Module["thisProgram"]=process["argv"][1].replace(/\\/g,"/")}Module["arguments"]=process["argv"].slice(2);process["on"]("uncaughtException",(function(ex){if(!(ex instanceof ExitStatus)){throw ex}}));process["on"]("unhandledRejection",(function(reason,p){err("node.js exiting due to unhandled promise rejection");process["exit"](1)}));Module["quit"]=(function(status){process["exit"](status)});Module["inspect"]=(function(){return"[Emscripten Module object]"})}else if(ENVIRONMENT_IS_SHELL){if(typeof read!="undefined"){Module["read"]=function shell_read(f){return read(f)}}Module["readBinary"]=function readBinary(f){var data;if(typeof readbuffer==="function"){return new Uint8Array(readbuffer(f))}data=read(f,"binary");assert(typeof data==="object");return data};if(typeof scriptArgs!="undefined"){Module["arguments"]=scriptArgs}else if(typeof arguments!="undefined"){Module["arguments"]=arguments}if(typeof quit==="function"){Module["quit"]=(function(status){quit(status)})}}else if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){Module["read"]=function shell_read(url){var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.send(null);return xhr.responseText};if(ENVIRONMENT_IS_WORKER){Module["readBinary"]=function readBinary(url){var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.responseType="arraybuffer";xhr.send(null);return new Uint8Array(xhr.response)}}Module["readAsync"]=function readAsync(url,onload,onerror){var xhr=new XMLHttpRequest;xhr.open("GET",url,true);xhr.responseType="arraybuffer";xhr.onload=function xhr_onload(){if(xhr.status==200||xhr.status==0&&xhr.response){onload(xhr.response);return}onerror()};xhr.onerror=onerror;xhr.send(null)};Module["setWindowTitle"]=(function(title){document.title=title})}else{throw new Error("environment detection error")}var out=Module["print"]||(typeof console!=="undefined"?console.log.bind(console):typeof print!=="undefined"?print:null);var err=Module["printErr"]||(typeof printErr!=="undefined"?printErr:typeof console!=="undefined"&&console.warn.bind(console)||out);for(key in moduleOverrides){if(moduleOverrides.hasOwnProperty(key)){Module[key]=moduleOverrides[key]}}moduleOverrides=undefined;var STACK_ALIGN=16;stackSave=stackRestore=stackAlloc=setTempRet0=getTempRet0=(function(){abort("cannot use the stack before compiled code is ready to run, and has provided stack access")});function staticAlloc(size){assert(!staticSealed);var ret=STATICTOP;STATICTOP=STATICTOP+size+15&-16;assert(STATICTOP>2];var end=ret+size+15&-16;HEAP32[DYNAMICTOP_PTR>>2]=end;if(end>=TOTAL_MEMORY){var success=enlargeMemory();if(!success){HEAP32[DYNAMICTOP_PTR>>2]=ret;return 0}}return ret}function alignMemory(size,factor){if(!factor)factor=STACK_ALIGN;var ret=size=Math.ceil(size/factor)*factor;return ret}function warnOnce(text){if(!warnOnce.shown)warnOnce.shown={};if(!warnOnce.shown[text]){warnOnce.shown[text]=1;err(text)}}var asm2wasmImports={"f64-rem":(function(x,y){return x%y}),"debugger":(function(){debugger})};var functionPointers=new Array(0);var GLOBAL_BASE=1024;var ABORT=0;var EXITSTATUS=0;function assert(condition,text){if(!condition){abort("Assertion failed: "+text)}}function getCFunc(ident){var func=Module["_"+ident];assert(func,"Cannot call unknown function "+ident+", make sure it is exported");return func}var JSfuncs={"stackSave":(function(){stackSave()}),"stackRestore":(function(){stackRestore()}),"arrayToC":(function(arr){var ret=stackAlloc(arr.length);writeArrayToMemory(arr,ret);return ret}),"stringToC":(function(str){var ret=0;if(str!==null&&str!==undefined&&str!==0){var len=(str.length<<2)+1;ret=stackAlloc(len);stringToUTF8(str,ret,len)}return ret})};var toC={"string":JSfuncs["stringToC"],"array":JSfuncs["arrayToC"]};function ccall(ident,returnType,argTypes,args,opts){function convertReturnValue(ret){if(returnType==="string")return Pointer_stringify(ret);if(returnType==="boolean")return Boolean(ret);return ret}var func=getCFunc(ident);var cArgs=[];var stack=0;assert(returnType!=="array",'Return type should not be "array".');if(args){for(var i=0;i>0];hasUtf|=t;if(t==0&&!length)break;i++;if(length&&i==length)break}if(!length)length=i;var ret="";if(hasUtf<128){var MAX_CHUNK=1024;var curr;while(length>0){curr=String.fromCharCode.apply(String,HEAPU8.subarray(ptr,ptr+Math.min(length,MAX_CHUNK)));ret=ret?ret+curr:curr;ptr+=MAX_CHUNK;length-=MAX_CHUNK}return ret}return UTF8ToString(ptr)}var UTF8Decoder=typeof TextDecoder!=="undefined"?new TextDecoder("utf8"):undefined;function UTF8ArrayToString(u8Array,idx){var endPtr=idx;while(u8Array[endPtr])++endPtr;if(endPtr-idx>16&&u8Array.subarray&&UTF8Decoder){return UTF8Decoder.decode(u8Array.subarray(idx,endPtr))}else{var u0,u1,u2,u3,u4,u5;var str="";while(1){u0=u8Array[idx++];if(!u0)return str;if(!(u0&128)){str+=String.fromCharCode(u0);continue}u1=u8Array[idx++]&63;if((u0&224)==192){str+=String.fromCharCode((u0&31)<<6|u1);continue}u2=u8Array[idx++]&63;if((u0&240)==224){u0=(u0&15)<<12|u1<<6|u2}else{u3=u8Array[idx++]&63;if((u0&248)==240){u0=(u0&7)<<18|u1<<12|u2<<6|u3}else{u4=u8Array[idx++]&63;if((u0&252)==248){u0=(u0&3)<<24|u1<<18|u2<<12|u3<<6|u4}else{u5=u8Array[idx++]&63;u0=(u0&1)<<30|u1<<24|u2<<18|u3<<12|u4<<6|u5}}}if(u0<65536){str+=String.fromCharCode(u0)}else{var ch=u0-65536;str+=String.fromCharCode(55296|ch>>10,56320|ch&1023)}}}}function UTF8ToString(ptr){return UTF8ArrayToString(HEAPU8,ptr)}function stringToUTF8Array(str,outU8Array,outIdx,maxBytesToWrite){if(!(maxBytesToWrite>0))return 0;var startIdx=outIdx;var endIdx=outIdx+maxBytesToWrite-1;for(var i=0;i=55296&&u<=57343)u=65536+((u&1023)<<10)|str.charCodeAt(++i)&1023;if(u<=127){if(outIdx>=endIdx)break;outU8Array[outIdx++]=u}else if(u<=2047){if(outIdx+1>=endIdx)break;outU8Array[outIdx++]=192|u>>6;outU8Array[outIdx++]=128|u&63}else if(u<=65535){if(outIdx+2>=endIdx)break;outU8Array[outIdx++]=224|u>>12;outU8Array[outIdx++]=128|u>>6&63;outU8Array[outIdx++]=128|u&63}else if(u<=2097151){if(outIdx+3>=endIdx)break;outU8Array[outIdx++]=240|u>>18;outU8Array[outIdx++]=128|u>>12&63;outU8Array[outIdx++]=128|u>>6&63;outU8Array[outIdx++]=128|u&63}else if(u<=67108863){if(outIdx+4>=endIdx)break;outU8Array[outIdx++]=248|u>>24;outU8Array[outIdx++]=128|u>>18&63;outU8Array[outIdx++]=128|u>>12&63;outU8Array[outIdx++]=128|u>>6&63;outU8Array[outIdx++]=128|u&63}else{if(outIdx+5>=endIdx)break;outU8Array[outIdx++]=252|u>>30;outU8Array[outIdx++]=128|u>>24&63;outU8Array[outIdx++]=128|u>>18&63;outU8Array[outIdx++]=128|u>>12&63;outU8Array[outIdx++]=128|u>>6&63;outU8Array[outIdx++]=128|u&63}}outU8Array[outIdx]=0;return outIdx-startIdx}function stringToUTF8(str,outPtr,maxBytesToWrite){assert(typeof maxBytesToWrite=="number","stringToUTF8(str, outPtr, maxBytesToWrite) is missing the third parameter that specifies the length of the output buffer!");return stringToUTF8Array(str,HEAPU8,outPtr,maxBytesToWrite)}var UTF16Decoder=typeof TextDecoder!=="undefined"?new TextDecoder("utf-16le"):undefined;function demangle(func){warnOnce("warning: build with -s DEMANGLE_SUPPORT=1 to link in libcxxabi demangling");return func}function demangleAll(text){var regex=/__Z[\w\d_]+/g;return text.replace(regex,(function(x){var y=demangle(x);return x===y?x:x+" ["+y+"]"}))}function jsStackTrace(){var err=new Error;if(!err.stack){try{throw new Error(0)}catch(e){err=e}if(!err.stack){return"(no stack trace available)"}}return err.stack.toString()}function stackTrace(){var js=jsStackTrace();if(Module["extraStackTrace"])js+="\n"+Module["extraStackTrace"]();return demangleAll(js)}var WASM_PAGE_SIZE=65536;var ASMJS_PAGE_SIZE=16777216;function alignUp(x,multiple){if(x%multiple>0){x+=multiple-x%multiple}return x}var buffer,HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64;function updateGlobalBuffer(buf){Module["buffer"]=buffer=buf}function updateGlobalBufferViews(){Module["HEAP8"]=HEAP8=new Int8Array(buffer);Module["HEAP16"]=HEAP16=new Int16Array(buffer);Module["HEAP32"]=HEAP32=new Int32Array(buffer);Module["HEAPU8"]=HEAPU8=new Uint8Array(buffer);Module["HEAPU16"]=HEAPU16=new Uint16Array(buffer);Module["HEAPU32"]=HEAPU32=new Uint32Array(buffer);Module["HEAPF32"]=HEAPF32=new Float32Array(buffer);Module["HEAPF64"]=HEAPF64=new Float64Array(buffer)}var STATIC_BASE,STATICTOP,staticSealed;var STACK_BASE,STACKTOP,STACK_MAX;var DYNAMIC_BASE,DYNAMICTOP_PTR;STATIC_BASE=STATICTOP=STACK_BASE=STACKTOP=STACK_MAX=DYNAMIC_BASE=DYNAMICTOP_PTR=0;staticSealed=false;function writeStackCookie(){assert((STACK_MAX&3)==0);HEAPU32[(STACK_MAX>>2)-1]=34821223;HEAPU32[(STACK_MAX>>2)-2]=2310721022}function checkStackCookie(){if(HEAPU32[(STACK_MAX>>2)-1]!=34821223||HEAPU32[(STACK_MAX>>2)-2]!=2310721022){abort("Stack overflow! Stack cookie has been overwritten, expected hex dwords 0x89BACDFE and 0x02135467, but received 0x"+HEAPU32[(STACK_MAX>>2)-2].toString(16)+" "+HEAPU32[(STACK_MAX>>2)-1].toString(16))}if(HEAP32[0]!==1668509029)throw"Runtime error: The application has corrupted its heap memory area (address zero)!"}function abortStackOverflow(allocSize){abort("Stack overflow! Attempted to allocate "+allocSize+" bytes on the stack, but stack has only "+(STACK_MAX-stackSave()+allocSize)+" bytes available!")}function abortOnCannotGrowMemory(){abort("Cannot enlarge memory arrays. Either (1) compile with -s TOTAL_MEMORY=X with X higher than the current value "+TOTAL_MEMORY+", (2) compile with -s ALLOW_MEMORY_GROWTH=1 which allows increasing the size at runtime, or (3) if you want malloc to return NULL (0) instead of this abort, compile with -s ABORTING_MALLOC=0 ")}function enlargeMemory(){abortOnCannotGrowMemory()}var TOTAL_STACK=Module["TOTAL_STACK"]||5242880;var TOTAL_MEMORY=Module["TOTAL_MEMORY"]||16777216;if(TOTAL_MEMORY0){var callback=callbacks.shift();if(typeof callback=="function"){callback();continue}var func=callback.func;if(typeof func==="number"){if(callback.arg===undefined){Module["dynCall_v"](func)}else{Module["dynCall_vi"](func,callback.arg)}}else{func(callback.arg===undefined?null:callback.arg)}}}var __ATPRERUN__=[];var __ATINIT__=[];var __ATMAIN__=[];var __ATPOSTRUN__=[];var runtimeInitialized=false;var runtimeExited=false;function preRun(){if(Module["preRun"]){if(typeof Module["preRun"]=="function")Module["preRun"]=[Module["preRun"]];while(Module["preRun"].length){addOnPreRun(Module["preRun"].shift())}}callRuntimeCallbacks(__ATPRERUN__)}function ensureInitRuntime(){checkStackCookie();if(runtimeInitialized)return;runtimeInitialized=true;callRuntimeCallbacks(__ATINIT__)}function preMain(){checkStackCookie();callRuntimeCallbacks(__ATMAIN__)}function postRun(){checkStackCookie();if(Module["postRun"]){if(typeof Module["postRun"]=="function")Module["postRun"]=[Module["postRun"]];while(Module["postRun"].length){addOnPostRun(Module["postRun"].shift())}}callRuntimeCallbacks(__ATPOSTRUN__)}function addOnPreRun(cb){__ATPRERUN__.unshift(cb)}function addOnPostRun(cb){__ATPOSTRUN__.unshift(cb)}function writeArrayToMemory(array,buffer){assert(array.length>=0,"writeArrayToMemory array must have a length (should be an array or typed array)");HEAP8.set(array,buffer)}function writeAsciiToMemory(str,buffer,dontAddNull){for(var i=0;i>0]=str.charCodeAt(i)}if(!dontAddNull)HEAP8[buffer>>0]=0}assert(Math["imul"]&&Math["fround"]&&Math["clz32"]&&Math["trunc"],"this is a legacy browser, build with LEGACY_VM_SUPPORT");var runDependencies=0;var runDependencyWatcher=null;var dependenciesFulfilled=null;var runDependencyTracking={};function addRunDependency(id){runDependencies++;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}if(id){assert(!runDependencyTracking[id]);runDependencyTracking[id]=1;if(runDependencyWatcher===null&&typeof setInterval!=="undefined"){runDependencyWatcher=setInterval((function(){if(ABORT){clearInterval(runDependencyWatcher);runDependencyWatcher=null;return}var shown=false;for(var dep in runDependencyTracking){if(!shown){shown=true;err("still waiting on run dependencies:")}err("dependency: "+dep)}if(shown){err("(end of list)")}}),1e4)}}else{err("warning: run dependency added without ID")}}function removeRunDependency(id){runDependencies--;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}if(id){assert(runDependencyTracking[id]);delete runDependencyTracking[id]}else{err("warning: run dependency removed without ID")}if(runDependencies==0){if(runDependencyWatcher!==null){clearInterval(runDependencyWatcher);runDependencyWatcher=null}if(dependenciesFulfilled){var callback=dependenciesFulfilled;dependenciesFulfilled=null;callback()}}}Module["preloadedImages"]={};Module["preloadedAudios"]={};var FS={error:(function(){abort("Filesystem support (FS) was not included. The problem is that you are using files from JS, but files were not used from C/C++, so filesystem support was not auto-included. You can force-include filesystem support with -s FORCE_FILESYSTEM=1")}),init:(function(){FS.error()}),createDataFile:(function(){FS.error()}),createPreloadedFile:(function(){FS.error()}),createLazyFile:(function(){FS.error()}),open:(function(){FS.error()}),mkdev:(function(){FS.error()}),registerDevice:(function(){FS.error()}),analyzePath:(function(){FS.error()}),loadFilesFromDB:(function(){FS.error()}),ErrnoError:function ErrnoError(){FS.error()}};Module["FS_createDataFile"]=FS.createDataFile;Module["FS_createPreloadedFile"]=FS.createPreloadedFile;var dataURIPrefix="data:application/octet-stream;base64,";function isDataURI(filename){return String.prototype.startsWith?filename.startsWith(dataURIPrefix):filename.indexOf(dataURIPrefix)===0}function integrateWasmJS(){var wasmTextFile="MyMoneroCoreCpp.wast";var wasmBinaryFile="MyMoneroCoreCpp.wasm";var asmjsCodeFile="MyMoneroCoreCpp.temp.asm.js";if(!isDataURI(wasmTextFile)){wasmTextFile=Module._locateFile(wasmTextFile)}if(!isDataURI(wasmBinaryFile)){wasmBinaryFile=Module._locateFile(wasmBinaryFile)}if(!isDataURI(asmjsCodeFile)){asmjsCodeFile=Module._locateFile(asmjsCodeFile)}var wasmPageSize=64*1024;var info={"global":null,"env":null,"asm2wasm":asm2wasmImports,"parent":Module};var exports=null;function mergeMemory(newBuffer){var oldBuffer=Module["buffer"];if(newBuffer.byteLength>2]=poolPtr;HEAP32[environ>>2]=envPtr}else{envPtr=HEAP32[environ>>2];poolPtr=HEAP32[envPtr>>2]}var strings=[];var totalSize=0;for(var key in ENV){if(typeof ENV[key]==="string"){var line=key+"="+ENV[key];strings.push(line);totalSize+=line.length}}if(totalSize>TOTAL_ENV_SIZE){throw new Error("Environment size exceeded TOTAL_ENV_SIZE!")}var ptrSize=4;for(var i=0;i>2]=poolPtr;poolPtr+=line.length+1}HEAP32[envPtr+strings.length*ptrSize>>2]=0}var EXCEPTIONS={last:0,caught:[],infos:{},deAdjust:(function(adjusted){if(!adjusted||EXCEPTIONS.infos[adjusted])return adjusted;for(var key in EXCEPTIONS.infos){var ptr=+key;var info=EXCEPTIONS.infos[ptr];if(info.adjusted===adjusted){return ptr}}return adjusted}),addRef:(function(ptr){if(!ptr)return;var info=EXCEPTIONS.infos[ptr];info.refcount++}),decRef:(function(ptr){if(!ptr)return;var info=EXCEPTIONS.infos[ptr];assert(info.refcount>0);info.refcount--;if(info.refcount===0&&!info.rethrown){if(info.destructor){Module["dynCall_vi"](info.destructor,ptr)}delete EXCEPTIONS.infos[ptr];___cxa_free_exception(ptr)}}),clearRef:(function(ptr){if(!ptr)return;var info=EXCEPTIONS.infos[ptr];info.refcount=0})};function ___lock(){}var SYSCALLS={varargs:0,get:(function(varargs){SYSCALLS.varargs+=4;var ret=HEAP32[SYSCALLS.varargs-4>>2];return ret}),getStr:(function(){var ret=Pointer_stringify(SYSCALLS.get());return ret}),get64:(function(){var low=SYSCALLS.get(),high=SYSCALLS.get();if(low>=0)assert(high===0);else assert(high===-1);return low}),getZero:(function(){assert(SYSCALLS.get()===0)})};function ___syscall140(which,varargs){SYSCALLS.varargs=varargs;try{var stream=SYSCALLS.getStreamFromFD(),offset_high=SYSCALLS.get(),offset_low=SYSCALLS.get(),result=SYSCALLS.get(),whence=SYSCALLS.get();var offset=offset_low;FS.llseek(stream,offset,whence);HEAP32[result>>2]=stream.position;if(stream.getdents&&offset===0&&whence===0)stream.getdents=null;return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return-e.errno}}function ___syscall146(which,varargs){SYSCALLS.varargs=varargs;try{var stream=SYSCALLS.get(),iov=SYSCALLS.get(),iovcnt=SYSCALLS.get();var ret=0;if(!___syscall146.buffers){___syscall146.buffers=[null,[],[]];___syscall146.printChar=(function(stream,curr){var buffer=___syscall146.buffers[stream];assert(buffer);if(curr===0||curr===10){(stream===1?out:err)(UTF8ArrayToString(buffer,0));buffer.length=0}else{buffer.push(curr)}})}for(var i=0;i>2];var len=HEAP32[iov+(i*8+4)>>2];for(var j=0;j=char_0&&f<=char_9){return"_"+name}else{return name}}function createNamedFunction(name,body){name=makeLegalFunctionName(name);return(function(){"use strict";return body.apply(this,arguments)})}function extendError(baseErrorType,errorName){var errorClass=createNamedFunction(errorName,(function(message){this.name=errorName;this.message=message;var stack=(new Error(message)).stack;if(stack!==undefined){this.stack=this.toString()+"\n"+stack.replace(/^Error(:[^\n]*)?\n/,"")}}));errorClass.prototype=Object.create(baseErrorType.prototype);errorClass.prototype.constructor=errorClass;errorClass.prototype.toString=(function(){if(this.message===undefined){return this.name}else{return this.name+": "+this.message}});return errorClass}var BindingError=undefined;function throwBindingError(message){throw new BindingError(message)}var InternalError=undefined;function throwInternalError(message){throw new InternalError(message)}function whenDependentTypesAreResolved(myTypes,dependentTypes,getTypeConverters){myTypes.forEach((function(type){typeDependencies[type]=dependentTypes}));function onComplete(typeConverters){var myTypeConverters=getTypeConverters(typeConverters);if(myTypeConverters.length!==myTypes.length){throwInternalError("Mismatched type converter count")}for(var i=0;i>shift])}),destructorFunction:null})}var emval_free_list=[];var emval_handle_array=[{},{value:undefined},{value:null},{value:true},{value:false}];function __emval_decref(handle){if(handle>4&&0===--emval_handle_array[handle].refcount){emval_handle_array[handle]=undefined;emval_free_list.push(handle)}}function count_emval_handles(){var count=0;for(var i=5;i>2])}function __embind_register_emval(rawType,name){name=readLatin1String(name);registerType(rawType,{name:name,"fromWireType":(function(handle){var rv=emval_handle_array[handle].value;__emval_decref(handle);return rv}),"toWireType":(function(destructors,value){return __emval_register(value)}),"argPackAdvance":8,"readValueFromPointer":simpleReadValueFromPointer,destructorFunction:null})}function _embind_repr(v){if(v===null){return"null"}var t=typeof v;if(t==="object"||t==="array"||t==="function"){return v.toString()}else{return""+v}}function floatReadValueFromPointer(name,shift){switch(shift){case 2:return(function(pointer){return this["fromWireType"](HEAPF32[pointer>>2])});case 3:return(function(pointer){return this["fromWireType"](HEAPF64[pointer>>3])});default:throw new TypeError("Unknown float type: "+name)}}function __embind_register_float(rawType,name,size){var shift=getShiftFromSize(size);name=readLatin1String(name);registerType(rawType,{name:name,"fromWireType":(function(value){return value}),"toWireType":(function(destructors,value){if(typeof value!=="number"&&typeof value!=="boolean"){throw new TypeError('Cannot convert "'+_embind_repr(value)+'" to '+this.name)}return value}),"argPackAdvance":8,"readValueFromPointer":floatReadValueFromPointer(name,shift),destructorFunction:null})}function runDestructors(destructors){while(destructors.length){var ptr=destructors.pop();var del=destructors.pop();del(ptr)}}function craftInvokerFunction(humanName,argTypes,classType,cppInvokerFunc,cppTargetFunc){var argCount=argTypes.length;if(argCount<2){throwBindingError("argTypes array size mismatch! Must at least get return value and 'this' types!")}var isClassMethodFunc=argTypes[1]!==null&&classType!==null;var needsDestructorStack=false;for(var i=1;i>2)+i])}return array}function replacePublicSymbol(name,value,numArguments){if(!Module.hasOwnProperty(name)){throwInternalError("Replacing nonexistant public symbol")}if(undefined!==Module[name].overloadTable&&undefined!==numArguments){Module[name].overloadTable[numArguments]=value}else{Module[name]=value;Module[name].argCount=numArguments}}function embind__requireFunction(signature,rawFunction){signature=readLatin1String(signature);function makeDynCaller(dynCall){return(function(){var args=new Array(arguments.length+1);args[0]=rawFunction;for(var i=0;i>1]}:function readU16FromPointer(pointer){return HEAPU16[pointer>>1]};case 2:return signed?function readS32FromPointer(pointer){return HEAP32[pointer>>2]}:function readU32FromPointer(pointer){return HEAPU32[pointer>>2]};default:throw new TypeError("Unknown integer type: "+name)}}function __embind_register_integer(primitiveType,name,size,minRange,maxRange){name=readLatin1String(name);if(maxRange===-1){maxRange=4294967295}var shift=getShiftFromSize(size);var fromWireType=(function(value){return value});if(minRange===0){var bitshift=32-8*size;fromWireType=(function(value){return value<>>bitshift})}var isUnsignedType=name.indexOf("unsigned")!=-1;registerType(primitiveType,{name:name,"fromWireType":fromWireType,"toWireType":(function(destructors,value){if(typeof value!=="number"&&typeof value!=="boolean"){throw new TypeError('Cannot convert "'+_embind_repr(value)+'" to '+this.name)}if(valuemaxRange){throw new TypeError('Passing a number "'+_embind_repr(value)+'" from JS side to C/C++ side to an argument of type "'+name+'", which is outside the valid range ['+minRange+", "+maxRange+"]!")}return isUnsignedType?value>>>0:value|0}),"argPackAdvance":8,"readValueFromPointer":integerReadValueFromPointer(name,shift,minRange!==0),destructorFunction:null})}function __embind_register_memory_view(rawType,dataTypeIndex,name){var typeMapping=[Int8Array,Uint8Array,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array];var TA=typeMapping[dataTypeIndex];function decodeMemoryView(handle){handle=handle>>2;var heap=HEAPU32;var size=heap[handle];var data=heap[handle+1];return new TA(heap["buffer"],data,size)}name=readLatin1String(name);registerType(rawType,{name:name,"fromWireType":decodeMemoryView,"argPackAdvance":8,"readValueFromPointer":decodeMemoryView},{ignoreDuplicateRegistrations:true})}function __embind_register_std_string(rawType,name){name=readLatin1String(name);registerType(rawType,{name:name,"fromWireType":(function(value){var length=HEAPU32[value>>2];var a=new Array(length);for(var i=0;i>2]=length;for(var i=0;i255){_free(ptr);throwBindingError("String has UTF-16 code units that do not fit in 8 bits")}HEAPU8[ptr+4+i]=charCode}if(destructors!==null){destructors.push(_free,ptr)}return ptr}),"argPackAdvance":8,"readValueFromPointer":simpleReadValueFromPointer,destructorFunction:(function(ptr){_free(ptr)})})}function __embind_register_std_wstring(rawType,charSize,name){name=readLatin1String(name);var getHeap,shift;if(charSize===2){getHeap=(function(){return HEAPU16});shift=1}else if(charSize===4){getHeap=(function(){return HEAPU32});shift=2}registerType(rawType,{name:name,"fromWireType":(function(value){var HEAP=getHeap();var length=HEAPU32[value>>2];var a=new Array(length);var start=value+4>>shift;for(var i=0;i>2]=length;var start=ptr+4>>shift;for(var i=0;i>2]=value;else err("failed to set errno from JS");return value}embind_init_charCodes();BindingError=Module["BindingError"]=extendError(Error,"BindingError");InternalError=Module["InternalError"]=extendError(Error,"InternalError");init_emval();UnboundTypeError=Module["UnboundTypeError"]=extendError(Error,"UnboundTypeError");DYNAMICTOP_PTR=staticAlloc(4);STACK_BASE=STACKTOP=alignMemory(STATICTOP);STACK_MAX=STACK_BASE+TOTAL_STACK;DYNAMIC_BASE=alignMemory(STACK_MAX);HEAP32[DYNAMICTOP_PTR>>2]=DYNAMIC_BASE;staticSealed=true;assert(DYNAMIC_BASE0){return}writeStackCookie();preRun();if(runDependencies>0)return;if(Module["calledRun"])return;function doRun(){if(Module["calledRun"])return;Module["calledRun"]=true;if(ABORT)return;ensureInitRuntime();preMain();if(Module["onRuntimeInitialized"])Module["onRuntimeInitialized"]();assert(!Module["_main"],'compiled without a main, but one is present. if you added it from JS, use Module["onRuntimeInitialized"]');postRun()}if(Module["setStatus"]){Module["setStatus"]("Running...");setTimeout((function(){setTimeout((function(){Module["setStatus"]("")}),1);doRun()}),1)}else{doRun()}checkStackCookie()}Module["run"]=run;var abortDecorators=[];function abort(what){if(Module["onAbort"]){Module["onAbort"](what)}if(what!==undefined){out(what);err(what);what=JSON.stringify(what)}else{what=""}ABORT=true;EXITSTATUS=1;var extra="";var output="abort("+what+") at "+stackTrace()+extra;if(abortDecorators){abortDecorators.forEach((function(decorator){output=decorator(output,what)}))}throw output}Module["abort"]=abort;if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].pop()()}}Module["noExitRuntime"]=true;run() +var Module=typeof MyMoneroCoreCpp!=="undefined"?MyMoneroCoreCpp:{};var moduleOverrides={};var key;for(key in Module){if(Module.hasOwnProperty(key)){moduleOverrides[key]=Module[key]}}Module["arguments"]=[];Module["thisProgram"]="./this.program";Module["quit"]=(function(status,toThrow){throw toThrow});Module["preRun"]=[];Module["postRun"]=[];var ENVIRONMENT_IS_WEB=false;var ENVIRONMENT_IS_WORKER=false;var ENVIRONMENT_IS_NODE=false;var ENVIRONMENT_IS_SHELL=false;ENVIRONMENT_IS_WEB=typeof window==="object";ENVIRONMENT_IS_WORKER=typeof importScripts==="function";ENVIRONMENT_IS_NODE=typeof process==="object"&&typeof require==="function"&&!ENVIRONMENT_IS_WEB&&!ENVIRONMENT_IS_WORKER;ENVIRONMENT_IS_SHELL=!ENVIRONMENT_IS_WEB&&!ENVIRONMENT_IS_NODE&&!ENVIRONMENT_IS_WORKER;if(Module["ENVIRONMENT"]){throw new Error("Module.ENVIRONMENT has been deprecated. To force the environment, use the ENVIRONMENT compile-time option (for example, -s ENVIRONMENT=web or -s ENVIRONMENT=node)")}assert(typeof Module["memoryInitializerPrefixURL"]==="undefined","Module.memoryInitializerPrefixURL option was removed, use Module.locateFile instead");assert(typeof Module["pthreadMainPrefixURL"]==="undefined","Module.pthreadMainPrefixURL option was removed, use Module.locateFile instead");assert(typeof Module["cdInitializerPrefixURL"]==="undefined","Module.cdInitializerPrefixURL option was removed, use Module.locateFile instead");assert(typeof Module["filePackagePrefixURL"]==="undefined","Module.filePackagePrefixURL option was removed, use Module.locateFile instead");var scriptDirectory="";function locateFile(path){if(Module["locateFile"]){return Module["locateFile"](path,scriptDirectory)}else{return scriptDirectory+path}}if(ENVIRONMENT_IS_NODE){scriptDirectory=__dirname+"/";var nodeFS;var nodePath;Module["read"]=function shell_read(filename,binary){var ret;if(!nodeFS)nodeFS=require("fs");if(!nodePath)nodePath=require("path");filename=nodePath["normalize"](filename);ret=nodeFS["readFileSync"](filename);return binary?ret:ret.toString()};Module["readBinary"]=function readBinary(filename){var ret=Module["read"](filename,true);if(!ret.buffer){ret=new Uint8Array(ret)}assert(ret.buffer);return ret};if(process["argv"].length>1){Module["thisProgram"]=process["argv"][1].replace(/\\/g,"/")}Module["arguments"]=process["argv"].slice(2);process["on"]("uncaughtException",(function(ex){if(!(ex instanceof ExitStatus)){throw ex}}));process["on"]("unhandledRejection",(function(reason,p){err("node.js exiting due to unhandled promise rejection");process["exit"](1)}));Module["quit"]=(function(status){process["exit"](status)});Module["inspect"]=(function(){return"[Emscripten Module object]"})}else if(ENVIRONMENT_IS_SHELL){if(typeof read!="undefined"){Module["read"]=function shell_read(f){return read(f)}}Module["readBinary"]=function readBinary(f){var data;if(typeof readbuffer==="function"){return new Uint8Array(readbuffer(f))}data=read(f,"binary");assert(typeof data==="object");return data};if(typeof scriptArgs!="undefined"){Module["arguments"]=scriptArgs}else if(typeof arguments!="undefined"){Module["arguments"]=arguments}if(typeof quit==="function"){Module["quit"]=(function(status){quit(status)})}}else if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){if(ENVIRONMENT_IS_WEB){if(document.currentScript){scriptDirectory=document.currentScript.src}}else{scriptDirectory=self.location.href}if(_scriptDir){scriptDirectory=_scriptDir}if(scriptDirectory.indexOf("blob:")!==0){scriptDirectory=scriptDirectory.split("/").slice(0,-1).join("/")+"/"}else{scriptDirectory=""}Module["read"]=function shell_read(url){var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.send(null);return xhr.responseText};if(ENVIRONMENT_IS_WORKER){Module["readBinary"]=function readBinary(url){var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.responseType="arraybuffer";xhr.send(null);return new Uint8Array(xhr.response)}}Module["readAsync"]=function readAsync(url,onload,onerror){var xhr=new XMLHttpRequest;xhr.open("GET",url,true);xhr.responseType="arraybuffer";xhr.onload=function xhr_onload(){if(xhr.status==200||xhr.status==0&&xhr.response){onload(xhr.response);return}onerror()};xhr.onerror=onerror;xhr.send(null)};Module["setWindowTitle"]=(function(title){document.title=title})}else{throw new Error("environment detection error")}var out=Module["print"]||(typeof console!=="undefined"?console.log.bind(console):typeof print!=="undefined"?print:null);var err=Module["printErr"]||(typeof printErr!=="undefined"?printErr:typeof console!=="undefined"&&console.warn.bind(console)||out);for(key in moduleOverrides){if(moduleOverrides.hasOwnProperty(key)){Module[key]=moduleOverrides[key]}}moduleOverrides=undefined;var STACK_ALIGN=16;stackSave=stackRestore=stackAlloc=setTempRet0=getTempRet0=(function(){abort("cannot use the stack before compiled code is ready to run, and has provided stack access")});function staticAlloc(size){assert(!staticSealed);var ret=STATICTOP;STATICTOP=STATICTOP+size+15&-16;assert(STATICTOP>2];var end=ret+size+15&-16;HEAP32[DYNAMICTOP_PTR>>2]=end;if(end>=TOTAL_MEMORY){var success=enlargeMemory();if(!success){HEAP32[DYNAMICTOP_PTR>>2]=ret;return 0}}return ret}function alignMemory(size,factor){if(!factor)factor=STACK_ALIGN;var ret=size=Math.ceil(size/factor)*factor;return ret}function warnOnce(text){if(!warnOnce.shown)warnOnce.shown={};if(!warnOnce.shown[text]){warnOnce.shown[text]=1;err(text)}}var asm2wasmImports={"f64-rem":(function(x,y){return x%y}),"debugger":(function(){debugger})};var functionPointers=new Array(0);var GLOBAL_BASE=1024;var ABORT=0;var EXITSTATUS=0;function assert(condition,text){if(!condition){abort("Assertion failed: "+text)}}function getCFunc(ident){var func=Module["_"+ident];assert(func,"Cannot call unknown function "+ident+", make sure it is exported");return func}var JSfuncs={"stackSave":(function(){stackSave()}),"stackRestore":(function(){stackRestore()}),"arrayToC":(function(arr){var ret=stackAlloc(arr.length);writeArrayToMemory(arr,ret);return ret}),"stringToC":(function(str){var ret=0;if(str!==null&&str!==undefined&&str!==0){var len=(str.length<<2)+1;ret=stackAlloc(len);stringToUTF8(str,ret,len)}return ret})};var toC={"string":JSfuncs["stringToC"],"array":JSfuncs["arrayToC"]};function ccall(ident,returnType,argTypes,args,opts){function convertReturnValue(ret){if(returnType==="string")return Pointer_stringify(ret);if(returnType==="boolean")return Boolean(ret);return ret}var func=getCFunc(ident);var cArgs=[];var stack=0;assert(returnType!=="array",'Return type should not be "array".');if(args){for(var i=0;i>0];hasUtf|=t;if(t==0&&!length)break;i++;if(length&&i==length)break}if(!length)length=i;var ret="";if(hasUtf<128){var MAX_CHUNK=1024;var curr;while(length>0){curr=String.fromCharCode.apply(String,HEAPU8.subarray(ptr,ptr+Math.min(length,MAX_CHUNK)));ret=ret?ret+curr:curr;ptr+=MAX_CHUNK;length-=MAX_CHUNK}return ret}return UTF8ToString(ptr)}var UTF8Decoder=typeof TextDecoder!=="undefined"?new TextDecoder("utf8"):undefined;function UTF8ArrayToString(u8Array,idx){var endPtr=idx;while(u8Array[endPtr])++endPtr;if(endPtr-idx>16&&u8Array.subarray&&UTF8Decoder){return UTF8Decoder.decode(u8Array.subarray(idx,endPtr))}else{var u0,u1,u2,u3,u4,u5;var str="";while(1){u0=u8Array[idx++];if(!u0)return str;if(!(u0&128)){str+=String.fromCharCode(u0);continue}u1=u8Array[idx++]&63;if((u0&224)==192){str+=String.fromCharCode((u0&31)<<6|u1);continue}u2=u8Array[idx++]&63;if((u0&240)==224){u0=(u0&15)<<12|u1<<6|u2}else{u3=u8Array[idx++]&63;if((u0&248)==240){u0=(u0&7)<<18|u1<<12|u2<<6|u3}else{u4=u8Array[idx++]&63;if((u0&252)==248){u0=(u0&3)<<24|u1<<18|u2<<12|u3<<6|u4}else{u5=u8Array[idx++]&63;u0=(u0&1)<<30|u1<<24|u2<<18|u3<<12|u4<<6|u5}}}if(u0<65536){str+=String.fromCharCode(u0)}else{var ch=u0-65536;str+=String.fromCharCode(55296|ch>>10,56320|ch&1023)}}}}function UTF8ToString(ptr){return UTF8ArrayToString(HEAPU8,ptr)}function stringToUTF8Array(str,outU8Array,outIdx,maxBytesToWrite){if(!(maxBytesToWrite>0))return 0;var startIdx=outIdx;var endIdx=outIdx+maxBytesToWrite-1;for(var i=0;i=55296&&u<=57343){var u1=str.charCodeAt(++i);u=65536+((u&1023)<<10)|u1&1023}if(u<=127){if(outIdx>=endIdx)break;outU8Array[outIdx++]=u}else if(u<=2047){if(outIdx+1>=endIdx)break;outU8Array[outIdx++]=192|u>>6;outU8Array[outIdx++]=128|u&63}else if(u<=65535){if(outIdx+2>=endIdx)break;outU8Array[outIdx++]=224|u>>12;outU8Array[outIdx++]=128|u>>6&63;outU8Array[outIdx++]=128|u&63}else if(u<=2097151){if(outIdx+3>=endIdx)break;outU8Array[outIdx++]=240|u>>18;outU8Array[outIdx++]=128|u>>12&63;outU8Array[outIdx++]=128|u>>6&63;outU8Array[outIdx++]=128|u&63}else if(u<=67108863){if(outIdx+4>=endIdx)break;outU8Array[outIdx++]=248|u>>24;outU8Array[outIdx++]=128|u>>18&63;outU8Array[outIdx++]=128|u>>12&63;outU8Array[outIdx++]=128|u>>6&63;outU8Array[outIdx++]=128|u&63}else{if(outIdx+5>=endIdx)break;outU8Array[outIdx++]=252|u>>30;outU8Array[outIdx++]=128|u>>24&63;outU8Array[outIdx++]=128|u>>18&63;outU8Array[outIdx++]=128|u>>12&63;outU8Array[outIdx++]=128|u>>6&63;outU8Array[outIdx++]=128|u&63}}outU8Array[outIdx]=0;return outIdx-startIdx}function stringToUTF8(str,outPtr,maxBytesToWrite){assert(typeof maxBytesToWrite=="number","stringToUTF8(str, outPtr, maxBytesToWrite) is missing the third parameter that specifies the length of the output buffer!");return stringToUTF8Array(str,HEAPU8,outPtr,maxBytesToWrite)}function lengthBytesUTF8(str){var len=0;for(var i=0;i=55296&&u<=57343)u=65536+((u&1023)<<10)|str.charCodeAt(++i)&1023;if(u<=127){++len}else if(u<=2047){len+=2}else if(u<=65535){len+=3}else if(u<=2097151){len+=4}else if(u<=67108863){len+=5}else{len+=6}}return len}var UTF16Decoder=typeof TextDecoder!=="undefined"?new TextDecoder("utf-16le"):undefined;function demangle(func){warnOnce("warning: build with -s DEMANGLE_SUPPORT=1 to link in libcxxabi demangling");return func}function demangleAll(text){var regex=/__Z[\w\d_]+/g;return text.replace(regex,(function(x){var y=demangle(x);return x===y?x:x+" ["+y+"]"}))}function jsStackTrace(){var err=new Error;if(!err.stack){try{throw new Error(0)}catch(e){err=e}if(!err.stack){return"(no stack trace available)"}}return err.stack.toString()}function stackTrace(){var js=jsStackTrace();if(Module["extraStackTrace"])js+="\n"+Module["extraStackTrace"]();return demangleAll(js)}var WASM_PAGE_SIZE=65536;var ASMJS_PAGE_SIZE=16777216;function alignUp(x,multiple){if(x%multiple>0){x+=multiple-x%multiple}return x}var buffer,HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64;function updateGlobalBuffer(buf){Module["buffer"]=buffer=buf}function updateGlobalBufferViews(){Module["HEAP8"]=HEAP8=new Int8Array(buffer);Module["HEAP16"]=HEAP16=new Int16Array(buffer);Module["HEAP32"]=HEAP32=new Int32Array(buffer);Module["HEAPU8"]=HEAPU8=new Uint8Array(buffer);Module["HEAPU16"]=HEAPU16=new Uint16Array(buffer);Module["HEAPU32"]=HEAPU32=new Uint32Array(buffer);Module["HEAPF32"]=HEAPF32=new Float32Array(buffer);Module["HEAPF64"]=HEAPF64=new Float64Array(buffer)}var STATIC_BASE,STATICTOP,staticSealed;var STACK_BASE,STACKTOP,STACK_MAX;var DYNAMIC_BASE,DYNAMICTOP_PTR;STATIC_BASE=STATICTOP=STACK_BASE=STACKTOP=STACK_MAX=DYNAMIC_BASE=DYNAMICTOP_PTR=0;staticSealed=false;function writeStackCookie(){assert((STACK_MAX&3)==0);HEAPU32[(STACK_MAX>>2)-1]=34821223;HEAPU32[(STACK_MAX>>2)-2]=2310721022}function checkStackCookie(){if(HEAPU32[(STACK_MAX>>2)-1]!=34821223||HEAPU32[(STACK_MAX>>2)-2]!=2310721022){abort("Stack overflow! Stack cookie has been overwritten, expected hex dwords 0x89BACDFE and 0x02135467, but received 0x"+HEAPU32[(STACK_MAX>>2)-2].toString(16)+" "+HEAPU32[(STACK_MAX>>2)-1].toString(16))}if(HEAP32[0]!==1668509029)throw"Runtime error: The application has corrupted its heap memory area (address zero)!"}function abortStackOverflow(allocSize){abort("Stack overflow! Attempted to allocate "+allocSize+" bytes on the stack, but stack has only "+(STACK_MAX-stackSave()+allocSize)+" bytes available!")}function abortOnCannotGrowMemory(){abort("Cannot enlarge memory arrays. Either (1) compile with -s TOTAL_MEMORY=X with X higher than the current value "+TOTAL_MEMORY+", (2) compile with -s ALLOW_MEMORY_GROWTH=1 which allows increasing the size at runtime, or (3) if you want malloc to return NULL (0) instead of this abort, compile with -s ABORTING_MALLOC=0 ")}function enlargeMemory(){abortOnCannotGrowMemory()}var TOTAL_STACK=Module["TOTAL_STACK"]||5242880;var TOTAL_MEMORY=Module["TOTAL_MEMORY"]||16777216;if(TOTAL_MEMORY0){var callback=callbacks.shift();if(typeof callback=="function"){callback();continue}var func=callback.func;if(typeof func==="number"){if(callback.arg===undefined){Module["dynCall_v"](func)}else{Module["dynCall_vi"](func,callback.arg)}}else{func(callback.arg===undefined?null:callback.arg)}}}var __ATPRERUN__=[];var __ATINIT__=[];var __ATMAIN__=[];var __ATPOSTRUN__=[];var runtimeInitialized=false;var runtimeExited=false;function preRun(){if(Module["preRun"]){if(typeof Module["preRun"]=="function")Module["preRun"]=[Module["preRun"]];while(Module["preRun"].length){addOnPreRun(Module["preRun"].shift())}}callRuntimeCallbacks(__ATPRERUN__)}function ensureInitRuntime(){checkStackCookie();if(runtimeInitialized)return;runtimeInitialized=true;callRuntimeCallbacks(__ATINIT__)}function preMain(){checkStackCookie();callRuntimeCallbacks(__ATMAIN__)}function postRun(){checkStackCookie();if(Module["postRun"]){if(typeof Module["postRun"]=="function")Module["postRun"]=[Module["postRun"]];while(Module["postRun"].length){addOnPostRun(Module["postRun"].shift())}}callRuntimeCallbacks(__ATPOSTRUN__)}function addOnPreRun(cb){__ATPRERUN__.unshift(cb)}function addOnPostRun(cb){__ATPOSTRUN__.unshift(cb)}function writeArrayToMemory(array,buffer){assert(array.length>=0,"writeArrayToMemory array must have a length (should be an array or typed array)");HEAP8.set(array,buffer)}function writeAsciiToMemory(str,buffer,dontAddNull){for(var i=0;i>0]=str.charCodeAt(i)}if(!dontAddNull)HEAP8[buffer>>0]=0}assert(Math["imul"]&&Math["fround"]&&Math["clz32"]&&Math["trunc"],"this is a legacy browser, build with LEGACY_VM_SUPPORT");var runDependencies=0;var runDependencyWatcher=null;var dependenciesFulfilled=null;var runDependencyTracking={};function addRunDependency(id){runDependencies++;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}if(id){assert(!runDependencyTracking[id]);runDependencyTracking[id]=1;if(runDependencyWatcher===null&&typeof setInterval!=="undefined"){runDependencyWatcher=setInterval((function(){if(ABORT){clearInterval(runDependencyWatcher);runDependencyWatcher=null;return}var shown=false;for(var dep in runDependencyTracking){if(!shown){shown=true;err("still waiting on run dependencies:")}err("dependency: "+dep)}if(shown){err("(end of list)")}}),1e4)}}else{err("warning: run dependency added without ID")}}function removeRunDependency(id){runDependencies--;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}if(id){assert(runDependencyTracking[id]);delete runDependencyTracking[id]}else{err("warning: run dependency removed without ID")}if(runDependencies==0){if(runDependencyWatcher!==null){clearInterval(runDependencyWatcher);runDependencyWatcher=null}if(dependenciesFulfilled){var callback=dependenciesFulfilled;dependenciesFulfilled=null;callback()}}}Module["preloadedImages"]={};Module["preloadedAudios"]={};var FS={error:(function(){abort("Filesystem support (FS) was not included. The problem is that you are using files from JS, but files were not used from C/C++, so filesystem support was not auto-included. You can force-include filesystem support with -s FORCE_FILESYSTEM=1")}),init:(function(){FS.error()}),createDataFile:(function(){FS.error()}),createPreloadedFile:(function(){FS.error()}),createLazyFile:(function(){FS.error()}),open:(function(){FS.error()}),mkdev:(function(){FS.error()}),registerDevice:(function(){FS.error()}),analyzePath:(function(){FS.error()}),loadFilesFromDB:(function(){FS.error()}),ErrnoError:function ErrnoError(){FS.error()}};Module["FS_createDataFile"]=FS.createDataFile;Module["FS_createPreloadedFile"]=FS.createPreloadedFile;var dataURIPrefix="data:application/octet-stream;base64,";function isDataURI(filename){return String.prototype.startsWith?filename.startsWith(dataURIPrefix):filename.indexOf(dataURIPrefix)===0}function integrateWasmJS(){var wasmTextFile="MyMoneroCoreCpp.wast";var wasmBinaryFile="MyMoneroCoreCpp.wasm";var asmjsCodeFile="MyMoneroCoreCpp.temp.asm.js";if(!isDataURI(wasmTextFile)){wasmTextFile=locateFile(wasmTextFile)}if(!isDataURI(wasmBinaryFile)){wasmBinaryFile=locateFile(wasmBinaryFile)}if(!isDataURI(asmjsCodeFile)){asmjsCodeFile=locateFile(asmjsCodeFile)}var wasmPageSize=64*1024;var info={"global":null,"env":null,"asm2wasm":asm2wasmImports,"parent":Module};var exports=null;function mergeMemory(newBuffer){var oldBuffer=Module["buffer"];if(newBuffer.byteLength>2]=poolPtr;HEAP32[environ>>2]=envPtr}else{envPtr=HEAP32[environ>>2];poolPtr=HEAP32[envPtr>>2]}var strings=[];var totalSize=0;for(var key in ENV){if(typeof ENV[key]==="string"){var line=key+"="+ENV[key];strings.push(line);totalSize+=line.length}}if(totalSize>TOTAL_ENV_SIZE){throw new Error("Environment size exceeded TOTAL_ENV_SIZE!")}var ptrSize=4;for(var i=0;i>2]=poolPtr;poolPtr+=line.length+1}HEAP32[envPtr+strings.length*ptrSize>>2]=0}var EXCEPTIONS={last:0,caught:[],infos:{},deAdjust:(function(adjusted){if(!adjusted||EXCEPTIONS.infos[adjusted])return adjusted;for(var key in EXCEPTIONS.infos){var ptr=+key;var info=EXCEPTIONS.infos[ptr];if(info.adjusted===adjusted){return ptr}}return adjusted}),addRef:(function(ptr){if(!ptr)return;var info=EXCEPTIONS.infos[ptr];info.refcount++}),decRef:(function(ptr){if(!ptr)return;var info=EXCEPTIONS.infos[ptr];assert(info.refcount>0);info.refcount--;if(info.refcount===0&&!info.rethrown){if(info.destructor){Module["dynCall_vi"](info.destructor,ptr)}delete EXCEPTIONS.infos[ptr];___cxa_free_exception(ptr)}}),clearRef:(function(ptr){if(!ptr)return;var info=EXCEPTIONS.infos[ptr];info.refcount=0})};function ___lock(){}var SYSCALLS={varargs:0,get:(function(varargs){SYSCALLS.varargs+=4;var ret=HEAP32[SYSCALLS.varargs-4>>2];return ret}),getStr:(function(){var ret=Pointer_stringify(SYSCALLS.get());return ret}),get64:(function(){var low=SYSCALLS.get(),high=SYSCALLS.get();if(low>=0)assert(high===0);else assert(high===-1);return low}),getZero:(function(){assert(SYSCALLS.get()===0)})};function ___syscall140(which,varargs){SYSCALLS.varargs=varargs;try{var stream=SYSCALLS.getStreamFromFD(),offset_high=SYSCALLS.get(),offset_low=SYSCALLS.get(),result=SYSCALLS.get(),whence=SYSCALLS.get();var offset=offset_low;FS.llseek(stream,offset,whence);HEAP32[result>>2]=stream.position;if(stream.getdents&&offset===0&&whence===0)stream.getdents=null;return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return-e.errno}}function ___syscall146(which,varargs){SYSCALLS.varargs=varargs;try{var stream=SYSCALLS.get(),iov=SYSCALLS.get(),iovcnt=SYSCALLS.get();var ret=0;if(!___syscall146.buffers){___syscall146.buffers=[null,[],[]];___syscall146.printChar=(function(stream,curr){var buffer=___syscall146.buffers[stream];assert(buffer);if(curr===0||curr===10){(stream===1?out:err)(UTF8ArrayToString(buffer,0));buffer.length=0}else{buffer.push(curr)}})}for(var i=0;i>2];var len=HEAP32[iov+(i*8+4)>>2];for(var j=0;j=char_0&&f<=char_9){return"_"+name}else{return name}}function createNamedFunction(name,body){name=makeLegalFunctionName(name);return(function(){"use strict";return body.apply(this,arguments)})}function extendError(baseErrorType,errorName){var errorClass=createNamedFunction(errorName,(function(message){this.name=errorName;this.message=message;var stack=(new Error(message)).stack;if(stack!==undefined){this.stack=this.toString()+"\n"+stack.replace(/^Error(:[^\n]*)?\n/,"")}}));errorClass.prototype=Object.create(baseErrorType.prototype);errorClass.prototype.constructor=errorClass;errorClass.prototype.toString=(function(){if(this.message===undefined){return this.name}else{return this.name+": "+this.message}});return errorClass}var BindingError=undefined;function throwBindingError(message){throw new BindingError(message)}var InternalError=undefined;function throwInternalError(message){throw new InternalError(message)}function whenDependentTypesAreResolved(myTypes,dependentTypes,getTypeConverters){myTypes.forEach((function(type){typeDependencies[type]=dependentTypes}));function onComplete(typeConverters){var myTypeConverters=getTypeConverters(typeConverters);if(myTypeConverters.length!==myTypes.length){throwInternalError("Mismatched type converter count")}for(var i=0;i>shift])}),destructorFunction:null})}var emval_free_list=[];var emval_handle_array=[{},{value:undefined},{value:null},{value:true},{value:false}];function __emval_decref(handle){if(handle>4&&0===--emval_handle_array[handle].refcount){emval_handle_array[handle]=undefined;emval_free_list.push(handle)}}function count_emval_handles(){var count=0;for(var i=5;i>2])}function __embind_register_emval(rawType,name){name=readLatin1String(name);registerType(rawType,{name:name,"fromWireType":(function(handle){var rv=emval_handle_array[handle].value;__emval_decref(handle);return rv}),"toWireType":(function(destructors,value){return __emval_register(value)}),"argPackAdvance":8,"readValueFromPointer":simpleReadValueFromPointer,destructorFunction:null})}function _embind_repr(v){if(v===null){return"null"}var t=typeof v;if(t==="object"||t==="array"||t==="function"){return v.toString()}else{return""+v}}function floatReadValueFromPointer(name,shift){switch(shift){case 2:return(function(pointer){return this["fromWireType"](HEAPF32[pointer>>2])});case 3:return(function(pointer){return this["fromWireType"](HEAPF64[pointer>>3])});default:throw new TypeError("Unknown float type: "+name)}}function __embind_register_float(rawType,name,size){var shift=getShiftFromSize(size);name=readLatin1String(name);registerType(rawType,{name:name,"fromWireType":(function(value){return value}),"toWireType":(function(destructors,value){if(typeof value!=="number"&&typeof value!=="boolean"){throw new TypeError('Cannot convert "'+_embind_repr(value)+'" to '+this.name)}return value}),"argPackAdvance":8,"readValueFromPointer":floatReadValueFromPointer(name,shift),destructorFunction:null})}function runDestructors(destructors){while(destructors.length){var ptr=destructors.pop();var del=destructors.pop();del(ptr)}}function craftInvokerFunction(humanName,argTypes,classType,cppInvokerFunc,cppTargetFunc){var argCount=argTypes.length;if(argCount<2){throwBindingError("argTypes array size mismatch! Must at least get return value and 'this' types!")}var isClassMethodFunc=argTypes[1]!==null&&classType!==null;var needsDestructorStack=false;for(var i=1;i>2)+i])}return array}function replacePublicSymbol(name,value,numArguments){if(!Module.hasOwnProperty(name)){throwInternalError("Replacing nonexistant public symbol")}if(undefined!==Module[name].overloadTable&&undefined!==numArguments){Module[name].overloadTable[numArguments]=value}else{Module[name]=value;Module[name].argCount=numArguments}}function embind__requireFunction(signature,rawFunction){signature=readLatin1String(signature);function makeDynCaller(dynCall){return(function(){var args=new Array(arguments.length+1);args[0]=rawFunction;for(var i=0;i>1]}:function readU16FromPointer(pointer){return HEAPU16[pointer>>1]};case 2:return signed?function readS32FromPointer(pointer){return HEAP32[pointer>>2]}:function readU32FromPointer(pointer){return HEAPU32[pointer>>2]};default:throw new TypeError("Unknown integer type: "+name)}}function __embind_register_integer(primitiveType,name,size,minRange,maxRange){name=readLatin1String(name);if(maxRange===-1){maxRange=4294967295}var shift=getShiftFromSize(size);var fromWireType=(function(value){return value});if(minRange===0){var bitshift=32-8*size;fromWireType=(function(value){return value<>>bitshift})}var isUnsignedType=name.indexOf("unsigned")!=-1;registerType(primitiveType,{name:name,"fromWireType":fromWireType,"toWireType":(function(destructors,value){if(typeof value!=="number"&&typeof value!=="boolean"){throw new TypeError('Cannot convert "'+_embind_repr(value)+'" to '+this.name)}if(valuemaxRange){throw new TypeError('Passing a number "'+_embind_repr(value)+'" from JS side to C/C++ side to an argument of type "'+name+'", which is outside the valid range ['+minRange+", "+maxRange+"]!")}return isUnsignedType?value>>>0:value|0}),"argPackAdvance":8,"readValueFromPointer":integerReadValueFromPointer(name,shift,minRange!==0),destructorFunction:null})}function __embind_register_memory_view(rawType,dataTypeIndex,name){var typeMapping=[Int8Array,Uint8Array,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array];var TA=typeMapping[dataTypeIndex];function decodeMemoryView(handle){handle=handle>>2;var heap=HEAPU32;var size=heap[handle];var data=heap[handle+1];return new TA(heap["buffer"],data,size)}name=readLatin1String(name);registerType(rawType,{name:name,"fromWireType":decodeMemoryView,"argPackAdvance":8,"readValueFromPointer":decodeMemoryView},{ignoreDuplicateRegistrations:true})}function __embind_register_std_string(rawType,name){name=readLatin1String(name);var stdStringIsUTF8=name==="std::string";registerType(rawType,{name:name,"fromWireType":(function(value){var length=HEAPU32[value>>2];var str;if(stdStringIsUTF8){var endChar=HEAPU8[value+4+length];var endCharSwap=0;if(endChar!=0){endCharSwap=endChar;HEAPU8[value+4+length]=0}var decodeStartPtr=value+4;for(var i=0;i<=length;++i){var currentBytePtr=value+4+i;if(HEAPU8[currentBytePtr]==0){var stringSegment=UTF8ToString(decodeStartPtr);if(str===undefined)str=stringSegment;else{str+=String.fromCharCode(0);str+=stringSegment}decodeStartPtr=currentBytePtr+1}}if(endCharSwap!=0)HEAPU8[value+4+length]=endCharSwap}else{var a=new Array(length);for(var i=0;i>2]=length;if(stdStringIsUTF8&&valueIsOfTypeString){stringToUTF8(value,ptr+4,length+1)}else{if(valueIsOfTypeString){for(var i=0;i255){_free(ptr);throwBindingError("String has UTF-16 code units that do not fit in 8 bits")}HEAPU8[ptr+4+i]=charCode}}else{for(var i=0;i>2];var a=new Array(length);var start=value+4>>shift;for(var i=0;i>2]=length;var start=ptr+4>>shift;for(var i=0;i>2]=value;else err("failed to set errno from JS");return value}embind_init_charCodes();BindingError=Module["BindingError"]=extendError(Error,"BindingError");InternalError=Module["InternalError"]=extendError(Error,"InternalError");init_emval();UnboundTypeError=Module["UnboundTypeError"]=extendError(Error,"UnboundTypeError");DYNAMICTOP_PTR=staticAlloc(4);STACK_BASE=STACKTOP=alignMemory(STATICTOP);STACK_MAX=STACK_BASE+TOTAL_STACK;DYNAMIC_BASE=alignMemory(STACK_MAX);HEAP32[DYNAMICTOP_PTR>>2]=DYNAMIC_BASE;staticSealed=true;assert(DYNAMIC_BASE0){return}writeStackCookie();preRun();if(runDependencies>0)return;if(Module["calledRun"])return;function doRun(){if(Module["calledRun"])return;Module["calledRun"]=true;if(ABORT)return;ensureInitRuntime();preMain();if(Module["onRuntimeInitialized"])Module["onRuntimeInitialized"]();assert(!Module["_main"],'compiled without a main, but one is present. if you added it from JS, use Module["onRuntimeInitialized"]');postRun()}if(Module["setStatus"]){Module["setStatus"]("Running...");setTimeout((function(){setTimeout((function(){Module["setStatus"]("")}),1);doRun()}),1)}else{doRun()}checkStackCookie()}Module["run"]=run;var abortDecorators=[];function abort(what){if(Module["onAbort"]){Module["onAbort"](what)}if(what!==undefined){out(what);err(what);what=JSON.stringify(what)}else{what=""}ABORT=true;EXITSTATUS=1;var extra="";var output="abort("+what+") at "+stackTrace()+extra;if(abortDecorators){abortDecorators.forEach((function(decorator){output=decorator(output,what)}))}throw output}Module["abort"]=abort;if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].pop()()}}Module["noExitRuntime"]=true;run() return MyMoneroCoreCpp; -}; -MyMoneroCoreCpp = MyMoneroCoreCpp.bind({ - _currentScript: typeof document !== 'undefined' ? document.currentScript : undefined -}); +} +); +})(); if (typeof exports === 'object' && typeof module === 'object') module.exports = MyMoneroCoreCpp; else if (typeof define === 'function' && define['amd']) diff --git a/cryptonote_utils/cryptonote_utils.js b/cryptonote_utils/cryptonote_utils.js index 3e30616..844ed70 100644 --- a/cryptonote_utils/cryptonote_utils.js +++ b/cryptonote_utils/cryptonote_utils.js @@ -33,30 +33,96 @@ // v--- These should maybe be injected into a context and supplied to currencyConfig for future platforms const JSBigInt = require("./biginteger").BigInteger; const cnBase58 = require("./cryptonote_base58").cnBase58; -var _CNCrypto = undefined; // undefined -> cause 'early' calls to CNCrypto to throw exception -require("./MyMoneroCoreCpp")().then(function(Module) -{ - _CNCrypto = Module; -}); -function loaded_CNCrypto() -{ // CAUTION: calling this method blocks until _CNCrypto is loaded - while (typeof _CNCrypto === 'undefined' || !_CNCrypto) { - } - return _CNCrypto; -} const mnemonic = require("./mnemonic"); const nacl = require("./nacl-fast-cn"); const sha3 = require("./sha3"); const nettype_utils = require("./nettype"); -var cnUtil = function(currencyConfig) { +var cnUtil = function(currencyConfig) +{ + const currency_amount_format_utils = require("../cryptonote_utils/money_format_utils")(currencyConfig) + // + this._CNCrypto = undefined; // undefined -> cause 'early' calls to CNCrypto to throw exception + const ENVIRONMENT_IS_WEB = typeof window==="object"; + const ENVIRONMENT_IS_WORKER = typeof importScripts==="function"; + const ENVIRONMENT_IS_NODE = typeof process==="object" && process.browser !== true && typeof require==="function" && ENVIRONMENT_IS_WORKER == false; // we want this to be true for Electron but not for a WebView + const ENVIRONMENT_IS_SHELL = !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_NODE && !ENVIRONMENT_IS_WORKER; + var _CNCrypto_template = + { + locateFile: function(filename, scriptDirectory) + { + if (currencyConfig["locateFile"]) { + return currencyConfig["locateFile"](filename, scriptDirectory) + } + var this_scriptDirectory = scriptDirectory + const lastChar = this_scriptDirectory.charAt(this_scriptDirectory.length - 1) + if (lastChar == "/") { + this_scriptDirectory = this_scriptDirectory.substring(0, this_scriptDirectory.length - 1) // remove trailing "/" + } + const scriptDirectory_pathComponents = this_scriptDirectory.split("/") + const lastPathComponent = scriptDirectory_pathComponents[scriptDirectory_pathComponents.length - 1] + var pathTo_cryptonoteUtilsDir; // add trailing slash to this + if (lastPathComponent == "cryptonote_utils") { // typical node or electron-main process + pathTo_cryptonoteUtilsDir = scriptDirectory_pathComponents.join("/") + "/" + } else if (ENVIRONMENT_IS_WEB) { // this will still match on electron-renderer, so the path must be patched up… + if (typeof __dirname !== undefined && __dirname !== "/") { // looks like node running in browser.. assuming Electron-renderer + // have to check != "/" b/c webpack (I think) replaces __dirname + pathTo_cryptonoteUtilsDir = "file://" + __dirname + "/" // prepending "file://" because it's going to try to stream it + } else { // actual web browser + pathTo_cryptonoteUtilsDir = this_scriptDirectory + "/mymonero_core_js/cryptonote_utils/" // this works for the MyMonero browser build, and is quite general, at least + } + } else { + throw "Undefined pathTo_cryptonoteUtilsDir. Please pass locateFile() to cryptonote_utils init." + } + const fullPath = pathTo_cryptonoteUtilsDir + filename + // + return fullPath + } + } + // if (ENVIRONMENT_IS_WEB && ENVIRONMENT_IS_NODE) { // that means it's probably electron-renderer + // const fs = require("fs"); + // const path = require("path"); + // const filepath = path.normalize(path.join(__dirname, "MyMoneroCoreCpp.wasm")); + // const wasmBinary = fs.readFileSync(filepath) + // console.log("wasmBinary", wasmBinary) + // _CNCrypto_template["wasmBinary"] = wasmBinary + // } + this._CNCrypto = undefined; + var loaded_CNCrypto = this.loaded_CNCrypto = function() + { // CAUTION: calling this method blocks until _CNCrypto is loaded + if (typeof this._CNCrypto === 'undefined' || !this._CNCrypto) { + throw "You must call OnceModuleReady to wait for _CNCrypto to be ready" + } + return this._CNCrypto; + } + this.moduleReadyFns = [] // initial (gets set to undefined once Module ready) + this.OnceModuleReady = function(fn) + { + if (this._CNCrypto == null) { + if (typeof this.moduleReadyFns == 'undefined' || !this.moduleReadyFns) { + throw "Expected moduleReadyFns" + } + this.moduleReadyFns.push(fn) + } else { + fn(Module) + } + } + require("./MyMoneroCoreCpp")(_CNCrypto_template).then(function(thisModule) + { + this._CNCrypto = thisModule + { + for (let fn of this.moduleReadyFns) { + fn(thisModule) + } + } + this.moduleReadyFns = [] // flash/free + }); + // var config = {}; // shallow copy of initConfig for (var key in currencyConfig) { config[key] = currencyConfig[key]; } - config.coinUnits = new JSBigInt(10).pow(config.coinUnitPlaces); - var HASH_STATE_BYTES = 200; var HASH_SIZE = 32; var ADDRESS_CHECKSUM_SIZE = 4; @@ -2613,7 +2679,7 @@ var cnUtil = function(currencyConfig) { //run the for loop twice to sort ins by key image //first generate key image and other construction data to sort it all in one go for (i = 0; i < sources.length; i++) { - console.log(i + ": " + this.formatMoneyFull(sources[i].amount)); + console.log(i + ": " + currency_amount_format_utils.formatMoneyFull(sources[i].amount)); if (sources[i].real_out >= sources[i].outputs.length) { throw "real index >= outputs.length"; } @@ -2718,11 +2784,11 @@ var cnUtil = function(currencyConfig) { if (outputs_money.add(fee_amount).compare(inputs_money) > 0) { throw "outputs money (" + - this.formatMoneyFull(outputs_money) + + currency_amount_format_utils.formatMoneyFull(outputs_money) + ") + fee (" + - this.formatMoneyFull(fee_amount) + + currency_amount_format_utils.formatMoneyFull(fee_amount) + ") > inputs money (" + - this.formatMoneyFull(inputs_money) + + currency_amount_format_utils.formatMoneyFull(inputs_money) + ")"; } if (!rct) { @@ -2790,6 +2856,43 @@ var cnUtil = function(currencyConfig) { return tx; }; + this.create_transaction__IPCsafe = function( + pub_keys, + sec_keys, + serialized__dsts, // amounts are strings + outputs, + mix_outs, + fake_outputs_count, + serialized__fee_amount, // string amount + payment_id, + pid_encrypt, + realDestViewKey, + unlock_time, + rct, + nettype, + ) { + const dsts = serialized__dsts.map(function(i) { + i.amount = new JSBigInt(i.amount) + return i + }) + console.log("deserialized DSTS is... ", dsts) + return this.create_transaction( + pub_keys, + sec_keys, + dsts, + outputs, + mix_outs, + fake_outputs_count, + new JSBigInt(serialized__fee_amount), + payment_id, + pid_encrypt, + realDestViewKey, + unlock_time, + rct, + nettype, + ); + } + this.create_transaction = function( pub_keys, sec_keys, @@ -2944,9 +3047,9 @@ var cnUtil = function(currencyConfig) { } } else if (cmp > 0) { throw "Need more money than found! (have: " + - cnUtil.formatMoney(found_money) + + currency_amount_format_utils.formatMoney(found_money) + " need: " + - cnUtil.formatMoney(needed_money) + + currency_amount_format_utils.formatMoney(needed_money) + ")"; } return this.construct_tx( @@ -2996,156 +3099,6 @@ var cnUtil = function(currencyConfig) { return size; }; - function trimRight(str, char) { - while (str[str.length - 1] == char) str = str.slice(0, -1); - return str; - } - - function padLeft(str, len, char) { - while (str.length < len) { - str = char + str; - } - return str; - } - - this.padLeft = padLeft; - - this.printDsts = function(dsts) { - for (var i = 0; i < dsts.length; i++) { - console.log( - dsts[i].address + ": " + this.formatMoneyFull(dsts[i].amount), - ); - } - }; - - this.formatMoneyFull = function(units) { - units = units.toString(); - var symbol = units[0] === "-" ? "-" : ""; - if (symbol === "-") { - units = units.slice(1); - } - var decimal; - if (units.length >= config.coinUnitPlaces) { - decimal = units.substr( - units.length - config.coinUnitPlaces, - config.coinUnitPlaces, - ); - } else { - decimal = padLeft(units, config.coinUnitPlaces, "0"); - } - return ( - symbol + - (units.substr(0, units.length - config.coinUnitPlaces) || "0") + - "." + - decimal - ); - }; - - this.formatMoneyFullSymbol = function(units) { - return this.formatMoneyFull(units) + " " + config.coinSymbol; - }; - - this.formatMoney = function(units) { - var f = trimRight(this.formatMoneyFull(units), "0"); - if (f[f.length - 1] === ".") { - return f.slice(0, f.length - 1); - } - return f; - }; - - this.formatMoneySymbol = function(units) { - return this.formatMoney(units) + " " + config.coinSymbol; - }; - - this.parseMoney = function(str) { - if (!str) return JSBigInt.ZERO; - var negative = str[0] === "-"; - if (negative) { - str = str.slice(1); - } - var decimalIndex = str.indexOf("."); - if (decimalIndex == -1) { - if (negative) { - return JSBigInt.multiply(str, config.coinUnits).negate(); - } - return JSBigInt.multiply(str, config.coinUnits); - } - if (decimalIndex + config.coinUnitPlaces + 1 < str.length) { - str = str.substr(0, decimalIndex + config.coinUnitPlaces + 1); - } - if (negative) { - return new JSBigInt(str.substr(0, decimalIndex)) - .exp10(config.coinUnitPlaces) - .add( - new JSBigInt(str.substr(decimalIndex + 1)).exp10( - decimalIndex + config.coinUnitPlaces - str.length + 1, - ), - ).negate; - } - return new JSBigInt(str.substr(0, decimalIndex)) - .exp10(config.coinUnitPlaces) - .add( - new JSBigInt(str.substr(decimalIndex + 1)).exp10( - decimalIndex + config.coinUnitPlaces - str.length + 1, - ), - ); - }; - - this.decompose_amount_into_digits = function(amount) { - /*if (dust_threshold === undefined) { - dust_threshold = config.dustThreshold; - }*/ - amount = amount.toString(); - var ret = []; - while (amount.length > 0) { - //split all the way down since v2 fork - /*var remaining = new JSBigInt(amount); - if (remaining.compare(config.dustThreshold) <= 0) { - if (remaining.compare(0) > 0) { - ret.push(remaining); - } - break; - }*/ - //check so we don't create 0s - if (amount[0] !== "0") { - var digit = amount[0]; - while (digit.length < amount.length) { - digit += "0"; - } - ret.push(new JSBigInt(digit)); - } - amount = amount.slice(1); - } - return ret; - }; - - this.decompose_tx_destinations = function(dsts, rct) { - var out = []; - if (rct) { - for (var i = 0; i < dsts.length; i++) { - out.push({ - address: dsts[i].address, - amount: dsts[i].amount, - }); - } - } else { - for (var i = 0; i < dsts.length; i++) { - var digits = this.decompose_amount_into_digits(dsts[i].amount); - for (var j = 0; j < digits.length; j++) { - if (digits[j].compare(0) > 0) { - out.push({ - address: dsts[i].address, - amount: digits[j], - }); - } - } - } - } - return out.sort(function(a, b) { - return a["amount"] - b["amount"]; - }); - }; - this.is_tx_unlocked = function(unlock_time, blockchain_height) { if (!config.maxBlockNumber) { throw "Max block number is not set in config!"; diff --git a/cryptonote_utils/money_format_utils.js b/cryptonote_utils/money_format_utils.js new file mode 100644 index 0000000..1efadd0 --- /dev/null +++ b/cryptonote_utils/money_format_utils.js @@ -0,0 +1,123 @@ +// Copyright (c) 2014-2018, MyMonero.com +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list +// of conditions and the following disclaimer in the documentation and/or other +// materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be +// used to endorse or promote products derived from this software without specific +// prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +const JSBigInt = require("./biginteger").BigInteger; +// +module.exports = function(currencyConfig) +{ + // `currencyConfig` needs coinUnitPlaces, and coinSymbol + var config = {}; // shallow copy of initConfig + { + for (var key in currencyConfig) { + config[key] = currencyConfig[key]; + } + config.coinUnits = new JSBigInt(10).pow(config.coinUnitPlaces); + } + this.formatMoneyFull = function(units) { + units = units.toString(); + var symbol = units[0] === "-" ? "-" : ""; + if (symbol === "-") { + units = units.slice(1); + } + var decimal; + if (units.length >= config.coinUnitPlaces) { + decimal = units.substr( + units.length - config.coinUnitPlaces, + config.coinUnitPlaces + ); + } else { + decimal = padLeft(units, config.coinUnitPlaces, "0"); + } + return ( + symbol + + (units.substr(0, units.length - config.coinUnitPlaces) || "0") + + "." + + decimal + ); + }; + + this.formatMoneyFullSymbol = function(units) { + return this.formatMoneyFull(units) + " " + config.coinSymbol; + }; + + function padLeft(str, len, char) { + while (str.length < len) str = char + str; + return str; + } + function trimRight(str, char) { + while (str[str.length - 1] == char) str = str.slice(0, -1); + return str; + } + this.formatMoney = function(units) { + var f = trimRight(this.formatMoneyFull(units), "0"); + if (f[f.length - 1] === ".") { + return f.slice(0, f.length - 1); + } + return f; + }; + + this.formatMoneySymbol = function(units) { + return this.formatMoney(units) + " " + config.coinSymbol; + }; + + this.parseMoney = function(str) { + if (!str) return JSBigInt.ZERO; + var negative = str[0] === "-"; + if (negative) { + str = str.slice(1); + } + var decimalIndex = str.indexOf("."); + if (decimalIndex == -1) { + if (negative) { + return JSBigInt.multiply(str, config.coinUnits).negate(); + } + return JSBigInt.multiply(str, config.coinUnits); + } + if (decimalIndex + config.coinUnitPlaces + 1 < str.length) { + str = str.substr(0, decimalIndex + config.coinUnitPlaces + 1); + } + if (negative) { + return new JSBigInt(str.substr(0, decimalIndex)) + .exp10(config.coinUnitPlaces) + .add( + new JSBigInt(str.substr(decimalIndex + 1)).exp10( + decimalIndex + config.coinUnitPlaces - str.length + 1, + ), + ).negate; + } + return new JSBigInt(str.substr(0, decimalIndex)) + .exp10(config.coinUnitPlaces) + .add( + new JSBigInt(str.substr(decimalIndex + 1)).exp10( + decimalIndex + config.coinUnitPlaces - str.length + 1, + ), + ); + }; + + return this; +}; \ No newline at end of file diff --git a/hostAPI/response_parser_utils.js b/hostAPI/response_parser_utils.js index a7b4e35..f753293 100644 --- a/hostAPI/response_parser_utils.js +++ b/hostAPI/response_parser_utils.js @@ -29,7 +29,7 @@ "use strict"; // const JSBigInt = require("../cryptonote_utils/biginteger").BigInteger; -const monero_utils = require("../monero_utils/monero_cryptonote_utils_instance"); +const monero_amount_format_utils = require("../monero_utils/monero_amount_format_utils"); const monero_keyImage_cache_utils = require("../monero_utils/monero_keyImage_cache_utils"); // function Parsed_AddressInfo__sync( @@ -228,7 +228,7 @@ function Parsed_AddressTransactions__sync( .subtract(transactions[i].total_sent || 0) .toString(); transactions[i].approx_float_amount = parseFloat( - monero_utils.formatMoney(transactions[i].amount), + monero_amount_format_utils.formatMoney(transactions[i].amount), ); transactions[i].timestamp = transactions[i].timestamp; const record__payment_id = transactions[i].payment_id; @@ -370,9 +370,9 @@ function Parsed_UnspentOuts__sync( !finalized_unspentOutput_atI_beforeSplice || typeof finalized_unspentOutput_atI_beforeSplice === "undefined" ) { - console.warn( - `This unspent output at i ${i} was literally undefined! Skipping.`, - ); // NOTE: Looks like the i-- code below should exit earlier if this is necessary + // console.warn( + // `This unspent output at i ${i} was literally undefined! Skipping.`, + // ); // NOTE: Looks like the i-- code below should exit earlier if this is necessary continue; } const beforeSplice__tx_pub_key = @@ -402,7 +402,7 @@ function Parsed_UnspentOuts__sync( key_image === finalized_unspentOutput_atI_beforeSplice.spend_key_images[j] ) { - // console.log("💬 Output was spent; key image: " + key_image + " amount: " + monero_utils.formatMoneyFull(finalized_unspentOutputs[i].amount)); + // console.log("💬 Output was spent; key image: " + key_image + " amount: " + monero_amount_format_utils.formatMoneyFull(finalized_unspentOutputs[i].amount)); // Remove output from list finalized_unspentOutputs.splice(i, 1); const finalized_unspentOutput_atI_afterSplice = @@ -414,17 +414,17 @@ function Parsed_UnspentOuts__sync( } i--; } else { - console.log( - "💬 Output used as mixin (" + - key_image + - "/" + - finalized_unspentOutputs[i].spend_key_images[j] + - ")", - ); + // console.log( + // "💬 Output used as mixin (" + + // key_image + + // "/" + + // finalized_unspentOutputs[i].spend_key_images[j] + + // ")", + // ); } } } - console.log("Unspent outs: " + JSON.stringify(finalized_unspentOutputs)); + // console.log("Unspent outs: " + JSON.stringify(finalized_unspentOutputs)); const unusedOuts = finalized_unspentOutputs.slice(0); const returnValuesByKey = { unspentOutputs: finalized_unspentOutputs, diff --git a/monero_utils/monero_amount_format_utils.js b/monero_utils/monero_amount_format_utils.js new file mode 100644 index 0000000..8afc8e1 --- /dev/null +++ b/monero_utils/monero_amount_format_utils.js @@ -0,0 +1,35 @@ +// Copyright (c) 2014-2018, MyMonero.com +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list +// of conditions and the following disclaimer in the documentation and/or other +// materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be +// used to endorse or promote products derived from this software without specific +// prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +"use strict"; +// +const monero_config = require("./monero_config") +const money_format_utils = require("../cryptonote_utils/money_format_utils") +const instance = money_format_utils(monero_config) +// +module.exports = instance; \ No newline at end of file diff --git a/monero_utils/monero_cryptonote_utils_instance.js b/monero_utils/monero_cryptonote_utils_instance.js index b5a51c4..a667375 100644 --- a/monero_utils/monero_cryptonote_utils_instance.js +++ b/monero_utils/monero_cryptonote_utils_instance.js @@ -28,8 +28,25 @@ // "use strict"; // -const monero_config = require("./monero_config"); -const cryptonote_utils = require("../cryptonote_utils/cryptonote_utils").cnUtil; -const monero_cryptonote_utils_instance = cryptonote_utils(monero_config); -// -module.exports = monero_cryptonote_utils_instance; +const ENVIRONMENT_IS_WEB = typeof window==="object"; +const ENVIRONMENT_IS_WORKER = typeof importScripts==="function"; +const ENVIRONMENT_IS_NODE = typeof process==="object" && process.browser !== true && typeof require==="function" && ENVIRONMENT_IS_WORKER == false; // we want this to be true for Electron but not for a WebView +var isElectronRenderer = (ENVIRONMENT_IS_NODE&&ENVIRONMENT_IS_WEB)/*this may become insufficient*/ + || (typeof window !== 'undefined' && window.IsElectronRendererProcess == true); +if (isElectronRenderer) { + // Require file again except on the main process ... + // this avoids a host of issues running wasm on the renderer side, + // for right now until we can load such files raw w/o unsafe-eval + // script-src CSP. makes calls synchronous. if that is a perf problem + // we can make API async. + // + // Resolves relative to the entrypoint of the main process. + const remotely_required = require('electron').remote.require("../mymonero_core_js/monero_utils/monero_cryptonote_utils_instance") + module.exports = remotely_required; +} else { + const monero_config = require("./monero_config"); + const cryptonote_utils = require("../cryptonote_utils/cryptonote_utils").cnUtil; + const monero_cryptonote_utils_instance = cryptonote_utils(monero_config); + // + module.exports = monero_cryptonote_utils_instance; +} \ No newline at end of file diff --git a/monero_utils/monero_sendingFunds_utils.js b/monero_utils/monero_sendingFunds_utils.js index f0ddcc4..bf51973 100644 --- a/monero_utils/monero_sendingFunds_utils.js +++ b/monero_utils/monero_sendingFunds_utils.js @@ -32,6 +32,7 @@ const async = require("async"); // const monero_config = require("./monero_config"); const monero_utils = require("./monero_cryptonote_utils_instance"); +const monero_amount_format_utils = require("./monero_amount_format_utils"); const monero_paymentID_utils = require("./monero_paymentID_utils"); const JSBigInt = require("../cryptonote_utils/biginteger").BigInteger; // @@ -254,7 +255,7 @@ function SendFunds( console.log( "💬 Total to send, before fee: " + sweeping ? "all" - : monero_utils.formatMoney(totalAmountWithoutFee_JSBigInt), + : monero_amount_format_utils.formatMoney(totalAmountWithoutFee_JSBigInt), ); if (!sweeping && totalAmountWithoutFee_JSBigInt.compare(0) <= 0) { const errStr = "The amount you've entered is too low"; @@ -338,7 +339,7 @@ function SendFunds( } console.log( "Received dynamic per kb fee", - monero_utils.formatMoneySymbol(dynamic_feePerKB_JSBigInt), + monero_amount_format_utils.formatMoneySymbol(dynamic_feePerKB_JSBigInt), ); _proceedTo_constructFundTransferListAndSendFundsByUsingUnusedUnspentOutsForMixin( moneroReady_targetDescription_address, @@ -405,7 +406,7 @@ function SendFunds( ); /*.add(hostingService_chargeAmount) NOTE service fee removed for now */ console.log( "Balance required: " + - monero_utils.formatMoneySymbol(totalAmountIncludingFees), + monero_amount_format_utils.formatMoneySymbol(totalAmountIncludingFees), ); } const usableOutputsAndAmounts = _outputsAndAmountToUseForMixin( @@ -440,11 +441,11 @@ function SendFunds( newNeededFee, ); if (totalAmountWithoutFee_JSBigInt.compare(0) < 1) { - const errStr = `Your spendable balance is too low. Have ${monero_utils.formatMoney( + const errStr = `Your spendable balance is too low. Have ${monero_amount_format_utils.formatMoney( usingOutsAmount, )} ${ monero_config.coinSymbol - } spendable, need ${monero_utils.formatMoney( + } spendable, need ${monero_amount_format_utils.formatMoney( newNeededFee, )} ${monero_config.coinSymbol}.`; __trampolineFor_err_withStr(errStr); @@ -467,7 +468,7 @@ function SendFunds( ); console.log( "Using output: " + - monero_utils.formatMoney(out.amount) + + monero_amount_format_utils.formatMoney(out.amount) + " - " + JSON.stringify(out), ); @@ -488,7 +489,7 @@ function SendFunds( } console.log( "New fee: " + - monero_utils.formatMoneySymbol(newNeededFee) + + monero_amount_format_utils.formatMoneySymbol(newNeededFee) + " for " + usingOuts.length + " inputs", @@ -497,18 +498,18 @@ function SendFunds( } console.log( "~ Balance required: " + - monero_utils.formatMoneySymbol(totalAmountIncludingFees), + monero_amount_format_utils.formatMoneySymbol(totalAmountIncludingFees), ); // Now we can validate available balance with usingOutsAmount (TODO? maybe this check can be done before selecting outputs?) const usingOutsAmount_comparedTo_totalAmount = usingOutsAmount.compare( totalAmountIncludingFees, ); if (usingOutsAmount_comparedTo_totalAmount < 0) { - const errStr = `Your spendable balance is too low. Have ${monero_utils.formatMoney( + const errStr = `Your spendable balance is too low. Have ${monero_amount_format_utils.formatMoney( usingOutsAmount, )} ${ monero_config.coinSymbol - } spendable, need ${monero_utils.formatMoney( + } spendable, need ${monero_amount_format_utils.formatMoney( totalAmountIncludingFees, )} ${monero_config.coinSymbol}.`; __trampolineFor_err_withStr(errStr); @@ -540,7 +541,7 @@ function SendFunds( // for RCT we don't presently care about dustiness so add entire change amount console.log( "Sending change of " + - monero_utils.formatMoneySymbol(changeAmount) + + monero_amount_format_utils.formatMoneySymbol(changeAmount) + " to " + wallet__public_address, ); @@ -559,7 +560,7 @@ function SendFunds( // miners will add dusty change to fee console.log( "💬 Miners will add change of " + - monero_utils.formatMoneyFullSymbol( + monero_amount_format_utils.formatMoneyFullSymbol( changeAmountDivRem[1], ) + " to transaction fee (below dust threshold)", @@ -572,7 +573,7 @@ function SendFunds( ); console.log( "💬 Sending change of " + - monero_utils.formatMoneySymbol(usableChange) + + monero_amount_format_utils.formatMoneySymbol(usableChange) + " to " + wallet__public_address, ); @@ -632,10 +633,16 @@ function SendFunds( preSuccess_nonTerminal_statusUpdate_fn( SendFunds_ProcessStep_Code.constructingTransaction, ); + function printDsts(dsts) + { + for (var i = 0; i < dsts.length; i++) { + console.log(dsts[i].address + ": " + monero_amount_format_utils.formatMoneyFull(dsts[i].amount)) + } + } var signedTx; try { console.log("Destinations: "); - monero_utils.printDsts(fundTransferDescriptions); + printDsts(fundTransferDescriptions); // TODO: port this out // var realDestViewKey; // need to get viewkey for encrypting here, because of splitting and sorting if (final__pid_encrypt) { @@ -645,21 +652,22 @@ function SendFunds( ).view; console.log("got realDestViewKey", realDestViewKey); } - var splitDestinations = monero_utils.decompose_tx_destinations( + console.log("fundTransferDescriptions", fundTransferDescriptions) + var IPCsafe_splitDestinations = decompose_tx_destinations( // TODO: port this out fundTransferDescriptions, isRingCT, + true // serialize (convert JSBigInts to strings for IPC) ); - console.log("Decomposed destinations:"); - monero_utils.printDsts(splitDestinations); + printDsts(IPCsafe_splitDestinations); // - signedTx = monero_utils.create_transaction( + signedTx = monero_utils.create_transaction__IPCsafe( wallet__public_keys, wallet__private_keys, - splitDestinations, + IPCsafe_splitDestinations, usingOuts, mix_outs, mixin, - attemptAt_network_minimumFee, + attemptAt_network_minimumFee.toString(), // must serialize for IPC final__payment_id, final__pid_encrypt, realDestViewKey, @@ -705,7 +713,7 @@ function SendFunds( " bytes <= " + numKB + " KB (current fee: " + - monero_utils.formatMoneyFull(attemptAt_network_minimumFee) + + monero_amount_format_utils.formatMoneyFull(attemptAt_network_minimumFee) + ")", ); const feeActuallyNeededByNetwork = calculate_fee__kb( @@ -721,11 +729,11 @@ function SendFunds( ) { console.log( "💬 Need to reconstruct the tx with enough of a network fee. Previous fee: " + - monero_utils.formatMoneyFull( + monero_amount_format_utils.formatMoneyFull( attemptAt_network_minimumFee, ) + " New fee: " + - monero_utils.formatMoneyFull( + monero_amount_format_utils.formatMoneyFull( feeActuallyNeededByNetwork, ), ); @@ -747,7 +755,7 @@ function SendFunds( const final_networkFee = attemptAt_network_minimumFee; // just to make things clear console.log( "💬 Successful tx generation, submitting tx. Going with final_networkFee of ", - monero_utils.formatMoney(final_networkFee), + monero_amount_format_utils.formatMoney(final_networkFee), ); // status: submitting… preSuccess_nonTerminal_statusUpdate_fn( @@ -770,7 +778,7 @@ function SendFunds( moneroReady_targetDescription_address, sweeping ? parseFloat( - monero_utils.formatMoneyFull( + monero_amount_format_utils.formatMoneyFull( totalAmountWithoutFee_JSBigInt, ), ) @@ -831,7 +839,7 @@ function new_moneroReadyTargetDescriptions_fromTargetDescriptions( // amount: var moneroReady_amountToSend; // possibly need this ; here for the JS parser try { - moneroReady_amountToSend = monero_utils.parseMoney( + moneroReady_amountToSend = monero_amount_format_utils.parseMoney( targetDescription_amount, ); } catch (e) { @@ -873,7 +881,7 @@ function _outputsAndAmountToUseForMixin( ) { console.log( "Selecting outputs to use. target: " + - monero_utils.formatMoney(target_amount), + monero_amount_format_utils.formatMoney(target_amount), ); var toFinalize_usingOutsAmount = new JSBigInt(0); const toFinalize_usingOuts = []; @@ -913,7 +921,7 @@ function _outputsAndAmountToUseForMixin( ); console.log( "Using output: " + - monero_utils.formatMoney(out_amount_JSBigInt) + + monero_amount_format_utils.formatMoney(out_amount_JSBigInt) + " - " + JSON.stringify(out), ); @@ -924,3 +932,59 @@ function _outputsAndAmountToUseForMixin( remaining_unusedOuts: remaining_unusedOuts, }; } + +function decompose_amount_into_digits(amount) +{ + /*if (dust_threshold === undefined) { + dust_threshold = config.dustThreshold; + }*/ + amount = amount.toString(); + var ret = []; + while (amount.length > 0) { + //split all the way down since v2 fork + /*var remaining = new JSBigInt(amount); + if (remaining.compare(config.dustThreshold) <= 0) { + if (remaining.compare(0) > 0) { + ret.push(remaining); + } + break; + }*/ + //check so we don't create 0s + if (amount[0] !== "0") { + var digit = amount[0]; + while (digit.length < amount.length) { + digit += "0"; + } + ret.push(new JSBigInt(digit)); + } + amount = amount.slice(1); + } + return ret; +} +function decompose_tx_destinations(dsts, rct, serializeForIPC) +{ + var out = []; + if (rct) { + for (var i = 0; i < dsts.length; i++) { + out.push({ + address: dsts[i].address, + amount: serializeForIPC ? dsts[i].amount.toString() : dsts[i].amount, + }); + } + } else { + for (var i = 0; i < dsts.length; i++) { + var digits = decompose_amount_into_digits(dsts[i].amount); + for (var j = 0; j < digits.length; j++) { + if (digits[j].compare(0) > 0) { + out.push({ + address: dsts[i].address, + amount: serializeForIPC ? digits[j].toString() : digits[j], + }); + } + } + } + } + return out.sort(function(a, b) { + return a["amount"] - b["amount"]; + }); +}; \ No newline at end of file diff --git a/tests/emjs/MyMoneroCoreCpp_int.node.js b/tests/emjs/MyMoneroCoreCpp_int.node.js index 3261256..ba38afe 100644 --- a/tests/emjs/MyMoneroCoreCpp_int.node.js +++ b/tests/emjs/MyMoneroCoreCpp_int.node.js @@ -31,8 +31,6 @@ const dummy_test_utils = require("./dummy-test-utils.js"); const dummy_cnUtils_instance = require("./dummy-cnutils").cnUtil() -console.log("dummy_test_utils.Module", dummy_test_utils.Module) - dummy_test_utils.OnceModuleReady( function(Module) { diff --git a/tests/emjs/cryptonote_utils__int.node.js b/tests/emjs/cryptonote_utils__int.node.js new file mode 100644 index 0000000..84bf26b --- /dev/null +++ b/tests/emjs/cryptonote_utils__int.node.js @@ -0,0 +1,41 @@ +// Copyright (c) 2014-2018, MyMonero.com +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list +// of conditions and the following disclaimer in the documentation and/or other +// materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be +// used to endorse or promote products derived from this software without specific +// prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"use strict"; +// +const monero_utils = require("../../monero_utils/monero_cryptonote_utils_instance"); +try { + console.log("loaded_CNCrypto", monero_utils.loaded_CNCrypto()) +} catch (e) { + console.log("Caught the expected exception while trying to call on CNCrypto while it's being loaded") +} +monero_utils.OnceModuleReady(function() +{ + console.log("loaded_CNCrypto", monero_utils.loaded_CNCrypto()) +}) + diff --git a/tests/emjs/dummy-test-utils.js b/tests/emjs/dummy-test-utils.js index 3f58e01..ff8981f 100644 --- a/tests/emjs/dummy-test-utils.js +++ b/tests/emjs/dummy-test-utils.js @@ -27,7 +27,7 @@ // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. "use strict"; -const MyMoneroCoreCpp = require("../../cryptonote_utils/MyMoneroCoreCpp.js"); +const MyMoneroCoreCpp_builder = require("../../cryptonote_utils/MyMoneroCoreCpp.js"); var public_key = "904e49462268d771cc1649084c35aa1296bfb214880fe2e7f373620a3e2ba597"; @@ -49,8 +49,10 @@ exports.OnceModuleReady = function(fn) fn(Module) } } - -MyMoneroCoreCpp().then(function(thisModule) +var Module_template = +{ +} +MyMoneroCoreCpp_builder(Module_template).then(function(thisModule) { Module = thisModule exports.Module = Module