lnsocket

A minimal C library for connecting to the lightning network
git clone git://jb55.com/lnsocket
Log | Files | Refs | Submodules | README | LICENSE

lnsocket.js (29000B)


      1 
      2 var Module = (() => {
      3   var _scriptDir = typeof document !== 'undefined' && document.currentScript ? document.currentScript.src : undefined;
      4   
      5   return (
      6 function(Module) {
      7   Module = Module || {};
      8 
      9 var Module=typeof Module!="undefined"?Module:{};var readyPromiseResolve,readyPromiseReject;Module["ready"]=new Promise(function(resolve,reject){readyPromiseResolve=resolve;readyPromiseReject=reject});Module.getRandomValue=function(){const window_="object"===typeof window?window:this;const crypto_=typeof window_.crypto!=="undefined"?window_.crypto:window_.msCrypto;let randomBytesNode;let fn;if(!crypto_){randomBytesNode=require("crypto").randomBytes;fn=randomValuesNode}else{fn=randomValuesStandard}function randomValuesNode(){return randomBytesNode(1)[0]>>>0}function randomValuesStandard(){var buf=new Uint32Array(1);crypto_.getRandomValues(buf);return buf[0]>>>0}return fn}();var moduleOverrides=Object.assign({},Module);var arguments_=[];var thisProgram="./this.program";var quit_=(status,toThrow)=>{throw toThrow};var ENVIRONMENT_IS_WEB=true;var ENVIRONMENT_IS_WORKER=false;var scriptDirectory="";function locateFile(path){if(Module["locateFile"]){return Module["locateFile"](path,scriptDirectory)}return scriptDirectory+path}var read_,readAsync,readBinary,setWindowTitle;if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){if(ENVIRONMENT_IS_WORKER){scriptDirectory=self.location.href}else if(typeof document!="undefined"&&document.currentScript){scriptDirectory=document.currentScript.src}if(_scriptDir){scriptDirectory=_scriptDir}if(scriptDirectory.indexOf("blob:")!==0){scriptDirectory=scriptDirectory.substr(0,scriptDirectory.replace(/[?#].*/,"").lastIndexOf("/")+1)}else{scriptDirectory=""}{read_=(url=>{var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.send(null);return xhr.responseText});if(ENVIRONMENT_IS_WORKER){readBinary=(url=>{var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.responseType="arraybuffer";xhr.send(null);return new Uint8Array(xhr.response)})}readAsync=((url,onload,onerror)=>{var xhr=new XMLHttpRequest;xhr.open("GET",url,true);xhr.responseType="arraybuffer";xhr.onload=(()=>{if(xhr.status==200||xhr.status==0&&xhr.response){onload(xhr.response);return}onerror()});xhr.onerror=onerror;xhr.send(null)})}setWindowTitle=(title=>document.title=title)}else{}var out=Module["print"]||console.log.bind(console);var err=Module["printErr"]||console.warn.bind(console);Object.assign(Module,moduleOverrides);moduleOverrides=null;if(Module["arguments"])arguments_=Module["arguments"];if(Module["thisProgram"])thisProgram=Module["thisProgram"];if(Module["quit"])quit_=Module["quit"];var wasmBinary;if(Module["wasmBinary"])wasmBinary=Module["wasmBinary"];var noExitRuntime=Module["noExitRuntime"]||true;if(typeof WebAssembly!="object"){abort("no native wasm support detected")}var wasmMemory;var ABORT=false;var EXITSTATUS;function getCFunc(ident){var func=Module["_"+ident];return func}function ccall(ident,returnType,argTypes,args,opts){var toC={"string":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},"array":function(arr){var ret=stackAlloc(arr.length);writeArrayToMemory(arr,ret);return ret}};function convertReturnValue(ret){if(returnType==="string")return UTF8ToString(ret);if(returnType==="boolean")return Boolean(ret);return ret}var func=getCFunc(ident);var cArgs=[];var stack=0;if(args){for(var i=0;i<args.length;i++){var converter=toC[argTypes[i]];if(converter){if(stack===0)stack=stackSave();cArgs[i]=converter(args[i])}else{cArgs[i]=args[i]}}}var ret=func.apply(null,cArgs);function onDone(ret){if(stack!==0)stackRestore(stack);return convertReturnValue(ret)}ret=onDone(ret);return ret}function cwrap(ident,returnType,argTypes,opts){argTypes=argTypes||[];var numericArgs=argTypes.every(function(type){return type==="number"});var numericRet=returnType!=="string";if(numericRet&&numericArgs&&!opts){return getCFunc(ident)}return function(){return ccall(ident,returnType,argTypes,arguments,opts)}}var UTF8Decoder=typeof TextDecoder!="undefined"?new TextDecoder("utf8"):undefined;function UTF8ArrayToString(heapOrArray,idx,maxBytesToRead){var endIdx=idx+maxBytesToRead;var endPtr=idx;while(heapOrArray[endPtr]&&!(endPtr>=endIdx))++endPtr;if(endPtr-idx>16&&heapOrArray.buffer&&UTF8Decoder){return UTF8Decoder.decode(heapOrArray.subarray(idx,endPtr))}else{var str="";while(idx<endPtr){var u0=heapOrArray[idx++];if(!(u0&128)){str+=String.fromCharCode(u0);continue}var u1=heapOrArray[idx++]&63;if((u0&224)==192){str+=String.fromCharCode((u0&31)<<6|u1);continue}var u2=heapOrArray[idx++]&63;if((u0&240)==224){u0=(u0&15)<<12|u1<<6|u2}else{u0=(u0&7)<<18|u1<<12|u2<<6|heapOrArray[idx++]&63}if(u0<65536){str+=String.fromCharCode(u0)}else{var ch=u0-65536;str+=String.fromCharCode(55296|ch>>10,56320|ch&1023)}}}return str}function UTF8ToString(ptr,maxBytesToRead){return ptr?UTF8ArrayToString(HEAPU8,ptr,maxBytesToRead):""}function stringToUTF8Array(str,heap,outIdx,maxBytesToWrite){if(!(maxBytesToWrite>0))return 0;var startIdx=outIdx;var endIdx=outIdx+maxBytesToWrite-1;for(var i=0;i<str.length;++i){var u=str.charCodeAt(i);if(u>=55296&&u<=57343){var u1=str.charCodeAt(++i);u=65536+((u&1023)<<10)|u1&1023}if(u<=127){if(outIdx>=endIdx)break;heap[outIdx++]=u}else if(u<=2047){if(outIdx+1>=endIdx)break;heap[outIdx++]=192|u>>6;heap[outIdx++]=128|u&63}else if(u<=65535){if(outIdx+2>=endIdx)break;heap[outIdx++]=224|u>>12;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}else{if(outIdx+3>=endIdx)break;heap[outIdx++]=240|u>>18;heap[outIdx++]=128|u>>12&63;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}}heap[outIdx]=0;return outIdx-startIdx}function stringToUTF8(str,outPtr,maxBytesToWrite){return stringToUTF8Array(str,HEAPU8,outPtr,maxBytesToWrite)}function writeArrayToMemory(array,buffer){HEAP8.set(array,buffer)}var buffer,HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64;function updateGlobalBufferAndViews(buf){buffer=buf;Module["HEAP8"]=HEAP8=new Int8Array(buf);Module["HEAP16"]=HEAP16=new Int16Array(buf);Module["HEAP32"]=HEAP32=new Int32Array(buf);Module["HEAPU8"]=HEAPU8=new Uint8Array(buf);Module["HEAPU16"]=HEAPU16=new Uint16Array(buf);Module["HEAPU32"]=HEAPU32=new Uint32Array(buf);Module["HEAPF32"]=HEAPF32=new Float32Array(buf);Module["HEAPF64"]=HEAPF64=new Float64Array(buf)}var INITIAL_MEMORY=Module["INITIAL_MEMORY"]||16777216;var wasmTable;var __ATPRERUN__=[];var __ATINIT__=[];var __ATPOSTRUN__=[];var runtimeInitialized=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 initRuntime(){runtimeInitialized=true;callRuntimeCallbacks(__ATINIT__)}function postRun(){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 addOnInit(cb){__ATINIT__.unshift(cb)}function addOnPostRun(cb){__ATPOSTRUN__.unshift(cb)}var runDependencies=0;var runDependencyWatcher=null;var dependenciesFulfilled=null;function addRunDependency(id){runDependencies++;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}}function removeRunDependency(id){runDependencies--;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}if(runDependencies==0){if(runDependencyWatcher!==null){clearInterval(runDependencyWatcher);runDependencyWatcher=null}if(dependenciesFulfilled){var callback=dependenciesFulfilled;dependenciesFulfilled=null;callback()}}}Module["preloadedImages"]={};Module["preloadedAudios"]={};function abort(what){{if(Module["onAbort"]){Module["onAbort"](what)}}what="Aborted("+what+")";err(what);ABORT=true;EXITSTATUS=1;what+=". Build with -s ASSERTIONS=1 for more info.";var e=new WebAssembly.RuntimeError(what);readyPromiseReject(e);throw e}var dataURIPrefix="data:application/octet-stream;base64,";function isDataURI(filename){return filename.startsWith(dataURIPrefix)}var wasmBinaryFile;wasmBinaryFile="lnsocket.wasm";if(!isDataURI(wasmBinaryFile)){wasmBinaryFile=locateFile(wasmBinaryFile)}function getBinary(file){try{if(file==wasmBinaryFile&&wasmBinary){return new Uint8Array(wasmBinary)}if(readBinary){return readBinary(file)}else{throw"both async and sync fetching of the wasm failed"}}catch(err){abort(err)}}function getBinaryPromise(){if(!wasmBinary&&(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER)){if(typeof fetch=="function"){return fetch(wasmBinaryFile,{credentials:"same-origin"}).then(function(response){if(!response["ok"]){throw"failed to load wasm binary file at '"+wasmBinaryFile+"'"}return response["arrayBuffer"]()}).catch(function(){return getBinary(wasmBinaryFile)})}}return Promise.resolve().then(function(){return getBinary(wasmBinaryFile)})}function createWasm(){var info={"a":asmLibraryArg};function receiveInstance(instance,module){var exports=instance.exports;Module["asm"]=exports;wasmMemory=Module["asm"]["i"];updateGlobalBufferAndViews(wasmMemory.buffer);wasmTable=Module["asm"]["m"];addOnInit(Module["asm"]["j"]);removeRunDependency("wasm-instantiate")}addRunDependency("wasm-instantiate");function receiveInstantiationResult(result){receiveInstance(result["instance"])}function instantiateArrayBuffer(receiver){return getBinaryPromise().then(function(binary){return WebAssembly.instantiate(binary,info)}).then(function(instance){return instance}).then(receiver,function(reason){err("failed to asynchronously prepare wasm: "+reason);abort(reason)})}function instantiateAsync(){if(!wasmBinary&&typeof WebAssembly.instantiateStreaming=="function"&&!isDataURI(wasmBinaryFile)&&typeof fetch=="function"){return fetch(wasmBinaryFile,{credentials:"same-origin"}).then(function(response){var result=WebAssembly.instantiateStreaming(response,info);return result.then(receiveInstantiationResult,function(reason){err("wasm streaming compile failed: "+reason);err("falling back to ArrayBuffer instantiation");return instantiateArrayBuffer(receiveInstantiationResult)})})}else{return instantiateArrayBuffer(receiveInstantiationResult)}}if(Module["instantiateWasm"]){try{var exports=Module["instantiateWasm"](info,receiveInstance);return exports}catch(e){err("Module.instantiateWasm callback failed with error: "+e);return false}}instantiateAsync().catch(readyPromiseReject);return{}}var ASM_CONSTS={70236:function(){return Module.getRandomValue()},70272:function(){if(Module.getRandomValue===undefined){try{var window_="object"===typeof window?window:self;var crypto_=typeof window_.crypto!=="undefined"?window_.crypto:window_.msCrypto;var randomValuesStandard=function(){var buf=new Uint32Array(1);crypto_.getRandomValues(buf);return buf[0]>>>0};randomValuesStandard();Module.getRandomValue=randomValuesStandard}catch(e){try{var crypto=require("crypto");var randomValueNodeJS=function(){var buf=crypto["randomBytes"](4);return(buf[0]<<24|buf[1]<<16|buf[2]<<8|buf[3])>>>0};randomValueNodeJS();Module.getRandomValue=randomValueNodeJS}catch(e){throw"No secure random number generator found"}}}}};function callRuntimeCallbacks(callbacks){while(callbacks.length>0){var callback=callbacks.shift();if(typeof callback=="function"){callback(Module);continue}var func=callback.func;if(typeof func=="number"){if(callback.arg===undefined){getWasmTableEntry(func)()}else{getWasmTableEntry(func)(callback.arg)}}else{func(callback.arg===undefined?null:callback.arg)}}}function getWasmTableEntry(funcPtr){return wasmTable.get(funcPtr)}function ___assert_fail(condition,filename,line,func){abort("Assertion failed: "+UTF8ToString(condition)+", at: "+[filename?UTF8ToString(filename):"unknown filename",line,func?UTF8ToString(func):"unknown function"])}function _abort(){abort("")}var readAsmConstArgsArray=[];function readAsmConstArgs(sigPtr,buf){readAsmConstArgsArray.length=0;var ch;buf>>=2;while(ch=HEAPU8[sigPtr++]){var readAsmConstArgsDouble=ch<105;if(readAsmConstArgsDouble&&buf&1)buf++;readAsmConstArgsArray.push(readAsmConstArgsDouble?HEAPF64[buf++>>1]:HEAP32[buf]);++buf}return readAsmConstArgsArray}function _emscripten_asm_const_int(code,sigPtr,argbuf){var args=readAsmConstArgs(sigPtr,argbuf);return ASM_CONSTS[code].apply(null,args)}function _emscripten_memcpy_big(dest,src,num){HEAPU8.copyWithin(dest,src,src+num)}function abortOnCannotGrowMemory(requestedSize){abort("OOM")}function _emscripten_resize_heap(requestedSize){var oldSize=HEAPU8.length;requestedSize=requestedSize>>>0;abortOnCannotGrowMemory(requestedSize)}var SYSCALLS={buffers:[null,[],[]],printChar:function(stream,curr){var buffer=SYSCALLS.buffers[stream];if(curr===0||curr===10){(stream===1?out:err)(UTF8ArrayToString(buffer,0));buffer.length=0}else{buffer.push(curr)}},varargs:undefined,get:function(){SYSCALLS.varargs+=4;var ret=HEAP32[SYSCALLS.varargs-4>>2];return ret},getStr:function(ptr){var ret=UTF8ToString(ptr);return ret},get64:function(low,high){return low}};function _fd_close(fd){return 0}function _fd_seek(fd,offset_low,offset_high,whence,newOffset){}function _fd_write(fd,iov,iovcnt,pnum){var num=0;for(var i=0;i<iovcnt;i++){var ptr=HEAP32[iov>>2];var len=HEAP32[iov+4>>2];iov+=8;for(var j=0;j<len;j++){SYSCALLS.printChar(fd,HEAPU8[ptr+j])}num+=len}HEAP32[pnum>>2]=num;return 0}var asmLibraryArg={"a":___assert_fail,"b":_abort,"h":_emscripten_asm_const_int,"g":_emscripten_memcpy_big,"c":_emscripten_resize_heap,"f":_fd_close,"d":_fd_seek,"e":_fd_write};var asm=createWasm();var ___wasm_call_ctors=Module["___wasm_call_ctors"]=function(){return(___wasm_call_ctors=Module["___wasm_call_ctors"]=Module["asm"]["j"]).apply(null,arguments)};var _malloc=Module["_malloc"]=function(){return(_malloc=Module["_malloc"]=Module["asm"]["k"]).apply(null,arguments)};var _free=Module["_free"]=function(){return(_free=Module["_free"]=Module["asm"]["l"]).apply(null,arguments)};var _lnsocket_make_default_initmsg=Module["_lnsocket_make_default_initmsg"]=function(){return(_lnsocket_make_default_initmsg=Module["_lnsocket_make_default_initmsg"]=Module["asm"]["n"]).apply(null,arguments)};var _lnsocket_encrypt=Module["_lnsocket_encrypt"]=function(){return(_lnsocket_encrypt=Module["_lnsocket_encrypt"]=Module["asm"]["o"]).apply(null,arguments)};var _lnsocket_decrypt=Module["_lnsocket_decrypt"]=function(){return(_lnsocket_decrypt=Module["_lnsocket_decrypt"]=Module["asm"]["p"]).apply(null,arguments)};var _lnsocket_decrypt_header=Module["_lnsocket_decrypt_header"]=function(){return(_lnsocket_decrypt_header=Module["_lnsocket_decrypt_header"]=Module["asm"]["q"]).apply(null,arguments)};var _lnsocket_make_ping_msg=Module["_lnsocket_make_ping_msg"]=function(){return(_lnsocket_make_ping_msg=Module["_lnsocket_make_ping_msg"]=Module["asm"]["r"]).apply(null,arguments)};var _lnsocket_msgbuf=Module["_lnsocket_msgbuf"]=function(){return(_lnsocket_msgbuf=Module["_lnsocket_msgbuf"]=Module["asm"]["s"]).apply(null,arguments)};var _lnsocket_create=Module["_lnsocket_create"]=function(){return(_lnsocket_create=Module["_lnsocket_create"]=Module["asm"]["t"]).apply(null,arguments)};var _lnsocket_destroy=Module["_lnsocket_destroy"]=function(){return(_lnsocket_destroy=Module["_lnsocket_destroy"]=Module["asm"]["u"]).apply(null,arguments)};var _lnsocket_secp=Module["_lnsocket_secp"]=function(){return(_lnsocket_secp=Module["_lnsocket_secp"]=Module["asm"]["v"]).apply(null,arguments)};var _lnsocket_genkey=Module["_lnsocket_genkey"]=function(){return(_lnsocket_genkey=Module["_lnsocket_genkey"]=Module["asm"]["w"]).apply(null,arguments)};var _lnsocket_setkey=Module["_lnsocket_setkey"]=function(){return(_lnsocket_setkey=Module["_lnsocket_setkey"]=Module["asm"]["x"]).apply(null,arguments)};var _lnsocket_print_errors=Module["_lnsocket_print_errors"]=function(){return(_lnsocket_print_errors=Module["_lnsocket_print_errors"]=Module["asm"]["y"]).apply(null,arguments)};var _lnsocket_act_two=Module["_lnsocket_act_two"]=function(){return(_lnsocket_act_two=Module["_lnsocket_act_two"]=Module["asm"]["z"]).apply(null,arguments)};var _commando_make_rpc_msg=Module["_commando_make_rpc_msg"]=function(){return(_commando_make_rpc_msg=Module["_commando_make_rpc_msg"]=Module["asm"]["A"]).apply(null,arguments)};var _lnsocket_act_one=Module["_lnsocket_act_one"]=function(){return(_lnsocket_act_one=Module["_lnsocket_act_one"]=Module["asm"]["B"]).apply(null,arguments)};var stackSave=Module["stackSave"]=function(){return(stackSave=Module["stackSave"]=Module["asm"]["C"]).apply(null,arguments)};var stackRestore=Module["stackRestore"]=function(){return(stackRestore=Module["stackRestore"]=Module["asm"]["D"]).apply(null,arguments)};var stackAlloc=Module["stackAlloc"]=function(){return(stackAlloc=Module["stackAlloc"]=Module["asm"]["E"]).apply(null,arguments)};Module["ccall"]=ccall;Module["cwrap"]=cwrap;var calledRun;dependenciesFulfilled=function runCaller(){if(!calledRun)run();if(!calledRun)dependenciesFulfilled=runCaller};function run(args){args=args||arguments_;if(runDependencies>0){return}preRun();if(runDependencies>0){return}function doRun(){if(calledRun)return;calledRun=true;Module["calledRun"]=true;if(ABORT)return;initRuntime();readyPromiseResolve(Module);if(Module["onRuntimeInitialized"])Module["onRuntimeInitialized"]();postRun()}if(Module["setStatus"]){Module["setStatus"]("Running...");setTimeout(function(){setTimeout(function(){Module["setStatus"]("")},1);doRun()},1)}else{doRun()}}Module["run"]=run;if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].pop()()}}run();
     10 
     11 
     12   return Module.ready
     13 }
     14 );
     15 })();
     16 if (typeof exports === 'object' && typeof module === 'object')
     17   module.exports = Module;
     18 else if (typeof define === 'function' && define['amd'])
     19   define([], function() { return Module; });
     20 else if (typeof exports === 'object')
     21   exports["Module"] = Module;
     22 
     23 async function lnsocket_init() {
     24 	const module = await Module()
     25 
     26 	function SocketImpl(host) {
     27 		if (!(this instanceof SocketImpl))
     28 			return new SocketImpl(host)
     29 
     30 		if (typeof WebSocket !== 'undefined') {
     31 			console.log("WebSocket", typeof WebSocket)
     32 			const ok = host.startsWith("ws://") || host.startsWith("wss://")
     33 			if (!ok)
     34 				throw new Error("host must start with ws:// or wss://")
     35 			const ws = new WebSocket(host)
     36 			ws.ondata = function(fn) {
     37 				ws.onmessage = (v) => {
     38 					const data = v.data.arrayBuffer()
     39 					fn(data)
     40 				}
     41 			}
     42 			return ws
     43 		}
     44 
     45 		//
     46 		// we're in nodejs
     47 		//
     48 		const net = require('net')
     49 		let [hostname,port] = host.split(":")
     50 		port = +port || 9735
     51 		const socket = net.createConnection(port, hostname, () => {
     52 			socket.emit("open")
     53 		})
     54 		socket.addEventListener = socket.on.bind(socket)
     55 
     56 		if (socket.onmessage)
     57 			throw new Error("socket already has onmessage?")
     58 
     59 		socket.ondata = (fn) => {
     60 			socket.on('data', fn)
     61 		}
     62 
     63 		socket.close = () => {
     64 			socket.destroy()
     65 		}
     66 
     67 		if (socket.send)
     68 			throw new Error("socket already has send?")
     69 
     70 		socket.send = function socket_send(data) {
     71 			return new Promise((resolve, reject) => {
     72 				socket.write(data, resolve)
     73 			});
     74 		}
     75 
     76 		return socket
     77 	}
     78 
     79 	const ACT_ONE_SIZE = 50
     80 	const ACT_TWO_SIZE = 50
     81 	const ACT_THREE_SIZE = 66
     82 	const DEFAULT_TIMEOUT = 15000
     83 
     84 	const COMMANDO_REPLY_CONTINUES = 0x594b
     85 	const COMMANDO_REPLY_TERM = 0x594d
     86 
     87 	const lnsocket_create = module.cwrap("lnsocket_create", "number")
     88 	const lnsocket_destroy = module.cwrap("lnsocket_destroy", "number")
     89 	const lnsocket_encrypt = module.cwrap("lnsocket_encrypt", "number", ["int", "array", "int", "int"])
     90 	const lnsocket_decrypt = module.cwrap("lnsocket_decrypt", "number", ["int", "array", "int"])
     91 	const lnsocket_decrypt_header = module.cwrap("lnsocket_decrypt_header", "number", ["number", "array"])
     92 	const lnsocket_msgbuf = module.cwrap("lnsocket_msgbuf", "number", ["int"])
     93 	const lnsocket_act_one = module.cwrap("lnsocket_act_one", "number", ["number", "string"])
     94 	const lnsocket_act_two = module.cwrap("lnsocket_act_two", "number", ["number", "array"])
     95 	const lnsocket_print_errors = module.cwrap("lnsocket_print_errors", "int")
     96 	const lnsocket_genkey = module.cwrap("lnsocket_genkey", null, ["number"])
     97 	const lnsocket_setkey = module.cwrap("lnsocket_setkey", "number", ["number", "array"])
     98 	const lnsocket_make_default_initmsg = module.cwrap("lnsocket_make_default_initmsg", "int", ["int", "int"])
     99 	const lnsocket_make_ping_msg = module.cwrap("lnsocket_make_ping_msg", "int", ["int", "int", "int", "int"])
    100 	const commando_make_rpc_msg = module.cwrap("commando_make_rpc_msg", "int", ["string", "string", "string", "number", "int", "int"])
    101 
    102 	function concat_u8_arrays(arrays) {
    103 		// sum of individual array lengths
    104 		let totalLength = arrays.reduce((acc, value) =>
    105 			acc + (value.length || value.byteLength)
    106 		, 0);
    107 
    108 		if (!arrays.length) return null;
    109 
    110 		let result = new Uint8Array(totalLength);
    111 
    112 		let length = 0;
    113 		for (let array of arrays) {
    114 			if (array instanceof ArrayBuffer)
    115 				result.set(new Uint8Array(array), length);
    116 			else
    117 				result.set(array, length);
    118 
    119 			length += (array.length || array.byteLength);
    120 		}
    121 
    122 		return result;
    123 	}
    124 
    125 	function parse_msgtype(buf) {
    126 		return buf[0] << 8 | buf[1]
    127 	}
    128 
    129 	function wasm_free(buf) {
    130 		module._free(buf);
    131 	}
    132 
    133 	function char_to_hex(cstr) {
    134 		const c = cstr.charCodeAt(0)
    135 		// c >= 0 && c <= 9
    136 		if (c >= 48 && c <= 57) {
    137 			return c - 48;
    138 		}
    139 		// c >= a && c <= f
    140 		if (c >= 97 && c <= 102) {
    141 			return c - 97 + 10;
    142 		}
    143 		// c >= A && c <= F
    144 		if (c >= 65 && c <= 70) {
    145 			return c - 65 + 10;
    146 		}
    147 		return -1;
    148 	}
    149 
    150 
    151 	function hex_decode(str, buflen)
    152 	{
    153 		let bufsize = buflen || 33
    154 		let c1, c2
    155 		let i = 0
    156 		let j = 0
    157 		let buf = new Uint8Array(bufsize)
    158 		let slen = str.length
    159 		while (slen > 1) {
    160 			if (-1==(c1 = char_to_hex(str[j])) || -1==(c2 = char_to_hex(str[j+1])))
    161 				return null;
    162 			if (!bufsize)
    163 				return null;
    164 			j += 2
    165 			slen -= 2
    166 			buf[i++] = (c1 << 4) | c2
    167 			bufsize--;
    168 		}
    169 
    170 		return buf
    171 	}
    172 
    173 	function wasm_alloc(len) {
    174 		const buf = module._malloc(len);
    175 		module.HEAPU8.set(Uint8Array, buf);
    176 		return buf
    177 	}
    178 
    179 	function wasm_mem(ptr, size) {
    180 		return new Uint8Array(module.HEAPU8.buffer, ptr, size);
    181 	}
    182 
    183 	function LNSocket(opts) {
    184 		if (!(this instanceof LNSocket))
    185 			return new LNSocket(opts)
    186 
    187 		this.opts = opts || {
    188 			timeout: DEFAULT_TIMEOUT
    189 		}
    190 		this.queue = []
    191 		this.ln = lnsocket_create()
    192 	}
    193 
    194 	LNSocket.prototype.queue_recv = function() {
    195 		let self = this
    196 		return new Promise((resolve, reject) => {
    197 			const checker = setInterval(() => {
    198 				const val = self.queue.shift()
    199 				if (val) {
    200 					clearInterval(checker)
    201 					resolve(val)
    202 				} else if (!self.connected) {
    203 					clearInterval(checker)
    204 					reject()
    205 				}
    206 			}, 5);
    207 		})
    208 	}
    209 
    210 	LNSocket.prototype.print_errors = function _lnsocket_print_errors() {
    211 		lnsocket_print_errors(this.ln)
    212 	}
    213 
    214 	LNSocket.prototype.genkey = function _lnsocket_genkey() {
    215 		lnsocket_genkey(this.ln)
    216 	}
    217 
    218 	LNSocket.prototype.setkeyraw = function lnsocket_setkeyraw(rawkey) {
    219 		return lnsocket_setkey(this.ln, rawkey)
    220 	}
    221 
    222 	LNSocket.prototype.setkey = function _lnsocket_setkey(key) {
    223 		const rawkey = hex_decode(key)
    224 		return this.setkeyraw(rawkey)
    225 	}
    226 
    227 	LNSocket.prototype.act_one_data = function _lnsocket_act_one(node_id) {
    228 		const act_one_ptr = lnsocket_act_one(this.ln, node_id)
    229 		if (act_one_ptr === 0)
    230 			return null
    231 		return wasm_mem(act_one_ptr, ACT_ONE_SIZE)
    232 	}
    233 
    234 	LNSocket.prototype.act_two = function _lnsocket_act_two(act2) {
    235 		const act_three_ptr = lnsocket_act_two(this.ln, new Uint8Array(act2))
    236 		if (act_three_ptr === 0) {
    237 			this.print_errors()
    238 			return null
    239 		}
    240 		return wasm_mem(act_three_ptr, ACT_THREE_SIZE)
    241 	}
    242 
    243 	LNSocket.prototype.connect = async function lnsocket_connect(node_id, host) {
    244 		await handle_connect(this, node_id, host)
    245 
    246 		const act1 = this.act_one_data(node_id)
    247 		this.ws.send(act1)
    248 		const act2 = await this.read_all(ACT_TWO_SIZE)
    249 		if (act2.length != ACT_TWO_SIZE) {
    250 			throw new Error(`expected act2 to be ${ACT_TWO_SIZE} long, got ${act2.length}`)
    251 		}
    252 		const act3 = this.act_two(act2)
    253 		this.ws.send(act3)
    254 	}
    255 
    256 	LNSocket.prototype.connect_and_init = async function _connect_and_init(node_id, host) {
    257 		await this.connect(node_id, host)
    258 		await this.perform_init()
    259 	}
    260 
    261 	LNSocket.prototype.read_all = async function read_all(n) {
    262 		let count = 0
    263 		let chunks = []
    264 		if (!this.connected)
    265 			throw new Error("read_all: not connected")
    266 		while (true) {
    267 			let res = await this.queue_recv()
    268 
    269 			const remaining = n - count
    270 
    271 			if (res.byteLength > remaining) {
    272 				chunks.push(res.slice(0, remaining))
    273 				this.queue.unshift(res.slice(remaining))
    274 				break
    275 			} else if (res.byteLength === remaining) {
    276 				chunks.push(res)
    277 				break
    278 			}
    279 
    280 			chunks.push(res)
    281 			count += res.byteLength
    282 		}
    283 
    284 		return concat_u8_arrays(chunks)
    285 	}
    286 
    287 	LNSocket.prototype.read_header = async function read_header() {
    288 		const header = await this.read_all(18)
    289 		if (header.length != 18)
    290 			throw new Error("Failed to read header")
    291 		return lnsocket_decrypt_header(this.ln, header)
    292 	}
    293 
    294 	LNSocket.prototype.rpc = async function lnsocket_rpc(opts) {
    295 		const msg = this.make_commando_msg(opts)
    296 		this.write(msg)
    297 		const res = await this.read_all_rpc()
    298 		return JSON.parse(res)
    299 	}
    300 
    301 	LNSocket.prototype.recv = async function lnsocket_recv() {
    302 		const msg = await this.read()
    303 		const msgtype = parse_msgtype(msg.slice(0,2))
    304 		const res = [msgtype, msg.slice(2)]
    305 		return res
    306 	}
    307 
    308 	LNSocket.prototype.read_all_rpc = async function read_all_rpc() {
    309 		let chunks = []
    310 		while (true) {
    311 			const [typ, msg] = await this.recv()
    312 			switch (typ) {
    313 			case COMMANDO_REPLY_TERM:
    314 				chunks.push(msg.slice(8))
    315 				return new TextDecoder().decode(concat_u8_arrays(chunks));
    316 			case COMMANDO_REPLY_CONTINUES:
    317 				chunks.push(msg.slice(8))
    318 				break
    319 			default:
    320 				console.log("got unknown type", typ)
    321 				continue
    322 			}
    323 		}
    324 	}
    325 
    326 	LNSocket.prototype.make_commando_msg = function _lnsocket_make_commando_msg(opts) {
    327 		const buflen = 4096
    328 		let len = 0;
    329 		const buf = wasm_alloc(buflen);
    330 
    331 		const params = JSON.stringify(opts.params||{})
    332 		if (!(len = commando_make_rpc_msg(opts.method, params, opts.rune,
    333 			0, buf, buflen))) {
    334 			throw new Error("couldn't make commando msg");
    335 		}
    336 
    337 		const dat = wasm_mem(buf, len)
    338 		wasm_free(buf);
    339 		return dat
    340 	}
    341 
    342 	LNSocket.prototype.make_ping_msg = function _lnsocket_make_ping_msg(num_pong_bytes=1, ignored_bytes=1)  {
    343 		const buflen = 32
    344 		let len = 0;
    345 		const buf = wasm_alloc(buflen)
    346 
    347 		if (!(len = lnsocket_make_ping_msg(buf, buflen, num_pong_bytes, ignored_bytes)))
    348 			throw new Error("couldn't make ping msg");
    349 
    350 		const dat = wasm_mem(buf, len)
    351 		wasm_free(buf);
    352 		return dat
    353 	}
    354 
    355 	LNSocket.prototype.encrypt = function _lnsocket_encrypt(dat) {
    356 		const len = lnsocket_encrypt(this.ln, dat, dat.length)
    357 		if (len === 0) {
    358 			this.print_errors()
    359 			throw new Error("encrypt error")
    360 		}
    361 		const enc = wasm_mem(lnsocket_msgbuf(this.ln), len)
    362 		return enc
    363 	}
    364 
    365 	LNSocket.prototype.decrypt = function _lnsocket_decrypt(dat) {
    366 		const len = lnsocket_decrypt(this.ln, dat, dat.length)
    367 		if (len === 0) {
    368 			this.print_errors()
    369 			throw new Error("decrypt error")
    370 		}
    371 		return wasm_mem(lnsocket_msgbuf(this.ln), len)
    372 	}
    373 
    374 	LNSocket.prototype.write = function _lnsocket_write(dat) {
    375 		this.ws.send(this.encrypt(dat))
    376 	}
    377 
    378 	LNSocket.prototype.read = async function _lnsocket_read() {
    379 		const size = await this.read_header()
    380 		const enc = await this.read_all(size+16)
    381 		return this.decrypt(enc)
    382 	}
    383 
    384 	LNSocket.prototype.make_default_initmsg = function _lnsocket_make_default_initmsg() {
    385 		const buflen = 1024
    386 		let len = 0;
    387 		const buf = module._malloc(buflen);
    388 		module.HEAPU8.set(Uint8Array, buf);
    389 
    390 		if (!(len = lnsocket_make_default_initmsg(buf, buflen)))
    391 			throw new Error("couldn't make initmsg");
    392 
    393 		const dat = wasm_mem(buf, len)
    394 		module._free(buf);
    395 		return dat
    396 	}
    397 
    398 	LNSocket.prototype.perform_init = async function lnsocket_connect() {
    399 		await this.read()
    400 		const our_init = this.make_default_initmsg()
    401 		this.write(our_init)
    402 	}
    403 
    404 	LNSocket.prototype.ping_pong = async function lnsocket_ping_pong() {
    405 		const pingmsg = this.make_ping_msg()
    406 		this.write(pingmsg)
    407 		return await this.read()
    408 	}
    409 
    410 	LNSocket.prototype.disconnect = function lnsocket_disconnect() {
    411 		if (this.connected === true && this.ws) {
    412 			this.ws.close()
    413 			return true
    414 		}
    415 		return false
    416 	}
    417 
    418 	LNSocket.prototype.destroy = function _lnsocket_destroy() {
    419 		this.disconnect()
    420 		lnsocket_destroy(this.ln)
    421 	}
    422 
    423 	function handle_connect(ln, node_id, host) {
    424 		const ws = new SocketImpl(host)
    425 		return new Promise((resolve, reject) => {
    426 			const timeout = ln.opts.timeout || DEFAULT_TIMEOUT
    427 			const timer = setTimeout(reject, timeout);
    428 
    429 			ws.ondata((v) => {
    430 				ln.queue.push(v)
    431 			});
    432 
    433 			ws.addEventListener('open', function(ev) {
    434 				ln.ws = ws
    435 				ln.connected = true
    436 				clearTimeout(timer)
    437 				resolve(ws)
    438 			});
    439 
    440 			ws.addEventListener('close', function(ev) {
    441 				ln.connected = false
    442 			});
    443 		})
    444 	}
    445 
    446 	return LNSocket
    447 }
    448 
    449 Module.init = Module.lnsocket_init = lnsocket_init