libnemo
Version:
Asynchronous, non-blocking Nano cryptocurrency integration toolkit.
52 lines • 359 kB
JavaScript
var __create=Object.create;var __defProp=Object.defineProperty;var __getOwnPropDesc=Object.getOwnPropertyDescriptor;var __getOwnPropNames=Object.getOwnPropertyNames;var __getProtoOf=Object.getPrototypeOf,__hasOwnProp=Object.prototype.hasOwnProperty;var __esm=(fn,res)=>function(){return fn&&(res=(0,fn[__getOwnPropNames(fn)[0]])(fn=0)),res};var __commonJS=(cb,mod)=>function(){return mod||(0,cb[__getOwnPropNames(cb)[0]])((mod={exports:{}}).exports,mod),mod.exports};var __export=(target,all)=>{for(var name in all)__defProp(target,name,{get:all[name],enumerable:!0})},__copyProps=(to,from2,except,desc)=>{if(from2&&typeof from2=="object"||typeof from2=="function")for(let key of __getOwnPropNames(from2))!__hasOwnProp.call(to,key)&&key!==except&&__defProp(to,key,{get:()=>from2[key],enumerable:!(desc=__getOwnPropDesc(from2,key))||desc.enumerable});return to};var __toESM=(mod,isNodeMode,target)=>(target=mod!=null?__create(__getProtoOf(mod)):{},__copyProps(isNodeMode||!mod||!mod.__esModule?__defProp(target,"default",{value:mod,enumerable:!0}):target,mod));var Blake2b,init_blake2b=__esm({"src/lib/blake2b.ts"(){"use strict";//! SPDX-FileCopyrightText: 2025 Chris Duncan <chris@zoso.dev>
//! SPDX-License-Identifier: GPL-3.0-or-later AND ISC
Blake2b=class _Blake2b{static get OUTBYTES_MIN(){return 1}static get OUTBYTES_MAX(){return 64}static get KEYBYTES_MIN(){return 1}static get KEYBYTES_MAX(){return 64}static get SALTBYTES(){return 16}static get PERSONALBYTES(){return 16}static get IV(){return[0x6a09e667f3bcc908n,0xbb67ae8584caa73bn,0x3c6ef372fe94f82bn,0xa54ff53a5f1d36f1n,0x510e527fade682d1n,0x9b05688c2b3e6c1fn,0x1f83d9abfb41bd6bn,0x5be0cd19137e2179n]}static get SIGMA(){return[[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15],[14,10,4,8,9,15,13,6,1,12,0,2,11,7,5,3],[11,8,12,0,5,2,15,13,10,14,3,6,7,1,9,4],[7,9,3,1,13,12,11,14,2,6,5,10,4,0,15,8],[9,0,5,7,2,4,10,15,14,1,11,12,6,8,3,13],[2,12,6,10,0,11,8,3,4,13,7,5,15,14,1,9],[12,5,1,15,14,13,4,10,0,7,6,3,9,2,8,11],[13,11,7,14,12,1,3,9,5,0,15,4,8,6,2,10],[6,15,14,9,11,3,0,8,12,2,13,7,1,4,10,5],[10,2,8,4,7,6,1,5,15,11,9,14,3,12,13,0],[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15],[14,10,4,8,9,15,13,6,1,12,0,2,11,7,5,3]]}static#toHex(buf){let str="";for(let i=0;i<buf.length;i++)str+=buf[i].toString(16).padStart(2,"0");return str}#G(r,i,a,b,c,d){this.#v[a]+=this.#v[b]+this.#m[_Blake2b.SIGMA[r][2*i+0]],this.#v[d]^=this.#v[a],this.#v[d]=this.#v[d]>>32n|this.#v[d]<<32n,this.#v[c]+=this.#v[d],this.#v[b]^=this.#v[c],this.#v[b]=this.#v[b]>>24n|this.#v[b]<<40n,this.#v[a]+=this.#v[b]+this.#m[_Blake2b.SIGMA[r][2*i+1]],this.#v[d]^=this.#v[a],this.#v[d]=this.#v[d]>>16n|this.#v[d]<<48n,this.#v[c]+=this.#v[d],this.#v[b]^=this.#v[c],this.#v[b]=this.#v[b]>>63n|this.#v[b]<<1n}#ROUND(r){this.#G(r,0,0,4,8,12),this.#G(r,1,1,5,9,13),this.#G(r,2,2,6,10,14),this.#G(r,3,3,7,11,15),this.#G(r,4,0,5,10,15),this.#G(r,5,1,6,11,12),this.#G(r,6,2,7,8,13),this.#G(r,7,3,4,9,14)}#blake2bCompress(final){for(let i=0;i<8;i++)this.#v[i]=this.#h[i],this.#v[i+8]=_Blake2b.IV[i];this.#v[12]^=this.#t&(1n<<64n)-1n,this.#v[13]^=this.#t&(1n<<128n)-(1n<<64n),final&&(this.#v[14]=~this.#v[14]);let buf=new DataView(this.#b.buffer);for(let i=0;i<16;i++)this.#m[i]=buf.getBigUint64(i*8,!0);for(let i=0;i<12;i++)this.#ROUND(i);for(let i=0;i<8;i++)this.#h[i]^=this.#v[i]^this.#v[i+8]}#blake2bUpdate(input){for(let i=0;i<input.length;i++)this.#c===this.#b.byteLength&&(this.#t+=BigInt(this.#b.byteLength),this.#c=0,this.#blake2bCompress(!1)),this.#b[this.#c++]=input[i]}#blake2bFinal(out){this.#t+=BigInt(this.#c),this.#b.fill(0,this.#c),this.#blake2bCompress(!0);let data2=new DataView(this.#h.buffer);for(let i=0;i<this.#outlen;i++)out[i]=data2.getUint8(i)}#parameter_block=new Uint8Array([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]);#parameter_view=new DataView(this.#parameter_block.buffer);#b=new Uint8Array(128);#h=new BigUint64Array(8);#t=0n;#c=0;#v=new BigUint64Array(16);#m=new BigUint64Array(16);#outlen;constructor(length,key,salt,personal){if(length==null)throw new TypeError("length is required");if(typeof length!="number")throw new TypeError("length must be number");if(length<_Blake2b.OUTBYTES_MIN||length>_Blake2b.OUTBYTES_MAX)throw new RangeError(`length must be ${_Blake2b.OUTBYTES_MIN}-${_Blake2b.OUTBYTES_MAX} bytes`);if(key!=null){if(!(key instanceof Uint8Array))throw new TypeError("key must be Uint8Array or Buffer");if(key.length<_Blake2b.KEYBYTES_MIN||key.length>_Blake2b.KEYBYTES_MAX)throw new RangeError(`key must be ${_Blake2b.KEYBYTES_MIN}-${_Blake2b.KEYBYTES_MAX} bytes`)}if(salt!=null){if(!(salt instanceof Uint8Array))throw new TypeError("salt must be Uint8Array or Buffer");if(salt.length!==_Blake2b.SALTBYTES)throw new RangeError(`salt must be ${_Blake2b.SALTBYTES} bytes`)}if(personal!=null){if(!(personal instanceof Uint8Array))throw new TypeError("personal must be Uint8Array or Buffer");if(personal.length!==_Blake2b.PERSONALBYTES)throw new RangeError(`personal must be ${_Blake2b.PERSONALBYTES} bytes`)}this.#outlen=length,this.#parameter_block[0]=length,this.#parameter_block[1]=key?.length??0,this.#parameter_block[2]=1,this.#parameter_block[3]=1,salt&&this.#parameter_block.set(salt,32),personal&&this.#parameter_block.set(personal,48);for(let i=0;i<8;i++)this.#h[i]=_Blake2b.IV[i]^this.#parameter_view.getBigUint64(i*8,!0);key&&(this.#blake2bUpdate(key),this.#c=128)}update(input){if(!(input instanceof Uint8Array))throw new TypeError("input must be Uint8Array or Buffer");return this.#blake2bUpdate(input),this}digest(out){let buf=!out||out==="binary"||out==="hex"?new Uint8Array(this.#outlen):out;if(!(buf instanceof Uint8Array))throw new TypeError('out must be "binary", "hex", Uint8Array, or Buffer');if(buf.length<this.#outlen)throw new RangeError("out must have at least outlen bytes of space");return this.#blake2bFinal(buf),out==="hex"?_Blake2b.#toHex(buf):buf}}}});var ALPHABET,BURN_ADDRESS,PREAMBLE,PREFIX,PREFIX_LEGACY,DIFFICULTY_RECEIVE,DIFFICULTY_SEND,LEDGER_STATUS_CODES,LEDGER_ADPU_CODES,UNITS,init_constants=__esm({"src/lib/constants.ts"(){"use strict";//! SPDX-FileCopyrightText: 2025 Chris Duncan <chris@zoso.dev>
//! SPDX-License-Identifier: GPL-3.0-or-later
ALPHABET="13456789abcdefghijkmnopqrstuwxyz",BURN_ADDRESS="nano_1111111111111111111111111111111111111111111111111111hifc8npp",PREAMBLE="0000000000000000000000000000000000000000000000000000000000000006",PREFIX="nano_",PREFIX_LEGACY="xrb_",DIFFICULTY_RECEIVE=0xfffffe0000000000n,DIFFICULTY_SEND=0xfffffff800000000n,LEDGER_STATUS_CODES=Object.freeze({26368:"INCORRECT_LENGTH",26378:"NO_APPLICATION_SPECIFIED",26631:"APPLICATION_NOT_INSTALLED",27904:"APPLICATION_ALREADY_LAUNCHED",27010:"SECURITY_STATUS_NOT_SATISFIED",27013:"CONDITIONS_OF_USE_NOT_SATISFIED",27265:"INVALID_SIGNATURE",27266:"CACHE_MISS",27392:"INCORRECT_PARAMETER",28161:"TRANSPORT_STATUS_ERROR",36864:"OK"}),LEDGER_ADPU_CODES=Object.freeze({class:161,bip32DerivationLevel:3,version:1,account:2,cacheBlock:3,signBlock:4,signNonce:5,paramUnused:0}),UNITS=Object.freeze({RAW:0,RAI:24,NYANO:24,KRAI:27,PICO:27,MRAI:30,NANO:30,KNANO:33,MNANO:36})}});var base32,bin,bytes,dec,hex,obj,utf8,convert_default,init_convert=__esm({"src/lib/convert.ts"(){"use strict";init_constants();//! SPDX-FileCopyrightText: 2025 Chris Duncan <chris@zoso.dev>
//! SPDX-License-Identifier: GPL-3.0-or-later
base32=class{static toBytes(base322){let leftover=base322.length*5%8,offset=leftover===0?0:8-leftover,bits=0,value=0,index=0,output=new Uint8Array(Math.ceil(base322.length*5/8));for(let i=0;i<base322.length;i++)value=value<<5|ALPHABET.indexOf(base322[i]),bits+=5,bits>=8&&(output[index++]=value>>>bits+offset-8&255,bits-=8);return bits>0&&(output[index++]=value<<bits+offset-8&255),leftover!==0&&(output=output.slice(1)),output}},bin=class{static toBytes(bin2){let bytes3=[];for(;bin2.length>0;){let bits=bin2.substring(0,8);bytes3.push(parseInt(bits,2)),bin2=bin2.substring(8)}return new Uint8Array(bytes3)}},bytes=class{static#decoder=new TextDecoder;static erase(bytes3){if(bytes3!=null){if(bytes3 instanceof ArrayBuffer){if(bytes3.detached)return;bytes3=new Uint8Array(bytes3)}bytes3.buffer.detached||(bytes3.fill(0),bytes3.buffer.transfer())}}static toBase32(bytes3){let leftover=bytes3.length*8%5,offset=leftover===0?0:5-leftover,value=0,output="",bits=0;for(let i=0;i<bytes3.length;i++)for(value=value<<8|bytes3[i],bits+=8;bits>=5;)output+=ALPHABET[value>>>bits+offset-5&31],bits-=5;return bits>0&&(output+=ALPHABET[value<<5-(bits+offset)&31]),output}static toBin(bytes3){return[...bytes3].map(b=>b.toString(2).padStart(8,"0")).join("")}static toDec(bytes3){let integers=[];bytes3.reverse().forEach(b=>integers.push(BigInt(b)));let decimal=0n;for(let i=0;i<integers.length;i++)decimal+=integers[i]<<BigInt(i*8);return decimal>9007199254740991n?decimal:Number(decimal)}static toHex(bytes3){return bytes3.buffer instanceof ArrayBuffer&&bytes3.buffer.detached?"":[...bytes3].map(byte=>byte.toString(16).padStart(2,"0")).join("").toUpperCase()}static toUtf8(bytes3){return this.#decoder.decode(bytes3)}},dec=class{static toBin(decimal,padding=0){if(typeof padding!="number")throw new TypeError("Invalid padding");try{return BigInt(decimal).toString(2).padStart(padding,"0")}catch{throw new RangeError("Invalid decimal integer")}}static toBytes(decimal,padding=0){if(decimal==null)throw new TypeError(`Failed to convert '${decimal}' from decimal to bytes`);if(typeof padding!="number")throw new TypeError("Invalid padding");let integer=BigInt(decimal),bytes3=[];for(;integer>0;){let lsb=BigInt.asUintN(8,integer);bytes3.push(Number(lsb)),integer>>=8n}let result2=new Uint8Array(Math.max(padding,bytes3.length));return result2.set(bytes3),result2.reverse()}static toHex(decimal,padding=0){if(decimal==null)throw new TypeError(`Failed to convert '${decimal}' from decimal to hex`);if(typeof padding!="number")throw new TypeError("Invalid padding");try{return BigInt(decimal).toString(16).padStart(padding,"0").toUpperCase()}catch{throw new RangeError("Invalid decimal integer")}}},hex=class{static toArray(hex2,padding=0){if(typeof hex2!="string"||!/^[A-Fa-f0-9]+$/i.test(hex2))throw new TypeError("Invalid string when converting hex to array",{cause:hex2});if(typeof padding!="number")throw new TypeError("Invalid padding when converting hex to array",{cause:padding});hex2.length%2===1&&(hex2=`0${hex2}`);let hexArray=hex2.match(/.{2}/g);if(hexArray==null)throw new RangeError("Invalid hex string when converting to array",{cause:hexArray});for(let i=hexArray.length;i<padding;i++)hexArray.unshift("0");return hexArray.map(v3=>parseInt(v3,16))}static toBin(hex2){return[...hex2].map(c=>dec.toBin(parseInt(c,16),4)).join("")}static toBytes(hex2,padding=0){return new Uint8Array(this.toArray(hex2,padding))}},obj=class{static toBytes(obj2){let values=Object.keys(obj2).map(key=>+key).sort((a,b)=>a-b).map(i=>obj2[i]);return new Uint8Array(values)}},utf8=class{static#encoder=new TextEncoder;static toBytes(utf82){return this.#encoder.encode(utf82)}static toHex(utf82){return bytes.toHex(this.toBytes(utf82))}},convert_default=`
const ALPHABET = '${ALPHABET}'
const base32 = ${base32}
const bin = ${bin}
const bytes = ${bytes}
const dec = ${dec}
const hex = ${hex}
const obj = ${obj}
const utf8 = ${utf8}
`}});var Rpc,init_rpc=__esm({"src/lib/rpc.ts"(){"use strict";//! SPDX-FileCopyrightText: 2025 Chris Duncan <chris@zoso.dev>
//! SPDX-License-Identifier: GPL-3.0-or-later
Rpc=class{#u;#n;constructor(url2,apiKeyName){this.#u=new URL(url2),this.#u.protocol="https:",this.#n=apiKeyName}async call(action,data2){var process3=process3||null;this.#validate(action);let headers={};headers["Content-Type"]="application/json",this.#n&&process3?.env?.LIBNEMO_RPC_API_KEY&&(headers[this.#n]=process3.env.LIBNEMO_RPC_API_KEY),data2??={},data2.action=action.toLowerCase();let body=JSON.stringify(data2).replaceAll("/","\\u002f").replaceAll("<","\\u003c").replaceAll(">","\\u003d").replaceAll("\\","\\u005c"),aborter=new AbortController,req=new Request(this.#u,{signal:aborter.signal,method:"POST",headers,body}),kill=setTimeout(()=>{aborter.abort()},1e4);try{let res=await fetch(req);if(res.status!==200)throw new Error(`${res.status} ${res.statusText}`);let data3=await res.json();if(data3.error!=null){let msg=data3.message==null?data3.error:`${data3.error} ${data3.message}`;throw new Error(msg)}return data3}catch(err){return JSON.stringify(err)}finally{clearTimeout(kill)}}#validate(action){if(!action)throw new ReferenceError("Action is required for RPCs");if(typeof action!="string")throw new TypeError("RPC action must be a string");if(!/^[A-Za-z]+(_[A-Za-z]+)*$/.test(action))throw new TypeError("RPC action contains invalid characters")}}}});import{parentPort}from"node:worker_threads";var WorkerInterface,init_worker_interface=__esm({"src/lib/workers/worker-interface.ts"(){"use strict";//! SPDX-FileCopyrightText: 2025 Chris Duncan <chris@zoso.dev>
//! SPDX-License-Identifier: GPL-3.0-or-later
WorkerInterface=class{static parentPort;static{this.parentPort=parentPort}static work(data2){return new Promise((resolve,reject)=>{try{if(data2==null)throw new Error("Missing data");let{x,y}=data2;resolve({x,y})}catch(err){reject(err)}})}static report(data2){let buffers=[];try{if(typeof data2=="object")for(let d of Object.keys(data2))data2[d]instanceof ArrayBuffer&&buffers.push(data2[d])}catch(err){throw new Error("Failed to report results",{cause:err})}parentPort?.postMessage(data2,buffers)}static listen(){let listener=async message=>{let{data:data2}=message;data2.method==="STOP"?(this.report({}),process.exit()):this.work(data2).then(this.report).catch(this.report)};this.parentPort?.on("message",listener)}}}});var Bip44Ckd,importWorkerThreads,bip44_ckd_default,init_bip44_ckd=__esm({"src/lib/workers/bip44-ckd.ts"(){"use strict";init_worker_interface();//! SPDX-FileCopyrightText: 2025 Chris Duncan <chris@zoso.dev>
//! SPDX-License-Identifier: GPL-3.0-or-later
Bip44Ckd=class extends WorkerInterface{static BIP44_COIN_NANO=165;static BIP44_PURPOSE=44;static HARDENED_OFFSET=2147483648;static SLIP10_ED25519="ed25519 seed";static{this.listen()}static async work(data2){if(data2.coin!=null&&(typeof data2.coin!="number"||!Number.isInteger(data2.coin)))throw new TypeError("BIP-44 coin derivation level must be an integer");if(!Array.isArray(data2.indexes)||data2.indexes.some(i=>!Number.isInteger(i)))throw new TypeError("BIP-44 account indexes must be an array of integers");if(!(data2.seed instanceof ArrayBuffer))throw new TypeError("BIP-44 seed must be an ArrayBuffer");let coin=data2.coin,indexes=Array.isArray(data2.indexes)?data2.indexes:[data2.indexes],seed=data2.seed,privateKeys={};for(let i of indexes){if(typeof i!="number"||!Number.isInteger(i))throw new TypeError("BIP-44 account derivation level must be an integer");try{let pk=await this.ckd(seed,coin,i);privateKeys[i]=pk}catch{}}return privateKeys}static async nanoCKD(seed,index){return await this.ckd(seed,this.BIP44_COIN_NANO,index)}static async ckd(seed,coin=this.BIP44_COIN_NANO,index){if(seed.byteLength<16||seed.byteLength>64)throw new RangeError("Invalid seed length");if(!Number.isSafeInteger(index)||index<0||index>2147483647)throw new RangeError(`Invalid child key index 0x${index.toString(16)}`);let masterKey=await this.slip10(this.SLIP10_ED25519,seed),purposeKey=await this.CKDpriv(masterKey,this.BIP44_PURPOSE+this.HARDENED_OFFSET),coinKey=await this.CKDpriv(purposeKey,coin+this.HARDENED_OFFSET);return(await this.CKDpriv(coinKey,index+this.HARDENED_OFFSET)).privateKey.buffer}static async slip10(curve,S){let key=new TextEncoder().encode(curve),data2=new Uint8Array(S),I=await this.hmac(key,data2),IL=new DataView(I.buffer.slice(0,I.length/2)),IR=new DataView(I.buffer.slice(I.length/2));return{privateKey:IL,chainCode:IR}}static async CKDpriv({privateKey,chainCode},index){let key=new Uint8Array(chainCode.buffer),data2=new Uint8Array(37);data2.set([0]),data2.set(this.ser256(privateKey),1),data2.set(this.ser32(index),33);let I=await this.hmac(key,data2),IL=new DataView(I.buffer.slice(0,I.length/2)),IR=new DataView(I.buffer.slice(I.length/2));return{privateKey:IL,chainCode:IR}}static ser32(integer){if(typeof integer!="number")throw new TypeError(`Expected a number, received ${typeof integer}`);if(integer>4294967295)throw new RangeError(`Expected 32-bit integer, received ${integer.toString(2).length}-bit value: ${integer}`);let view=new DataView(new ArrayBuffer(4));return view.setUint32(0,integer,!1),new Uint8Array(view.buffer)}static ser256(integer){if(!(integer instanceof DataView))throw new TypeError(`Expected DataView, received ${typeof integer}`);if(integer.byteLength>32)throw new RangeError(`Expected 32-byte integer, received ${integer.byteLength}-byte value: ${integer}`);return new Uint8Array(integer.buffer)}static async hmac(key,data2){let{subtle}=globalThis.crypto,pk=await subtle.importKey("raw",key,{name:"HMAC",hash:"SHA-512"},!1,["sign"]),signature=await subtle.sign("HMAC",pk,data2);return new Uint8Array(signature)}},importWorkerThreads="";importWorkerThreads="import { parentPort } from 'node:worker_threads'";bip44_ckd_default=`
${importWorkerThreads}
const WorkerInterface = ${WorkerInterface}
const Bip44Ckd = ${Bip44Ckd}
`}});var NanoNaCl,importWorkerThreads2,nano_nacl_default,init_nano_nacl=__esm({"src/lib/workers/nano-nacl.ts"(){"use strict";init_worker_interface();init_blake2b();init_convert();//! SPDX-FileCopyrightText: 2025 Chris Duncan <chris@zoso.dev>
//! SPDX-License-Identifier: GPL-3.0-or-later
NanoNaCl=class extends WorkerInterface{static{this.listen()}static async work(data2){if(typeof data2.method!="string"||!(data2.msg==null||data2.msg instanceof ArrayBuffer)||!(data2.privateKey==null||data2.privateKey instanceof ArrayBuffer)||!(data2.publicKey==null||data2.publicKey instanceof ArrayBuffer)||!(data2.signature==null||data2.signature instanceof ArrayBuffer))throw new TypeError("Invalid NanoNaCl input");let method=data2.method,msg=new Uint8Array(data2.msg),privateKey=new Uint8Array(data2.privateKey),publicKey=new Uint8Array(data2.publicKey),signature=new Uint8Array(data2.signature);try{switch(method){case"convert":return{publicKey:(await this.convert(privateKey)).buffer};case"detached":return{signature:(await this.detached(msg,privateKey)).buffer};case"verify":return{isVerified:await this.verify(msg,signature,publicKey)};default:throw new TypeError(`unknown NanoNaCl method ${method}`)}}catch(err){throw new Error(`NanoNaCl worker failed on ${method??"unknown method"}`,{cause:err})}}static gf=function(init5){let r=new Float64Array(16);if(init5)for(let i=0;i<init5.length;i++)r[i]=init5[i];return r};static gf0=this.gf();static gf1=this.gf([1]);static D=this.gf([30883,4953,19914,30187,55467,16705,2637,112,59544,30585,16505,36039,65139,11119,27886,20995]);static D2=this.gf([61785,9906,39828,60374,45398,33411,5274,224,53552,61171,33010,6542,64743,22239,55772,9222]);static X=this.gf([54554,36645,11616,51542,42930,38181,51040,26924,56412,64982,57905,49316,21502,52590,14035,8553]);static Y=this.gf([26200,26214,26214,26214,26214,26214,26214,26214,26214,26214,26214,26214,26214,26214,26214,26214]);static I=this.gf([41136,18958,6951,50414,58488,44335,6150,12099,55207,15867,153,11085,57099,20417,9344,11139]);static vn(x,xi,y,yi,n){let d=0;for(let i=0;i<n;i++)d|=x[xi+i]^y[yi+i];return(1&d-1>>>8)-1}static crypto_verify_32(x,xi,y,yi){return this.vn(x,xi,y,yi,32)}static set25519(r,a){for(let i=0;i<16;i++)r[i]=a[i]|0}static car25519(o){let v3,c=1;for(let i=0;i<16;i++)v3=o[i]+c+65535,c=Math.floor(v3/65536),o[i]=v3-c*65536;o[0]+=38*(c-1)}static sel25519(p,q3,b){let t,c=~(b-1);for(let i=0;i<16;i++)t=c&(p[i]^q3[i]),p[i]^=t,q3[i]^=t}static pack25519(o,n){let b,m3=this.gf(),t=this.gf();for(let i=0;i<16;i++)t[i]=n[i];this.car25519(t),this.car25519(t),this.car25519(t);for(let j=0;j<2;j++){m3[0]=t[0]-65517;for(let i=1;i<15;i++)m3[i]=t[i]-65535-(m3[i-1]>>16&1),m3[i-1]&=65535;m3[15]=t[15]-32767-(m3[14]>>16&1),b=m3[15]>>16&1,m3[14]&=65535,this.sel25519(t,m3,1-b)}for(let i=0;i<16;i++)o[2*i]=t[i]&255,o[2*i+1]=t[i]>>8}static neq25519(a,b){let c=new Uint8Array(32),d=new Uint8Array(32);return this.pack25519(c,a),this.pack25519(d,b),this.crypto_verify_32(c,0,d,0)}static par25519(a){let d=new Uint8Array(32);return this.pack25519(d,a),d[0]&1}static unpack25519(o,n){for(let i=0;i<16;i++)o[i]=n[2*i]+(n[2*i+1]<<8);o[15]&=32767}static A(o,a,b){for(let i=0;i<16;i++)o[i]=a[i]+b[i]}static Z(o,a,b){for(let i=0;i<16;i++)o[i]=a[i]-b[i]}static M(o,a,b){let v3,c,s=65536,t=new Array(31);t.fill(0);for(let i=0;i<16;i++)for(let j=0;j<16;j++)t[i+j]+=a[i]*b[j];for(let i=0;i<15;i++)t[i]+=38*t[i+16];c=1;for(let i=0;i<16;i++)v3=t[i]+c+s-1,c=Math.floor(v3/s),t[i]=v3-c*s;t[0]+=38*(c-1),c=1;for(let i=0;i<16;i++)v3=t[i]+c+s-1,c=Math.floor(v3/s),t[i]=v3-c*s;t[0]+=38*(c-1);for(let i=0;i<16;i++)o[i]=t[i]}static S(o,a){this.M(o,a,a)}static inv25519(o,i){let c=new Float64Array(16);for(let a=0;a<16;a++)c[a]=i[a];for(let a=253;a>=0;a--)this.S(c,c),a!==2&&a!==4&&this.M(c,c,i);for(let a=0;a<16;a++)o[a]=c[a]}static pow2523(o,i){let c=this.gf();for(let a=0;a<16;a++)c[a]=i[a];for(let a=250;a>=0;a--)this.S(c,c),a!==1&&this.M(c,c,i);for(let a=0;a<16;a++)o[a]=c[a]}static crypto_hash(out,m3,n){let input=new Uint8Array(n);for(let i=0;i<n;++i)input[i]=m3[i];let hash2=new Blake2b(64).update(m3).digest();for(let i=0;i<64;++i)out[i]=hash2[i];return 0}static add(p,q3){let a=this.gf(),b=this.gf(),c=this.gf(),d=this.gf(),e=this.gf(),f=this.gf(),g=this.gf(),h=this.gf(),t=this.gf();this.Z(a,p[1],p[0]),this.Z(t,q3[1],q3[0]),this.M(a,a,t),this.A(b,p[0],p[1]),this.A(t,q3[0],q3[1]),this.M(b,b,t),this.M(c,p[3],q3[3]),this.M(c,c,this.D2),this.M(d,p[2],q3[2]),this.A(d,d,d),this.Z(e,b,a),this.Z(f,d,c),this.A(g,d,c),this.A(h,b,a),this.M(p[0],e,f),this.M(p[1],h,g),this.M(p[2],g,f),this.M(p[3],e,h)}static cswap(p,q3,b){for(let i=0;i<4;i++)this.sel25519(p[i],q3[i],b)}static pack(r,p){let tx=this.gf(),ty=this.gf(),zi=this.gf();this.inv25519(zi,p[2]),this.M(tx,p[0],zi),this.M(ty,p[1],zi),this.pack25519(r,ty),r[31]^=this.par25519(tx)<<7}static scalarmult(p,q3,s){this.set25519(p[0],this.gf0),this.set25519(p[1],this.gf1),this.set25519(p[2],this.gf1),this.set25519(p[3],this.gf0);for(let i=255;i>=0;--i){let b=s[i/8|0]>>(i&7)&1;this.cswap(p,q3,b),this.add(q3,p),this.add(p,p),this.cswap(p,q3,b)}}static scalarbase(p,s){let q3=[this.gf(),this.gf(),this.gf(),this.gf()];this.set25519(q3[0],this.X),this.set25519(q3[1],this.Y),this.set25519(q3[2],this.gf1),this.M(q3[3],this.X,this.Y),this.scalarmult(p,q3,s)}static L=new Float64Array([237,211,245,92,26,99,18,88,214,156,247,162,222,249,222,20,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16]);static modL(r,x){let carry,i,j,k;for(i=63;i>=32;--i){for(carry=0,j=i-32,k=i-12;j<k;++j)x[j]+=carry-16*x[i]*this.L[j-(i-32)],carry=Math.floor((x[j]+128)/256),x[j]-=carry*256;x[j]+=carry,x[i]=0}for(carry=0,j=0;j<32;j++)x[j]+=carry-(x[31]>>4)*this.L[j],carry=x[j]>>8,x[j]&=255;for(j=0;j<32;j++)x[j]-=carry*this.L[j];for(i=0;i<32;i++)x[i+1]+=x[i]>>8,r[i]=x[i]&255}static reduce(r){let x=new Float64Array(64);for(let i=0;i<64;i++)x[i]=r[i];for(let i=0;i<64;i++)r[i]=0;this.modL(r,x)}static crypto_sign(sm,m3,n,sk,pk){let d=new Uint8Array(64),h=new Uint8Array(64),r=new Uint8Array(64),x=new Float64Array(64),p=[this.gf(),this.gf(),this.gf(),this.gf()];this.crypto_hash(d,sk,32),d[0]&=248,d[31]&=127,d[31]|=64;let smlen=n+64;for(let i=0;i<n;i++)sm[64+i]=m3[i];for(let i=0;i<32;i++)sm[32+i]=d[32+i];this.crypto_hash(r,sm.subarray(32),n+32),this.reduce(r),this.scalarbase(p,r),this.pack(sm,p);for(let i=0;i<32;i++)sm[i+32]=pk[i];this.crypto_hash(h,sm,n+64),this.reduce(h);for(let i=0;i<64;i++)x[i]=0;for(let i=0;i<32;i++)x[i]=r[i];for(let i=0;i<32;i++)for(let j=0;j<32;j++)x[i+j]+=h[i]*d[j];return this.modL(sm.subarray(32),x),smlen}static unpackneg(r,p){let t=this.gf(),chk=this.gf(),num=this.gf(),den=this.gf(),den2=this.gf(),den4=this.gf(),den6=this.gf();return this.set25519(r[2],this.gf1),this.unpack25519(r[1],p),this.S(num,r[1]),this.M(den,num,this.D),this.Z(num,num,r[2]),this.A(den,r[2],den),this.S(den2,den),this.S(den4,den2),this.M(den6,den4,den2),this.M(t,den6,num),this.M(t,t,den),this.pow2523(t,t),this.M(t,t,num),this.M(t,t,den),this.M(t,t,den),this.M(r[0],t,den),this.S(chk,r[0]),this.M(chk,chk,den),this.neq25519(chk,num)&&this.M(r[0],r[0],this.I),this.S(chk,r[0]),this.M(chk,chk,den),this.neq25519(chk,num)?-1:(this.par25519(r[0])===p[31]>>7&&this.Z(r[0],this.gf0,r[0]),this.M(r[3],r[0],r[1]),0)}static crypto_sign_open(m3,sm,n,pk){let t=new Uint8Array(32),h=new Uint8Array(64),p=[this.gf(),this.gf(),this.gf(),this.gf()],q3=[this.gf(),this.gf(),this.gf(),this.gf()];if(n<64||this.unpackneg(q3,pk))return-1;for(let i=0;i<n;i++)m3[i]=sm[i];for(let i=0;i<32;i++)m3[i+32]=pk[i];if(this.crypto_hash(h,m3,n),this.reduce(h),this.scalarmult(p,q3,h),this.scalarbase(q3,sm.subarray(32)),this.add(p,q3),this.pack(t,p),n-=64,this.crypto_verify_32(sm,0,t,0)){for(let i=0;i<n;i++)m3[i]=0;return-1}for(let i=0;i<n;i++)m3[i]=sm[i+64];return n}static crypto_sign_BYTES=64;static crypto_sign_PUBLICKEYBYTES=32;static crypto_sign_PRIVATEKEYBYTES=32;static crypto_sign_SEEDBYTES=32;static checkArrayTypes(...args){for(let i=0;i<args.length;i++)if(!(args[i]instanceof Uint8Array))throw new TypeError(`expected Uint8Array; actual ${args[i].constructor?.name??typeof args[i]}`)}static sign(msg,privateKey){if(this.checkArrayTypes(msg,privateKey),privateKey.byteLength!==this.crypto_sign_PRIVATEKEYBYTES)throw new Error(`expected key size ${this.crypto_sign_PRIVATEKEYBYTES} bytes; actual key size ${privateKey.byteLength} bytes`);let signedMsg=new Uint8Array(this.crypto_sign_BYTES+msg.length),publicKey=this.convert(privateKey);return this.crypto_sign(signedMsg,msg,msg.length,privateKey,publicKey),signedMsg}static open(signedMsg,publicKey){if(this.checkArrayTypes(signedMsg,publicKey),publicKey.length!==this.crypto_sign_PUBLICKEYBYTES)throw new Error("bad public key size");let tmp=new Uint8Array(signedMsg.length),mlen=this.crypto_sign_open(tmp,signedMsg,signedMsg.length,publicKey);if(mlen<0)return new Uint8Array(0);let m3=new Uint8Array(mlen);for(let i=0;i<m3.length;i++)m3[i]=tmp[i];return m3}static detached(msg,privateKey){let signedMsg=this.sign(msg,privateKey),sig=new Uint8Array(this.crypto_sign_BYTES);for(let i=0;i<sig.length;i++)sig[i]=signedMsg[i];return sig}static verify(msg,sig,publicKey){if(this.checkArrayTypes(msg,sig,publicKey),sig.length!==this.crypto_sign_BYTES)throw new Error("bad signature size");if(publicKey.length!==this.crypto_sign_PUBLICKEYBYTES)throw new Error("bad public key size");let sm=new Uint8Array(this.crypto_sign_BYTES+msg.length),m3=new Uint8Array(this.crypto_sign_BYTES+msg.length);for(let i=0;i<this.crypto_sign_BYTES;i++)sm[i]=sig[i];for(let i=0;i<msg.length;i++)sm[i+this.crypto_sign_BYTES]=msg[i];return this.crypto_sign_open(m3,sm,sm.length,publicKey)>=0}static convert(seed){if(typeof seed=="string"&&(seed=hex.toBytes(seed)),this.checkArrayTypes(seed),seed.length!==this.crypto_sign_SEEDBYTES)throw new Error("bad seed size");let pk=new Uint8Array(this.crypto_sign_PUBLICKEYBYTES),p=[this.gf(),this.gf(),this.gf(),this.gf()],hash2=new Uint8Array(64);return this.crypto_hash(hash2,seed,64),hash2[0]&=248,hash2[31]&=127,hash2[31]|=64,this.scalarbase(p,hash2),this.pack(pk,p),pk}},importWorkerThreads2="";importWorkerThreads2="import { parentPort } from 'node:worker_threads'";nano_nacl_default=`
${importWorkerThreads2}
${convert_default}
const Blake2b = ${Blake2b}
const WorkerInterface = ${WorkerInterface}
const NanoNaCl = ${NanoNaCl}
`}});var Entropy,init_entropy=__esm({"src/lib/entropy.ts"(){"use strict";init_convert();//! SPDX-FileCopyrightText: 2025 Chris Duncan <chris@zoso.dev>
//! SPDX-License-Identifier: GPL-3.0-or-later
Entropy=class _Entropy{static#isInternal=!1;static MIN=16;static MAX=32;static MOD=4;#bytes;get bits(){return bytes.toBin(this.#bytes)}get buffer(){return this.#bytes.buffer}get bytes(){return this.#bytes}get hex(){return bytes.toHex(this.#bytes)}constructor(bytes3){if(!_Entropy.#isInternal)throw new Error("Entropy cannot be instantiated directly. Use 'await Entropy.create()' instead.");_Entropy.#isInternal=!1,this.#bytes=bytes3}static async create(size){return new Promise(resolve=>{if(size!=null){if(typeof size!="number")throw new TypeError(`Entropy cannot use ${typeof size} as a size`);if(size<this.MIN||size>this.MAX)throw new RangeError(`Entropy must be ${this.MIN}-${this.MAX} bytes`);if(size%this.MOD!==0)throw new RangeError(`Entropy must be a multiple of ${this.MOD} bytes`)}_Entropy.#isInternal=!0,resolve(new this(globalThis.crypto.getRandomValues(new Uint8Array(size??this.MAX))))})}static async import(input){return new Promise((resolve,reject)=>{if(typeof input=="string"){if(input.length<this.MIN*2||input.length>this.MAX*2)throw new RangeError(`Entropy must be ${this.MIN*2}-${this.MAX*2} characters`);if(input.length%this.MOD*2!==0)throw new RangeError(`Entropy must be a multiple of ${this.MOD*2} characters`);if(!/^[0-9a-fA-F]+$/i.test(input))throw new RangeError("Entropy contains invalid hexadecimal characters");_Entropy.#isInternal=!0,resolve(new this(hex.toBytes(input)))}if(input instanceof ArrayBuffer){if(input.byteLength<this.MIN||input.byteLength>this.MAX)throw new Error(`Entropy must be ${this.MIN}-${this.MAX} bytes`);if(input.byteLength%this.MOD!==0)throw new RangeError(`Entropy must be a multiple of ${this.MOD} bytes`);_Entropy.#isInternal=!0,resolve(new this(new Uint8Array(input)))}if(input instanceof Uint8Array){if(!(input.buffer instanceof ArrayBuffer))throw new TypeError("Entropy imported bytes must be backed by an ArrayBuffer.");if(input.length<this.MIN||input.length>this.MAX)throw new Error(`Entropy must be ${this.MIN}-${this.MAX} bytes`);if(input.length%this.MOD!==0)throw new RangeError(`Entropy must be a multiple of ${this.MOD} bytes`);_Entropy.#isInternal=!0,resolve(new this(input))}reject(new TypeError(`Entropy cannot import ${typeof input}`))})}destroy(){try{return globalThis.crypto.getRandomValues(this.#bytes),!0}catch{return!1}}}}});var Safe,importWorkerThreads3,importFakeIndexedDb,safe_default,init_safe=__esm({"src/lib/workers/safe.ts"(){"use strict";init_worker_interface();init_constants();init_convert();init_entropy();//! SPDX-FileCopyrightText: 2025 Chris Duncan <chris@zoso.dev>
//! SPDX-License-Identifier: GPL-3.0-or-later
Safe=class extends WorkerInterface{static DB_NAME="libnemo";static DB_STORES=["Wallet","Account","Rolodex"];static ERR_MSG="Failed to store item in Safe";static#storage;static{this.listen()}static async work(data2){let{method,name,store}=data2;if(typeof method!="string")throw new TypeError("Invalid method");if(delete data2.method,name!=null&&typeof name!="string")throw new TypeError("Invalid name");if(delete data2.name,typeof store!="string")throw new TypeError("Invalid store");delete data2.store;let password=data2.password;delete data2.password,this.#storage=await this.#open(this.DB_NAME);try{switch(method){case"store":return{result:await this.store(data2,store,password)};case"fetch":return await this.fetch(name,store,password);case"export":return await this.fetch(name,store,password,!0);case"destroy":return{result:await this.destroy(data2,store)};default:throw new Error(`unknown Safe method ${method}`)}}catch(err){throw new Error("Safe error",{cause:err})}}static async destroy(data2,store){try{return await this.#delete(Object.keys(data2),store)}catch{throw new Error(this.ERR_MSG)}}static async store(data2,store,password){if(this.#isDataValid(data2),typeof store!="string"||store==="")throw new Error("Invalid database store name");if(!(password instanceof ArrayBuffer))throw new Error("Invalid password");let records=[];try{let salt=await Entropy.create(),encryptionKey=await this.#createAesKey("encrypt",password,salt.buffer);for(let label of Object.keys(data2)){let iv=await Entropy.create(),encrypted=await globalThis.crypto.subtle.encrypt({name:"AES-GCM",iv:iv.buffer},encryptionKey,data2[label]),record={iv:iv.buffer,salt:salt.buffer,label,encrypted};records.push(record)}return await this.#put(records,store)}catch{throw new Error(this.ERR_MSG)}finally{bytes.erase(password)}}static async fetch(name,store,password,all=!1){let names=Array.isArray(name)?name:[name];if(names.some(v3=>typeof v3!="string"))throw new Error("Invalid fields");let fields=names;if(typeof store!="string"||store==="")throw new Error("Invalid database store name");if(!(password instanceof ArrayBuffer))throw new Error("Invalid password");let results={};try{let records=all?await this.#getAll(store):await this.#get(fields,store);if(records==null)throw new Error("");let decryptionKeys={};for(let record of records){let salt=await Entropy.import(record.salt);decryptionKeys[salt.hex]??=await this.#createAesKey("decrypt",password,salt.buffer);let iv=await Entropy.import(record.iv),decrypted=await globalThis.crypto.subtle.decrypt({name:"AES-GCM",iv:iv.buffer},decryptionKeys[salt.hex],record.encrypted);results[record.label]=decrypted}return results}catch(err){throw new Error("Failed to get records",{cause:err})}finally{bytes.erase(password)}}static async#createAesKey(purpose,password,salt){let derivationKey=await globalThis.crypto.subtle.importKey("raw",password,"PBKDF2",!1,["deriveBits","deriveKey"]),derivationAlgorithm={name:"PBKDF2",hash:"SHA-512",iterations:21e4,salt},derivedKeyType={name:"AES-GCM",length:256};return await globalThis.crypto.subtle.deriveKey(derivationAlgorithm,derivationKey,derivedKeyType,!1,[purpose])}static async#delete(names,store){let transaction=this.#storage.transaction(store,"readwrite"),db=transaction.objectStore(store);return new Promise((resolve,reject)=>{let requests=names.map(name=>{let request=db.delete(name);return request.onsuccess=event=>{},request.onerror=event=>{},request});transaction.oncomplete=event=>{for(let request of requests)request?.error!=null&&reject(request.error),request.result!==void 0&&resolve(!1);resolve(!0)},transaction.onerror=event=>{reject(event.target.error)}})}static async#get(names,store){let transaction=this.#storage.transaction(store,"readonly"),db=transaction.objectStore(store);return new Promise((resolve,reject)=>{let requests=names.map(name=>{let request=db.get(name);return request.onsuccess=event=>{},request.onerror=event=>{},request});transaction.oncomplete=event=>{let results=[];for(let request of requests)request?.error==null&&request.result!=null&&results.push(request.result);resolve(results)},transaction.onerror=event=>{reject(event.target.error)}})}static async#getAll(store){let transaction=this.#storage.transaction(store,"readonly"),db=transaction.objectStore(store);return new Promise((resolve,reject)=>{let request=db.getAll();request.onsuccess=event=>{},request.onerror=event=>{},transaction.oncomplete=event=>{request?.error!=null?reject(request.error):request.result==null?reject("getAll request failed"):resolve(request.result)},transaction.onerror=event=>{reject(event.target.error)}})}static#isDataValid(data2){if(typeof data2!="object")throw new Error("Invalid data");let dataObject=data2;if(Object.keys(dataObject).some(k=>!(dataObject[k]instanceof ArrayBuffer)))throw new Error("Invalid data")}static async#open(database){return new Promise((resolve,reject)=>{let request=indexedDB.open(database,1);request.onupgradeneeded=event=>{let db=event.target.result;for(let DB_STORE of this.DB_STORES)db.objectStoreNames.contains(DB_STORE)||db.createObjectStore(DB_STORE)},request.onsuccess=event=>{resolve(event.target.result)},request.onerror=event=>{reject(new Error("Database error",{cause:event}))}})}static async#put(records,store){let transaction=this.#storage.transaction(store,"readwrite"),db=transaction.objectStore(store);return new Promise((resolve,reject)=>{let requests=records.map(record=>{let request=db.put(record,record.label);return request.onsuccess=event=>{},request.onerror=event=>{},request});transaction.oncomplete=event=>{let results=[];for(let request of requests)request?.error==null&&request.result!=null&&results.push(request.result);resolve(results.length>0)},transaction.onerror=event=>{reject(event.target.error)}})}},importWorkerThreads3="",importFakeIndexedDb="";importWorkerThreads3="import { parentPort } from 'node:worker_threads'";importFakeIndexedDb="import 'fake-indexeddb/auto'";safe_default=`
${importWorkerThreads3}
${importFakeIndexedDb}
${convert_default}
const PBKDF2_ITERATIONS = ${21e4}
const Entropy = ${Entropy}
const WorkerInterface = ${WorkerInterface}
const Safe = ${Safe}
`}});import{Worker as NodeWorker}from"node:worker_threads";var WorkerQueue,Bip44CkdWorker,NanoNaClWorker,SafeWorker,init_worker_queue=__esm({"src/lib/workers/worker-queue.ts"(){"use strict";init_bip44_ckd();init_nano_nacl();init_safe();//! SPDX-FileCopyrightText: 2025 Chris Duncan <chris@zoso.dev>
//! SPDX-License-Identifier: GPL-3.0-or-later
WorkerQueue=class _WorkerQueue{static#instances=[];static get instances(){return this.#instances}#job;#isIdle;#queue=[];#url;#worker;constructor(worker2){this.#isIdle=!0,this.#queue=[],this.#url=URL.createObjectURL(new Blob([worker2],{type:"text/javascript"})),this.#worker=new NodeWorker(worker2,{eval:!0,stderr:!1,stdout:!1}),this.#worker.on("message",message=>{this.#report(message)}),_WorkerQueue.#instances.push(this)}async assign(data2){return this.#assign(data2,task=>this.#queue.push(task))}async prioritize(data2){return this.#assign(data2,task=>this.#queue.unshift(task))}terminate(){this.#job=void 0,this.#worker.terminate()}async#assign(data2,enqueue){return new Promise(async(resolve,reject)=>{let task={id:performance.now(),data:data2,resolve,reject};await enqueue(task),this.#isIdle&&this.#process()})}#process=()=>{if(this.#job=this.#queue.shift(),this.#isIdle=this.#job==null,this.#job!=null){let{data:data2,reject}=this.#job;try{let buffers=[];for(let d of Object.keys(data2))data2[d]instanceof ArrayBuffer&&buffers.push(data2[d]);this.#worker.postMessage({data:data2},buffers)}catch(err){reject(err)}}};#report(results){if(this.#job==null)throw new Error("Worker returned results but had nowhere to report it.");let{resolve,reject}=this.#job;try{resolve(results)}catch(err){reject(err)}finally{this.#process()}}},Bip44CkdWorker=new WorkerQueue(bip44_ckd_default),NanoNaClWorker=new WorkerQueue(nano_nacl_default),SafeWorker=new WorkerQueue(safe_default)}});var init_workers=__esm({"src/lib/workers/index.ts"(){"use strict";init_worker_queue();//! SPDX-FileCopyrightText: 2025 Chris Duncan <chris@zoso.dev>
//! SPDX-License-Identifier: GPL-3.0-or-later
}});var Account,AccountList,init_account=__esm({"src/lib/account.ts"(){"use strict";init_blake2b();init_constants();init_convert();init_rpc();init_workers();//! SPDX-FileCopyrightText: 2025 Chris Duncan <chris@zoso.dev>
//! SPDX-License-Identifier: GPL-3.0-or-later
Account=class _Account{static#isInternal=!1;#address;#index;#publicKey;#balance;#frontier;#receivable;#representative;#weight;get address(){return`${PREFIX}${this.#address}`}get index(){return this.#index}get publicKey(){return bytes.toHex(this.#publicKey)}get balance(){return this.#balance}get frontier(){return this.#frontier}get receivable(){return this.#receivable}get representative(){return this.#representative}get weight(){return this.#weight}set balance(v3){this.#balance=v3?BigInt(v3):void 0}set frontier(v3){this.#frontier=v3}set receivable(v3){this.#receivable=v3?BigInt(v3):void 0}set representative(v3){if(v3 instanceof _Account)this.#representative=v3;else if(typeof v3=="string")this.#representative=_Account.import(v3);else throw new TypeError(`Invalid argument for account representative: ${v3}`)}set weight(v3){this.#weight=v3?BigInt(v3):void 0}constructor(address,publicKey,index){if(!_Account.#isInternal)throw new Error("Account cannot be instantiated directly. Use factory methods instead.");this.#address=address.replace(PREFIX,"").replace(PREFIX_LEGACY,""),this.#publicKey=typeof publicKey=="string"?hex.toBytes(publicKey):publicKey,this.#index=index}async destroy(){await SafeWorker.assign({method:"destroy",store:"Account",[this.publicKey]:this.publicKey}),this.#frontier=void 0,this.#balance=void 0,this.#receivable=void 0,this.#representative=void 0,this.#weight=void 0}static import(input,password){let isInputArray=Array.isArray(input),inputs=isInputArray?input:[input];return this.#isKeyPairs(inputs)&&password!=null?new Promise((resolve,reject)=>{this.#fromPrivate(inputs,password).then(r=>resolve(isInputArray?r:r[0])).catch(e=>reject(e))}):isInputArray?this.#fromPublic(inputs):this.#fromPublic(inputs)[0]}async export(password,format){typeof password=="string"&&(password=utf8.toBytes(password));try{let privateKey=await this.#export(password);return format==="hex"?bytes.toHex(privateKey):privateKey}catch{throw new Error("Failed to export Account private key")}finally{bytes.erase(password)}}async refresh(rpc){if((typeof rpc=="string"||rpc instanceof URL)&&(rpc=new Rpc(rpc)),!(rpc instanceof Rpc))throw new TypeError("RPC must be a valid node");let data2={account:this.address,receivable:!0,representative:!0,weight:!0},{balance,frontier,receivable,representative,weight}=await rpc.call("account_info",data2);if(frontier==null)throw new Error("Account not found");this.#balance=BigInt(balance),this.#frontier=frontier,this.#receivable=BigInt(receivable),this.#representative=await _Account.import(representative),this.#weight=BigInt(weight)}async sign(block,password){typeof password=="string"&&(password=utf8.toBytes(password));try{let{signature}=await NanoNaClWorker.assign({method:"detached",privateKey:(await this.#export(password)).buffer,msg:hex.toBytes(block.hash).buffer});return block.signature=bytes.toHex(new Uint8Array(signature)),block.signature}catch(err){throw new Error("Failed to sign block",{cause:err})}finally{bytes.erase(password)}}static validate(address){if(address===void 0)throw new ReferenceError("Address is undefined.");if(typeof address!="string")throw new TypeError("Address must be a string.");if(!new RegExp(`^(${PREFIX}|${PREFIX_LEGACY})[13]{1}[${ALPHABET}]{59}$`).test(address))throw new RangeError("Invalid address format");let expectedChecksum=address.slice(-8),keyBase32=address.slice(address.indexOf("_")+1,-8),keyBuf=base32.toBytes(keyBase32),actualChecksumBuf=new Blake2b(5).update(keyBuf).digest();actualChecksumBuf.reverse();let actualChecksum=bytes.toBase32(actualChecksumBuf);if(expectedChecksum!==actualChecksum)throw new Error("Incorrect address checksum")}static#addressToKey(address){let publicKey=base32.toBytes(address.slice(-60,-8)),checksum=base32.toBytes(address.slice(-8)),rechecksum=new Blake2b(5).update(publicKey).digest().reverse();if(bytes.toHex(checksum)!==bytes.toHex(rechecksum))throw new Error("Checksum mismatch in address");return publicKey}async#export(password){if(typeof password=="string"&&(password=utf8.toBytes(password)),password==null||!(password instanceof Uint8Array))throw new Error("Password must be string or bytes");try{let response=await SafeWorker.assign({method:"fetch",name:this.publicKey,store:"Account",password:password.buffer});return new Uint8Array(response[this.publicKey])}catch(err){throw new Error(`Failed to export private key for Account ${this.address}`,{cause:err})}finally{bytes.erase(password)}}static async#fromPrivate(keypairs,password){if(typeof password=="string"&&(password=utf8.toBytes(password)),password==null||!(password instanceof Uint8Array))throw new Error("Invalid password when importing Account");let accounts=[],privateAccounts={method:"store",store:"Account",password:password.buffer};for(let keypair of keypairs){let{index,privateKey}=keypair;if(index==null)throw new RangeError("Index missing for Account");this.#validateKey(privateKey),typeof privateKey=="string"&&(privateKey=hex.toBytes(privateKey));try{let result2=await NanoNaClWorker.assign({method:"convert",privateKey:new Uint8Array(privateKey).buffer}),publicKey=new Uint8Array(result2.publicKey);privateAccounts[bytes.toHex(publicKey)]=privateKey.buffer;let address=this.#keyToAddress(publicKey);this.#isInternal=!0,accounts.push(new this(address,publicKey,index))}catch(err){throw new Error("Failed to derive public key from private key",{cause:err})}}try{let{result:result2}=await SafeWorker.assign(privateAccounts);if(!result2)throw null;return accounts}catch(err){throw new Error("Failed to lock Accounts",{cause:err})}finally{bytes.erase(password)}}static#fromPublic(input){let keypairs=this.#isKeyPairs(input)?input:this.#isKeys(input)?input.map(i=>({publicKey:i})):[];if(keypairs.length===0)throw new TypeError("Invalid public input for Account");let accounts=[],address,publicKey,index;for(let keypair of keypairs){let keyError,addressError,key=keypair.publicKey;try{this.#validateKey(key),publicKey=typeof key=="string"?hex.toBytes(key):key,address=this.#keyToAddress(publicKey)}catch(err){keyError=err;try{this.validate(key),address=key,publicKey=this.#addressToKey(address)}catch(err2){throw addressError=err2,new TypeError("Failed to import Account from public data",{cause:{keyError,addressError}})}}index=keypair.index,this.#isInternal=!0,accounts.push(new this(address,publicKey,index))}return accounts}static#isKey(input){return typeof input=="string"||input instanceof Uint8Array&&"buffer"in input}static#isKeys(input){if(Array.isArray(input)){for(let i of input)if(!this.#isKey(i))return!1}return!0}static#isKeyPair(input){if(typeof input=="object"){let obj2=input;if("index"in obj2&&typeof obj2.index=="number"||"publicKey"in obj2&&this.#isKey(obj2.publicKey)||"privateKey"in obj2&&this.#isKey(obj2.privateKey))return!0}return!1}static#isKeyPairs(input){if(Array.isArray(input)){for(let i of input)if(!this.#isKeyPair(i))return!1}return!0}static#keyToAddress(publicKey){let checksum=new Blake2b(5).update(publicKey).digest().reverse(),encodedPublicKey=bytes.toBase32(publicKey),encodedChecksum=bytes.toBase32(checksum);return`${PREFIX}${encodedPublicKey}${encodedChecksum}`}static#validateKey(key){if(key===void 0)throw new TypeError("Key is undefined");if(typeof key!="string"&&!(key instanceof Uint8Array))throw new TypeError("Key must be a string or Uint8Array");if(typeof key=="string"){if(key.length!==64)throw new TypeError(`Key must be ${64} characters`);if(!/^[A-Fa-f0-9]{64}$/i.test(key))throw new RangeError("Key is not a valid hexadecimal value")}if(key instanceof Uint8Array){if(key.byteLength!==32)throw new TypeError(`Key must be ${32} BYTES`);if(key.every(v3=>v3===0))throw new TypeError("Key is not a valid byte array")}}},AccountList=class extends Object{get length(){return Object.keys(this).length}*[Symbol.iterator](){let indexes=Object.keys(this).map(key=>parseInt(key)).filter(index=>Number.isFinite(index)).sort((a,b)=>a-b);for(let i of indexes)yield this[i]}static{Object.defineProperty(this,"length",{enumerable:!1})}}}});function bigintAsUintNArray(int,bits,length=0){let UintTypedArray={8:Uint8Array,16:Uint16Array,32:Uint32Array,64:BigUint64Array};if(![8,16,32,64].includes(bits))throw new Error("Invalid TypedArray UintN subclass");int<0n&&(int=~(int-1n)),length=Math.max(length,Math.ceil(bigintByteLength(int)/bits));let mask=(1n<<BigInt(bits))-1n,uintArray=new UintTypedArray[bits](length);for(let i=length-1;i>=0;i--)bits===64?uintArray[i]=int&mask:uintArray[i]=Number(int&mask),int>>=BigInt(bits);return uintArray}function bigintBitLength(int){let bitLength=1n;for(;int>1n||int<-1n;)bitLength++,int>>=1n;return bitLength}function bigintByteLength(int){let byteLength=0;for(;int>0n||int<-1n;)byteLength++,int>>=8n;return byteLength}function bigintFrom(value,type){if(typeof value=="bigint")return value;if(typeof value=="boolean"||typeof value=="number")return BigInt(value);if(typeof value=="string"){let v3=value.trim().replace(/n$/,"");if(/^0[Bb][01]+$/.test(v3)||/^0[Oo][0-7]+$/.test(v3)||/^0[Xx][A-Fa-f\d]+$/.test(v3)||/^\d+$/.test(v3))return BigInt(v3);if(type==="bin"&&/^[01]+$/.test(v3))return BigInt(`0b${v3}`);if(type==="oct"&&/^[0-7]+$/.test(v3))return BigInt(`0o${v3}`);if(type==="hex"||/^\d*[A-Fa-f]+\d*$/.test(v3))return BigInt(`0x${v3}`)}throw new TypeError("can't convert string to BigInt")}function bigintRandom(max=0xFFFFFFFFFFFFFFFFn){if(typeof max!="bigint"||max<1n)throw new TypeError("Invalid max value");let randomUint8Array=new Uint8Array(bigintByteLength(max)),mask=(1n<<bigintBitLength(max))-1n,output=0n;do{output=0n,crypto.getRandomValues(randomUint8Array),output=BigInt(randomUint8Array[0]);for(let i=1;i<randomUint8Array.length;i++)output<<=8n,output+=BigInt(randomUint8Array[i]);output&=mask}while(output>max);return output}function bigintToHex(int,length=0){if(typeof length!="number")throw new TypeError("invalid length");return int.toString(16).padStart(length,"0")}function G(a,b,c,d,x,y){v[a]+=v[b]+m[x],v[d]^=v[a],v[d]=v[d]>>32n|v[d]<<32n,v[c]+=v[d],v[b]^=v[c],v[b]=v[b]>>24n|v[b]<<40n,v[a]+=v[b]+m[y],v[d]^=v[a],v[d]=v[d]>>16n|v[d]<<48n,v[c]+=v[d],v[b]^=v[c],v[b]=v[b]>>63n|v[b]<<1n}function ROUND(i){let s=blake2b_sigma[i];G(0,4,8,12,s[0],s[1]),G(1,5,9,13,s[2],s[3]),G(2,6,10,14,s[4],s[5]),G(3,7,11,15,s[6],s[7]),G(0,5,10,15,s[8],s[9]),G(1,6,11,12,s[10],s[11]),G(2,7,8,13,s[12],s[13]),G(3,4,9,14,s[14],s[15])}function init(seed,hash2){result=0n;for(let i=0;i<8;i++)v[i]=blake2b_IV[i],v[i+8]=blake2b_IV[i];v[0]^=blake2b_param,v[12]^=40n,v[14]=~v[14],mView.setBigUint64(0,seed,!0);for(let i=0;i<4;i++)mView.setBigUint64(8*(i+1),hash2[i])}function blake2b(work,hash2){init(work,bigintAsUintNArray(hash2,64,4));for(let i=0;i<12;i++)ROUND(i);result=blake2b_IV[0]^0x01010008n^v[0]^v[8]}function validate(work,hash2,difficulty,debug){return logger.isEnabled=debug,blake2b(work,hash2),{hash:bigintToHex(hash2,64),work:bigintToHex(work,16),difficulty:bigintToHex(result,16),valid:result>=difficulty?"1":"0",valid_all:result>=SEND?"1":"0",valid_receive:result>=RECEIVE?"1":"0"}}async function generate(hash2,difficulty,debug){return logger2.isEnabled=debug,new Promise((resolve,reject)=>{let check3=()=>{try{let result2=validate(bigintRandom(),hash2,difficulty,!1);for(let i=0;i<32768&&(result2=validate(bigintRandom(),hash2,difficulty,!1),result2.valid!=="1");i++