@timestope-official/bitcoinkrypton-browser 0.0.1-0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +72 -0
- package/VERSION +5 -0
- package/krypton.js +2 -0
- package/krypton.js.map +1 -0
- package/namespace.d.ts +8 -0
- package/package.json +41 -0
- package/types.d.ts +4353 -0
- package/web-babel.js +2 -0
- package/web-babel.js.map +1 -0
- package/web-offline.js +2 -0
- package/web-offline.js.map +1 -0
- package/web.esm.js +2 -0
- package/web.esm.js.map +1 -0
- package/web.js +2 -0
- package/web.js.map +1 -0
- package/worker-js.js +1 -0
- package/worker-wasm.js +1 -0
- package/worker-wasm.wasm +0 -0
- package/worker.js +2 -0
- package/worker.js.map +1 -0
package/web.esm.js
ADDED
@@ -0,0 +1,2 @@
|
|
1
|
+
if("undefined"==typeof JDB)var JDB={};!function(e){e="undefined"!=typeof e?e:{};class Class{static register(t){"undefined"!=typeof e&&(e[t.name]=t)}}Class.register(Class);class LogNative{constructor(){this._global_level=Log.TRACE;this._tag_levels={};try{if(window.localStorage)try{let t=window.localStorage.getItem("log_tag_levels");t&&"string"==typeof t&&(t=JSON.parse(t));t&&"object"==typeof t&&(this._tag_levels=t)}catch(e){console.warn("Failed to load log configuration from local storage.")}}catch(e){}}isLoggable(e,t){return e&&this._tag_levels[e]?this._tag_levels[e]<=t:this._tag_levels["*"]?this._tag_levels["*"]<=t:this._global_level<=t}setLoggable(e,t){e&&e.name&&(e=e.name);this._tag_levels[e]=t;window.localStorage&&window.localStorage.setItem("log_tag_levels",JSON.stringify(this._tag_levels))}msg(e,t,s){t&&t.name&&(t=t.name);if(this.isLoggable(t,e)){t&&s.unshift(t+":");s.unshift(`[${Log.Level.toStringTag(e)} ${(new Date).toTimeString().substr(0,8)}]`);console.error&&e>=Log.ERROR?console.error.apply(console,s):console.warn&&e>=Log.WARNING?console.warn.apply(console,s):console.info&&e>=Log.INFO?console.info.apply(console,s):console.debug&&e>=Log.DEBUG?console.debug.apply(console,s):console.trace&&e<=Log.TRACE?console.trace.apply(console,s):console.log.apply(console,s)}}}Class.register(LogNative);class IDBTools{static convertKeyRange(e){return e instanceof KeyRange?e.exactMatch?IDBKeyRange.only(e.lower):e.lower!==undefined&&e.upper===undefined?IDBKeyRange.lowerBound(e.lower,e.lowerOpen):e.upper!==undefined&&e.lower===undefined?IDBKeyRange.upperBound(e.upper,e.upperOpen):IDBKeyRange.bound(e.lower,e.upper,e.lowerOpen,e.upperOpen):e}}Class.register(IDBTools);class IDBBackend{constructor(e,t,s=null){this._db=e;this._tableName=t;this._indices=new Map;this._indicesToCreate=new Map;this._indicesToDelete=[];this._codec=s}get connected(){return this._db.connected}get _backend(){if(!this.connected)throw new Error("Requires a connected database");return this._db.backend}get indices(){return this._indices}init(e,t,s){for(const{indexName:r,upgradeCondition:n}of this._indicesToDelete)e.indexNames.contains(r)&&(null===n||!0===n||"function"==typeof n&&n(t,s))&&e.deleteIndex(r);this._indicesToDelete=[];for(const[r,{index:n,upgradeCondition:i}]of this._indicesToCreate)if(!e.indexNames.contains(r)&&(null===i||!0===i||"function"==typeof i&&i(t,s))){const t=Array.isArray(n.keyPath)?n.keyPath.join("."):n.keyPath;e.createIndex(r,t,{unique:n.unique,multiEntry:n.multiEntry})}this._indicesToCreate.clear()}decode(e,t){return e===undefined?undefined:null!==this._codec&&this._codec!==undefined?this._codec.decode(e,t):e}encode(e){return e===undefined?undefined:null!==this._codec&&this._codec!==undefined?this._codec.encode(e):e}async get(e,t={}){const s=this._backend;return new Promise((r,n)=>{const i=s.transaction([this._tableName]).objectStore(this._tableName).get(e);i.onsuccess=(s=>{try{r(t&&t.raw?s.target.result:this.decode(s.target.result,e))}catch(i){n(i)}});i.onerror=n})}async values(e=null,t=null){if(null!==e&&e instanceof Query)return e.values(this,t);e=IDBTools.convertKeyRange(e);const s=this._backend;return new Promise((r,n)=>{const i=[],o=s.transaction([this._tableName],"readonly").objectStore(this._tableName).openCursor(e);o.onsuccess=(e=>{const s=e.target.result;if(s){if(null!==t&&i.length>=t){r(i);return}try{i.push(this.decode(s.value,s.primaryKey))}catch(o){n(o)}s["continue"]()}else r(i)});o.onerror=(()=>n(o.error))})}async keys(e=null,t=null){if(null!==e&&e instanceof Query)return e.keys(this,t);e=IDBTools.convertKeyRange(e);const s=this._backend;return new Promise((r,n)=>{const i=new Set,o=s.transaction([this._tableName],"readonly").objectStore(this._tableName),a=o.openKeyCursor?o.openKeyCursor(e):o.openCursor(e);a.onsuccess=(e=>{const s=e.target.result;if(s){if(null!==t&&i.size>=t){r(i);return}i.add(s.primaryKey);s["continue"]()}else r(i)});a.onerror=(()=>n(a.error))})}keyStream(e,t=!0,s=null){s=IDBTools.convertKeyRange(s);const r=this._backend;return new Promise((n,i)=>{const o=r.transaction([this._tableName],"readonly").objectStore(this._tableName),a=o.openKeyCursor?o.openKeyCursor(s,t?"next":"prev"):o.openCursor(s,t?"next":"prev");a.onsuccess=(t=>{const s=t.target.result;if(s)try{e(s.primaryKey)?s["continue"]():n()}catch(r){i(r)}else n()});a.onerror=(()=>i(a.error))})}valueStream(e,t=!0,s=null){s=IDBTools.convertKeyRange(s);const r=this._backend;return new Promise((n,i)=>{const o=r.transaction([this._tableName],"readonly").objectStore(this._tableName).openCursor(s,t?"next":"prev");o.onsuccess=(t=>{const s=t.target.result;if(s)try{e(this.decode(s.value,s.primaryKey),s.primaryKey)?s["continue"]():n()}catch(r){i(r)}else n()});o.onerror=(()=>i(o.error))})}async maxValue(e=null){e=IDBTools.convertKeyRange(e);const t=this._backend;return new Promise((s,r)=>{const n=t.transaction([this._tableName],"readonly").objectStore(this._tableName).openCursor(e,"prev");n.onsuccess=(e=>{try{const n=e.target.result;s(n?this.decode(n.value,n.primaryKey):undefined)}catch(t){r(t)}});n.onerror=(()=>r(n.error))})}async maxKey(e=null){e=IDBTools.convertKeyRange(e);const t=this._backend;return new Promise((s,r)=>{const n=t.transaction([this._tableName],"readonly").objectStore(this._tableName),i=n.openKeyCursor?n.openKeyCursor(e,"prev"):n.openCursor(e,"prev");i.onsuccess=(()=>s(i.result?i.result.primaryKey:undefined));i.onerror=(()=>r(i.error))})}async minValue(e=null){e=IDBTools.convertKeyRange(e);const t=this._backend;return new Promise((s,r)=>{const n=t.transaction([this._tableName],"readonly").objectStore(this._tableName).openCursor(e,"next");n.onsuccess=(e=>{try{const n=e.target.result;s(n?this.decode(n.value,n.primaryKey):undefined)}catch(t){r(t)}});n.onerror=(()=>r(n.error))})}async minKey(e=null){e=IDBTools.convertKeyRange(e);const t=this._backend;return new Promise((s,r)=>{const n=t.transaction([this._tableName],"readonly").objectStore(this._tableName),i=n.openKeyCursor?n.openKeyCursor(e,"next"):n.openCursor(e,"next");i.onsuccess=(()=>s(i.result?i.result.primaryKey:undefined));i.onerror=(()=>r(i.error))})}async count(e=null){e=IDBTools.convertKeyRange(e);const t=this._backend;return new Promise((s,r)=>{let n;(n=e?t.transaction([this._tableName],"readonly").objectStore(this._tableName).count(e):t.transaction([this._tableName],"readonly").objectStore(this._tableName).count()).onsuccess=(()=>s(n.result));n.onerror=(()=>r(n.error))})}index(e){return this._indices.get(e)}get backend(){return this._db.backend}get tableName(){return this._tableName}async _apply(e){const t=this._backend;return new Promise((s,r)=>{const n=t.transaction([this._tableName],"readwrite"),i=n.objectStore(this._tableName);e._truncated&&i.clear();for(const t of e._removed)i["delete"](t);for(const[t,o]of e._modified)i.put(this.encode(o),t);n.oncomplete=(()=>s(!0));n.onerror=r;n.onabort=r})}async truncate(){const e=this._backend;return new Promise((t,s)=>{const r=e.transaction([this._tableName],"readonly").objectStore(this._tableName).clear();r.onsuccess=t;r.onerror=(()=>s(r.error))})}createIndex(e,t,s={}){let{multiEntry:r=!1,upgradeCondition:n=null,unique:i=!1}=s||{};if(this._db.connected)throw new Error("Cannot create index while connected");const o=new PersistentIndex(this,e,t=t||e,r,i);this._indices.set(e,o);this._indicesToCreate.set(e,{index:o,upgradeCondition:n})}deleteIndex(e,t={}){let{upgradeCondition:s=null}=t||{};if(this._db.connected)throw new Error("Cannot delete index while connected");this._indicesToDelete.push({indexName:e,upgradeCondition:s})}close(){return this._db.close()}async applyCombined(e){const t=new EncodedTransaction(this._tableName);e._truncated&&t.truncate();for(const s of e._removed)t.remove(s);for(const[s,r]of e._modified)t.put(s,this.encode(r));return t}isSynchronous(){return!1}}Class.register(IDBBackend);class JungleDB{constructor(e,t,s={}){if(t<=0)throw new Error("The version provided must not be less or equal to 0");this._databaseDir=e;this._dbVersion=t;this._oldDbVersion=null;this._onUpgradeNeeded=s.onUpgradeNeeded;this._connected=!1;this._objectStores=new Map;this._objectStoreBackends=new Map;this._objectStoresToDelete=[]}get _indexedDB(){return window.indexedDB||window.webkitIndexedDB||window.mozIndexedDB||window.OIndexedDB||window.msIndexedDB}connect(){if(this._db)return Promise.resolve(this._db);const e=this._indexedDB.open(this._databaseDir,this._dbVersion),t=this;return new Promise((s,r)=>{e.onsuccess=(async()=>{t._connected=!0;t._db=e.result;null!==t._oldDbVersion&&t._onUpgradeNeeded&&await t._onUpgradeNeeded(t._oldDbVersion,t._dbVersion,t);s(e.result)});e.onerror=r;e.onupgradeneeded=(s=>t._initDB(s,e))})}async _initDB(e,t){const s=e.target.result;for(const{tableName:r,upgradeCondition:n}of this._objectStoresToDelete)s.objectStoreNames.contains(r)&&(null===n||!0===n||"function"==typeof n&&n(e.oldVersion,e.newVersion))&&s.deleteObjectStore(r);this._objectStoresToDelete=[];for(const[r,{backend:n,upgradeCondition:i}]of this._objectStoreBackends){let o;o=!s.objectStoreNames.contains(r)&&(null===i||!0===i||"function"==typeof i&&i(e.oldVersion,e.newVersion))?s.createObjectStore(r):t.transaction.objectStore(r);n.init(o,e.oldVersion,e.newVersion)}this._oldDbVersion=e.oldVersion;this._objectStoreBackends.clear()}get backend(){return this._db}get connected(){return this._connected}getObjectStore(e){return this._objectStores.get(e)}static createVolatileObjectStore(e={}){const{codec:t=null}=e||{};return new ObjectStore(new InMemoryBackend("",t),null)}createObjectStore(e,t={}){const{codec:s=null,persistent:r=!0,upgradeCondition:n=null,enableLruCache:i=!0,lruCacheSize:o=CachedBackend.MAX_CACHE_SIZE,rawLruCacheSize:a=0}=t||{};if(this._connected)throw new Error("Cannot create ObjectStore while connected");if(this._objectStores.has(e))return this._objectStores.get(e);let c=null,h=c=r?new IDBBackend(this,e,s):new InMemoryBackend(e,s);r&&i&&(h=new CachedBackend(c,o,a));const l=new ObjectStore(h,this,e);this._objectStores.set(e,l);this._objectStoreBackends.set(e,{backend:c,upgradeCondition:n});return l}deleteObjectStore(e,t={}){let{upgradeCondition:s=null}=t||{};if(this._connected)throw new Error("Cannot delete ObjectStore while connected");this._objectStoresToDelete.push({tableName:e,upgradeCondition:s})}async close(){if(this._connected){this._connected=!1;this.backend.close()}}async destroy(){await this.close();return new Promise((e,t)=>{const s=this._indexedDB.deleteDatabase(this._databaseDir);s.onsuccess=e;s.onerror=t})}static async commitCombined(e,t,...s){if(e instanceof CombinedTransaction){const t=[],s=[],r=[],n=await Promise.all(e.transactions.map(e=>e.objectStore._backend.applyCombined(e)));for(const e of n){let n=e;Array.isArray(e)||(n=[e]);for(const e of n)if("function"==typeof e)t.push(e);else{s.push(e);r.push(e.tableName)}}const i=null!==e.backend?e.backend.backend:null;return new Promise((e,n)=>{if(r.length>0){const o=i.transaction(r,"readwrite");for(const e of s){const t=o.objectStore(e.tableName);e.truncated&&t.clear();for(const s of e.removed)t["delete"](s);for(const[s,r]of e.modified)t.put(r,s)}o.oncomplete=(()=>{Promise.all(t.map(e=>e())).then(()=>{e(!0)})});o.onerror=n;o.onabort=n}else Promise.all(t.map(e=>e())).then(()=>{e(!0)})})}s.push(e);s.push(t);if(!s.every(e=>e instanceof Transaction))throw new Error("Invalid arguments supplied");return new CombinedTransaction(...s).commit()}toString(){return`JungleDB{name=${this._databaseDir}}`}}JungleDB.JSON_ENCODING={};JungleDB.BINARY_ENCODING={};JungleDB.STRING_ENCODING={};JungleDB.NUMBER_ENCODING={};JungleDB.GENERIC_ENCODING={};Class.register(JungleDB);class PersistentIndex{constructor(e,t,s,r=!1,n=!1){this._objectStore=e;this._indexName=t;this._keyPath=s;this._multiEntry=r;this._unique=n}async truncate(){}get keyPath(){return this._keyPath}get multiEntry(){return this._multiEntry}get unique(){return this._unique}_index(e){return e.transaction([this._objectStore.tableName],"readonly").objectStore(this._objectStore.tableName).index(this._indexName)}async values(e=null,t=null){e=IDBTools.convertKeyRange(e);const s=await this._objectStore.backend;return new Promise((r,n)=>{const i=[],o=this._index(s).openCursor(e);o.onsuccess=(e=>{const s=e.target.result;if(s){if(null!==t&&i.length>=t){r(i);return}try{i.push(this._objectStore.decode(s.value,s.primaryKey))}catch(o){n(o)}s["continue"]()}else r(i)});o.onerror=(()=>n(o.error))})}async keys(e=null,t=null){e=IDBTools.convertKeyRange(e);const s=await this._objectStore.backend;return new Promise((r,n)=>{const i=new Set,o=this._index(s),a=o.openKeyCursor?o.openKeyCursor(e):o.openCursor(e);a.onsuccess=(e=>{const s=e.target.result;if(s){if(null!==t&&i.size>=t){r(i);return}i.add(s.primaryKey);s["continue"]()}else r(i)});a.onerror=(()=>n(a.error))})}async maxValues(e=null){e=IDBTools.convertKeyRange(e);const t=await this._objectStore.backend;return new Promise((s,r)=>{const n=[];let i=null;const o=this._index(t).openCursor(e,"prev");o.onsuccess=(e=>{const t=e.target.result;t&&null===i&&(i=t.key);if(t&&ComparisonUtils.equals(i,t.key)){try{n.push(this._objectStore.decode(t.value,t.primaryKey))}catch(o){r(o)}t["continue"]()}else s(n)});o.onerror=(()=>r(o.error))})}async maxKeys(e=null){e=IDBTools.convertKeyRange(e);const t=await this._objectStore.backend;return new Promise((s,r)=>{const n=new Set;let i=null;const o=this._index(t),a=o.openKeyCursor?o.openKeyCursor(e,"prev"):o.openCursor(e,"prev");a.onsuccess=(e=>{const t=e.target.result;t&&null===i&&(i=t.key);if(t&&ComparisonUtils.equals(i,t.key)){n.add(t.primaryKey);t["continue"]()}else s(n)});a.onerror=(()=>r(a.error))})}async minValues(e=null){e=IDBTools.convertKeyRange(e);const t=await this._objectStore.backend;return new Promise((s,r)=>{const n=[];let i=null;const o=this._index(t).openCursor(e,"next");o.onsuccess=(e=>{const t=e.target.result;t&&null===i&&(i=t.key);if(t&&ComparisonUtils.equals(i,t.key)){try{n.push(this._objectStore.decode(t.value,t.primaryKey))}catch(o){r(o)}t["continue"]()}else s(n)});o.onerror=(()=>r(o.error))})}async minKeys(e=null){e=IDBTools.convertKeyRange(e);const t=await this._objectStore.backend;return new Promise((s,r)=>{const n=new Set;let i=null;const o=this._index(t),a=o.openKeyCursor?o.openKeyCursor(e,"next"):o.openCursor(e,"next");a.onsuccess=(e=>{const t=e.target.result;t&&null===i&&(i=t.key);if(t&&ComparisonUtils.equals(i,t.key)){n.add(t.primaryKey);t["continue"]()}else s(n)});a.onerror=(()=>r(a.error))})}async keyStream(e,t=!0,s=null){s=IDBTools.convertKeyRange(s);const r=await this._objectStore.backend;return new Promise((n,i)=>{const o=this._index(r),a=o.openKeyCursor?o.openKeyCursor(s,t?"next":"prev"):o.openCursor(s,t?"next":"prev");a.onsuccess=(t=>{const s=t.target.result;if(s)try{e(s.primaryKey)?s["continue"]():n()}catch(r){i(r)}else n()});a.onerror=(()=>i(a.error))})}async valueStream(e,t=!0,s=null){s=IDBTools.convertKeyRange(s);const r=await this._objectStore.backend;return new Promise((n,i)=>{const o=this._index(r).openCursor(s,t?"next":"prev");o.onsuccess=(t=>{const s=t.target.result;if(s)try{e(this._objectStore.decode(s.value,s.primaryKey),s.primaryKey)?s["continue"]():n()}catch(r){i(r)}else n()});o.onerror=(()=>i(o.error))})}async count(e=null){e=IDBTools.convertKeyRange(e);const t=await this._objectStore.backend;return new Promise((s,r)=>{let n;(n=e?this._index(t).count(e):this._index(t).count()).onsuccess=(()=>s(n.result));n.onerror=(()=>r(n.error))})}}Class.register(PersistentIndex);Object.defineProperty(Array.prototype,"iterator",{value:function(e=!0){let t=e?0:this.length-1;return{next:()=>t>=0&&t<this.length?this[e?t++:t--]:undefined,hasNext:()=>t>=0&&t<this.length,peek:()=>t>=0&&t<this.length?this[t]:undefined}}});class Node{constructor(e=[]){this._keys=e}get keys(){return this._keys}}Class.register(Node);class LeafNode extends Node{constructor(e=[],t=[]){if(e.length!==t.length)throw new Error("Keys and records must have the same length");super(e);this._records=t;this.prevLeaf=null;this.nextLeaf=null}get records(){return this._records}isLeaf(){return!0}getItem(e,t){const s=this._keys;if(t===BTree.NEAR_MODE.GE){for(let r=0,n=s.length;r<n;++r)if(ComparisonUtils.compare(e,s[r])<=0)return r}else if(t===BTree.NEAR_MODE.LE){for(let r=s.length-1;r>=0;--r)if(ComparisonUtils.compare(e,s[r])>=0)return r}else for(let r=0,n=s.length;r<n;++r)if(ComparisonUtils.equals(e,s[r]))return r;return-1}addKey(e,t){let s=this._keys.length;for(let r=0,n=s;r<n;++r){if(ComparisonUtils.equals(e,this._keys[r]))return-1;if(ComparisonUtils.compare(e,this._keys[r])<=0){s=r;break}}this._keys.splice(s,0,e);this._records.splice(s,0,t);return s}split(){const e=Math.floor(this._keys.length/2),t=[],s=[];for(let n=0;n<e;++n){t.unshift(this._keys.pop());s.unshift(this._records.pop())}const r=new LeafNode(t,s);r.prevLeaf=this;r.nextLeaf=this.nextLeaf;null!==this.nextLeaf&&(this.nextLeaf.prevLeaf=r);this.nextLeaf=r;return r}merge(e,t,s){for(let n=0,i=e.keys.length;n<i;++n){this._keys.push(e.keys[n]);this._records.push(e.records[n])}this.nextLeaf=e.nextLeaf;null!==e.nextLeaf&&(e.nextLeaf.prevLeaf=this);e.prevLeaf=null;e.nextLeaf=null;let r=t.keys.length-1;for(let n=r;n>=0;--n)if(ComparisonUtils.equals(t.keys[n],s)){r=n;break}t.keys.splice(r,1);t.nodePointers.splice(r+1,1)}}Class.register(LeafNode);class InnerNode extends Node{constructor(e=[],t=[]){super(e);this._nodePointers=t}isLeaf(){return!1}get nodePointers(){return this._nodePointers}getItem(e){const t=this._keys.length;for(let s=0;s<t;++s)if(e<this._keys[s])return s;return this._keys.length}addKey(e,t,s){const r=this._keys.length;let n=r;for(let i=0;i<r;++i)if(ComparisonUtils.compare(e,this._keys[i])<=0){n=i;break}this._keys.splice(n,0,e);this._nodePointers.splice(n,0,t);this._nodePointers[n+1]=s}split(){const e=Math.ceil(this._keys.length/2)-1,t=[this._nodePointers.pop()],s=[];for(let r=e-1;r>=0;--r){s.unshift(this._keys.pop());t.unshift(this._nodePointers.pop())}return new InnerNode(s,t)}merge(e,t,s){const r=t.keys[s];this._keys.push(r);for(let n=0,i=e.keys.length;n<i;++n){this._keys.push(e.keys[n]);this._nodePointers.push(e.nodePointers[n])}this._nodePointers.push(e.nodePointers[e.nodePointers.length-1]);t.keys.splice(s,1);t.nodePointers.splice(s+1,1);return r}}Class.register(InnerNode);class BTree{constructor(e=7){this._root=new LeafNode;this._maxkey=e-1;this._minkyl=Math.floor(e/2);this._minkyn=Math.floor(this._maxkey/2);this._leaf=null;this._item=-1;this._key=null;this._record=null;this._length=0;this._eof=!0;this._found=!1}get length(){return this._length}get currentKey(){return this._key}get currentRecord(){return this._record}insert(e,t){const s=[];this._leaf=this._root;for(;!this._leaf.isLeaf();){s.push(this._leaf);this._item=this._leaf.getItem(e);this._leaf=this._leaf.nodePointers[this._item]}this._item=this._leaf.addKey(e,t);this._key=e;this._eof=!1;if(-1===this._item){this._found=!0;this._item=this._leaf.getItem(e,!1);this._record=this._leaf.records[this._item]}else{this._found=!1;this._record=t;this._length++;if(this._leaf.keys.length>this._maxkey){let t=this._leaf,r=this._leaf.split(),n=r.keys[0];this._item=this._leaf.getItem(e,!1);if(-1===this._item){this._leaf=this._leaf.nextLeaf;this._item=this._leaf.getItem(e,!1)}for(;;){if(0===s.length){const e=new InnerNode;e.keys[0]=n;e.nodePointers[0]=t;e.nodePointers[1]=r;this._root=e;break}const e=s.pop();e.addKey(n,t,r);if(e.keys.length<=this._maxkey)break;t=e;r=e.split();n=e.keys.pop()}}}return!this._found}remove(e){if("undefined"==typeof e){if(-1===this._item){this._eof=!0;this._found=!1;return!1}e=this._leaf.keys[this._item]}this._del(e);if(this._found){this.seek(e,BTree.NEAR_MODE.GE);this._found=!0}else{this._item=-1;this._eof=!0;this._key=null;this._record=null}return this._found}seek(e,t=BTree.NEAR_MODE.NONE){this._leaf=this._root;for(;!this._leaf.isLeaf();){this._item=this._leaf.getItem(e);this._leaf=this._leaf.nodePointers[this._item]}this._item=this._leaf.getItem(e,t);if(t===BTree.NEAR_MODE.GE&&-1===this._item&&null!==this._leaf.nextLeaf){this._leaf=this._leaf.nextLeaf;this._item=0}if(t===BTree.NEAR_MODE.LE&&-1===this._item&&null!==this._leaf.prevLeaf){this._leaf=this._leaf.prevLeaf;this._item=this._leaf.records.length-1}if(-1===this._item){this._eof=!0;this._key=null;this._found=!1;this._record=null}else{this._eof=!1;this._found=this._leaf.keys[this._item]===e;this._key=this._leaf.keys[this._item];this._record=this._leaf.records[this._item]}return!this._eof}skip(e=1){"number"!=typeof e&&(e=1);-1!==this._item&&null!==this._leaf||(this._eof=!0);if(e>0){for(;!this._eof&&this._leaf.keys.length-this._item-1<e;){e=e-this._leaf.keys.length+this._item;this._leaf=this._leaf.nextLeaf;null===this._leaf?this._eof=!0:this._item=0}this._eof||(this._item=this._item+e)}else{e=-e;for(;!this._eof&&this._item<e;){e=e-this._item-1;this._leaf=this._leaf.prevLeaf;null===this._leaf?this._eof=!0:this._item=this._leaf.keys.length-1}this._eof||(this._item=this._item-e)}if(this._eof){this._item=-1;this._found=!1;this._key=null;this._record=null}else{this._found=!0;this._key=this._leaf.keys[this._item];this._record=this._leaf.records[this._item]}return this._found}goto(e){if(e<0){this.goBottom();this._eof||this.skip(e+1)}else{this.goTop();this._eof||this.skip(e-1)}return this._found}keynum(){if(null===this._leaf||-1===this._item)return-1;let e=this._item+1,t=this._leaf;for(;null!==t.prevLeaf;)e+=(t=t.prevLeaf).keys.length;return e}goTop(){this._leaf=this._root;for(;!this._leaf.isLeaf();)this._leaf=this._leaf.nodePointers[0];if(0===this._leaf.keys.length){this._item=-1;this._eof=!0;this._found=!1;this._key=null;this._record=null}else{this._item=0;this._eof=!1;this._found=!0;this._key=this._leaf.keys[0];this._record=this._leaf.records[0]}return this._found}goBottom(){this._leaf=this._root;for(;!this._leaf.isLeaf();)this._leaf=this._leaf.nodePointers[this._leaf.nodePointers.length-1];if(0===this._leaf.keys.length){this._item=-1;this._eof=!0;this._found=!1;this._key=null;this._record=null}else{this._item=this._leaf.keys.length-1;this._eof=!1;this._found=!0;this._key=this._leaf.keys[this._item];this._record=this._leaf.records[this._item]}return this._found}pack(){let e,t;this.goTop(0);if(this._leaf===this._root)return!1;let s=new LeafNode,r=0,n=this._leaf,i=0,o=[],a=[];for(;;){s.keys[r]=n.keys[i];s.records[r]=n.records[i];0===r&&a.push(s);if(i===n.keys.length-1){if(null===n.nextLeaf)break;n=n.nextLeaf;i=0}else i++;if(r===this._maxkey-1){const e=new LeafNode;s.nextLeaf=e;e.prevLeaf=s;s=e;r=0}else r++}let c,h,l=this._minkyl-s.keys.length;n=s.prevLeaf;if(l>0&&null!==n)for(t=l-1;t>=0;--t){s.keys.unshift(n.keys.pop());s.records.unshift(n.records.pop())}for(t=1,e=a.length;t<e;++t)o.push(a[t].keys[0]);o[o.length]=null;for(;null!==o[0];){c=o;h=a;o=[];a=[];r=this._maxkey+1;t=0;e=c.length;for(;t<e;t++){if(r>this._maxkey){s=new InnerNode;r=0;a.push(s)}s.keys[r]=c[t];s.nodePointers[r]=h[t];r++}if((l=this._minkyn-s.keys.length+1)>0&&a.length>1){n=a[a.length-2];for(t=l-1;t>=0;--t){s.keys.unshift(n.keys.pop());s.nodePointers.unshift(n.nodePointers.pop())}}t=0;e=a.length;for(;t<e;++t)o.push(a[t].keys.pop())}this._root=a[0];this.goTop();return this._found}_del(e){const t=[];let s,r=null,n=-1;this._leaf=this._root;for(;!this._leaf.isLeaf();){t.push(this._leaf);r=this._leaf;n=this._leaf.getItem(e);this._leaf=this._leaf.nodePointers[n]}this._item=this._leaf.getItem(e,!1);if(-1===this._item){this._found=!1;return}this._found=!0;this._leaf.keys.splice(this._item,1);this._leaf.records.splice(this._item,1);this._length--;if(this._leaf===this._root)return;if(this._leaf.keys.length>=this._minkyl){0===this._item&&BTree._fixNodes(t,e,this._leaf.keys[0]);return}let i=0===n?null:r.nodePointers[n-1];if(null!==i&&i.keys.length>this._minkyl){s=0===this._item?e:this._leaf.keys[0];this._leaf.keys.unshift(i.keys.pop());this._leaf.records.unshift(i.records.pop());BTree._fixNodes(t,s,this._leaf.keys[0]);return}let o=n===r.keys.length?null:r.nodePointers[n+1];if(null!==o&&o.keys.length>this._minkyl){this._leaf.keys.push(o.keys.shift());this._leaf.records.push(o.records.shift());0===this._item&&BTree._fixNodes(t,e,this._leaf.keys[0]);BTree._fixNodes(t,this._leaf.keys[this._leaf.keys.length-1],o.keys[0]);return}if(null!==i){s=0===this._item?e:this._leaf.keys[0];i.merge(this._leaf,r,s);this._leaf=i}else{s=o.keys[0];this._leaf.merge(o,r,s);0===this._item&&BTree._fixNodes(t,e,this._leaf.keys[0])}if(1===t.length&&0===r.keys.length){this._root=this._leaf;return}let a,c=t.pop();for(;c.keys.length<this._minkyn&&t.length>0;){if(null!==(o=(a=(r=t.pop()).getItem(s))===r.keys.length?null:r.nodePointers[a+1])&&o.keys.length>this._minkyn){c.keys.push(r.keys[a]);r.keys[a]=o.keys.shift();c.nodePointers.push(o.nodePointers.shift());break}if(null!==(i=0===a?null:r.nodePointers[a-1])&&i.keys.length>this._minkyn){c.keys.unshift(r.keys[a-1]);r.keys[a-1]=i.keys.pop();c.nodePointers.unshift(i.nodePointers.pop());break}if(null!==i){s=i.merge(c,r,a-1);c=i}else null!==o&&(s=c.merge(o,r,a));if(0===t.length&&0===r.keys.length){this._root=c;break}c=r}}static _fixNodes(e,t,s){let r,n=e.length,i=!0;do{for(let o=(r=e[--n].keys).length-1;o>=0;--o)if(r[o]===t){r[o]=s;i=!1;break}}while(i&&n>0)}goToLowerBound(e,t=!1){if(e!==undefined){let s=this.seek(e,BTree.NEAR_MODE.GE);s&&t&&ComparisonUtils.equals(e,this.currentKey)&&(s=this.skip());return s}return this.goTop()}goToUpperBound(e,t=!1){if(e!==undefined){let s=this.seek(e,BTree.NEAR_MODE.LE);s&&t&&ComparisonUtils.equals(e,this.currentKey)&&(s=this.skip(-1));return s}return this.goBottom()}}BTree.NEAR_MODE={NONE:0,LE:1,GE:2};Class.register(BTree);class BufferUtils{static _codePointTextDecoder(e){if("undefined"==typeof TextDecoder)throw new Error("TextDecoder not supported");if(null===BufferUtils._ISO_8859_15_DECODER)throw new Error("TextDecoder does not supprot iso-8859-15");if(BufferUtils._ISO_8859_15_DECODER===undefined)try{BufferUtils._ISO_8859_15_DECODER=new TextDecoder("iso-8859-15")}finally{BufferUtils._ISO_8859_15_DECODER=null}return BufferUtils._ISO_8859_15_DECODER.decode(e).replace("€","¤").replace("Š","¦").replace("š","¨").replace("Ž","´").replace("ž","¸").replace("Œ","¼").replace("œ","½").replace("Ÿ","¾")}static _tripletToBase64(e){return BufferUtils._BASE64_LOOKUP[e>>18&63]+BufferUtils._BASE64_LOOKUP[e>>12&63]+BufferUtils._BASE64_LOOKUP[e>>6&63]+BufferUtils._BASE64_LOOKUP[63&e]}static _base64encodeChunk(e,t,s){let r;const n=[];for(let i=t;i<s;i+=3){r=(e[i]<<16&16711680)+(e[i+1]<<8&65280)+(255&e[i+2]);n.push(BufferUtils._tripletToBase64(r))}return n.join("")}static _base64fromByteArray(e){let t;const s=e.length,r=s%3;let n="";const i=[];for(let o=0,a=s-r;o<a;o+=16383)i.push(BufferUtils._base64encodeChunk(e,o,o+16383>a?a:o+16383));if(1===r){t=e[s-1];n+=BufferUtils._BASE64_LOOKUP[t>>2];n+=BufferUtils._BASE64_LOOKUP[t<<4&63];n+="=="}else if(2===r){t=(e[s-2]<<8)+e[s-1];n+=BufferUtils._BASE64_LOOKUP[t>>10];n+=BufferUtils._BASE64_LOOKUP[t>>4&63];n+=BufferUtils._BASE64_LOOKUP[t<<2&63];n+="="}i.push(n);return i.join("")}static toBase64(e){if("undefined"!=typeof Buffer&&"undefined"==typeof window)return Buffer.from(e).toString("base64");if("undefined"!=typeof TextDecoder&&null!==BufferUtils._ISO_8859_15_DECODER)try{return btoa(BufferUtils._codePointTextDecoder(new Uint8Array(e)))}catch(t){}return BufferUtils._base64fromByteArray(new Uint8Array(e))}static fromBase64(e){if(!/^([0-9a-zA-Z+/]{4})*(([0-9a-zA-Z+/]{2}==)|([0-9a-zA-Z+/]{3}=))?$/.test(e))throw new Error("Invalid base64");return Uint8Array.from(atob(e),e=>e.charCodeAt(0))}static toBase64lex(e){const t=BufferUtils.toBase64(e);let s="";for(let r=0;r<t.length;r++)s+=BufferUtils.BASE64_TO_BASE64_LEX[t[r]];return s}static fromBase64lex(e){let t="";for(let s=0;s<e.length;s++)t+=BufferUtils.BASE64_LEX_TO_BASE64[e[s]];return BufferUtils.fromBase64(t)}static equals(e,t){if(e.length!==t.length)return!1;const s=new Uint8Array(e),r=new Uint8Array(t);for(let n=0;n<e.length;n++)if(s[n]!==r[n])return!1;return!0}static compare(e,t){if(e.length<t.length)return-1;if(e.length>t.length)return 1;for(let s=0;s<e.length;s++){if(e[s]<t[s])return-1;if(e[s]>t[s])return 1}return 0}}BufferUtils.BASE64_ALPHABET="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";BufferUtils._BASE64_LOOKUP=[];for(let t=0,s=BufferUtils.BASE64_ALPHABET.length;t<s;++t)BufferUtils._BASE64_LOOKUP[t]=BufferUtils.BASE64_ALPHABET[t];BufferUtils.BASE64_LEX_ALPHABET="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~";BufferUtils.BASE64_TO_BASE64_LEX={"=":"-"};BufferUtils.BASE64_LEX_TO_BASE64={"-":"="};for(let t=0,s=BufferUtils.BASE64_ALPHABET.length;t<s;++t){BufferUtils.BASE64_TO_BASE64_LEX[BufferUtils.BASE64_ALPHABET[t]]=BufferUtils.BASE64_LEX_ALPHABET[t];BufferUtils.BASE64_LEX_TO_BASE64[BufferUtils.BASE64_LEX_ALPHABET[t]]=BufferUtils.BASE64_ALPHABET[t]}Class.register(BufferUtils);class ComparisonUtils{static equals(e,t){return e===t||(e instanceof Set&&t instanceof Set?e.equals(t):!(!ComparisonUtils.isUint8Array(e)||!ComparisonUtils.isUint8Array(t))&&BufferUtils.equals(new Uint8Array(e),new Uint8Array(t)))}static compare(e,t){return ComparisonUtils.isUint8Array(e)&&ComparisonUtils.isUint8Array(t)?BufferUtils.compare(new Uint8Array(e),new Uint8Array(t)):e<t?-1:e>t?1:0}static isUint8Array(e){return"undefined"!=typeof Buffer&&"undefined"==typeof window&&e instanceof Buffer||(ArrayBuffer.isView(e)||e instanceof ArrayBuffer)}}Class.register(ComparisonUtils);class JSONUtils{static stringify(e){return JSON.stringify(e,JSONUtils.jsonifyType)}static parse(e){return JSON.parse(e,JSONUtils.parseType)}static parseType(e,t){if(t&&t[JSONUtils.TYPE_SYMBOL])switch(t[JSONUtils.TYPE_SYMBOL]){case"Uint8Array":return BufferUtils.fromBase64(t[JSONUtils.VALUE_SYMBOL]);case"Set":return Set.from(t[JSONUtils.VALUE_SYMBOL])}return t}static jsonifyType(e,t){return t instanceof Uint8Array?JSONUtils.typedObject("Uint8Array",BufferUtils.toBase64(t)):t instanceof Set?JSONUtils.typedObject("Set",Array.from(t)):t}static typedObject(e,t){const s={};s[JSONUtils.TYPE_SYMBOL]=e;s[JSONUtils.VALUE_SYMBOL]=t;return s}}JSONUtils.TYPE_SYMBOL="__";JSONUtils.VALUE_SYMBOL="value";Class.register(JSONUtils);class Log{static get instance(){Log._instance||(Log._instance=new Log(new LogNative));return Log._instance}constructor(e){this._native=e}setLoggable(e,t){this._native.setLoggable(e,t)}get level(){return this._native._global_level}set level(e){this._native._global_level=e}msg(e,t,s){if(this._native.isLoggable(t,e)){for(let e=0;e<s.length;++e){"function"==typeof s[e]&&(s[e]=s[e]());"object"==typeof s[e]&&("function"==typeof s[e].toString?s[e]=s[e].toString():s[e].constructor&&s[e].constructor.name?s[e]=`{Object: ${s[e].constructor.name}}`:s[e]="{Object}")}this._native.msg(e,t,s)}}static d(e,t,...s){if(arguments.length>=2){e=arguments[0];s=Array.prototype.slice.call(arguments,1)}else{e=undefined;s=Array.prototype.slice.call(arguments,0)}Log.instance.msg(Log.DEBUG,e,s)}static e(e,t,...s){if(arguments.length>=2){e=arguments[0];s=Array.prototype.slice.call(arguments,1)}else{e=undefined;s=Array.prototype.slice.call(arguments,0)}Log.instance.msg(Log.ERROR,e,s)}static i(e,t,...s){if(arguments.length>=2){e=arguments[0];s=Array.prototype.slice.call(arguments,1)}else{e=undefined;s=Array.prototype.slice.call(arguments,0)}Log.instance.msg(Log.INFO,e,s)}static v(e,t,...s){if(arguments.length>=2){e=arguments[0];s=Array.prototype.slice.call(arguments,1)}else{e=undefined;s=Array.prototype.slice.call(arguments,0)}Log.instance.msg(Log.VERBOSE,e,s)}static w(e,t,...s){if(arguments.length>=2){e=arguments[0];s=Array.prototype.slice.call(arguments,1)}else{e=undefined;s=Array.prototype.slice.call(arguments,0)}Log.instance.msg(Log.WARNING,e,s)}static t(e,t,...s){if(arguments.length>=2){e=arguments[0];s=Array.prototype.slice.call(arguments,1)}else{e=undefined;s=Array.prototype.slice.call(arguments,0)}Log.instance.msg(Log.TRACE,e,s)}}Log.Level={TRACE:1,VERBOSE:2,DEBUG:3,INFO:4,WARNING:5,ERROR:6,ASSERT:7,toStringTag:function(e){switch(e){case Log.TRACE:return"T";case Log.VERBOSE:return"V";case Log.DEBUG:return"D";case Log.INFO:return"I";case Log.WARNING:return"W";case Log.ERROR:return"E";case Log.ASSERT:return"A";default:return"*"}}};Log.TRACE=Log.Level.TRACE;Log.VERBOSE=Log.Level.VERBOSE;Log.DEBUG=Log.Level.DEBUG;Log.INFO=Log.Level.INFO;Log.WARNING=Log.Level.WARNING;Log.ERROR=Log.Level.ERROR;Log.ASSERT=Log.Level.ASSERT;Log._instance=null;Log.d.tag=(e=>Log.d.bind(null,e));Log.e.tag=(e=>Log.e.bind(null,e));Log.i.tag=(e=>Log.i.bind(null,e));Log.v.tag=(e=>Log.v.bind(null,e));Log.w.tag=(e=>Log.w.bind(null,e));Log.t.tag=(e=>Log.t.bind(null,e));Class.register(Log);class LinkedList{constructor(...e){this._length=0;this._head=null;this._tail=null;const t=1===e.length&&Array.isArray(e[0])?e[0]:e;for(const s of t)this.push(s)}push(e){const t={next:null,prev:this._head,value:e};this._push(t)}_push(e){this._length++;if(this._head){this._head.next=e;this._head=e}else{this._head=e;this._tail=e}}unshift(e){const t={next:this._tail,prev:null,value:e};this._unshift(t)}_unshift(e){this._length++;if(this._head){this._tail.prev=e;this._tail=e}else{this._head=e;this._tail=e}}pop(){if(!this._head)return null;this._length--;const e=this._head,t=e.prev;if(!t){this._head=null;this._tail=null;return e.value}t.next=null;this._head=t;return e.value}shift(){if(!this._head)return null;this._length--;const e=this._tail,t=e.next;if(!t){this._head=null;this._tail=null;return e.value}t.prev=null;this._tail=t;return e.value}_remove(e){if(e===this._head)this.pop();else if(e===this._tail)this.shift();else{this._length--;e.prev.next=e.next;e.next.prev=e.prev}}clear(){this._length=0;this._head=null;this._tail=null}[Symbol.iterator](){return this.iterator()}*iterator(){let e=this._tail;for(;e;){yield e.value;e=e.next}}isEmpty(){return 0===this._length}get first(){return this._tail?this._tail.value:null}get last(){return this._head?this._head.value:null}get length(){return this._length}}Class.register(LinkedList);class UniqueLinkedList extends LinkedList{constructor(){super();this._map=new Map}push(e){this._map.has(e)||super.push(e)}_push(e){super._push(e);this._map.set(e.value,e)}unshift(e){this._map.has(e)||super.unshift(e)}_unshift(e){super._unshift(e);this._map.set(e.value,e)}pop(){const e=super.pop();this._map["delete"](e);return e}shift(){const e=super.shift();this._map["delete"](e);return e}clear(){super.clear();this._map.clear()}contains(e){return this._map.has(e)}remove(e){const t=this._map.get(e);if(t){super._remove(t);this._map["delete"](e)}}moveBack(e){const t=this._map.get(e);if(t){if(t===this._head)return;if(t===this._tail){t.next.prev=null;this._tail=t.next}else{t.prev.next=t.next;t.next.prev=t.prev}t.next=null;t.prev=this._head;this._head.next=t;this._head=t}else super.push(e)}}Class.register(UniqueLinkedList);class LRUMap{constructor(e){this._maxSize=e;this._map=new Map;this._accessQueue=new UniqueLinkedList}get size(){return this._map.size}clear(){this._accessQueue.clear();return this._map.clear()}"delete"(e){this._accessQueue.remove(e);return this._map["delete"](e)}entries(){return this._map.entries()}forEach(e,t){return this._map.forEach(e,t)}get(e){this._access(e);return this._map.get(e)}has(e){return this._map.has(e)}keys(){return this._map.keys()}evict(e=1){for(;e>0&&this._accessQueue.length>0;){const t=this._accessQueue.shift();this._map["delete"](t);--e}}_access(e){this._accessQueue.moveBack(e)}set(e,t){this.size>=this._maxSize&&this.evict();if(this.size<this._maxSize){this._map.set(e,t);this._access(e)}}values(){return this._map.values()}[Symbol.iterator](){return this._map.entries()}}Class.register(LRUMap);class ObjectUtils{static byKeyPath(e,t){if(!Array.isArray(t))return e[t];let s=e;for(const r of t){if(s===undefined)return undefined;s=s[r]}return s}}Class.register(ObjectUtils);Set.prototype.union=function(e){const t=new Set(this);for(const s of e)t.add(s);return t};Set.prototype.intersection=function(e){const t=new Set;for(const s of e)this.has(s)&&t.add(s);return t};Set.prototype.difference=function(e){const t=new Set(this);for(const s of e)t["delete"](s);return t};Set.prototype.equals=function(e){if(this.size!==e.size)return!1;for(const t of e)if(!this.has(t))return!1;return!0};Set.prototype.limit=function(e=null){if(null===e)return this;const t=new Set;let s=0;for(const r of this){if(null!==e&&s>=e)break;t.add(r);s++}return t};Set.from=function(e){return e&&"function"==typeof e[Symbol.iterator]&&"string"!=typeof e?new Set(e):new Set([e])};Set.sampleElement=function(e){return e.size>0?e.values().next().value:undefined};class SortedList{constructor(e=[],t){this._list=e;this._compare=t||SortedList._compare}static _compare(e,t){return e.compare?e.compare(t):e>t?1:e<t?-1:0}indexOf(e){let t=0,s=this._list.length-1,r=null,n=null;for(;t<=s;){r=Math.round((t+s)/2);n=this._list[r];if(this._compare(n,e)<0)t=r+1;else{if(!(this._compare(n,e)>0))return r;s=r-1}}return-1}_insertionIndex(e){let t=0,s=this._list.length-1,r=null,n=null;for(;t<=s;){r=Math.round((t+s)/2);n=this._list[r];if(this._compare(n,e)<0)t=r+1;else{if(!(this._compare(n,e)>0))break;s=r-1}}return t}add(e){this._list.splice(this._insertionIndex(e),0,e)}has(e){return this.indexOf(e)>=0}shift(){return this._list.shift()}pop(){return this._list.pop()}peekFirst(){return this._list[0]}peekLast(){return this._list[this._list.length-1]}remove(e){const t=this.indexOf(e);t>-1&&this._list.splice(t,1)}clear(){this._list=[]}values(){return this._list}[Symbol.iterator](){return this._list[Symbol.iterator]()}copy(){return new SortedList(this._list.slice(),this._compare)}get length(){return this._list.length}}Class.register(SortedList);class Synchronizer{constructor(){this._queue=[];this._working=!1}push(e){return new Promise((t,s)=>{this._queue.push({fn:e,resolve:t,error:s});this._working||this._doWork()["catch"](Log.w.tag(Synchronizer))})}async _doWork(){this._working=!0;for(;this._queue.length;){const t=this._queue.shift();try{const s=await t.fn();t.resolve(s)}catch(e){t.error&&t.error(e)}}this._working=!1}get working(){return this._working}}Class.register(Synchronizer);class EncodedTransaction{constructor(e){this._tableName=e;this._modified=new Map;this._removed=new Set;this._truncated=!1}get tableName(){return this._tableName}get modified(){return this._modified}get removed(){return this._removed}get truncated(){return this._truncated}truncate(){this._truncated=!0;this._modified.clear();this._removed.clear()}put(e,t){this._removed["delete"](e);this._modified.set(e,t)}get(e){return this._modified.get(e)}remove(e){this._removed.add(e);this._modified["delete"](e)}}Class.register(EncodedTransaction);class GenericValueEncoding{static _encodeInteger(e){const t=new Uint8Array(9),s=new DataView(t.buffer);s.setUint8(0,GenericValueEncoding.Type.INTEGER);s.setUint32(1,Math.floor(e/Math.pow(2,32)));s.setUint32(5,e);return t}static _decodeInteger(e){const t=new DataView(e.buffer);return t.getUint32(1)*Math.pow(2,32)+t.getUint32(5)}static _encodeString(e,t=GenericValueEncoding.Type.STRING){const s=new Uint8Array(e.length+1);s[0]=t;for(let r=0;r<e.length;++r)s[r+1]=e.charCodeAt(r);return s}static _decodeString(e){return String.fromCharCode.apply(null,e.subarray(1))}static _encodeOther(e){return GenericValueEncoding._encodeString(JSONUtils.stringify(e),GenericValueEncoding.Type.JSON)}static _decodeOther(e){const t=GenericValueEncoding._decodeString(e);return JSONUtils.parse(t)}static _encodeBuffer(e){const t=new Uint8Array(e.byteLength+1);t[0]=GenericValueEncoding.Type.BUFFER;t.set(e,1);return t}static _decodeBuffer(e){return e.subarray(1)}static encode(e){return Number.isInteger(e)?GenericValueEncoding._encodeInteger(e):"string"==typeof e?this._encodeString(e):e instanceof Uint8Array?GenericValueEncoding._encodeBuffer(e):GenericValueEncoding._encodeOther(e)}static decode(e){switch((e=new Uint8Array(e))[0]){case GenericValueEncoding.Type.INTEGER:return GenericValueEncoding._decodeInteger(e);case GenericValueEncoding.Type.STRING:return GenericValueEncoding._decodeString(e);case GenericValueEncoding.Type.BUFFER:return GenericValueEncoding._decodeBuffer(e);default:return GenericValueEncoding._decodeOther(e)}}static get encoding(){return JungleDB.Encoding.BINARY}}GenericValueEncoding.Type={INTEGER:0,STRING:1,JSON:2,BUFFER:3};Class.register(GenericValueEncoding);class CachedBackend{constructor(e,t=CachedBackend.MAX_CACHE_SIZE,s=0){this._backend=e;this._cache=new LRUMap(t);this._rawCache=new LRUMap(s)}get connected(){return this._backend.connected}get indices(){return this._backend.indices}async _retrieveValues(e){const t=[];for(const s of e)t.push(this.get(s));return Promise.all(t)}_has(e){return this._cache.has(e)||this._rawCache.has(e)}_get(e,t){if(t&&t.raw){if(this._rawCache.has(e))return this._rawCache.get(e);{const t=this.encode(this._cache.get(e));this._rawCache.set(e,t);return t}}if(this._cache.has(e))return this._cache.get(e);{const t=this.decode(this._rawCache.get(e),e);this._cache.set(e,t);return t}}getSync(e,t={}){if(this._has(e))return this._get(e,t);if(this._backend.isSynchronous()){const s=this._backend.getSync(e,t);t&&t.raw?this._rawCache.set(e,s):this._cache.set(e,s);return s}if(t&&t.expectPresence)throw new Error(`Missing key in cached backend: ${e}`);return undefined}isCached(e){return!1}async get(e,t={}){if(this._has(e))return this._get(e,t);const s=await this._backend.get(e,t);t&&t.raw?this._rawCache.set(e,s):this._cache.set(e,s);return s}keys(e=null,t=null){return this._backend.keys(e,t)}values(e=null,t=null){return this._backend.values(e,t)}keyStream(e,t=!0,s=null){return this._backend.keyStream(e,t,s)}valueStream(e,t=!0,s=null){return this._backend.valueStream(e,t,s)}maxValue(e=null){return this._backend.maxValue(e)}maxKey(e=null){return this._backend.maxKey(e)}minKey(e=null){return this._backend.minKey(e)}minValue(e=null){return this._backend.minValue(e)}count(e=null){return this._backend.count(e)}_apply(e){this._applyLocally(e);return this._backend._apply(e)}_applyLocally(e){e._truncated&&this._cache.clear();for(const t of e._removed)this._cache["delete"](t);for(const[t,s]of e._modified)this._cache.set(t,s)}async truncate(){this._cache.clear();return this._backend.truncate()}index(e){return this._backend.index(e)}createIndex(e,t,s={}){return this._backend.createIndex(e,t,s)}deleteIndex(e,t={}){return this._backend.deleteIndex(e,t)}close(){return this._backend.close()}async applyCombined(e){return[await this._backend.applyCombined(e),()=>this._applyLocally(e)]}isSynchronous(){return!0}decode(e,t){return this._backend.decode(e,t)}encode(e){return this._backend.encode(e)}}CachedBackend.MAX_CACHE_SIZE=5e3;Class.register(CachedBackend);class InMemoryIndex{constructor(e,t,s=!1,r=!1){this._objectStore=e;this._keyPath=t;this._multiEntry=s;this._unique=r;this._tree=new BTree}truncate(){this._tree=new BTree}_indexKey(e,t){return t===undefined?undefined:this.keyPath?ObjectUtils.byKeyPath(t,this.keyPath):e}get keyPath(){return this._keyPath}get multiEntry(){return this._multiEntry}get unique(){return this._unique}_insert(e,t){const s=this._tree;this._multiEntry&&Array.isArray(t)||(t=[t]);for(const r of t)if(s.seek(r)){if(this._unique)throw new Error(`Uniqueness constraint violated for key ${e} on path ${this._keyPath}`);s.currentRecord.add(e)}else s.insert(r,this._unique?e:new SortedList([e],ComparisonUtils.compare))}put(e,t,s){const r=this._indexKey(e,s),n=this._indexKey(e,t);if(!ComparisonUtils.equals(r,n)){r!==undefined&&this._remove(e,r);n!==undefined&&this._insert(e,n)}}remove(e,t){const s=this._indexKey(e,t);s!==undefined&&this._remove(e,s)}_remove(e,t){const s=this._tree;this._multiEntry&&Array.isArray(t)||(t=[t]);for(const r of t)s.seek(r)&&(!this._unique&&s.currentRecord.length>1?s.currentRecord.remove(e):s.remove(r))}async _retrieveValues(e){const t=[];for(const s of e)t.push(this._objectStore.get(s));return Promise.all(t)}async values(e=null,t=null){const s=await this.keys(e,t);return this._retrieveValues(s)}async keys(e=null,t=null){let s=new Set;if(e instanceof KeyRange&&e.exactMatch){this._tree.seek(e.lower)&&(s=Set.from(this._tree.currentRecord));return s.limit(t)}if(e instanceof KeyRange){if(!this._tree.goToLowerBound(e.lower,e.lowerOpen))return s}else if(!this._tree.goTop())return s;for(;(!(e instanceof KeyRange)||e.includes(this._tree.currentKey))&&!(null!==t&&s.size>=t);){s=s.union(Set.from(this._tree.currentRecord));if(!this._tree.skip())break}return s.limit(t)}keyStream(e,t=!0,s=null){if(s instanceof KeyRange){if(t){if(!this._tree.goToLowerBound(s.lower,s.lowerOpen))return Promise.resolve()}else if(!this._tree.goToUpperBound(s.upper,s.upperOpen))return Promise.resolve()}else if(t){if(!this._tree.goTop())return Promise.resolve()}else if(!this._tree.goBottom())return Promise.resolve();e:for(;!(s instanceof KeyRange)||s.includes(this._tree.currentKey);){if(this._unique){if(!e(this._tree.currentRecord))break}else{const s=this._tree.currentRecord.values();if(t){for(let t=0;t<s.length;t++)if(!e(s[t]))break e}else for(let t=s.length-1;t>=0;t--)if(!e(s[t]))break e}if(!this._tree.skip(t?1:-1))break}return Promise.resolve()}async valueStream(e,t=!0,s=null){if(s instanceof KeyRange){if(t){if(!this._tree.goToLowerBound(s.lower,s.lowerOpen))return}else if(!this._tree.goToUpperBound(s.upper,s.upperOpen))return}else if(t){if(!this._tree.goTop())return}else if(!this._tree.goBottom())return;e:for(;!(s instanceof KeyRange)||s.includes(this._tree.currentKey);){if(this._unique){if(!e(await this._objectStore.get(this._tree.currentRecord),this._tree.currentRecord))break}else{const s=this._tree.currentRecord.values();if(t){for(let t=0;t<s.length;t++)if(!e(await this._objectStore.get(s[t]),s[t]))break e}else for(let t=s.length-1;t>=0;t--)if(!e(await this._objectStore.get(s[t]),s[t]))break e}if(!this._tree.skip(t?1:-1))break}}async maxValues(e=null){const t=await this.maxKeys(e);return this._retrieveValues(t)}async maxKeys(e=null){const t=e instanceof KeyRange;return this._tree.goToUpperBound(t?e.upper:undefined,!!t&&e.upperOpen)?Set.from(this._tree.currentRecord):new Set}async minValues(e=null){const t=await this.minKeys(e);return this._retrieveValues(t)}async minKeys(e=null){const t=e instanceof KeyRange;return this._tree.goToLowerBound(t?e.lower:undefined,!!t&&e.lowerOpen)?Set.from(this._tree.currentRecord):new Set}async count(e=null){return(await this.keys(e)).size}}Class.register(InMemoryIndex);class InMemoryBackend{constructor(e,t=null){this._cache=new Map;this._indices=new Map;this._primaryIndex=new InMemoryIndex(this,undefined,!1,!0);this._tableName=e;this._codec=t}get connected(){return!0}get indices(){return this._indices}getSync(e,t={}){const s=this._cache.get(e);return t&&t.raw?s:this.decode(s,e)}get(e,t={}){try{return Promise.resolve(this.getSync(e,t))}catch(s){return Promise.reject(s)}}async values(e=null,t=null){if(null!==e&&e instanceof Query)return e.values(this,t);const s=[];for(const r of await this.keys(e,t))s.push(await this.get(r));return Promise.resolve(s)}keys(e=null,t=null){return null!==e&&e instanceof Query?e.keys(this,t):this._primaryIndex.keys(e,t)}keyStream(e,t=!0,s=null){return this._primaryIndex.keyStream(e,t,s)}valueStream(e,t=!0,s=null){return this._primaryIndex.valueStream(e,t,s)}async maxValue(e=null){const t=await this.maxKey(e);return this.get(t)}async maxKey(e=null){const t=await this._primaryIndex.maxKeys(e);return Set.sampleElement(t)}async minValue(e=null){const t=await this.minKey(e);return this.get(t)}async minKey(e=null){const t=await this._primaryIndex.minKeys(e);return Set.sampleElement(t)}async count(e=null){return(await this.keys(e)).size}index(e){return this._indices.get(e)}async _apply(e){e._truncated&&this.truncateSync();const t=new Map;for(const s of e._removed){const e=this.getSync(s);e&&t.set(s,e);this._cache["delete"](s)}for(const[s,r]of e._modified){const e=this.getSync(s);e&&t.set(s,e);this._cache.set(s,this.encode(r))}InMemoryBackend._indexApply(this._primaryIndex,e,t);for(const s of this._indices.values())InMemoryBackend._indexApply(s,e,t)}static _indexApply(e,t,s){t._truncated&&e.truncate();for(const r of t._removed)e.remove(r,s.get(r));for(const[r,n]of t._modified)e.put(r,n,s.get(r))}async truncate(){this.truncateSync()}truncateSync(){this._cache.clear();this._primaryIndex.truncate();for(const e of this._indices.values())e.truncate()}async map(e){for(const[t,s]of this._cache)e(t,s)}createIndex(e,t,s={}){let{multiEntry:r=!1,unique:n=!1,upgradeCondition:i=null}=s||{};const o=new InMemoryIndex(this,t=t||e,r,n);this._indices.set(e,o)}deleteIndex(e,t={}){let{upgradeCondition:s=null}=t||{};this._indices["delete"](e)}decode(e,t){return e===undefined?undefined:null!==this._codec&&this._codec!==undefined?this._codec.decode(e,t):e}encode(e){return e===undefined?undefined:null!==this._codec&&this._codec!==undefined?this._codec.encode(e):e}get tableName(){return this._tableName}async applyCombined(e){return()=>this._apply(e)}isSynchronous(){return!0}isCached(e){return!0}}Class.register(InMemoryBackend);class KeyRange{constructor(e,t,s,r){this._lower=e;this._upper=t;this._lowerOpen=s;this._upperOpen=r}get lower(){return this._lower}get upper(){return this._upper}get lowerOpen(){return this._lowerOpen}get upperOpen(){return this._upperOpen}get exactMatch(){return this._lower===this._upper&&!this._lowerOpen&&!this.upperOpen}includes(e){return(this._lower===undefined||ComparisonUtils.compare(this._lower,e)<0||!this._lowerOpen&&ComparisonUtils.equals(this._lower,e))&&(this._upper===undefined||ComparisonUtils.compare(this._upper,e)>0||!this._upperOpen&&ComparisonUtils.equals(this._upper,e))}static upperBound(e,t=!1){return new KeyRange(undefined,e,!1,t)}static lowerBound(e,t=!1){return new KeyRange(e,undefined,t,!1)}static bound(e,t,s=!1,r=!1){return new KeyRange(e,t,s,r)}static only(e){return new KeyRange(e,e,!1,!1)}}Class.register(KeyRange);class ObjectStore{constructor(e,t,s){this._backend=e;this._db=t;this._name=s;this._stateStack=[];this._backendInfo=new TransactionInfo(this._backend,null);this._transactions=new Map;this._transactions.set(ObjectStore.BACKEND_ID,this._backendInfo);this._snapshotManager=new SnapshotManager;this._synchronizer=new Synchronizer}get jungleDB(){return this._db}get connected(){return this._backend.connected}get _currentState(){return this._stateStack.length>0?this._stateStack[this._stateStack.length-1].transaction:this._backend}get _currentStateInfo(){return this._stateStack.length>0?this._stateStack[this._stateStack.length-1]:this._backendInfo}get _currentStateId(){return this._stateStack.length>0?this._stateStack[this._stateStack.length-1].id:ObjectStore.BACKEND_ID}get indices(){if(!this._backend.connected)throw new Error("JungleDB is not connected");return this._currentState.indices}get(e,t={}){if(!this._backend.connected)throw new Error("JungleDB is not connected");return this._currentState.get(e,t)}async put(e,t){if(!this._backend.connected)throw new Error("JungleDB is not connected");const s=this.transaction();try{await s.put(e,t)}catch(r){await s.abort();throw r}return s.commit()}async remove(e){if(!this._backend.connected)throw new Error("JungleDB is not connected");const t=this.transaction();try{await t.remove(e)}catch(s){await t.abort();throw s}return t.commit()}getSync(e,t={}){if(!this._backend.connected)throw new Error("JungleDB is not connected");if(!this._currentState.isSynchronous())throw new Error("Only works on synchronous backends");return this._currentState.getSync(e,t)}isCached(e){if(!this._backend.connected)throw new Error("JungleDB is not connected");if(!this._currentState.isSynchronous())throw new Error("Only works on synchronous backends");return this._currentState.isCached(e)}keys(e=null,t=null){if(!this._backend.connected)throw new Error("JungleDB is not connected");return null!==e&&e instanceof Query?e.keys(this._currentState,t):this._currentState.keys(e,t)}values(e=null,t=null){if(!this._backend.connected)throw new Error("JungleDB is not connected");return null!==e&&e instanceof Query?e.values(this._currentState,t):this._currentState.values(e,t)}keyStream(e,t=!0,s=null){return this._currentState.keyStream(e,t,s)}valueStream(e,t=!0,s=null){return this._currentState.valueStream(e,t,s)}maxValue(e=null){if(!this._backend.connected)throw new Error("JungleDB is not connected");return this._currentState.maxValue(e)}maxKey(e=null){if(!this._backend.connected)throw new Error("JungleDB is not connected");return this._currentState.maxKey(e)}minKey(e=null){if(!this._backend.connected)throw new Error("JungleDB is not connected");return this._currentState.minKey(e)}minValue(e=null){if(!this._backend.connected)throw new Error("JungleDB is not connected");return this._currentState.minValue(e)}count(e=null){if(!this._backend.connected)throw new Error("JungleDB is not connected");return this._currentState.count(e)}async commit(e){if(!this._isCommittable(e)){await this.abort(e);return!1}await this._commitInternal(e);return!0}_isCommittable(e){if(!this._backend.connected)throw new Error("JungleDB is not connected");if(!(e instanceof Transaction&&e.state===Transaction.STATE.OPEN&&this._transactions.has(e.id)))throw new Error("Can only commit open transactions");return this._transactions.get(e.id).isCommittable()}async _commitBackend(){throw new Error("Cannot commit object stores")}async _commitInternal(e){const t=this._transactions.get(e.id);if(this._stateStack.length>=ObjectStore.MAX_STACK_SIZE){Log.e(ObjectStore,`Transaction stack size exceeded ${this.toStringFull()}`);throw new Error("Transaction stack size exceeded")}this._stateStack.push(t);t.close();t.isFlushable()&&await this._flattenState(e)}_setParent(e){throw new Error("Unsupported operation")}async abort(e){if(!this._backend.connected)throw new Error("JungleDB is not connected");if(e instanceof Snapshot)return this._snapshotManager.abortSnapshot(e);if(!(e instanceof Transaction&&e.state===Transaction.STATE.OPEN&&this._transactions.has(e.id)))throw new Error("Can only abort open transactions");const t=this._transactions.get(e.id);t.abort();t.parent&&0===t.parent.numOpenChildren&&await this._flattenState();this._transactions["delete"](e.id);return!0}_flattenState(e){return this._synchronizer.push(()=>this._flattenStateInternal(e))}async _flattenStateInternal(e){if(e&&e instanceof Transaction){const s=this._transactions.get(e.id);if(!s.isFlushable())return!1;const r=s.parent.transaction,n=()=>{s.flush();this._transactions["delete"](e.id);const t=this._stateStack.indexOf(s);t>=0&&this._stateStack.splice(t,1);this._flattenState()["catch"](Log.w.tag(ObjectStore))};if(null===e.dependency){s.parent.isBackend()&&await this._snapshotManager.applyTx(e,r);try{await r._apply(e)}catch(t){s.abort();this._transactions["delete"](e.id);const r=this._stateStack.indexOf(s);r>=0&&this._stateStack.splice(r,1);e._setAborted();Log.e(ObjectStore,"Error while applying transaction",t)}n();return!0}return await e.dependency.onFlushable(e,n,()=>this._snapshotManager.applyTx(e,r))}for(;this._stateStack.length>0&&await this._flattenStateInternal(this._currentState););for(;this._stateStack.length>0&&await this._flattenStateInternal(this._stateStack[0].transaction););return!1}index(e){if(!this._backend.connected)throw new Error("JungleDB is not connected");return this._currentState.index(e)}createIndex(e,t,s={}){return this._backend.createIndex(e,t,s)}deleteIndex(e,t={}){return this._backend.deleteIndex(e,t)}transaction(e=!0){if(!this._backend.connected)throw new Error("JungleDB is not connected");if(this._backend.isSynchronous())return this.synchronousTransaction(e);const t=new Transaction(this,this._currentState,this,e);this._transactions.set(t.id,new TransactionInfo(t,this._currentStateInfo));return t}synchronousTransaction(e=!0){if(!this._backend.connected)throw new Error("JungleDB is not connected");const t=new SynchronousTransaction(this,this._currentState,this,e);this._transactions.set(t.id,new TransactionInfo(t,this._currentStateInfo));return t}isSynchronous(){return this._backend.isSynchronous()}snapshot(){return this._currentStateId!==ObjectStore.BACKEND_ID?this._currentState.snapshot():this._snapshotManager.createSnapshot(this,this._currentState)}async _apply(e){throw new Error("Unsupported operation")}async truncate(){if(!this._backend.connected)throw new Error("JungleDB is not connected");const e=this.transaction();await e.truncate();return e.commit()}close(){if(this._stateStack.length>0)throw new Error("Cannot close database while transactions are active");return this._backend.close()}decode(e,t){return this._backend.decode(e,t)}encode(e){return this._backend.encode(e)}toStringFull(){return`ObjectStore{\n stack=[${this._stateStack.map(e=>`{tx=${e}, open=${e.numOpenChildren}}`)}],\n db=${this._db}/${this._name?this._name:"unnamed"}\n}`}toString(){return`ObjectStore{stackSize=${this._stateStack.length}, db=${this._db}/${this._name?this._name:"unnamed"}}`}}ObjectStore.MAX_STACK_SIZE=10;ObjectStore.BACKEND_ID="backend";Class.register(ObjectStore);class TransactionInfo{constructor(e,t,s=[]){this.transaction=e;this.children=s;this._parentInfo=t;this._open=!0;this._parentInfo&&this._parentInfo.addChild(this)}addChild(e){this.children.push(e)}removeChild(e){const t=this.children.indexOf(e);t>=0&&this.children.splice(t,1)}flush(){if(!this.isBackend()){const e=this.parent;this.parent.removeChild(this);for(const t of this.children.slice())t.parent=e;this.children=[];this._parentInfo=null}}abort(){this.isBackend()||this.parent.removeChild(this)}close(){this._open=!1}get parent(){return this._parentInfo}set parent(e){this.parent.removeChild(this);this._parentInfo=e;this.parent.addChild(this);this.transaction._setParent(e.transaction)}get id(){return this.isBackend()?ObjectStore.BACKEND_ID:this.transaction.id}isBackend(){return null===this._parentInfo}isOpen(){return this._open}get numOpenChildren(){return this.children.filter(e=>e.isOpen()).length}isCommittable(){return this._parentInfo&&this._parentInfo.children.every(e=>e.isOpen())}isFlushable(){return this.parent&&0===this.parent.numOpenChildren&&(null===this.transaction.dependency||this.parent.isBackend())}toString(){return this.transaction.toStringShort()}}class Query{static _parseKeyRange(e,t,s){switch(e){case Query.OPERATORS.GT:return KeyRange.lowerBound(t,!0);case Query.OPERATORS.GE:return KeyRange.lowerBound(t,!1);case Query.OPERATORS.LT:return KeyRange.upperBound(t,!0);case Query.OPERATORS.LE:return KeyRange.upperBound(t,!1);case Query.OPERATORS.EQ:return KeyRange.only(t);case Query.OPERATORS.BETWEEN:return KeyRange.bound(t,s,!0,!0);case Query.OPERATORS.WITHIN:return KeyRange.bound(t,s,!1,!1)}Log.e(`Unknown operator: ${e}`);throw new Error("Unknown operator")}static and(e){const t=Array.from(arguments);return new Query(t,Query.OPERATORS.AND)}static or(e){const t=Array.from(arguments);return new Query(t,Query.OPERATORS.OR)}static max(e){return new Query(e,Query.OPERATORS.MAX)}static min(e){return new Query(e,Query.OPERATORS.MIN)}static lt(e,t){return new Query(e,Query.OPERATORS.LT,t)}static le(e,t){return new Query(e,Query.OPERATORS.LE,t)}static gt(e,t){return new Query(e,Query.OPERATORS.GT,t)}static ge(e,t){return new Query(e,Query.OPERATORS.GE,t)}static eq(e,t){return new Query(e,Query.OPERATORS.EQ,t)}static between(e,t,s){return new Query(e,Query.OPERATORS.BETWEEN,t,s)}static within(e,t,s){return new Query(e,Query.OPERATORS.WITHIN,t,s)}constructor(e,t,s,r){if(Array.isArray(e)){if(e.some(e=>!(e instanceof Query)))throw new Error("Invalid query");if(Query.COMBINED_OPERATORS.indexOf(t)<0)throw new Error("Unknown operator");this._queryType=Query.Type.COMBINED;this._queries=e;this._op=t}else{if(Query.RANGE_OPERATORS.indexOf(t)>=0){this._queryType=Query.Type.RANGE;this._keyRange=Query._parseKeyRange(t,s,r)}else{if(!(Query.ADVANCED_OPERATORS.indexOf(t)>=0))throw new Error("Unknown operator");this._queryType=Query.Type.ADVANCED;this._op=t}this._indexName=e}}async values(e,t=null){const s=await this._execute(e,t),r=[];for(const n of s)r.push(e.get(n));return Promise.all(r)}keys(e,t=null){return this._execute(e,t)}async _execute(e,t=null){switch(this._queryType){case Query.Type.COMBINED:return Promise.resolve(this._executeCombined(e,t));case Query.Type.ADVANCED:return Promise.resolve(this._executeAdvanced(e,t));case Query.Type.RANGE:return this._executeRange(e,t)}return Promise.resolve(new Set)}async _executeCombined(e,t=null){const s=[];for(const n of this._queries)s.push(n._execute(e,t));const r=await Promise.all(s);if(this._op===Query.OPERATORS.AND){if(0===r.length)return new Set;if(1===r.length)return null===t||t>=1?r[0]:new Set;const e=r.shift(),s=new Set;let n=0;for(const i of e)if(r.every(e=>e.has(i))){if(null!==t&&n>=t)break;s.add(i);n++}return s}if(this._op===Query.OPERATORS.OR){const e=new Set;let s=0;for(const n of r){for(const r of n){if(null!==t&&s>=t)break;e.add(r);s++}if(null!==t&&s>=t)break}return e}return new Set}async _executeAdvanced(e,t=null){const s=e.index(this._indexName);let r=new Set;switch(this._op){case Query.OPERATORS.MAX:r=await s.maxKeys();break;case Query.OPERATORS.MIN:r=await s.minKeys()}return new Set(r.limit(t))}async _executeRange(e,t=null){const s=e.index(this._indexName);return new Set(await s.keys(this._keyRange,t))}}Query.OPERATORS={GT:0,GE:1,LT:2,LE:3,EQ:4,BETWEEN:7,WITHIN:8,MAX:9,MIN:10,AND:11,OR:12};Query.RANGE_OPERATORS=[Query.OPERATORS.GT,Query.OPERATORS.GE,Query.OPERATORS.LT,Query.OPERATORS.LE,Query.OPERATORS.EQ,Query.OPERATORS.BETWEEN,Query.OPERATORS.WITHIN];Query.ADVANCED_OPERATORS=[Query.OPERATORS.MAX,Query.OPERATORS.MIN];Query.COMBINED_OPERATORS=[Query.OPERATORS.AND,Query.OPERATORS.OR];Query.Type={RANGE:0,ADVANCED:1,COMBINED:2};Class.register(Query);class TransactionIndex extends InMemoryIndex{static derive(e,t){const s=new Map;for(const[r,n]of t.indices)s.set(r,new TransactionIndex(e,t,r,n.keyPath,n.multiEntry,n.unique));return s}get _index(){return this._backend.index(this._databaseDir)}constructor(e,t,s,r,n=!1,i=!1){super(e,r,n,i);this._backend=t;this._databaseDir=s}async checkUniqueConstraint(e,t,s=!0){if(!this.unique)return;let r=this._indexKey(e,t);if(r!==undefined){this.multiEntry&&Array.isArray(r)||(r=[r]);for(const e of r){if(await this.count(KeyRange.only(e))>(s?1:0))throw new Error(`Uniqueness constraint violated for key ${e} on path ${this._keyPath}`)}}}async keys(e=null,t=null){const s=[];this._objectStore._truncated?s.push(new Set):s.push(this._index.keys(e,t));s.push(InMemoryIndex.prototype.keys.call(this,e,t));let[r,n]=await Promise.all(s);return(r=(r=r.difference(this._objectStore._removed)).difference(this._objectStore._modified.keys())).union(n).limit(t)}async values(e=null,t=null){const s=await this.keys(e,t);return InMemoryIndex.prototype._retrieveValues.call(this,s)}async maxValues(e=null){const t=await this.maxKeys(e);return InMemoryIndex.prototype._retrieveValues.call(this,t)}async maxKeys(e=null){let t;t=this._objectStore._truncated?new Set:await this._index.maxKeys(e);let s=Set.sampleElement(t),r=undefined,n=undefined;if(s!==undefined){r=await this._backend.get(s);n=ObjectUtils.byKeyPath(r,this.keyPath)}t=(t=t.difference(this._objectStore._removed)).difference(this._objectStore._modified.keys());for(;s!==undefined&&0===t.size;){const i=KeyRange.upperBound(n,!0);t=await this._index.maxKeys(i);if((s=Set.sampleElement(t))!==undefined){r=await this._backend.get(s);n=ObjectUtils.byKeyPath(r,this.keyPath)}t=(t=t.difference(this._objectStore._removed)).difference(this._objectStore._modified.keys());if(n&&null!==e&&!e.includes(n)){t=new Set;break}}const i=await InMemoryIndex.prototype.maxKeys.call(this,e);if(0===t.size)return i;if(0===i.size)return t;const o=await this._objectStore.get(Set.sampleElement(i)),a=n,c=ObjectUtils.byKeyPath(o,this.keyPath);return ComparisonUtils.compare(a,c)>0?t:ComparisonUtils.compare(a,c)<0?i:t.union(i)}async minValues(e=null){const t=await this.minKeys(e);return InMemoryIndex.prototype._retrieveValues.call(this,t)}async minKeys(e=null){let t;t=this._objectStore._truncated?new Set:await this._index.minKeys(e);let s=Set.sampleElement(t),r=undefined,n=undefined;if(s!==undefined){r=await this._backend.get(s);n=ObjectUtils.byKeyPath(r,this.keyPath)}t=(t=t.difference(this._objectStore._removed)).difference(this._objectStore._modified.keys());for(;s!==undefined&&0===t.size;){const i=KeyRange.lowerBound(n,!0);t=await this._index.minKeys(i);if((s=Set.sampleElement(t))!==undefined){r=await this._backend.get(s);n=ObjectUtils.byKeyPath(r,this.keyPath)}t=(t=t.difference(this._objectStore._removed)).difference(this._objectStore._modified.keys());if(n&&null!==e&&!e.includes(n)){t=new Set;break}}const i=await InMemoryIndex.prototype.minKeys.call(this,e);if(0===t.size)return i;if(0===i.size)return t;const o=await this._objectStore.get(Set.sampleElement(i)),a=n,c=ObjectUtils.byKeyPath(o,this.keyPath);return ComparisonUtils.compare(a,c)<0?t:ComparisonUtils.compare(a,c)>0?i:t.union(i)}async count(e=null){return(await this.keys(e)).size}}Class.register(TransactionIndex);class Transaction{constructor(e,t,s,r=!0){this._id=Transaction._instanceCount++;this._objectStore=e;this._parent=t;this._managingBackend=s||t;this._modified=new Map;this._removed=new Set;this._truncated=!1;this._indices=TransactionIndex.derive(this,t);this._state=Transaction.STATE.OPEN;this._nested=new Set;this._nestedCommitted=!1;this._dependency=null;this._snapshotManager=new SnapshotManager;this._startTime=Date.now();this._enableWatchdog=r;this._enableWatchdog&&(this._watchdog=setTimeout(()=>{Log.w(Transaction,`Violation: tx id ${this._id} took longer than expected (still open after ${Transaction.WATCHDOG_TIMER/1e3}s), ${this.toString()}.`)},Transaction.WATCHDOG_TIMER))}get objectStore(){return this._objectStore}get nested(){return this._managingBackend instanceof Transaction}get dependency(){return this._dependency}get connected(){return this._managingBackend.connected}get id(){return this._id}get indices(){return this._indices}get state(){return this._state}_applySync(e){e._truncated&&this.truncateSync();for(const[t,s]of e._modified)this._put(t,s);for(const t of e._removed)this._remove(t)}async truncate(){return this.truncateSync()}truncateSync(){if(this._state!==Transaction.STATE.OPEN)throw new Error("Transaction already closed");this._truncated=!0;this._modified.clear();this._removed.clear();for(const e of this._indices.values())e.truncate()}async get(e,t={}){return this._removed.has(e)?undefined:this._modified.has(e)?t&&t.raw?this.encode(this._modified.get(e)):this._modified.get(e):this._truncated?undefined:this._parent.get(e,t)}async put(e,t){if(this._state!==Transaction.STATE.OPEN)throw new Error("Transaction already closed");const s=[];for(const r of this._indices.values())s.push(r.checkUniqueConstraint(e,t,!1));await Promise.all(s);this._put(e,t)}putSync(e,t){if(this._state!==Transaction.STATE.OPEN)throw new Error("Transaction already closed");this._put(e,t)}async remove(e){if(this._state!==Transaction.STATE.OPEN)throw new Error("Transaction already closed");this._remove(e)}removeSync(e){if(this._state!==Transaction.STATE.OPEN)throw new Error("Transaction already closed");this._remove(e)}async keys(e=null){if(null!==e&&e instanceof Query)return e.keys(this);let t=new Set;this._truncated||(t=await this._parent.keys(e));t=t.difference(this._removed);for(const s of this._modified.keys())(null===e||e.includes(s))&&t.add(s);return t}async values(e=null){if(null!==e&&e instanceof Query)return e.values(this);const t=await this.keys(e),s=[];for(const r of t)s.push(this.get(r));return Promise.all(s)}async keyStream(e,t=!0,s=null){let r=Array.from(this._modified.keys());s instanceof KeyRange&&(r=r.filter(e=>s.includes(e)));let n=(r=r.sort()).iterator(t);if(!this._truncated){let r=!1;await this._parent.keyStream(s=>{for(;n.hasNext()&&(t&&ComparisonUtils.compare(n.peek(),s)<0||!t&&ComparisonUtils.compare(n.peek(),s)>0);){const t=n.next();if(!e(t)){r=!0;return!1}}if(n.hasNext()&&ComparisonUtils.equals(n.peek(),s)){const t=n.next();if(!e(t)){r=!0;return!1}return!0}if(!this._removed.has(s)&&!e(s)){r=!0;return!1}return!0},t,s);if(r)return}for(;n.hasNext()&&e(n.next()););}async valueStream(e,t=!0,s=null){let r=Array.from(this._modified.keys());s instanceof KeyRange&&(r=r.filter(e=>s.includes(e)));let n=(r=r.sort()).iterator(t);if(!this._truncated){let r=!1;await this._parent.valueStream((s,i)=>{for(;n.hasNext()&&(t&&ComparisonUtils.compare(n.peek(),i)<0||!t&&ComparisonUtils.compare(n.peek(),i)>0);){const t=n.next(),s=this._modified.get(t);if(!e(s,t)){r=!0;return!1}}if(n.hasNext()&&ComparisonUtils.equals(n.peek(),i)){const t=n.next(),s=this._modified.get(t);if(!e(s,t)){r=!0;return!1}return!0}if(!this._removed.has(i)&&!e(s,i)){r=!0;return!1}return!0},t,s);if(r)return}for(;n.hasNext();){const t=n.next(),s=await this.get(t);if(!e(s,t))break}}async maxValue(e=null){const t=await this.maxKey(e);return this.get(t)}async maxKey(e=null){let t=undefined;this._truncated||(t=await this._parent.maxKey(e));for(;t!==undefined&&this._removed.has(t);){const s=KeyRange.upperBound(t,!0);t=await this._parent.maxKey(s);if(null!==e&&!e.includes(t)){t=undefined;break}}for(const s of this._modified.keys())(null===e||e.includes(s))&&(t===undefined||ComparisonUtils.compare(s,t)>0)&&(t=s);return t}async minValue(e=null){const t=await this.minKey(e);return this.get(t)}async minKey(e=null){let t=undefined;this._truncated||(t=await this._parent.minKey(e));for(;t!==undefined&&this._removed.has(t);){const s=KeyRange.lowerBound(t,!0);t=await this._parent.minKey(s);if(null!==e&&!e.includes(t)){t=undefined;break}}for(const s of this._modified.keys())(null===e||e.includes(s))&&(t===undefined||s<t)&&(t=s);return t}async count(e=null){return(await this.keys(e)).size}index(e){return this._indices.get(e)}close(){return this.abort()}transaction(e=!0){if(this._state!==Transaction.STATE.OPEN&&this._state!==Transaction.STATE.NESTED)throw new Error("Transaction already closed");const t=new Transaction(this._objectStore,this,this,e);this._nested.add(t);this._state=Transaction.STATE.NESTED;return t}synchronousTransaction(e=!0){if(this._state!==Transaction.STATE.OPEN&&this._state!==Transaction.STATE.NESTED)throw new Error("Transaction already closed");const t=new SynchronousTransaction(this._objectStore,this,this,e);this._nested.add(t);this._state=Transaction.STATE.NESTED;return t}isSynchronous(){return!1}snapshot(){if(this.state!==Transaction.STATE.COMMITTED){const e=this._managingBackend.snapshot();e.inherit(this);return e}return this._snapshotManager.createSnapshot(this._objectStore,this)}toString(){return`Transaction{id=${this._id}, changes=±${this._modified.size+this._removed.size}, truncated=${this._truncated}, objectStore=${this._objectStore}, state=${this._state}, dependency=${this._dependency}}`}toStringShort(){return`Transaction{id=${this._id}, changes=±${this._modified.size+this._removed.size}, truncated=${this._truncated}, state=${this._state}, dependency=${this._dependency}}`}async commit(e){if(e!==undefined){if(!this._isCommittable(e)){await this.abort(e);return!1}await this._commitInternal(e);return!0}if(null!==this._dependency)return this._dependency.commit();await this._checkConstraints();return this._commitBackend()}async abort(e){if(e!==undefined){if(e instanceof Snapshot)return this._snapshotManager.abortSnapshot(e);if(!this._nested.has(e)||e.state!==Transaction.STATE.OPEN)throw new Error("Can only abort open, nested transactions");this._nested["delete"](e);if(0===this._nested.size){this._state=Transaction.STATE.OPEN;this._nestedCommitted=!1}return!0}return null!==this._dependency?this._dependency.abort():this._abortBackend()}async _apply(e){if(!(e instanceof Transaction))throw new Error("Can only apply transactions");await this._snapshotManager.applyTx(e,this);this._applySync(e)}async _commitBackend(){if(this._state!==Transaction.STATE.OPEN)throw new Error("Transaction already closed or in nested state");this._enableWatchdog&&clearTimeout(this._watchdog);const e=Date.now();if(await this._managingBackend.commit(this)){this._state=Transaction.STATE.COMMITTED;this._performanceCheck(e,"commit");this._performanceCheck();return!0}this._state=Transaction.STATE.CONFLICTED;this._performanceCheck(e,"commit");this._performanceCheck();return!1}_performanceCheck(e=this._startTime,t=null){const s=Date.now()-e;t=t?` function '${t}'`:"";s>Transaction.WATCHDOG_TIMER&&Log.w(Transaction,`Violation: tx id ${this._id}${t} took ${(s/1e3).toFixed(2)}s (${this.toString()}).`)}_isCommittable(e){if(e!==undefined){if(!this._nested.has(e)||e.state!==Transaction.STATE.OPEN)throw new Error("Can only commit open, nested transactions");return!this._nestedCommitted}return this._managingBackend._isCommittable(this)}async _commitInternal(e){this._nested["delete"](e);this._nestedCommitted=!0;await this._apply(e);if(0===this._nested.size){this._state=Transaction.STATE.OPEN;this._nestedCommitted=!1}}_setParent(e){this._parent=e}async _abortBackend(){if(this._state===Transaction.STATE.ABORTED||this._state===Transaction.STATE.CONFLICTED)return!0;if(this._state!==Transaction.STATE.OPEN&&this._state!==Transaction.STATE.NESTED)throw new Error("Transaction already closed");this._state===Transaction.STATE.NESTED&&await Promise.all(Array.from(this._nested).map(e=>e.abort()));this._enableWatchdog&&clearTimeout(this._watchdog);const e=Date.now();await this._managingBackend.abort(this);this._setAborted();this._performanceCheck(e,"abort");this._performanceCheck();return!0}_setAborted(){this._state=Transaction.STATE.ABORTED}_put(e,t){this._removed["delete"](e);const s=this._modified.get(e);this._modified.set(e,t);for(const r of this._indices.values())r.put(e,t,s)}_remove(e){this._removed.add(e);const t=this._modified.get(e);this._modified["delete"](e);for(const s of this._indices.values())s.remove(e,t)}async _checkConstraints(){const e=[];for(const s of this._indices.values())if(s.unique)for(const[t,r]of this._modified)e.push(s.checkUniqueConstraint(t,r));if(e.length>0)try{await Promise.all(e)}catch(t){await this.abort();throw t}}decode(e,t){return this._objectStore.decode(e,t)}encode(e){return this._objectStore.encode(e)}}Transaction.WATCHDOG_TIMER=5e3;Transaction.STATE={OPEN:0,COMMITTED:1,ABORTED:2,CONFLICTED:3,NESTED:4};Transaction._instanceCount=0;Class.register(Transaction);class SynchronousTransaction extends Transaction{constructor(e,t,s,r=!0){super(e,t,s,r);this._cache=new Map}preload(e){e=e.filter(e=>!this.isCached(e));return Promise.all(e.map(e=>this.get(e)))}isCached(e){return this._cache.has(e)||!!this._parent.isSynchronous()&&this._parent.isCached(e)}async get(e,t={}){t.expectPresence=!1;let s;if(this.isCached(e))s=this.getSync(e,t);else{s=await Transaction.prototype.get.call(this,e,t);t&&t.raw?this._cache.set(e,this.decode(s,e)):this._cache.set(e,s)}return s}_getCached(e,t={}){const{expectPresence:s=!0}=t||{};let r=this._cache.get(e);if(!r&&this._parent.isSynchronous())return this._parent.getSync(e,t);if(s&&!r)throw new Error(`Missing key in cache: ${e}`);t&&t.raw&&(r=this.encode(r));return r}getSync(e,t={}){return this._removed.has(e)?undefined:this._modified.has(e)?t&&t.raw?this.encode(this._modified.get(e)):this._modified.get(e):this._truncated?undefined:this._getCached(e,t)}isSynchronous(){return!0}}Class.register(SynchronousTransaction);class Snapshot extends Transaction{constructor(e,t){super(e,t,e,!1)}inherit(e){if(!(e instanceof Transaction))throw new Error("Can only inherit transactions");return super._applySync(e)}async _apply(e){if(!(e instanceof Transaction))throw new Error("Can only apply transactions");e._truncated&&await this.valueStream((e,t)=>{this._modified.has(t)||this._put(t,e);return!0});for(const[t,s]of e._modified){if(this._modified.has(t))continue;let e=await this.get(t);e?this._put(t,e,s):this._remove(t,s)}for(const t of e._removed){if(this._modified.has(t))continue;let e=await this.get(t);this._put(t,e)}}async truncate(){throw new Error("Unsupported operation on snapshots: truncate")}truncateSync(){throw new Error("Unsupported operation on snapshots: truncateSync")}async commit(e){throw new Error("Cannot commit snapshots: commit")}_isCommittable(e){return!1}async _commitInternal(e){throw new Error("Cannot commit snapshots")}async _commitBackend(){throw new Error("Cannot commit snapshots")}abort(e){return this._abortBackend()}async _abortBackend(){if(this._state!==Transaction.STATE.OPEN)throw new Error("Snapshot already closed");if(!(await this._managingBackend.abort(this)))return!1;this._state=Transaction.STATE.ABORTED;this._truncated=!0;this._modified.clear();this._removed.clear();for(const e of this._indices.values())e.truncate();return!0}async put(e,t){throw new Error("Unsupported operation on snapshots: put")}putSync(e,t){throw new Error("Unsupported operation on snapshots: putSync")}async remove(e){throw new Error("Unsupported operation on snapshots: remove")}removeSync(e){throw new Error("Unsupported operation on snapshots: removeSync")}close(){return this.abort()}transaction(){throw new Error("Unsupported operation on snapshots: transaction")}synchronousTransaction(){throw new Error("Unsupported operation on snapshots: synchronousTransaction")}snapshot(){throw new Error("Unsupported operation on snapshots: snapshot")}}Class.register(Snapshot);class SnapshotManager{constructor(){this._snapshots=new Set}createSnapshot(e,t){const s=new Snapshot(e,t);this._snapshots.add(s);return s}abortSnapshot(e){return this._snapshots["delete"](e)}async applyTx(e,t){if(!(e instanceof Transaction))throw new Error("Can only apply transactions");const s=[];for(const r of this._snapshots)s.push(r._apply(e));for(const r of e._snapshotManager){r._backend=t;this._snapshots.add(r)}return Promise.all(s)}[Symbol.iterator](){return this._snapshots.values()}}Class.register(SnapshotManager);class CombinedTransaction{constructor(...e){if(!this.isConsistent(e))throw new Error("Given set of transactions violates rules for combined transactions");this._transactions=e;this._flushable=new Map;this._preprocessing=[];this._dependency=this}get backend(){return this._jdb}get transactions(){return this._transactions}isConsistent(e){const t=new Set;this._jdb=null;for(const s of e){if(s.state!==Transaction.STATE.OPEN)return!1;if(s.nested)return!1;if(t.has(s._objectStore))return!1;if(null===this._jdb)this._jdb=s._objectStore.jungleDB;else if(this._jdb!==s._objectStore.jungleDB&&null!==s._objectStore.jungleDB)return!1;t.add(s._objectStore)}return!0}async onFlushable(e,t=null,s=null){this._flushable.set(e,t);null!==s&&this._preprocessing.push(s);if(this._transactions.every(e=>this._flushable.has(e))){const e=[];for(const t of this._preprocessing)e.push(t());await Promise.all(e);await JungleDB.commitCombined(this);for(const t of this._flushable.values())t();return!0}return!1}async commit(){if(this._isCommittable()){await this._checkConstraints();await this._commitBackend();return!0}await this.abort();return!1}abort(){return this._abortBackend()}async _abortBackend(){return(await Promise.all(this._transactions.map(e=>e._abortBackend()))).every(e=>e)}transaction(e){throw new Error("Unsupported operation")}snapshot(){throw new Error("Unsupported operation")}_isCommittable(){return this._transactions.every(e=>e._isCommittable())}async _checkConstraints(){try{await Promise.all(this._transactions.map(e=>e._checkConstraints()))}catch(e){await this.abort();throw e}}async _commitBackend(){return(await Promise.all(this._transactions.map(e=>e._commitBackend()))).every(e=>e)}async _commitInternal(e){throw new Error("Cannot commit transactions to a combined transaction")}_setParent(e){throw new Error("Unsupported operation")}set _dependency(e){for(const t of this._transactions)t._dependency=e}get dependency(){return this}get objectStore(){throw new Error("Unsupported operation")}toString(){return`CombinedTransaction{size=${this._transactions.length}, states=[${this._transactions.map(e=>e.state)}]}`}}Class.register(CombinedTransaction);e._loaded=!0;"function"==typeof e._onload&&e._onload()}(JDB);var Proxy,exports={},Krypton=exports;Krypton._currentScript||(Krypton._currentScript=document.currentScript);if(!Krypton._currentScript){const e=document.getElementsByTagName("script");Krypton._currentScript=e[e.length-1]}Krypton._path||(Krypton._currentScript&&-1!==Krypton._currentScript.src.indexOf("/")?Krypton._path=Krypton._currentScript.src.substring(0,Krypton._currentScript.src.lastIndexOf("/")+1):Krypton._path="./");class Class{static get scope(){return"undefined"!=typeof exports?exports:"undefined"!=typeof self?self:window}static register(e){"undefined"!=typeof exports&&(exports[e.name]=e)}}Class.register(Class);class LogNative{constructor(){this._global_level=Log.INFO;this._tag_levels={};try{if(window.localStorage)try{let t=window.localStorage.getItem("log_tag_levels");t&&"string"==typeof t&&(t=JSON.parse(t));t&&"object"==typeof t&&(this._tag_levels=t)}catch(e){console.warn("Failed to load log configuration from local storage.")}}catch(e){}}isLoggable(e,t){return e&&this._tag_levels[e]?this._tag_levels[e]<=t:this._tag_levels["*"]?this._tag_levels["*"]<=t:this._global_level<=t}setLoggable(e,t){e&&e.name&&(e=e.name);this._tag_levels[e]=t;window.localStorage&&window.localStorage.setItem("log_tag_levels",JSON.stringify(this._tag_levels))}msg(e,t,s){t&&t.name&&(t=t.name);if(this.isLoggable(t,e)){t&&s.unshift(t+":");s.unshift(`[${Log.Level.toStringTag(e)} ${(new Date).toTimeString().substr(0,8)}]`);console.error&&e>=Log.ERROR?console.error.apply(console,s):console.warn&&e>=Log.WARNING?console.warn.apply(console,s):console.info&&e>=Log.INFO?console.info.apply(console,s):console.debug&&e>=Log.DEBUG?console.debug.apply(console,s):console.trace&&e<=Log.TRACE?console.trace.apply(console,s):console.log.apply(console,s)}}}Class.register(LogNative);class Log{static get instance(){Log._instance||(Log._instance=new Log(new LogNative));return Log._instance}constructor(e){this._native=e}setLoggable(e,t){this._native.setLoggable(e,Log.Level.get(t))}get level(){return this._native._global_level}set level(e){this._native._global_level=Log.Level.get(e)}msg(e,t,s){if(this._native.isLoggable(t,e)){for(let e=0;e<s.length;++e){"function"==typeof s[e]&&(s[e]=s[e]());"object"==typeof s[e]&&("function"==typeof s[e].toString?s[e]=s[e].toString():s[e].constructor&&s[e].constructor.name?s[e]=`{Object: ${s[e].constructor.name}}`:s[e]="{Object}")}this._native.msg(e,t,s)}}static d(e,t,...s){if(arguments.length>=2){e=arguments[0];s=Array.prototype.slice.call(arguments,1)}else{e=undefined;s=Array.prototype.slice.call(arguments,0)}Log.instance.msg(Log.DEBUG,e,s)}static e(e,t,...s){if(arguments.length>=2){e=arguments[0];s=Array.prototype.slice.call(arguments,1)}else{e=undefined;s=Array.prototype.slice.call(arguments,0)}Log.instance.msg(Log.ERROR,e,s)}static i(e,t,...s){if(arguments.length>=2){e=arguments[0];s=Array.prototype.slice.call(arguments,1)}else{e=undefined;s=Array.prototype.slice.call(arguments,0)}Log.instance.msg(Log.INFO,e,s)}static v(e,t,...s){if(arguments.length>=2){e=arguments[0];s=Array.prototype.slice.call(arguments,1)}else{e=undefined;s=Array.prototype.slice.call(arguments,0)}Log.instance.msg(Log.VERBOSE,e,s)}static w(e,t,...s){if(arguments.length>=2){e=arguments[0];s=Array.prototype.slice.call(arguments,1)}else{e=undefined;s=Array.prototype.slice.call(arguments,0)}Log.instance.msg(Log.WARNING,e,s)}static t(e,t,...s){if(arguments.length>=2){e=arguments[0];s=Array.prototype.slice.call(arguments,1)}else{e=undefined;s=Array.prototype.slice.call(arguments,0)}Log.instance.msg(Log.TRACE,e,s)}}Log.Level={TRACE:1,VERBOSE:2,DEBUG:3,INFO:4,WARNING:5,ERROR:6,ASSERT:7,toStringTag:function(e){switch(e){case Log.Level.TRACE:return"T";case Log.Level.VERBOSE:return"V";case Log.Level.DEBUG:return"D";case Log.Level.INFO:return"I";case Log.Level.WARNING:return"W";case Log.Level.ERROR:return"E";case Log.Level.ASSERT:return"A";default:return"*"}},toString:function(e){switch(e){case Log.Level.TRACE:return"trace";case Log.Level.VERBOSE:return"verbose";case Log.Level.DEBUG:return"debug";case Log.Level.INFO:return"info";case Log.Level.WARNING:return"warn";case Log.Level.ERROR:return"error";case Log.Level.ASSERT:return"assert";default:return"unknown"}},get:function(e){if("number"==typeof e)return e;if(!isNaN(parseInt(e)))return parseInt(e);switch(e.toLowerCase()){case"t":case"trace":return Log.Level.TRACE;case"v":case"verbose":return Log.Level.VERBOSE;case"d":case"debug":return Log.Level.DEBUG;case"i":case"info":return Log.Level.INFO;case"w":case"warn":case"warning":return Log.Level.WARNING;case"e":case"error":case"exception":return Log.Level.ERROR;case"a":case"assert":case"assertion":return Log.Level.ASSERT}return 0}};Log.TRACE=Log.Level.TRACE;Log.VERBOSE=Log.Level.VERBOSE;Log.DEBUG=Log.Level.DEBUG;Log.INFO=Log.Level.INFO;Log.WARNING=Log.Level.WARNING;Log.ERROR=Log.Level.ERROR;Log.ASSERT=Log.Level.ASSERT;Log._instance=null;Log.d.tag=(e=>Log.d.bind(null,e));Log.e.tag=(e=>Log.e.bind(null,e));Log.i.tag=(e=>Log.i.bind(null,e));Log.v.tag=(e=>Log.v.bind(null,e));Log.w.tag=(e=>Log.w.bind(null,e));Log.t.tag=(e=>Log.t.bind(null,e));Class.register(Log);class Observable{static get WILDCARD(){return"*"}constructor(){this._listeners=new Map}_offAll(){this._listeners.clear()}on(e,t){if(this._listeners.has(e))return this._listeners.get(e).push(t)-1;this._listeners.set(e,[t]);return 0}off(e,t){this._listeners.has(e)&&this._listeners.get(e)[t]&&delete this._listeners.get(e)[t]}fire(e,...t){const s=[];if(this._listeners.has(e)){const n=this._listeners.get(e);for(const i in n)if(n.hasOwnProperty(i))try{const o=n[i].apply(null,t);o instanceof Promise&&s.push(o["catch"](t=>Log.e(this.constructor.name,`Exception thrown by '${e}' listener #${i}: ${t.message||t}`,t)))}catch(r){Log.e(this.constructor.name,`Exception thrown by '${e}' listener #${i}: ${r.message||r}`,r)}}if(this._listeners.has(Observable.WILDCARD)){const t=this._listeners.get(Observable.WILDCARD);for(const n in t)if(t.hasOwnProperty(n))try{const i=t[n].apply(null,arguments);i instanceof Promise&&s.push(i["catch"](t=>Log.e(this.constructor.name,`Exception thrown by '${e}' wildcard listener #${n}: ${t.message||t}`,t)))}catch(r){Log.e(this.constructor.name,`Exception thrown by '${e}' wildcard listener #${n}: ${r.message||r}`,r)}}return s.length>0?Promise.all(s):null}bubble(e,...t){for(const s of t){let t;t=s===Observable.WILDCARD?function(){this.fire.apply(this,arguments)}:function(){this.fire.apply(this,[s,...arguments])};e.on(s,t.bind(this))}}}Class.register(Observable);class DataChannel extends Observable{constructor(){super();this._buffer=null;this._currentMessageLength=0;this._msgType=0;this._receivingTag=-1;this._sendingTag=0;this._expectedMessagesByType=new Map;this._timers=new Timers;this._lastChunkReceivedAt=0;this._closed=!1}isExpectingMessage(e){return this._expectedMessagesByType.has(e)}confirmExpectedMessage(e,t){const s=this._expectedMessagesByType.get(e);if(s){this._timers.clearTimeout(`chunk-${s.id}`);this._timers.clearTimeout(`msg-${s.id}`);for(const e of s.types)this._expectedMessagesByType["delete"](e);t||s.onErrorOrTimeout()}}expectMessage(e,t,s=DataChannel.MESSAGE_TIMEOUT,r=DataChannel.CHUNK_TIMEOUT){Array.isArray(e)||(e=[e]);if(0===e.length)return;const n=new ExpectedMessage(e,t,s,r);for(const i of e)this._expectedMessagesByType.set(i,n);this._timers.resetTimeout(`chunk-${n.id}`,this._onTimeout.bind(this,n),r);this._timers.resetTimeout(`msg-${n.id}`,this._onTimeout.bind(this,n),s)}close(){if(!this._closed){this._closed=!0;this._timers.clearAll();for(let e of this._expectedMessagesByType.values())e.onErrorOrTimeout();this._close();this.fire("close",this);this._offAll()}}_close(){throw new Error("Not implemented")}_error(e){this.fire("error",e,this);Log.e(DataChannel,e);this.close()}_onMessage(e){try{if(this.readyState!==DataChannel.ReadyState.OPEN)return;const s=new SerialBuffer(e);if(0===s.byteLength)return;if(s.byteLength>DataChannel.CHUNK_SIZE_MAX){this._error("Received chunk larger than maximum chunk size, discarding");return}const r=s.readUint8(),n=s.byteLength-s.readPos,i=s.read(n);if(null===this._buffer&&r===(this._receivingTag+1)%NumberUtils.UINT8_MAX){const e=new SerialBuffer(i),t=Message.peekLength(e);if(t>DataChannel.MESSAGE_SIZE_MAX){this._error(`Received message with excessive message size ${t} > ${DataChannel.MESSAGE_SIZE_MAX}`);return}this._buffer=new SerialBuffer(Math.min(t,DataChannel.CHUNK_SIZE_MAX));this._currentMessageLength=t;this._receivingTag=r;this._msgType=Message.peekType(e)}if(null===this._buffer){Log.e(DataChannel,`Message does not start with next tag ${this._receivingTag+1} (got ${r} instead), but buffer is null`);return}if(r!==this._receivingTag){this._error(`Received message with wrong message tag ${r}, expected ${this._receivingTag}`);return}let o=this._currentMessageLength-this._buffer.writePos;if(n>o){this._error("Received chunk larger than remaining bytes to read, discarding");return}if(s.byteLength!==DataChannel.CHUNK_SIZE_MAX&&n!==o){this._error("Received chunk that is neither max chunk size nor the final chunk");return}if(this._buffer.byteLength<this._buffer.writePos+n){const e=new SerialBuffer(Math.min(2*this._buffer.byteLength,this._currentMessageLength));e.set(this._buffer);e.writePos=this._buffer.writePos;this._buffer=e}this._buffer.write(i);o-=n;this._lastChunkReceivedAt=Date.now();const a=this._expectedMessagesByType.get(this._msgType);if(0===o){const e=this._buffer.buffer;this._buffer=null;this._currentMessageLength=0;this._timers.clearTimeout("next-chunk");this.fire("message",e,this)}else{a?this._timers.resetTimeout(`chunk-${a.id}`,this._onTimeout.bind(this,a),a.chunkTimeout):this._timers.resetTimeout("next-chunk",this._onTimeout.bind(this),DataChannel.CHUNK_TIMEOUT);this.fire("chunk",this._buffer)}}catch(t){this._error(`Error occurred while parsing incoming message: ${t.message||t}`)}}_onTimeout(e){if(e){this._timers.clearTimeout(`chunk-${e.id}`);this._timers.clearTimeout(`msg-${e.id}`);for(const t of e.types)this._expectedMessagesByType["delete"](t);e.onErrorOrTimeout()}else Log.w(DataChannel,"DataChannel receive timeout");this._buffer=null}send(e){Assert.that(e.byteLength<=DataChannel.MESSAGE_SIZE_MAX,"DataChannel.send() max message size exceeded");const t=this._sendingTag;this._sendingTag=(this._sendingTag+1)%NumberUtils.UINT8_MAX;this._sendChunked(e,t)}_sendChunked(e,t){let s=e.byteLength,r=null;for(;s>0;){let n=null;if(s+1>=DataChannel.CHUNK_SIZE_MAX){(n=new SerialBuffer(DataChannel.CHUNK_SIZE_MAX)).writeUint8(t);r=new Uint8Array(e.buffer,e.byteLength-s,DataChannel.CHUNK_SIZE_MAX-1)}else{(n=new SerialBuffer(s+1)).writeUint8(t);r=new Uint8Array(e.buffer,e.byteLength-s,s)}n.write(r);this.sendChunk(n);s-=r.byteLength}}sendChunk(e){throw new Error("Not implemented")}get readyState(){throw new Error("Not implemented")}get lastMessageReceivedAt(){return this._lastChunkReceivedAt}}DataChannel.CHUNK_SIZE_MAX=16384;DataChannel.MESSAGE_SIZE_MAX=10485760;DataChannel.CHUNK_TIMEOUT=5e3;DataChannel.MESSAGE_TIMEOUT=DataChannel.MESSAGE_SIZE_MAX/DataChannel.CHUNK_SIZE_MAX*DataChannel.CHUNK_TIMEOUT;Class.register(DataChannel);class ExpectedMessage{constructor(e,t,s=DataChannel.MESSAGE_TIMEOUT,r=DataChannel.CHUNK_TIMEOUT){this.id=e.join(":");this.types=e;this._errorOrTimeoutCallback=t;this._errorOrTimeoutCallbackInvoked=!1;this.msgTimeout=s;this.chunkTimeout=r}onErrorOrTimeout(){if(!this._errorOrTimeoutCallbackInvoked){this._errorOrTimeoutCallbackInvoked=!0;this._errorOrTimeoutCallback()}}}DataChannel.ReadyState={CONNECTING:0,OPEN:1,CLOSING:2,CLOSED:3,fromString:function(e){switch(e){case"connecting":return DataChannel.ReadyState.CONNECTING;case"open":return DataChannel.ReadyState.OPEN;case"closing":return DataChannel.ReadyState.CLOSING;case"closed":return DataChannel.ReadyState.CLOSED;default:throw new Error("Invalid string")}}};class CryptoLib{static get instance(){if(!CryptoLib._instance){const e={};e.getRandomValues=(window.crypto||window.msCrypto).getRandomValues.bind(window.crypto);CryptoLib._instance=e}return CryptoLib._instance}}CryptoLib._instance=null;Class.register(CryptoLib);class WebRtcFactory{static newPeerConnection(e){return new RTCPeerConnection(e)}static newSessionDescription(e){return new RTCSessionDescription(e)}static newIceCandidate(e){return new RTCIceCandidate(e)}}Class.register(WebRtcFactory);class WebSocketFactory{static newWebSocketServer(){return new Observable}static newWebSocket(e){return new WebSocket(e)}}Class.register(WebSocketFactory);class HttpRequest{static get(e,t=5e3,s=-1){return new Promise((s,r)=>{const n=new XMLHttpRequest;n.open("GET",e,!0);n.responseType="text";n.timeout=t;n.onload=(()=>{n.readyState===XMLHttpRequest.DONE&&200===n.status?s(n.responseText):r(new Error(`Request failed (status ${n.status})`))});n.onerror=r;n.onabort=r;n.ontimeout=r;n.send();setTimeout(()=>n.abort(),t)})}}Class.register(HttpRequest);class PlatformUtils{static isBrowser(){return!0}static isWeb(){return"undefined"!=typeof window}static isNodeJs(){return!1}static supportsWebRTC(){const e=PlatformUtils.isBrowser()?window.RTCPeerConnection||window.webkitRTCPeerConnection:null;return!!e&&"function"==typeof e.prototype.createDataChannel}static supportsWS(){return location&&"http:"===location.protocol}static isOnline(){return!("onLine"in window.navigator)||window.navigator.onLine}static isWindows(){return/^win/.test(window.navigator.platform)}static get userAgentString(){try{return window.navigator.platform}catch(e){return"unknown"}}static get hardwareConcurrency(){return"object"==typeof navigator&&navigator.hardwareConcurrency?navigator.hardwareConcurrency:1}}Class.register(PlatformUtils);class WasmHelper{static async doImport(){return WasmHelper.doImportBrowser()}static async doImportBrowser(){WasmHelper._importBrowserPromise=WasmHelper._importBrowserPromise||(async()=>{await WasmHelper.importWasmBrowser("worker-wasm.wasm")?await WasmHelper.importScriptBrowser("worker-wasm.js","Module","sha256-Pbm9dyLcorY4zzI5YHfcFL2c8cVh2AJOIsxqa3ceOp4="):await WasmHelper.importScriptBrowser("worker-js.js","Module","sha256-Ym7/F/nwZ7ZVkZcFF1RSK0M0DhYBfB+lQHiEJ1N9lgI=")})();try{await WasmHelper._importBrowserPromise}catch(e){WasmHelper._importBrowserPromise=null;throw e}}static async importWasm(e,t="Module"){return WasmHelper.importWasmBrowser(e,t)}static async importWasmBrowser(e,t="Module"){e=WasmHelper._adjustWasmPath(e);if(!WasmHelper._global.WebAssembly){Log.w(WasmHelper,"No support for WebAssembly available.");return Promise.resolve(!1)}return new Promise(s=>{try{const n=new XMLHttpRequest;n.open("GET",e,!0);n.responseType="arraybuffer";n.onload=function(){WasmHelper._global[t]=WasmHelper._global[t]||{};WasmHelper._global[t].wasmBinary=n.response;s(!0)};n.onerror=function(){Log.w(WasmHelper,`Failed to access WebAssembly module ${e}`);s(!1)};n.send(null)}catch(r){Log.w(WasmHelper,`Failed to access WebAssembly module ${e}`);s(!1)}})}static async importScript(e,t="Module"){return WasmHelper.importScriptBrowser(e,t)}static async importScriptBrowser(e,t="Module",s=null){if(t&&WasmHelper._global[t]&&WasmHelper._global[t].asm)return!1;e=WasmHelper._adjustScriptPath(e);const r=WasmHelper._global[t]||{};return new Promise(async(n,i)=>{const o=new Promise(e=>{r.onRuntimeInitialized=(()=>e(!0))});if("function"==typeof importScripts){await new Promise(s=>{WasmHelper._moduleLoadedCallbacks[t]=s;importScripts(e)});WasmHelper._global[t]=WasmHelper._global[t](r)}else if("object"==typeof window){await new Promise(r=>{WasmHelper._moduleLoadedCallbacks[t]=r;WasmHelper._loadBrowserScript(e,s)});WasmHelper._global[t]=WasmHelper._global[t](r)}else{if("function"!=typeof require){i("No way to load scripts.");return}WasmHelper._global[t]=require(e)(r)}await o;r.asm&&!WasmHelper._global[t].asm&&(WasmHelper._global[t]=r);n(!0)})}static fireModuleLoaded(e="Module"){if("function"==typeof WasmHelper._moduleLoadedCallbacks[e]){WasmHelper._moduleLoadedCallbacks[e]();WasmHelper._moduleLoadedCallbacks[e]=null}}static _loadBrowserScript(e,t){const s=document.getElementsByTagName("head")[0],r=document.createElement("script");r.type="text/javascript";r.src=e;if(null!=t){r.integrity=t;r.crossOrigin="anonymous"}s.appendChild(r)}static _adjustWasmPath(e){"undefined"!=typeof Krypton&&Krypton._path&&(e=`${Krypton._path}${e}`);"string"==typeof __dirname&&-1===e.indexOf("/")&&(e=`${__dirname}/${e}`);return e}static _adjustScriptPath(e){"undefined"!=typeof Krypton&&Krypton._path&&(e=`${Krypton._path}${e}`);"string"==typeof __dirname&&-1===e.indexOf("/")&&(e=`${__dirname}/${e}`);return e}static get _global(){return"undefined"!=typeof global?global:"undefined"!=typeof window?window:"undefined"!=typeof self?self:null}}WasmHelper._moduleLoadedCallbacks={};Class.register(WasmHelper);class ConstantHelper{constructor(){this._originalValues=new Map}static get instance(){ConstantHelper._instance||(ConstantHelper._instance=new ConstantHelper);return ConstantHelper._instance}isConstant(e){if(e.indexOf(".")<1)return!1;const t=e.split(".",2)[0];return!(e=e.split(".",2)[1]).startsWith("_")&&(e.toUpperCase()===e&&(t in Class.scope&&(!!Class.scope[t]&&(!!Class.scope[t].hasOwnProperty&&(!!Class.scope[t].hasOwnProperty(e)&&(!!Object.keys(Class.scope[t]).includes(e)&&"number"==typeof Class.scope[t][e]))))))}_ensureIsConstant(e){if(!this.isConstant(e))throw new Error(`${e} is not a numerical constant.`)}get(e){this._ensureIsConstant(e);const t=e.split(".",2)[0];e=e.split(".",2)[1];return Class.scope[t][e]}set(e,t){this._ensureIsConstant(e);this._originalValues.has(e)||this._originalValues.set(e,this.get(e));const s=e.split(".",2)[0];e=e.split(".",2)[1];Class.scope[s][e]=t}reset(e){this._ensureIsConstant(e);if(this._originalValues.has(e)){this.set(e,this._originalValues.get(e));this._originalValues["delete"](e)}}resetAll(){for(const e of this._originalValues.keys())this.set(e,this._originalValues.get(e));this._originalValues.clear()}}Class.register(ConstantHelper);class Services{constructor(e=Services.NONE,t=Services.NONE){this._provided=e;this._accepted=t}get provided(){return this._provided}get accepted(){return this._accepted}set provided(e){this._provided=e}set accepted(e){this._accepted=e}static isFullNode(e){return 0!=(e&Services.FLAG_FULL)}static isLightNode(e){return 0!=(e&Services.FLAG_LIGHT)}static isNanoNode(e){return e===Services.FLAG_NANO}static providesServices(e,...t){e=Services.legacyProvideToCurrent(e);const s=t.reduce((e,t)=>e|t)&Services.ALL_CURRENT;return(e&s)===s}static legacyProvideToCurrent(e){e===Services.FLAG_NANO&&(e=Services.PROVIDES_NANO);e===Services.FLAG_LIGHT&&(e=Services.PROVIDES_LIGHT);e===Services.FLAG_FULL&&(e=Services.PROVIDES_FULL);return e}static toNameArray(e){const t=[];let s=1;do{(e&s)===s&&Services.NAMES[s]&&t.push(Services.NAMES[s]);s<<=1}while(s<Services.ALL_CURRENT);return t}}Services.NONE=0;Services.FLAG_NANO=1;Services.FLAG_LIGHT=2;Services.FLAG_FULL=4;Services.ALL_LEGACY=7;Services.FULL_BLOCKS=8;Services.BLOCK_HISTORY=16;Services.BLOCK_PROOF=32;Services.CHAIN_PROOF=64;Services.ACCOUNTS_PROOF=128;Services.ACCOUNTS_CHUNKS=256;Services.MEMPOOL=512;Services.TRANSACTION_INDEX=1024;Services.BODY_PROOF=2048;Services.ALL_CURRENT=4095-Services.ALL_LEGACY;Services.NAMES={};Services.NAMES[Services.FULL_BLOCKS]="FULL_BLOCKS";Services.NAMES[Services.BLOCK_HISTORY]="BLOCK_HISTORY";Services.NAMES[Services.BLOCK_PROOF]="BLOCK_PROOF";Services.NAMES[Services.CHAIN_PROOF]="CHAIN_PROOF";Services.NAMES[Services.ACCOUNTS_PROOF]="ACCOUNTS_PROOF";Services.NAMES[Services.ACCOUNTS_CHUNKS]="ACCOUNTS_CHUNKS";Services.NAMES[Services.MEMPOOL]="MEMPOOL";Services.NAMES[Services.TRANSACTION_INDEX]="TRANSACTION_INDEX";Services.NAMES[Services.BODY_PROOF]="BODY_PROOF";Services.PROVIDES_FULL=Services.FLAG_FULL|Services.ALL_CURRENT;Services.PROVIDES_LIGHT=Services.FLAG_LIGHT|Services.FULL_BLOCKS|Services.BLOCK_PROOF|Services.CHAIN_PROOF|Services.ACCOUNTS_PROOF|Services.ACCOUNTS_CHUNKS|Services.MEMPOOL|Services.BODY_PROOF;Services.PROVIDES_NANO=Services.FLAG_NANO|Services.CHAIN_PROOF;Services.PROVIDES_PICO=Services.NONE;Services.ACCEPTS_FULL=Services.FLAG_FULL|Services.FULL_BLOCKS|Services.BLOCK_HISTORY;Services.ACCEPTS_LIGHT=Services.FLAG_LIGHT|Services.FLAG_FULL|Services.FULL_BLOCKS|Services.CHAIN_PROOF|Services.ACCOUNTS_CHUNKS;Services.ACCEPTS_NANO=Services.FLAG_NANO|Services.FLAG_LIGHT|Services.FLAG_FULL|Services.CHAIN_PROOF;Services.ACCEPTS_PICO=Services.FLAG_NANO|Services.FLAG_LIGHT|Services.FLAG_FULL;Services.ACCEPTS_SPV=Services.BLOCK_PROOF|Services.ACCOUNTS_PROOF|Services.MEMPOOL|Services.TRANSACTION_INDEX|Services.BODY_PROOF;Class.register(Services);class Timers{constructor(){this._timeouts=Object.create(null);this._intervals=Object.create(null)}setTimeout(e,t,s){if(this._timeouts[e])throw new Error(`Duplicate timeout for key ${e}`);this._timeouts[e]=setTimeout(t,s)}clearTimeout(e){clearTimeout(this._timeouts[e]);delete this._timeouts[e]}resetTimeout(e,t,s){clearTimeout(this._timeouts[e]);this._timeouts[e]=setTimeout(t,s)}timeoutExists(e){return this._timeouts[e]!==undefined}setInterval(e,t,s){if(this._intervals[e])throw new Error(`Duplicate interval for key ${e}`);this._intervals[e]=setInterval(t,s)}clearInterval(e){clearInterval(this._intervals[e]);delete this._intervals[e]}resetInterval(e,t,s){clearInterval(this._intervals[e]);this._intervals[e]=setInterval(t,s)}intervalExists(e){return this._intervals[e]!==undefined}clearAll(){for(const e in this._timeouts)this.clearTimeout(e);for(const e in this._intervals)this.clearInterval(e)}}Class.register(Timers);class Version{static isCompatible(e){return e>=1}static createUserAgent(e){(e=e?e.trim():"").length>0&&(e=` ${e}`);const t=PlatformUtils.isBrowser()?"browser; ":PlatformUtils.isNodeJs()?"nodejs; ":"";return`core-js/${Version.CORE_JS_VERSION} (${t}${PlatformUtils.userAgentString})${e}`}}Version.CODE=2;Version.CORE_JS_VERSION="<filled-by-build-system>";Class.register(Version);Version.CORE_JS_VERSION="1.0.4-0.0.1";class Time{constructor(e=0){this._offset=e}get offset(){return this._offset}set offset(e){this._offset=e}now(){return Date.now()+this._offset}}Class.register(Time);class EventLoopHelper{static webYield(){return PlatformUtils.isWeb()?EventLoopHelper.yield():Promise.resolve()}static yield(){return new Promise(e=>setTimeout(e))}}Class.register(EventLoopHelper);class IteratorUtils{static alternate(...e){const t=e.length;let s=0,r=!1;const n=()=>{if(!r)for(let r=0;r<t;r++){const r=e[s].next();s=(s+1)%t;if(!r.done)return r}r=!0;return{done:!0}};return{next:n,[Symbol.iterator]:()=>({next:n})}}}Class.register(IteratorUtils);class ArrayUtils{static randomElement(e){return e[Math.floor(Math.random()*e.length)]}static subarray(e,t,s){function clamp(e,t,s){return e<t?t:e>s?s:e}t===undefined&&(t=0);s===undefined&&(s=e.byteLength);t=clamp(t,0,e.byteLength);let r=(s=clamp(s,0,e.byteLength))-t;r<0&&(r=0);return new Uint8Array(e.buffer,e.byteOffset+t,r)}static*k_combinations(e,t){const s=e.length;if(t>s)return;const r=Array.from(new Array(t),(e,t)=>t);yield r.map(t=>e[t]);const n=Array.from(new Array(t),(e,s)=>t-s-1);for(;;){let i=t-1,o=!1;for(i of n)if(r[i]!==i+s-t){o=!0;break}if(!o)return;r[i]+=1;for(const e of Array.from(new Array(t-i-1),(e,t)=>i+t+1))r[e]=r[e-1]+1;yield r.map(t=>e[t])}}}Class.register(ArrayUtils);class HashMap{constructor(e=HashMap._hash){this._map=new Map;this._fnHash=e}static _hash(e){return null===e||e===undefined?e:e.hashCode?e.hashCode():e.toString()}get(e){return this._map.get(this._fnHash(e))}put(e,t){this._map.set(this._fnHash(e),t)}remove(e){this._map["delete"](this._fnHash(e))}clear(){this._map.clear()}contains(e){return this._map.has(this._fnHash(e))}keys(){return Array.from(this._map.keys())}keyIterator(){return this._map.keys()}values(){return Array.from(this._map.values())}valueIterator(){return this._map.values()}entries(){return Array.from(this._map.entries())}entryIterator(){return this._map.entries()}get length(){return this._map.size}isEmpty(){return 0===this._map.size}}Class.register(HashMap);class HashSet{constructor(e=HashSet._hash){this._map=new Map;this._fnHash=e}static _hash(e){return null===e||e===undefined?e:e.hashCode?e.hashCode():e.toString()}add(e){this._map.set(this._fnHash(e),e)}addAll(e){for(const t of e)this.add(t)}get(e){return this._map.get(this._fnHash(e))}remove(e){this._map["delete"](this._fnHash(e))}removeAll(e){for(const t of e)this.remove(t)}clear(){this._map.clear()}contains(e){return this._map.has(this._fnHash(e))}values(){return Array.from(this._map.values())}valueIterator(){return this._map.values()}[Symbol.iterator](){return this.valueIterator()}get length(){return this._map.size}isEmpty(){return 0===this._map.size}}Class.register(HashSet);class LimitHashSet{constructor(e,t=LimitHashSet._hash){if(e<=0)throw new Error("Invalid limit");this._limit=e;this._fnHash=t;this._list=new UniqueLinkedList(t)}static _hash(e){return null===e||e===undefined?e:e.hashCode?e.hashCode():e.toString()}add(e){this._list.push(e,!0);this._list.length>this._limit&&this._list.shift()}addAll(e){for(const t of e)this.add(t)}get(e){return this._list.get(e)}remove(e){this._list.remove(e)}removeAll(e){for(const t of e)this.remove(t)}clear(){this._list.clear()}contains(e){return this._list.contains(e)}values(){return Array.from(this._list.iterator())}valueIterator(){return this._list.iterator()}[Symbol.iterator](){return this.valueIterator()}get length(){return this._list.length}isEmpty(){return 0===this._list.length}}Class.register(LimitHashSet);class InclusionHashSet{constructor(e=InclusionHashSet._hash){this._set=new Set;this._fnHash=e}static _hash(e){return null===e||e===undefined?e:e.hashCode?e.hashCode():e.toString()}add(e){this._set.add(this._fnHash(e))}addAll(e){for(const t of e)this.add(t)}remove(e){this._set["delete"](this._fnHash(e))}removeAll(e){for(const t of e)this.remove(t)}clear(){this._set.clear()}contains(e){return this._set.has(this._fnHash(e))}values(){return Array.from(this._set.values())}valueIterator(){return this._set.values()}[Symbol.iterator](){return this.valueIterator()}get length(){return this._set.size}isEmpty(){return 0===this._set.size}_addHashed(e){this._set.add(e)}clone(){const e=new InclusionHashSet(this._fnHash);for(const t of this)e._addHashed(t);return e}}Class.register(InclusionHashSet);class LimitInclusionHashSet{constructor(e,t=LimitInclusionHashSet._hash){if(e<=0)throw new Error("Invalid limit");this._limit=e;this._fnHash=t;this._list=new UniqueLinkedList(e=>e)}static _hash(e){return null===e||e===undefined?e:e.hashCode?e.hashCode():e.toString()}add(e){this.length>=this._limit&&this._list.shift();this._list.push(this._fnHash(e))}addAll(e){for(const t of e)this.add(t)}remove(e){this._list.remove(this._fnHash(e))}removeAll(e){for(const t of e)this.remove(t)}clear(){this._list.clear()}contains(e){return this._list.contains(this._fnHash(e))}values(){return Array.from(this._list)}valueIterator(){return this._list.iterator()}[Symbol.iterator](){return this.valueIterator()}get length(){return this._list.length}isEmpty(){return 0===this._list.length}_addHashed(e){this._list.push(e)}clone(){const e=new LimitInclusionHashSet(this._limit,this._fnHash);for(const t of this)e._addHashed(t);return e}}Class.register(LimitInclusionHashSet);class LimitIterable{constructor(e,t){this._iterator=e[Symbol.iterator]?e[Symbol.iterator]():e;this._limit=t}[Symbol.iterator](){return LimitIterable.iterator(this._iterator,this._limit)}static iterator(e,t){let s=0;return{next:()=>{const r=s++>=t,n=e.next();return{value:r?undefined:n.value,done:r||n.done}}}}}Class.register(LimitIterable);class LinkedList{constructor(...e){this._length=0;this._head=null;this._tail=null;const t=1===e.length&&Array.isArray(e[0])?e[0]:e;for(const s of t)this.push(s)}push(e){const t={next:null,prev:this._head,value:e};this._push(t)}_push(e){this._length++;if(this._head){this._head.next=e;this._head=e}else{this._head=e;this._tail=e}}unshift(e){const t={next:this._tail,prev:null,value:e};this._unshift(t)}_unshift(e){this._length++;if(this._head){this._tail.prev=e;this._tail=e}else{this._head=e;this._tail=e}}pop(){if(!this._head)return null;this._length--;const e=this._head,t=e.prev;if(!t){this._head=null;this._tail=null;return e.value}t.next=null;this._head=t;return e.value}shift(){if(!this._head)return null;this._length--;const e=this._tail,t=e.next;if(!t){this._head=null;this._tail=null;return e.value}t.prev=null;this._tail=t;return e.value}_remove(e){if(e===this._head)this.pop();else if(e===this._tail)this.shift();else{this._length--;e.prev.next=e.next;e.next.prev=e.prev}}clear(){this._length=0;this._head=null;this._tail=null}[Symbol.iterator](){return this.iterator()}*iterator(){let e=this._tail;for(;e;){yield e.value;e=e.next}}isEmpty(){return 0===this._length}get first(){return this._tail?this._tail.value:null}get last(){return this._head?this._head.value:null}get length(){return this._length}}Class.register(LinkedList);class UniqueLinkedList extends LinkedList{constructor(e){super();this._map=new HashMap(e)}push(e,t=!1){const s=this._map.get(e);if(s){s.value=e;t&&this._moveBack(s)}else super.push(e)}_push(e){super._push(e);this._map.put(e.value,e)}unshift(e){this._map.contains(e)||super.unshift(e)}_unshift(e){super._unshift(e);this._map.put(e.value,e)}pop(){const e=super.pop();this._map.remove(e);return e}shift(){const e=super.shift();this._map.remove(e);return e}clear(){super.clear();this._map.clear()}get(e){const t=this._map.get(e);return t&&t.value}contains(e){return this._map.contains(e)}remove(e){const t=this._map.get(e);if(t){super._remove(t);this._map.remove(e)}}moveBack(e){const t=this._map.get(e);t?this._moveBack(t):super.push(e)}_moveBack(e){if(e!==this._head){if(e===this._tail){e.next.prev=null;this._tail=e.next}else{e.prev.next=e.next;e.next.prev=e.prev}e.next=null;e.prev=this._head;this._head.next=e;this._head=e}}}Class.register(UniqueLinkedList);class Queue{constructor(...e){this._queue=this._newQueue(...e)}_newQueue(...e){return new LinkedList(...e)}enqueue(e){this._queue.push(e)}enqueueAll(e){for(const t of e)this.enqueue(t)}dequeue(){return this._queue.shift()}dequeueMulti(e){e=Math.min(this._queue.length,e);const t=[];for(let s=0;s<e;s++)t.push(this.dequeue());return t}peek(){return this._queue.first}clear(){this._queue.clear()}isEmpty(){return this._queue.isEmpty()}get length(){return this._queue.length}}Class.register(Queue);class UniqueQueue extends Queue{constructor(e){super(e)}_newQueue(...e){return new UniqueLinkedList(...e)}contains(e){return this._queue.contains(e)}remove(e){this._queue.remove(e)}requeue(e){this._queue.moveBack(e)}}Class.register(UniqueQueue);class ThrottledQueue extends UniqueQueue{constructor(e=Number.POSITIVE_INFINITY,t=e,s=1e3,r=Number.POSITIVE_INFINITY,n){super();this._maxSize=r;this._maxAtOnce=e;this._availableNow=this._maxAtOnce;this._timers=new Timers;this._timers.setInterval("allowance",()=>{this._availableNow=Math.min(this._maxAtOnce,this._availableNow+t);"function"==typeof n&&this.isAvailable()&&n()},s)}stop(){this._timers.clearAll()}enqueue(e){this.length>=this._maxSize&&super.dequeue();super.enqueue(e)}dequeue(){if(this.available>0){this._availableNow--;return super.dequeue()}return null}dequeueMulti(e){e=Math.min(this.available,e);return super.dequeueMulti(e)}isAvailable(){return this.available>0}get available(){return Math.min(this._availableNow,this.length)}}Class.register(ThrottledQueue);class SortedList{constructor(e=[],t){this._list=e;this._compare=t||SortedList._compare}static _compare(e,t){return e.compare?e.compare(t):e>t?1:e<t?-1:0}indexOf(e){let t=0,s=this._list.length-1,r=null,n=null;for(;t<=s;){r=Math.floor((t+s)/2);n=this._list[r];if(this._compare(n,e)<0)t=r+1;else{if(!(this._compare(n,e)>0)){for(;r>0&&0==this._compare(this._list[r-1],e);)r--;return r}s=r-1}}return-1}_insertionIndex(e){let t=0,s=this._list.length-1,r=null,n=null;for(;t<=s;){r=Math.floor((t+s)/2);n=this._list[r];if(this._compare(n,e)<0)t=r+1;else{if(!(this._compare(n,e)>0))return r;s=r-1}}return s+1}add(e){this._list.splice(this._insertionIndex(e),0,e)}shift(){return this._list.shift()}pop(){return this._list.pop()}peekFirst(){return this._list[0]}peekLast(){return this._list[this._list.length-1]}remove(e){const t=this.indexOf(e);t>-1&&this._list.splice(t,1)}clear(){this._list=[]}values(){return this._list}[Symbol.iterator](){return this._list[Symbol.iterator]()}copy(){return new SortedList(this._list.slice(),this._compare)}get length(){return this._list.length}}Class.register(SortedList);class Assert{static that(e,t="Assertion failed"){if(!e)throw new Error(t)}}Class.register(Assert);class BufferUtils{static toAscii(e){const t=BufferUtils._toUint8View(e);let s="";for(let r=0;r<t.length;r+=8192)s+=String.fromCharCode.apply(null,t.subarray(r,r+8192));return s}static fromAscii(e){const t=new Uint8Array(e.length);for(let s=0;s<e.length;++s)t[s]=e.charCodeAt(s);return t}static _codePointTextDecoder(e){if("undefined"==typeof TextDecoder)throw new Error("TextDecoder not supported");if(null===BufferUtils._ISO_8859_15_DECODER)throw new Error("TextDecoder does not support iso-8859-15");if(BufferUtils._ISO_8859_15_DECODER===undefined)try{BufferUtils._ISO_8859_15_DECODER=new TextDecoder("iso-8859-15")}catch(s){BufferUtils._ISO_8859_15_DECODER=null;throw new Error("TextDecoder does not support iso-8859-15")}const t=BufferUtils._toUint8View(e);return BufferUtils._ISO_8859_15_DECODER.decode(t).replace(/\u20ac/g,"¤").replace(/\u0160/g,"¦").replace(/\u0161/g,"¨").replace(/\u017d/g,"´").replace(/\u017e/g,"¸").replace(/\u0152/g,"¼").replace(/\u0153/g,"½").replace(/\u0178/g,"¾")}static _tripletToBase64(e){return BufferUtils._BASE64_LOOKUP[e>>18&63]+BufferUtils._BASE64_LOOKUP[e>>12&63]+BufferUtils._BASE64_LOOKUP[e>>6&63]+BufferUtils._BASE64_LOOKUP[63&e]}static _base64encodeChunk(e,t,s){let r;const n=[];for(let i=t;i<s;i+=3){r=(e[i]<<16&16711680)+(e[i+1]<<8&65280)+(255&e[i+2]);n.push(BufferUtils._tripletToBase64(r))}return n.join("")}static _base64fromByteArray(e){let t;const s=e.length,r=s%3;let n="";const i=[];for(let o=0,a=s-r;o<a;o+=16383)i.push(BufferUtils._base64encodeChunk(e,o,o+16383>a?a:o+16383));if(1===r){t=e[s-1];n+=BufferUtils._BASE64_LOOKUP[t>>2];n+=BufferUtils._BASE64_LOOKUP[t<<4&63];n+="=="}else if(2===r){t=(e[s-2]<<8)+e[s-1];n+=BufferUtils._BASE64_LOOKUP[t>>10];n+=BufferUtils._BASE64_LOOKUP[t>>4&63];n+=BufferUtils._BASE64_LOOKUP[t<<2&63];n+="="}i.push(n);return i.join("")}static toBase64(e){if(PlatformUtils.isNodeJs())return Buffer.from(e).toString("base64");if("undefined"!=typeof TextDecoder&&null!==BufferUtils._ISO_8859_15_DECODER)try{return btoa(BufferUtils._codePointTextDecoder(e))}catch(t){}return BufferUtils._base64fromByteArray(BufferUtils._toUint8View(e))}static fromBase64(e,t){const s=new Uint8Array(atob(e).split("").map(e=>e.charCodeAt(0)));if(t!==undefined&&s.length!==t)throw new Error("Decoded length does not match expected length");return new SerialBuffer(s)}static toBase64Url(e){return BufferUtils.toBase64(e).replace(/\//g,"_").replace(/\+/g,"-").replace(/=/g,".")}static fromBase64Url(e,t){return BufferUtils.fromBase64(e.replace(/_/g,"/").replace(/-/g,"+").replace(/\./g,"="),t)}static toBase32(e,t=BufferUtils.BASE32_ALPHABET.KRYPTON){let s,r,n,i=3,o=0,a="";for(n=0;n<e.length;n++){a+=t[31&(r=o|(s=e[n])>>i)];i>5&&(a+=t[31&(r=s>>(i-=5))]);o=s<<(i=5-i);i=8-i}3!==i&&(a+=t[31&o]);for(;a.length%8!=0&&33===t.length;)a+=t[32];return a}static fromBase32(e,t=BufferUtils.BASE32_ALPHABET.KRYPTON){const s=[];t.toUpperCase().split("").forEach((e,t)=>{e in s||(s[e]=t)});let r,n=8,i=0,o=[];e.toUpperCase().split("").forEach(e=>{if(33!==t.length||e!==t[32]){r=255&s[e];if((n-=5)>0)i|=r<<n;else if(n<0){o.push(i|r>>-n);i=r<<(n+=8)&255}else{o.push(i|r);n=8;i=0}}});8!==n&&0!==i&&o.push(i);return new Uint8Array(o)}static toHex(e){let t="";for(let s=0;s<e.length;s++){const r=e[s];t+=BufferUtils.HEX_ALPHABET[r>>>4];t+=BufferUtils.HEX_ALPHABET[15&r]}return t}static fromHex(e,t){e=e.trim();if(!StringUtils.isHexBytes(e,t))throw new Error("String is not an hex string (of matching length)");return new SerialBuffer(new Uint8Array((e.match(/.{2}/g)||[]).map(e=>parseInt(e,16))))}static toBinary(e){let t="";for(let s=0;s<e.length;s++){const r=e[s];t+=StringUtils.lpad(r.toString(2),"0",8)}return t}static _strToUint8Array(e){const t=[];let s=0;for(let r=0;r<e.length;r++){let n=e.charCodeAt(r);if(n<128)t[s++]=n;else if(n<2048){t[s++]=n>>6|192;t[s++]=63&n|128}else if(55296==(64512&n)&&r+1<e.length&&56320==(64512&e.charCodeAt(r+1))){n=65536+((1023&n)<<10)+(1023&e.charCodeAt(++r));t[s++]=n>>18|240;t[s++]=n>>12&63|128;t[s++]=n>>6&63|128;t[s++]=63&n|128}else{t[s++]=n>>12|224;t[s++]=n>>6&63|128;t[s++]=63&n|128}}return new Uint8Array(t)}static _utf8TextEncoder(e){if("undefined"==typeof TextEncoder)throw new Error("TextEncoder not supported");if(null===BufferUtils._UTF8_ENCODER)throw new Error("TextEncoder does not support utf8");if(BufferUtils._UTF8_ENCODER===undefined)try{BufferUtils._UTF8_ENCODER=new TextEncoder}catch(t){BufferUtils._UTF8_ENCODER=null;throw new Error("TextEncoder does not support utf8")}return BufferUtils._UTF8_ENCODER.encode(e)}static fromUtf8(e){if(PlatformUtils.isNodeJs())return Buffer.from(e);if("undefined"!=typeof TextEncoder&&null!==BufferUtils._UTF8_ENCODER)try{return BufferUtils._utf8TextEncoder(e)}catch(t){}return BufferUtils._strToUint8Array(e)}static fromAny(e,t){if(""===e)return SerialBuffer.EMPTY;if(!e)throw new Error("Invalid buffer format");if(e instanceof Uint8Array)return new SerialBuffer(e);try{return BufferUtils.fromHex(e,t)}catch(s){}try{return BufferUtils.fromBase64(e,t)}catch(s){}throw new Error("Invalid buffer format")}static concatTypedArrays(e,t){const s=new e.constructor(e.length+t.length);s.set(e,0);s.set(t,e.length);return s}static equals(e,t){const s=BufferUtils._toUint8View(e),r=BufferUtils._toUint8View(t);if(s.length!==r.length)return!1;for(let n=0;n<s.length;n++)if(s[n]!==r[n])return!1;return!0}static compare(e,t){if(e.length<t.length)return-1;if(e.length>t.length)return 1;for(let s=0;s<e.length;s++){if(e[s]<t[s])return-1;if(e[s]>t[s])return 1}return 0}static xor(e,t){const s=new Uint8Array(e.byteLength);for(let r=0;r<e.byteLength;++r)s[r]=e[r]^t[r];return s}static _toUint8View(e){if(e instanceof Uint8Array)return e;if(e instanceof ArrayBuffer)return new Uint8Array(e);if(e.buffer instanceof ArrayBuffer)return new Uint8Array(e.buffer);throw new Error("TypedArray or ArrayBuffer required")}static toBase58(e,t=BufferUtils.BASE58_ALPHABET){let s,r=[],n="",i=0;for(;i<e.length&&!e[i];i++)n+=t[0];for(;i<e.length;i++){let t=e[i];s=0;for(;s in r||t;){let e=r[s]?(r[s]<<8)+t:t;t=e/58|0;r[s]=e%58;s++}}for(;s--;)n+=t[r[s]];return n}static fromBase58(e,t=BufferUtils.BASE58_ALPHABET){let s,r=[],n=[],i=0;for(;i<e.length&&!t.indexOf(e[i]);i++)r.push(0);for(;i<e.length;i++){let r=t.indexOf(e[i]);if(r<0)return"";s=0;for(;s in n||r;){let e=n[s]?58*n[s]+r:r;r=e>>8;n[s]=e%256;s++}}for(;s--;)r.push(n[s]);return new Uint8Array(r)}static toBase58Check(e,t=128,s,r=BufferUtils.BASE58_ALPHABET){let n;n=new SerialBuffer(s?[255&t,...e,255&s]:[255&t,...e]);const i=Hash.computeSha256(Hash.computeSha256(n)).subarray(0,4),o=new SerialBuffer([...n,...i]);return BufferUtils.toBase58(o,r)}static fromBase58Check(e,t=!1,s=BufferUtils.BASE58_ALPHABET){const r=BufferUtils.fromBase58(e,s),n=t?-5:-4;return new Uint8Array(r.slice(1,n))}}BufferUtils.BASE64_ALPHABET="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";BufferUtils.BASE32_ALPHABET={RFC4648:"ABCDEFGHIJKLMNOPQRSTUVWXYZ234567=",RFC4648_HEX:"0123456789ABCDEFGHIJKLMNOPQRSTUV=",KRYPTON:"0123456789ABCDEFGHJKLMNPQRSTUVXY"};BufferUtils.HEX_ALPHABET="0123456789abcdef";BufferUtils._BASE64_LOOKUP=[];for(let e=0,t=BufferUtils.BASE64_ALPHABET.length;e<t;++e)BufferUtils._BASE64_LOOKUP[e]=BufferUtils.BASE64_ALPHABET[e];BufferUtils.BASE58_ALPHABET="123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";Class.register(BufferUtils);class SerialBuffer extends Uint8Array{constructor(e){super(e);this._view=new DataView(this.buffer);this._readPos=0;this._writePos=0}subarray(e,t){return ArrayUtils.subarray(this,e,t)}get readPos(){return this._readPos}set readPos(e){if(e<0||e>this.byteLength)throw`Invalid readPos ${e}`;this._readPos=e}get writePos(){return this._writePos}set writePos(e){if(e<0||e>this.byteLength)throw`Invalid writePos ${e}`;this._writePos=e}reset(){this._readPos=0;this._writePos=0}read(e){const t=this.subarray(this._readPos,this._readPos+e);this._readPos+=e;return new Uint8Array(t)}write(e){this.set(e,this._writePos);this._writePos+=e.byteLength}readUint8(){return this._view.getUint8(this._readPos++)}writeUint8(e){this._view.setUint8(this._writePos++,e)}readUint16(){const e=this._view.getUint16(this._readPos);this._readPos+=2;return e}writeUint16(e){this._view.setUint16(this._writePos,e);this._writePos+=2}readUint32(){const e=this._view.getUint32(this._readPos);this._readPos+=4;return e}writeUint32(e){this._view.setUint32(this._writePos,e);this._writePos+=4}readUint64(){const e=this._view.getUint32(this._readPos)*Math.pow(2,32)+this._view.getUint32(this._readPos+4);if(!NumberUtils.isUint64(e))throw new Error("Malformed value");this._readPos+=8;return e}writeUint64(e){if(!NumberUtils.isUint64(e))throw new Error("Malformed value");this._view.setUint32(this._writePos,Math.floor(e/Math.pow(2,32)));this._view.setUint32(this._writePos+4,e);this._writePos+=8}readUint128(){const e=new BigNumber("1000000000000000000000000",16),t=new BigNumber("10000000000000000",16),s=new BigNumber("100000000",16),r=this._view.getUint32(this._readPos),n=this._view.getUint32(this._readPos+4),i=this._view.getUint32(this._readPos+8),o=this._view.getUint32(this._readPos+12),a=e.times(r).plus(t.times(n)).plus(s.times(i)).plus(o);if(!NumberUtils.isUint128(a))throw new Error("Malformed value");this._readPos+=16;return a}writeUint128(e){if(!NumberUtils.isUint128(e))throw new Error("Malformed value");const t=new BigNumber("1000000000000000000000000",16),s=new BigNumber("10000000000000000",16),r=new BigNumber("100000000",16),n=e.idiv(t),i=e.mod(t).idiv(s),o=e.mod(s).idiv(r),a=e.mod(r);this._view.setUint32(this._writePos,n.toNumber());this._view.setUint32(this._writePos+4,i.toNumber());this._view.setUint32(this._writePos+8,o.toNumber());this._view.setUint32(this._writePos+12,a.toNumber());this._writePos+=16}readVarUint(){const e=this.readUint8();return e<253?e:253===e?this.readUint16():254===e?this.readUint32():this.readUint64()}writeVarUint(e){if(!NumberUtils.isUint64(e))throw new Error("Malformed value");if(e<253)this.writeUint8(e);else if(e<=65535){this.writeUint8(253);this.writeUint16(e)}else if(e<=4294967295){this.writeUint8(254);this.writeUint32(e)}else{this.writeUint8(255);this.writeUint64(e)}}static varUintSize(e){if(!NumberUtils.isUint64(e))throw new Error("Malformed value");return e<253?1:e<=65535?3:e<=4294967295?5:9}readFloat64(){const e=this._view.getFloat64(this._readPos);this._readPos+=8;return e}writeFloat64(e){this._view.setFloat64(this._writePos,e);this._writePos+=8}readString(e){const t=this.read(e);return BufferUtils.toAscii(t)}writeString(e,t){if(StringUtils.isMultibyte(e)||e.length!==t)throw new Error("Malformed value/length");const s=BufferUtils.fromAscii(e);this.write(s)}readPaddedString(e){const t=this.read(e);let s=0;for(;s<e&&0!==t[s];)s++;const r=new Uint8Array(t.buffer,t.byteOffset,s);return BufferUtils.toAscii(r)}writePaddedString(e,t){if(StringUtils.isMultibyte(e)||e.length>t)throw new Error("Malformed value/length");const s=BufferUtils.fromAscii(e);this.write(s);const r=t-s.byteLength;this.write(new Uint8Array(r))}readVarLengthString(){const e=this.readUint8();if(this._readPos+e>this.length)throw new Error("Malformed length");const t=this.read(e);return BufferUtils.toAscii(t)}writeVarLengthString(e){if(StringUtils.isMultibyte(e)||!NumberUtils.isUint8(e.length))throw new Error("Malformed value");const t=BufferUtils.fromAscii(e);this.writeUint8(t.byteLength);this.write(t)}static varLengthStringSize(e){if(StringUtils.isMultibyte(e)||!NumberUtils.isUint8(e.length))throw new Error("Malformed value");return 1+e.length}static concat(e){const t=e.reduce((e,t)=>e+t.length,0),s=new SerialBuffer(t);if(!e.length)return s;let r=0;for(let n of e){s.set(n,r);r+=n.length}return s}}SerialBuffer.EMPTY=new SerialBuffer(0);Class.register(SerialBuffer);class Synchronizer extends Observable{constructor(e,t){super();this._queue=new LinkedList;this._working=!1;this._throttleAfter=e;this._throttleWait=t;this._elapsed=0;this._totalElapsed=0;this._totalJobs=0;this._totalThrottles=0}push(e){return new Promise((t,s)=>{this._queue.push({fn:e,resolve:t,reject:s});if(!this._working){this.fire("work-start",this);this._doWork()["catch"](Log.w.tag(Synchronizer))}})}clear(){for(const e of this._queue)e.reject&&e.reject();this._queue.clear()}async _doWork(){this._working=!0;for(;this._queue.length>0;){const t=Date.now(),s=this._queue.shift();try{const t=await s.fn();s.resolve(t)}catch(e){s.reject&&s.reject(e)}this._totalJobs++;if(this._throttleAfter!==undefined){this._elapsed+=Date.now()-t;if(this._elapsed>=this._throttleAfter){this._totalElapsed+=this._elapsed;this._totalThrottles++;this._elapsed=0;setTimeout(this._doWork.bind(this),this._throttleWait);return}}}this._working=!1;this._totalElapsed+=this._elapsed;this._elapsed=0;this.fire("work-end",this)}get working(){return this._working}get length(){return this._queue.length}get totalElapsed(){return this._totalElapsed}get totalJobs(){return this._totalJobs}get totalThrottles(){return this._totalThrottles}}Class.register(Synchronizer);class MultiSynchronizer extends Observable{constructor(e,t){super();this._synchronizers=new Map;this._throttleAfter=e;this._throttleWait=t}push(e,t){let s=this._synchronizers.get(e);if(!s){(s=new Synchronizer(this._throttleAfter,this._throttleWait)).on("work-start",()=>this.fire("work-start",s,e,this));s.on("work-end",()=>this.fire("work-end",s,e,this));this._synchronizers.set(e,s)}return s.push(t)}clear(){for(const e of this._synchronizers.values())e.clear();this._synchronizers.clear()}isWorking(e){const t=this._synchronizers.get(e);return!!t&&t.working}}Class.register(MultiSynchronizer);class PrioritySynchronizer extends Observable{constructor(e,t,s){super();this._queues=[];for(let r=0;r<e;r++)this._queues[r]=new LinkedList;this._working=!1;this._throttleAfter=t;this._throttleWait=s;this._elapsed=0;this._totalElapsed=0;this._totalJobs=0;this._totalThrottles=0}push(e,t){Assert.that(e>=0&&e<this._queues.length&&Number.isInteger(e),"Invalid priority");return new Promise((s,r)=>{this._queues[e].push({fn:t,resolve:s,reject:r});if(!this._working){this.fire("work-start",this);this._doWork()["catch"](Log.w.tag(PrioritySynchronizer))}})}clear(){for(const e of this._queues){for(const t of e)t.reject&&t.reject();e.clear()}}async _doWork(){this._working=!0;for(const t of this._queues)for(;t.length>0;){const s=Date.now(),r=t.shift();try{const t=await r.fn();r.resolve(t)}catch(e){r.reject&&r.reject(e)}this._totalJobs++;if(this._throttleAfter!==undefined){this._elapsed+=Date.now()-s;if(this._elapsed>=this._throttleAfter){this._totalElapsed+=this._elapsed;this._totalThrottles++;this._elapsed=0;setTimeout(this._doWork.bind(this),this._throttleWait);return}}}this._working=!1;this._totalElapsed+=this._elapsed;this._elapsed=0;this.fire("work-end",this)}get working(){return this._working}get length(){return this._queues.reduce((e,t)=>e+t.length,0)}get totalElapsed(){return this._totalElapsed}get totalJobs(){return this._totalJobs}get totalThrottles(){return this._totalThrottles}}Class.register(PrioritySynchronizer);class RateLimit{constructor(e,t=6e4){this._allowedOccurrences=e;this._timeRange=t;this._lastReset=0;this._counter=0}note(e=1){const t=Date.now();if(this._lastReset<t-this._timeRange){this._lastReset=t;this._counter=0}return(this._counter+=e)<=this._allowedOccurrences}get lastReset(){return this._lastReset}}Class.register(RateLimit);class IWorker{static async createProxy(e,t,s){return new(IWorker.Proxy(e))(s,t)}static async startWorkerForProxy(e,t,s){if(IWorker._workersSupported){s||(s=`${Krypton._path}worker.js`);return IWorker.createProxy(e,t,new Worker(URL.createObjectURL(new Blob([`Krypton = {_path: '${Krypton._path}'}; importScripts('${s.replace(/'/g,"")}');`]))))}await IWorker._workerImplementation[e.name].init(t);return IWorker._workerImplementation[e.name]}static async startWorkerPoolForProxy(e,t,s,r){return new(IWorker.Pool(e))(t=>IWorker.startWorkerForProxy(e,t,r),t,s).start()}static async stubBaseOnMessage(e){try{if("init"===e.data.command)if(IWorker._workerImplementation[e.data.args[0]]){const t=await IWorker._workerImplementation[e.data.args[0]].init(e.data.args[1]);self.postMessage({status:"OK",result:t,id:e.data.id})}else self.postMessage({status:"error",result:"Unknown worker!",id:e.data.id});else self.postMessage({status:"error",result:"Worker not yet initialized!",id:e.data.id})}catch(t){self.postMessage({status:"error",result:t,id:e.data.id})}}static get _workersSupported(){return"undefined"!=typeof Worker}static get areWorkersAsync(){return IWorker._workersSupported}static get _insideWebWorker(){return"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope}static get _global(){return"undefined"!=typeof global?global:"undefined"!=typeof window?window:"undefined"!=typeof self?self:null}static prepareForWorkerUse(e,t){IWorker._insideWebWorker&&(self.onmessage=IWorker.stubBaseOnMessage);IWorker._workerImplementation=IWorker._workerImplementation||{};IWorker._workerImplementation[e.name]=t}static _loadBrowserScript(e,t){const s=document.getElementsByTagName("head")[0],r=document.createElement("script");r.type="text/javascript";r.src=e;const n=()=>setTimeout(t,100);r.onreadystatechange=n;r.onload=n;s.appendChild(r)}static Proxy(e){const t=class extends e{constructor(t,s){super();this._name=s;this._messageId=0;this._worker=t;this._worker.onmessage=this._receive.bind(this);this._waiting=new Map;return this._invoke("init",[e.name,s]).then(()=>this)}_receive(e){const t=this._waiting.get(e.data.id);if(t){this._waiting["delete"](e.data.id);"OK"===e.data.status?t.resolve(e.data.result):"error"===e.data.status&&t.error(e.data.result)}else Log.w(WorkerProxy,"Unknown reply",e)}_invoke(e,t=[]){return new Promise((s,r)=>{const n={command:e,args:t,id:this._messageId++};this._waiting.set(n.id,{resolve:s,error:r});this._worker.postMessage(n)})}destroy(){return this._invoke("destroy")}};for(const s of Object.getOwnPropertyNames(e.prototype))"function"==typeof e.prototype[s]&&"constructor"!==s&&(t.prototype[s]=function(...e){return this._invoke(s,e)});return t}static Stub(e){const t=class extends e{constructor(){super()}_result(e,t,s){self.postMessage({status:t,result:s,id:e.data.id})}_onmessage(e){try{const s=this._invoke(e.data.command,e.data.args);s instanceof Promise?s.then(t=>{this._result(e,"OK",t)}):this._result(e,"OK",s)}catch(t){this._result(e,"error",t.message||t)}}init(e){this._name=e;if(IWorker._insideWebWorker){self.name=e;self.onmessage=(e=>this._onmessage(e))}}_invoke(e,t){return this[e].apply(this,t)}destroy(){IWorker._insideWebWorker&&self.close()}};for(const s of Object.getOwnPropertyNames(e.prototype))"function"==typeof e.prototype[s]&&"constructor"!==s&&(t.prototype[s]=function(){throw`Not implemented in IWorker Stub: ${s}`});return t}static Pool(e){const t=class extends e{constructor(e,t="pool",s=1){super();this._proxyInitializer=e;this._name=t;this._poolSize=s;this._workers=[];this._freeWorkers=[];this._waitingCalls=[]}async start(){await this._updateToSize();return this}get poolSize(){return this._poolSize}set poolSize(e){this._poolSize=e;this._updateToSize()["catch"](Log.w.tag(IWorker))}destroy(){this._poolSize=0;return this._updateToSize()}_invoke(e,t){return IWorker._workersSupported?new Promise((s,r)=>{this._waitingCalls.push({name:e,args:t,resolve:s,error:r});const n=this._freeWorkers.shift();n&&this._step(n)["catch"](Log.w.tag(IWorker))}):this._workers[0][e].apply(this._workers[0],t)}async _step(e){let t=this._waitingCalls.shift();for(;t;){try{t.resolve(await e[t.name].apply(e,t.args))}catch(s){t.error(s)}if(-1===this._workers.indexOf(e)){e.destroy();return}t=this._waitingCalls.shift()}this._freeWorkers.push(e)}async _updateToSize(){if("undefined"==typeof Worker&&this._poolSize>1){Log.d(IWorker,"Pool of size larger than 1 requires WebWorker support.");this._poolSize=1}const e=[];for(;this._workers.length+e.length<this._poolSize;)e.push(this._proxyInitializer(`${this._name}#${this._workers.length+e.length}`));const t=await Promise.all(e);for(const s of t){this._workers.push(s);this._step(s)["catch"](Log.w.tag(IWorker))}for(;this._workers.length>this._poolSize;){const e=this._freeWorkers.shift()||this._workers.pop(),t=this._workers.indexOf(e);if(t>=0){this._workers.splice(t,1);e.destroy()}}return this}};for(const s of Object.getOwnPropertyNames(e.prototype))"function"==typeof e.prototype[s]&&"constructor"!==s&&(t.prototype[s]=function(...e){return this._invoke(s,e)});return t}}IWorker._moduleLoadedCallbacks={};IWorker._workerImplementation={};Class.register(IWorker);class CryptoWorker{static get lib(){return CryptoLib.instance}static async getInstanceAsync(){CryptoWorker._workerAsync||(CryptoWorker._workerAsync=await IWorker.startWorkerPoolForProxy(CryptoWorker,"crypto",4));return CryptoWorker._workerAsync}async computeArgon2d(e){}async computeArgon2dBatch(e){}async kdfLegacy(e,t,s,r){}async kdf(e,t,s,r){}async blockVerify(e,t,s,r,n){}}CryptoWorker._workerAsync=null;Class.register(CryptoWorker);class CryptoWorkerImpl extends(IWorker.Stub(CryptoWorker)){constructor(){super();this._superInit=super.init}async init(e){await this._superInit.call(this,e);PlatformUtils.isBrowser()&&await WasmHelper.doImportBrowser();CryptoWorker._workerAsync=this}computeArgon2d(e){if(PlatformUtils.isNodeJs()){const t=new Uint8Array(Hash.getSize(Hash.Algorithm.ARGON2D)),s=NodeNative.node_argon2(t,new Uint8Array(e),512);if(0!==s)throw s;return t}{let s;try{s=Module.stackSave();const r=Hash.getSize(Hash.Algorithm.ARGON2D),n=Module.stackAlloc(r),i=Module.stackAlloc(e.length);new Uint8Array(Module.HEAPU8.buffer,i,e.length).set(e);const o=Module._krypton_argon2(n,i,e.length,512);if(0!==o)throw o;const a=new Uint8Array(r);a.set(new Uint8Array(Module.HEAPU8.buffer,n,r));return a}catch(t){Log.w(CryptoWorkerImpl,t);throw t}finally{s!==undefined&&Module.stackRestore(s)}}}computeArgon2dBatch(e){const t=[];if(PlatformUtils.isNodeJs()){for(const s of e){const e=new Uint8Array(Hash.getSize(Hash.Algorithm.ARGON2D)),r=NodeNative.node_argon2(e,new Uint8Array(s),512);if(0!==r)throw r;t.push(e)}return t}{let r;try{r=Module.stackSave();const n=Hash.getSize(Hash.Algorithm.ARGON2D),i=Module.stackAlloc(n),o=Module.stackSave();for(const s of e){Module.stackRestore(o);const e=Module.stackAlloc(s.length);new Uint8Array(Module.HEAPU8.buffer,e,s.length).set(s);const r=Module._krypton_argon2(i,e,s.length,512);if(0!==r)throw r;const a=new Uint8Array(n);a.set(new Uint8Array(Module.HEAPU8.buffer,i,n));t.push(a)}return t}catch(s){Log.w(CryptoWorkerImpl,s);throw s}finally{r!==undefined&&Module.stackRestore(r)}}}kdfLegacy(e,t,s,r=Hash.getSize(Hash.Algorithm.ARGON2D)){if(PlatformUtils.isNodeJs()){const n=new Uint8Array(r),i=NodeNative.node_kdf_legacy(n,new Uint8Array(e),new Uint8Array(t),512,s);if(0!==i)throw i;return n}{let i;try{i=Module.stackSave();const o=Module.stackAlloc(r),a=Module.stackAlloc(e.length);new Uint8Array(Module.HEAPU8.buffer,a,e.length).set(e);const c=Module.stackAlloc(t.length);new Uint8Array(Module.HEAPU8.buffer,c,t.length).set(t);const h=Module._krypton_kdf_legacy(o,r,a,e.length,c,t.length,512,s);if(0!==h)throw h;const l=new Uint8Array(r);l.set(new Uint8Array(Module.HEAPU8.buffer,o,r));return l}catch(n){Log.w(CryptoWorkerImpl,n);throw n}finally{i!==undefined&&Module.stackRestore(i)}}}kdf(e,t,s,r=Hash.getSize(Hash.Algorithm.ARGON2D)){if(PlatformUtils.isNodeJs()){const n=new Uint8Array(r),i=NodeNative.node_kdf(n,new Uint8Array(e),new Uint8Array(t),512,s);if(0!==i)throw i;return n}{let i;try{i=Module.stackSave();const o=Module.stackAlloc(r),a=Module.stackAlloc(e.length);new Uint8Array(Module.HEAPU8.buffer,a,e.length).set(e);const c=Module.stackAlloc(t.length);new Uint8Array(Module.HEAPU8.buffer,c,t.length).set(t);const h=Module._krypton_kdf(o,r,a,e.length,c,t.length,512,s);if(0!==h)throw h;const l=new Uint8Array(r);l.set(new Uint8Array(Module.HEAPU8.buffer,o,r));return l}catch(n){Log.w(CryptoWorkerImpl,n);throw n}finally{i!==undefined&&Module.stackRestore(i)}}}async blockVerify(e,t,s,r,n){GenesisConfig={GENESIS_HASH:Hash.unserialize(new SerialBuffer(r)),NETWORK_ID:n};const i=Block.unserialize(new SerialBuffer(e));for(let l=0;l<t.length;l++)i.body.transactions[l]._valid=t[l];const o=await i._verify(s),a=await i.header.pow(),c=i.interlink.hash(),h=i.body.hash();return{valid:o,pow:a.serialize(),interlinkHash:c.serialize(),bodyHash:h.serialize()}}}IWorker.prepareForWorkerUse(CryptoWorker,new CryptoWorkerImpl);class CryptoUtils{static computeHmacSha512(e,t){e.length>CryptoUtils.SHA512_BLOCK_SIZE&&(e=new SerialBuffer(Hash.computeSha512(e)));const s=new SerialBuffer(CryptoUtils.SHA512_BLOCK_SIZE),r=new SerialBuffer(CryptoUtils.SHA512_BLOCK_SIZE);for(let i=0;i<CryptoUtils.SHA512_BLOCK_SIZE;++i){const t=e[i]||0;s[i]=54^t;r[i]=92^t}const n=Hash.computeSha512(BufferUtils.concatTypedArrays(s,t));return Hash.computeSha512(BufferUtils.concatTypedArrays(r,n))}static computePBKDF2sha512(e,t,s,r){const n=Hash.SIZE.get(Hash.Algorithm.SHA512);if(r>(Math.pow(2,32)-1)*n)throw new Error("Derived key too long");const i=Math.ceil(r/n),o=r-(i-1)*n,a=new SerialBuffer(r);for(let c=1;c<=i;c++){let r=new SerialBuffer(t.length+4);r.write(t);r.writeUint32(c);const n=r=CryptoUtils.computeHmacSha512(e,r);for(let t=1;t<s;t++){r=CryptoUtils.computeHmacSha512(e,r);for(let e=0;e<n.length;e++)n[e]^=r[e]}c<i?a.write(n):a.write(n.slice(0,o))}return a}static async otpKdfLegacy(e,t,s,r){const n=await CryptoWorker.getInstanceAsync(),i=await n.kdfLegacy(t,s,r,e.byteLength);return BufferUtils.xor(e,i)}static async otpKdf(e,t,s,r){const n=await CryptoWorker.getInstanceAsync(),i=await n.kdf(t,s,r,e.byteLength);return BufferUtils.xor(e,i)}}CryptoUtils.SHA512_BLOCK_SIZE=128;Class.register(CryptoUtils);class CRC8{static _createTable(){const e=[];for(let t=0;t<256;++t){let s=t;for(let e=0;e<8;++e)s=0!=(128&s)?(s<<1^151)%256:(s<<1)%256;e[t]=s}return e}static compute(e){CRC8._table||(CRC8._table=CRC8._createTable());let t=0;for(let s=0;s<e.length;s++)t=CRC8._table[(t^e[s])%256];return t}}CRC8._table=null;Class.register(CRC8);class CRC32{static _createTable(){let e;const t=[];for(let s=0;s<256;++s){e=s;for(let t=0;t<8;++t)e=1&e?CRC32._POLYNOMIAL^e>>>1:e>>>1;t[s]=e>>>0}return t}static compute(e){CRC32._table||(CRC32._table=CRC32._createTable());CRC32._hex_chars||(CRC32._hex_chars="0123456789abcdef".split(""));const t=new Uint8Array(e);let s=-1,r="";for(let n=0;n<t.length;++n)s=CRC32._table[255&(s^t[n])]^s>>>8;s^=-1;r+=CRC32._hex_chars[s>>28&15]+CRC32._hex_chars[s>>24&15]+CRC32._hex_chars[s>>20&15]+CRC32._hex_chars[s>>16&15]+CRC32._hex_chars[s>>12&15]+CRC32._hex_chars[s>>8&15]+CRC32._hex_chars[s>>4&15]+CRC32._hex_chars[15&s];return parseInt(r,16)}}CRC32._table=null;CRC32._hex_chars=null;CRC32._POLYNOMIAL=3988292384;Class.register(CRC32);!function(e){"use strict";var t,s=/^-?(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?$/i,r=Math.ceil,n=Math.floor,i="[BigNumber Error] ",o=i+"Number primitive has more than 15 significant digits: ",a=1e14,c=14,h=9007199254740991,l=[1,10,100,1e3,1e4,1e5,1e6,1e7,1e8,1e9,1e10,1e11,1e12,1e13],u=1e7,d=1e9;function bitFloor(e){var t=0|e;return e>0||e===t?t:t-1}function coeffToString(e){for(var t,s,r=1,n=e.length,i=e[0]+"";r<n;){t=e[r++]+"";s=c-t.length;for(;s--;t="0"+t);i+=t}for(n=i.length;48===i.charCodeAt(--n););return i.slice(0,n+1||1)}function compare(e,t){var s,r,n=e.c,i=t.c,o=e.s,a=t.s,c=e.e,h=t.e;if(!o||!a)return null;s=n&&!n[0];r=i&&!i[0];if(s||r)return s?r?0:-a:o;if(o!=a)return o;s=o<0;r=c==h;if(!n||!i)return r?0:!n^s?1:-1;if(!r)return c>h^s?1:-1;a=(c=n.length)<(h=i.length)?c:h;for(o=0;o<a;o++)if(n[o]!=i[o])return n[o]>i[o]^s?1:-1;return c==h?0:c>h^s?1:-1}function intCheck(e,t,s,o){if(e<t||e>s||e!==(e<0?r(e):n(e)))throw Error(i+(o||"Argument")+("number"==typeof e?e<t||e>s?" out of range: ":" not an integer: ":" not a primitive number: ")+e)}function isArray(e){return"[object Array]"==Object.prototype.toString.call(e)}function isOdd(e){var t=e.c.length-1;return bitFloor(e.e/c)==t&&e.c[t]%2!=0}function toExponential(e,t){return(e.length>1?e.charAt(0)+"."+e.slice(1):e)+(t<0?"e":"e+")+t}function toFixedPoint(e,t,s){var r,n;if(t<0){for(n=s+".";++t;n+=s);e=n+e}else if(++t>(r=e.length)){for(n=s,t-=r;--t;n+=s);e+=n}else t<r&&(e=e.slice(0,t)+"."+e.slice(t));return e}(t=function clone(e){var t,_,f,g,p,y,C,m,w,A=BigNumber.prototype={constructor:BigNumber,toString:null,valueOf:null},S=new BigNumber(1),E=20,T=4,k=-7,b=21,P=-1e7,I=1e7,N=!1,B=1,v=0,R={decimalSeparator:".",groupSeparator:",",groupSize:3,secondaryGroupSize:0,fractionGroupSeparator:" ",fractionGroupSize:0},O="0123456789abcdefghijklmnopqrstuvwxyz";function BigNumber(e,t){var r,i,a,l,u,d,g,p=this;if(!(p instanceof BigNumber))return new BigNumber(e,t);if(null==t){if(e instanceof BigNumber){p.s=e.s;p.e=e.e;p.c=(e=e.c)?e.slice():e;return}if((u="number"==typeof e)&&0*e==0){p.s=1/e<0?(e=-e,-1):1;if(e===~~e){for(a=0,l=e;l>=10;l/=10,a++);p.e=a;p.c=[e];return}g=e+""}else{if(!s.test(g=e+""))return f(p,g,u);p.s=45==g.charCodeAt(0)?(g=g.slice(1),-1):1}}else{intCheck(t,2,O.length,"Base");g=e+"";if(10==t)return round(p=new BigNumber(e instanceof BigNumber?e:g),E+p.e+1,T);if(u="number"==typeof e){if(0*e!=0)return f(p,g,u,t);p.s=1/e<0?(g=g.slice(1),-1):1;if(BigNumber.DEBUG&&g.replace(/^0\.0*|\./,"").length>15)throw Error(o+e);u=!1}else{p.s=45===g.charCodeAt(0)?(g=g.slice(1),-1):1;t>10&&t<37&&(g=g.toLowerCase())}r=O.slice(0,t);a=l=0;for(d=g.length;l<d;l++)if(r.indexOf(i=g.charAt(l))<0){if("."==i&&l>a){a=d;continue}return f(p,e+"",u,t)}g=_(g,t,10,p.s)}(a=g.indexOf("."))>-1&&(g=g.replace(".",""));if((l=g.search(/e/i))>0){a<0&&(a=l);a+=+g.slice(l+1);g=g.substring(0,l)}else a<0&&(a=g.length);for(l=0;48===g.charCodeAt(l);l++);for(d=g.length;48===g.charCodeAt(--d););if(g=g.slice(l,++d)){d-=l;if(u&&BigNumber.DEBUG&&d>15&&(e>h||e!==n(e)))throw Error(o+p.s*e);if((a=a-l-1)>I)p.c=p.e=null;else if(a<P)p.c=[p.e=0];else{p.e=a;p.c=[];l=(a+1)%c;a<0&&(l+=c);if(l<d){l&&p.c.push(+g.slice(0,l));for(d-=c;l<d;)p.c.push(+g.slice(l,l+=c));g=g.slice(l);l=c-g.length}else l-=d;for(;l--;g+="0");p.c.push(+g)}}else p.c=[p.e=0]}BigNumber.clone=clone;BigNumber.ROUND_UP=0;BigNumber.ROUND_DOWN=1;BigNumber.ROUND_CEIL=2;BigNumber.ROUND_FLOOR=3;BigNumber.ROUND_HALF_UP=4;BigNumber.ROUND_HALF_DOWN=5;BigNumber.ROUND_HALF_EVEN=6;BigNumber.ROUND_HALF_CEIL=7;BigNumber.ROUND_HALF_FLOOR=8;BigNumber.EUCLID=9;BigNumber.config=BigNumber.set=function(e){var t,s;if(null!=e){if("object"!=typeof e)throw Error(i+"Object expected: "+e);if(e.hasOwnProperty(t="DECIMAL_PLACES")){intCheck(s=e[t],0,d,t);E=s}if(e.hasOwnProperty(t="ROUNDING_MODE")){intCheck(s=e[t],0,8,t);T=s}if(e.hasOwnProperty(t="EXPONENTIAL_AT"))if(isArray(s=e[t])){intCheck(s[0],-d,0,t);intCheck(s[1],0,d,t);k=s[0];b=s[1]}else{intCheck(s,-d,d,t);k=-(b=s<0?-s:s)}if(e.hasOwnProperty(t="RANGE"))if(isArray(s=e[t])){intCheck(s[0],-d,-1,t);intCheck(s[1],1,d,t);P=s[0];I=s[1]}else{intCheck(s,-d,d,t);if(!s)throw Error(i+t+" cannot be zero: "+s);P=-(I=s<0?-s:s)}if(e.hasOwnProperty(t="CRYPTO")){if((s=e[t])!==!!s)throw Error(i+t+" not true or false: "+s);if(s){if("undefined"==typeof crypto||!crypto||!crypto.getRandomValues&&!crypto.randomBytes){N=!s;throw Error(i+"crypto unavailable")}N=s}else N=s}if(e.hasOwnProperty(t="MODULO_MODE")){intCheck(s=e[t],0,9,t);B=s}if(e.hasOwnProperty(t="POW_PRECISION")){intCheck(s=e[t],0,d,t);v=s}if(e.hasOwnProperty(t="FORMAT")){if("object"!=typeof(s=e[t]))throw Error(i+t+" not an object: "+s);R=s}if(e.hasOwnProperty(t="ALPHABET")){if("string"!=typeof(s=e[t])||/^.$|\.|(.).*\1/.test(s))throw Error(i+t+" invalid: "+s);O=s}}return{DECIMAL_PLACES:E,ROUNDING_MODE:T,EXPONENTIAL_AT:[k,b],RANGE:[P,I],CRYPTO:N,MODULO_MODE:B,POW_PRECISION:v,FORMAT:R,ALPHABET:O}};BigNumber.isBigNumber=function(e){return e instanceof BigNumber||e&&!0===e._isBigNumber||!1};BigNumber.maximum=BigNumber.max=function(){return maxOrMin(arguments,A.lt)};BigNumber.minimum=BigNumber.min=function(){return maxOrMin(arguments,A.gt)};BigNumber.random=(g=9007199254740992*Math.random()&2097151?function(){return n(9007199254740992*Math.random())}:function(){return 8388608*(1073741824*Math.random()|0)+(8388608*Math.random()|0)},function(e){var t,s,o,a,h,u=0,_=[],f=new BigNumber(S);null==e?e=E:intCheck(e,0,d);a=r(e/c);if(N)if(crypto.getRandomValues){t=crypto.getRandomValues(new Uint32Array(a*=2));for(;u<a;)if((h=131072*t[u]+(t[u+1]>>>11))>=9e15){s=crypto.getRandomValues(new Uint32Array(2));t[u]=s[0];t[u+1]=s[1]}else{_.push(h%1e14);u+=2}u=a/2}else{if(!crypto.randomBytes){N=!1;throw Error(i+"crypto unavailable")}t=crypto.randomBytes(a*=7);for(;u<a;)if((h=281474976710656*(31&t[u])+1099511627776*t[u+1]+4294967296*t[u+2]+16777216*t[u+3]+(t[u+4]<<16)+(t[u+5]<<8)+t[u+6])>=9e15)crypto.randomBytes(7).copy(t,u);else{_.push(h%1e14);u+=7}u=a/7}if(!N)for(;u<a;)(h=g())<9e15&&(_[u++]=h%1e14);a=_[--u];e%=c;if(a&&e){h=l[c-e];_[u]=n(a/h)*h}for(;0===_[u];_.pop(),u--);if(u<0)_=[o=0];else{for(o=-1;0===_[0];_.splice(0,1),o-=c);for(u=1,h=_[0];h>=10;h/=10,u++);u<c&&(o-=c-u)}f.e=o;f.c=_;return f});_=function(){function toBaseOut(e,t,s,r){for(var n,i,o=[0],a=0,c=e.length;a<c;){for(i=o.length;i--;o[i]*=t);o[0]+=r.indexOf(e.charAt(a++));for(n=0;n<o.length;n++)if(o[n]>s-1){null==o[n+1]&&(o[n+1]=0);o[n+1]+=o[n]/s|0;o[n]%=s}}return o.reverse()}return function(e,s,r,n,i){var o,a,c,h,l,u,d,_,f=e.indexOf("."),g=E,p=T;if(f>=0){h=v;v=0;e=e.replace(".","");u=(_=new BigNumber(s)).pow(e.length-f);v=h;_.c=toBaseOut(toFixedPoint(coeffToString(u.c),u.e,"0"),10,r,"0123456789");_.e=_.c.length}c=h=(d=toBaseOut(e,s,r,i?(o=O,"0123456789"):(o="0123456789",O))).length;for(;0==d[--h];d.pop());if(!d[0])return o.charAt(0);if(f<0)--c;else{u.c=d;u.e=c;u.s=n;d=(u=t(u,_,g,p,r)).c;l=u.r;c=u.e}f=d[a=c+g+1];h=r/2;l=l||a<0||null!=d[a+1];l=p<4?(null!=f||l)&&(0==p||p==(u.s<0?3:2)):f>h||f==h&&(4==p||l||6==p&&1&d[a-1]||p==(u.s<0?8:7));if(a<1||!d[0])e=l?toFixedPoint(o.charAt(1),-g,o.charAt(0)):o.charAt(0);else{d.length=a;if(l)for(--r;++d[--a]>r;){d[a]=0;if(!a){++c;d=[1].concat(d)}}for(h=d.length;!d[--h];);for(f=0,e="";f<=h;e+=o.charAt(d[f++]));e=toFixedPoint(e,c,o.charAt(0))}return e}}();t=function(){function multiply(e,t,s){var r,n,i,o,a=0,c=e.length,h=t%u,l=t/u|0;for(e=e.slice();c--;){a=((n=h*(i=e[c]%u)+(r=l*i+(o=e[c]/u|0)*h)%u*u+a)/s|0)+(r/u|0)+l*o;e[c]=n%s}a&&(e=[a].concat(e));return e}function compare(e,t,s,r){var n,i;if(s!=r)i=s>r?1:-1;else for(n=i=0;n<s;n++)if(e[n]!=t[n]){i=e[n]>t[n]?1:-1;break}return i}function subtract(e,t,s,r){for(var n=0;s--;){e[s]-=n;n=e[s]<t[s]?1:0;e[s]=n*r+e[s]-t[s]}for(;!e[0]&&e.length>1;e.splice(0,1));}return function(e,t,s,r,i){var o,h,l,u,d,_,f,g,p,y,C,m,w,A,S,E,T,k=e.s==t.s?1:-1,b=e.c,P=t.c;if(!(b&&b[0]&&P&&P[0]))return new BigNumber(e.s&&t.s&&(b?!P||b[0]!=P[0]:P)?b&&0==b[0]||!P?0*k:k/0:NaN);p=(g=new BigNumber(k)).c=[];k=s+(h=e.e-t.e)+1;if(!i){i=a;h=bitFloor(e.e/c)-bitFloor(t.e/c);k=k/c|0}for(l=0;P[l]==(b[l]||0);l++);P[l]>(b[l]||0)&&h--;if(k<0){p.push(1);u=!0}else{A=b.length;E=P.length;l=0;k+=2;if((d=n(i/(P[0]+1)))>1){P=multiply(P,d,i);b=multiply(b,d,i);E=P.length;A=b.length}w=E;C=(y=b.slice(0,E)).length;for(;C<E;y[C++]=0);T=P.slice();T=[0].concat(T);S=P[0];P[1]>=i/2&&S++;do{d=0;if((o=compare(P,y,E,C))<0){m=y[0];E!=C&&(m=m*i+(y[1]||0));if((d=n(m/S))>1){d>=i&&(d=i-1);f=(_=multiply(P,d,i)).length;C=y.length;for(;1==compare(_,y,f,C);){d--;subtract(_,E<f?T:P,f,i);f=_.length;o=1}}else{0==d&&(o=d=1);f=(_=P.slice()).length}f<C&&(_=[0].concat(_));subtract(y,_,C,i);C=y.length;if(-1==o)for(;compare(P,y,E,C)<1;){d++;subtract(y,E<C?T:P,C,i);C=y.length}}else if(0===o){d++;y=[0]}p[l++]=d;if(y[0])y[C++]=b[w]||0;else{y=[b[w]];C=1}}while((w++<A||null!=y[0])&&k--);u=null!=y[0];p[0]||p.splice(0,1)}if(i==a){for(l=1,k=p[0];k>=10;k/=10,l++);round(g,s+(g.e=l+h*c-1)+1,r,u)}else{g.e=h;g.r=+u}return g}}();function format(e,t,s,r){var n,i,o,a,c;null==s?s=T:intCheck(s,0,8);if(!e.c)return e.toString();n=e.c[0];o=e.e;if(null==t){c=coeffToString(e.c);c=1==r||2==r&&o<=k?toExponential(c,o):toFixedPoint(c,o,"0")}else{i=(e=round(new BigNumber(e),t,s)).e;a=(c=coeffToString(e.c)).length;if(1==r||2==r&&(t<=i||i<=k)){for(;a<t;c+="0",a++);c=toExponential(c,i)}else{t-=o;c=toFixedPoint(c,i,"0");if(i+1>a){if(--t>0)for(c+=".";t--;c+="0");}else if((t+=i-a)>0){i+1==a&&(c+=".");for(;t--;c+="0");}}}return e.s<0&&n?"-"+c:c}function maxOrMin(e,t){var s,r,n=0;isArray(e[0])&&(e=e[0]);s=new BigNumber(e[0]);for(;++n<e.length;){if(!(r=new BigNumber(e[n])).s){s=r;break}t.call(s,r)&&(s=r)}return s}function normalise(e,t,s){for(var r=1,n=t.length;!t[--n];t.pop());for(n=t[0];n>=10;n/=10,r++);if((s=r+s*c-1)>I)e.c=e.e=null;else if(s<P)e.c=[e.e=0];else{e.e=s;e.c=t}return e}f=(p=/^(-?)0([xbo])(?=\w[\w.]*$)/i,y=/^([^.]+)\.$/,C=/^\.([^.]+)$/,m=/^-?(Infinity|NaN)$/,w=/^\s*\+(?=[\w.])|^\s+|\s+$/g,function(e,t,s,r){var n,o=s?t:t.replace(w,"");if(m.test(o)){e.s=isNaN(o)?null:o<0?-1:1;e.c=e.e=null}else{if(!s){o=o.replace(p,function(e,t,s){n="x"==(s=s.toLowerCase())?16:"b"==s?2:8;return r&&r!=n?e:t});if(r){n=r;o=o.replace(y,"$1").replace(C,"0.$1")}if(t!=o)return new BigNumber(o,n)}if(BigNumber.DEBUG)throw Error(i+"Not a"+(r?" base "+r:"")+" number: "+t);e.c=e.e=e.s=null}});function round(e,t,s,i){var o,h,u,d,_,f,g,p=e.c,y=l;if(p){e:{for(o=1,d=p[0];d>=10;d/=10,o++);if((h=t-o)<0){h+=c;u=t;g=(_=p[f=0])/y[o-u-1]%10|0}else if((f=r((h+1)/c))>=p.length){if(!i)break e;for(;p.length<=f;p.push(0));_=g=0;o=1;u=(h%=c)-c+1}else{_=d=p[f];for(o=1;d>=10;d/=10,o++);g=(u=(h%=c)-c+o)<0?0:_/y[o-u-1]%10|0}i=i||t<0||null!=p[f+1]||(u<0?_:_%y[o-u-1]);i=s<4?(g||i)&&(0==s||s==(e.s<0?3:2)):g>5||5==g&&(4==s||i||6==s&&(h>0?u>0?_/y[o-u]:0:p[f-1])%10&1||s==(e.s<0?8:7));if(t<1||!p[0]){p.length=0;if(i){t-=e.e+1;p[0]=y[(c-t%c)%c];e.e=-t||0}else p[0]=e.e=0;return e}if(0==h){p.length=f;d=1;f--}else{p.length=f+1;d=y[c-h];p[f]=u>0?n(_/y[o-u]%y[u])*d:0}if(i)for(;;){if(0==f){for(h=1,u=p[0];u>=10;u/=10,h++);u=p[0]+=d;for(d=1;u>=10;u/=10,d++);if(h!=d){e.e++;p[0]==a&&(p[0]=1)}break}p[f]+=d;if(p[f]!=a)break;p[f--]=0;d=1}for(h=p.length;0===p[--h];p.pop());}e.e>I?e.c=e.e=null:e.e<P&&(e.c=[e.e=0])}return e}A.absoluteValue=A.abs=function(){var e=new BigNumber(this);e.s<0&&(e.s=1);return e};A.comparedTo=function(e,t){return compare(this,new BigNumber(e,t))};A.decimalPlaces=A.dp=function(e,t){var s,r,n,i=this;if(null!=e){intCheck(e,0,d);null==t?t=T:intCheck(t,0,8);return round(new BigNumber(i),e+i.e+1,t)}if(!(s=i.c))return null;r=((n=s.length-1)-bitFloor(this.e/c))*c;if(n=s[n])for(;n%10==0;n/=10,r--);r<0&&(r=0);return r};A.dividedBy=A.div=function(e,s){return t(this,new BigNumber(e,s),E,T)};A.dividedToIntegerBy=A.idiv=function(e,s){return t(this,new BigNumber(e,s),0,1)};A.exponentiatedBy=A.pow=function(e,t){var s,o,a,h,l,u,d,_=this;if((e=new BigNumber(e)).c&&!e.isInteger())throw Error(i+"Exponent not an integer: "+e);null!=t&&(t=new BigNumber(t));h=e.e>14;if(!_.c||!_.c[0]||1==_.c[0]&&!_.e&&1==_.c.length||!e.c||!e.c[0]){d=new BigNumber(Math.pow(+_.valueOf(),h?2-isOdd(e):+e));return t?d.mod(t):d}l=e.s<0;if(t){if(t.c?!t.c[0]:!t.s)return new BigNumber(NaN);(o=!l&&_.isInteger()&&t.isInteger())&&(_=_.mod(t))}else{if(e.e>9&&(_.e>0||_.e<-1||(0==_.e?_.c[0]>1||h&&_.c[1]>=24e7:_.c[0]<8e13||h&&_.c[0]<=9999975e7))){a=_.s<0&&isOdd(e)?-0:0;_.e>-1&&(a=1/a);return new BigNumber(l?1/a:a)}v&&(a=r(v/c+2))}if(h){s=new BigNumber(.5);u=isOdd(e)}else u=e%2;l&&(e.s=1);d=new BigNumber(S);for(;;){if(u){if(!(d=d.times(_)).c)break;a?d.c.length>a&&(d.c.length=a):o&&(d=d.mod(t))}if(h){round(e=e.times(s),e.e+1,1);if(!e.c[0])break;h=e.e>14;u=isOdd(e)}else{if(!(e=n(e/2)))break;u=e%2}_=_.times(_);a?_.c&&_.c.length>a&&(_.c.length=a):o&&(_=_.mod(t))}if(o)return d;l&&(d=S.div(d));return t?d.mod(t):a?round(d,v,T,void 0):d};A.integerValue=function(e){var t=new BigNumber(this);null==e?e=T:intCheck(e,0,8);return round(t,t.e+1,e)};A.isEqualTo=A.eq=A.equals=function(e,t){return 0===compare(this,new BigNumber(e,t))};A.isFinite=function(){return!!this.c};A.isGreaterThan=A.gt=function(e,t){return compare(this,new BigNumber(e,t))>0};A.isGreaterThanOrEqualTo=A.gte=function(e,t){return 1===(t=compare(this,new BigNumber(e,t)))||0===t};A.isInteger=function(){return!!this.c&&bitFloor(this.e/c)>this.c.length-2};A.isLessThan=A.lt=function(e,t){return compare(this,new BigNumber(e,t))<0};A.isLessThanOrEqualTo=A.lte=function(e,t){return-1===(t=compare(this,new BigNumber(e,t)))||0===t};A.isNaN=function(){return!this.s};A.isNegative=function(){return this.s<0};A.isPositive=function(){return this.s>0};A.isZero=function(){return!!this.c&&0==this.c[0]};A.minus=function(e,t){var s,r,n,i,o=this,h=o.s;t=(e=new BigNumber(e,t)).s;if(!h||!t)return new BigNumber(NaN);if(h!=t){e.s=-t;return o.plus(e)}var l=o.e/c,u=e.e/c,d=o.c,_=e.c;if(!l||!u){if(!d||!_)return d?(e.s=-t,e):new BigNumber(_?o:NaN);if(!d[0]||!_[0])return _[0]?(e.s=-t,e):new BigNumber(d[0]?o:3==T?-0:0)}l=bitFloor(l);u=bitFloor(u);d=d.slice();if(h=l-u){if(i=h<0){h=-h;n=d}else{u=l;n=_}n.reverse();for(t=h;t--;n.push(0));n.reverse()}else{r=(i=(h=d.length)<(t=_.length))?h:t;for(h=t=0;t<r;t++)if(d[t]!=_[t]){i=d[t]<_[t];break}}i&&(n=d,d=_,_=n,e.s=-e.s);if((t=(r=_.length)-(s=d.length))>0)for(;t--;d[s++]=0);t=a-1;for(;r>h;){if(d[--r]<_[r]){for(s=r;s&&!d[--s];d[s]=t);--d[s];d[r]+=a}d[r]-=_[r]}for(;0==d[0];d.splice(0,1),--u);if(!d[0]){e.s=3==T?-1:1;e.c=[e.e=0];return e}return normalise(e,d,u)};A.modulo=A.mod=function(e,s){var r,n,i=this;e=new BigNumber(e,s);if(!i.c||!e.s||e.c&&!e.c[0])return new BigNumber(NaN);if(!e.c||i.c&&!i.c[0])return new BigNumber(i);if(9==B){n=e.s;e.s=1;r=t(i,e,0,3);e.s=n;r.s*=n}else r=t(i,e,0,B);(e=i.minus(r.times(e))).c[0]||1!=B||(e.s=i.s);return e};A.multipliedBy=A.times=function(e,t){var s,r,n,i,o,h,l,d,_,f,g,p,y,C,m,w=this,A=w.c,S=(e=new BigNumber(e,t)).c;if(!(A&&S&&A[0]&&S[0])){if(!w.s||!e.s||A&&!A[0]&&!S||S&&!S[0]&&!A)e.c=e.e=e.s=null;else{e.s*=w.s;if(A&&S){e.c=[0];e.e=0}else e.c=e.e=null}return e}r=bitFloor(w.e/c)+bitFloor(e.e/c);e.s*=w.s;(l=A.length)<(f=S.length)&&(y=A,A=S,S=y,n=l,l=f,f=n);for(n=l+f,y=[];n--;y.push(0));C=a;m=u;for(n=f;--n>=0;){s=0;g=S[n]%m;p=S[n]/m|0;for(i=n+(o=l);i>n;){s=((d=g*(d=A[--o]%m)+(h=p*d+(_=A[o]/m|0)*g)%m*m+y[i]+s)/C|0)+(h/m|0)+p*_;y[i--]=d%C}y[i]=s}s?++r:y.splice(0,1);return normalise(e,y,r)};A.negated=function(){var e=new BigNumber(this);e.s=-e.s||null;return e};A.plus=function(e,t){var s,r=this,n=r.s;t=(e=new BigNumber(e,t)).s;if(!n||!t)return new BigNumber(NaN);if(n!=t){e.s=-t;return r.minus(e)}var i=r.e/c,o=e.e/c,h=r.c,l=e.c;if(!i||!o){if(!h||!l)return new BigNumber(n/0);if(!h[0]||!l[0])return l[0]?e:new BigNumber(h[0]?r:0*n)}i=bitFloor(i);o=bitFloor(o);h=h.slice();if(n=i-o){if(n>0){o=i;s=l}else{n=-n;s=h}s.reverse();for(;n--;s.push(0));s.reverse()}(n=h.length)-(t=l.length)<0&&(s=l,l=h,h=s,t=n);for(n=0;t;){n=(h[--t]=h[t]+l[t]+n)/a|0;h[t]=a===h[t]?0:h[t]%a}if(n){h=[n].concat(h);++o}return normalise(e,h,o)};A.precision=A.sd=function(e,t){var s,r,n,i=this;if(null!=e&&e!==!!e){intCheck(e,1,d);null==t?t=T:intCheck(t,0,8);return round(new BigNumber(i),e,t)}if(!(s=i.c))return null;r=(n=s.length-1)*c+1;if(n=s[n]){for(;n%10==0;n/=10,r--);for(n=s[0];n>=10;n/=10,r++);}e&&i.e+1>r&&(r=i.e+1);return r};A.shiftedBy=function(e){intCheck(e,-h,h);return this.times("1e"+e)};A.squareRoot=A.sqrt=function(){var e,s,r,n,i,o=this,a=o.c,c=o.s,h=o.e,l=E+4,u=new BigNumber("0.5");if(1!==c||!a||!a[0])return new BigNumber(!c||c<0&&(!a||a[0])?NaN:a?o:1/0);if(0==(c=Math.sqrt(+o))||c==1/0){((s=coeffToString(a)).length+h)%2==0&&(s+="0");c=Math.sqrt(s);h=bitFloor((h+1)/2)-(h<0||h%2);r=new BigNumber(s=c==1/0?"1e"+h:(s=c.toExponential()).slice(0,s.indexOf("e")+1)+h)}else r=new BigNumber(c+"");if(r.c[0]){(c=(h=r.e)+l)<3&&(c=0);for(;;){i=r;r=u.times(i.plus(t(o,i,l,1)));if(coeffToString(i.c).slice(0,c)===(s=coeffToString(r.c)).slice(0,c)){r.e<h&&--c;if("9999"!=(s=s.slice(c-3,c+1))&&(n||"4999"!=s)){if(!+s||!+s.slice(1)&&"5"==s.charAt(0)){round(r,r.e+E+2,1);e=!r.times(r).eq(o)}break}if(!n){round(i,i.e+E+2,0);if(i.times(i).eq(o)){r=i;break}}l+=4;c+=4;n=1}}}return round(r,r.e+E+1,T,e)};A.toExponential=function(e,t){if(null!=e){intCheck(e,0,d);e++}return format(this,e,t,1)};A.toFixed=function(e,t){if(null!=e){intCheck(e,0,d);e=e+this.e+1}return format(this,e,t)};A.toFormat=function(e,t){var s=this.toFixed(e,t);if(this.c){var r,n=s.split("."),i=+R.groupSize,o=+R.secondaryGroupSize,a=R.groupSeparator,c=n[0],h=n[1],l=this.s<0,u=l?c.slice(1):c,d=u.length;o&&(r=i,i=o,o=r,d-=r);if(i>0&&d>0){r=d%i||i;c=u.substr(0,r);for(;r<d;r+=i)c+=a+u.substr(r,i);o>0&&(c+=a+u.slice(r));l&&(c="-"+c)}s=h?c+R.decimalSeparator+((o=+R.fractionGroupSize)?h.replace(new RegExp("\\d{"+o+"}\\B","g"),"$&"+R.fractionGroupSeparator):h):c}return s};A.toFraction=function(e){var s,r,n,o,a,h,u,d,_,f,g,p,y=this,C=y.c;if(null!=e&&(!(d=new BigNumber(e)).isInteger()&&(d.c||1!==d.s)||d.lt(S)))throw Error(i+"Argument "+(d.isInteger()?"out of range: ":"not an integer: ")+e);if(!C)return y.toString();r=new BigNumber(S);f=n=new BigNumber(S);o=_=new BigNumber(S);p=coeffToString(C);h=r.e=p.length-y.e-1;r.c[0]=l[(u=h%c)<0?c+u:u];e=!e||d.comparedTo(r)>0?h>0?r:f:d;u=I;I=1/0;d=new BigNumber(p);_.c[0]=0;for(;;){g=t(d,r,0,1);if(1==(a=n.plus(g.times(o))).comparedTo(e))break;n=o;o=a;f=_.plus(g.times(a=f));_=a;r=d.minus(g.times(a=r));d=a}a=t(e.minus(n),o,0,1);_=_.plus(a.times(f));n=n.plus(a.times(o));_.s=f.s=y.s;s=t(f,o,h*=2,T).minus(y).abs().comparedTo(t(_,n,h,T).minus(y).abs())<1?[f.toString(),o.toString()]:[_.toString(),n.toString()];I=u;return s};A.toNumber=function(){return+this};A.toPrecision=function(e,t){null!=e&&intCheck(e,1,d);return format(this,e,t,2)};A.toString=function(e){var t,s=this,r=s.s,n=s.e;if(null===n)if(r){t="Infinity";r<0&&(t="-"+t)}else t="NaN";else{t=coeffToString(s.c);if(null==e)t=n<=k||n>=b?toExponential(t,n):toFixedPoint(t,n,"0");else{intCheck(e,2,O.length,"Base");t=_(toFixedPoint(t,n,"0"),10,e,r,!0)}r<0&&s.c[0]&&(t="-"+t)}return t};A.valueOf=A.toJSON=function(){var e,t=this,s=t.e;if(null===s)return t.toString();e=coeffToString(t.c);e=s<=k||s>=b?toExponential(e,s):toFixedPoint(e,s,"0");return t.s<0?"-"+e:e};A._isBigNumber=!0;null!=e&&BigNumber.set(e);return BigNumber}())["default"]=t.BigNumber=t;e.BigNumber=t}(Class.scope);const BigNumber=Class.scope.BigNumber;BigNumber.config({DECIMAL_PLACES:11});class NumberUtils{static isUint8(e){return Number.isInteger(e)&&e>=0&&e<=NumberUtils.UINT8_MAX}static isUint16(e){return Number.isInteger(e)&&e>=0&&e<=NumberUtils.UINT16_MAX}static isUint32(e){return Number.isInteger(e)&&e>=0&&e<=NumberUtils.UINT32_MAX}static isUint64(e){return Number.isInteger(e)&&e>=0&&e<=NumberUtils.UINT64_MAX}static isUint128(e){return e.isInteger()&&e.gte(0)&&e.lte(NumberUtils.UINT128_MAX)}static randomUint32(){return Math.floor(Math.random()*(NumberUtils.UINT32_MAX+1))}static randomUint64(){return Math.floor(Math.random()*(NumberUtils.UINT64_MAX+1))}static fromBinary(e){return parseInt(e,2)}}NumberUtils.UINT8_MAX=255;NumberUtils.UINT16_MAX=65535;NumberUtils.UINT32_MAX=4294967295;NumberUtils.UINT64_MAX=Number.MAX_SAFE_INTEGER;NumberUtils.UINT128_MAX=new BigNumber("ffffffffffffffffffffffffffffffff",16);Class.register(NumberUtils);class MerkleTree{static computeRoot(e,t=MerkleTree._hash){return MerkleTree._computeRoot(e,t)}static _computeRoot(e,t){const s=e.length;if(0===s)return Hash.light(new Uint8Array(0));if(1===s)return t(e[0]);const r=Math.round(s/2),n=e.slice(0,r),i=e.slice(r),o=MerkleTree._computeRoot(n,t),a=MerkleTree._computeRoot(i,t);return Hash.light(BufferUtils.concatTypedArrays(o.serialize(),a.serialize()))}static _hash(e){if(e instanceof Hash)return e;if("function"==typeof e.hash)return e.hash();if("function"==typeof e.serialize)return Hash.light(e.serialize());if(e instanceof Uint8Array)return Hash.light(e);throw new Error("MerkleTree objects must be Uint8Array or have a .hash()/.serialize() method")}}Class.register(MerkleTree);class MerklePath{constructor(e){if(!Array.isArray(e)||!NumberUtils.isUint8(e.length)||e.some(e=>!(e instanceof MerklePathNode)))throw new Error("Malformed nodes");this._nodes=e}static compute(e,t,s=MerkleTree._hash){const r=s(t),n=[];MerklePath._compute(e,r,n,s);return new MerklePath(n)}static _compute(e,t,s,r){const n=e.length;let i;if(0===n)return{containsLeaf:!1,inner:i=Hash.light(new Uint8Array(0))};if(1===n)return{containsLeaf:(i=r(e[0])).equals(t),inner:i};const o=Math.round(n/2),a=e.slice(0,o),c=e.slice(o),{containsLeaf:h,inner:l}=MerklePath._compute(a,t,s,r),{containsLeaf:u,inner:d}=MerklePath._compute(c,t,s,r);i=Hash.light(BufferUtils.concatTypedArrays(l.serialize(),d.serialize()));if(h){s.push(new MerklePathNode(d,!1));return{containsLeaf:!0,inner:i}}if(u){s.push(new MerklePathNode(l,!0));return{containsLeaf:!0,inner:i}}return{containsLeaf:!1,inner:i}}computeRoot(e,t=MerkleTree._hash){let s=t(e);for(const r of this._nodes){const e=r.left,t=r.hash,n=new SerialBuffer(2*t.serializedSize);e&&t.serialize(n);s.serialize(n);e||t.serialize(n);s=Hash.light(n)}return s}static _compress(e){const t=e.length,s=Math.ceil(t/8),r=new Uint8Array(s);for(let n=0;n<t;n++)e[n].left&&(r[Math.floor(n/8)]|=128>>>n%8);return r}static unserialize(e){const t=e.readUint8(),s=Math.ceil(t/8),r=e.read(s),n=[];for(let i=0;i<t;i++){const t=0!=(r[Math.floor(i/8)]&128>>>i%8),s=e.readUint8(),o=Hash.unserialize(e,s);n.push(new MerklePathNode(o,t))}return new MerklePath(n)}serialize(e){(e=e||new SerialBuffer(this.serializedSize)).writeUint8(this._nodes.length);e.write(MerklePath._compress(this._nodes));for(const t of this._nodes){e.writeUint8(t.hash.algorithm);t.hash.serialize(e)}return e}get serializedSize(){return 1+Math.ceil(this._nodes.length/8)+this._nodes.reduce((e,t)=>e+1+t.hash.serializedSize,0)}equals(e){return e instanceof MerklePath&&this._nodes.length===e._nodes.length&&this._nodes.every((t,s)=>t.equals(e._nodes[s]))}get nodes(){return this._nodes}}Class.register(MerklePath);class MerklePathNode{constructor(e,t){this._hash=e;this._left=t}get hash(){return this._hash}get left(){return this._left}equals(e){return e instanceof MerklePathNode&&this._hash.equals(e.hash)&&this._left===e.left}}Class.register(MerklePathNode);class MerkleProof{constructor(e,t){if(!Array.isArray(e)||!NumberUtils.isUint16(e.length))throw new Error("Malformed nodes");if(!Array.isArray(t)||!NumberUtils.isUint16(t.length))throw new Error("Malformed operations");this._nodes=e;this._operations=t}static compute(e,t,s=MerkleTree._hash){const r=t.map(s),{containsLeaf:n,operations:i,path:o,inner:a}=MerkleProof._compute(e,r,s);return new MerkleProof(o,i)}static computeWithAbsence(e,t,s,r=MerkleTree._hash){const n=new Set;(t=t.slice()).sort(s);let i=0,o=0;for(;o<e.length&&i<t.length;){const r=e[o],a=s(r,t[i]);if(0===a){n.add(t[i]);++i}else if(a>0){o>0&&n.add(e[o-1]);n.add(r);++i}else++o}i<t.length&&e.length>0&&n.add(e[e.length-1]);return MerkleProof.compute(e,Array.from(n),r)}static _compute(e,t,s){const r=e.length;let n;if(0===r){n=Hash.light(new Uint8Array(0));return{containsLeaf:!1,operations:[MerkleProof.Operation.CONSUME_PROOF],path:[n],inner:n}}if(1===r){n=s(e[0]);const r=t.some(e=>n.equals(e));return{containsLeaf:r,operations:[r?MerkleProof.Operation.CONSUME_INPUT:MerkleProof.Operation.CONSUME_PROOF],path:r?[]:[n],inner:n}}const i=Math.round(r/2),o=e.slice(0,i),a=e.slice(i),{containsLeaf:c,operations:h,path:l,inner:u}=MerkleProof._compute(o,t,s),{containsLeaf:d,operations:_,path:f,inner:g}=MerkleProof._compute(a,t,s);n=Hash.light(BufferUtils.concatTypedArrays(u.serialize(),g.serialize()));if(!c&&!d)return{containsLeaf:!1,operations:[MerkleProof.Operation.CONSUME_PROOF],path:[n],inner:n};let p=h;p=p.concat(_);let y=l;y=y.concat(f);p.push(MerkleProof.Operation.HASH);return{containsLeaf:!0,operations:p,path:y,inner:n}}computeRoot(e,t=MerkleTree._hash){const s=e.map(t),r=[],n=this._nodes.slice();for(const i of this._operations)switch(i){case MerkleProof.Operation.CONSUME_PROOF:if(0===n.length)throw new Error("Invalid operation.");r.push(n.shift());break;case MerkleProof.Operation.CONSUME_INPUT:if(0===s.length)throw new Error("Invalid operation.");r.push(s.shift());break;case MerkleProof.Operation.HASH:{if(r.length<2)throw new Error("Invalid operation.");const e=r.splice(-2,2),t=new SerialBuffer(e.reduce((e,t)=>e+t.serializedSize,0)),[s,n]=e;s.serialize(t);n.serialize(t);r.push(Hash.light(t));break}default:throw new Error("Invalid operation.")}if(1!==r.length||0!==n.length||0!==s.length)throw Error("Did not consume all nodes.");return r[0]}static _compress(e){const t=e.length,s=Math.ceil(t/4),r=new Uint8Array(s);for(let n=0;n<t;n++){const t=3&e[n];r[Math.floor(n/4)]|=t<<n%4*2}return r}static unserialize(e){const t=e.readUint16(),s=Math.ceil(t/4),r=e.read(s),n=[];for(let a=0;a<t;a++){const e=r[Math.floor(a/4)]>>>a%4*2&3;n.push(e)}const i=e.readUint16(),o=[];for(let a=0;a<i;a++)o.push(Hash.unserialize(e));return new MerkleProof(o,n)}serialize(e){(e=e||new SerialBuffer(this.serializedSize)).writeUint16(this._operations.length);e.write(MerkleProof._compress(this._operations));e.writeUint16(this._nodes.length);for(const t of this._nodes)t.serialize(e);return e}get serializedSize(){return 4+Math.ceil(this._operations.length/4)+this._nodes.reduce((e,t)=>e+t.serializedSize,0)}equals(e){return e instanceof MerkleProof&&this._nodes.length===e._nodes.length&&this._nodes.every((t,s)=>t.equals(e._nodes[s]))&&this._operations.length===e._operations.length&&this._operations.every((t,s)=>t===e._operations[s])}get nodes(){return this._nodes}}MerkleProof.Operation={CONSUME_PROOF:0,CONSUME_INPUT:1,HASH:2};Class.register(MerkleProof);class MnemonicUtils{static _crcChecksum(e){const t=8*e.length/32,s=CRC8.compute(e);return BufferUtils.toBinary([s]).slice(0,t)}static _sha256Checksum(e){const t=8*e.length/32,s=Hash.computeSha256(e);return BufferUtils.toBinary(s).slice(0,t)}static _entropyToBits(e){if(e.length<16)throw new Error("Invalid key, length < 16");if(e.length>32)throw new Error("Invalid key, length > 32");if(e.length%4!=0)throw new Error("Invalid key, length % 4 != 0");return BufferUtils.toBinary(e)}static _normalizeEntropy(e){"string"==typeof e&&(e=BufferUtils.fromHex(e));e instanceof Entropy&&(e=e.serialize());e instanceof ArrayBuffer&&(e=new Uint8Array(e));return e}static _bitsToMnemonic(e,t){return e.match(/(.{11})/g).map(e=>{const s=NumberUtils.fromBinary(e);return t[s]})}static _mnemonicToBits(e,t){const s=e;if(s.length<12)throw new Error("Invalid mnemonic, less than 12 words");if(s.length>24)throw new Error("Invalid mnemonic, more than 24 words");if(s.length%3!=0)throw new Error("Invalid mnemonic, words % 3 != 0");return s.map(function(e){const s=t.indexOf(e.toLowerCase());if(-1===s)throw new Error(`Invalid mnemonic, word >${e}< is not in wordlist`);return StringUtils.lpad(s.toString(2),"0",11)}).join("")}static _bitsToEntropy(e,t=!1){const s=e.length-(e.length%8||8),r=e.slice(0,s),n=e.slice(s),i=r.match(/(.{8})/g).map(NumberUtils.fromBinary);if(i.length<16)throw new Error("Invalid generated key, length < 16");if(i.length>32)throw new Error("Invalid generated key, length > 32");if(i.length%4!=0)throw new Error("Invalid generated key, length % 4 != 0");const o=new Uint8Array(i);if((t?MnemonicUtils._crcChecksum(o):MnemonicUtils._sha256Checksum(o))!==n)throw new Error("Invalid checksum");return o}static entropyToMnemonic(e,t){t=t||MnemonicUtils.DEFAULT_WORDLIST;e=MnemonicUtils._normalizeEntropy(e);const s=MnemonicUtils._entropyToBits(e)+MnemonicUtils._sha256Checksum(e);return MnemonicUtils._bitsToMnemonic(s,t)}static entropyToLegacyMnemonic(e,t){t=t||MnemonicUtils.DEFAULT_WORDLIST;e=MnemonicUtils._normalizeEntropy(e);const s=MnemonicUtils._entropyToBits(e)+MnemonicUtils._crcChecksum(e);return MnemonicUtils._bitsToMnemonic(s,t)}static mnemonicToEntropy(e,t){Array.isArray(e)||(e=e.trim().split(/\s+/g));t=t||MnemonicUtils.DEFAULT_WORDLIST;const s=MnemonicUtils._mnemonicToBits(e,t);return new Entropy(MnemonicUtils._bitsToEntropy(s,!1))}static legacyMnemonicToEntropy(e,t){Array.isArray(e)||(e=e.trim().split(/\s+/g));t=t||MnemonicUtils.DEFAULT_WORDLIST;const s=MnemonicUtils._mnemonicToBits(e,t);return new Entropy(MnemonicUtils._bitsToEntropy(s,!0))}static _salt(e){return`mnemonic${e||""}`}static mnemonicToSeed(e,t){Array.isArray(e)&&(e=e.join(" "));const s=BufferUtils.fromAscii(e),r=BufferUtils.fromAscii(MnemonicUtils._salt(t));return CryptoUtils.computePBKDF2sha512(s,r,2048,64)}static mnemonicToExtendedPrivateKey(e,t){const s=MnemonicUtils.mnemonicToSeed(e,t);return ExtendedPrivateKey.generateMasterKey(s)}static isCollidingChecksum(e){const t=MnemonicUtils._normalizeEntropy(e);return MnemonicUtils._crcChecksum(t)===MnemonicUtils._sha256Checksum(t)}static getMnemonicType(e,t){Array.isArray(e)||(e=e.trim().split(/\s+/g));t=t||MnemonicUtils.DEFAULT_WORDLIST;const s=MnemonicUtils._mnemonicToBits(e,t);let r=!0;try{MnemonicUtils._bitsToEntropy(s,!1)}catch(i){r=!1}let n=!0;try{MnemonicUtils._bitsToEntropy(s,!0)}catch(i){n=!1}if(r&&n)return MnemonicUtils.MnemonicType.UNKNOWN;if(!r&&!n)throw new Error("Invalid checksum");return r?MnemonicUtils.MnemonicType.BIP39:MnemonicUtils.MnemonicType.LEGACY}}MnemonicUtils.ENGLISH_WORDLIST=["abandon","ability","able","about","above","absent","absorb","abstract","absurd","abuse","access","accident","account","accuse","achieve","acid","acoustic","acquire","across","act","action","actor","actress","actual","adapt","add","addict","address","adjust","admit","adult","advance","advice","aerobic","affair","afford","afraid","again","age","agent","agree","ahead","aim","air","airport","aisle","alarm","album","alcohol","alert","alien","all","alley","allow","almost","alone","alpha","already","also","alter","always","amateur","amazing","among","amount","amused","analyst","anchor","ancient","anger","angle","angry","animal","ankle","announce","annual","another","answer","antenna","antique","anxiety","any","apart","apology","appear","apple","approve","april","arch","arctic","area","arena","argue","arm","armed","armor","army","around","arrange","arrest","arrive","arrow","art","artefact","artist","artwork","ask","aspect","assault","asset","assist","assume","asthma","athlete","atom","attack","attend","attitude","attract","auction","audit","august","aunt","author","auto","autumn","average","avocado","avoid","awake","aware","away","awesome","awful","awkward","axis","baby","bachelor","bacon","badge","bag","balance","balcony","ball","bamboo","banana","banner","bar","barely","bargain","barrel","base","basic","basket","battle","beach","bean","beauty","because","become","beef","before","begin","behave","behind","believe","below","belt","bench","benefit","best","betray","better","between","beyond","bicycle","bid","bike","bind","biology","bird","birth","bitter","black","blade","blame","blanket","blast","bleak","bless","blind","blood","blossom","blouse","blue","blur","blush","board","boat","body","boil","bomb","bone","bonus","book","boost","border","boring","borrow","boss","bottom","bounce","box","boy","bracket","brain","brand","brass","brave","bread","breeze","brick","bridge","brief","bright","bring","brisk","broccoli","broken","bronze","broom","brother","brown","brush","bubble","buddy","budget","buffalo","build","bulb","bulk","bullet","bundle","bunker","burden","burger","burst","bus","business","busy","butter","buyer","buzz","cabbage","cabin","cable","cactus","cage","cake","call","calm","camera","camp","can","canal","cancel","candy","cannon","canoe","canvas","canyon","capable","capital","captain","car","carbon","card","cargo","carpet","carry","cart","case","cash","casino","castle","casual","cat","catalog","catch","category","cattle","caught","cause","caution","cave","ceiling","celery","cement","census","century","cereal","certain","chair","chalk","champion","change","chaos","chapter","charge","chase","chat","cheap","check","cheese","chef","cherry","chest","chicken","chief","child","chimney","choice","choose","chronic","chuckle","chunk","churn","cigar","cinnamon","circle","citizen","city","civil","claim","clap","clarify","claw","clay","clean","clerk","clever","click","client","cliff","climb","clinic","clip","clock","clog","close","cloth","cloud","clown","club","clump","cluster","clutch","coach","coast","coconut","code","coffee","coil","coin","collect","color","column","combine","come","comfort","comic","common","company","concert","conduct","confirm","congress","connect","consider","control","convince","cook","cool","copper","copy","coral","core","corn","correct","cost","cotton","couch","country","couple","course","cousin","cover","coyote","crack","cradle","craft","cram","crane","crash","crater","crawl","crazy","cream","credit","creek","crew","cricket","crime","crisp","critic","crop","cross","crouch","crowd","crucial","cruel","cruise","crumble","crunch","crush","cry","crystal","cube","culture","cup","cupboard","curious","current","curtain","curve","cushion","custom","cute","cycle","dad","damage","damp","dance","danger","daring","dash","daughter","dawn","day","deal","debate","debris","decade","december","decide","decline","decorate","decrease","deer","defense","define","defy","degree","delay","deliver","demand","demise","denial","dentist","deny","depart","depend","deposit","depth","deputy","derive","describe","desert","design","desk","despair","destroy","detail","detect","develop","device","devote","diagram","dial","diamond","diary","dice","diesel","diet","differ","digital","dignity","dilemma","dinner","dinosaur","direct","dirt","disagree","discover","disease","dish","dismiss","disorder","display","distance","divert","divide","divorce","dizzy","doctor","document","dog","doll","dolphin","domain","donate","donkey","donor","door","dose","double","dove","draft","dragon","drama","drastic","draw","dream","dress","drift","drill","drink","drip","drive","drop","drum","dry","duck","dumb","dune","during","dust","dutch","duty","dwarf","dynamic","eager","eagle","early","earn","earth","easily","east","easy","echo","ecology","economy","edge","edit","educate","effort","egg","eight","either","elbow","elder","electric","elegant","element","elephant","elevator","elite","else","embark","embody","embrace","emerge","emotion","employ","empower","empty","enable","enact","end","endless","endorse","enemy","energy","enforce","engage","engine","enhance","enjoy","enlist","enough","enrich","enroll","ensure","enter","entire","entry","envelope","episode","equal","equip","era","erase","erode","erosion","error","erupt","escape","essay","essence","estate","eternal","ethics","evidence","evil","evoke","evolve","exact","example","excess","exchange","excite","exclude","excuse","execute","exercise","exhaust","exhibit","exile","exist","exit","exotic","expand","expect","expire","explain","expose","express","extend","extra","eye","eyebrow","fabric","face","faculty","fade","faint","faith","fall","false","fame","family","famous","fan","fancy","fantasy","farm","fashion","fat","fatal","father","fatigue","fault","favorite","feature","february","federal","fee","feed","feel","female","fence","festival","fetch","fever","few","fiber","fiction","field","figure","file","film","filter","final","find","fine","finger","finish","fire","firm","first","fiscal","fish","fit","fitness","fix","flag","flame","flash","flat","flavor","flee","flight","flip","float","flock","floor","flower","fluid","flush","fly","foam","focus","fog","foil","fold","follow","food","foot","force","forest","forget","fork","fortune","forum","forward","fossil","foster","found","fox","fragile","frame","frequent","fresh","friend","fringe","frog","front","frost","frown","frozen","fruit","fuel","fun","funny","furnace","fury","future","gadget","gain","galaxy","gallery","game","gap","garage","garbage","garden","garlic","garment","gas","gasp","gate","gather","gauge","gaze","general","genius","genre","gentle","genuine","gesture","ghost","giant","gift","giggle","ginger","giraffe","girl","give","glad","glance","glare","glass","glide","glimpse","globe","gloom","glory","glove","glow","glue","goat","goddess","gold","good","goose","gorilla","gospel","gossip","govern","gown","grab","grace","grain","grant","grape","grass","gravity","great","green","grid","grief","grit","grocery","group","grow","grunt","guard","guess","guide","guilt","guitar","gun","gym","habit","hair","half","hammer","hamster","hand","happy","harbor","hard","harsh","harvest","hat","have","hawk","hazard","head","health","heart","heavy","hedgehog","height","hello","helmet","help","hen","hero","hidden","high","hill","hint","hip","hire","history","hobby","hockey","hold","hole","holiday","hollow","home","honey","hood","hope","horn","horror","horse","hospital","host","hotel","hour","hover","hub","huge","human","humble","humor","hundred","hungry","hunt","hurdle","hurry","hurt","husband","hybrid","ice","icon","idea","identify","idle","ignore","ill","illegal","illness","image","imitate","immense","immune","impact","impose","improve","impulse","inch","include","income","increase","index","indicate","indoor","industry","infant","inflict","inform","inhale","inherit","initial","inject","injury","inmate","inner","innocent","input","inquiry","insane","insect","inside","inspire","install","intact","interest","into","invest","invite","involve","iron","island","isolate","issue","item","ivory","jacket","jaguar","jar","jazz","jealous","jeans","jelly","jewel","job","join","joke","journey","joy","judge","juice","jump","jungle","junior","junk","just","kangaroo","keen","keep","ketchup","key","kick","kid","kidney","kind","kingdom","kiss","kit","kitchen","kite","kitten","kiwi","knee","knife","knock","know","lab","label","labor","ladder","lady","lake","lamp","language","laptop","large","later","latin","laugh","laundry","lava","law","lawn","lawsuit","layer","lazy","leader","leaf","learn","leave","lecture","left","leg","legal","legend","leisure","lemon","lend","length","lens","leopard","lesson","letter","level","liar","liberty","library","license","life","lift","light","like","limb","limit","link","lion","liquid","list","little","live","lizard","load","loan","lobster","local","lock","logic","lonely","long","loop","lottery","loud","lounge","love","loyal","lucky","luggage","lumber","lunar","lunch","luxury","lyrics","machine","mad","magic","magnet","maid","mail","main","major","make","mammal","man","manage","mandate","mango","mansion","manual","maple","marble","march","margin","marine","market","marriage","mask","mass","master","match","material","math","matrix","matter","maximum","maze","meadow","mean","measure","meat","mechanic","medal","media","melody","melt","member","memory","mention","menu","mercy","merge","merit","merry","mesh","message","metal","method","middle","midnight","milk","million","mimic","mind","minimum","minor","minute","miracle","mirror","misery","miss","mistake","mix","mixed","mixture","mobile","model","modify","mom","moment","monitor","monkey","monster","month","moon","moral","more","morning","mosquito","mother","motion","motor","mountain","mouse","move","movie","much","muffin","mule","multiply","muscle","museum","mushroom","music","must","mutual","myself","mystery","myth","naive","name","napkin","narrow","nasty","nation","nature","near","neck","need","negative","neglect","neither","nephew","nerve","nest","net","network","neutral","never","news","next","nice","night","noble","noise","nominee","noodle","normal","north","nose","notable","note","nothing","notice","novel","now","nuclear","number","nurse","nut","oak","obey","object","oblige","obscure","observe","obtain","obvious","occur","ocean","october","odor","off","offer","office","often","oil","okay","old","olive","olympic","omit","once","one","onion","online","only","open","opera","opinion","oppose","option","orange","orbit","orchard","order","ordinary","organ","orient","original","orphan","ostrich","other","outdoor","outer","output","outside","oval","oven","over","own","owner","oxygen","oyster","ozone","pact","paddle","page","pair","palace","palm","panda","panel","panic","panther","paper","parade","parent","park","parrot","party","pass","patch","path","patient","patrol","pattern","pause","pave","payment","peace","peanut","pear","peasant","pelican","pen","penalty","pencil","people","pepper","perfect","permit","person","pet","phone","photo","phrase","physical","piano","picnic","picture","piece","pig","pigeon","pill","pilot","pink","pioneer","pipe","pistol","pitch","pizza","place","planet","plastic","plate","play","please","pledge","pluck","plug","plunge","poem","poet","point","polar","pole","police","pond","pony","pool","popular","portion","position","possible","post","potato","pottery","poverty","powder","power","practice","praise","predict","prefer","prepare","present","pretty","prevent","price","pride","primary","print","priority","prison","private","prize","problem","process","produce","profit","program","project","promote","proof","property","prosper","protect","proud","provide","public","pudding","pull","pulp","pulse","pumpkin","punch","pupil","puppy","purchase","purity","purpose","purse","push","put","puzzle","pyramid","quality","quantum","quarter","question","quick","quit","quiz","quote","rabbit","raccoon","race","rack","radar","radio","rail","rain","raise","rally","ramp","ranch","random","range","rapid","rare","rate","rather","raven","raw","razor","ready","real","reason","rebel","rebuild","recall","receive","recipe","record","recycle","reduce","reflect","reform","refuse","region","regret","regular","reject","relax","release","relief","rely","remain","remember","remind","remove","render","renew","rent","reopen","repair","repeat","replace","report","require","rescue","resemble","resist","resource","response","result","retire","retreat","return","reunion","reveal","review","reward","rhythm","rib","ribbon","rice","rich","ride","ridge","rifle","right","rigid","ring","riot","ripple","risk","ritual","rival","river","road","roast","robot","robust","rocket","romance","roof","rookie","room","rose","rotate","rough","round","route","royal","rubber","rude","rug","rule","run","runway","rural","sad","saddle","sadness","safe","sail","salad","salmon","salon","salt","salute","same","sample","sand","satisfy","satoshi","sauce","sausage","save","say","scale","scan","scare","scatter","scene","scheme","school","science","scissors","scorpion","scout","scrap","screen","script","scrub","sea","search","season","seat","second","secret","section","security","seed","seek","segment","select","sell","seminar","senior","sense","sentence","series","service","session","settle","setup","seven","shadow","shaft","shallow","share","shed","shell","sheriff","shield","shift","shine","ship","shiver","shock","shoe","shoot","shop","short","shoulder","shove","shrimp","shrug","shuffle","shy","sibling","sick","side","siege","sight","sign","silent","silk","silly","silver","similar","simple","since","sing","siren","sister","situate","six","size","skate","sketch","ski","skill","skin","skirt","skull","slab","slam","sleep","slender","slice","slide","slight","slim","slogan","slot","slow","slush","small","smart","smile","smoke","smooth","snack","snake","snap","sniff","snow","soap","soccer","social","sock","soda","soft","solar","soldier","solid","solution","solve","someone","song","soon","sorry","sort","soul","sound","soup","source","south","space","spare","spatial","spawn","speak","special","speed","spell","spend","sphere","spice","spider","spike","spin","spirit","split","spoil","sponsor","spoon","sport","spot","spray","spread","spring","spy","square","squeeze","squirrel","stable","stadium","staff","stage","stairs","stamp","stand","start","state","stay","steak","steel","stem","step","stereo","stick","still","sting","stock","stomach","stone","stool","story","stove","strategy","street","strike","strong","struggle","student","stuff","stumble","style","subject","submit","subway","success","such","sudden","suffer","sugar","suggest","suit","summer","sun","sunny","sunset","super","supply","supreme","sure","surface","surge","surprise","surround","survey","suspect","sustain","swallow","swamp","swap","swarm","swear","sweet","swift","swim","swing","switch","sword","symbol","symptom","syrup","system","table","tackle","tag","tail","talent","talk","tank","tape","target","task","taste","tattoo","taxi","teach","team","tell","ten","tenant","tennis","tent","term","test","text","thank","that","theme","then","theory","there","they","thing","this","thought","three","thrive","throw","thumb","thunder","ticket","tide","tiger","tilt","timber","time","tiny","tip","tired","tissue","title","toast","tobacco","today","toddler","toe","together","toilet","token","tomato","tomorrow","tone","tongue","tonight","tool","tooth","top","topic","topple","torch","tornado","tortoise","toss","total","tourist","toward","tower","town","toy","track","trade","traffic","tragic","train","transfer","trap","trash","travel","tray","treat","tree","trend","trial","tribe","trick","trigger","trim","trip","trophy","trouble","truck","true","truly","trumpet","trust","truth","try","tube","tuition","tumble","tuna","tunnel","turkey","turn","turtle","twelve","twenty","twice","twin","twist","two","type","typical","ugly","umbrella","unable","unaware","uncle","uncover","under","undo","unfair","unfold","unhappy","uniform","unique","unit","universe","unknown","unlock","until","unusual","unveil","update","upgrade","uphold","upon","upper","upset","urban","urge","usage","use","used","useful","useless","usual","utility","vacant","vacuum","vague","valid","valley","valve","van","vanish","vapor","various","vast","vault","vehicle","velvet","vendor","venture","venue","verb","verify","version","very","vessel","veteran","viable","vibrant","vicious","victory","video","view","village","vintage","violin","virtual","virus","visa","visit","visual","vital","vivid","vocal","voice","void","volcano","volume","vote","voyage","wage","wagon","wait","walk","wall","walnut","want","warfare","warm","warrior","wash","wasp","waste","water","wave","way","wealth","weapon","wear","weasel","weather","web","wedding","weekend","weird","welcome","west","wet","whale","what","wheat","wheel","when","where","whip","whisper","wide","width","wife","wild","will","win","window","wine","wing","wink","winner","winter","wire","wisdom","wise","wish","witness","wolf","woman","wonder","wood","wool","word","work","world","worry","worth","wrap","wreck","wrestle","wrist","write","wrong","yard","year","yellow","you","young","youth","zebra","zero","zone","zoo"];MnemonicUtils.DEFAULT_WORDLIST=MnemonicUtils.ENGLISH_WORDLIST;MnemonicUtils.MnemonicType={UNKNOWN:-1,LEGACY:0,BIP39:1};Object.freeze(MnemonicUtils);Class.register(MnemonicUtils);class StringUtils{static isMultibyte(e){return/[\uD800-\uDFFF]/.test(e)}static isHex(e){return/^[0-9A-Fa-f]*$/.test(e)}static isHexBytes(e,t){return!!StringUtils.isHex(e)&&(e.length%2==0&&("number"!=typeof t||e.length/2===t))}static commonPrefix(e,t){let s=0;for(;s<e.length&&e[s]===t[s];++s);return e.substr(0,s)}static lpad(e,t,s){for(;e.length<s;)e=t+e;return e}}Class.register(StringUtils);class Policy{static coinsToSatoshis(e){return new BigNumber(e).times(Policy.SATOSHIS_PER_COIN).integerValue()}static satoshisToCoins(e){return new BigNumber(e).div(Policy.SATOSHIS_PER_COIN)}static blockRewardAt(e){if(e<=0)return new BigNumber(0);const t=Math.min(Math.floor((e-1)/Policy.HALVING_INTERVAL),Policy.HALVING_TARGET_MAX-1);return new BigNumber(Policy.INITIAL_BLOCK_REWARD).idiv(Math.pow(2,t))}static blockTime(e){return e<=Policy.BLOCK_TIME_MILESTONE?Policy.INITIAL_BLOCK_TIME:e>Policy.HALVING_INTERVAL*Policy.HALVING_TARGET_MAX?Policy.INITIAL_BLOCK_TIME:Policy.BLOCK_TIME_MULTIPLE*(Policy.HALVING_TARGET_MAX-Math.floor((e-1)/Policy.HALVING_INTERVAL))}static targetedTime(e){if(e<=Policy.BLOCK_TIME_MILESTONE)return(e-1)*Policy.INITIAL_BLOCK_TIME;const t=Policy.BLOCK_TIME_MILESTONE*Policy.INITIAL_BLOCK_TIME,s=Policy.BLOCK_TIME_MULTIPLE*Policy.HALVING_TARGET_MAX;if(e<=Policy.HALVING_INTERVAL)return t+(e-Policy.BLOCK_TIME_MILESTONE-1)*s;let r=t+(Policy.HALVING_INTERVAL-Policy.BLOCK_TIME_MILESTONE)*s,n=e-Policy.HALVING_INTERVAL,i=1;for(;n>Policy.HALVING_INTERVAL&&i<Policy.HALVING_TARGET_MAX;){r+=Policy.HALVING_INTERVAL*Policy.BLOCK_TIME_MULTIPLE*(Policy.HALVING_TARGET_MAX-i);n-=Policy.HALVING_INTERVAL;i+=1}i>=Policy.HALVING_TARGET_MAX?r+=(n-1)*Policy.INITIAL_BLOCK_TIME:r+=(n-1)*Policy.BLOCK_TIME_MULTIPLE*(Policy.HALVING_TARGET_MAX-i);return r}static targetedTimeBlockRange(e,t){const s=e>1?e:1,r=t>1?t:1;if(s>=r)return 0;const n=Policy.HALVING_INTERVAL*Policy.HALVING_TARGET_MAX;let i=r-s;if(r<=Policy.BLOCK_TIME_MILESTONE||s>n)return i*Policy.INITIAL_BLOCK_TIME;const o=Policy.BLOCK_TIME_MULTIPLE*Policy.HALVING_TARGET_MAX;if(r<=Policy.HALVING_INTERVAL)return s<=Policy.BLOCK_TIME_MILESTONE?(Policy.BLOCK_TIME_MILESTONE-s+1)*Policy.INITIAL_BLOCK_TIME+(r-Policy.BLOCK_TIME_MILESTONE-1)*o:i*o;const a=Math.floor((s-1)/Policy.HALVING_INTERVAL);let c,h=Math.floor((r-1)/Policy.HALVING_INTERVAL);if(a===h)return i*Policy.BLOCK_TIME_MULTIPLE*(Policy.HALVING_TARGET_MAX-a);let l,u=0;if(s<=Policy.BLOCK_TIME_MILESTONE)c=(Policy.BLOCK_TIME_MILESTONE-s+1)*Policy.INITIAL_BLOCK_TIME+(Policy.HALVING_INTERVAL-Policy.BLOCK_TIME_MILESTONE)*o;else{c=((a+1)*Policy.HALVING_INTERVAL-s+1)*Policy.BLOCK_TIME_MULTIPLE*(Policy.HALVING_TARGET_MAX-a)}if(r>n){h=Policy.HALVING_TARGET_MAX;l=(r-n-1)*Policy.INITIAL_BLOCK_TIME}else{l=(r-h*Policy.HALVING_INTERVAL-1)*Policy.BLOCK_TIME_MULTIPLE*(Policy.HALVING_TARGET_MAX-h)}for(let d=a+1;d<h;d++)u+=Policy.HALVING_INTERVAL*Policy.BLOCK_TIME_MULTIPLE*(Policy.HALVING_TARGET_MAX-d);return c+u+l}static txFee(e){if(e<=1)return new BigNumber(0);const t=Math.floor((e-1)/Policy.TX_FEE_CHANGING_INTERVAL);return t<Policy.TX_FEE_CHANGING_TOTAL_NUMBER?new BigNumber(Policy.INITIAL_TX_FEE).div(Math.pow(10,t)):new BigNumber(1)}static blockSize(e){return e<Policy.FORKING_FOR_BLOCK_DIFFICULTY_BLOCK_SIZE?Policy.INITIAL_BLOCK_SIZE:Policy.BASE_BLOCK_SIZE+Policy.BLOCK_SIZE_FACTOR*Math.floor(e/Policy.BLOCK_SIZE_CHANGING_INTERVAL)}static difficultyBlockWindow(e){if(e>=Policy.SECOND_FORKING_FOR_BLOCK_DIFFICULTY||e<Policy.FORKING_FOR_BLOCK_DIFFICULTY_BLOCK_SIZE)return Policy.DIFFICULTY_BLOCK_WINDOW;const t=Policy.blockTime(e);return Math.floor(360/t)}}Policy.INITIAL_BLOCK_TIME=3;Policy.BLOCK_TIME_MULTIPLE=3;Policy.BLOCK_TIME_MILESTONE=11e5;Policy.INITIAL_BLOCK_SIZE=1e5;Policy.BASE_BLOCK_SIZE=21e5;Policy.BLOCK_SIZE_FACTOR=2100;Policy.BLOCK_SIZE_CHANGING_INTERVAL=21e5;Policy.BLOCK_TARGET_MAX=new BigNumber(2).pow(240);Policy.DIFFICULTY_BLOCK_WINDOW=120;Policy.FORKING_FOR_BLOCK_DIFFICULTY_BLOCK_SIZE=1124816;Policy.DIFFICULTY_MAX_ADJUSTMENT_FACTOR=2;Policy.NEW_DIFFICULTY_MAX_ADJUSTMENT_FACTOR=1.3;Policy.NEW_DIFFICULTY_MIN_ADJUSTMENT_FACTOR=.7;Policy.SECOND_FORKING_FOR_BLOCK_DIFFICULTY=1132333;Policy.SECOND_DIFFICULTY_MAX_ADJUSTMENT_FACTOR=1.5;Policy.SECOND_DIFFICULTY_MIN_ADJUSTMENT_FACTOR=.5;Policy.TRANSACTION_VALIDITY_WINDOW=120;Policy.SATOSHIS_PER_COIN=1e11;Policy.INITIAL_SUPPLY=0;Policy.INITIAL_BLOCK_REWARD=5e11;Policy.HALVING_TARGET_MAX=21;Policy.HALVING_INTERVAL=21e5;Policy.M=240;Policy.K=120;Policy.DELTA=.15;Policy.NUM_BLOCKS_VERIFICATION=250;Policy.NUM_SNAPSHOTS_MAX=20;Policy.INITIAL_TX_FEE=1e6;Policy.TX_FEE_CHANGING_INTERVAL=63e5;Policy.TX_FEE_CHANGING_TOTAL_NUMBER=6;Class.register(Policy);class Serializable{equals(e){return e instanceof Serializable&&BufferUtils.equals(this.serialize(),e.serialize())}compare(e){return BufferUtils.compare(this.serialize(),e.serialize())}hashCode(){return this.toBase64()}serialize(e){}toString(){return this.toBase64()}toBase64(){return BufferUtils.toBase64(this.serialize())}toHex(){return BufferUtils.toHex(this.serialize())}toBase58(){return BufferUtils.toBase58(this.serialize())}toBase58Check(e=128,t){return BufferUtils.toBase58Check(this.serialize(),e,t)}}Class.register(Serializable);class Hash extends Serializable{constructor(e,t=Hash.Algorithm.BLAKE2B){if(null===e)e=new Uint8Array(Hash.getSize(t));else{if(!(e instanceof Uint8Array))throw new Error("Primitive: Invalid type");if(e.length!==Hash.getSize(t))throw new Error("Primitive: Invalid length")}super();this._obj=e;this._algorithm=t}static light(e){return Hash.blake2b(e)}static blake2b(e){return new Hash(Hash.computeBlake2b(e),Hash.Algorithm.BLAKE2B)}static hard(e){return Hash.argon2d(e)}static async argon2d(e){return new Hash(await(await CryptoWorker.getInstanceAsync()).computeArgon2d(e),Hash.Algorithm.ARGON2D)}static sha256(e){return new Hash(Hash.computeSha256(e),Hash.Algorithm.SHA256)}static sha512(e){return new Hash(Hash.computeSha512(e),Hash.Algorithm.SHA512)}static ripemd160(e){return new Hash(Hash.computeRipemd160(e),Hash.Algorithm.RIPEMD160)}static doubleHash(e){return Hash.ripemd160(Hash.computeSha256(e))}static keccak256(e){return new Hash(Hash.computeKeccak256(e),Hash.Algorithm.KECCAK256)}static compute(e,t){switch(t){case Hash.Algorithm.BLAKE2B:return Hash.blake2b(e);case Hash.Algorithm.SHA256:return Hash.sha256(e);default:throw new Error("Invalid hash algorithm")}}static unserialize(e,t=Hash.Algorithm.BLAKE2B){return new Hash(e.read(Hash.getSize(t)),t)}serialize(e){(e=e||new SerialBuffer(this.serializedSize)).write(this._obj);return e}subarray(e,t){return this._obj.subarray(e,t)}get serializedSize(){return Hash.SIZE.get(this._algorithm)}get array(){return this._obj}get algorithm(){return this._algorithm}equals(e){return e instanceof Hash&&e._algorithm===this._algorithm&&super.equals(e)}static fromAny(e,t=Hash.Algorithm.BLAKE2B){if(e instanceof Hash)return e;try{return new Hash(BufferUtils.fromAny(e,Hash.SIZE.get(t)),t)}catch(s){throw new Error("Invalid hash format")}}toPlain(){return this.toHex()}static fromBase64(e){return new Hash(BufferUtils.fromBase64(e))}static fromHex(e){return new Hash(BufferUtils.fromHex(e))}static fromPlain(e){return Hash.fromString(e)}static fromString(e){try{return Hash.fromHex(e)}catch(t){}try{return Hash.fromBase64(e)}catch(t){}throw new Error("Invalid hash format")}static isHash(e){return e instanceof Hash}static getSize(e){const t=Hash.SIZE.get(e);if("number"!=typeof t)throw new Error("Invalid hash algorithm");return t}static computeBlake2b(e){if(PlatformUtils.isNodeJs()){const t=new Uint8Array(Hash.getSize(Hash.Algorithm.BLAKE2B));NodeNative.node_blake2(t,new Uint8Array(e));return t}{let s;try{s=Module.stackSave();const r=Hash.getSize(Hash.Algorithm.BLAKE2B),n=Module.stackAlloc(r),i=Module.stackAlloc(e.length);new Uint8Array(Module.HEAPU8.buffer,i,e.length).set(e);const o=Module._krypton_blake2(n,i,e.length);if(0!==o)throw o;const a=new Uint8Array(r);a.set(new Uint8Array(Module.HEAPU8.buffer,n,r));return a}catch(t){Log.w(Hash,t);throw t}finally{s!==undefined&&Module.stackRestore(s)}}}static computeSha256(e){if(PlatformUtils.isNodeJs()){const t=new Uint8Array(Hash.getSize(Hash.Algorithm.SHA256));NodeNative.node_sha256(t,new Uint8Array(e));return t}{let s;try{s=Module.stackSave();const r=Hash.getSize(Hash.Algorithm.SHA256),n=Module.stackAlloc(r),i=Module.stackAlloc(e.length);new Uint8Array(Module.HEAPU8.buffer,i,e.length).set(e);Module._krypton_sha256(n,i,e.length);const o=new Uint8Array(r);o.set(new Uint8Array(Module.HEAPU8.buffer,n,r));return o}catch(t){Log.w(Hash,t);throw t}finally{s!==undefined&&Module.stackRestore(s)}}}static computeSha512(e){if(PlatformUtils.isNodeJs()){const t=new Uint8Array(Hash.getSize(Hash.Algorithm.SHA512));NodeNative.node_sha512(t,new Uint8Array(e));return t}{let s;try{s=Module.stackSave();const r=Hash.getSize(Hash.Algorithm.SHA512),n=Module.stackAlloc(r),i=Module.stackAlloc(e.length);new Uint8Array(Module.HEAPU8.buffer,i,e.length).set(e);Module._krypton_sha512(n,i,e.length);const o=new Uint8Array(r);o.set(new Uint8Array(Module.HEAPU8.buffer,n,r));return o}catch(t){Log.w(Hash,t);throw t}finally{s!==undefined&&Module.stackRestore(s)}}}static computeRipemd160(e){if(PlatformUtils.isNodeJs()){const t=new Uint8Array(Hash.getSize(Hash.Algorithm.RIPEMD160));NodeNative.node_ripemd160(t,new Uint8Array(e));return t}{let s;try{s=Module.stackSave();const r=Hash.getSize(Hash.Algorithm.RIPEMD160),n=Module.stackAlloc(r),i=Module.stackAlloc(e.length);new Uint8Array(Module.HEAPU8.buffer,i,e.length).set(e);Module._ripemd160(i,e.length,n);const o=new Uint8Array(r);o.set(new Uint8Array(Module.HEAPU8.buffer,n,r));return o}catch(t){Log.w(Hash,t);throw t}finally{s!==undefined&&Module.stackRestore(s)}}}static computeKeccak256(e){if(PlatformUtils.isNodeJs()){const t=new Uint8Array(Hash.getSize(Hash.Algorithm.KECCAK256));NodeNative.node_keccak256(t,new Uint8Array(e));return t}{let s;try{s=Module.stackSave();const r=Hash.getSize(Hash.Algorithm.KECCAK256),n=Module.stackAlloc(r),i=Module.stackAlloc(e.length);new Uint8Array(Module.HEAPU8.buffer,i,e.length).set(e);Module._keccak256(i,e.length,n);const o=new Uint8Array(r);o.set(new Uint8Array(Module.HEAPU8.buffer,n,r));return o}catch(t){Log.w(Hash,t);throw t}finally{s!==undefined&&Module.stackRestore(s)}}}}Hash.Algorithm={BLAKE2B:1,ARGON2D:2,SHA256:3,SHA512:4,RIPEMD160:5,KECCAK256:6};Hash.Algorithm.toString=function(e){switch(e){case Hash.Algorithm.BLAKE2B:return"blake2b";case Hash.Algorithm.ARGON2D:return"argon2d";case Hash.Algorithm.SHA256:return"sha256";case Hash.Algorithm.SHA512:return"sha512";case Hash.Algorithm.RIPEMD160:return"ripemd160";case Hash.Algorithm.KECCAK256:return"keccak256"}throw new Error("Invalid hash algorithm")};Hash.Algorithm.fromAny=function(e){if("number"==typeof e)return e;switch(e){case"blake2b":return Hash.Algorithm.BLAKE2B;case"argon2d":return Hash.Algorithm.ARGON2D;case"sha256":return Hash.Algorithm.SHA256;case"sha512":return Hash.Algorithm.SHA512;case"ripemd160":return Hash.Algorithm.RIPEMD160;case"keccak256":return Hash.Algorithm.KECCAK256}throw new Error("Invalid hash algorithm")};Hash.SIZE=new Map;Hash.SIZE.set(Hash.Algorithm.BLAKE2B,32);Hash.SIZE.set(Hash.Algorithm.ARGON2D,32);Hash.SIZE.set(Hash.Algorithm.SHA256,32);Hash.SIZE.set(Hash.Algorithm.SHA512,64);Hash.SIZE.set(Hash.Algorithm.RIPEMD160,20);Hash.SIZE.set(Hash.Algorithm.KECCAK256,32);Hash.NULL=new Hash(new Uint8Array(32));Class.register(Hash);class Secret extends Serializable{constructor(e,t){super();this._type=e;this._purposeId=t}static fromEncrypted(e,t){const s=e.readUint8(),r=e.readUint8();if(r>32)throw new Error("Rounds out-of-bounds");const n=Math.pow(2,r);switch(s){case 1:return Secret._decryptV1(e,t,n);case 2:return Secret._decryptV2(e,t,n);case 3:return Secret._decryptV3(e,t,n);default:throw new Error("Unsupported version")}}static async _decryptV1(e,t,s){const r=e.read(Secret.SIZE),n=e.read(Secret.ENCRYPTION_SALT_SIZE),i=e.read(Secret.ENCRYPTION_CHECKSUM_SIZE),o=await CryptoUtils.otpKdfLegacy(r,t,n,s),a=new PrivateKey(o),c=PublicKey.derive(a).hash().subarray(0,Secret.ENCRYPTION_CHECKSUM_SIZE);if(!BufferUtils.equals(i,c))throw new Error("Invalid key");return a}static async _decryptV2(e,t,s){const r=e.read(Secret.SIZE),n=e.read(Secret.ENCRYPTION_SALT_SIZE),i=e.read(Secret.ENCRYPTION_CHECKSUM_SIZE),o=await CryptoUtils.otpKdfLegacy(r,t,n,s),a=Hash.computeBlake2b(o).subarray(0,Secret.ENCRYPTION_CHECKSUM_SIZE);if(!BufferUtils.equals(i,a))throw new Error("Invalid key");return new PrivateKey(o)}static async _decryptV3(e,t,s){const r=e.read(Secret.ENCRYPTION_SALT_SIZE),n=e.read(Secret.ENCRYPTION_CHECKSUM_SIZE_V3+4+Secret.SIZE),i=await CryptoUtils.otpKdf(n,t,r,s),o=i.subarray(0,Secret.ENCRYPTION_CHECKSUM_SIZE_V3),a=i.subarray(Secret.ENCRYPTION_CHECKSUM_SIZE_V3),c=Hash.computeBlake2b(a).subarray(0,Secret.ENCRYPTION_CHECKSUM_SIZE_V3);if(!BufferUtils.equals(o,c))throw new Error("Invalid key");const h=a[0]<<24|a[1]<<16|a[2]<<8|a[3],l=a.subarray(4);switch(h){case PrivateKey.PURPOSE_ID:return new PrivateKey(l);case Entropy.PURPOSE_ID:default:return new Entropy(l)}}async exportEncrypted(e){const t=new Uint8Array(Secret.ENCRYPTION_SALT_SIZE);CryptoWorker.lib.getRandomValues(t);const s=new SerialBuffer(4+Secret.SIZE);s.writeUint32(this._purposeId);s.write(this.serialize());const r=Hash.computeBlake2b(s).subarray(0,Secret.ENCRYPTION_CHECKSUM_SIZE_V3),n=new SerialBuffer(r.byteLength+s.byteLength);n.write(r);n.write(s);const i=await CryptoUtils.otpKdf(n,e,t,Secret.ENCRYPTION_KDF_ROUNDS),o=new SerialBuffer(2+t.byteLength+i.byteLength);o.writeUint8(3);o.writeUint8(Math.log2(Secret.ENCRYPTION_KDF_ROUNDS));o.write(t);o.write(i);return o}get encryptedSize(){return 2+Secret.ENCRYPTION_SALT_SIZE+Secret.ENCRYPTION_CHECKSUM_SIZE_V3+4+Secret.SIZE}get type(){return this._type}}Secret.Type={PRIVATE_KEY:1,ENTROPY:2};Secret.SIZE=32;Secret.ENCRYPTION_SALT_SIZE=16;Secret.ENCRYPTION_KDF_ROUNDS=256;Secret.ENCRYPTION_CHECKSUM_SIZE=4;Secret.ENCRYPTION_CHECKSUM_SIZE_V3=2;Class.register(Secret);class PrivateKey extends Secret{constructor(e){super(Secret.Type.PRIVATE_KEY,PrivateKey.PURPOSE_ID);if(!(e instanceof Uint8Array))throw new Error("Primitive: Invalid type");if(e.length!==PrivateKey.SIZE)throw new Error("Primitive: Invalid length");this._obj=e}static generate(){const e=new Uint8Array(PrivateKey.SIZE);CryptoWorker.lib.getRandomValues(e);return new PrivateKey(e)}static unserialize(e){return new PrivateKey(e.read(PrivateKey.SIZE))}serialize(e){(e=e||new SerialBuffer(this.serializedSize)).write(this._obj);return e}get serializedSize(){return PrivateKey.SIZE}overwrite(e){this._obj.set(e._obj)}equals(e){return e instanceof PrivateKey&&super.equals(e)}static _privateKeyDelinearize(e,t,s){if(e.byteLength!==PrivateKey.SIZE||t.byteLength!==PublicKey.SIZE||s.byteLength!==Hash.getSize(Hash.Algorithm.SHA256))throw Error("Wrong buffer size.");if(PlatformUtils.isNodeJs()){const r=new Uint8Array(PublicKey.SIZE);NodeNative.node_secp256k1_derive_delinearized_seckey(r,new Uint8Array(s),new Uint8Array(t),new Uint8Array(e));return r}{let n;try{n=Module.stackSave();const i=Module.stackAlloc(PublicKey.SIZE),o=Module.stackAlloc(e.length),a=Module.stackAlloc(t.length),c=Module.stackAlloc(s.length);new Uint8Array(Module.HEAPU8.buffer,o,e.length).set(e);new Uint8Array(Module.HEAPU8.buffer,a,t.length).set(t);new Uint8Array(Module.HEAPU8.buffer,c,s.length).set(s);Module._secp256k1_derive_delinearized_seckey(i,c,a,o);const h=new Uint8Array(PrivateKey.SIZE);h.set(new Uint8Array(Module.HEAPU8.buffer,i,PrivateKey.SIZE));return h}catch(r){Log.w(CryptoWorkerImpl,r);throw r}finally{n!==undefined&&Module.stackRestore(n)}}}}PrivateKey.SIZE=Secret.SIZE;PrivateKey.PURPOSE_ID=1107296257;Class.register(PrivateKey);class PublicKey extends Serializable{static copy(e){return e?new PublicKey(new Uint8Array(e._obj)):e}constructor(e){super();if(!(e instanceof Uint8Array))throw new Error("Primitive: Invalid type");if(e.length!==PublicKey.SIZE)throw new Error("Primitive: Invalid length");this._obj=e}static derive(e){return new PublicKey(PublicKey._publicKeyDerive(e._obj))}compress(){return PublicKey._compressPublicKey(this._obj)}static sum(e){(e=e.slice()).sort((e,t)=>e.compare(t));return PublicKey._delinearizeAndAggregatePublicKeys(e)}static unserialize(e){return new PublicKey(e.read(PublicKey.SIZE))}static fromAny(e){if(!e)throw new Error("Invalid public key format");if(e instanceof PublicKey)return e;try{return new PublicKey(BufferUtils.fromAny(e,PublicKey.SIZE))}catch(t){throw new Error("Invalid public key format")}}serialize(e){(e=e||new SerialBuffer(this.serializedSize)).write(this._obj);return e}get serializedSize(){return PublicKey.SIZE}equals(e){return e instanceof PublicKey&&super.equals(e)}hash(){return Hash.keccak256(this.serialize().slice(1))}compare(e){return BufferUtils.compare(this._obj,e._obj)}toAddress(){return Address.fromHash(this.hash())}toPeerId(){return new PeerId(this.hash().subarray(0,16))}static _delinearizeAndAggregatePublicKeys(e){const t=e.map(e=>e.serialize()),s=PublicKey._publicKeysHash(t),r=PublicKey._publicKeysDelinearizeAndAggregate(t,s);return new PublicKey(r)}static _compressPublicKey(e){if(e.byteLength!==PublicKey.SIZE)throw Error("Wrong buffer size.");const t=new Uint8Array(32);CryptoWorker.lib.getRandomValues(t);if(PlatformUtils.isNodeJs()){NodeNative.node_secp256k1_ctx_init(t);const s=new Uint8Array(PublicKey.COMPRESSED_SIZE);NodeNative.node_secp256k1_pubkey_compress(s,new Uint8Array(e));NodeNative.node_secp256k1_ctx_release();return s}{let r;try{r=Module.stackSave();const n=Module.stackAlloc(32);new Uint8Array(Module.HEAP8.buffer,n,32).set(t);Module._secp256k1_ctx_init(n);const i=Module.stackAlloc(PublicKey.COMPRESSED_SIZE),o=new Uint8Array(Module.HEAP8.buffer,i,PublicKey.COMPRESSED_SIZE),a=Module.stackAlloc(PublicKey.SIZE);new Uint8Array(Module.HEAP8.buffer,a,PublicKey.SIZE).set(e);Module._secp256k1_pubkey_compress(i,a);const c=new Uint8Array(PublicKey.COMPRESSED_SIZE);c.set(o);return c}catch(s){Log.w(PublicKey,s);throw s}finally{Module._secp256k1_ctx_release();r!==undefined&&Module.stackRestore(r)}}}static _publicKeyDerive(e){if(e.byteLength!==PrivateKey.SIZE)throw Error("Wrong buffer size.");const t=new Uint8Array(32);CryptoWorker.lib.getRandomValues(t);if(PlatformUtils.isNodeJs()){NodeNative.node_secp256k1_ctx_init(t);const s=new Uint8Array(PublicKey.SIZE);NodeNative.node_secp256k1_pubkey_create(s,new Uint8Array(e));NodeNative.node_secp256k1_ctx_release();return s}{let r;try{r=Module.stackSave();const n=Module.stackAlloc(32);new Uint8Array(Module.HEAP8.buffer,n,32).set(t);Module._secp256k1_ctx_init(n);const i=Module.stackAlloc(PublicKey.SIZE),o=new Uint8Array(Module.HEAP8.buffer,i,PublicKey.SIZE),a=Module.stackAlloc(e.length),c=new Uint8Array(Module.HEAP8.buffer,a,PrivateKey.SIZE);c.set(e);Module._secp256k1_pubkey_create(i,PublicKey.SIZE,a);c.fill(0);const h=new Uint8Array(PublicKey.SIZE);h.set(o);return h}catch(s){Log.w(PublicKey,s);throw s}finally{Module._secp256k1_ctx_release();r!==undefined&&Module.stackRestore(r)}}}static _publicKeysHash(e){if(e.some(e=>e.byteLength!==PublicKey.SIZE))throw Error("Wrong buffer size.");const t=new Uint8Array(e.length*PublicKey.SIZE);for(let r=0;r<e.length;++r)t.set(e[r],r*PublicKey.SIZE);if(PlatformUtils.isNodeJs()){const s=new Uint8Array(Hash.getSize(Hash.Algorithm.SHA256));NodeNative.node_secp256k1_hash_pubkeys(s,t,e.length,PublicKey.SIZE);return s}{let r;try{r=Module.stackSave();const n=Hash.getSize(Hash.Algorithm.SHA256),i=Module.stackAlloc(n),o=Module.stackAlloc(t.length);new Uint8Array(Module.HEAPU8.buffer,o,t.length).set(t);Module._secp256k1_hash_pubkeys(i,o,e.length,PublicKey.SIZE);const a=new Uint8Array(n);a.set(new Uint8Array(Module.HEAPU8.buffer,i,n));return a}catch(s){Log.w(PublicKey,s);throw s}finally{r!==undefined&&Module.stackRestore(r)}}}static _publicKeyDelinearize(e,t){if(e.byteLength!==PublicKey.SIZE||t.byteLength!==Hash.getSize(Hash.Algorithm.SHA256))throw Error("Wrong buffer size.");if(PlatformUtils.isNodeJs()){const s=new Uint8Array(PublicKey.SIZE);NodeNative.node_secp256k1_delinearize_pubkey(s,new Uint8Array(t),new Uint8Array(e));return s}{let r;try{r=Module.stackSave();const n=Module.stackAlloc(PublicKey.SIZE),i=Module.stackAlloc(e.length),o=Module.stackAlloc(t.length);new Uint8Array(Module.HEAPU8.buffer,i,e.length).set(e);new Uint8Array(Module.HEAPU8.buffer,o,t.length).set(t);Module._secp256k1_delinearize_pubkey(n,o,i);const a=new Uint8Array(PublicKey.SIZE);a.set(new Uint8Array(Module.HEAPU8.buffer,n,PublicKey.SIZE));return a}catch(s){Log.w(PublicKey,s);throw s}finally{r!==undefined&&Module.stackRestore(r)}}}static _publicKeysDelinearizeAndAggregate(e,t){if(e.some(e=>e.byteLength!==PublicKey.SIZE)||t.byteLength!==Hash.getSize(Hash.Algorithm.SHA256))throw Error("Wrong buffer size.");const s=new Uint8Array(e.length*PublicKey.SIZE);for(let n=0;n<e.length;++n)s.set(e[n],n*PublicKey.SIZE);if(PlatformUtils.isNodeJs()){const r=new Uint8Array(PublicKey.SIZE);NodeNative.node_secp256k1_aggregate_delinearized_publkeys(r,new Uint8Array(t),s,e.length,PublicKey.SIZE);return r}{let n;try{n=Module.stackSave();const i=Module.stackAlloc(PublicKey.SIZE),o=Module.stackAlloc(s.length),a=Module.stackAlloc(t.length);new Uint8Array(Module.HEAPU8.buffer,o,s.length).set(s);new Uint8Array(Module.HEAPU8.buffer,a,t.length).set(t);Module._secp256k1_aggregate_delinearized_publkeys(i,a,o,e.length,PublicKey.SIZE);const c=new Uint8Array(PublicKey.SIZE);c.set(new Uint8Array(Module.HEAPU8.buffer,i,PublicKey.SIZE));return c}catch(r){Log.w(PublicKey,r);throw r}finally{n!==undefined&&Module.stackRestore(n)}}}}PublicKey.COMPRESSED_SIZE=33;PublicKey.SIZE=65;Class.register(PublicKey);class KeyPair extends Serializable{constructor(e,t,s=!1,r=null){if(!(e instanceof Object))throw new Error("Primitive: Invalid type");if(!(t instanceof Object))throw new Error("Primitive: Invalid type");super();this._locked=s;this._lockedInternally=s;this._lockSalt=r;this._publicKey=t;this._internalPrivateKey=new PrivateKey(e.serialize())}static generate(){const e=PrivateKey.generate();return new KeyPair(e,PublicKey.derive(e))}static derive(e){return new KeyPair(e,PublicKey.derive(e))}static fromHex(e){return KeyPair.unserialize(BufferUtils.fromHex(e))}static unserialize(e){const t=PrivateKey.unserialize(e),s=PublicKey.unserialize(e);let r=!1,n=null;if(e.readPos<e.byteLength){if(1===e.readUint8()){r=!0;n=e.read(32)}}return new KeyPair(t,s,r,n)}serialize(e){e=e||new SerialBuffer(this.serializedSize);this._privateKey.serialize(e);this.publicKey.serialize(e);if(this._locked){e.writeUint8(1);e.write(this._lockSalt)}else e.writeUint8(0);return e}get privateKey(){if(this.isLocked)throw new Error("KeyPair is locked");return this._privateKey}get _privateKey(){return this._unlockedPrivateKey||this._internalPrivateKey}get publicKey(){return this._publicKey||(this._publicKey=new PublicKey(this._obj.publicKey))}get serializedSize(){return this._privateKey.serializedSize+this.publicKey.serializedSize+(this._locked?this._lockSalt.byteLength+1:1)}async lock(e,t){if(this._locked)throw new Error("KeyPair already locked");t&&(this._lockSalt=t);if(!this._lockSalt||0===this._lockSalt.length){this._lockSalt=new Uint8Array(32);CryptoWorker.lib.getRandomValues(this._lockSalt)}this._internalPrivateKey.overwrite(await this._otpPrivateKey(e));this._clearUnlockedPrivateKey();this._locked=!0;this._lockedInternally=!0}async unlock(e){if(!this._locked)throw new Error("KeyPair not locked");const t=await this._otpPrivateKey(e);if(!PublicKey.derive(t).equals(this.publicKey))throw new Error("Invalid key");this._unlockedPrivateKey=t;this._locked=!1}relock(){if(this._locked)throw new Error("KeyPair already locked");if(!this._lockedInternally)throw new Error("KeyPair was never locked");this._clearUnlockedPrivateKey();this._locked=!0}_clearUnlockedPrivateKey(){if(this._lockedInternally&&!this._locked){this._unlockedPrivateKey.overwrite(PrivateKey.unserialize(new SerialBuffer(this._unlockedPrivateKey.serializedSize)));this._unlockedPrivateKey=null}}async _otpPrivateKey(e){return new PrivateKey(await CryptoUtils.otpKdfLegacy(this._privateKey.serialize(),e,this._lockSalt,KeyPair.LOCK_KDF_ROUNDS))}get isLocked(){return this._locked}static async fromEncrypted(e,t){const s=await Secret.fromEncrypted(e,t);if(s.type!==Secret.Type.PRIVATE_KEY)throw new Error("Expected privateKey, got Entropy");return KeyPair.derive(s)}exportEncrypted(e){return this._privateKey.exportEncrypted(e)}get encryptedSize(){return this._privateKey.encryptedSize}equals(e){return e instanceof KeyPair&&super.equals(e)}}KeyPair.LOCK_KDF_ROUNDS=256;Class.register(KeyPair);class Entropy extends Secret{constructor(e){super(Secret.Type.ENTROPY,Entropy.PURPOSE_ID);if(!(e instanceof Uint8Array))throw new Error("Primitive: Invalid type");if(e.length!==Entropy.SIZE)throw new Error("Primitive: Invalid length");this._obj=e}static generate(){const e=new Uint8Array(Entropy.SIZE);CryptoWorker.lib.getRandomValues(e);return new Entropy(e)}toExtendedPrivateKey(e,t){return MnemonicUtils.mnemonicToExtendedPrivateKey(this.toMnemonic(t),e)}toMnemonic(e){return MnemonicUtils.entropyToMnemonic(this,e)}static unserialize(e){return new Entropy(e.read(Entropy.SIZE))}serialize(e){(e=e||new SerialBuffer(this.serializedSize)).write(this._obj);return e}get serializedSize(){return Entropy.SIZE}overwrite(e){this._obj.set(e._obj)}equals(e){return e instanceof Entropy&&super.equals(e)}}Entropy.SIZE=Secret.SIZE;Entropy.PURPOSE_ID=1107296258;Class.register(Entropy);class ExtendedPrivateKey extends Serializable{constructor(e,t){super();if(!(e instanceof PrivateKey))throw new Error("ExtendedPrivateKey: Invalid key");if(!(t instanceof Uint8Array))throw new Error("ExtendedPrivateKey: Invalid chainCode");if(t.length!==ExtendedPrivateKey.CHAIN_CODE_SIZE)throw new Error("ExtendedPrivateKey: Invalid chainCode length");this._key=e;this._chainCode=t}static generateMasterKey(e){const t=BufferUtils.fromAscii("secp256k1 seed"),s=CryptoUtils.computeHmacSha512(t,e);return new ExtendedPrivateKey(new PrivateKey(s.slice(0,32)),s.slice(32))}derive(e){e<2147483648&&(e+=2147483648);const t=new SerialBuffer(1+PrivateKey.SIZE+4);t.writeUint8(0);this._key.serialize(t);t.writeUint32(e);const s=CryptoUtils.computeHmacSha512(this._chainCode,t);return new ExtendedPrivateKey(new PrivateKey(s.slice(0,32)),s.slice(32))}static isValidPath(e){if(null===e.match(/^m(\/[0-9]+')*$/))return!1;const t=e.split("/");for(let s=1;s<t.length;s++)if(!NumberUtils.isUint32(parseInt(t[s])))return!1;return!0}derivePath(e){if(!ExtendedPrivateKey.isValidPath(e))throw new Error("Invalid path");let t=this;const s=e.split("/");for(let r=1;r<s.length;r++){const e=parseInt(s[r]);t=t.derive(e)}return t}static derivePathFromSeed(e,t){return ExtendedPrivateKey.generateMasterKey(t).derivePath(e)}static unserialize(e){const t=PrivateKey.unserialize(e),s=e.read(ExtendedPrivateKey.CHAIN_CODE_SIZE);return new ExtendedPrivateKey(t,s)}serialize(e){e=e||new SerialBuffer(this.serializedSize);this._key.serialize(e);e.write(this._chainCode);return e}get serializedSize(){return this._key.serializedSize+ExtendedPrivateKey.CHAIN_CODE_SIZE}equals(e){return e instanceof ExtendedPrivateKey&&super.equals(e)}get privateKey(){return this._key}toAddress(){return PublicKey.derive(this._key).toAddress()}}ExtendedPrivateKey.CHAIN_CODE_SIZE=32;Class.register(ExtendedPrivateKey);class RandomSecret extends Serializable{constructor(e){super();if(!(e instanceof Uint8Array))throw new Error("Primitive: Invalid type");if(e.length!==RandomSecret.SIZE)throw new Error("Primitive: Invalid length");this._obj=e}static unserialize(e){return new RandomSecret(e.read(RandomSecret.SIZE))}serialize(e){(e=e||new SerialBuffer(this.serializedSize)).write(this._obj);return e}get serializedSize(){return RandomSecret.SIZE}equals(e){return e instanceof RandomSecret&&super.equals(e)}}RandomSecret.SIZE=32;Class.register(RandomSecret);class Signature extends Serializable{static copy(e){if(!e)return e;const t=new Uint8Array(e._obj);return new Signature(t)}constructor(e){super();if(!(e instanceof Uint8Array))throw new Error("Primitive: Invalid type");if(e.length!==Signature.SIZE)throw new Error("Primitive: Invalid length");this._obj=e}static create(e,t,s){return new Signature(Signature._signatureCreate(e._obj,t.compress(),s))}static fromPartialSignatures(e,t){const s=Signature._combinePartialSignatures(e.serialize(),t.map(e=>e.serialize()));return new Signature(s)}static unserialize(e){return new Signature(e.read(Signature.SIZE))}static fromAny(e){if(!e)throw new Error("Invalid signature format");if(e instanceof Signature)return e;try{return new Signature(BufferUtils.fromAny(e,Signature.SIZE))}catch(t){throw new Error("Invalid signature format")}}serialize(e){(e=e||new SerialBuffer(this.serializedSize)).write(this._obj);return e}get serializedSize(){return Signature.SIZE}verify(e,t){return Signature._signatureVerify(e.compress(),t,this._obj)}equals(e){return e instanceof Signature&&super.equals(e)}static _combinePartialSignatures(e,t){return Signature._aggregatePartialSignatures(t)}static _aggregatePartialSignatures(e){return e.reduce((e,t)=>{if(!e)return t;const s=e.slice(0,PartialSignature.HALF_SIZE),r=e.slice(PartialSignature.HALF_SIZE),n=t.slice(PartialSignature.HALF_SIZE),i=Signature._scalarsAdd(r,n);return BufferUtils.concatTypedArrays(s,i)})}static _scalarsAdd(e,t){if(e.byteLength!==PartialSignature.HALF_SIZE||t.byteLength!==PartialSignature.HALF_SIZE)throw Error("Wrong buffer size.");if(PlatformUtils.isNodeJs()){const s=new Uint8Array(PartialSignature.HALF_SIZE);NodeNative.node_secp256k1_add_scalars(s,new Uint8Array(e),new Uint8Array(t));return s}{let r;try{r=Module.stackSave();const n=Module.stackAlloc(PartialSignature.HALF_SIZE),i=Module.stackAlloc(e.length),o=Module.stackAlloc(t.length);new Uint8Array(Module.HEAPU8.buffer,i,e.length).set(e);new Uint8Array(Module.HEAPU8.buffer,o,t.length).set(t);Module._secp256k1_add_scalars(n,i,o);const a=new Uint8Array(PartialSignature.HALF_SIZE);a.set(new Uint8Array(Module.HEAPU8.buffer,n,PartialSignature.HALF_SIZE));return a}catch(s){Log.w(Signature,s);throw s}finally{r!==undefined&&Module.stackRestore(r)}}}static _signatureCreate(e,t,s){if(e.byteLength!==PrivateKey.SIZE||t.byteLength!=PublicKey.COMPRESSED_SIZE)throw Error("Wrong buffer size.");const r=new Uint8Array(32);CryptoWorker.lib.getRandomValues(r);if(PlatformUtils.isNodeJs()){NodeNative.node_secp256k1_ctx_init(r);const n=new Uint8Array(Signature.SIZE);NodeNative.node_secp256k1_schnorr_sign(n,new Uint8Array(s),new Uint8Array(t),new Uint8Array(e));NodeNative.node_secp256k1_ctx_release();return n}{let i;try{i=Module.stackSave();const o=Module.stackAlloc(32);new Uint8Array(Module.HEAP8.buffer,o,32).set(r);Module._secp256k1_ctx_init(o);const a=Module.stackAlloc(Signature.SIZE),c=new Uint8Array(Module.HEAP8.buffer,a,Signature.SIZE),h=Module.stackAlloc(s.length);new Uint8Array(Module.HEAP8.buffer,h,s.length).set(s);const l=Module.stackAlloc(t.length);new Uint8Array(Module.HEAP8.buffer,l,t.length).set(t);const u=Module.stackAlloc(e.length),d=new Uint8Array(Module.HEAP8.buffer,u,e.length);d.set(e);Module._secp256k1_schnorr_sign(a,h,s.byteLength,l,u);d.fill(0);const _=new Uint8Array(Signature.SIZE);_.set(c);return _}catch(n){Log.w(Signature,n);throw n}finally{Module._secp256k1_ctx_release();i!==undefined&&Module.stackRestore(i)}}}static _signatureVerify(e,t,s){const r=new Uint8Array(32);CryptoWorker.lib.getRandomValues(r);if(PlatformUtils.isNodeJs()){NodeNative.node_secp256k1_ctx_init(r);const n=!!NodeNative.node_secp256k1_schnorr_verify(new Uint8Array(s),new Uint8Array(t),new Uint8Array(e));NodeNative.node_secp256k1_ctx_release();return n}{let i;try{i=Module.stackSave();const o=Module.stackAlloc(32);new Uint8Array(Module.HEAP8.buffer,o,32).set(r);Module._secp256k1_ctx_init(o);const a=Module.stackAlloc(e.length);new Uint8Array(Module.HEAP8.buffer,a,e.length).set(e);const c=Module.stackAlloc(t.length);new Uint8Array(Module.HEAP8.buffer,c,t.length).set(t);const h=Module.stackAlloc(s.length);new Uint8Array(Module.HEAP8.buffer,h,s.length).set(s);return!!Module._secp256k1_schnorr_verify(h,c,t.byteLength,a)}catch(n){Log.w(Signature,n);throw n}finally{Module._secp256k1_ctx_release();i!==undefined&&Module.stackRestore(i)}}}}Signature.SIZE=64;Class.register(Signature);class Commitment extends Serializable{static copy(e){return e?new Commitment(new Uint8Array(e._obj)):e}static sum(e){return new Commitment(Commitment._commitmentsAggregate(e.map(e=>e._obj)))}constructor(e){super();if(!(e instanceof Uint8Array))throw new Error("Primitive: Invalid type");if(e.length!==Commitment.SIZE)throw new Error("Primitive: Invalid length");this._obj=e}compress(){return PublicKey._compressPublicKey(this._obj)}static unserialize(e){return new Commitment(e.read(Commitment.SIZE))}serialize(e){(e=e||new SerialBuffer(this.serializedSize)).write(this._obj);return e}get serializedSize(){return Commitment.SIZE}equals(e){return e instanceof Commitment&&super.equals(e)}static _commitmentsAggregate(e){if(e.some(e=>e.byteLength!==Commitment.SIZE))throw Error("Wrong buffer size.");const t=new Uint8Array(e.length*Commitment.SIZE);for(let r=0;r<e.length;++r)t.set(e[r],r*Commitment.SIZE);if(PlatformUtils.isNodeJs()){const s=new Uint8Array(Commitment.SIZE);NodeNative.node_secp256k1_aggregate_commitments(s,t,e.length,Commitment.SIZE);return s}{let r;try{r=Module.stackSave();const n=Module.stackAlloc(Commitment.SIZE),i=Module.stackAlloc(t.length);new Uint8Array(Module.HEAPU8.buffer,i,t.length).set(t);Module._secp256k1_aggregate_commitments(n,i,e.length,Commitment.SIZE);const o=new Uint8Array(Commitment.SIZE);o.set(new Uint8Array(Module.HEAPU8.buffer,n,Commitment.SIZE));return o}catch(s){Log.w(CryptoWorkerImpl,s);throw s}finally{r!==undefined&&Module.stackRestore(r)}}}}Commitment.COMPRESSED_SIZE=33;Commitment.SIZE=65;Class.register(Commitment);class CommitmentPair extends Serializable{constructor(e,t){super();if(!(e instanceof RandomSecret))throw new Error("Primitive: Invalid type");if(!(t instanceof Commitment))throw new Error("Primitive: Invalid type");this._secret=e;this._commitment=t}static generate(){const e=new Uint8Array(CommitmentPair.RANDOMNESS_SIZE);CryptoWorker.lib.getRandomValues(e);const t=CommitmentPair._commitmentCreate(e);return new CommitmentPair(new RandomSecret(t.secret),new Commitment(t.commitment))}static unserialize(e){const t=RandomSecret.unserialize(e),s=Commitment.unserialize(e);return new CommitmentPair(t,s)}static fromHex(e){return this.unserialize(BufferUtils.fromHex(e))}serialize(e){e=e||new SerialBuffer(this.serializedSize);this.secret.serialize(e);this.commitment.serialize(e);return e}get secret(){return this._secret}get commitment(){return this._commitment}get serializedSize(){return this.secret.serializedSize+this.commitment.serializedSize}equals(e){return e instanceof CommitmentPair&&super.equals(e)}static _commitmentCreate(e){const t=new Uint8Array(32);CryptoWorker.lib.getRandomValues(t);if(PlatformUtils.isNodeJs()){NodeNative.node_secp256k1_ctx_init(t);const s=new Uint8Array(Commitment.SIZE),r=new Uint8Array(PrivateKey.SIZE);NodeNative.node_secp256k1_create_commitment(r,s,e);NodeNative.node_secp256k1_ctx_release();return{commitment:s,secret:r}}{let r;try{r=Module.stackSave();const n=Module.stackAlloc(32);new Uint8Array(Module.HEAP8.buffer,n,32).set(t);Module._secp256k1_ctx_init(n);const i=Module.stackAlloc(Commitment.SIZE),o=Module.stackAlloc(PrivateKey.SIZE),a=Module.stackAlloc(e.length);new Uint8Array(Module.HEAPU8.buffer,a,e.length).set(e);const c=Module._secp256k1_create_commitment(o,i,Commitment.SIZE,a);if(1!==c)throw new Error(`Secret must not be 0 or 1: ${c}`);const h=new Uint8Array(Commitment.SIZE),l=new Uint8Array(PrivateKey.SIZE);h.set(new Uint8Array(Module.HEAPU8.buffer,i,Commitment.SIZE));l.set(new Uint8Array(Module.HEAPU8.buffer,o,PrivateKey.SIZE));return{commitment:h,secret:l}}catch(s){Log.w(CommitmentPair,s);throw s}finally{Module._secp256k1_ctx_release();r!==undefined&&Module.stackRestore(r)}}}}CommitmentPair.SERIALIZED_SIZE=RandomSecret.SIZE+Signature.SIZE;CommitmentPair.RANDOMNESS_SIZE=32;Class.register(CommitmentPair);class PartialSignature extends Serializable{constructor(e){super();if(!(e instanceof Uint8Array))throw new Error("Primitive: Invalid type");if(e.length!==PartialSignature.SIZE)throw new Error("Primitive: Invalid length");this._obj=e}static create(e,t,s,r,n,i){const o=PartialSignature._delinearizedPartialSignatureCreate(s.map(e=>e.compress()),e._obj,t.compress(),r._obj,n.compress(),i);return new PartialSignature(o)}static unserialize(e){return new PartialSignature(e.read(PartialSignature.SIZE))}serialize(e){(e=e||new SerialBuffer(this.serializedSize)).write(this._obj);return e}get serializedSize(){return PartialSignature.SIZE}equals(e){return e instanceof PartialSignature&&super.equals(e)}static _delinearizedPartialSignatureCreate(e,t,s,r,n,i){if(e.some(e=>e.byteLength!==PublicKey.COMPRESSED_SIZE)||t.byteLength!==PrivateKey.SIZE||s.byteLength!==PublicKey.COMPRESSED_SIZE||r.byteLength!==RandomSecret.SIZE||n.byteLength!==Commitment.COMPRESSED_SIZE)throw Error("Wrong buffer size.");const o=new Uint8Array(32);CryptoWorker.lib.getRandomValues(o);const a=new Uint8Array(e.length*PublicKey.COMPRESSED_SIZE);for(let h=0;h<e.length;++h)a.set(e[h],h*PublicKey.COMPRESSED_SIZE);if(PlatformUtils.isNodeJs()){NodeNative.node_secp256k1_ctx_init(o);const c=new Uint8Array(PartialSignature.SIZE);NodeNative.node_secp256k1_partial_sign(c,new Uint8Array(i),new Uint8Array(n),new Uint8Array(r),new Uint8Array(a),e.length,new Uint8Array(s),new Uint8Array(t));NodeNative.node_secp256k1_ctx_release();return c}{let h;try{h=Module.stackSave();const l=Module.stackAlloc(32);new Uint8Array(Module.HEAP8.buffer,l,32).set(o);Module._secp256k1_ctx_init(l);const u=Module.stackAlloc(PartialSignature.SIZE),d=Module.stackAlloc(a.length),_=Module.stackAlloc(t.length),f=Module.stackAlloc(s.length),g=Module.stackAlloc(r.length),p=Module.stackAlloc(n.length),y=Module.stackAlloc(i.length);new Uint8Array(Module.HEAPU8.buffer,d,a.length).set(a);new Uint8Array(Module.HEAPU8.buffer,_,t.length).set(t);new Uint8Array(Module.HEAPU8.buffer,f,s.length).set(s);new Uint8Array(Module.HEAPU8.buffer,g,r.length).set(r);new Uint8Array(Module.HEAPU8.buffer,p,n.length).set(n);new Uint8Array(Module.HEAPU8.buffer,y,i.length).set(i);Module._secp256k1_partial_sign(u,y,i.length,p,g,d,e.length,f,_);const C=new Uint8Array(PartialSignature.SIZE);C.set(new Uint8Array(Module.HEAPU8.buffer,u,PartialSignature.SIZE));return C}catch(c){Log.w(CryptoWorkerImpl,c);throw c}finally{Module._secp256k1_ctx_release();h!==undefined&&Module.stackRestore(h)}}}}PartialSignature.HALF_SIZE=32;PartialSignature.SIZE=64;Class.register(PartialSignature);class Address extends Serializable{static copy(e){if(!e)return e;const t=new Uint8Array(e._obj);return new Address(t)}static fromHash(e){return new Address(e.subarray(-Address.SERIALIZED_SIZE))}constructor(e){super();if(!(e instanceof Uint8Array))throw new Error("Primitive: Invalid type");if(e.length!==Address.SERIALIZED_SIZE)throw new Error("Primitive: Invalid length");this._obj=e}static unserialize(e){return new Address(e.read(Address.SERIALIZED_SIZE))}serialize(e){(e=e||new SerialBuffer(this.serializedSize)).write(this._obj);return e}subarray(e,t){return this._obj.subarray(e,t)}get serializedSize(){return Address.SERIALIZED_SIZE}equals(e){return e instanceof Address&&super.equals(e)}static fromAny(e){if(e instanceof Address)return e;if("string"==typeof e)return Address.fromString(e);throw new Error("Invalid address format")}toPlain(){return this.toUserFriendlyAddress()}static fromString(e){try{return Address.fromUserFriendlyAddress(e)}catch(t){}try{return Address.fromHex(e)}catch(t){}try{return Address.fromBase64(e)}catch(t){}throw new Error("Invalid address format")}static fromBase64(e){return new Address(BufferUtils.fromBase64(e))}static fromHex(e){return new Address(BufferUtils.fromHex(e))}static fromBech32(e){if(!this.isBech32Address(e))throw new Error("Invalid Bech32 Address");return new Address(Bech32.fromBech32(e))}static fromUserFriendlyAddress(e){return Address.fromHex(e)}toBech32(){return Bech32.toBech32(this.serialize())}toUserFriendlyAddress(e=!0){return this.toHex()}static isBech32Address(e){return Bech32.isBech32Address(e)}}Address.SERIALIZED_SIZE=20;Address.HEX_SIZE=40;Address.NULL=new Address(new Uint8Array(Address.SERIALIZED_SIZE));Address.CONTRACT_CREATION=new Address(new Uint8Array(Address.SERIALIZED_SIZE));Class.register(Address);class Bech32{static polymod(e){let t=1;for(let s=0;s<e.length;++s){const r=t>>25;t=(33554431&t)<<5^e[s];for(let e=0;e<5;++e)r>>e&1&&(t^=Bech32.GENERATOR[e])}return t}static hrpExpand(e){const t=[];let s;for(s=0;s<e.length;++s)t.push(e.charCodeAt(s)>>5);t.push(0);for(s=0;s<e.length;++s)t.push(31&e.charCodeAt(s));return SerialBuffer.from(t)}static verifyChecksum(e,t){return Bech32.polymod(SerialBuffer.concat([Bech32.hrpExpand(e),t]))===Bech32.ENCODING}static createChecksum(e,t){const s=SerialBuffer.concat([Bech32.hrpExpand(e),t,SerialBuffer.from([0,0,0,0,0,0])]),r=Bech32.polymod(s)^Bech32.ENCODING,n=[];for(let i=0;i<6;++i)n.push(r>>5*(5-i)&31);return SerialBuffer.from(n)}static bech32Encode(e,t){const s=SerialBuffer.concat([t,Bech32.createChecksum(e,t)]);let r=e+"1";for(let n=0;n<s.length;++n)r+=Bech32.CHARSET.charAt(s[n]);return r}static bech32Decode(e){let t,s=!1,r=!1;for(t=0;t<e.length;++t){if(e.charCodeAt(t)<33||e.charCodeAt(t)>126)return null;e.charCodeAt(t)>=97&&e.charCodeAt(t)<=122&&(s=!0);e.charCodeAt(t)>=65&&e.charCodeAt(t)<=90&&(r=!0)}if(s&&r)return null;const n=(e=e.toLowerCase()).lastIndexOf("1");if(n<1||n+7>e.length||e.length>90)return null;const i=e.substring(0,n),o=[];for(t=n+1;t<e.length;++t){const s=Bech32.CHARSET.indexOf(e.charAt(t));if(-1===s)return null;o.push(s)}return Bech32.verifyChecksum(i,SerialBuffer.from(o))?{hrp:i,data:SerialBuffer.from(o.slice(0,o.length-6))}:null}static convertBits(e,t,s,r=!0){let n=0,i=0;const o=[],a=(1<<s)-1;for(let c=0;c<e.length;++c){const r=e[c];if(r<0||r>>t!=0)return null;n=n<<t|r;i+=t;for(;i>=s;){i-=s;o.push(n>>i&a)}}if(r)i>0&&o.push(n<<s-i&a);else if(i>=t||n<<s-i&a)return null;return SerialBuffer.from(o)}static toBech32(e,t=Bech32.HRP){const s=Bech32.convertBits(SerialBuffer.from(e),8,5);if(null===s)throw new Error("Could not convert byte Buffer to 5-bit Buffer");return Bech32.bech32Encode(t,SerialBuffer.concat([SerialBuffer.from([0]),s]))}static fromBech32(e,t=Bech32.HRP){const s=Bech32.bech32Decode(e);if(null===s)throw new Error("Invalid bech32 address");const{hrp:r,data:n}=s;if(r!==t)throw new Error(`Expected hrp to be ${t} but got ${r}`);const i=Bech32.convertBits(n.slice(1),5,8,!1);if(null===i)throw new Error("Could not convert buffer to bytes");return new SerialBuffer(i)}static isBech32Address(e){return!!e.match(/^bc1[qpzry9x8gf2tvdw0s3jn54khce6mua7l]{39}/)}}Bech32.ENCODING=1;Bech32.HRP="bc";Bech32.CHARSET="qpzry9x8gf2tvdw0s3jn54khce6mua7l";Bech32.GENERATOR=[996825010,642813549,513874426,1027748829,705979059];Class.register(Bech32);class Account{constructor(e,t){const s=new BigNumber(t);if(!NumberUtils.isUint8(e))throw new Error("Malformed type");if(!NumberUtils.isUint128(s))throw new Error("Malformed balance");this._type=e;this._balance=s}static unserialize(e){const t=e.readUint8();e.readPos--;if(!Account.TYPE_MAP.has(t))throw new Error("Unknown account type");return Account.TYPE_MAP.get(t).unserialize(e)}serialize(e){(e=e||new SerialBuffer(this.serializedSize)).writeUint8(this._type);e.writeUint128(this._balance);return e}get serializedSize(){return 17}equals(e){return BufferUtils.equals(this.serialize(),e.serialize())}toString(){return`Account{type=${this._type}, balance=${this._balance.toString()}`}static fromAny(e){return e instanceof Account?e:Account.fromPlain(e)}static fromPlain(e){if(!e||e.type===undefined)throw new Error("Invalid account");const t=Account.Type.fromAny(e.type);return Account.TYPE_MAP.get(t).fromPlain(e)}toPlain(){return{type:Account.Type.toString(this.type),balance:this.balance.toString()}}get balance(){return this._balance}get type(){return this._type}withBalance(e){throw new Error("Not yet implemented.")}withOutgoingTransaction(e,t,s,r=!1){if(r){if(t<e.validityStartHeight||t>=e.validityStartHeight+Policy.TRANSACTION_VALIDITY_WINDOW)throw new Account.ValidityError;return this.withBalance(this._balance.plus(e.value).plus(e.fee))}{const r=this._balance.minus(e.value).minus(e.fee);if(r.lt(0))throw new Account.BalanceError;if(t<e.validityStartHeight||t>=e.validityStartHeight+Policy.TRANSACTION_VALIDITY_WINDOW)throw new Account.ValidityError;if(s.containsTransaction(e))throw new Account.DoubleTransactionError;return this.withBalance(r)}}withIncomingTransaction(e,t,s=!1){if(s){const t=this._balance.minus(e.value);if(t.lt(0))throw new Account.BalanceError;return this.withBalance(t)}return this.withBalance(this._balance.plus(e.value))}withContractCommand(e,t,s=!1){throw new Error("Not yet implemented")}isInitial(){return this===Account.INITIAL}isToBePruned(){return this._balance.eq(0)&&!this.isInitial()}static dataToPlain(e){return{}}static proofToPlain(e){return{}}}Account.Type={BASIC:0,VESTING:1,HTLC:2};Account.Type.toString=function(e){switch(e){case Account.Type.BASIC:return"basic";case Account.Type.VESTING:return"vesting";case Account.Type.HTLC:return"htlc"}throw new Error("Invalid account type")};Account.Type.fromAny=function(e){if("number"==typeof e)return e;switch(e){case"basic":return Account.Type.BASIC;case"vesting":return Account.Type.VESTING;case"htlc":return Account.Type.HTLC}throw new Error("Invalid account type")};Account.TYPE_MAP=new Map;Account.BalanceError=class extends Error{constructor(){super("Balance Error!")}};Account.DoubleTransactionError=class extends Error{constructor(){super("Double Transaction Error!")}};Account.ProofError=class extends Error{constructor(){super("Proof Error!")}};Account.ValidityError=class extends Error{constructor(){super("Validity Error!")}};Class.register(Account);class PrunedAccount{constructor(e,t){if(!(e instanceof Address))throw new Error("Malformed address");this._address=e;this._account=t}static unserialize(e){return new PrunedAccount(Address.unserialize(e),Account.unserialize(e))}static fromAny(e){return e instanceof PrunedAccount?e:PrunedAccount.fromPlain(e)}static fromPlain(e){return new PrunedAccount(Address.fromAny(e.address),Account.fromAny(e.account))}compare(e){return this._address.compare(e._address)}get address(){return this._address}get account(){return this._account}serialize(e){e=e||new SerialBuffer(this.serializedSize);this._address.serialize(e);this._account.serialize(e);return this}get serializedSize(){return this._address.serializedSize+this._account.serializedSize}hashCode(){return this._address.hashCode()}toPlain(){return{address:this.address.toPlain(),account:this.account.toPlain()}}}Class.register(PrunedAccount);class BasicAccount extends Account{static copy(e){return e?new BasicAccount(e._balance):e}constructor(e=0){super(Account.Type.BASIC,e)}static unserialize(e){if(e.readUint8()!==Account.Type.BASIC)throw new Error("Invalid account type");const t=e.readUint128();return new BasicAccount(t)}static fromPlain(e){if(!e)throw new Error("Invalid account");return new BasicAccount(e.balance)}equals(e){return e instanceof BasicAccount&&this._type===e._type&&this._balance.eq(e._balance)}toString(){return`BasicAccount{balance=${this._balance.toString()}}`}static verifyOutgoingTransaction(e){return SignatureProof.verifyTransaction(e)}static verifyIncomingTransaction(e){return!(e.data.byteLength>64)}withBalance(e){return new BasicAccount(e)}withIncomingTransaction(e,t,s=!1){if(!s){if(e.hasFlag(Transaction.Flag.CONTRACT_CREATION)!==(e.recipientType!==this._type))throw new Error("Data Error!")}return super.withIncomingTransaction(e,t,s)}withContractCommand(e,t,s=!1){return!s&&e.recipientType!==this._type&&e.hasFlag(Transaction.Flag.CONTRACT_CREATION)?Account.TYPE_MAP.get(e.recipientType).create(this._balance,t,e):this}isInitial(){return this._balance&&this._balance.eq(0)}static dataToPlain(e){return Account.dataToPlain(e)}static proofToPlain(e){try{const s=SignatureProof.unserialize(new SerialBuffer(e));return{signature:s.signature.toHex(),publicKey:s.publicKey.toHex(),signer:s.publicKey.toAddress().toPlain(),pathLength:s.merklePath.nodes.length}}catch(t){return Account.proofToPlain(e)}}}Account.INITIAL=new BasicAccount(0);Account.TYPE_MAP.set(Account.Type.BASIC,BasicAccount);Class.register(BasicAccount);class Contract extends Account{constructor(e,t){super(e,t)}static verifyIncomingTransaction(e){return!!e.recipient.equals(e.getContractCreationAddress())}withIncomingTransaction(e,t,s=!1){if(!s&&e.hasFlag(Transaction.Flag.CONTRACT_CREATION))throw new Error("Data error");return super.withIncomingTransaction(e,t,s)}withContractCommand(e,t,s=!1){return s&&e.hasFlag(Transaction.Flag.CONTRACT_CREATION)?new BasicAccount(this.balance):this}}Class.register(Contract);class HashedTimeLockedContract extends Contract{constructor(e=0,t=Address.NULL,s=Address.NULL,r=Hash.NULL,n=1,i=0,o=e){super(Account.Type.HTLC,e);const a=new BigNumber(o);if(!(t instanceof Address))throw new Error("Malformed sender address");if(!(s instanceof Address))throw new Error("Malformed recipient address");if(!(r instanceof Hash))throw new Error("Malformed hashRoot");if(!NumberUtils.isUint8(n)||0===n)throw new Error("Malformed hashCount");if(!NumberUtils.isUint32(i))throw new Error("Malformed timeout");if(!NumberUtils.isUint128(a))throw new Error("Malformed totalAmount");this._sender=t;this._recipient=s;this._hashRoot=r;this._hashCount=n;this._timeout=i;this._totalAmount=a}static create(e,t,s){const r=new SerialBuffer(s.data),n=Address.unserialize(r),i=Address.unserialize(r),o=r.readUint8(),a=Hash.unserialize(r,o),c=r.readUint8(),h=r.readUint32();return new HashedTimeLockedContract(e,n,i,a,c,h)}static unserialize(e){if(e.readUint8()!==Account.Type.HTLC)throw new Error("Invalid account type");const t=e.readUint128(),s=Address.unserialize(e),r=Address.unserialize(e),n=e.readUint8(),i=Hash.unserialize(e,n),o=e.readUint8(),a=e.readUint32(),c=e.readUint128();return new HashedTimeLockedContract(t,s,r,i,o,a,c)}static fromPlain(e){if(!e)throw new Error("Invalid account");return new HashedTimeLockedContract(e.balance,Address.fromAny(e.sender),Address.fromAny(e.recipient),Hash.fromAny(e.hashRoot,Hash.Algorithm.fromAny(e.hashAlgorithm)),e.hashCount,e.timeout,e.totalAmount)}serialize(e){e=e||new SerialBuffer(this.serializedSize);super.serialize(e);this._sender.serialize(e);this._recipient.serialize(e);e.writeUint8(this._hashRoot.algorithm);this._hashRoot.serialize(e);e.writeUint8(this._hashCount);e.writeUint32(this._timeout);e.writeUint128(this._totalAmount);return e}get serializedSize(){return super.serializedSize+this._sender.serializedSize+this._recipient.serializedSize+1+this._hashRoot.serializedSize+1+4+16}get sender(){return this._sender}get recipient(){return this._recipient}get hashAlgorithm(){return this._hashRoot.algorithm}get hashRoot(){return this._hashRoot}get hashCount(){return this._hashCount}get timeout(){return this._timeout}get totalAmount(){return this._totalAmount}toString(){return`HashedTimeLockedContract{balance=${this._balance.toString()}, sender=${this._sender.toUserFriendlyAddress(!1)}, recipient=${this._sender.toUserFriendlyAddress(!1)}, amount=${this._totalAmount.toString()}/${this._hashCount}, timeout=${this._timeout}}`}toPlain(){const e=super.toPlain();e.sender=this.sender.toPlain();e.recipient=this.recipient.toPlain();e.hashAlgorithm=Hash.Algorithm.toString(this.hashRoot.algorithm);e.hashRoot=this.hashRoot.toPlain();e.hashCount=this.hashCount;e.timeout=this.timeout;e.totalAmount=this.totalAmount.toString();return e}equals(e){return e instanceof HashedTimeLockedContract&&this._type===e._type&&this._balance.eq(e._balance)&&this._sender.equals(e._sender)&&this._recipient.equals(e._recipient)&&this._hashRoot.equals(e._hashRoot)&&this._hashCount===e._hashCount&&this._timeout===e._timeout&&this._totalAmount.eq(e._totalAmount)}static verifyOutgoingTransaction(e){try{const s=new SerialBuffer(e.proof);switch(s.readUint8()){case HashedTimeLockedContract.ProofType.REGULAR_TRANSFER:{const t=s.readUint8(),r=s.readUint8(),n=Hash.unserialize(s,t);let i=Hash.unserialize(s,t);for(let e=0;e<r;++e)i=Hash.compute(i.array,t);if(!n.equals(i))return!1;if(!SignatureProof.unserialize(s).verify(null,e.serializeContent()))return!1;break}case HashedTimeLockedContract.ProofType.EARLY_RESOLVE:if(!SignatureProof.unserialize(s).verify(null,e.serializeContent()))return!1;if(!SignatureProof.unserialize(s).verify(null,e.serializeContent()))return!1;break;case HashedTimeLockedContract.ProofType.TIMEOUT_RESOLVE:if(!SignatureProof.unserialize(s).verify(null,e.serializeContent()))return!1;break;default:return!1}return s.readPos===s.byteLength}catch(t){return!1}}static verifyIncomingTransaction(e){try{const s=new SerialBuffer(e.data);Address.unserialize(s);Address.unserialize(s);const r=s.readUint8();Hash.unserialize(s,r);const n=s.readUint8();s.readUint32();return 0!==n&&(r!==Hash.Algorithm.ARGON2D&&(s.readPos===s.byteLength&&Contract.verifyIncomingTransaction(e)))}catch(t){return!1}}withBalance(e){return new HashedTimeLockedContract(e,this._sender,this._recipient,this._hashRoot,this._hashCount,this._timeout,this._totalAmount)}withOutgoingTransaction(e,t,s,r=!1){const n=new SerialBuffer(e.proof);let i=0;switch(n.readUint8()){case HashedTimeLockedContract.ProofType.REGULAR_TRANSFER:{if(this._timeout<t)throw new Account.ProofError;const e=n.readUint8(),s=n.readUint8();if(!Hash.unserialize(n,e).equals(this._hashRoot))throw new Account.ProofError;Hash.unserialize(n,e);if(!SignatureProof.unserialize(n).isSignedBy(this._recipient))throw new Account.ProofError;i=BigNumber.max(0,this._totalAmount.times(1-s/this._hashCount).idiv(1));break}case HashedTimeLockedContract.ProofType.EARLY_RESOLVE:if(!SignatureProof.unserialize(n).isSignedBy(this._recipient))throw new Account.ProofError;if(!SignatureProof.unserialize(n).isSignedBy(this._sender))throw new Account.ProofError;break;case HashedTimeLockedContract.ProofType.TIMEOUT_RESOLVE:if(this._timeout>=t)throw new Account.ProofError;if(!SignatureProof.unserialize(n).isSignedBy(this._sender))throw new Account.ProofError;break;default:throw new Account.ProofError}if(!r){if(this._balance.minus(e.value).minus(e.fee).lt(i))throw new Account.BalanceError}return super.withOutgoingTransaction(e,t,s,r)}withIncomingTransaction(e,t,s=!1){throw new Error("Illegal incoming transaction")}static dataToPlain(e){try{const s=new SerialBuffer(e),r=Address.unserialize(s),n=Address.unserialize(s),i=s.readUint8(),o=Hash.unserialize(s,i),a=s.readUint8(),c=s.readUint32();return{sender:r.toPlain(),recipient:n.toPlain(),hashAlgorithm:Hash.Algorithm.toString(i),hashRoot:o.toPlain(),hashCount:a,timeout:c}}catch(t){return Account.dataToPlain(e)}}static proofToPlain(e){try{const s=new SerialBuffer(e),r=s.readUint8();switch(r){case HashedTimeLockedContract.ProofType.REGULAR_TRANSFER:{const e=s.readUint8(),t=s.readUint8(),n=Hash.unserialize(s,e),i=Hash.unserialize(s,e),o=SignatureProof.unserialize(s);return{type:HashedTimeLockedContract.ProofType.toString(r),hashAlgorithm:Hash.Algorithm.toString(e),hashDepth:t,hashRoot:n.toPlain(),preImage:i.toPlain(),signer:o.publicKey.toAddress().toPlain(),signature:o.signature.toHex(),publicKey:o.publicKey.toHex(),pathLength:o.merklePath.nodes.length}}case HashedTimeLockedContract.ProofType.EARLY_RESOLVE:{const e=SignatureProof.unserialize(s),t=SignatureProof.unserialize(s);return{type:HashedTimeLockedContract.ProofType.toString(r),signer:e.publicKey.toAddress().toPlain(),signature:e.signature.toHex(),publicKey:e.publicKey.toHex(),pathLength:e.merklePath.nodes.length,creator:t.publicKey.toAddress().toPlain(),creatorSignature:t.signature.toHex(),creatorPublicKey:t.publicKey.toHex(),creatorPathLength:t.merklePath.nodes.length}}case HashedTimeLockedContract.ProofType.TIMEOUT_RESOLVE:{const e=SignatureProof.unserialize(s);return{type:HashedTimeLockedContract.ProofType.toString(r),creator:e.publicKey.toAddress().toPlain(),creatorSignature:e.signature.toHex(),creatorPublicKey:e.publicKey.toHex(),creatorPathLength:e.merklePath.nodes.length}}default:return!1}}catch(t){return Account.proofToPlain(e)}}}HashedTimeLockedContract.ProofType={REGULAR_TRANSFER:1,EARLY_RESOLVE:2,TIMEOUT_RESOLVE:3};HashedTimeLockedContract.ProofType.toString=function(e){switch(e){case HashedTimeLockedContract.ProofType.REGULAR_TRANSFER:return"regular-transfer";case HashedTimeLockedContract.ProofType.EARLY_RESOLVE:return"early-resolve";case HashedTimeLockedContract.ProofType.TIMEOUT_RESOLVE:return"timeout-resolve"}throw new Error("Invalid proof type")};Account.TYPE_MAP.set(Account.Type.HTLC,HashedTimeLockedContract);Class.register(HashedTimeLockedContract);class VestingContract extends Contract{constructor(e=0,t=Address.NULL,s=0,r=0,n=e,i=e){super(Account.Type.VESTING,e);const o=new BigNumber(n),a=new BigNumber(i);if(!(t instanceof Address))throw new Error("Malformed owner address");if(!NumberUtils.isUint32(s))throw new Error("Malformed vestingStart");if(!NumberUtils.isUint32(r))throw new Error("Malformed vestingStepBlocks");if(!NumberUtils.isUint128(o))throw new Error("Malformed vestingStepAmount");if(!NumberUtils.isUint128(a))throw new Error("Malformed vestingTotalAmount");this._owner=t;this._vestingStart=s;this._vestingStepBlocks=r;this._vestingStepAmount=o;this._vestingTotalAmount=a}static create(e,t,s){let r,n,i,o;const a=new SerialBuffer(s.data),c=Address.unserialize(a);o=s.value;switch(s.data.length){case Address.SERIALIZED_SIZE+4:r=0;n=a.readUint32();i=o;break;case Address.SERIALIZED_SIZE+24:r=a.readUint32();n=a.readUint32();i=a.readUint128();break;case Address.SERIALIZED_SIZE+40:r=a.readUint32();n=a.readUint32();i=a.readUint128();o=a.readUint128();break;default:throw new Error("Invalid transaction data")}return new VestingContract(e,c,r,n,i,o)}static unserialize(e){if(e.readUint8()!==Account.Type.VESTING)throw new Error("Invalid account type");const t=e.readUint128(),s=Address.unserialize(e),r=e.readUint32(),n=e.readUint32(),i=e.readUint128(),o=e.readUint128();return new VestingContract(t,s,r,n,i,o)}static fromPlain(e){if(!e)throw new Error("Invalid account");return new VestingContract(e.balance,Address.fromAny(e.owner),e.vestingStart,e.vestingStepBlocks,e.vestingStepAmount,e.vestingTotalAmount)}serialize(e){e=e||new SerialBuffer(this.serializedSize);super.serialize(e);this._owner.serialize(e);e.writeUint32(this._vestingStart);e.writeUint32(this._vestingStepBlocks);e.writeUint128(this._vestingStepAmount);e.writeUint128(this._vestingTotalAmount);return e}get serializedSize(){return super.serializedSize+this._owner.serializedSize+4+4+16+16}get owner(){return this._owner}get vestingStart(){return this._vestingStart}get vestingStepBlocks(){return this._vestingStepBlocks}get vestingStepAmount(){return this._vestingStepAmount}get vestingTotalAmount(){return this._vestingTotalAmount}toString(){return`VestingAccount{balance=${this._balance.toString()}, owner=${this._owner.toUserFriendlyAddress()}`}toPlain(){const e=super.toPlain();e.owner=this.owner.toPlain();e.vestingStart=this.vestingStart;e.vestingStepBlocks=this.vestingStepBlocks;e.vestingStepAmount=this.vestingStepAmount.toString();e.vestingTotalAmount=this.vestingTotalAmount.toString();return e}equals(e){return e instanceof VestingContract&&this._type===e._type&&this._balance.eq(e._balance)&&this._owner.equals(e._owner)&&this._vestingStart===e._vestingStart&&this._vestingStepBlocks===e._vestingStepBlocks&&this._vestingStepAmount.eq(e._vestingStepAmount)&&this._vestingTotalAmount.eq(e._vestingTotalAmount)}static verifyOutgoingTransaction(e){const t=new SerialBuffer(e.proof);return!!SignatureProof.unserialize(t).verify(null,e.serializeContent())&&t.readPos===t.byteLength}static verifyIncomingTransaction(e){switch(e.data.length){case Address.SERIALIZED_SIZE+4:case Address.SERIALIZED_SIZE+24:case Address.SERIALIZED_SIZE+40:return Contract.verifyIncomingTransaction(e);default:return!1}}withBalance(e){return new VestingContract(e,this._owner,this._vestingStart,this._vestingStepBlocks,this._vestingStepAmount,this._vestingTotalAmount)}withOutgoingTransaction(e,t,s,r=!1){if(!r){const s=this.getMinCap(t);if(this._balance.minus(e.value).minus(e.fee).lt(s))throw new Account.BalanceError;const r=new SerialBuffer(e.proof);if(!SignatureProof.unserialize(r).isSignedBy(this._owner))throw new Account.ProofError}return super.withOutgoingTransaction(e,t,s,r)}withIncomingTransaction(e,t,s=!1){throw new Error("Illegal incoming transaction")}getMinCap(e){return this._vestingStepBlocks&&this._vestingStepAmount.gt(0)?BigNumber.max(0,this._vestingTotalAmount.minus(this._vestingStepAmount.times(Math.floor((e-this._vestingStart)/this._vestingStepBlocks)))):new BigNumber(0)}static dataToPlain(e){try{let s,r,n,i;const o=new SerialBuffer(e),a=Address.unserialize(o);switch(e.length){case Address.SERIALIZED_SIZE+4:s=0;r=o.readUint32();break;case Address.SERIALIZED_SIZE+24:s=o.readUint32();r=o.readUint32();n=o.readUint128().toString();break;case Address.SERIALIZED_SIZE+40:s=o.readUint32();r=o.readUint32();n=o.readUint128().toString();i=o.readUint128().toString();break;default:throw new Error("Invalid transaction data")}return{owner:a.toPlain(),vestingStart:s,vestingStepBlocks:r,vestingStepAmount:n,vestingTotalAmount:i}}catch(t){return Account.dataToPlain(e)}}static proofToPlain(e){try{const s=SignatureProof.unserialize(new SerialBuffer(e));return{signature:s.signature.toHex(),publicKey:s.publicKey.toHex(),signer:s.publicKey.toAddress().toPlain(),pathLength:s.merklePath.nodes.length}}catch(t){return Account.proofToPlain(e)}}}Account.TYPE_MAP.set(Account.Type.VESTING,VestingContract);Class.register(VestingContract);class AccountsTreeNode{static terminalNode(e,t){return new AccountsTreeNode(AccountsTreeNode.TERMINAL,e,t)}static branchNode(e,t=[],s=[]){if(t.length!==s.length)throw new Error("Invalid list of children for branch node");return new AccountsTreeNode(AccountsTreeNode.BRANCH,e,t,s)}constructor(e,t="",s,r=[]){this._type=e;this._prefix=t;if(this.isBranch()){this._childrenSuffixes=s;this._childrenHashes=r}else{if(!this.isTerminal())throw`Invalid AccountsTreeNode type: ${e}`;this._account=s}}static isTerminalType(e){return e===AccountsTreeNode.TERMINAL}static isBranchType(e){return e===AccountsTreeNode.BRANCH}static unserialize(e){const t=e.readUint8(),s=e.readVarLengthString();if(AccountsTreeNode.isTerminalType(t)){const t=Account.unserialize(e);return AccountsTreeNode.terminalNode(s,t)}if(AccountsTreeNode.isBranchType(t)){const t=[],r=[],n=e.readUint8();for(let s=0;s<n;++s){const s=e.readVarLengthString(),n=Hash.unserialize(e),i=parseInt(s[0],16);t[i]=s;r[i]=n}return AccountsTreeNode.branchNode(s,t,r)}throw`Invalid AccountsTreeNode type: ${t}`}serialize(e){(e=e||new SerialBuffer(this.serializedSize)).writeUint8(this._type);e.writeVarLengthString(this._prefix);if(this.isTerminal())this._account.serialize(e);else{const t=this._childrenSuffixes.reduce((e,t)=>e+!!t,0);e.writeUint8(t);for(let s=0;s<this._childrenSuffixes.length;++s)if(this._childrenHashes[s]){e.writeVarLengthString(this._childrenSuffixes[s]);this._childrenHashes[s].serialize(e)}}return e}get serializedSize(){let e;if(this.isTerminal())e=this._account.serializedSize;else{e=1+this._childrenHashes.reduce((e,t,s)=>e+(t?t.serializedSize+SerialBuffer.varLengthStringSize(this._childrenSuffixes[s]):0),0)}return 1+SerialBuffer.varLengthStringSize(this._prefix)+e}getChildHash(e){return this._childrenHashes&&this._childrenHashes[this._getChildIndex(e)]}getChild(e){const t=this._childrenSuffixes&&this._childrenSuffixes[this._getChildIndex(e)];return t?this.prefix+t:t}withChild(e,t){const s=this._childrenSuffixes.slice()||[],r=this._childrenHashes.slice()||[];s[this._getChildIndex(e)]=e.substr(this.prefix.length);r[this._getChildIndex(e)]=t;return AccountsTreeNode.branchNode(this._prefix,s,r)}withoutChild(e){const t=this._childrenSuffixes.slice()||[],s=this._childrenHashes.slice()||[];delete t[this._getChildIndex(e)];delete s[this._getChildIndex(e)];return AccountsTreeNode.branchNode(this._prefix,t,s)}hasChildren(){return this._childrenSuffixes&&this._childrenSuffixes.some(e=>!!e)}hasSingleChild(){return this._childrenSuffixes&&1===this._childrenSuffixes.reduce((e,t)=>e+!!t,0)}getFirstChild(){if(!this._childrenSuffixes)return undefined;const e=this._childrenSuffixes.find(e=>!!e);return e?this.prefix+e:undefined}getLastChild(){if(!this._childrenSuffixes)return undefined;for(let e=this._childrenSuffixes.length-1;e>=0;--e)if(this._childrenSuffixes[e])return this.prefix+this._childrenSuffixes[e];return undefined}getChildren(){return this._childrenSuffixes?this._childrenSuffixes.filter(e=>!!e).map(e=>this.prefix+e):undefined}get account(){return this._account}get prefix(){return this._prefix}set prefix(e){this._prefix=e;this._hash=undefined}withAccount(e){return AccountsTreeNode.terminalNode(this._prefix,e)}hash(){this._hash||(this._hash=Hash.light(this.serialize()));return this._hash}isChildOf(e){return e.getChildren()&&e.getChildren().includes(this._prefix)}isTerminal(){return AccountsTreeNode.isTerminalType(this._type)}isBranch(){return AccountsTreeNode.isBranchType(this._type)}_getChildIndex(e){Assert.that(e.substr(0,this.prefix.length)===this.prefix,`Prefix ${e} is not a child of the current node ${this.prefix}`);return parseInt(e[this.prefix.length],16)}equals(e){if(!(e instanceof AccountsTreeNode))return!1;if(!Object.is(this.prefix,e.prefix))return!1;if(this.isTerminal())return e.isTerminal()&&e._account.equals(this._account);if(!e.isBranch())return!1;if(this._childrenSuffixes.length!==e._childrenSuffixes.length)return!1;if(e._childrenSuffixes.length!==e._childrenHashes.length)return!1;for(let t=0;t<this._childrenSuffixes.length;++t){const s=this._childrenHashes[t],r=e._childrenHashes[t];if(s){if(!r||!s.equals(r))return!1}else if(r)return!1;if(this._childrenSuffixes[t]!==e._childrenSuffixes[t])return!1}return!0}}AccountsTreeNode.BRANCH=0;AccountsTreeNode.TERMINAL=255;Class.register(AccountsTreeNode);class AccountsTreeStore{static initPersistent(e){e.createObjectStore("Accounts",{codec:new AccountsTreeStoreCodec})}static getPersistent(e){return new AccountsTreeStore(e.getObjectStore("Accounts"))}static createVolatile(){const e=JDB.JungleDB.createVolatileObjectStore();return new AccountsTreeStore(e)}constructor(e){this._store=e}get(e){return this._store.get(e)}async put(e){const t=e.prefix;await this._store.put(t,e);return t}async remove(e){const t=e.prefix;await this._store.remove(t);return t}getRootNode(){return this.get("")}async getTerminalNodes(e,t){const s=[];await this._store.keyStream(e=>{if(e.length===Address.HEX_SIZE){s.push(e);if(s.length===t)return!1}return!0},!0,JDB.KeyRange.lowerBound(e,!0));const r=[];for(const n of s)r.push(this._store.get(n));return Promise.all(r)}snapshot(e){const t=this._store.snapshot();e&&t.inherit(e._store);return new AccountsTreeStore(t)}transaction(e=!0){const t=this._store.transaction(e);return new AccountsTreeStore(t)}synchronousTransaction(e=!0){const t=this._store.synchronousTransaction(e);return new SynchronousAccountsTreeStore(t)}truncate(){return this._store.truncate()}commit(){return this._store.commit()}abort(){return this._store.abort()}get tx(){return this._store instanceof JDB.Transaction?this._store:undefined}}Class.register(AccountsTreeStore);class AccountsTreeStoreCodec{encode(e){return e.serialize()}decode(e,t){return AccountsTreeNode.unserialize(new SerialBuffer(e))}get valueEncoding(){return JDB.JungleDB.BINARY_ENCODING}}class SynchronousAccountsTreeStore extends AccountsTreeStore{constructor(e){super(e);this._syncStore=e}async preload(e){await this._syncStore.preload(e)}getSync(e,t=!0){return this._syncStore.getSync(e,{expectPresence:t})}putSync(e){const t=e.prefix;this._syncStore.putSync(t,e);return t}removeSync(e){const t=e.prefix;this._syncStore.removeSync(t);return t}getRootNodeSync(){return this.getSync("")}}Class.register(SynchronousAccountsTreeStore);class AccountsProof{constructor(e){if(!e||!Array.isArray(e)||!NumberUtils.isUint16(e.length)||e.some(e=>!(e instanceof AccountsTreeNode)))throw new Error("Malformed nodes");this._nodes=e;this._index=null}static unserialize(e){const t=e.readUint16(),s=[];for(let r=0;r<t;r++)s.push(AccountsTreeNode.unserialize(e));return new AccountsProof(s)}serialize(e){(e=e||new SerialBuffer(this.serializedSize)).writeUint16(this._nodes.length);for(const t of this._nodes)t.serialize(e);return e}get serializedSize(){let e=2;for(const t of this._nodes)e+=t.serializedSize;return e}verify(){const e=[];this._index=new HashMap;for(const t of this._nodes){if(t.isBranch()){let s;for(;s=e.pop();){if(!s.isChildOf(t)){e.push(s);break}{const e=s.hash();if(!t.getChildHash(s.prefix).equals(e)||t.getChild(s.prefix)!==s.prefix)return!1;this._index.put(e,s)}}}e.push(t)}return 1===e.length&&""===e[0].prefix&&e[0].isBranch()}getAccount(e){if(!this._index)throw new Error("AccountsProof must be verified before retrieving accounts. Call verify() first.");const t=this._nodes[this._nodes.length-1],s=e.toHex();return this._getAccount(t,s)}_getAccount(e,t){const s=StringUtils.commonPrefix(e.prefix,t);if(s.length!==e.prefix.length)return Account.INITIAL;if(s===t)return e.account;const r=e.getChildHash(t);if(r){const e=this._index.get(r);if(!e)throw new Error("Requested address not part of AccountsProof");return this._getAccount(e,t)}return Account.INITIAL}toString(){return`AccountsProof{length=${this.length}}`}root(){return this._nodes[this._nodes.length-1].hash()}get length(){return this._nodes.length}get nodes(){return this._nodes}}Class.register(AccountsProof);class AccountsTreeChunk{constructor(e,t){if(!e||!NumberUtils.isUint16(e.length)||e.some(e=>!(e instanceof AccountsTreeNode&&e.isTerminal())))throw new Error("Malformed nodes");this._nodes=e;this._proof=t}static unserialize(e){const t=e.readUint16(),s=[];for(let n=0;n<t;n++)s.push(AccountsTreeNode.unserialize(e));const r=AccountsProof.unserialize(e);return new AccountsTreeChunk(s,r)}serialize(e){(e=e||new SerialBuffer(this.serializedSize)).writeUint16(this._nodes.length);for(const t of this._nodes)t.serialize(e);this._proof.serialize(e);return e}get serializedSize(){let e=2;for(const t of this._nodes)e+=t.serializedSize;return e+=this._proof.serializedSize}verify(){if(!this._proof.verify())return!1;let e=null;for(let t=0;t<=this._nodes.length;++t){const s=t<this._nodes.length?this._nodes[t]:this.tail;if(e&&e>=s.prefix)return!1;e=s.prefix}return!0}toString(){return`AccountsTreeChunk{length=${this.length}}`}root(){return this._proof.root()}get terminalNodes(){return this._nodes.concat([this.tail])}get proof(){return this._proof}get head(){return this._nodes.length>0?this._nodes[0]:this.tail}get tail(){return this._proof.nodes[0]}get length(){return this._nodes.length+1}}AccountsTreeChunk.SIZE_MAX=5e3;AccountsTreeChunk.EMPTY=new AccountsTreeChunk([],new AccountsProof([]));Class.register(AccountsTreeChunk);class AccountsTree extends Observable{static async getPersistent(e){const t=AccountsTreeStore.getPersistent(e);return new AccountsTree(t)._init()}static async createVolatile(){const e=AccountsTreeStore.createVolatile();return new AccountsTree(e)._init()}constructor(e){super();this._store=e;this._synchronizer=new Synchronizer}async _init(){let e=await this._store.getRootNode();if(!e){e=AccountsTreeNode.branchNode("",[],[]);await this._store.put(e)}return this}put(e,t){return this._synchronizer.push(()=>this._put(e,t))}async _put(e,t){if(t.isInitial()&&!(await this.get(e)))return;const s=await this._store.getRootNode();Assert.that(!!s,"Corrupted store: Failed to fetch AccountsTree root node");const r=e.toHex();await this._insert(s,r,t,[])}async _insert(e,t,s,r){const n=StringUtils.commonPrefix(e.prefix,t);if(n.length!==e.prefix.length){const i=AccountsTreeNode.terminalNode(t,s),o=i.hash();await this._store.put(i);const a=AccountsTreeNode.branchNode(n).withChild(e.prefix,e.hash()).withChild(i.prefix,o),c=a.hash();await this._store.put(a);return this._updateKeys(a.prefix,c,r)}if(n===t){if(s.isInitial()){await this._store.remove(e);return this._prune(e.prefix,r)}const t=(e=e.withAccount(s)).hash();await this._store.put(e);return this._updateKeys(e.prefix,t,r)}const i=e.getChild(t);if(i){const n=await this._store.get(i);r.push(e);return this._insert(n,t,s,r)}const o=AccountsTreeNode.terminalNode(t,s),a=o.hash();await this._store.put(o);const c=(e=e.withChild(o.prefix,a)).hash();await this._store.put(e);return this._updateKeys(e.prefix,c,r)}async _prune(e,t){let s=t.length-1;for(;s>=0;--s){let r=t[s];if((r=r.withoutChild(e)).hasSingleChild()&&""!==r.prefix){await this._store.remove(r);const e=r.getFirstChild(),n=await this._store.get(e);await this._store.put(n);const i=n.hash();return this._updateKeys(n.prefix,i,t.slice(0,s))}if(r.hasChildren()||""===r.prefix){const e=r.hash();await this._store.put(r);return this._updateKeys(r.prefix,e,t.slice(0,s))}e=r.prefix}return undefined}async _updateKeys(e,t,s){let r=s.length-1;for(;r>=0;--r){let n=s[r];n=n.withChild(e,t);await this._store.put(n);t=n.hash();e=n.prefix}return t}async get(e){const t=await this._store.get(e.toHex());return t!==undefined?t.account:null}async getAccountsProof(e){const t=await this._store.getRootNode();Assert.that(!!t,"Corrupted store: Failed to fetch AccountsTree root node");const s=[];for(const n of e)s.push(n.toHex());s.sort();const r=[];await this._getAccountsProof(t,s,r);return new AccountsProof(r)}async _getAccountsProof(e,t,s){let r=!1;for(let n=0;n<t.length;){let i=t[n];if(StringUtils.commonPrefix(e.prefix,i).length!==e.prefix.length||e.prefix===i){r=!0;n++;continue}const o=e.getChild(i);if(o){const e=await this._store.get(o),a=[i];let c=n+1;for(;c<t.length&&t[c].startsWith(e.prefix);++c)a.push(t[c]);n=c;r=await this._getAccountsProof(e,a,s)||r}else{r=!0;n++}}r&&s.push(e);return r}async getChunk(e,t){const s=await this._store.getTerminalNodes(e,t),r=s.pop();let n;n=r?await this.getAccountsProof([Address.fromHex(r.prefix)]):await this.getAccountsProof([Address.fromHex("ffffffffffffffffffffffffffffffffffffffff")]);return new AccountsTreeChunk(s,n)}transaction(e=!0){return new AccountsTree(this._store.transaction(e))._init()}synchronousTransaction(e=!0){const t=this._store.synchronousTransaction(e);return new SynchronousAccountsTree(t)._init()}async partialTree(){const e=this._store.synchronousTransaction(!1);await e.truncate();return new PartialAccountsTree(e)._init()}snapshot(e){return new AccountsTree(this._store.snapshot(e?e._store:undefined))._init()}async commit(){Assert.that(!(await this.root()).equals(new Hash(null)));return this._store.commit()}abort(){return this._store.abort()}async root(){const e=await this._store.getRootNode();return e&&e.hash()}get tx(){return this._store.tx}async isEmpty(){return!(await this._store.getRootNode()).hasChildren()}}Class.register(AccountsTree);class SynchronousAccountsTree extends AccountsTree{constructor(e){super(e);this._syncStore=e}async preloadAddresses(e){const t=await this._syncStore.getRootNode();Assert.that(!!t,"Corrupted store: Failed to fetch AccountsTree root node");const s=[];for(const r of e)s.push(r.toHex());s.sort();await this._preloadAddresses(t,s)}async _preloadAddresses(e,t){e.hasChildren()&&await this._syncStore.preload(e.getChildren());for(let s=0;s<t.length;){const r=t[s];if(StringUtils.commonPrefix(e.prefix,r).length!==e.prefix.length||e.prefix===r){s++;continue}const n=e.getChild(r);if(n){const e=this._syncStore.getSync(n),i=[r];let o=s+1;for(;o<t.length&&t[o].startsWith(e.prefix);++o)i.push(t[o]);s=o;await this._preloadAddresses(e,i)}else s++}}putSync(e,t){this.putBatch(e,t);this.finalizeBatch()}finalizeBatch(){const e=this._syncStore.getRootNodeSync();this._updateHashes(e)}putBatch(e,t){if(t.isInitial()&&!this.getSync(e,!1))return;const s=this._syncStore.getRootNodeSync();Assert.that(!!s,"Corrupted store: Failed to fetch AccountsTree root node");const r=e.toHex();this._insertBatch(s,r,t,[])}_insertBatch(e,t,s,r){const n=StringUtils.commonPrefix(e.prefix,t);if(n.length!==e.prefix.length){const i=AccountsTreeNode.terminalNode(t,s);this._syncStore.putSync(i);const o=AccountsTreeNode.branchNode(n).withChild(e.prefix,new Hash(null)).withChild(i.prefix,new Hash(null));this._syncStore.putSync(o);return this._updateKeysBatch(o.prefix,r)}if(n===t){if(s.isInitial()){this._syncStore.removeSync(e);return this._pruneBatch(e.prefix,r)}e=e.withAccount(s);this._syncStore.putSync(e);return this._updateKeysBatch(e.prefix,r)}const i=e.getChild(t);if(i){const n=this._syncStore.getSync(i);r.push(e);return this._insertBatch(n,t,s,r)}const o=AccountsTreeNode.terminalNode(t,s);this._syncStore.putSync(o);e=e.withChild(o.prefix,new Hash(null));this._syncStore.putSync(e);return this._updateKeysBatch(e.prefix,r)}_pruneBatch(e,t){let s=t.length-1;for(;s>=0;--s){let r=t[s];if((r=r.withoutChild(e)).hasSingleChild()&&""!==r.prefix){this._syncStore.removeSync(r);const e=r.getFirstChild(),n=this._syncStore.getSync(e);this._syncStore.putSync(n);return this._updateKeysBatch(n.prefix,t.slice(0,s))}if(r.hasChildren()||""===r.prefix){this._syncStore.putSync(r);return this._updateKeysBatch(r.prefix,t.slice(0,s))}e=r.prefix}return undefined}_updateKeysBatch(e,t){let s=t.length-1;for(;s>=0;--s){let r=t[s];r=r.withChild(e,new Hash(null));this._syncStore.putSync(r);e=r.prefix}}_updateHashes(e){if(e.isTerminal())return e.hash();const t=new Hash(null),s=e.getChildren().map(s=>{const r=e.getChildHash(s);if(!r.equals(t))return r;const n=this._syncStore.getSync(s);return this._updateHashes(n)});let r=e;e.getChildren().forEach((e,t)=>{r=r.withChild(e,s[t])});this._syncStore.putSync(r);return r.hash()}getSync(e,t=!0){const s=this._syncStore.getSync(e.toHex(),t);return s!==undefined?s.account:null}rootSync(){const e=this._syncStore.getRootNodeSync();return e&&e.hash()}}Class.register(SynchronousAccountsTree);class PartialAccountsTree extends SynchronousAccountsTree{constructor(e){super(e);this._complete=!1;this._lastPrefix=""}async pushChunk(e){if(!e.verify())return PartialAccountsTree.Status.ERR_INCORRECT_PROOF;const t=this.synchronousTransaction();t._putLight(e.terminalNodes);if(!t._mergeProof(e.proof,e.tail.prefix)){await t.abort();return PartialAccountsTree.Status.ERR_UNMERGEABLE}this._complete=t.complete;await t.commit();this._lastPrefix=e.tail.prefix;return this._complete?PartialAccountsTree.Status.OK_COMPLETE:PartialAccountsTree.Status.OK_UNFINISHED}_mergeProof(e,t){let s=this._store.getRootNodeSync(),r=s.getChildren(),n=!0,i=e.length-1;for(;i>0;--i){const o=e.nodes[i];if(StringUtils.commonPrefix(s.prefix,o.prefix)!==s.prefix)return!1;const a=o.getChildren();if(r.length>a.length)return!1;const c=s.getLastChild();let h=!1,l=0;for(const e of a){if(!(e<=t.substr(0,e.length)))break;{const t=r.shift();if(StringUtils.commonPrefix(c,e)===e){e!==c&&(h=!0);continue}if(t!==e)return!1;const n=s.getChildHash(t),i=o.getChildHash(t);if(!n||!i||!n.equals(i))return!1}++l}if(0!==r.length)return!1;n=n&&l===a.length-1;if(h)r=[c];else{if(s.isTerminal())return!1;r=(s=this._store.getSync(s.getLastChild())).getChildren();if(s.isTerminal())break}}if(!s.equals(e.nodes[0]))return!1;this._complete=n;return!0}_putLight(e){Assert.that(e.every(e=>e.isTerminal()),"Can only build tree from terminal nodes");let t=this._store.getRootNodeSync();Assert.that(!!t,"Corrupted store: Failed to fetch AccountsTree root node");for(const s of e){this._insertBatch(t,s.prefix,s.account,[]);t=this._store.getRootNodeSync();Assert.that(!!t,"Corrupted store: Failed to fetch AccountsTree root node")}this._updateHashes(t)}get complete(){return this._complete}get missingPrefix(){return this._lastPrefix}synchronousTransaction(e=!0){const t=new PartialAccountsTree(this._store.synchronousTransaction(e));t._complete=this._complete;t._lastPrefix=this._lastPrefix;return t}transaction(e=!0){if(!this.complete)throw new Error("Can only construct AccountsTree from complete PartialAccountsTree");return new AccountsTree(this._store.synchronousTransaction(e))}commit(){return this._store.commit()}abort(){return this._store.abort()}}PartialAccountsTree.Status={ERR_HASH_MISMATCH:-3,ERR_INCORRECT_PROOF:-2,ERR_UNMERGEABLE:-1,OK_COMPLETE:0,OK_UNFINISHED:1};Class.register(PartialAccountsTree);class Accounts extends Observable{static async getPersistent(e){const t=await AccountsTree.getPersistent(e);return new Accounts(t)}static async createVolatile(){const e=await AccountsTree.createVolatile();return new Accounts(e)}constructor(e){super();this._tree=e;this.bubble(this._tree,"*")}async initialize(e,t){Assert.that(await this._tree.isEmpty());const s=await this._tree.synchronousTransaction();try{const r=BufferUtils.fromBase64(t),i=r.readUint16();for(let e=0;e<i;e++){const e=Address.unserialize(r),t=Account.unserialize(r);s.putSync(e,t)}await this._commitBlockBody(s,e.body,e.height,new TransactionCache);s.finalizeBatch()}catch(n){await s.abort();throw n}const r=s.rootSync();if(!e.accountsHash.equals(r)){await s.abort();throw new Error("Genesis AccountsHash mismatch")}return s.commit()}getAccountsProof(e){return this._tree.getAccountsProof(e)}getAccountsTreeChunk(e){return this._tree.getChunk(e,AccountsTreeChunk.SIZE_MAX)}async commitBlock(e,t){const s=await this._tree.synchronousTransaction();await s.preloadAddresses(e.body.getAddresses());try{this._commitBlockBody(s,e.body,e.height,t)}catch(n){await s.abort();throw n}s.finalizeBatch();const r=s.rootSync();if(!e.accountsHash.equals(r)){await s.abort();throw new Error("AccountsHash mismatch")}return s.commit()}async commitBlockBody(e,t,s){const r=await this._tree.synchronousTransaction();await r.preloadAddresses(e.getAddresses());try{this._commitBlockBody(r,e,t,s)}catch(n){await r.abort();throw n}r.finalizeBatch();return r.commit()}async gatherToBePrunedAccounts(e,t,s){const r=await this._tree.synchronousTransaction(),n=[];for(const i of e)n.push(i.sender,i.recipient);await r.preloadAddresses(n);try{this._processSenderAccounts(r,e,t,s);this._processRecipientAccounts(r,e,t);this._processContracts(r,e,t);const n=new HashSet;for(const t of e){const e=this._getSync(t.sender,undefined,r);e.isToBePruned()&&n.add(new PrunedAccount(t.sender,e))}return n.values().sort((e,t)=>e.compare(t))}finally{await r.abort()}}async revertBlock(e,t){if(!e)throw new Error("block undefined");const s=await this._tree.root();if(!e.accountsHash.equals(s))throw new Error("AccountsHash mismatch");return this.revertBlockBody(e.body,e.height,t)}async revertBlockBody(e,t,s){const r=await this._tree.synchronousTransaction();await r.preloadAddresses(e.getAddresses());try{this._revertBlockBody(r,e,t,s)}catch(n){await r.abort();throw n}r.finalizeBatch();return r.commit()}async get(e,t,s=this._tree){const r=await s.get(e);if(!r){if("undefined"==typeof t)return Account.INITIAL;throw new Error("Account type was given but account not present")}if("undefined"!=typeof t&&r.type!==t)throw new Error("Account type does match actual account");return r}_getSync(e,t,s){const r=s.getSync(e,!1);if(!r){if("undefined"==typeof t)return Account.INITIAL;throw new Error("Account type was given but account not present")}if("undefined"!=typeof t&&r.type!==t)throw new Error("Account type does match actual account");return r}async transaction(e=!0){return new Accounts(await this._tree.transaction(e))}async snapshot(e){return new Accounts(await this._tree.snapshot(e?e._tree:undefined))}partialAccountsTree(){return this._tree.partialTree()}commit(){return this._tree.commit()}abort(){return this._tree.abort()}_processSenderAccounts(e,t,s,r,n=!1){for(const i of t){const t=this._getSync(i.sender,n?undefined:i.senderType,e);e.putBatch(i.sender,t.withOutgoingTransaction(i,s,r,n))}}_processRecipientAccounts(e,t,s,r=!1){for(const n of t){const t=this._getSync(n.recipient,undefined,e);e.putBatch(n.recipient,t.withIncomingTransaction(n,s,r))}}_processContracts(e,t,s,r=!1){r&&(t=t.slice().reverse());for(const n of t){const t=this._getSync(n.recipient,r?n.recipientType:undefined,e);e.putBatch(n.recipient,t.withContractCommand(n,s,r))}}_commitBlockBody(e,t,s,r){this._processSenderAccounts(e,t.transactions,s,r);this._processRecipientAccounts(e,t.transactions,s);this._processContracts(e,t.transactions,s);const n=t.prunedAccounts.slice();for(const i of t.transactions){const t=this._getSync(i.sender,undefined,e);if(t.isToBePruned()){const s=n.findIndex(e=>e.address.equals(i.sender));if(-1===s||!t.equals(n[s].account))throw new Error("Account was not pruned correctly");e.putBatch(i.sender,Account.INITIAL);n.splice(s,1)}}if(n.length>0)throw new Error("Account was invalidly pruned");this._rewardMiner(e,t,s,!1)}_revertBlockBody(e,t,s,r){this._rewardMiner(e,t,s,!0);for(const n of t.prunedAccounts)e.putBatch(n.address,n.account);this._processContracts(e,t.transactions,s,!0);this._processRecipientAccounts(e,t.transactions,s,!0);this._processSenderAccounts(e,t.transactions,s,r,!0)}_rewardMiner(e,t,s,r=!1){const n=t.transactions.reduce((e,t)=>e.plus(t.fee),new BigNumber(0)),i=new ExtendedTransaction(Address.NULL,Account.Type.BASIC,t.minerAddr,Account.Type.BASIC,n.plus(Policy.blockRewardAt(s)),0,Transaction.Flag.NONE,new Uint8Array(0)),o=this._getSync(t.minerAddr,undefined,e);e.putBatch(t.minerAddr,o.withIncomingTransaction(i,s,r))}hash(){return this._tree.root()}get tx(){return this._tree.tx}}Class.register(Accounts);class BlockHeader{constructor(e,t,s,r,n,i,o,a,c=BlockHeader.CURRENT_VERSION){if(!NumberUtils.isUint16(c))throw new Error("Malformed version");if(!Hash.isHash(e))throw new Error("Malformed prevHash");if(!Hash.isHash(t))throw new Error("Malformed interlinkHash");if(!Hash.isHash(s))throw new Error("Malformed bodyHash");if(!Hash.isHash(r))throw new Error("Malformed accountsHash");if(!NumberUtils.isUint32(n)||!BlockUtils.isValidCompact(n))throw new Error("Malformed nBits");if(!NumberUtils.isUint32(i))throw new Error("Invalid height");if(!NumberUtils.isUint32(o))throw new Error("Malformed timestamp");if(!NumberUtils.isUint32(a))throw new Error("Malformed nonce");this._version=c;this._prevHash=e;this._interlinkHash=t;this._bodyHash=s;this._accountsHash=r;this._nBits=n;this._height=i;this._timestamp=o;this._nonce=a}static unserialize(e){const t=e.readUint16();if(!BlockHeader.SUPPORTED_VERSIONS.includes(t))throw new Error(`Unsupported block version ${t}`);const s=Hash.unserialize(e),r=Hash.unserialize(e),n=Hash.unserialize(e),i=Hash.unserialize(e),o=e.readUint32(),a=e.readUint32(),c=e.readUint32(),h=e.readUint32();return new BlockHeader(s,r,n,i,o,a,c,h,t)}serialize(e){(e=e||new SerialBuffer(this.serializedSize)).writeUint16(this._version);this._prevHash.serialize(e);this._interlinkHash.serialize(e);this._bodyHash.serialize(e);this._accountsHash.serialize(e);e.writeUint32(this._nBits);e.writeUint32(this._height);e.writeUint32(this._timestamp);e.writeUint32(this._nonce);return e}get serializedSize(){return 2+this._prevHash.serializedSize+this._interlinkHash.serializedSize+this._bodyHash.serializedSize+this._accountsHash.serializedSize+4+4+4+4}async verifyProofOfWork(e){const t=await this.pow(e);return BlockUtils.isProofOfWork(t,this.target)}isImmediateSuccessorOf(e){if(this.height!==e.height+1)return!1;if(this.timestamp<e.timestamp)return!1;const t=e.hash();return!!this.prevHash.equals(t)}hash(e){this._hash=this._hash||Hash.light(this.serialize(e));return this._hash}async pow(e){this._pow=this._pow||await Hash.hard(this.serialize(e));return this._pow}equals(e){return e instanceof BlockHeader&&this._prevHash.equals(e.prevHash)&&this._interlinkHash.equals(e.interlinkHash)&&this._bodyHash.equals(e.bodyHash)&&this._accountsHash.equals(e.accountsHash)&&this._nBits===e.nBits&&this._height===e.height&&this._timestamp===e.timestamp&&this._nonce===e.nonce}toString(){return"BlockHeader{"+`prevHash=${this._prevHash}, `+`interlinkHash=${this._interlinkHash}, `+`bodyHash=${this._bodyHash}, `+`accountsHash=${this._accountsHash}, `+`nBits=${this._nBits.toString(16)}, `+`height=${this._height}, `+`timestamp=${this._timestamp}, `+`nonce=${this._nonce}`+"}"}get version(){return this._version}get prevHash(){return this._prevHash}get interlinkHash(){return this._interlinkHash}get bodyHash(){return this._bodyHash}get accountsHash(){return this._accountsHash}get nBits(){return this._nBits}get target(){return BlockUtils.compactToTarget(this._nBits)}get difficulty(){return BlockUtils.compactToDifficulty(this._nBits)}get height(){return this._height}get timestamp(){return this._timestamp}get nonce(){return this._nonce}set nonce(e){this._nonce=e;this._hash=null;this._pow=null}}BlockHeader.Version={V1:1};BlockHeader.CURRENT_VERSION=BlockHeader.Version.V1;BlockHeader.SUPPORTED_VERSIONS=[BlockHeader.Version.V1];BlockHeader.SERIALIZED_SIZE=146;Class.register(BlockHeader);class BlockInterlink{static _compress(e,t){const s=e.length,r=Math.ceil(s/8),n=new Uint8Array(r);let i=t;const o=[];for(let a=0;a<s;a++){const t=e[a];if(t.equals(i))n[Math.floor(a/8)]|=128>>>a%8;else{o.push(t);i=t}}return{repeatBits:n,compressed:o}}constructor(e,t,s,r){if(!Array.isArray(e)||!NumberUtils.isUint8(e.length)||e.some(e=>!(e instanceof Hash)))throw new Error("Malformed hashes");if((s||r)&&(!s||!r))throw new Error("Malformed repeatBits/compressed");if(!t&&!s)throw new Error("Either prevHash or repeatBits/compressed required");s||({repeatBits:s,compressed:r}=BlockInterlink._compress(e,t));this._hashes=e;this._repeatBits=s;this._compressed=r}static unserialize(e,t){const s=e.readUint8(),r=Math.ceil(s/8),n=e.read(r);let i=t;const o=[],a=[];for(let c=0;c<s;c++){if(!(0!=(n[Math.floor(c/8)]&128>>>c%8))){i=Hash.unserialize(e);a.push(i)}o.push(i)}return new BlockInterlink(o,t,n,a)}serialize(e){(e=e||new SerialBuffer(this.serializedSize)).writeUint8(this._hashes.length);e.write(this._repeatBits);for(const t of this._compressed)t.serialize(e);return e}get serializedSize(){return 1+this._repeatBits.length+this._compressed.reduce((e,t)=>e+t.serializedSize,0)}equals(e){return e instanceof BlockInterlink&&this._hashes.length===e._hashes.length&&this._hashes.every((t,s)=>t.equals(e.hashes[s]))}hash(){this._hash||(this._hash=MerkleTree.computeRoot([this._repeatBits,GenesisConfig.GENESIS_HASH,...this._compressed]));return this._hash}get hashes(){return this._hashes}get length(){return this._hashes.length}}Class.register(BlockInterlink);class BlockBody{static getMetadataSize(e){return Address.SERIALIZED_SIZE+1+e.byteLength+2+2}constructor(e,t,s=new Uint8Array(0),r=[]){if(!(e instanceof Address))throw new Error("Malformed minerAddr");if(!Array.isArray(t)||t.some(e=>!(e instanceof Transaction)))throw new Error("Malformed transactions");if(!(s instanceof Uint8Array&&NumberUtils.isUint8(s.byteLength)))throw new Error("Malformed extraData");this._minerAddr=e;this._extraData=s;this._transactions=t;this._prunedAccounts=r;this._hash=null}static unserialize(e){const t=Address.unserialize(e),s=e.readUint8(),r=e.read(s),n=e.readUint16(),i=new Array(n);for(let c=0;c<n;c++)i[c]=Transaction.unserialize(e);const o=e.readUint16(),a=[];for(let c=0;c<o;c++)a.push(PrunedAccount.unserialize(e));return new BlockBody(t,i,r,a)}serialize(e){e=e||new SerialBuffer(this.serializedSize);this._minerAddr.serialize(e);e.writeUint8(this._extraData.byteLength);e.write(this._extraData);e.writeUint16(this._transactions.length);for(const t of this._transactions)t.serialize(e);e.writeUint16(this._prunedAccounts.length);for(const t of this._prunedAccounts)t.serialize(e);return e}get serializedSize(){let e=this._minerAddr.serializedSize+1+this._extraData.byteLength+2+2;for(const t of this._transactions)e+=t.serializedSize;return e+=this._prunedAccounts.reduce((e,t)=>e+t.serializedSize,0)}verify(){let e=null;for(const s of this._transactions){if(e&&e.compareBlockOrder(s)>=0){Log.w(BlockBody,"Invalid block - transactions not ordered.");return!1}e=s;if(!s.verify()){Log.w(BlockBody,"Invalid block - invalid transaction");return!1}}let t=null;for(const s of this._prunedAccounts){if(t&&t.compare(s)>=0){Log.w(BlockBody,"Invalid block - pruned accounts not ordered.");return!1}t=s;if(!s.account.isToBePruned()){Log.w(BlockBody,"Invalid block - invalid pruned account");return!1}}return!0}getMerkleLeafs(){return[this._minerAddr,this._extraData,...this._transactions,...this.prunedAccounts]}hash(){this._hash||(this._hash=MerkleTree.computeRoot(this.getMerkleLeafs()));return this._hash}equals(e){return e instanceof BlockBody&&this._minerAddr.equals(e.minerAddr)&&BufferUtils.equals(this._extraData,e.extraData)&&this._transactions.length===e.transactions.length&&this._transactions.every((t,s)=>t.equals(e.transactions[s]))}getAddresses(){const e=[this._minerAddr];for(const t of this._transactions)e.push(t.sender,t.recipient);return e}get extraData(){return this._extraData}get minerAddr(){return this._minerAddr}get transactions(){return this._transactions}get transactionCount(){return this._transactions.length}get prunedAccounts(){return this._prunedAccounts}}Class.register(BlockBody);class BlockUtils{static compactToTarget(e){return new BigNumber(16777215&e).times(new BigNumber(2).pow(8*Math.max((e>>24)-3,0)))}static targetToCompact(e){if(!e.isFinite()||e.isNaN())throw new Error("Invalid Target");let t=Math.max(Math.ceil(Math.log2(e.toNumber())/8),1);e/Math.pow(2,8*(t-1))>=128&&t>=3&&t++;return(t<<24)+(e/Math.pow(2,8*Math.max(t-3,0))&16777215)}static getTargetHeight(e){return Math.ceil(Math.log2(e.toNumber()))}static getTargetDepth(e){return BlockUtils.getTargetHeight(Policy.BLOCK_TARGET_MAX)-BlockUtils.getTargetHeight(e)}static compactToDifficulty(e){return Policy.BLOCK_TARGET_MAX.div(BlockUtils.compactToTarget(e))}static difficultyToCompact(e){return BlockUtils.targetToCompact(BlockUtils.difficultyToTarget(e))}static difficultyToTarget(e){return Policy.BLOCK_TARGET_MAX.div(e)}static targetToDifficulty(e){return Policy.BLOCK_TARGET_MAX.div(e)}static hashToTarget(e){return new BigNumber(e.toHex(),16)}static realDifficulty(e){return BlockUtils.targetToDifficulty(BlockUtils.hashToTarget(e))}static getHashDepth(e){return BlockUtils.getTargetDepth(BlockUtils.hashToTarget(e))}static isProofOfWork(e,t){return new BigNumber(e.toHex(),16).lte(t)}static isValidCompact(e){return BlockUtils.isValidTarget(BlockUtils.compactToTarget(e))}static isValidTarget(e){return null!==e&&e.gte(1)&&e.lte(Policy.BLOCK_TARGET_MAX)}static getNextTarget(e,t,s){const r=Policy.difficultyBlockWindow(e.height);Assert.that(e.height-t.height===r||e.height<=r&&1===t.height,`Tail and head block must be ${r} blocks apart`);let n=e.timestamp-t.timestamp;if(e.height<=r){n+=(r-e.height+1)*Policy.INITIAL_BLOCK_TIME;s=s.plus(r-e.height+1)}let i=n/(r*Policy.blockTime(e.height));if(e.height>=Policy.SECOND_FORKING_FOR_BLOCK_DIFFICULTY){i=Math.max(i,1/Policy.SECOND_DIFFICULTY_MAX_ADJUSTMENT_FACTOR);i=Math.min(i,1/Policy.SECOND_DIFFICULTY_MIN_ADJUSTMENT_FACTOR)}else if(e.height>=Policy.FORKING_FOR_BLOCK_DIFFICULTY_BLOCK_SIZE){i=Math.max(i,1/Policy.NEW_DIFFICULTY_MAX_ADJUSTMENT_FACTOR);i=Math.min(i,1/Policy.NEW_DIFFICULTY_MIN_ADJUSTMENT_FACTOR)}else{i=Math.max(i,1/Policy.DIFFICULTY_MAX_ADJUSTMENT_FACTOR);i=Math.min(i,Policy.DIFFICULTY_MAX_ADJUSTMENT_FACTOR)}const o=s.div(r);let a=BlockUtils.difficultyToTarget(o).times(i);a=BigNumber.min(a,Policy.BLOCK_TARGET_MAX);a=BigNumber.max(a,1);const c=BlockUtils.targetToCompact(a);return BlockUtils.compactToTarget(c)}}Class.register(BlockUtils);class Subscription{static fromAddresses(e){return new Subscription(Subscription.Type.ADDRESSES,e)}constructor(e,t=null){if(!NumberUtils.isUint8(e))throw new Error("Invalid type");if(e===Subscription.Type.ADDRESSES&&(!Array.isArray(t)||!NumberUtils.isUint16(t.length)||t.some(e=>!(e instanceof Address))))throw new Error("Invalid addresses");this._type=e;this._addresses=new HashSet;switch(e){case Subscription.Type.ADDRESSES:this._addresses.addAll(t)}}static unserialize(e){const t=e.readUint8();let s=null;switch(t){case Subscription.Type.ADDRESSES:{s=[];const t=e.readUint16();for(let r=0;r<t;++r)s.push(Address.unserialize(e));break}}return new Subscription(t,s)}serialize(e){(e=e||new SerialBuffer(this.serializedSize)).writeUint8(this._type);switch(this._type){case Subscription.Type.ADDRESSES:e.writeUint16(this._addresses.length);for(const t of this._addresses)t.serialize(e)}return e}get serializedSize(){let e=0;switch(this._type){case Subscription.Type.ADDRESSES:e=2;for(const t of this._addresses)e+=t.serializedSize}return 1+e}matchesBlock(e){switch(this._type){case Subscription.Type.NONE:return!1;case Subscription.Type.ANY:case Subscription.Type.ADDRESSES:return!0;default:throw new Error("Unknown type")}}matchesTransaction(e){switch(this._type){case Subscription.Type.NONE:return!1;case Subscription.Type.ANY:return!0;case Subscription.Type.ADDRESSES:return this._addresses.contains(e.recipient)||this._addresses.contains(e.sender);default:throw new Error("Unknown type")}}isSubsetOf(e){if(e.type===Subscription.Type.ANY||this.type===Subscription.Type.NONE)return!0;if(e.type!==this.type)return!1;switch(this.type){case Subscription.Type.ADDRESSES:return this.addresses.reduce((t,s)=>t&&e.addresses.find(e=>e.equals(s)),!0)}return!1}toString(){return`Subscription{type=${this._type}, addresses=[${this._addresses.values()}]}`}get type(){return this._type}get addresses(){return this._addresses.values()}}Subscription.Type={NONE:0,ANY:1,ADDRESSES:2};Subscription.NONE=new Subscription(Subscription.Type.NONE);Subscription.BLOCKS_ONLY=new Subscription(Subscription.Type.ADDRESSES,[]);Subscription.ANY=new Subscription(Subscription.Type.ANY);Class.register(Subscription);class Transaction{constructor(e,t,s,r,n,i,o,a,c,h,l=GenesisConfig.NETWORK_ID){const u=new BigNumber(i);if(!(t instanceof Address))throw new Error("Malformed sender");if(!NumberUtils.isUint8(s))throw new Error("Malformed sender type");if(!(r instanceof Address))throw new Error("Malformed recipient");if(!NumberUtils.isUint8(n))throw new Error("Malformed recipient type");if(!NumberUtils.isUint128(u)||u.eq(0))throw new Error("Malformed value");if(!NumberUtils.isUint32(o))throw new Error("Malformed validityStartHeight");if(!NumberUtils.isUint8(a)&&(a&~Transaction.Flag.ALL)>0)throw new Error("Malformed flags");if(!(c instanceof Uint8Array&&NumberUtils.isUint16(c.byteLength)))throw new Error("Malformed data");if(h&&(!(h instanceof Uint8Array)||!NumberUtils.isUint16(h.byteLength)))throw new Error("Malformed proof");if(!NumberUtils.isUint8(l))throw new Error("Malformed networkId");this._format=e;this._sender=t;this._senderType=s;this._recipient=r;this._recipientType=n;this._value=u;this._fee=Policy.txFee(o);this._networkId=l;this._validityStartHeight=o;this._flags=a;this._data=c;this._proof=h;this._recipient===Address.CONTRACT_CREATION&&(this._recipient=this.getContractCreationAddress())}static unserialize(e){const t=e.readUint8();e.readPos--;if(!Transaction.FORMAT_MAP.has(t))throw new Error("Invalid transaction type");return Transaction.FORMAT_MAP.get(t).unserialize(e)}serializeContent(e){(e=e||new SerialBuffer(this.serializedContentSize)).writeUint16(this._data.byteLength);e.write(this._data);this._sender.serialize(e);e.writeUint8(this._senderType);this._recipient.serialize(e);e.writeUint8(this._recipientType);e.writeUint128(this._value);e.writeUint128(this._fee);e.writeUint32(this._validityStartHeight);e.writeUint8(this._networkId);e.writeUint8(this._flags);return e}get serializedContentSize(){return 2+this._data.byteLength+this._sender.serializedSize+1+this._recipient.serializedSize+1+16+16+4+1+1}verify(e){this._valid===undefined&&(this._valid=this._verify(e));return this._valid}_verify(e=GenesisConfig.NETWORK_ID){if(this._networkId!==e){Log.w(Transaction,"Transaction is not valid in this network",this);return!1}if(this._recipient.equals(this._sender)){Log.w(Transaction,"Sender and recipient must not match",this);return!1}if(!Account.TYPE_MAP.has(this._senderType)||!Account.TYPE_MAP.has(this._recipientType)){Log.w(Transaction,"Invalid account type",this);return!1}if(!Account.TYPE_MAP.get(this._senderType).verifyOutgoingTransaction(this)){Log.w(Transaction,"Invalid for sender",this);return!1}if(!Account.TYPE_MAP.get(this._recipientType).verifyIncomingTransaction(this)){Log.w(Transaction,"Invalid for recipient",this);return!1}if(!this._fee.eq(Policy.txFee(this._validityStartHeight))){Log.w(Transaction,"Invalid for tx fee",this);return!1}return!0}get serializedSize(){throw new Error("Getter needs to be overwritten by subclasses")}serialize(e){throw new Error("Method needs to be overwritten by subclasses")}hash(){this._hash=this._hash||Hash.light(this.serializeContent());return this._hash}compare(e){return this.fee.div(this.serializedSize).gt(e.fee.div(e.serializedSize))?-1:this.fee.div(this.serializedSize).lt(e.fee.div(e.serializedSize))?1:this.serializedSize>e.serializedSize?-1:this.serializedSize<e.serializedSize?1:this.fee.gt(e.fee)?-1:this.fee.lt(e.fee)?1:this.value.gt(e.value)?-1:this.value.lt(e.value)?1:this.compareBlockOrder(e)}compareBlockOrder(e){const t=this._recipient.compare(e._recipient);if(0!==t)return t;if(this._validityStartHeight<e._validityStartHeight)return-1;if(this._validityStartHeight>e._validityStartHeight)return 1;if(this._fee.gt(e._fee))return-1;if(this._fee.lt(e._fee))return 1;if(this._value.gt(e._value))return-1;if(this._value.lt(e._value))return 1;const s=this._sender.compare(e._sender);return 0!==s?s:this._recipientType<e._recipientType?-1:this._recipientType>e._recipientType?1:this._senderType<e._senderType?-1:this._senderType>e._senderType?1:this._flags<e._flags?-1:this._flags>e._flags?1:BufferUtils.compare(this._data,e._data)}equals(e){return e instanceof Transaction&&this._sender.equals(e._sender)&&this._senderType===e._senderType&&this._recipient.equals(e._recipient)&&this._recipientType===e._recipientType&&this._value.eq(e._value)&&this._fee.eq(e._fee)&&this._validityStartHeight===e._validityStartHeight&&this._networkId===e._networkId&&this._flags===e._flags&&BufferUtils.equals(this._data,e._data)}toString(){return"Transaction{"+`sender=${this._sender.toHex()}, `+`recipient=${this._recipient.toHex()}, `+`value=${this._value.toString()}, `+`fee=${this._fee.toString()}, `+`validityStartHeight=${this._validityStartHeight}, `+`networkId=${this._networkId}`+"}"}toPlain(){const e=Account.TYPE_MAP.get(this.recipientType).dataToPlain(this.data);e.raw=BufferUtils.toHex(this.data);const t=Account.TYPE_MAP.get(this.senderType).proofToPlain(this.proof);t.raw=BufferUtils.toHex(this.proof);return{transactionHash:this.hash().toPlain(),format:Transaction.Format.toString(this._format),sender:this.sender.toPlain(),senderType:Account.Type.toString(this.senderType),recipient:this.recipient.toPlain(),recipientType:Account.Type.toString(this.recipientType),value:this.value.toString(),fee:this.fee.toString(),feePerByte:this.feePerByte.toString(),validityStartHeight:this.validityStartHeight,network:GenesisConfig.networkIdToNetworkName(this.networkId),flags:this.flags,data:e,proof:t,size:this.serializedSize,valid:this.verify()}}static fromPlain(e){if(!e)throw new Error("Invalid transaction format");const t=Transaction.Format.fromAny(e.format);if(!Transaction.FORMAT_MAP.has(t))throw new Error("Invalid transaction type");return Transaction.FORMAT_MAP.get(t).fromPlain(e)}static fromAny(e){if(e instanceof Transaction)return e;if("object"==typeof e)return Transaction.fromPlain(e);if("string"==typeof e)return Transaction.unserialize(new SerialBuffer(BufferUtils.fromHex(e)));throw new Error("Invalid transaction format")}getContractCreationAddress(){const e=Transaction.unserialize(this.serialize());e._recipient=Address.NULL;e._hash=null;return Address.fromHash(e.hash())}get format(){return this._format}get sender(){return this._sender}get senderType(){return this._senderType}get recipient(){return this._recipient}get recipientType(){return this._recipientType}get value(){return this._value}get fee(){return this._fee}get feePerByte(){return this._fee.div(this.serializedSize)}get networkId(){return this._networkId}get validityStartHeight(){return this._validityStartHeight}get flags(){return this._flags}hasFlag(e){return(this._flags&e)>0}get data(){return this._data}get proof(){return this._proof}set proof(e){this._proof=e}}Transaction.Format={BASIC:0,EXTENDED:1};Transaction.Format.toString=function(e){switch(e){case Transaction.Format.BASIC:return"basic";case Transaction.Format.EXTENDED:return"extended"}throw new Error("Invalid transaction format")};Transaction.Format.fromAny=function(e){if("number"==typeof e)return e;switch(e){case"basic":return Transaction.Format.BASIC;case"extended":return Transaction.Format.EXTENDED}throw new Error("Invalid transaction format")};Transaction.Flag={NONE:0,CONTRACT_CREATION:1,ALL:1};Transaction.FORMAT_MAP=new Map;Class.register(Transaction);class SignatureProof{static verifyTransaction(e){try{const s=new SerialBuffer(e.proof),r=SignatureProof.unserialize(s);if(s.readPos!==s.byteLength){Log.w(SignatureProof,"Invalid SignatureProof - overlong");return!1}return r.verify(e.sender,e.serializeContent())}catch(t){Log.w(SignatureProof,`Failed to verify transaction: ${t.message||t}`);return!1}}static singleSig(e,t){return new SignatureProof(e,new MerklePath([]),t)}static multiSig(e,t,s){const r=MerklePath.compute(t,e);return new SignatureProof(e,r,s)}constructor(e,t,s){if(!(e instanceof PublicKey))throw new Error("Malformed publickKey");if(!(t instanceof MerklePath))throw new Error("Malformed merklePath");if(s&&!(s instanceof Signature))throw new Error("Malformed signature");this._publicKey=e;this._merklePath=t;this._signature=s}static unserialize(e){const t=PublicKey.unserialize(e),s=MerklePath.unserialize(e),r=Signature.unserialize(e);return new SignatureProof(t,s,r)}serialize(e){e=e||new SerialBuffer(this.serializedSize);this._publicKey.serialize(e);this._merklePath.serialize(e);this._signature&&this._signature.serialize(e);return e}get serializedSize(){return this._publicKey.serializedSize+this._merklePath.serializedSize+(this._signature?this._signature.serializedSize:0)}static get SINGLE_SIG_SIZE(){return PublicKey.SIZE+new MerklePath([]).serializedSize+Signature.SIZE}equals(e){return e instanceof SignatureProof&&this._publicKey.equals(e._publicKey)&&this._merklePath.equals(e._merklePath)&&(this._signature?this._signature.equals(e._signature):this._signature===e._signature)}verify(e,t){if(null!==e&&!this.isSignedBy(e)){Log.w(SignatureProof,"Invalid SignatureProof - signer does not match sender address");return!1}if(!this._signature){Log.w(SignatureProof,"Invalid SignatureProof - signature is missing");return!1}if(!this._signature.verify(this._publicKey,t)){Log.w(SignatureProof,"Invalid SignatureProof - signature is invalid");return!1}return!0}isSignedBy(e){const t=this._merklePath.computeRoot(this._publicKey);return Address.fromHash(t).equals(e)}get publicKey(){return this._publicKey}get merklePath(){return this._merklePath}get signature(){return this._signature}set signature(e){this._signature=e}}Class.register(SignatureProof);class BasicTransaction extends Transaction{constructor(e,t,s,r,n,i){if(!(e instanceof PublicKey))throw new Error("Malformed senderPubKey");if(n!==undefined&&!(n instanceof Signature))throw new Error("Malformed signature");const o=SignatureProof.singleSig(e,n);super(Transaction.Format.BASIC,e.toAddress(),Account.Type.BASIC,t,Account.Type.BASIC,s,r,Transaction.Flag.NONE,new Uint8Array(0),o.serialize(),i);this._signatureProof=o}static unserialize(e){const t=e.readUint8();Assert.that(t===Transaction.Format.BASIC);const s=PublicKey.unserialize(e),r=Address.unserialize(e),n=e.readUint128(),i=(e.readUint128(),e.readUint32()),o=e.readUint8(),a=Signature.unserialize(e);return new BasicTransaction(s,r,n,i,a,o)}static fromPlain(e){if(!e)throw new Error("Invalid transaction format");return new BasicTransaction(PublicKey.fromAny(e.proof.publicKey||e.senderPubKey),Address.fromAny(e.recipient),e.value,e.validityStartHeight,Signature.fromAny(e.proof.signature||e.signature),GenesisConfig.networkIdFromAny(e.network||e.networkId))}serialize(e){(e=e||new SerialBuffer(this.serializedSize)).writeUint8(Transaction.Format.BASIC);this.senderPubKey.serialize(e);this._recipient.serialize(e);e.writeUint128(this._value);e.writeUint128(this._fee);e.writeUint32(this._validityStartHeight);e.writeUint8(this._networkId);this.signature.serialize(e);return e}get serializedSize(){return 1+this.senderPubKey.serializedSize+this._recipient.serializedSize+16+16+4+1+this.signature.serializedSize}get senderPubKey(){return this._signatureProof.publicKey}get signature(){return this._signatureProof.signature}set signature(e){this._signatureProof.signature=e;this._proof=this._signatureProof.serialize()}}Transaction.FORMAT_MAP.set(Transaction.Format.BASIC,BasicTransaction);Class.register(BasicTransaction);class ExtendedTransaction extends Transaction{constructor(e,t,s,r,n,i,o,a,c=new Uint8Array(0),h){super(Transaction.Format.EXTENDED,e,t,s,r,n,i,o,a,c,h)}static unserialize(e){const t=e.readUint8();Assert.that(t===Transaction.Format.EXTENDED);const s=e.readUint16(),r=e.read(s),n=Address.unserialize(e),i=e.readUint8(),o=Address.unserialize(e),a=e.readUint8(),c=e.readUint128(),h=(e.readUint128(),e.readUint32()),l=e.readUint8(),u=e.readUint8(),d=e.readUint16(),_=e.read(d);return new ExtendedTransaction(n,i,o,a,c,h,u,r,_,l)}static fromPlain(e){if(!e)throw new Error("Invalid transaction format");return new ExtendedTransaction(Address.fromAny(e.sender),Account.Type.fromAny(e.senderType),Address.fromAny(e.recipient),Account.Type.fromAny(e.recipientType),e.value,e.validityStartHeight,e.flags,BufferUtils.fromAny(e.data.raw===undefined?e.data:e.data.raw),BufferUtils.fromAny(e.proof.raw===undefined?e.proof:e.proof.raw),GenesisConfig.networkIdFromAny(e.network||e.networkId))}serialize(e){(e=e||new SerialBuffer(this.serializedSize)).writeUint8(Transaction.Format.EXTENDED);this.serializeContent(e);e.writeUint16(this._proof.byteLength);e.write(this._proof);return e}get serializedSize(){return 1+this.serializedContentSize+2+this._proof.byteLength}}Transaction.FORMAT_MAP.set(Transaction.Format.EXTENDED,ExtendedTransaction);Class.register(ExtendedTransaction);class TransactionsProof{constructor(e,t){if(!Array.isArray(e)||!NumberUtils.isUint16(e.length)||e.some(e=>!(e instanceof Transaction)))throw new Error("Malformed transactions");if(!(t instanceof MerkleProof))throw new Error("Malformed merkle proof");this._transactions=e;this._proof=t}static unserialize(e){const t=e.readUint16(),s=[];for(let n=0;n<t;++n)s.push(Transaction.unserialize(e));const r=MerkleProof.unserialize(e);return new TransactionsProof(s,r)}serialize(e){(e=e||new SerialBuffer(this.serializedSize)).writeUint16(this._transactions.length);for(const t of this._transactions)t.serialize(e);this._proof.serialize(e);return e}get serializedSize(){return 2+this._transactions.reduce((e,t)=>e+t.serializedSize,0)+this._proof.serializedSize}toString(){return`TransactionsProof{length=${this.length}}`}root(){return this._proof.computeRoot(this._transactions)}get length(){return this._transactions.length}get transactions(){return this._transactions}get proof(){return this._proof}}Class.register(TransactionsProof);class TransactionCache{constructor(e=null,t=[]){this._transactionHashes=e||new InclusionHashSet(e=>e.toBase64());this._blockOrder=t}containsTransaction(e){return this._transactionHashes.contains(e.hash())}static _getBlockDescriptor(e){return{hash:e.hash(),prevHash:e.prevHash,transactionHashes:e.transactions.map(e=>e.hash())}}pushBlock(e){Assert.that(!this.head||e.prevHash.equals(this.head.hash),"Not a successor of head");const t=TransactionCache._getBlockDescriptor(e);this._blockOrder.push(t);this._transactionHashes.addAll(t.transactionHashes);this._blockOrder.length>Policy.TRANSACTION_VALIDITY_WINDOW&&this.shiftBlock()}shiftBlock(){const e=this._blockOrder.shift();e&&this._transactionHashes.removeAll(e.transactionHashes)}revertBlock(e){const t=this._blockOrder.pop();if(t){Assert.that(t.hash.equals(e.hash()),"Invalid block to revert");this._transactionHashes.removeAll(t.transactionHashes)}return this.missingBlocks}prependBlocks(e){if(e.length+this._blockOrder.length>Policy.TRANSACTION_VALIDITY_WINDOW)throw new Error("Exceeding transaction cache size");Assert.that(!this.tail||0===e.length||this.tail.prevHash.equals(e[e.length-1].hash()),"Not a predecessor of tail");const t=e.map(e=>TransactionCache._getBlockDescriptor(e));this._blockOrder.unshift(...t);t.forEach(e=>this._transactionHashes.addAll(e.transactionHashes))}get missingBlocks(){return Policy.TRANSACTION_VALIDITY_WINDOW-this._blockOrder.length}get transactions(){return this._transactionHashes}clone(){return new TransactionCache(this._transactionHashes.clone(),this._blockOrder.slice())}isEmpty(){return 0===this._blockOrder.length}get head(){return 0===this._blockOrder.length?null:this._blockOrder[this._blockOrder.length-1]}get tail(){return 0===this._blockOrder.length?null:this._blockOrder[0]}}Class.register(TransactionCache);class TransactionStoreEntry{constructor(e,t,s,r,n,i){this._transactionHash=e;this._sender=t;this._recipient=s;this._blockHeight=r;this._blockHash=n;this._index=i;this.senderBuffer=this._sender.serialize();this.recipientBuffer=this._recipient.serialize();this.transactionHashBuffer=this._transactionHash.serialize()}static fromBlock(e){const t=e.hash(),s=[];for(let r=0;r<e.transactions.length;++r){const n=e.transactions[r];s.push(new TransactionStoreEntry(n.hash(),n.sender,n.recipient,e.height,t,r))}return s}static fromJSON(e,t){return new TransactionStoreEntry(Hash.unserialize(new SerialBuffer(t.transactionHashBuffer)),Address.unserialize(new SerialBuffer(t.senderBuffer)),Address.unserialize(new SerialBuffer(t.recipientBuffer)),t.blockHeight,Hash.fromBase64(t.blockHash),t.index)}toJSON(){return{transactionHashBuffer:this.transactionHashBuffer,senderBuffer:this.senderBuffer,recipientBuffer:this.recipientBuffer,blockHeight:this.blockHeight,blockHash:this.blockHash.toBase64(),index:this.index}}get transactionHash(){return this._transactionHash}get sender(){return this._sender}get recipient(){return this._recipient}get blockHeight(){return this._blockHeight}get blockHash(){return this._blockHash}get index(){return this._index}}Class.register(TransactionStoreEntry);class TransactionStore{static initPersistent(e){e.deleteObjectStore("Transactions",{upgradeCondition:e=>e<4,indexNames:["sender","recipient"]});e.deleteObjectStore("Transactions",{upgradeCondition:e=>e>=4&&e<8,indexNames:["sender","recipient","transactionHash"]});const t=e.createObjectStore("Transactions",{codec:new TransactionStoreCodec,keyEncoding:JDB.JungleDB.NUMBER_ENCODING});t.createIndex("sender",["senderBuffer"],{keyEncoding:JDB.JungleDB.BINARY_ENCODING});t.createIndex("recipient",["recipientBuffer"],{keyEncoding:JDB.JungleDB.BINARY_ENCODING});t.createIndex("transactionHash",["transactionHashBuffer"],{keyEncoding:JDB.JungleDB.BINARY_ENCODING})}static getPersistent(e){return new TransactionStore(e.getObjectStore("Transactions"))}static createVolatile(){const e=JDB.JungleDB.createVolatileObjectStore();e.createIndex("sender",["senderBuffer"]);e.createIndex("recipient",["recipientBuffer"]);e.createIndex("transactionHash",["transactionHashBuffer"],{unique:!0});return new TransactionStore(e)}constructor(e){this._store=e}async _getCurrentId(e){e=e||this._store;return await e.get(TransactionStore.CURRENT_ID_KEY)||1}_setCurrentId(e,t){return(t=t||this._store).put(TransactionStore.CURRENT_ID_KEY,e)}async _idForHash(e,t){const s=(t=t||this._store).index("transactionHash"),r=await s.keys(JDB.KeyRange.only(e.serialize()));for(const n of r)return n;return null}async get(e){const t=this._store.index("transactionHash"),s=await t.values(JDB.KeyRange.only(e.serialize()));return s&&s.length>0?s[0]:null}async getBySender(e,t=null){const s=this._store.index("sender"),r=[];await s.valueStream((e,s)=>{if(null!==t&&r.length>=t)return!1;r.push(e);return!0},!1,JDB.KeyRange.only(e.serialize()));return r}async getByRecipient(e,t=null){const s=this._store.index("recipient"),r=[];await s.valueStream((e,s)=>{if(null!==t&&r.length>=t)return!1;r.push(e);return!0},!1,JDB.KeyRange.only(e.serialize()));return r}async put(e){const t=TransactionStoreEntry.fromBlock(e),s=this._store.transaction();let r=await this._getCurrentId(s);for(const n of t){s.putSync(r,n);r++}await this._setCurrentId(r,s);return s.commit()}async remove(e){const t=this._store.transaction();for(const s of e.transactions)t.removeSync(await this._idForHash(s.hash(),t));return t.commit()}snapshot(e){const t=this._store.snapshot();e&&t.inherit(e._store);return new TransactionStore(t)}transaction(e=!0){const t=this._store.transaction(e);return new TransactionStore(t)}truncate(){return this._store.truncate()}commit(){return this._store.commit()}abort(){return this._store.abort()}get tx(){return this._store instanceof JDB.Transaction?this._store:undefined}}TransactionStore.CURRENT_ID_KEY=0;Class.register(TransactionStore);class TransactionStoreCodec{encode(e){return e instanceof TransactionStoreEntry?e.toJSON():e}decode(e,t){return 0===t?e:TransactionStoreEntry.fromJSON(t,e)}get valueEncoding(){return JDB.JungleDB.JSON_ENCODING}}class TransactionReceipt{constructor(e,t,s){this._transactionHash=e;this._blockHash=t;this._blockHeight=s}static unserialize(e){const t=Hash.unserialize(e),s=Hash.unserialize(e),r=e.readUint32();return new TransactionReceipt(t,s,r)}serialize(e){e=e||new SerialBuffer(this.serializedSize);this._transactionHash.serialize(e);this._blockHash.serialize(e);e.writeUint32(this._blockHeight);return e}get serializedSize(){return this._transactionHash.serializedSize+this._blockHash.serializedSize+4}get transactionHash(){return this._transactionHash}get blockHash(){return this._blockHash}get blockHeight(){return this._blockHeight}equals(e){return e instanceof TransactionReceipt&&(this.transactionHash.equals(e.transactionHash)&&this.blockHash.equals(e.blockHash)&&this.blockHeight===e.blockHeight)}toPlain(){return{transactionHash:this.transactionHash.toPlain(),blockHash:this.blockHash.toPlain(),blockHeight:this.blockHeight}}static fromPlain(e){if(!e)throw new Error("invalid transaction receipt");return new TransactionReceipt(Hash.fromAny(e.transactionHash),Hash.fromAny(e.blockHash),e.blockHeight)}static fromAny(e){if(e instanceof TransactionReceipt)return e;if("string"==typeof e)return TransactionReceipt.unserialize(BufferUtils.fromHex(e));if("object"==typeof e)return TransactionReceipt.fromPlain(e);throw new Error("invalid transaction receipt")}}Class.register(TransactionReceipt);class Block{constructor(e,t,s){if(!(e instanceof BlockHeader))throw new Error("Malformed header");if(!(t instanceof BlockInterlink))throw new Error("Malformed interlink");if(s&&!(s instanceof BlockBody))throw new Error("Malformed body");this._header=e;this._interlink=t;this._body=s}static unserialize(e){const t=BlockHeader.unserialize(e),s=BlockInterlink.unserialize(e,t.prevHash);let r=undefined;e.readUint8()&&(r=BlockBody.unserialize(e));return new Block(t,s,r)}serialize(e){e=e||new SerialBuffer(this.serializedSize);this._header.serialize(e);this._interlink.serialize(e);if(this._body){e.writeUint8(1);this._body.serialize(e)}else e.writeUint8(0);return e}get serializedSize(){return this._header.serializedSize+this._interlink.serializedSize+1+(this._body?this._body.serializedSize:0)}async verify(e){if(this._valid===undefined)if(this.isLight()||this.body.transactions.length<150||!IWorker.areWorkersAsync)this._valid=await this._verify(e.now());else{const t=this.body.transactions.map(e=>e._valid),s=await CryptoWorker.getInstanceAsync(),{valid:r,pow:n,interlinkHash:i,bodyHash:o}=await s.blockVerify(this.serialize(),t,e.now(),GenesisConfig.GENESIS_HASH.serialize(),GenesisConfig.NETWORK_ID);this._valid=r;this.header._pow=Hash.unserialize(new SerialBuffer(n));this.interlink._hash=Hash.unserialize(new SerialBuffer(i));this.body._hash=Hash.unserialize(new SerialBuffer(o))}return this._valid}async _verify(e){if(1e3*this._header.timestamp>e+1e3*Block.TIMESTAMP_DRIFT_MAX){Log.w(Block,"Invalid block - timestamp too far in the future");return!1}if(!(await this._header.verifyProofOfWork())){Log.w(Block,"Invalid block - PoW verification failed");return!1}if(this.serializedSize>Policy.blockSize(this.height)){Log.w(Block,"Invalid block - max block size exceeded");return!1}return!!this._verifyInterlink()&&!(this.isFull()&&!this._verifyBody())}_verifyInterlink(){if(1===this.height&&this._header.interlinkHash.equals(new Hash(null)))return!0;const e=this._interlink.hash();if(!this._header.interlinkHash.equals(e)){Log.w(Block,"Invalid block - interlink hash mismatch");return!1}return!0}_verifyBody(){if(!this._body.verify())return!1;const e=this._body.hash();if(!this._header.bodyHash.equals(e)){Log.w(Block,"Invalid block - body hash mismatch");return!1}return!0}async isImmediateSuccessorOf(e){if(!this._header.isImmediateSuccessorOf(e.header))return!1;const t=await e.getNextInterlink(this.target,this.version);return!!this._interlink.equals(t)}async isInterlinkSuccessorOf(e){if(this._header.height<=e.header.height){Log.v(Block,"No interlink successor - height");return!1}if(this._header.timestamp<e.header.timestamp){Log.v(Block,"No interlink successor - timestamp");return!1}const t=e.hash();if(!GenesisConfig.GENESIS_HASH.equals(t)){const s=await e.pow(),r=BlockUtils.getTargetHeight(this.target);let n=!1,i=0;for(;i<this._interlink.length;i++)if(t.equals(this._interlink.hashes[i])){n=!0;const e=new BigNumber(2).pow(r-i);if(!BlockUtils.isProofOfWork(s,e)){Log.v(Block,"No interlink successor - invalid position in interlink");return!1}}if(!n){Log.v(Block,"No interlink successor - not in interlink");return!1}}if(this._header.prevHash.equals(t)){if(this._header.height!==e.header.height+1){Log.v(Block,"No interlink successor - immediate height");return!1}const t=(await e.getNextInterlink(this.target,this.version)).hash();if(!this._header.interlinkHash.equals(t)){Log.v(Block,"No interlink successor - immediate interlink");return!1}}else{if(this._header.height===e.header.height+1){Log.v(Block,"No interlink successor - immediate height (2)");return!1}{const t=new HashSet;t.addAll(this._interlink.hashes);t.removeAll(e.interlink.hashes);if(t.length>this._header.height-e.header.height){Log.v(Block,"No interlink successor - too many new blocks");return!1}const s=BlockUtils.getTargetDepth(this.target)-BlockUtils.getTargetDepth(e.target);if(this._interlink.length<e.interlink.length-s){Log.v(Block,"No interlink successor - interlink too short");return!1}let r=!1;const n=this._interlink.hashes,i=e.interlink.hashes;for(let e=1;e<i.length&&e-s<n.length;e++)if(i[e].equals(n[e-s]))r=!0;else if(r){Log.v(Block,"No interlink successor - invalid common suffix");return!1}}}return!0}async isSuccessorOf(e){return await this.isImmediateSuccessorOf(e)||await this.isInterlinkSuccessorOf(e)}async getNextInterlink(e,t=BlockHeader.CURRENT_VERSION){const s=[],r=this.hash(),n=BlockUtils.getHashDepth(await this.pow()),i=BlockUtils.getTargetDepth(e),o=Math.max(n-i+1,0);for(let a=0;a<o;a++)s.push(r);for(let a=o+(i-BlockUtils.getTargetDepth(this.target));a<this.interlink.length;a++)s.push(this.interlink.hashes[a]);return new BlockInterlink(s,r)}shallowCopy(){return new Block(this._header,this._interlink,this._body)}equals(e){return e instanceof Block&&this._header.equals(e._header)&&this._interlink.equals(e._interlink)&&(this._body?this._body.equals(e._body):!e._body)}isLight(){return!this._body}isFull(){return!!this._body}toLight(){return this.isLight()?this:new Block(this._header,this._interlink)}toFull(e){return this.isFull()?this:new Block(this._header,this._interlink,e)}get header(){return this._header}get interlink(){return this._interlink}get body(){if(this.isLight())throw new Error("Cannot access body of light block");return this._body}get version(){return this._header.version}get prevHash(){return this._header.prevHash}get interlinkHash(){return this._header.interlinkHash}get bodyHash(){return this._header.bodyHash}get accountsHash(){return this._header.accountsHash}get nBits(){return this._header.nBits}get target(){return this._header.target}get difficulty(){return this._header.difficulty}get height(){return this._header.height}get timestamp(){return this._header.timestamp}get nonce(){return this._header.nonce}get minerAddr(){return this._body?this._body.minerAddr:undefined}get transactions(){return this._body?this._body.transactions:undefined}get extraData(){return this._body?this._body.extraData:undefined}get prunedAccounts(){return this._body?this._body.prunedAccounts:undefined}get transactionCount(){return this._body?this._body.transactionCount:undefined}hash(e){return this._header.hash(e)}pow(e){return this._header.pow(e)}static fromAny(e){if(e instanceof Block)return e;if("object"==typeof e)return Block.fromPlain(e);if("string"==typeof e)return Block.unserialize(BufferUtils.fromHex(e));throw new Error("Invalid block")}static fromPlain(e){const t=new BlockHeader(Hash.fromAny(e.prevHash),Hash.fromAny(e.interlinkHash),Hash.fromAny(e.bodyHash),Hash.fromAny(e.accountsHash),e.nBits,e.height,e.timestamp,e.nonce,e.version),s=new BlockInterlink((e.interlink.hashes||e.interlink).map(e=>Hash.fromAny(e)),Hash.fromAny(e.prevHash));let r=null;e.minerAddr&&e.extraData!==undefined&&Array.isArray(e.transactions)&&Array.isArray(e.prunedAccounts)&&(r=new BlockBody(Address.fromAny(e.minerAddr),e.transactions.map(e=>Transaction.fromAny(e)),BufferUtils.fromAny(e.extraData),e.prunedAccounts.map(e=>PrunedAccount.fromAny(e))));return new Block(t,s,r)}toString(){return`Block{height=${this.height},prev=${this.prevHash}}`}toPlain(){const e={version:this.version,hash:this.hash().toPlain(),prevHash:this.prevHash.toPlain(),interlinkHash:this.interlinkHash.toPlain(),bodyHash:this.bodyHash.toPlain(),accountsHash:this.accountsHash.toPlain(),nBits:this.nBits,difficulty:this.difficulty.toString(),height:this.height,timestamp:this.timestamp,nonce:this.nonce,interlink:this.interlink.hashes.map(e=>e.toPlain())};if(this.isFull()){e.minerAddr=this.minerAddr.toPlain();e.transactions=this.transactions.map(e=>e.toPlain());e.extraData=BufferUtils.toHex(this.extraData);e.prunedAccounts=this.prunedAccounts.map(e=>e.toPlain())}return e}}Block.TIMESTAMP_DRIFT_MAX=600;Class.register(Block);class IBlockchain extends Observable{get head(){}get headHash(){}get height(){}}Class.register(IBlockchain);class BaseChain extends IBlockchain{constructor(e){super();this._store=e}async getBlock(e,t=!1,s=!1){const r=await this._store.getChainData(e,s);return r&&(r.onMainChain||t)?r.head:null}getRawBlock(e,t=!1){return this._store.getRawBlock(e,t)}getBlockAt(e,t=!1){return this._store.getBlockAt(e,t)||null}getNearestBlockAt(e,t=!0){return this._store.getNearestBlockAt(e,t)||null}async getSuccessorBlocks(e){return this._store.getSuccessorBlocks(e)}async getBlockLocators(){const e=[this.headHash];let t=this.head;for(let r=Math.min(10,this.height)-1;r>0&&t;r--){e.push(t.prevHash);t=await this.getBlock(t.prevHash)}let s=2;for(let r=this.height-10-s;r>0;r-=s){(t=await this.getBlockAt(r))&&e.push(await t.hash());s*=2;if(e.length>=GetBlocksMessage.LOCATORS_MAX_COUNT)break}if(0===e.length||!e[e.length-1].equals(GenesisConfig.GENESIS_HASH)){e.length>=GetBlocksMessage.LOCATORS_MAX_COUNT&&e.pop();e.push(GenesisConfig.GENESIS_HASH)}return e}async getNextTarget(e,t){let s;if(e){const t=e.hash();s=await this._store.getChainData(t);Assert.that(!!s)}else{e=this.head;s=this._mainChain}if(t){s=await s.nextChainData(t);e=t}const r=Policy.difficultyBlockWindow(e.height),n=Math.max(e.height-r,1);let i;if(s.onMainChain)i=await this._store.getChainDataAt(n);else{let e=s;for(let t=0;t<r&&!e.onMainChain;t++)if(!(e=await this._store.getChainData(e.head.prevHash)))return null;i=e.onMainChain&&e.head.height>n?await this._store.getChainDataAt(n):e}if(!i||i.totalDifficulty.lt(1))return null;const o=s.totalDifficulty.minus(i.totalDifficulty);return BlockUtils.getNextTarget(s.head.header,i.head.header,o)}_getChainProof(){return this._prove(Policy.M,Policy.K,Policy.DELTA)}async _prove(e,t,s){Assert.that(e>=1,"m must be >= 1");Assert.that(s>0,"delta must be > 0");let r=new BlockChain([]),n=1;const i=await this._store.getChainDataAt(Math.max(this.height-t,1));for(let a=i.superBlockCounts.getCandidateDepth(e);a>=0;a--){const t=await this._getSuperChain(a,i,n);r=BlockChain.merge(r,new BlockChain(t.map(e=>e.head.toLight())));if(BaseChain._isGoodSuperChain(t,a,e,s)){Assert.that(t.length>=e,`Good superchain expected to be at least ${e} long`);Log.v(BaseChain,()=>`Found good superchain at depth ${a} with length ${t.length} (#${n} - #${i.head.height})`);n=t[t.length-e].head.height}}const o=await this._getHeaderChain(this.height-i.head.height);return new ChainProof(r,o)}async _getSuperChain(e,t,s=1){Assert.that(s>=1,"tailHeight must be >= 1");const r=[];BlockUtils.getHashDepth(await t.head.pow())>=e&&r.push(t);let n=t,i=Math.max(e-BlockUtils.getTargetDepth(n.head.target),-1);for(;i<n.head.interlink.hashes.length&&n.head.height>s;){const t=i<0?n.head.prevHash:n.head.interlink.hashes[i];if(!(n=await this._store.getChainData(t))){Log.w(BaseChain,`Failed to find block ${t} while constructing SuperChain at depth ${e} - returning truncated chain`);break}r.push(n);i=Math.max(e-BlockUtils.getTargetDepth(n.head.target),-1)}(0===r.length||r[r.length-1].head.height>1)&&1===s&&r.push(await ChainData.initial(GenesisConfig.GENESIS_BLOCK));return r.reverse()}static _isGoodSuperChain(e,t,s,r){return BaseChain._hasSuperQuality(e,t,s,r)&&BaseChain._hasMultiLevelQuality(e,t,s,r)}static _hasSuperQuality(e,t,s,r){Assert.that(s>=1,"m must be >= 1");if(e.length<s)return!1;for(let n=s;n<=e.length;n++){const s=e[e.length-1].head.height-e[e.length-n].head.height+1;if(!BaseChain._isLocallyGood(n,s,t,r))return!1}return!0}static _hasMultiLevelQuality(e,t,s,r){if(t<=0)return!0;for(let n=0;n<e.length-s;n++){const i=e[n],o=e[n+s];for(let e=t;e>=1;e--){const a=o.superBlockCounts.get(e)-i.superBlockCounts.get(e);switch(BaseChain.MULTILEVEL_STRATEGY){case BaseChain.MultilevelStrategy.STRICT:{const s=o.superBlockCounts.get(e-1)-i.superBlockCounts.get(e-1);if(2*a<Math.pow(1-r,1/t)*s){Log.d(BaseChain,`Chain badness detected at depth ${t}, failing at ${e}/${e-1}`+` with ${a}/${Math.pow(1-r,1/t)*s}/${s} blocks`);return!1}break}default:case BaseChain.MultilevelStrategy.MODERATE:for(let c=e-1;c>=0;c--){const h=o.superBlockCounts.get(c)-i.superBlockCounts.get(c);if(!BaseChain._isLocallyGood(a,h,e-c,r)){Log.d(BaseChain,`Chain badness detected at depth ${t}[${n}:${n+s}], failing at ${e}/${c}`);return!1}}break;case BaseChain.MultilevelStrategy.RELAXED:{const a=o.superBlockCounts.get(e-1)-i.superBlockCounts.get(e-1),c=o.head.height-i.head.height+1;if(!BaseChain._isLocallyGood(a,c,t,r)){Log.d(BaseChain,`Chain badness detected at depth ${t}[${n}:${n+s}], failing at ${e}`);return!1}break}}}}return!0}static _isLocallyGood(e,t,s,r){return e>(1-r)*Math.pow(2,-s)*t}async _getHeaderChain(e,t=this.head){const s=[];for(;t&&s.length<e;){s.push(t.header);t=await this.getBlock(t.prevHash)}return new HeaderChain(s.reverse())}async _extendChainProof(e,t,s=!0){const r=e.suffix.headers.slice();r.push(t);const n=e.prefix.blocks.slice();if(r.length<=Policy.K)return new ChainProof(new BlockChain(n),new HeaderChain(r));const i=r.shift(),o=await e.prefix.head.getNextInterlink(i.target,i.version),a=new Block(i,o);n.push(a);const c=(await e.prefix.getSuperChains()).slice(),h=BlockUtils.getHashDepth(await a.pow());for(let d=h;d>=0;d--)c[d]?c[d]=new BlockChain([...c[d].blocks,a]):c[d]=new BlockChain([a]);if(h-BlockUtils.getTargetDepth(a.target)<=0)return new ChainProof(new BlockChain(n,c),new HeaderChain(r));const l=new Set;for(let d=h;d>=0;d--){const e=c[d];if(e.length<Policy.M)continue;const t=e.blocks.map(e=>({head:e}));if(!BaseChain._hasSuperQuality(t,d,Policy.M,Policy.DELTA)){Log.w(BaseChain,`Chain quality badness detected at depth ${d}`);if(s)return null;continue}const r=e.blocks[e.length-Policy.M];for(let s=d-1;s>=0;s--){let e=0,t=c[s].blocks[e];for(;t.height<=r.height;){BlockUtils.getHashDepth(await t.pow())===s&&t.height>1&&l.add(t.height);e++;t=c[s].blocks[e]}e>0&&(c[s]=new BlockChain(c[s].blocks.slice(e)))}}const u=new BlockChain(n.filter(e=>!l.has(e.height)),c);return new ChainProof(u,new HeaderChain(r))}async _getBlockProof(e,t){const s=(e,t)=>{const s=Math.min(t-BlockUtils.getTargetDepth(e.target),e.interlink.length-1);return s<0?e.prevHash:e.interlink.hashes[s]},r=[],n=e.hash(),i=BlockUtils.hashToTarget(await e.pow()),o=BlockUtils.getTargetDepth(i);let a=BlockUtils.getTargetDepth(t.target)+t.interlink.length-1,c=t,h=s(c,a);for(;!n.equals(h);){const t=await this.getBlock(h);if(!t){Log.w(BaseChain,`Failed to find block ${h} while constructing inclusion proof`);return null}if(t.height<e.height){if(a<=o)return null;h=s(c,--a)}else{if(!(t.height>e.height)){Log.w(BaseChain,`Failed to prove block ${n} - different block ${h} at its height ${c.height}`);return null}r.push(t.toLight());h=s(c=t,a)}}r.push(e.toLight());return new BlockChain(r.reverse())}static async manyPow(e){const t=await CryptoWorker.getInstanceAsync(),s=t.poolSize||1,r=[];let n=0;for(let a=0;a<s;++a){r.push([]);for(;n<(a+1)/s*e.length;++n)r[a].push(e[n].serialize())}const i=[];for(const a of r)i.push(t.computeArgon2dBatch(a));const o=(await Promise.all(i)).reduce((e,t)=>[...e,...t],[]);for(let a=0;a<e.length;++a)e[a]._pow=new Hash(o[a])}static async isBetterProof(e,t,s){const r=BlockChain.lowestCommonAncestor(e.prefix,t.prefix),n=await NanoChain._getProofScore(e.prefix,r,s),i=await NanoChain._getProofScore(t.prefix,r,s);return n===i?e.suffix.totalDifficulty().gt(t.suffix.totalDifficulty()):n>i}static async _getProofScore(e,t,s){const r=[];for(const c of e.blocks){if(c.height<t.height)continue;const e=BlockUtils.getHashDepth(await c.pow());r[e]=r[e]?r[e]+1:1}let n,i=0;for(n=r.length-1;i<s&&n>=0;n--)i+=r[n]?r[n]:0;let o=Math.pow(2,n+1)*i,a=i;for(let c=n;c>=0;c--){a+=r[c]?r[c]:0;const e=Math.pow(2,c)*a;o=Math.max(o,e)}return o}}BaseChain.MultilevelStrategy={STRICT:1,MODERATE:2,RELAXED:3};BaseChain.MULTILEVEL_STRATEGY=BaseChain.MultilevelStrategy.MODERATE;Class.register(BaseChain);class BlockChain{static merge(e,t){const s=[];let r=0,n=0;for(;r<e.length&&n<t.length;){const i=e.blocks[r],o=t.blocks[n];if(i.height===o.height){Assert.that(i.equals(o),"Encountered different blocks at same height during chain merge");s.push(i);r++;n++}else if(i.height<o.height){s.push(i);r++}else{s.push(o);n++}}for(;r<e.length;r++)s.push(e.blocks[r]);for(;n<t.length;n++)s.push(t.blocks[n]);return new BlockChain(s)}static lowestCommonAncestor(e,t){let s=e.length-1,r=t.length-1;for(;s>=0&&r>=0;){const n=e.blocks[s],i=t.blocks[r];if(n.equals(i))return n;n.height>i.height?s--:r--}return undefined}constructor(e,t){if(!Array.isArray(e)||!NumberUtils.isUint16(e.length)||e.some(e=>!(e instanceof Block&&e.isLight())))throw new Error("Malformed blocks");this._blocks=e;this._chains=t}static unserialize(e){const t=e.readUint16(),s=[];for(let r=0;r<t;r++)s.push(Block.unserialize(e));return new BlockChain(s)}serialize(e){(e=e||new SerialBuffer(this.serializedSize)).writeUint16(this._blocks.length);for(const t of this._blocks)t.serialize(e);return e}get serializedSize(){return 2+this._blocks.reduce((e,t)=>e+t.serializedSize,0)}async verify(){for(let e=this._blocks.length-1;e>=1;e--){e%100==99&&await EventLoopHelper.webYield();if(!(await this._blocks[e].isSuccessorOf(this._blocks[e-1])))return!1}return!0}denseSuffix(){const e=[this.head];let t=this.head;for(let s=this.length-2;s>=0;s--){const r=this.blocks[s];if(!r.hash().equals(t.prevHash))break;e.push(r);t=r}e.reverse();return e}async getSuperChains(){if(!this._chains){this._chains=[];for(let e=0;e<this.length;e++){const t=this.blocks[e],s=BlockUtils.getHashDepth(await t.pow());this._chains[s]?this._chains[s].blocks.push(t):this._chains[s]||(this._chains[s]=new BlockChain([t]));for(let e=s-1;e>=0;e--)this._chains[e]&&this._chains[e].blocks.push(t)}for(let e=0;e<this._chains.length;e++)this._chains[e]||(this._chains[e]=new BlockChain([]))}return this._chains}isAnchored(){return GenesisConfig.GENESIS_HASH.equals(this.tail.hash())}toString(){return`BlockChain{length=${this.length}}`}get length(){return this._blocks.length}get blocks(){return this._blocks}get head(){return this._blocks[this.length-1]}get tail(){return this._blocks[0]}totalDifficulty(){return this._blocks.reduce((e,t)=>e+BlockUtils.targetToDifficulty(t.target),0)}}Class.register(BlockChain);class BlockProducer{constructor(e,t,s,r){this._blockchain=e;this._accounts=t;this._mempool=s;this._time=r}async getNextBlock(e,t=new Uint8Array(0)){const s=await this._blockchain.getNextTarget(),r=await this._getNextInterlink(s),n=await this._getNextBody(r.serializedSize,e,t),i=await this._getNextHeader(s,r,n);return(await this._blockchain.getNextTarget()).equals(s)?new Block(i,r,n):this.getNextBlock(e,t)}async _getNextHeader(e,t,s){const r=this._blockchain.headHash,n=t.hash(),i=this._blockchain.height+1,o=await this._accounts.transaction();let a;try{await o.commitBlockBody(s,i,this._blockchain.transactionCache);a=await o.hash()}catch(u){throw new Error(`Invalid block body: ${u.message}`)}finally{await o.abort()}const c=s.hash(),h=this._getNextTimestamp(),l=BlockUtils.targetToCompact(e);return new BlockHeader(r,n,c,a,l,i,h,0)}_getNextInterlink(e){return this._blockchain.head.getNextInterlink(e)}async _getNextBody(e,t,s){const r=Policy.blockSize(this._blockchain.height+1)-BlockHeader.SERIALIZED_SIZE-e-BlockBody.getMetadataSize(s),n=await this._mempool.getTransactionsForBlock(r),i=await this._accounts.gatherToBePrunedAccounts(n,this._blockchain.height+1,this._blockchain.transactionCache);return new BlockBody(t,n,s,i)}_getNextTimestamp(){const e=Math.floor(this._time.now()/1e3);return Math.max(e,this._blockchain.head.timestamp+1)}}Class.register(BlockProducer);class HeaderChain{constructor(e){if(!e||!Array.isArray(e)||!NumberUtils.isUint16(e.length)||e.some(e=>!(e instanceof BlockHeader)))throw new Error("Malformed headers");this._headers=e}static unserialize(e){const t=e.readUint16(),s=[];for(let r=0;r<t;r++)s.push(BlockHeader.unserialize(e));return new HeaderChain(s)}serialize(e){(e=e||new SerialBuffer(this.serializedSize)).writeUint16(this._headers.length);for(const t of this._headers)t.serialize(e);return e}get serializedSize(){return 2+this._headers.reduce((e,t)=>e+t.serializedSize,0)}async verify(){for(let e=this._headers.length-1;e>=1;e--)if(!this._headers[e].isImmediateSuccessorOf(this._headers[e-1]))return!1;return!0}toString(){return`HeaderChain{length=${this.length}}`}get length(){return this._headers.length}get headers(){return this._headers}get head(){return this._headers[this.length-1]}get tail(){return this._headers[0]}totalDifficulty(){let e=new BigNumber(0);for(const t of this._headers)e=e.plus(t.difficulty);return e}}Class.register(HeaderChain);class ChainProof{constructor(e,t){if(!(e instanceof BlockChain&&e.length))throw new Error("Malformed prefix");if(!(t instanceof HeaderChain))throw new Error("Malformed suffix");this._prefix=e;this._suffix=t}static unserialize(e){const t=BlockChain.unserialize(e),s=HeaderChain.unserialize(e);return new ChainProof(t,s)}serialize(e){e=e||new SerialBuffer(this.serializedSize);this._prefix.serialize(e);this._suffix.serialize(e);return e}get serializedSize(){return this._prefix.serializedSize+this._suffix.serializedSize}async verify(){return!!this._prefix.isAnchored()&&(!(!(await this._prefix.verify())||!(await this._suffix.verify()))&&(!(this._suffix.length>0&&!this._suffix.tail.isImmediateSuccessorOf(this._prefix.head.header))&&!!this._verifyDifficulty()))}_verifyDifficulty(){const e=this.prefix.denseSuffix().map(e=>e.header).concat(this.suffix.headers);let t=new BigNumber(0);const s=[];for(let n=0;n<e.length;n++){t=t.plus(e[n].difficulty);s[n]=new BigNumber(t)}let r=e.length-2;if(r>=0&&e[r].height<Policy.difficultyBlockWindow(e[r].height))return!0;for(;r>=0;){let t=r-Policy.difficultyBlockWindow(e[r].height);if(t<0){if(1!==e[0].height)break;t=0}const n=e[r],i=e[t],o=s[r].minus(s[t]),a=BlockUtils.getNextTarget(n,i,o),c=BlockUtils.targetToCompact(a),h=e[r+1];if(h.nBits!==c){Log.w(ChainProof,`Block target mismatch: expected=${c}, got=${h.nBits}`);return!1}--r}return!0}toString(){return`ChainProof{prefix=${this._prefix.length}, suffix=${this._suffix.length}, height=${this.head.height}}`}get prefix(){return this._prefix}get suffix(){return this._suffix}get head(){return this._suffix.length>0?this._suffix.head:this._prefix.head.header}}Class.register(ChainProof);class ChainData{static async initial(e,t){const s=await e.pow(),r=BlockUtils.realDifficulty(s),n=BlockUtils.getHashDepth(s);t?t=t.copyAndAdd(n):(t=new SuperBlockCounts).add(n);return new ChainData(e,e.difficulty,r,t,!0)}constructor(e,t,s,r,n=!1,i=null){this._head=e;this._totalDifficulty=t;this._totalWork=s;this._superBlockCounts=r;this._onMainChain=n;this._mainChainSuccessor=i;this._height=e.height}toObj(){Assert.that(this._head.header._pow instanceof Hash,"Expected cached PoW hash");return{_head:this._head.toLight().serialize(),_totalDifficulty:this._totalDifficulty.toString(),_totalWork:this._totalWork.toString(),_superBlockCounts:this._superBlockCounts.array,_onMainChain:this._onMainChain,_mainChainSuccessor:this._mainChainSuccessor?this._mainChainSuccessor.serialize():null,_height:this._head.height,_pow:this._head.header._pow.serialize()}}static fromObj(e,t){if(!e)return null;const s=Block.unserialize(new SerialBuffer(e._head));s.header._pow=Hash.unserialize(new SerialBuffer(e._pow));s.header._hash=t?Hash.fromBase64(t):null;const r=new SuperBlockCounts(e._superBlockCounts),n=e._mainChainSuccessor?Hash.unserialize(new SerialBuffer(e._mainChainSuccessor)):null;return new ChainData(s,new BigNumber(e._totalDifficulty),new BigNumber(e._totalWork),r,e._onMainChain,n)}shallowCopy(){return new ChainData(this.head.shallowCopy(),this.totalDifficulty,this.totalWork,this.superBlockCounts,this.onMainChain,this.mainChainSuccessor)}async nextChainData(e){Assert.that(this._totalDifficulty>0);const t=await e.pow(),s=this.totalDifficulty.plus(e.difficulty),r=this.totalWork.plus(BlockUtils.realDifficulty(t)),n=this.superBlockCounts.copyAndAdd(BlockUtils.getHashDepth(t));return new ChainData(e,s,r,n)}async previousChainData(e){Assert.that(this._totalDifficulty>0);const t=await this.head.pow(),s=this.totalDifficulty.minus(this.head.difficulty),r=this.totalWork.minus(BlockUtils.realDifficulty(t)),n=this.superBlockCounts.copyAndSubtract(BlockUtils.getHashDepth(t));return new ChainData(e,s,r,n)}get head(){return this._head}get totalDifficulty(){return this._totalDifficulty}get totalWork(){return this._totalWork}get superBlockCounts(){return this._superBlockCounts}get onMainChain(){return this._onMainChain}set onMainChain(e){this._onMainChain=e}get mainChainSuccessor(){return this._mainChainSuccessor}set mainChainSuccessor(e){this._mainChainSuccessor=e}}Class.register(ChainData);class SuperBlockCounts{constructor(e=[]){this._arr=e}add(e){Assert.that(NumberUtils.isUint8(e));for(let t=0;t<=e;t++)this._arr[t]=this.get(t)+1}subtract(e){Assert.that(NumberUtils.isUint8(e));for(let t=0;t<=e;t++){this._arr[t]--;Assert.that(this._arr[t]>=0)}}copyAndAdd(e){const t=new SuperBlockCounts(this._arr.slice());t.add(e);return t}copyAndSubtract(e){const t=new SuperBlockCounts(this._arr.slice());t.subtract(e);return t}get(e){Assert.that(NumberUtils.isUint8(e));return this._arr[e]||0}getCandidateDepth(e){for(let t=this._arr.length-1;t>=0;t--)if(this._arr[t]>=e)return t;return 0}get length(){return this._arr.length}get array(){return this._arr}}Class.register(SuperBlockCounts);class ChainDataStore{static initPersistent(e){const t=e.createObjectStore("ChainData",{codec:new ChainDataStoreCodec,enableLruCache:ChainDataStore.CHAINDATA_CACHING_ENABLED,lruCacheSize:ChainDataStore.CHAINDATA_CACHE_SIZE});ChainDataStore._createIndexes(t);e.createObjectStore("Block",{codec:new BlockStoreCodec,enableLruCache:ChainDataStore.BLOCKS_CACHING_ENABLED,lruCacheSize:ChainDataStore.BLOCKS_CACHE_SIZE,rawLruCacheSize:ChainDataStore.BLOCKS_RAW_CACHE_SIZE})}static getPersistent(e){const t=e.getObjectStore("ChainData"),s=e.getObjectStore("Block");return new ChainDataStore(t,s)}static createVolatile(){const e=JDB.JungleDB.createVolatileObjectStore({codec:new ChainDataStoreCodec}),t=JDB.JungleDB.createVolatileObjectStore({codec:new BlockStoreCodec});ChainDataStore._createIndexes(e);return new ChainDataStore(e,t)}static _createIndexes(e){e.createIndex("height",["_height"],{lmdbKeyEncoding:JDB.JungleDB.NUMBER_ENCODING,leveldbKeyEncoding:JDB.JungleDB.NUMBER_ENCODING})}constructor(e,t){this._chainStore=e;this._blockStore=t}async getChainData(e,t=!1){let s=await this._chainStore.get(e.toBase64());s&&(s=s.shallowCopy());if(!s||!t)return s;const r=await this._blockStore.get(e.toBase64());r&&r.isFull()&&(s.head._body=r.body);return s}putChainData(e,t,s=!0){const r=t.shallowCopy();r.head._body=null;if(this._chainStore instanceof JDB.Transaction){this._chainStore.putSync(e.toBase64(),r);s&&t.head.isFull()&&this._blockStore.putSync(e.toBase64(),t.head);return Promise.resolve(!0)}if(s&&t.head.isFull()){const s=this._chainStore.synchronousTransaction();s.putSync(e.toBase64(),r);const n=this._blockStore.synchronousTransaction();n.putSync(e.toBase64(),t.head);return JDB.JungleDB.commitCombined(s,n)}return this._chainStore.put(e.toBase64(),r)}putChainDataSync(e,t,s=!0){const r=t.shallowCopy();r.head._body=null;Assert.that(this._chainStore instanceof JDB.Transaction);this._chainStore.putSync(e.toBase64(),r);s&&t.head.isFull()&&this._blockStore.putSync(e.toBase64(),t.head)}removeChainDataSync(e){Assert.that(this._chainStore instanceof JDB.Transaction);this._chainStore.removeSync(e.toBase64());this._blockStore.removeSync(e.toBase64())}async getBlock(e,t=!1){if(t){const t=await this._blockStore.get(e.toBase64());if(t)return t}const s=await this._chainStore.get(e.toBase64());return s?s.head:null}async getRawBlock(e,t=!1){const s=await this._chainStore.get(e.toBase64());if(!s||!s.onMainChain&&!t)return null;const r=await this._blockStore.get(e.toBase64(),{raw:!0});return r?new Uint8Array(r):null}async getChainDataCandidatesAt(e){const t=await this._chainStore.values(JDB.Query.eq("height",e));return t&&t.length?t:undefined}async getChainDataAt(e,t=!1){const s=await this.getChainDataCandidatesAt(e);if(!s)return undefined;for(const r of s)if(r.onMainChain){const e=r.shallowCopy();if(t){const t=await this._blockStore.get(r.head.hash().toBase64());t&&(e.head._body=t.body)}return e}return null}async getBlockAt(e,t=!1){const s=await this.getChainDataAt(e,t);return s?s.head:null}async getSuccessorBlocks(e){const t=await this.getChainDataCandidatesAt(e.height+1);if(!t)return[];const s=[];for(const r of t)r.head.prevHash.equals(e.hash())&&s.push(r.head);return s}async getNearestBlockAt(e,t=!0){const s=this._chainStore.index("height"),r=t?await s.maxValues(JDB.KeyRange.upperBound(e)):await s.minValues(JDB.KeyRange.lowerBound(e));if(!r||!r.length)return undefined;for(const n of r)if(n.onMainChain)return n.head;return null}getBlocks(e,t=500,s=!0){return t<=0?Promise.resolve([]):s?this.getBlocksForward(e,t):this.getBlocksBackward(e,t)}async getBlocksForward(e,t=500){let s=await this._chainStore.get(e.toBase64());if(!s)return[];const r=[];for(;r.length<t&&s.mainChainSuccessor;){if(!(s=await this._chainStore.get(s.mainChainSuccessor.toBase64())))return r;r.push(s.head)}return r}async getBlocksBackward(e,t=500,s=!1){const r=s?e=>this._blockStore.get(e):e=>this._chainStore.get(e).then(e=>e.head),n=await this._chainStore.get(e.toBase64());if(!n)return[];let i=n.head;const o=[];for(;o.length<t&&i.height>1;){if(!(i=await r(i.prevHash.toBase64())))return o;o.push(i)}return o}async getHead(){const e=await this._chainStore.get("main");return e?Hash.fromBase64(e):undefined}setHead(e){return this._chainStore.put("main",e.toBase64())}setHeadSync(e){Assert.that(this._chainStore instanceof JDB.SynchronousTransaction);this._chainStore.putSync("main",e.toBase64())}transaction(e=!0){const t=this._chainStore.transaction(e),s=this._blockStore.transaction(e);return new ChainDataStore(t,s)}synchronousTransaction(e=!0){const t=this._chainStore.synchronousTransaction(e),s=this._blockStore.synchronousTransaction(e);return new ChainDataStore(t,s)}commit(){return this._chainStore instanceof JDB.Transaction?JDB.JungleDB.commitCombined(this._chainStore,this._blockStore):Promise.resolve()}abort(){return Promise.all([this._chainStore.abort(),this._blockStore.abort()])}snapshot(){const e=this._chainStore.snapshot(),t=this._blockStore.snapshot();return new ChainDataStore(e,t)}truncate(){if(this._chainStore instanceof JDB.Transaction){this._chainStore.truncateSync();this._blockStore.truncateSync();return Promise.resolve(!0)}const e=this._chainStore.transaction();e.truncateSync();const t=this._blockStore.transaction();t.truncateSync();return JDB.JungleDB.commitCombined(e,t)}get txs(){return this._chainStore instanceof JDB.Transaction?[this._chainStore,this._blockStore]:[]}}ChainDataStore.CHAINDATA_CACHING_ENABLED=!0;ChainDataStore.CHAINDATA_CACHE_SIZE=5e3;ChainDataStore.BLOCKS_CACHING_ENABLED=!0;ChainDataStore.BLOCKS_CACHE_SIZE=0;ChainDataStore.BLOCKS_RAW_CACHE_SIZE=500;Class.register(ChainDataStore);class ChainDataStoreCodec{encode(e){return"string"==typeof e?e:e.toObj()}decode(e,t){return"string"==typeof e?e:ChainData.fromObj(e,t)}get valueEncoding(){return JDB.JungleDB.JSON_ENCODING}}class BlockStoreCodec{encode(e){return e.serialize()}decode(e,t){const s=Block.unserialize(new SerialBuffer(e));s.header._hash=Hash.fromBase64(t);return s}get valueEncoding(){return JDB.JungleDB.BINARY_ENCODING}}class MempoolTransactionSet{constructor(e){this._transactions=new SortedList(e)}add(e){this._transactions.add(e);return this}remove(e){this._transactions.remove(e);return this}copyAndAdd(e){const t=this._transactions.copy();t.add(e);return new MempoolTransactionSet(t.values())}get transactions(){return this._transactions.values()}get sender(){return this._transactions.length>0?this._transactions.values()[0].sender:null}get senderType(){return this._transactions.length>0?this._transactions.values()[0].senderType:undefined}get length(){return this._transactions.length}numBelowFeePerByte(e){let t=0;for(const s of this._transactions)s.feePerByte.lt(e)&&t++;return t}toString(){return`MempoolTransactionSet{length=${this.length}}`}}Class.register(MempoolTransactionSet);class MempoolFilter{constructor(){this._blacklist=new LimitInclusionHashSet(MempoolFilter.BLACKLIST_SIZE)}acceptsTransaction(e){return e.fee.gte(MempoolFilter.FEE)&&e.value.gte(MempoolFilter.VALUE)&&e.value.plus(e.fee).gte(MempoolFilter.TOTAL_VALUE)&&(!e.hasFlag(Transaction.Flag.CONTRACT_CREATION)||e.fee.gte(MempoolFilter.CONTRACT_FEE)&&e.feePerByte.gte(MempoolFilter.CONTRACT_FEE_PER_BYTE)&&e.value.gte(MempoolFilter.CONTRACT_VALUE))}acceptsRecipientAccount(e,t,s){return s.balance.gte(MempoolFilter.RECIPIENT_BALANCE)&&(!t.isInitial()||e.fee.gte(MempoolFilter.CREATION_FEE)&&e.feePerByte.gte(MempoolFilter.CREATION_FEE_PER_BYTE)&&e.value.gte(MempoolFilter.CREATION_VALUE))}acceptsSenderAccount(e,t,s){return s.balance.gte(MempoolFilter.SENDER_BALANCE)||s.isInitial()||s.isToBePruned()}blacklist(e){this._blacklist.add(e)}isBlacklisted(e){return this._blacklist.contains(e)}}MempoolFilter.BLACKLIST_SIZE=25e3;MempoolFilter.FEE=0;MempoolFilter.VALUE=0;MempoolFilter.TOTAL_VALUE=0;MempoolFilter.RECIPIENT_BALANCE=0;MempoolFilter.SENDER_BALANCE=0;MempoolFilter.CREATION_FEE=0;MempoolFilter.CREATION_FEE_PER_BYTE=0;MempoolFilter.CREATION_VALUE=0;MempoolFilter.CONTRACT_FEE=0;MempoolFilter.CONTRACT_FEE_PER_BYTE=0;MempoolFilter.CONTRACT_VALUE=0;Class.register(MempoolFilter);class Mempool extends Observable{constructor(e,t){super();this._blockchain=e;this._accounts=t;this._transactionsByFeePerByte=new SortedList;this._transactionsByHash=new HashMap;this._transactionSetBySender=new HashMap;this._transactionSetByRecipient=new HashMap;this._filter=new MempoolFilter;this._synchronizer=new Synchronizer;e.on("head-changed",(e,t)=>{t||this._evictTransactions()["catch"](Log.e.tag(Mempool))});e.on("rebranched",async e=>{await this._evictTransactions();await this._restoreTransactions(e)})}pushTransaction(e){return this._synchronizer.push(()=>this._pushTransaction(e))}async _pushTransaction(e){const t=e.hash();if(this._transactionsByHash.contains(t))return Mempool.ReturnCode.KNOWN;if(!this._filter.acceptsTransaction(e)){this._filter.blacklist(t);return Mempool.ReturnCode.FILTERED}const s=this._transactionSetBySender.get(e.sender)||new MempoolTransactionSet;if(!e.verify())return Mempool.ReturnCode.INVALID;try{const s=await this._accounts.get(e.recipient),r=s.withIncomingTransaction(e,this._blockchain.height+1).withContractCommand(e,this._blockchain.height+1);if(!this._filter.acceptsRecipientAccount(e,s,r)){this._filter.blacklist(t);return Mempool.ReturnCode.FILTERED}}catch(c){Log.d(Mempool,()=>`Rejected transaction ${t.toHex()} from ${e.sender.toUserFriendlyAddress()} - ${c.message}`);return Mempool.ReturnCode.INVALID}let r;try{r=await this._accounts.get(e.sender,e.senderType)}catch(c){Log.d(Mempool,()=>`Rejected transaction ${t.toHex()} from ${e.sender.toUserFriendlyAddress()} - ${c.message}`);return Mempool.ReturnCode.INVALID}const n=[],i=[];let o=r;for(const h of s.copyAndAdd(e).transactions){let t,s="transactions per sender exceeded";try{if(n.length<Mempool.TRANSACTIONS_PER_SENDER_MAX){o=o.withOutgoingTransaction(h,this._blockchain.height+1,this._blockchain.transactionCache);n.push(h);continue}}catch(c){t=c;s=c.message}if(h.equals(e)){Log.d(Mempool,()=>`Rejected transaction from ${e.sender.toUserFriendlyAddress()} - ${s}`);return t instanceof Account.DoubleTransactionError?Mempool.ReturnCode.MINED:t instanceof Account.ValidityError?Mempool.ReturnCode.EXPIRED:Mempool.ReturnCode.INVALID}i.push(h)}if(!this._filter.acceptsSenderAccount(e,r,o)){this._filter.blacklist(t);return Mempool.ReturnCode.FILTERED}for(const h of i)this._removeTransaction(h);this._transactionsByFeePerByte.add(e);this._transactionsByHash.put(t,e);this._transactionSetBySender.put(e.sender,new MempoolTransactionSet(n));const a=this._transactionSetByRecipient.get(e.recipient)||new HashSet;a.add(e.hash());this._transactionSetByRecipient.put(e.recipient,a);this.fire("transaction-added",e);this._transactionsByFeePerByte.length>Mempool.SIZE_MAX&&this._popLowFeeTransaction();return Mempool.ReturnCode.ACCEPTED}_popLowFeeTransaction(){const e=this._transactionsByFeePerByte.pop(),t=this._transactionSetBySender.get(e.sender);t.remove(e);0===t.length&&this._transactionSetBySender.remove(e.sender);const s=this._transactionSetByRecipient.get(e.recipient);s?1===s.length?this._transactionSetByRecipient.remove(e.recipient):s.remove(e.hash()):Log.e(Mempool,`Invalid state: no transactionsByRecipient for ${e}`);this._transactionsByHash.remove(e.hash());this.fire("transaction-removed",e)}_removeTransaction(e){this._transactionsByHash.remove(e.hash());this._transactionsByFeePerByte.remove(e);const t=this._transactionSetByRecipient.get(e.recipient);if(t){1===t.length?this._transactionSetByRecipient.remove(e.recipient):t.remove(e.hash());this.fire("transaction-removed",e)}else Log.e(Mempool,`Invalid state: no transactionsByRecipient for ${e}`)}getTransaction(e){return this._transactionsByHash.get(e)}*transactionGenerator(e=Infinity){let t=0;for(const s of this._transactionsByFeePerByte){const r=s.serializedSize;if(!(t+r>=e)){yield s;t+=r}}}getTransactions(e=Infinity){return Array.from(this.transactionGenerator(e))}async getTransactionsForBlock(e){const t=this.getTransactions(e);let s=(await this._accounts.gatherToBePrunedAccounts(t,this._blockchain.height+1,this._blockchain.transactionCache)).reduce((e,t)=>e+t.serializedSize,0)+t.reduce((e,t)=>e+t.serializedSize,0);for(;s>e;)s-=t.pop().serializedSize;t.sort((e,t)=>e.compareBlockOrder(t));return t}getPendingTransactions(e){return this.getTransactionsBySender(e)}getTransactionsBySender(e){const t=this._transactionSetBySender.get(e);return t?t.transactions:[]}getTransactionsByRecipient(e){const t=this._transactionSetByRecipient.get(e);if(!t)return[];const s=[];for(const r of t.valueIterator()){const e=this._transactionsByHash.get(r);Assert.that(!!e);s.push(e)}return s}getTransactionsByAddresses(e,t=Infinity){const s=[];for(const r of e){const e=this.getTransactionsBySender(r);for(const r of e){if(s.length>=t)return s;s.push(r)}const n=this.getTransactionsByRecipient(r);for(const r of n){if(s.length>=t)return s;s.push(r)}}return s}isFiltered(e){return this._filter.isBlacklisted(e)}_restoreTransactions(e){return this._synchronizer.push(async()=>{for(let t=e.length-1;t>=0;t--)for(const s of e[t].transactions)await this._pushTransaction(s)})}_evictTransactions(){return this._synchronizer.push(()=>this.__evictTransactions())}async __evictTransactions(){for(const t of this._transactionSetBySender.keys()){const s=this._transactionSetBySender.get(t);try{const r=await this._accounts.get(s.sender,s.senderType),n=[];let i=r;for(const t of s.transactions)try{const s=i.withOutgoingTransaction(t,this._blockchain.height+1,this._blockchain.transactionCache);(await this._accounts.get(t.recipient)).withIncomingTransaction(t,this._blockchain.height+1).withContractCommand(t,this._blockchain.height+1);n.push(t);i=s}catch(e){this._removeTransaction(t)}0===n.length?this._transactionSetBySender.remove(t):this._transactionSetBySender.put(t,new MempoolTransactionSet(n))}catch(e){for(const t of s.transactions)this._removeTransaction(t);this._transactionSetBySender.remove(t)}}this.fire("transactions-ready")}get length(){return this._transactionsByHash.length}get queue(){return this._synchronizer}}Mempool.TRANSACTION_RELAY_FEE_MIN=1;Mempool.TRANSACTIONS_PER_SENDER_MAX=2100;Mempool.FREE_TRANSACTIONS_PER_SENDER_MAX=10;Mempool.SIZE_MAX=21e5;Mempool.ReturnCode={EXPIRED:-5,MINED:-4,FILTERED:-3,FEE_TOO_LOW:-2,INVALID:-1,ACCEPTED:1,KNOWN:2};Class.register(Mempool);class InvRequestManager{constructor(){this._vectorsToRequest=new HashMap;this._timers=new Timers}askToRequestVector(e,t){if(e.syncing||this._vectorsToRequest.length>InvRequestManager.MAX_INV_MANAGED)e.requestVector(t);else if(this._vectorsToRequest.contains(t)){const s=this._vectorsToRequest.get(t);s.current.peer.channel.closed&&(s.current=null);if(null===s.current){s.current=e;this._request(t)}else s.waiting.add(e)}else{this._vectorsToRequest.put(t,{current:e,waiting:new Set});this._request(t)}}_request(e){Assert.that(this._vectorsToRequest.contains(e));const t=this._vectorsToRequest.get(e).current;Assert.that(t);t.requestVector(e);this._timers.resetTimeout(e.hash,()=>this.noteVectorNotReceived(t,e),InvRequestManager.MAX_TIME_PER_VECTOR)}noteVectorNotReceived(e,t){if(this._vectorsToRequest.contains(t)){const s=this._vectorsToRequest.get(t);if(s.current!==e)s.waiting["delete"](e);else{this._timers.clearTimeout(t.hash);s.current=null;if(0!==s.waiting.size){s.current=s.waiting.values().next().value;s.waiting["delete"](s.current);this._request(t)}null===s.current&&this._vectorsToRequest.remove(t)}}}noteVectorReceived(e){this._timers.clearTimeout(e.hash);this._vectorsToRequest.remove(e)}}InvRequestManager.MAX_TIME_PER_VECTOR=1e4;InvRequestManager.MAX_INV_MANAGED=1e4;Class.register(InvRequestManager);class BaseConsensusAgent extends Observable{constructor(e,t,s,r){super();this._time=e;this._peer=t;this._synced=!1;this._knownObjects=new LimitInclusionHashSet(BaseConsensusAgent.KNOWN_OBJECTS_COUNT_MAX);this._knownObjects.add(new InvVector(InvVector.Type.BLOCK,t.headHash));this._blocksToRequest=new UniqueQueue;this._txsToRequest=new ThrottledQueue(BaseConsensusAgent.TRANSACTIONS_AT_ONCE+BaseConsensusAgent.FREE_TRANSACTIONS_AT_ONCE,BaseConsensusAgent.TRANSACTIONS_PER_SECOND+BaseConsensusAgent.FREE_TRANSACTIONS_PER_SECOND,1e3,BaseConsensusAgent.REQUEST_TRANSACTIONS_WAITING_MAX);this._objectsInFlight=new HashSet;this._objectsThatFlew=new HashSet;this._objectsProcessing=new HashSet;this._remoteSubscription=Subscription.NONE;this._localSubscription=Subscription.NONE;this._lastSubscriptionChange=null;this._targetSubscription=r||Subscription.ANY;this._timers=new Timers;this._waitingInvVectors=new ThrottledQueue(BaseConsensusAgent.TRANSACTIONS_AT_ONCE,BaseConsensusAgent.TRANSACTIONS_PER_SECOND,1e3,BaseConsensusAgent.REQUEST_TRANSACTIONS_WAITING_MAX);this._timers.setInterval("invVectors",()=>this._sendWaitingInvVectors(),BaseConsensusAgent.TRANSACTION_RELAY_INTERVAL);this._waitingFreeInvVectors=new ThrottledQueue(BaseConsensusAgent.FREE_TRANSACTIONS_AT_ONCE,BaseConsensusAgent.FREE_TRANSACTIONS_PER_SECOND,1e3,BaseConsensusAgent.REQUEST_TRANSACTIONS_WAITING_MAX);this._timers.setInterval("freeInvVectors",()=>this._sendFreeWaitingInvVectors(),BaseConsensusAgent.FREE_TRANSACTION_RELAY_INTERVAL);this._blockProofRequest=null;this._transactionsProofRequest=null;this._transactionReceiptsRequest=null;this._pendingRequests=new HashMap;this._synchronizer=new MultiSynchronizer;this._invRequestManager=s;this._listenersToDisconnect=new Set;this._onToDisconnect(t.channel,"inv",e=>this._onInv(e));this._onToDisconnect(t.channel,"block",e=>this._onBlock(e));this._onToDisconnect(t.channel,"header",e=>this._onHeader(e));this._onToDisconnect(t.channel,"tx",e=>this._onTx(e));this._onToDisconnect(t.channel,"not-found",e=>this._onNotFound(e));this._onToDisconnect(t.channel,"subscribe",e=>this._onSubscribe(e));this._onToDisconnect(t.channel,"get-data",e=>this._onGetData(e));this._onToDisconnect(t.channel,"get-header",e=>this._onGetHeader(e));this._onToDisconnect(t.channel,"block-proof",e=>this._onBlockProof(e));this._onToDisconnect(t.channel,"transactions-proof",e=>this._onTransactionsProof(e));this._onToDisconnect(t.channel,"transaction-receipts",e=>this._onTransactionReceipts(e));this._onToDisconnect(t.channel,"mempool",e=>this._onMempool(e));this._onToDisconnect(t.channel,"get-head",e=>this._onGetHead(e));this._onToDisconnect(t.channel,"head",e=>this._onHead(e));this._onToDisconnect(t.channel,"close",()=>this._onClose());this._requestHead()}_onToDisconnect(e,t,s){const r=e.on(t,s);this._listenersToDisconnect.add({obj:e,type:t,id:r})}_disconnectListeners(){for(const e of this._listenersToDisconnect)e.obj.off(e.type,e.id);this._offAll()}providesServices(...e){return Services.providesServices(this._peer.peerAddress.services,...e)}_requestHead(){this._peer.channel.getHead()}onHeadUpdated(){this._timers.resetTimeout("get-next-head",()=>this._requestHead(),BaseConsensusAgent.HEAD_REQUEST_INTERVAL)}_onGetHead(e){this._peer.channel.head(this._blockchain.head.header)}_onHead(e){this._peer.head=e.header;this.onHeadUpdated()}subscribe(e){this._targetSubscription=e;this._subscribe(e)}_subscribeTarget(){this._subscribe(this._targetSubscription)}_subscribe(e){this._localSubscription=e;this._lastSubscriptionChange=Date.now();this._peer.channel.subscribe(this._localSubscription)}relayBlock(e){if(!this._synced)return!1;if(!this._remoteSubscription.matchesBlock(e))return!1;const t=InvVector.fromBlock(e);if(this._knownObjects.contains(t))return!1;this._peer.channel.inv([t,...this._waitingInvVectors.dequeueMulti(BaseInventoryMessage.VECTORS_MAX_COUNT-1)]);this._timers.timeoutExists(`knows-block-${t.hash.toBase64()}`)||this._timers.setTimeout(`knows-block-${t.hash.toBase64()}`,()=>{this._knownObjects.add(t)},BaseConsensusAgent.KNOWS_OBJECT_AFTER_INV_DELAY);return!0}requestBlock(e){return new Promise((t,s)=>{const r=new InvVector(InvVector.Type.BLOCK,e);if(this._pendingRequests.contains(r))this._pendingRequests.get(r).push({resolve:t,reject:s});else{this._pendingRequests.put(r,[{resolve:t,reject:s}]);this._peer.channel.getData([r]);this._timers.setTimeout(`block-request-${r.hash.toBase64()}`,()=>{const e=this._pendingRequests.get(r);if(e){this._pendingRequests.remove(r);for(const{reject:t}of e)t(new Error("Timeout"))}},BaseConsensusAgent.REQUEST_TIMEOUT)}})}requestTransaction(e){return new Promise((t,s)=>{const r=new InvVector(InvVector.Type.TRANSACTION,e);if(this._pendingRequests.contains(r))this._pendingRequests.get(r).push({resolve:t,reject:s});else{this._pendingRequests.put(r,[{resolve:t,reject:s}]);if(!this._objectsInFlight.contains(r)){this._peer.channel.getData([r]);this._objectsInFlight.add(r)}this._timers.setTimeout(`tx-request-${r.hash.toBase64()}`,()=>{const e=this._pendingRequests.get(r);if(e){this._pendingRequests.remove(r);for(const{reject:t}of e)t(new Error("Timeout"))}},BaseConsensusAgent.REQUEST_TIMEOUT)}})}_sendWaitingInvVectors(){const e=this._waitingInvVectors.dequeueMulti(BaseInventoryMessage.VECTORS_MAX_COUNT);if(e.length>0){this._peer.channel.inv(e);Log.v(BaseConsensusAgent,()=>`[INV] Sent ${e.length} vectors to ${this._peer.peerAddress}`)}}_sendFreeWaitingInvVectors(){const e=[];let t=0;for(;e.length<BaseInventoryMessage.VECTORS_MAX_COUNT&&this._waitingFreeInvVectors.isAvailable()&&t<BaseConsensusAgent.FREE_TRANSACTION_SIZE_PER_INTERVAL;){const s=this._waitingFreeInvVectors.dequeue();e.push(s.inv);t+=s.serializedSize}if(e.length>0){this._peer.channel.inv(e);Log.v(BaseConsensusAgent,()=>`[INV] Sent ${e.length} vectors to ${this._peer.peerAddress}`)}}relayTransaction(e){if(!this._remoteSubscription.matchesTransaction(e)){Log.v(BaseConsensusAgent,`Not sending ${e.hash()} to ${this.peer.peerAddress}: not subscribed`);return!1}const t=InvVector.fromTransaction(e);if(this._knownObjects.contains(t)){Log.v(BaseConsensusAgent,`Not sending ${e.hash()} to ${this.peer.peerAddress}: already knows`);return!1}const s=e.serializedSize;e.fee/s<BaseConsensusAgent.TRANSACTION_RELAY_FEE_MIN?this._waitingFreeInvVectors.enqueue(new FreeTransactionVector(t,s)):this._waitingInvVectors.enqueue(t);this._timers.setTimeout(`knows-tx-${t.hash.toBase64()}`,()=>{this._knownObjects.add(t)},BaseConsensusAgent.KNOWS_OBJECT_AFTER_INV_DELAY);Log.v(BaseConsensusAgent,`Sending ${e.hash()} to ${this.peer.peerAddress}`);return!0}removeTransaction(e){const t=InvVector.fromTransaction(e);this._waitingFreeInvVectors.remove(t);this._waitingInvVectors.remove(t)}knowsBlock(e){const t=new InvVector(InvVector.Type.BLOCK,e);return this._knownObjects.contains(t)}knowsTransaction(e){const t=new InvVector(InvVector.Type.TRANSACTION,e);return this._knownObjects.contains(t)}_onSubscribe(e){this._remoteSubscription=e.subscription}async _onMempool(e){const t=this._getSubscribedMempoolTransactions();let s=[];for(const r of t){s.push(InvVector.fromTransaction(r));if(s.length>=BaseInventoryMessage.VECTORS_MAX_COUNT){this._peer.channel.inv(s);s=[];await new Promise(e=>setTimeout(e,FullConsensusAgent.MEMPOOL_THROTTLE))}}s.length>0&&this._peer.channel.inv(s)}_getSubscribedMempoolTransactions(){return[]}_onInv(e){return this._synchronizer.push("onInv",this.__onInv.bind(this,e))}async __onInv(e){for(const r of e.vectors){this._knownObjects.add(r);this._waitingInvVectors.remove(r);this._waitingFreeInvVectors.remove(r)}const t=[],s=[];for(const r of e.vectors)if(!this._objectsInFlight.contains(r)&&!this._objectsProcessing.contains(r)&&this._shouldRequestData(r))switch(r.type){case InvVector.Type.BLOCK:{const e=await this._getBlock(r.hash,!0);if(e)this._onKnownBlockAnnounced(r.hash,e);else{t.push(r);this._onNewBlockAnnounced(r.hash)}break}case InvVector.Type.TRANSACTION:{const e=this._getTransaction(r.hash);if(e)this._onKnownTransactionAnnounced(r.hash,e);else{s.push(r);this._onNewTransactionAnnounced(r.hash)}break}}Log.v(BaseConsensusAgent,()=>`[INV] ${e.vectors.length} vectors (${t.length} new blocks, ${s.length} new txs) received from ${this._peer.peerAddress}`);if(t.length>0||s.length>0){for(const e of t)this._invRequestManager.askToRequestVector(this,e);for(const e of s)this._invRequestManager.askToRequestVector(this,e)}else this._onNoUnknownObjects()}requestVector(...e){this._blocksToRequest.enqueueAll(e.filter(e=>e.type===InvVector.Type.BLOCK));this._txsToRequest.enqueueAll(e.filter(e=>e.type===InvVector.Type.TRANSACTION));this._timers.clearTimeout("inv");this._blocksToRequest.length+this._txsToRequest.available>=BaseConsensusAgent.REQUEST_THRESHOLD?this._requestData():this._timers.setTimeout("inv",()=>this._requestData(),BaseConsensusAgent.REQUEST_THROTTLE)}_shouldRequestData(e){return!0}_getBlock(e,t=!1,s=!1){throw new Error("not implemented")}_getRawBlock(e,t=!1){throw new Error("not implemented")}_getTransaction(e){throw new Error("not implemented")}_onNewBlockAnnounced(e){}_onKnownBlockAnnounced(e,t){}_onNewTransactionAnnounced(e){}_onKnownTransactionAnnounced(e,t){}_requestData(){if(!this._objectsInFlight.isEmpty())return;if(this._blocksToRequest.isEmpty()&&!this._txsToRequest.isAvailable())return;const e=BaseInventoryMessage.VECTORS_MAX_COUNT;let t=this._blocksToRequest.dequeueMulti(e);t.length<e&&(t=t.concat(this._txsToRequest.dequeueMulti(e-t.length)));this._objectsInFlight.addAll(t);this._doRequestData(t);this._timers.setTimeout("getData",()=>this._noMoreData(),BaseConsensusAgent.REQUEST_TIMEOUT)}_doRequestData(e){if(this._willRequestHeaders()){const t=[],s=[];for(const r of e)r.type===InvVector.Type.BLOCK?t.push(r):s.push(r);this._peer.channel.getHeader(t);this._peer.channel.getData(s)}else this._peer.channel.getData(e)}_willRequestHeaders(){return!1}async _onBlock(e){const t=e.block.hash(),s=new InvVector(InvVector.Type.BLOCK,t),r=this._pendingRequests.get(s);if(!r&&!this._objectsInFlight.contains(s)&&!this._objectsThatFlew.contains(s)){Log.w(BaseConsensusAgent,`Unsolicited block ${t} received from ${this._peer.peerAddress}, discarding`);return}const n=e.block.isFull()?e.block.body.transactions:[],i=n.map(e=>this._getTransaction(e.hash()));for(let a=0;a<n.length;a++){const e=i[a];e&&(n[a]=e)}if(r){this._pendingRequests.remove(s);this._timers.clearTimeout(`block-request-${s.hash.toBase64()}`);for(const{resolve:t}of r)try{t(e.block)}catch(o){}}else{if(!this._peer.head&&this._peer.headHash.equals(t)||this._peer.head&&this._peer.head.height<e.block.height){this._peer.head=e.block.header;this.onHeadUpdated()}this._onObjectReceived(s);this._objectsProcessing.add(s);await this._processBlock(t,e.block);this._onObjectProcessed(s);this._invRequestManager.noteVectorReceived(InvVector.fromBlock(e.block))}}async _processBlock(e,t){}async _onHeader(e){const t=e.header.hash(),s=new InvVector(InvVector.Type.BLOCK,t);if(this._objectsInFlight.contains(s)||this._objectsThatFlew.contains(s)){if(!this._peer.head&&this._peer.headHash.equals(t)||this._peer.head&&this._peer.head.height<e.header.height){this._peer.head=e.header;this.onHeadUpdated()}this._onObjectReceived(s);this._objectsProcessing.add(s);await this._processHeader(t,e.header);this._onObjectProcessed(s)}else Log.w(BaseConsensusAgent,`Unsolicited header ${t} received from ${this._peer.peerAddress}, discarding`)}async _processHeader(e,t){}async _onTx(e){const t=e.transaction.hash(),s=new InvVector(InvVector.Type.TRANSACTION,t);if(!this._objectsInFlight.contains(s)&&!this._objectsThatFlew.contains(s)){Log.w(BaseConsensusAgent,`Unsolicited transaction ${t} received from ${this._peer.peerAddress}, discarding`);return}this._invRequestManager.noteVectorReceived(InvVector.fromTransaction(e.transaction));this._onObjectReceived(s);this._objectsProcessing.add(s);this._localSubscription.matchesTransaction(e.transaction)&&await this._processTransaction(t,e.transaction);const r=this._pendingRequests.get(s);if(r){this._pendingRequests.remove(s);this._timers.clearTimeout(`tx-request-${s.hash.toBase64()}`);for(const{resolve:t}of r)try{t(e.transaction)}catch(n){}}else!this._localSubscription.matchesTransaction(e.transaction)&&this._lastSubscriptionChange+BaseConsensusAgent.SUBSCRIPTION_CHANGE_GRACE_PERIOD>Date.now()&&this._peer.channel.close(CloseType.TRANSACTION_NOT_MATCHING_SUBSCRIPTION,"received transaction not matching our subscription");this._onObjectProcessed(s)}async _processTransaction(e,t){}_onNotFound(e){Log.d(BaseConsensusAgent,`[NOTFOUND] ${e.vectors.length} unknown objects received from ${this._peer.peerAddress}`);for(const s of e.vectors){const e=this._pendingRequests.get(s);if(e){this._pendingRequests.remove(s);this._timers.clearTimeout((s.type===InvVector.Type.BLOCK?"block":"tx")+"-request-"+s.hash.toBase64());for(const{reject:s}of e)try{s(new Error("Not found"))}catch(t){}}if(this._objectsInFlight.contains(s)){this._invRequestManager.noteVectorNotReceived(this,s);this._onObjectReceived(s)}}}_onObjectReceived(e){if(!this._objectsInFlight.isEmpty()){this._objectsInFlight.remove(e);this._objectsInFlight.isEmpty()?this._noMoreData():this._timers.resetTimeout("getData",()=>this._noMoreData(),BaseConsensusAgent.REQUEST_TIMEOUT)}}_noMoreData(){this._timers.clearTimeout("getData");for(const e of this._objectsInFlight.values())this._invRequestManager.noteVectorNotReceived(this,e);this._objectsThatFlew.addAll(this._objectsInFlight.values());this._objectsInFlight.clear();!this._blocksToRequest.isEmpty()||this._txsToRequest.isAvailable()?this._requestData():this._onAllObjectsReceived()}_onNoUnknownObjects(){}_onAllObjectsReceived(){}_onObjectProcessed(e){this._objectsProcessing.remove(e);this._objectsProcessing.isEmpty()&&this._onAllObjectsProcessed()}_onAllObjectsProcessed(){}async _onGetData(e){for(const s of e.vectors)this._knownObjects.add(s);const t=[];for(const s of e.vectors)switch(s.type){case InvVector.Type.BLOCK:{const e=await this._getRawBlock(s.hash,!1);e?this._peer.channel.rawBlock(e):t.push(s);break}case InvVector.Type.TRANSACTION:{const e=this._getTransaction(s.hash);if(e){this._peer.channel.tx(e);this.fire("transaction-relayed",e)}else t.push(s);break}}t.length&&this._peer.channel.notFound(t)}async _onGetHeader(e){for(const s of e.vectors)this._knownObjects.add(s);const t=[];for(const s of e.vectors)switch(s.type){case InvVector.Type.BLOCK:{const e=await this._getBlock(s.hash);e?this._peer.channel.header(e.header):t.push(s);break}case InvVector.Type.TRANSACTION:}t.length&&this._peer.channel.notFound(t)}getBlockProof(e,t){return this._synchronizer.push("getBlockProof",this._getBlockProof.bind(this,e,t))}_getBlockProof(e,t){Assert.that(null===this._blockProofRequest);Log.v(BaseConsensusAgent,()=>`Requesting BlockProof for ${e} from ${this._peer.peerAddress}`);return new Promise((s,r)=>{this._blockProofRequest={blockHashToProve:e,knownBlock:t,resolve:s,reject:r};this._peer.channel.getBlockProof(e,t.hash());this._peer.channel.expectMessage(Message.Type.BLOCK_PROOF,()=>{this._blockProofRequest=null;r(new Error("Timeout"))},BaseConsensusAgent.BLOCK_PROOF_REQUEST_TIMEOUT)})}getBlockProofAt(e,t){if(this._peer.version<2)throw new Error("Request not supported by peer version");return this._synchronizer.push("getBlockProof",this._getBlockProofAt.bind(this,e,t))}_getBlockProofAt(e,t){Assert.that(null===this._blockProofRequest);Log.v(BaseConsensusAgent,()=>`Requesting BlockProof at ${e} from ${this._peer.peerAddress}`);return new Promise((s,r)=>{this._blockProofRequest={blockHeightToProve:e,knownBlock:t,resolve:s,reject:r};this._peer.channel.getBlockProofAt(e,t.hash());this._peer.channel.expectMessage(Message.Type.BLOCK_PROOF,()=>{this._blockProofRequest=null;r(new Error("Timeout"))},BaseConsensusAgent.BLOCK_PROOF_REQUEST_TIMEOUT)})}async _onBlockProof(e){Log.v(BaseConsensusAgent,()=>`[BLOCK-PROOF] Received from ${this._peer.peerAddress}: proof=${e.proof} (${e.serializedSize} bytes)`);if(!this._blockProofRequest){Log.w(BaseConsensusAgent,`Unsolicited header proof received from ${this._peer.peerAddress}`);return}const{blockHashToProve:t,blockHeightToProve:s,knownBlock:r,resolve:n,reject:i}=this._blockProofRequest;this._blockProofRequest=null;if(!e.hasProof()||0===e.proof.length){i(new Error("Block proof request was rejected"));return}const o=e.proof;if(o.tail.hash().equals(t)||o.tail.height===s)if(await r.isInterlinkSuccessorOf(o.head))if(await o.verify())if((await Promise.all(o.blocks.map(e=>e.verify(this._time)))).every(e=>e))n(o.tail);else{Log.w(BaseConsensusAgent,`Invalid BlockProof received from ${this._peer.peerAddress}`);this._peer.channel.close(CloseType.INVALID_BLOCK_PROOF,"Invalid BlockProof");i(new Error("Invalid BlockProof"))}else{Log.w(BaseConsensusAgent,`Invalid BlockProof received from ${this._peer.peerAddress}`);this._peer.channel.close(CloseType.INVALID_BLOCK_PROOF,"Invalid BlockProof");i(new Error("Invalid BlockProof"))}else{Log.w(BaseConsensusAgent,`Received BlockProof with invalid head block from ${this._peer.peerAddress}`);i(new Error("Invalid head block"))}else{Log.w(BaseConsensusAgent,`Received BlockProof with invalid tail block from ${this._peer.peerAddress}`);i(new Error("Invalid tail block"))}}getTransactionsProof(e,t){return this.getTransactionsProofByAddresses(e,t)}getTransactionsProofByAddresses(e,t){return this._synchronizer.push("getTransactionsProof",this._getTransactionsProofByAddresses.bind(this,e,t))}getTransactionsProofByHashes(e,t){if(this._peer.version<2)throw new Error("Request not supported by peer version");return this._synchronizer.push("getTransactionsProof",this._getTransactionsProofByHashes.bind(this,e,t))}_getTransactionsProofByAddresses(e,t){Assert.that(null===this._transactionsProofRequest);Log.v(BaseConsensusAgent,()=>`Requesting TransactionsProof for ${t}@${e.height} from ${this._peer.peerAddress}`);return new Promise((s,r)=>{this._transactionsProofRequest={addresses:t,block:e,resolve:s,reject:r};this._peer.channel.getTransactionsProofByAddresses(e.hash(),t);this._peer.channel.expectMessage(Message.Type.TRANSACTIONS_PROOF,()=>{this._transactionsProofRequest=null;this._peer.channel.close(CloseType.GET_TRANSACTIONS_PROOF_TIMEOUT,"getTransactionsProof timeout");r(new Error("Timeout"))},BaseConsensusAgent.TRANSACTIONS_PROOF_REQUEST_TIMEOUT)})}_getTransactionsProofByHashes(e,t){Assert.that(null===this._transactionsProofRequest);Log.v(BaseConsensusAgent,()=>`Requesting TransactionsProof for ${t}@${e.height} from ${this._peer.peerAddress}`);return new Promise((s,r)=>{this._transactionsProofRequest={hashes:t,block:e,resolve:s,reject:r};this._peer.channel.getTransactionsProofByHashes(e.hash(),t);this._peer.channel.expectMessage(Message.Type.TRANSACTIONS_PROOF,()=>{this._transactionsProofRequest=null;this._peer.channel.close(CloseType.GET_TRANSACTIONS_PROOF_TIMEOUT,"getTransactionsProof timeout");r(new Error("Timeout"))},BaseConsensusAgent.TRANSACTIONS_PROOF_REQUEST_TIMEOUT)})}_onTransactionsProof(e){Log.v(BaseConsensusAgent,()=>`[TRANSACTIONS-PROOF] Received from ${this._peer.peerAddress}:`+` blockHash=${e.blockHash}, proof=${e.proof} (${e.serializedSize} bytes)`);if(!this._transactionsProofRequest){Log.w(BaseConsensusAgent,`Unsolicited transactions proof received from ${this._peer.peerAddress}`);return}const{addresses:t=[],hashes:s=[],block:r,resolve:n,reject:i}=this._transactionsProofRequest;this._transactionsProofRequest=null;if(!e.hasProof()){Log.w(BaseConsensusAgent,`TransactionsProof request was rejected by ${this._peer.peerAddress}`);i(new Error("TransactionsProof request was rejected"));return}if(!r.hash().equals(e.blockHash)){Log.w(BaseConsensusAgent,`Received TransactionsProof for invalid reference block from ${this._peer.peerAddress}`);i(new Error("Invalid reference block"));return}const o=e.proof;let a=null;try{a=o.root()}catch(c){}if(r.bodyHash.equals(a)){for(const e of o.transactions)if(!t.some(t=>e.sender.equals(t)||e.recipient.equals(t))&&!s.some(t=>e.hash().equals(t))){Log.w(BaseConsensusAgent,`TransactionsProof with unwanted transactions received from ${this._peer.peer}`);this._peer.channel.close(CloseType.INVALID_TRANSACTION_PROOF,"TransactionsProof contains unwanted transactions");i(new Error("TransactionsProof contains unwanted transactions"));return}n(o.transactions)}else{Log.w(BaseConsensusAgent,`Invalid TransactionsProof received from ${this._peer.peerAddress}`);this._peer.channel.close(CloseType.INVALID_TRANSACTION_PROOF,"Invalid TransactionsProof");i(new Error("Invalid TransactionsProof"))}}getTransactionReceipts(e){return this.getTransactionReceiptsByAddress(e)}getTransactionReceiptsByAddress(e,t){return this._synchronizer.push("getTransactionReceipts",this._getTransactionReceiptsByAddress.bind(this,e,t))}getTransactionReceiptsByHashes(e){if(this._peer.version<2)throw new Error("Request not supported by peer version");return this._synchronizer.push("getTransactionReceipts",this._getTransactionReceiptsByHashes.bind(this,e))}_getTransactionReceiptsByAddress(e,t){Assert.that(null===this._transactionReceiptsRequest);return new Promise((s,r)=>{this._transactionReceiptsRequest={address:e,limit:t,resolve:s,reject:r};this._peer.channel.getTransactionReceiptsByAddress(e);this._peer.channel.expectMessage(Message.Type.TRANSACTION_RECEIPTS,()=>{this._transactionReceiptsRequest=null;this._peer.channel.close(CloseType.GET_TRANSACTION_RECEIPTS_TIMEOUT,"getTransactionReceipts timeout");r(new Error("Timeout"))},BaseConsensusAgent.TRANSACTION_RECEIPTS_REQUEST_TIMEOUT)})}_getTransactionReceiptsByHashes(e){Assert.that(null===this._transactionReceiptsRequest);return new Promise((t,s)=>{this._transactionReceiptsRequest={hashes:e,resolve:t,reject:s};this._peer.channel.getTransactionReceiptsByHashes(e);this._peer.channel.expectMessage(Message.Type.TRANSACTION_RECEIPTS,()=>{this._transactionReceiptsRequest=null;this._peer.channel.close(CloseType.GET_TRANSACTION_RECEIPTS_TIMEOUT,"getTransactionReceipts timeout");s(new Error("Timeout"))},BaseConsensusAgent.TRANSACTION_RECEIPTS_REQUEST_TIMEOUT)})}_onTransactionReceipts(e){Log.v(BaseConsensusAgent,()=>`[TRANSACTION-RECEIPTS] Received from ${this._peer.peerAddress}:`+` ${e.hasReceipts()?e.receipts.length:"<rejected>"}`);if(!this._transactionReceiptsRequest){Log.w(BaseConsensusAgent,`Unsolicited transaction receipts received from ${this._peer.peerAddress}`);return}const{address:t,hashes:s,limit:r,resolve:n,reject:i}=this._transactionReceiptsRequest;this._transactionReceiptsRequest=null;if(!e.hasReceipts()){Log.w(BaseConsensusAgent,`TransactionReceipts request was rejected by ${this._peer.peerAddress}`);i(new Error("TransactionReceipts request was rejected"));return}let o=e.receipts;o.sort((e,t)=>t.blockHeight-e.blockHeight);r!==undefined&&r<o.length&&(o=o.slice(0,r));if(s!==undefined)for(const a of o)if(!s.some(e=>e.equals(a.transactionHash))){Log.w(BaseConsensusAgent,`TransactionsReceipts with unwanted transactions received from ${this._peer.peer}`);this._peer.channel.close(CloseType.INVALID_TRANSACTION_RECEIPTS,"TransactionsReceipts contains unwanted transactions");i(new Error("TransactionsReceipts contains unwanted transactions"));return}n(o)}_onClose(){this._shutdown();this.fire("close",this);this._disconnectListeners()}shutdown(){this._disconnectListeners();this._shutdown()}_shutdown(){this._synchronizer.clear();this._timers.clearAll();this._txsToRequest.stop();this._waitingInvVectors.stop();this._waitingFreeInvVectors.stop()}get peer(){return this._peer}get synced(){return this._synced}get syncing(){return!1}}BaseConsensusAgent.REQUEST_THRESHOLD=50;BaseConsensusAgent.REQUEST_THROTTLE=500;BaseConsensusAgent.REQUEST_TIMEOUT=1e4;BaseConsensusAgent.REQUEST_TRANSACTIONS_WAITING_MAX=5e3;BaseConsensusAgent.REQUEST_BLOCKS_WAITING_MAX=5e3;BaseConsensusAgent.BLOCK_PROOF_REQUEST_TIMEOUT=1e4;BaseConsensusAgent.TRANSACTIONS_PROOF_REQUEST_TIMEOUT=1e4;BaseConsensusAgent.TRANSACTION_RECEIPTS_REQUEST_TIMEOUT=15e3;BaseConsensusAgent.TRANSACTION_RELAY_INTERVAL=5e3;BaseConsensusAgent.TRANSACTIONS_AT_ONCE=100;BaseConsensusAgent.TRANSACTIONS_PER_SECOND=10;BaseConsensusAgent.FREE_TRANSACTION_RELAY_INTERVAL=6e3;BaseConsensusAgent.FREE_TRANSACTIONS_AT_ONCE=10;BaseConsensusAgent.FREE_TRANSACTIONS_PER_SECOND=1;BaseConsensusAgent.FREE_TRANSACTION_SIZE_PER_INTERVAL=15e3;BaseConsensusAgent.TRANSACTION_RELAY_FEE_MIN=1;BaseConsensusAgent.SUBSCRIPTION_CHANGE_GRACE_PERIOD=3e3;BaseConsensusAgent.HEAD_REQUEST_INTERVAL=1e5;BaseConsensusAgent.KNOWS_OBJECT_AFTER_INV_DELAY=3e3;BaseConsensusAgent.KNOWN_OBJECTS_COUNT_MAX=4e4;Class.register(BaseConsensusAgent);class FreeTransactionVector{constructor(e,t){this._inv=e;this._serializedSize=t}hashCode(){return this._inv.hashCode()}toString(){return this._inv.toString()}get inv(){return this._inv}get serializedSize(){return this._serializedSize}}class BaseConsensus extends Observable{constructor(e,t,s){super();this._blockchain=e;this._network=s;this._agents=new HashMap;this._timers=new Timers;this._established=!1;this._syncPeer=null;this._subscription=Subscription.ANY;this._invRequestManager=new InvRequestManager;this._listenersToDisconnect=new Set;this._onToDisconnect(s,"peer-joined",e=>this._onPeerJoined(e));this._onToDisconnect(s,"peer-left",e=>this._onPeerLeft(e));this._onToDisconnect(e,"head-changed",e=>this._onHeadChanged(e));this._onToDisconnect(e,"rebranched",(e,t,s)=>this._onRebranched(s,e,t));this._onToDisconnect(e,"extended",e=>this._onExtended(e));this._onToDisconnect(e,"block",e=>this.fire("block",e));this._onToDisconnect(t,"transaction-added",e=>this._onTransactionAdded(e));this._onToDisconnect(t,"transaction-removed",e=>this._onTransactionRemoved(e))}async getHeadHash(){return this._blockchain.headHash}async getHeadHeight(){return this._blockchain.height}async getBlock(e,t=!0,s=t,r){let n=await this._blockchain.getBlock(e,!0,t||s);t=t||s&&!this._hasPeersWithVersion(2);(!n||t&&!n.isFull())&&(n=await this._requestBlock(e,t,n?n.height:r,!!n)||n);return n}async getBlockAt(e,t=!0){if(e>this._blockchain.height||e<1)throw new Error("Invalid height");let s=await this._blockchain.getBlockAt(e,t);s?s&&t&&!s.isFull()&&(s=await this._requestBlock(s.hash(),t,e,!0)||s):s=await this._requestBlockAt(e,t);return s}async getBlockTemplate(e,t){throw new Error("not implemented: getBlockTemplate")}async submitBlock(e){throw new Error("not implemented: submitBlock")}async getAccounts(e){throw new Error("not implemented: getAccounts")}getPendingTransactions(e){return this._requestPendingTransactions(e)}async getPendingTransactionsByAddress(e,t){throw new Error("not implemented: getPendingTransactionsByAddress")}async getTransactionsFromBlock(e,t,s,r){r||(r=await this.getBlock(t,!1,!0,s));return r&&r.isFull()?r.transactions.filter(t=>e.find(e=>e.equals(t.hash()))):this._requestTransactionsByHashes(e,r)}async getTransactionsFromBlockByAddresses(e,t,s){let r=await this._blockchain.getBlock(t,!1,!0);r||(r=this._requestBlock(t,!1,s));return r&&r.isFull()?r.transactions.filter(t=>!!e.find(e=>e.equals(t.sender)||e.equals(t.recipient))):this._requestTransactionsByAddresses(e,r)}getTransactionReceiptsByAddress(e,t){return this._requestTransactionReceiptsByAddress(e,t)}getTransactionReceiptsByHashes(e){return this._requestTransactionReceiptsByHashes(e)}async sendTransaction(e){throw new Error("not implemented: sendTransaction")}getMempoolContents(){return[]}_onToDisconnect(e,t,s){const r=e.on(t,s);this._listenersToDisconnect.add({obj:e,type:t,id:r})}_disconnectListeners(){for(const e of this._listenersToDisconnect)e.obj.off(e.type,e.id);this._offAll()}handoverTo(e){this._disconnectListeners();for(const t of this._agents.valueIterator()){const s=t.peer;t.shutdown();this._onPeerLeft(s);e._onPeerJoined(s)}return e}_hasPeersWithVersion(e){for(const t of this._agents.valueIterator())if(t.peer.version>=e)return!0;return!1}async _requestBlock(e,t=!1,s,r){let n=null;if(t||!s){const t=[],o=!s||s<this._blockchain.height-Policy.NUM_BLOCKS_VERIFICATION;for(const e of this._agents.valueIterator())e.synced&&e.providesServices(Services.FULL_BLOCKS)&&(!o||e.providesServices(Services.BLOCK_HISTORY))&&t.push(e);t.sort((t,s)=>t.knowsBlock(e)!==s.knowsBlock(e)?.5-t.knowsBlock(e):Math.random()-.5);for(const s of t)try{if(n=await s.requestBlock(e))break}catch(i){Log.w(BaseConsensus,`Failed to retrieve block for ${e} from ${s.peer.peerAddress}: ${i&&i.message||i}`)}if(!n)throw new Error(`Failed to retrieve block for ${e}`);r||await this._requestBlockProof(e,n.height);return n}return this._requestBlockProof(e,s)}async _requestBlockAt(e,t){const s=await this._requestBlockProofAt(e);if(t&&!s.isFull()){const t=s.hash(),n=[],i=e<this._blockchain.height-Policy.NUM_BLOCKS_VERIFICATION;for(const e of this._agents.valueIterator())e.synced&&e.providesServices(Services.FULL_BLOCKS)&&(!i||e.providesServices(Services.BLOCK_HISTORY))&&n.push(e);n.sort((e,s)=>e.knowsBlock(t)!==s.knowsBlock(t)?.5-e.knowsBlock(t):Math.random()-.5);for(const s of n)try{return await s.requestBlock(t)}catch(r){Log.w(BaseConsensus,`Failed to retrieve block for ${t}@${e} from ${s.peer.peerAddress}: ${r&&r.message||r}`)}throw new Error(`Failed to retrieve block for ${t}@${e}`)}return s}_requestPendingTransactions(e){return Promise.all(e.map(e=>this._requestPendingTransaction(e)["catch"](()=>null))).then(e=>e.filter(e=>!!e))}async _requestPendingTransaction(e){const t=[];for(const r of this._agents.valueIterator())r.synced&&r.providesServices(Services.MEMPOOL)&&t.push(r);t.sort((t,s)=>t.knowsTransaction(e)!==s.knowsTransaction(e)?.5-t.knowsTransaction(e):Math.random()-.5);for(const r of t)try{const t=await r.requestTransaction(e);if(t)return t}catch(s){Log.w(BaseConsensus,`Failed to retrieve pending transaction for ${e} from ${r.peer.peerAddress}: ${s&&s.message||s}`)}throw new Error(`Failed to retrieve pending transaction for ${e}`)}async _requestTransactionReceiptsByHashes(e){const t=[];for(const r of this._agents.valueIterator())r.synced&&r.providesServices(Services.TRANSACTION_INDEX)&&r.peer.version>=2&&t.push(r);for(const r of t)try{return await r.getTransactionReceiptsByHashes(e)}catch(s){Log.w(BaseConsensus,`Failed to retrieve transaction receipts for ${e} from ${r.peer.peerAddress}: ${s&&s.message||s}`)}throw new Error(`Failed to retrieve transaction receipts for ${e}`)}async _requestTransactionsByHashes(e,t){const s=[],r=t.height<this._blockchain.height-Policy.NUM_BLOCKS_VERIFICATION;for(const o of this._agents.valueIterator())o.synced&&o.providesServices(Services.BODY_PROOF)&&(!r||o.providesServices(Services.BLOCK_HISTORY))&&o.peer.version>=2&&s.push(o);const n=t.hash();s.sort((e,t)=>e.knowsBlock(n)!==t.knowsBlock(n)?.5-e.knowsBlock(n):Math.random()-.5);for(const o of s)try{return await o.getTransactionsProofByHashes(t,e)}catch(i){Log.w(BaseConsensus,`Failed to retrieve transactions for ${e} from ${o.peer.peerAddress}: ${i&&i.message||i}`)}throw new Error(`Failed to retrieve transactions for ${e}`)}subscribe(e){this._subscription=e;for(const t of this._agents.valueIterator())t.subscribe(e)}getSubscription(){return this._subscription}_newConsensusAgent(e){throw new Error("not implemented")}_onPeerJoined(e){const t=this._newConsensusAgent(e);this._agents.put(e.id,t);t.on("close",()=>this._onPeerLeft(t.peer));t.on("sync",()=>this._onPeerSynced(t.peer));t.on("out-of-sync",()=>this._onPeerOutOfSync(t.peer));this.bubble(t,"transaction-relayed");this._timers.resetTimeout("sync",this._syncBlockchain.bind(this),BaseConsensus.SYNC_THROTTLE);return t}_onPeerLeft(e){if(e.equals(this._syncPeer)){Log.d(BaseConsensus,`Peer ${e.peerAddress} left during sync`);this._syncPeer=null;this.fire("sync-failed",e.peerAddress)}this._agents.remove(e.id);this._syncBlockchain()}_syncBlockchain(){const e=[];let t=0;for(const r of this._agents.valueIterator())r.synced?Services.isFullNode(r.peer.peerAddress.services)&&t++:e.push(r);if(this._established&&(t<BaseConsensus.MIN_FULL_NODES||0===this._agents.length)){this._established=!1;this.fire("lost")}if(this._syncPeer)return;const s=ArrayUtils.randomElement(e);if(s){this._syncPeer=s.peer;this._established||this.fire("syncing");Log.v(BaseConsensus,`Syncing blockchain with peer ${s.peer.peerAddress}`);s.syncBlockchain()["catch"](Log.e.tag(BaseConsensusAgent))}else if(this._hasEnoughPeers(t,this._agents.length)){if(!this._established){Log.i(BaseConsensus,`Synced with all connected peers (${this._agents.length}), consensus established.`);Log.d(BaseConsensus,`Blockchain: height=${this._blockchain.height}, headHash=${this._blockchain.headHash}`);this._established=!0;this.fire("established");this._network.allowInboundConnections=!0}}else this.fire("waiting")}_hasEnoughPeers(e,t){return e>=BaseConsensus.MIN_FULL_NODES}_onPeerSynced(e){if(e.equals(this._syncPeer)){Log.v(BaseConsensus,`Finished sync with peer ${e.peerAddress}`);this._syncPeer=null}this._syncBlockchain()}_onPeerOutOfSync(e){Log.w(BaseConsensus,`Peer ${e.peerAddress} out of sync, resyncing`);this._syncBlockchain()}_onHeadChanged(e){if(this._established)for(const t of this._agents.valueIterator())t.relayBlock(e)}async _onRebranched(e,t,s){await this.fire("head-changed",e,"rebranched",t,s)}async _onExtended(e){await this.fire("head-changed",e.hash(),"extended",[],[e])}_onTransactionAdded(e){this.fire("transaction-added",e);if(this._established)for(const t of this._agents.valueIterator())t.relayTransaction(e)}_onTransactionRemoved(e){this.fire("transaction-removed",e);for(const t of this._agents.valueIterator())t.removeTransaction(e)}async _requestBlockProof(e,t){const s=await this._blockchain.getNearestBlockAt(t,!1);if(!s)throw new Error("No suitable reference block found for block proof");if(e.equals(s.hash()))return s;const r=[],n=t<this._blockchain.height-Policy.NUM_BLOCKS_VERIFICATION||s.height<this._blockchain.height-Policy.NUM_BLOCKS_VERIFICATION;for(const a of this._agents.valueIterator())a.synced&&a.providesServices(Services.BLOCK_PROOF)&&(!n||a.providesServices(Services.BLOCK_HISTORY))&&r.push(a);const i=s.hash();r.sort((e,t)=>e.knowsBlock(i)!==t.knowsBlock(i)?.5-e.knowsBlock(i):Math.random()-.5);for(const a of r)try{return await a.getBlockProof(e,s)}catch(o){Log.w(BaseConsensus,`Failed to retrieve block proof for ${e}@${t} from ${a.peer.peerAddress}: ${o&&o.message||o}`)}throw new Error(`Failed to retrieve block proof for ${e}`)}async _requestBlockProofAt(e){const t=await this._blockchain.getNearestBlockAt(e,!1);if(!t)throw new Error("No suitable reference block found for block proof");if(e===t.height)return t;const s=[],r=e<this._blockchain.height-Policy.NUM_BLOCKS_VERIFICATION||t.height<this._blockchain.height-Policy.NUM_BLOCKS_VERIFICATION;for(const o of this._agents.valueIterator())o.synced&&o.providesServices(Services.BLOCK_PROOF)&&(!r||o.providesServices(Services.BLOCK_HISTORY))&&o.peer.version>=2&&s.push(o);const n=t.hash();s.sort((e,t)=>e.knowsBlock(n)!==t.knowsBlock(n)?.5-e.knowsBlock(n):Math.random()-.5);for(const o of s)try{return await o.getBlockProofAt(e,t)}catch(i){Log.w(BaseConsensus,`Failed to retrieve block proof at ${e} from ${o.peer.peerAddress}: ${i&&i.message||i}`)}throw new Error(`Failed to retrieve block proof at ${e}`)}async _requestTransactionsByAddresses(e,t=this._blockchain.head){if(0===e.length)return[];const s=[],r=t.height<this._blockchain.height-Policy.NUM_BLOCKS_VERIFICATION;for(const o of this._agents.valueIterator())o.synced&&o.providesServices(Services.BODY_PROOF)&&(!r||o.providesServices(Services.BLOCK_HISTORY))&&s.push(o);const n=t.hash();s.sort((e,t)=>e.knowsBlock(n)!==t.knowsBlock(n)?.5-e.knowsBlock(n):Math.random()-.5);for(const o of s)try{return await o.getTransactionsProofByAddresses(t,e)}catch(i){Log.w(BaseConsensus,`Failed to retrieve transactions proof for ${e} from ${o.peer.peerAddress}: ${i&&i.message||i}`)}throw new Error(`Failed to retrieve transactions proof for ${e}`)}async _requestTransactionReceiptsByAddress(e,t){const s=[];for(const n of this._agents.valueIterator())n.synced&&n.providesServices(Services.TRANSACTION_INDEX)&&s.push(n);s.sort(()=>Math.random()-.5);for(const n of s)try{return await n.getTransactionReceiptsByAddress(e,t)}catch(r){Log.w(BaseConsensus,`Failed to retrieve transaction receipts for ${e} from ${n.peer.peerAddress}: ${r&&r.message||r}`)}throw new Error(`Failed to retrieve transaction receipts for ${e}`)}async _requestTransactionHistory(e){const t=await this._requestTransactionReceiptsByAddress(e),s=[];let r=null;for(const o of t)if(!o.blockHash.equals(r)){const e=await this._blockchain.getBlock(o.blockHash);if(e)s.push(Promise.resolve(e));else{const e=this._requestBlockProof(o.blockHash,o.blockHeight)["catch"](e=>Log.e(BaseConsensus,`Failed to retrieve proof for block ${o.blockHash}`+` (${e}) - transaction history may be incomplete`));s.push(e)}r=o.blockHash}const n=await Promise.all(s),i=[];for(const o of n){if(!o)continue;const t=this._requestTransactionsByAddresses([e],o).then(e=>e.map(e=>({transaction:e,header:o.header})))["catch"](e=>Log.e(BaseConsensus,`Failed to retrieve transactions for block ${o.hash()}`+` (${e}) - transaction history may be incomplete`));i.push(t)}return(await Promise.all(i)).reduce((e,t)=>t?e.concat(t):e,[]).sort((e,t)=>e.header.height-t.header.height)}get established(){return this._established}get network(){return this._network}get invRequestManager(){return this._invRequestManager}}BaseConsensus.MAX_ATTEMPTS_TO_FETCH=5;BaseConsensus.SYNC_THROTTLE=1500;BaseConsensus.MIN_FULL_NODES=1;BaseConsensus.TRANSACTION_RELAY_TIMEOUT=1e4;BaseConsensus.SendTransactionResult={REJECTED_LOCAL:-4,EXPIRED:-3,ALREADY_MINED:-2,INVALID:-1,NONE:0,RELAYED:1,KNOWN:2,PENDING_LOCAL:3};Class.register(BaseConsensus);class BaseMiniConsensusAgent extends BaseConsensusAgent{constructor(e,t,s,r,n,i){super(s,r,n,i);this._blockchain=e;this._mempool=t;this._subscribeTarget();this._accountsRequest=null;this._onToDisconnect(r.channel,"accounts-proof",e=>this._onAccountsProof(e))}requestMempool(){const e=BaseMiniConsensusAgent.MEMPOOL_DELAY_MIN+Math.random()*(BaseMiniConsensusAgent.MEMPOOL_DELAY_MAX-BaseMiniConsensusAgent.MEMPOOL_DELAY_MIN);setTimeout(()=>this._peer.channel.mempool(),e)}getAccounts(e,t){return this._synchronizer.push("getAccounts",this._getAccounts.bind(this,e,t))}async _getAccounts(e,t){Assert.that(null===this._accountsRequest);const s=await this._blockchain.getBlock(e);if(!s)throw new Error("Unknown block hash");Log.d(BaseMiniConsensusAgent,`Requesting AccountsProof for ${t} from ${this._peer.peerAddress}`);return new Promise((r,n)=>{this._accountsRequest={addresses:t,block:s,resolve:r,reject:n};this._peer.channel.getAccountsProof(e,t);this._peer.channel.expectMessage(Message.Type.ACCOUNTS_PROOF,()=>{this._peer.channel.close(CloseType.GET_ACCOUNTS_PROOF_TIMEOUT,"getAccountsProof timeout");n(new Error("Timeout"))},BaseMiniConsensusAgent.ACCOUNTSPROOF_REQUEST_TIMEOUT)})}async _onAccountsProof(e){Log.d(BaseMiniConsensusAgent,`[ACCOUNTS-PROOF] Received from ${this._peer.peerAddress}: blockHash=${e.blockHash}, proof=${e.proof} (${e.serializedSize} bytes)`);if(!this._accountsRequest){Log.w(BaseMiniConsensusAgent,`Unsolicited accounts proof received from ${this._peer.peerAddress}`);return}const{addresses:t,block:s,resolve:r,reject:n}=this._accountsRequest;this._accountsRequest=null;if(!e.hasProof()){n(new Error("Accounts request was rejected"));return}if(!s.hash().equals(e.blockHash)){Log.w(BaseMiniConsensusAgent,`Received AccountsProof for invalid reference block from ${this._peer.peerAddress}`);n(new Error("Invalid reference block"));return}const i=e.proof;if(!i.verify()){Log.w(BaseMiniConsensusAgent,`Invalid AccountsProof received from ${this._peer.peerAddress}`);this._peer.channel.close(CloseType.INVALID_ACCOUNTS_PROOF,"Invalid AccountsProof");n(new Error("Invalid AccountsProof"));return}const o=i.root();if(!s.accountsHash.equals(o)){Log.w(BaseMiniConsensusAgent,`Invalid AccountsProof (root hash) received from ${this._peer.peerAddress}`);this._peer.channel.close(CloseType.INVALID_ACCOUNTS_PROOF,"AccountsProof root hash mismatch");n(new Error("AccountsProof root hash mismatch"));return}const a=[];for(const h of t)try{const e=i.getAccount(h);a.push(e)}catch(c){Log.w(BaseMiniConsensusAgent,`Incomplete AccountsProof received from ${this._peer.peerAddress}`);this._peer.channel.close(CloseType.INVALID_ACCOUNTS_PROOF,"Incomplete AccountsProof");n(new Error("Incomplete AccountsProof"));return}r(a)}_getSubscribedMempoolTransactions(){switch(this._remoteSubscription.type){case Subscription.Type.ADDRESSES:return this._mempool.getTransactionsByAddresses(this._remoteSubscription.addresses,BaseMiniConsensusAgent.MEMPOOL_ENTRIES_MAX);case Subscription.Type.ANY:return this._mempool.getTransactions(BaseMiniConsensusAgent.MEMPOOL_ENTRIES_MAX)}return[]}}BaseMiniConsensusAgent.ACCOUNTSPROOF_REQUEST_TIMEOUT=5e3;BaseMiniConsensusAgent.MEMPOOL_DELAY_MIN=500;BaseMiniConsensusAgent.MEMPOOL_DELAY_MAX=5e3;BaseMiniConsensusAgent.MEMPOOL_ENTRIES_MAX=1e3;Class.register(BaseMiniConsensusAgent);class BaseMiniConsensus extends BaseConsensus{constructor(e,t,s){super(e,t,s);this._blockchain=e;this._mempool=t;this._subscription=Subscription.BLOCKS_ONLY;this._onToDisconnect(this,"head-changed",(e,t,s,r)=>this._onNewAdoptedBlocks(r));this._onToDisconnect(t,"transaction-mined",(e,t)=>this.fire("transaction-mined",e,t,this._blockchain.head))}subscribeAccounts(e){this.subscribe(Subscription.fromAddresses(e))}subscribe(e){const t=this._subscription;super.subscribe(e);e.type===Subscription.Type.ADDRESSES&&this._mempool.evictExceptAddresses(e.addresses);if(!e.isSubsetOf(t))for(const s of this._agents.valueIterator())s.requestMempool()}addSubscriptions(e){e=Array.isArray(e)?e:[e];const t=new HashSet;t.addAll(this._subscription.addresses);t.addAll(e);this.subscribeAccounts(t.values())}removeSubscriptions(e){e=Array.isArray(e)?e:[e];const t=new HashSet;t.addAll(this._subscription.addresses);t.removeAll(e);this.subscribeAccounts(t.values())}_onTransactionAdded(e){this.fire("transaction-added",e)}async _onNewAdoptedBlocks(e){if(this._established)for(const s of e)try{const e=await this._requestTransactionsByAddresses(this._subscription.addresses,s);await this._mempool.changeHead(s,e)}catch(t){Log.e(BaseMiniConsensus,`Failed to retrieve transaction proof to update mempool: ${t.message||t}`)}}async getAccount(e,t=null){return(await this.getAccounts([e],t))[0]}async getAccounts(e,t){t=t||this._blockchain.headHash;const s=[];for(const n of this._agents.valueIterator())n.synced&&Services.providesServices(n.peer.peerAddress.services,Services.ACCOUNTS_PROOF)&&s.push(n);s.sort((e,s)=>e.knowsBlock(t)!==s.knowsBlock(t)?.5-e.knowsBlock(t):Math.random()-.5);for(const n of s)try{return await n.getAccounts(t,e)}catch(r){Log.w(BaseMiniConsensus,`Failed to retrieve accounts ${e} from ${n.peer.peerAddress}: ${r}`)}throw new Error(`Failed to retrieve accounts ${e}`)}async sendTransaction(e){try{await this.relayTransaction(e);return await new Promise(t=>{let s;s=this.on("transaction-relayed",r=>{if(r.equals(e)){this.off("transaction-relayed",s);t(!0)}});setTimeout(()=>{this.off("transaction-relayed",s);t(!1)},BaseConsensus.TRANSACTION_RELAY_TIMEOUT)})?BaseConsensus.SendTransactionResult.RELAYED:BaseConsensus.SendTransactionResult.PENDING_LOCAL}catch(t){Log.d(BaseMiniConsensus,()=>`Error sending transaction ${e}: ${t.message||t}`);if(t instanceof BaseMiniConsensus.MempoolRejectedError)switch(t.mempoolReturnCode){case Mempool.ReturnCode.KNOWN:return BaseConsensus.SendTransactionResult.KNOWN;case Mempool.ReturnCode.INVALID:return BaseConsensus.SendTransactionResult.INVALID;case Mempool.ReturnCode.EXPIRED:return BaseConsensus.SendTransactionResult.EXPIRED}try{this._mempool.removeTransaction(e)}catch(t){}return BaseConsensus.SendTransactionResult.REJECTED_LOCAL}}async getPendingTransactions(e){const t=new HashSet(e=>e instanceof Transaction?e.hash().hashCode():e.hashCode());for(const s of e){const e=this._mempool.getTransaction(s);e&&t.add(e)}t.length!==e.length&&t.addAll(await this._requestPendingTransactions(e.filter(e=>!t.get(e))));return e.map(e=>t.get(e)).filter(e=>!!e)}async getPendingTransactionsByAddress(e,t){if(this._subscription.addresses&&this._subscription.addresses.some(t=>t.equals(e)))return this._mempool.getTransactionsByAddresses([e],t);throw new Error("Can not provide pending transactions without prior subscription")}async relayTransaction(e){const t=await this._mempool.pushTransaction(e);if(t!==Mempool.ReturnCode.ACCEPTED)throw new BaseMiniConsensus.MempoolRejectedError(t);let s=!1;for(const r of this._agents.valueIterator())s=r.relayTransaction(e)&&r.providesServices(Services.MEMPOOL)||s;if(!s)throw new Error("Failed to relay transaction - no agent relayed transaction")}}BaseMiniConsensus.MempoolRejectedError=class extends Error{constructor(e){super("Failed to relay transaction - mempool rejected transaction");this._mempoolReturnCode=e}get mempoolReturnCode(){return this._mempoolReturnCode}};Class.register(BaseMiniConsensus);class FullChain extends BaseChain{static getPersistent(e,t,s,r){const n=ChainDataStore.getPersistent(e);return new FullChain(n,t,s,r)._init()}static createVolatile(e,t,s){const r=ChainDataStore.createVolatile();return new FullChain(r,e,t,s)._init()}constructor(e,t,s,r){super(e);this._accounts=t;this._time=s;this._snapshots=new HashMap;this._snapshotOrder=[];this._mainChain=null;this._proof=null;this._transactionCache=new TransactionCache;this._transactionStore=r;this._synchronizer=new PrioritySynchronizer(2,FullChain.SYNCHRONIZER_THROTTLE_AFTER,FullChain.SYNCHRONIZER_THROTTLE_WAIT);this._blockKnownCount=this._blockInvalidCount=this._blockOrphanCount=this._blockExtendedCount=this._blockRebranchedCount=this._blockForkedCount=0}async _init(){this._headHash=await this._store.getHead();if(this._headHash){const e=await this._store.getChainData(GenesisConfig.GENESIS_HASH);if(!e||!e.onMainChain)throw new Error("Invalid genesis block stored. Reset your consensus database.");this._mainChain=await this._store.getChainData(this._headHash,!0);Assert.that(!!this._mainChain,"Failed to load main chain from storage");if(!this._mainChain.head.accountsHash.equals(await this._accounts.hash()))throw new Error("Corrupted store: Inconsistent chain/accounts state");const t=await this._store.getBlocksBackward(this.headHash,this._transactionCache.missingBlocks-1,!0);this._transactionCache.prependBlocks([...t.reverse(),this._mainChain.head])}else{this._mainChain=await ChainData.initial(GenesisConfig.GENESIS_BLOCK);this._headHash=GenesisConfig.GENESIS_HASH;const e=this._store.synchronousTransaction();e.putChainDataSync(GenesisConfig.GENESIS_HASH,this._mainChain);e.setHeadSync(GenesisConfig.GENESIS_HASH);await e.commit();await this._accounts.initialize(GenesisConfig.GENESIS_BLOCK,GenesisConfig.GENESIS_ACCOUNTS)}return this}pushBlock(e){return this._synchronizer.push(0,this._pushBlock.bind(this,e))}async _pushBlock(e){const t=e.hash();if(await this._store.getBlock(t)){this._blockKnownCount++;return FullChain.OK_KNOWN}if(!e.isFull()){Log.w(FullChain,"Rejecting block - body missing");this._blockInvalidCount++;return FullChain.ERR_INVALID}if(!(await e.verify(this._time))){this._blockInvalidCount++;return FullChain.ERR_INVALID}const s=await this._store.getChainData(e.prevHash);if(!s){Log.w(FullChain,"Rejecting block - unknown predecessor");this._blockOrphanCount++;return FullChain.ERR_ORPHAN}const r=s.head;if(!(await e.isImmediateSuccessorOf(r))){Log.w(FullChain,"Rejecting block - not a valid immediate successor");this._blockInvalidCount++;return FullChain.ERR_INVALID}const n=await this.getNextTarget(r);Assert.that(BlockUtils.isValidTarget(n),"Failed to compute next target in FullChain");if(e.nBits!==BlockUtils.targetToCompact(n)){Log.w(FullChain,"Rejecting block - difficulty mismatch");this._blockInvalidCount++;return FullChain.ERR_INVALID}const i=await s.nextChainData(e);if(e.prevHash.equals(this.headHash)){if(!(await this._extend(t,i,s))){this._blockInvalidCount++;return FullChain.ERR_INVALID}this._blockExtendedCount++;return FullChain.OK_EXTENDED}if(i.totalDifficulty.gt(this.totalDifficulty)){if(!(await this._rebranch(t,i))){this._blockInvalidCount++;return FullChain.ERR_INVALID}this._blockRebranchedCount++;return FullChain.OK_REBRANCHED}Log.v(FullChain,`Creating/extending fork with block ${t}, height=${e.height}, totalDifficulty=${i.totalDifficulty}, totalWork=${i.totalWork}`);await this._store.putChainData(t,i);this._blockForkedCount++;await this.fire("block",t);return FullChain.OK_FORKED}async _verifyInterlink(e){for(let t=0;t<e.interlink.length;t++){const s=await this._store.getBlock(e.interlink.hashes[t]);if(!s||!(await e.isInterlinkSuccessorOf(s)))return!1}return!0}async _extend(e,t,s){const r=await this._accounts.transaction();try{await r.commitBlock(t.head,this._transactionCache)}catch(i){Log.w(FullChain,`Rejecting block - failed to commit to AccountsTree: ${i.message||i}`);r.abort()["catch"](Log.w.tag(FullChain));return!1}t.onMainChain=!0;s.mainChainSuccessor=e;const n=await this._store.synchronousTransaction();n.putChainDataSync(e,t);n.putChainDataSync(t.head.prevHash,s,!1);n.setHeadSync(e);if(this._transactionStore){const e=this._transactionStore.transaction();await e.put(t.head);await JDB.JungleDB.commitCombined(...n.txs,r.tx,e.tx)}else await JDB.JungleDB.commitCombined(...n.txs,r.tx);await this._saveSnapshot(e);this._transactionCache.pushBlock(t.head);this._shouldExtendChainProof()&&this._proof?this._proof=await this._extendChainProof(this._proof,t.head.header):this._proof=null;this._mainChain=t;this._headHash=e;await this.fire("head-changed",this.head,!1);await this.fire("block",e);await this.fire("extended",this.head);return!0}_shouldExtendChainProof(){return!1}async _rebranch(e,t){Log.v(FullChain,`Rebranching to fork ${e}, height=${t.head.height}, totalDifficulty=${t.totalDifficulty}, totalWork=${t.totalWork}`);for(const A of this._snapshotOrder){this._snapshots.get(A).abort()}this._snapshots.clear();this._snapshotOrder=[];const s=[],r=[];let n=t,i=e;for(;!n.onMainChain;){s.push(n);r.push(i);i=n.head.prevHash;n=await this._store.getChainData(i,!0);Assert.that(!!n,"Corrupted store: Failed to find fork predecessor while rebranching")}Log.v(FullChain,()=>`Found common ancestor ${i.toBase64()} ${s.length} blocks up`);const o=n,a=i,c=await this._accounts.transaction(!1),h=this._transactionCache.clone(),l=this._transactionStore?this._transactionStore.transaction():null,u=[];let d=this._headHash,_=this._mainChain;for(;!d.equals(a);){try{await c.revertBlock(_.head,h);h.revertBlock(_.head);this._transactionStore&&await l.remove(_.head);u.push(_)}catch(w){Log.e(FullChain,"Failed to revert main chain while rebranching",w);c.abort()["catch"](Log.w.tag(FullChain));this._transactionStore&&l.abort()["catch"](Log.w.tag(FullChain));return!1}d=_.head.prevHash;_=await this._store.getChainData(d,!0);Assert.that(!!_,"Corrupted store: Failed to find main chain predecessor while rebranching");Assert.that(_.head.accountsHash.equals(await c.hash()),"Failed to revert main chain - inconsistent state")}Assert.that(!h.head||d.equals(h.head.hash),"Invalid TransactionCache head");const f=h.missingBlocks,g=h.isEmpty()?o.mainChainSuccessor:h.tail.hash,p=await this._store.getBlocksBackward(g,f,!0);h.prependBlocks(p.reverse());for(let A=s.length-1;A>=0;A--)try{await c.commitBlock(s[A].head,h);h.pushBlock(s[A].head);this._transactionStore&&await l.put(s[A].head)}catch(w){Log.e(FullChain,"Failed to apply fork block while rebranching",w);c.abort()["catch"](Log.w.tag(FullChain));this._transactionStore&&l.abort()["catch"](Log.w.tag(FullChain));const e=this._store.synchronousTransaction(!1);for(;A>=0;A--)e.removeChainDataSync(r[A]);await e.commit();return!1}const y=this._store.synchronousTransaction(!1);for(const A of u){A.onMainChain=!1;A.mainChainSuccessor=null;y.putChainDataSync(A.head.hash(),A,!1)}o.mainChainSuccessor=r[r.length-1];y.putChainDataSync(a,o,!1);for(let A=s.length-1;A>=0;A--){const e=s[A];e.onMainChain=!0;e.mainChainSuccessor=A>0?r[A-1]:null;y.putChainDataSync(r[A],e,0===A)}y.setHeadSync(e);this._transactionStore?await JDB.JungleDB.commitCombined(...y.txs,c.tx,l.tx):await JDB.JungleDB.commitCombined(...y.txs,c.tx);this._transactionCache=h;this._proof=null;const C=[];for(const A of u){await this.fire("block-reverted",A.head);C.push(A.head)}const m=[];for(let A=s.length-1;A>=0;A--){this._mainChain=s[A];this._headHash=r[A];await this.fire("head-changed",this.head,A>0);m.push(this.head)}await this.fire("block",e);await this.fire("rebranched",C,m,e);return!0}getBlocks(e,t=500,s=!0){return this._store.getBlocks(e,t,s)}getChainProof(){return this._synchronizer.push(1,async()=>{this._proof||(this._proof=await this._getChainProof());return this._proof})}getBlockProof(e,t){return this._synchronizer.push(1,this._getBlockProof.bind(this,e,t))}async getAccountsTreeChunk(e,t){const s=await this._getSnapshot(e);return s&&await s.getAccountsTreeChunk(t)}async getAccountsProof(e,t){const s=await this._getSnapshot(e);return s&&await s.getAccountsProof(t)}async getTransactionsProof(e,t){return this.getTransactionsProofByAddresses(e,t)}async getTransactionsProofByAddresses(e,t){const s=await this.getBlock(e,!1,!0);if(!s||!s.isFull())return null;const r=[],n=new HashSet;n.addAll(t);for(const o of s.transactions)(n.contains(o.sender)||n.contains(o.recipient))&&r.push(o);const i=MerkleProof.compute(s.body.getMerkleLeafs(),r);return new TransactionsProof(r,i)}async getTransactionsProofByHashes(e,t){const s=await this.getBlock(e,!1,!0);if(!s||!s.isFull())return null;const r=[],n=new HashSet;n.addAll(t);for(const o of s.transactions)n.contains(o.hash())&&r.push(o);const i=MerkleProof.compute(s.body.getMerkleLeafs(),r);return new TransactionsProof(r,i)}async getTransactionReceiptsByAddress(e,t=null){if(!this._transactionStore)return null;const s=[],r=await this._transactionStore.getBySender(e,!t||t<0||!Number.isFinite(t)?null:t/2),n=await this._transactionStore.getByRecipient(e,!t||t<0||!Number.isFinite(t)?null:t/2);r.forEach(e=>{s.push(new TransactionReceipt(e.transactionHash,e.blockHash,e.blockHeight))});n.forEach(e=>{s.push(new TransactionReceipt(e.transactionHash,e.blockHash,e.blockHeight))});return s}async getTransactionReceiptsByHashes(e,t=null){if(!this._transactionStore)return null;const s=[],r=await Promise.all(e.map(e=>this._transactionStore.get(e)));for(const n of r)n&&(!t||t<0||s.length<t)&&s.push(new TransactionReceipt(n.transactionHash,n.blockHash,n.blockHeight));return s}async getTransactionInfoByHash(e){if(!this._transactionStore)throw new Error("Invalid request");const t=await this._transactionStore.get(e);return t||null}_getSnapshot(e){return this._synchronizer.push(1,async()=>{const t=await this.getBlock(e);if(!t||this._mainChain.head.height-t.height>Policy.NUM_SNAPSHOTS_MAX)return null;let s=null;if(this._snapshots.contains(e))s=this._snapshots.get(e);else{const e=await this._accounts.transaction(),r=this._transactionCache.clone();let n=this._headHash;for(;!t.prevHash.equals(n);){const t=await this.getBlock(n,!1,!0);if(!this._snapshots.contains(n)){s=await this._accounts.snapshot(e);this._snapshots.put(n,s);this._snapshotOrder.unshift(n)}await e.revertBlock(t,r);r.revertBlock(t);n=t.prevHash}await e.abort()}Assert.that(t.accountsHash.equals(await s.hash()),"AccountsHash mismatch for snapshot of block ${blockHash}");return s})}async _saveSnapshot(e){if(this._snapshotOrder.length>0){const t=this._snapshotOrder.shift(),s=this._snapshots.get(t);s?await s.abort():Log.e(FullChain,()=>`Snapshot with hash ${t.toBase64()} not found.`);this._snapshots.remove(t);const r=await this._accounts.snapshot();this._snapshots.put(e,r);this._snapshotOrder.push(e)}}get head(){return this._mainChain.head}get headHash(){return this._headHash}get height(){return this._mainChain.head.height}get totalDifficulty(){return this._mainChain.totalDifficulty}get totalWork(){return this._mainChain.totalWork}get accounts(){return this._accounts}get transactionCache(){return this._transactionCache}get blockForkedCount(){return this._blockForkedCount}get blockRebranchedCount(){return this._blockRebranchedCount}get blockExtendedCount(){return this._blockExtendedCount}get blockOrphanCount(){return this._blockOrphanCount}get blockInvalidCount(){return this._blockInvalidCount}get blockKnownCount(){return this._blockKnownCount}accountsHash(){return this._accounts.hash()}get queue(){return this._synchronizer}}FullChain.ERR_ORPHAN=-2;FullChain.ERR_INVALID=-1;FullChain.OK_KNOWN=0;FullChain.OK_EXTENDED=1;FullChain.OK_REBRANCHED=2;FullChain.OK_FORKED=3;FullChain.SYNCHRONIZER_THROTTLE_AFTER=500;FullChain.SYNCHRONIZER_THROTTLE_WAIT=30;Class.register(FullChain);class FullConsensusAgent extends BaseConsensusAgent{constructor(e,t,s,r,n,i){super(s,r,n,i);this._blockchain=e;this._mempool=t;this._syncing=!1;this._numBlocksExtending=-1;this._numBlocksForking=-1;this._forkHead=null;this._failedSyncs=0;this._syncTarget=r.headHash;this._chainProofLimit=new RateLimit(FullConsensusAgent.CHAIN_PROOF_RATE_LIMIT);this._accountsProofLimit=new RateLimit(FullConsensusAgent.ACCOUNTS_PROOF_RATE_LIMIT);this._accountsTreeChunkLimit=new RateLimit(FullConsensusAgent.ACCOUNTS_TREE_CHUNK_RATE_LIMIT);this._transactionsProofLimit=new RateLimit(FullConsensusAgent.TRANSACTION_PROOF_RATE_LIMIT);this._transactionReceiptsLimit=new RateLimit(FullConsensusAgent.TRANSACTION_RECEIPTS_RATE_LIMIT);this._blockProofLimit=new RateLimit(FullConsensusAgent.BLOCK_PROOF_RATE_LIMIT);this._getBlocksLimit=new RateLimit(FullConsensusAgent.GET_BLOCKS_RATE_LIMIT);this._onToDisconnect(r.channel,"get-blocks",e=>this._onGetBlocks(e));this._onToDisconnect(r.channel,"get-chain-proof",e=>this._onGetChainProof(e));this._onToDisconnect(r.channel,"get-accounts-proof",e=>this._onGetAccountsProof(e));this._onToDisconnect(r.channel,"get-accounts-tree-chunk",e=>this._onGetAccountsTreeChunk(e));this._onToDisconnect(r.channel,"get-transactions-proof",e=>this._onGetTransactionsProofByAddresses(e));this._onToDisconnect(r.channel,"get-transaction-receipts",e=>this._onGetTransactionReceiptsByAddress(e));this._onToDisconnect(r.channel,"get-block-proof",e=>this._onGetBlockProof(e));this._onToDisconnect(r.channel,"get-block-proof-at",e=>this._onGetBlockProofAt(e));this._onToDisconnect(r.channel,"get-transactions-proof-by-hashes",e=>this._onGetTransactionsProofByHashes(e));this._onToDisconnect(r.channel,"get-transaction-receipts-by-hashes",e=>this._onGetTransactionReceiptsByHashes(e))}async syncBlockchain(){this._syncing=!0;if(!this.providesServices(Services.BLOCK_HISTORY,Services.FULL_BLOCKS)){this._syncFinished();return}if(!this._objectsInFlight.isEmpty()){Log.v(FullConsensusAgent,`Waiting for ${this._objectsInFlight.length} objects to arrive ...`);return}if(!this._objectsProcessing.isEmpty()){Log.v(FullConsensusAgent,`Waiting for ${this._objectsProcessing.length} objects to be processed ...`);return}await this._blockchain.getBlock(this._syncTarget,!0)?this._syncFinished():0===this._numBlocksExtending&&++this._failedSyncs>=FullConsensusAgent.SYNC_ATTEMPTS_MAX?this._peer.channel.close(CloseType.BLOCKCHAIN_SYNC_FAILED,"blockchain sync failed"):this._requestBlocks()["catch"](Log.w.tag(FullConsensusAgent))}_syncFinished(){this._subscribeTarget();const e=FullConsensusAgent.MEMPOOL_DELAY_MIN+Math.random()*(FullConsensusAgent.MEMPOOL_DELAY_MAX-FullConsensusAgent.MEMPOOL_DELAY_MIN);setTimeout(()=>this._peer.channel.mempool(),e);this._syncing=!1;this._synced=!0;this._numBlocksExtending=0;this._numBlocksForking=0;this._forkHead=null;this._failedSyncs=0;this.fire("sync")}async _requestBlocks(e){if(this._peer.channel.isExpectingMessage(Message.Type.INV))return;this._peer.channel.expectMessage(Message.Type.INV,()=>{this._peer.channel.close(CloseType.GET_BLOCKS_TIMEOUT,"getBlocks timeout")},BaseConsensusAgent.REQUEST_TIMEOUT);let t;t=this._forkHead&&0===this._numBlocksExtending&&this._numBlocksForking>0?[this._forkHead.hash()]:await this._blockchain.getBlockLocators();this._numBlocksExtending=0;this._numBlocksForking=0;this._peer.channel.getBlocks(t,e)}_shouldRequestData(e){return!(e.type===InvVector.Type.BLOCK&&!this.providesServices(Services.FULL_BLOCKS)||e.type===InvVector.Type.TRANSACTION&&this._mempool.isFiltered(e.hash))}_getBlock(e,t=!1,s=!1){return this._blockchain.getBlock(e,t,s)}_getRawBlock(e,t=!1){return this._blockchain.getRawBlock(e,t)}_getTransaction(e){return this._mempool.getTransaction(e)}async _onKnownBlockAnnounced(e,t){if(this._syncing){this._numBlocksForking++;this._forkHead=t}}_onNoUnknownObjects(){this._syncing&&this.syncBlockchain()["catch"](Log.e.tag(FullConsensusAgent))}_onAllObjectsReceived(){this._syncing&&this.syncBlockchain()["catch"](Log.e.tag(FullConsensusAgent))}_onHeader(e){Log.w(FullConsensusAgent,`Unsolicited header message received from ${this._peer.peerAddress}, discarding`)}async _processBlock(e,t){switch(await this._blockchain.pushBlock(t)){case FullChain.ERR_INVALID:this._peer.channel.close(CloseType.INVALID_BLOCK,"received invalid block");break;case FullChain.OK_EXTENDED:case FullChain.OK_REBRANCHED:this._syncing&&this._numBlocksExtending++;break;case FullChain.OK_FORKED:if(this._syncing){this._numBlocksForking++;this._forkHead=t}break;case FullChain.ERR_ORPHAN:this._onOrphanBlock(e,t);break;case FullChain.OK_KNOWN:Log.v(FullConsensusAgent,`Received known block ${e} (height=${t.height}, prevHash=${t.prevHash}) from ${this._peer.peerAddress}`)}}_onOrphanBlock(e,t){if(this._synced){Log.d(FullConsensusAgent,`Received orphan block ${e} (height=${t.height}, prevHash=${t.prevHash}) from ${this._peer.peerAddress}`);this._timers.timeoutExists("outOfSync")||this._subscribe(Subscription.NONE);this._syncTarget=e;this._timers.resetTimeout("outOfSync",()=>this._outOfSync(),FullConsensusAgent.RESYNC_THROTTLE)}else Log.w(FullConsensusAgent,`Received orphan block ${e} (height=${t.height}, prevHash=${t.prevHash}) while syncing`)}_outOfSync(){this._timers.clearTimeout("outOfSync");this._synced=!1;this.fire("out-of-sync")}async _processTransaction(e,t){switch(await this._mempool.pushTransaction(t)){case Mempool.ReturnCode.FEE_TOO_LOW:this._peer.channel.reject(Message.Type.TX,RejectMessage.Code.REJECT_INSUFFICIENT_FEE,"Sender has too many free transactions",t.hash().serialize());break;case Mempool.ReturnCode.INVALID:this._peer.channel.reject(Message.Type.TX,RejectMessage.Code.REJECT_INVALID,"Invalid transaction",t.hash().serialize());break;case Mempool.ReturnCode.MINED:case Mempool.ReturnCode.EXPIRED:Log.v(FullConsensusAgent,()=>`Ignored transaction ${e.toHex()} relayed by ${this._peer.peerAddress} (${this._peer.netAddress})`);break;case Mempool.ReturnCode.FILTERED:Log.v(FullConsensusAgent,()=>`Filtered transaction ${e.toHex()} relayed by ${this._peer.peerAddress} (${this._peer.netAddress})`)}}_onAllObjectsProcessed(){this._syncing&&this.syncBlockchain()["catch"](Log.e.tag(FullConsensusAgent))}async _onGetBlocks(e){if(!this._getBlocksLimit.note()){Log.w(FullConsensusAgent,"Rejecting GetBlocks message - rate-limit exceeded");return}Log.v(FullConsensusAgent,`[GETBLOCKS] ${e.locators.length} block locators maxInvSize ${e.maxInvSize} received from ${this._peer.peerAddress}`);let t=GenesisConfig.GENESIS_BLOCK;for(const n of e.locators){const e=await this._blockchain.getBlock(n);if(e){t=e;break}}const s=await this._blockchain.getBlocks(t.hash(),Math.min(e.maxInvSize,FullConsensusAgent.GETBLOCKS_VECTORS_MAX),e.direction===GetBlocksMessage.Direction.FORWARD),r=[];for(const n of s)r.push(InvVector.fromBlock(n));this._peer.channel.inv(r)}async _onGetChainProof(e){if(!this._chainProofLimit.note()){Log.w(FullConsensusAgent,"Rejecting GetChainProof message - rate-limit exceeded");this._peer.channel.close(CloseType.RATE_LIMIT_EXCEEDED,"rate-limit exceeded");return}const t=await this._blockchain.getChainProof();this._peer.channel.chainProof(t)}async _onGetBlockProof(e){if(!this._blockProofLimit.note()){Log.w(FullConsensusAgent,"Rejecting GetBlockProof message - rate-limit exceeded");this._peer.channel.blockProof(null);return}const t=await this._blockchain.getBlock(e.blockHashToProve),s=await this._blockchain.getBlock(e.knownBlockHash);if(!t||!s){this._peer.channel.blockProof();return}const r=await this._blockchain.getBlockProof(t,s);this._peer.channel.blockProof(r)}async _onGetBlockProofAt(e){if(!this._blockProofLimit.note()){Log.w(FullConsensusAgent,"Rejecting GetBlockProof message - rate-limit exceeded");this._peer.channel.blockProof(null);return}const t=await this._blockchain.getBlockAt(e.blockHeightToProve),s=await this._blockchain.getBlock(e.knownBlockHash);if(!t||!s){this._peer.channel.blockProof();return}const r=await this._blockchain.getBlockProof(t,s);this._peer.channel.blockProof(r)}async _onGetAccountsProof(e){if(!this._accountsProofLimit.note()){Log.w(FullConsensusAgent,"Rejecting GetAccountsProof message - rate-limit exceeded");this._peer.channel.accountsProof(e.blockHash,null);return}const t=await this._blockchain.getAccountsProof(e.blockHash,e.addresses);this._peer.channel.accountsProof(e.blockHash,t)}async _onGetTransactionsProofByAddresses(e){if(!this._transactionsProofLimit.note()){Log.w(FullConsensusAgent,"Rejecting GetTransactionsProof message - rate-limit exceeded");this._peer.channel.transactionsProof(e.blockHash,null);return}const t=await this._blockchain.getTransactionsProofByAddresses(e.blockHash,e.addresses);this._peer.channel.transactionsProof(e.blockHash,t)}async _onGetTransactionsProofByHashes(e){if(!this._transactionsProofLimit.note()){Log.w(FullConsensusAgent,"Rejecting GetTransactionsProof message - rate-limit exceeded");this._peer.channel.transactionsProof(e.blockHash,null);return}const t=await this._blockchain.getTransactionsProofByHashes(e.blockHash,e.hashes);this._peer.channel.transactionsProof(e.blockHash,t)}async _onGetAccountsTreeChunk(e){if(!this._accountsTreeChunkLimit.note()){Log.w(FullConsensusAgent,"Rejecting GetAccountsTreeChunk message - rate-limit exceeded");this._peer.channel.accountsTreeChunk(e.blockHash,null);return}const t=await this._blockchain.getAccountsTreeChunk(e.blockHash,e.startPrefix);this._peer.channel.accountsTreeChunk(e.blockHash,t)}async _onGetTransactionReceiptsByAddress(e){if(!this._transactionReceiptsLimit.note()){Log.w(FullConsensusAgent,"Rejecting GetTransactionReceipts message - rate-limit exceeded");this._peer.channel.transactionReceipts(null);return}const t=await this._blockchain.getTransactionReceiptsByAddress(e.address,TransactionReceiptsMessage.RECEIPTS_MAX_COUNT);this._peer.channel.transactionReceipts(t)}async _onGetTransactionReceiptsByHashes(e){if(!this._transactionReceiptsLimit.note()){Log.w(FullConsensusAgent,"Rejecting GetTransactionReceipts message - rate-limit exceeded");this._peer.channel.transactionReceipts(null);return}const t=await this._blockchain.getTransactionReceiptsByHashes(e.hashes,TransactionReceiptsMessage.RECEIPTS_MAX_COUNT);this._peer.channel.transactionReceipts(t)}get syncing(){return this._syncing}_getSubscribedMempoolTransactions(){switch(this._remoteSubscription.type){case Subscription.Type.ADDRESSES:return this._mempool.getTransactionsByAddresses(this._remoteSubscription.addresses,FullConsensusAgent.MEMPOOL_ENTRIES_MAX);case Subscription.Type.ANY:return new LimitIterable(this._mempool.transactionGenerator(),FullConsensusAgent.MEMPOOL_ENTRIES_MAX)}return[]}}FullConsensusAgent.SYNC_ATTEMPTS_MAX=25;FullConsensusAgent.GETBLOCKS_VECTORS_MAX=500;FullConsensusAgent.RESYNC_THROTTLE=3e3;FullConsensusAgent.MEMPOOL_DELAY_MIN=2e3;FullConsensusAgent.MEMPOOL_DELAY_MAX=2e4;FullConsensusAgent.MEMPOOL_THROTTLE=1e3;FullConsensusAgent.MEMPOOL_ENTRIES_MAX=1e4;FullConsensusAgent.CHAIN_PROOF_RATE_LIMIT=3;FullConsensusAgent.ACCOUNTS_PROOF_RATE_LIMIT=60;FullConsensusAgent.ACCOUNTS_TREE_CHUNK_RATE_LIMIT=300;FullConsensusAgent.TRANSACTION_PROOF_RATE_LIMIT=180;FullConsensusAgent.TRANSACTION_RECEIPTS_RATE_LIMIT=30;FullConsensusAgent.BLOCK_PROOF_RATE_LIMIT=180;FullConsensusAgent.GET_BLOCKS_RATE_LIMIT=30;Class.register(FullConsensusAgent);class FullConsensus extends BaseConsensus{constructor(e,t,s){super(e,t,s);this._blockchain=e;this._mempool=t;this._producer=new BlockProducer(e,e.accounts,t,s.time)}getBlock(e,t=!0,s=t,r){const n=this._blockchain.getBlock(e,!0,t);if(!n)throw new Error(`No block found for hash ${e}`);return n}getBlockAt(e,t=!0){if(e>this._blockchain.height||e<1)throw new Error("Invalid height");const s=this._blockchain.getBlockAt(e,t);if(!s)throw new Error(`No block found at height ${e}`);return s}getBlockTemplate(e,t){return this._producer.getNextBlock(e,t)}async submitBlock(e){return await this.blockchain.pushBlock(e)>=0}getAccounts(e){return Promise.all(e.map(e=>this._blockchain.accounts.get(e)))}async getPendingTransactions(e){return e.map(e=>this._mempool.getTransaction(e)).filter(e=>null!=e)}async getPendingTransactionsByAddress(e,t){return this._mempool.getTransactionsByAddresses([e],t)}async getTransactionsFromBlock(e,t,s,r){if(!(r=r&&r.isFull()?r:await this._blockchain.getBlock(t,!1,!0)))throw new Error(`No block found for hash ${t}`);return r.transactions.filter(t=>e.find(e=>e.equals(t.hash())))}getTransactionReceiptsByAddress(e,t){return this._blockchain.getTransactionReceiptsByAddress(e,t)}getTransactionReceiptsByHashes(e){return this._blockchain.getTransactionReceiptsByHashes(e)}async sendTransaction(e){switch(await this._mempool.pushTransaction(e)){case Mempool.ReturnCode.ACCEPTED:return await new Promise(t=>{let s;s=this.on("transaction-relayed",r=>{if(r.equals(e)){this.off("transaction-relayed",s);t(!0)}});setTimeout(()=>{this.off("transaction-relayed",s);t(!1)},BaseConsensus.TRANSACTION_RELAY_TIMEOUT)})?BaseConsensus.SendTransactionResult.RELAYED:BaseConsensus.SendTransactionResult.PENDING_LOCAL;case Mempool.ReturnCode.KNOWN:return BaseConsensus.SendTransactionResult.KNOWN;case Mempool.ReturnCode.FEE_TOO_LOW:case Mempool.ReturnCode.FILTERED:return BaseConsensus.SendTransactionResult.REJECTED_LOCAL;case Mempool.ReturnCode.MINED:return BaseConsensus.SendTransactionResult.ALREADY_MINED;case Mempool.ReturnCode.EXPIRED:return BaseConsensus.SendTransactionResult.EXPIRED;case Mempool.ReturnCode.INVALID:return BaseConsensus.SendTransactionResult.INVALID}return BaseConsensus.SendTransactionResult.NONE}getMempoolContents(){return this._mempool.getTransactions()}_newConsensusAgent(e){return new FullConsensusAgent(this._blockchain,this._mempool,this._network.time,e,this._invRequestManager,this._subscription)}get blockchain(){return this._blockchain}get mempool(){return this._mempool}}Class.register(FullConsensus);class LightChain extends FullChain{static getPersistent(e,t,s){const r=ChainDataStore.getPersistent(e);return new LightChain(r,t,s)._init()}static createVolatile(e,t){const s=ChainDataStore.createVolatile();return new LightChain(s,e,t)._init()}constructor(e,t,s){super(e,t,s)}async _init(){await FullChain.prototype._init.call(this);this._proof||(this._proof=await this._getChainProof());return this}async partialChain(){const e=await this.getChainProof(),t=new PartialLightChain(this._store,this._accounts,this._time,e,this._synchronizer);t.on("committed",(e,t,s,r)=>{this._proof=e;this._headHash=t;this._mainChain=s;this._transactionCache=r;this.fire("block",t);this.fire("head-changed",this.head)});await t._init();return t}_shouldExtendChainProof(){return!0}}Class.register(LightChain);class LightConsensusAgent extends FullConsensusAgent{constructor(e,t,s,r,n,i){super(e,t,s,r,n,i);this._blockchain=e;this._partialChain=null;this._syncing=!1;this._catchup=!1;this._onMainChain=!1;this._orphanedBlocks=[];this._busy=!1;this._accountsRequest=null;this._requestedChainProof=!1;this._numWeakProofs=0;this._onToDisconnect(r.channel,"chain-proof",e=>this._onChainProof(e));this._onToDisconnect(r.channel,"accounts-tree-chunk",e=>this._onAccountsTreeChunk(e))}async syncBlockchain(){if(!this.providesServices(Services.FULL_BLOCKS,Services.CHAIN_PROOF,Services.ACCOUNTS_CHUNKS,Services.MEMPOOL)){this._syncFinished();return}if(!this._objectsInFlight.isEmpty()){Log.v(LightConsensusAgent,`Waiting for ${this._objectsInFlight.length} objects to arrive ...`);return}if(!this._objectsProcessing.isEmpty()){Log.v(LightConsensusAgent,`Waiting for ${this._objectsProcessing.length} objects to be processed ...`);return}if(this._failedSyncs>=LightConsensusAgent.SYNC_ATTEMPTS_MAX){this._peer.channel.close(CloseType.BLOCKCHAIN_SYNC_FAILED,"blockchain sync failed");if(this._partialChain){await this._partialChain.abort();this._partialChain=null}return}const e=await this._blockchain.getBlock(this._syncTarget,!0);if(!e||this._syncing){if(!e&&!this._syncing){this._syncing=!0;this._onMainChain=!1;let e;try{e=await this.getHeader(this._syncTarget)}catch(t){this._peer.channel.close(CloseType.ABORTED_SYNC,"Failed to retrieve sync target header");return}this._catchup=Math.abs(e.height-this._blockchain.height)<=Policy.NUM_BLOCKS_VERIFICATION;Log.d(LightConsensusAgent,`Start syncing, catchup mode: ${this._catchup}`)}if(this._syncing&&!this._busy)if(this._catchup)await FullConsensusAgent.prototype.syncBlockchain.call(this);else{this._partialChain||await this._initChainProofSync();switch(this._partialChain.state){case PartialLightChain.State.PROVE_CHAIN:this._requestChainProof();this.fire("sync-chain-proof",this._peer.peerAddress);break;case PartialLightChain.State.PROVE_ACCOUNTS_TREE:this._requestAccountsTree();this.fire("sync-accounts-tree",this._peer.peerAddress);break;case PartialLightChain.State.PROVE_BLOCKS:this._requestProofBlocks();this.fire("verify-accounts-tree",this._peer.peerAddress);break;case PartialLightChain.State.COMPLETE:this.fire("sync-finalize",this._peer.peerAddress);this._busy=!0;await this._partialChain.commit();await this._applyOrphanedBlocks();this._syncFinished();break;case PartialLightChain.State.ABORTED:this._peer.channel.close(CloseType.ABORTED_SYNC,"aborted sync");break;case PartialLightChain.State.WEAK_PROOF:Log.d(LightConsensusAgent,`Not syncing with ${this._peer.peerAddress} - weaker proof`);this._numWeakProofs++;this._numWeakProofs>=LightConsensusAgent.WEAK_PROOFS_MAX?this._peer.channel.close(CloseType.BLOCKCHAIN_SYNC_FAILED,"too many weak proofs"):this._syncFinished()}}}else this._syncFinished()}async _initChainProofSync(){this._subscribeTarget();this._syncing=!0;this._synced=!1;this._catchup=!1;this._onMainChain=!0;this._partialChain&&await this._partialChain.abort();this._partialChain=await this._blockchain.partialChain()}_syncFinished(){this._partialChain&&(this._partialChain=null);this._busy=!1;super._syncFinished()}async _applyOrphanedBlocks(){for(const e of this._orphanedBlocks){if(await this._blockchain.pushBlock(e)===LightChain.ERR_INVALID){this._peer.channel.close(CloseType.INVALID_BLOCK,"received invalid block");break}}this._orphanedBlocks=[]}_requestChainProof(){Assert.that(this._partialChain&&this._partialChain.state===PartialLightChain.State.PROVE_CHAIN);Assert.that(!this._requestedChainProof);this._busy=!0;this._peer.channel.getChainProof();this._requestedChainProof=!0;this._peer.channel.expectMessage(Message.Type.CHAIN_PROOF,()=>{this._peer.channel.close(CloseType.GET_CHAIN_PROOF_TIMEOUT,"getChainProof timeout")},LightConsensusAgent.CHAINPROOF_REQUEST_TIMEOUT,LightConsensusAgent.CHAINPROOF_CHUNK_TIMEOUT)}async _onChainProof(e){Assert.that(this._partialChain&&this._partialChain.state===PartialLightChain.State.PROVE_CHAIN);Log.d(LightConsensusAgent,`[CHAIN-PROOF] Received from ${this._peer.peerAddress}: ${e.proof}`);if(this._requestedChainProof){this._requestedChainProof=!1;this._syncing&&this.fire("verify-chain-proof",this._peer.peerAddress);if(await this._partialChain.pushProof(e.proof)){this._busy=!1;this.syncBlockchain()["catch"](Log.e.tag(LightConsensusAgent))}else{Log.w(LightConsensusAgent,`Invalid chain proof received from ${this._peer.peerAddress} - verification failed`);this._peer.channel.close(CloseType.INVALID_CHAIN_PROOF,"Invalid chain proof")}}else Log.w(LightConsensusAgent,`Unsolicited chain proof received from ${this._peer.peerAddress}`)}_requestAccountsTree(){Assert.that(this._partialChain&&this._partialChain.state===PartialLightChain.State.PROVE_ACCOUNTS_TREE);Assert.that(!this._accountsRequest);this._busy=!0;const e=this._partialChain.getMissingAccountsPrefix(),t=this._partialChain.headHash;Log.d(LightConsensusAgent,`Requesting AccountsTreeChunk starting at ${e} from ${this._peer.peerAddress}`);this._accountsRequest={startPrefix:e,blockHash:t};this._peer.channel.getAccountsTreeChunk(t,e);this._peer.channel.expectMessage(Message.Type.ACCOUNTS_TREE_CHUNK,()=>{this._accountsRequest=null;this._peer.channel.close(CloseType.GET_ACCOUNTS_TREE_CHUNK_TIMEOUT,"getAccountsTreeChunk timeout")},LightConsensusAgent.ACCOUNTS_TREE_CHUNK_REQUEST_TIMEOUT)}async _onAccountsTreeChunk(e){Log.d(LightConsensusAgent,`[ACCOUNTS-TREE-CHUNK] Received from ${this._peer.peerAddress}: blockHash=${e.blockHash}, proof=${e.chunk}`);if(!this._accountsRequest){Log.w(LightConsensusAgent,`Unsolicited accounts tree chunk received from ${this._peer.peerAddress}`);return}Assert.that(this._partialChain&&this._partialChain.state===PartialLightChain.State.PROVE_ACCOUNTS_TREE);const{startPrefix:t,blockHash:s}=this._accountsRequest;this._accountsRequest=null;if(!e.hasChunk()){await this._partialChain.abort();this._partialChain=null;this._busy=!1;this._failedSyncs++;return}if(!s.equals(e.blockHash)||e.chunk.head.prefix<=t){Log.w(LightConsensusAgent,`Received AccountsTreeChunk for block != head or wrong start prefix from ${this._peer.peerAddress}`);this._peer.channel.close(CloseType.UNEXPECTED_ACCOUNTS_TREE_CHUNK,"Unexpected AccountsTreeChunk");return}const r=e.chunk;if(!r.verify()){Log.w(LightConsensusAgent,`Invalid AccountsTreeChunk received from ${this._peer.peerAddress}`);this._peer.channel.close(CloseType.INVALID_ACCOUNTS_TREE_CHUNCK,"Invalid AccountsTreeChunk");return}const n=r.root();if(!(await this._partialChain.getBlock(s)).accountsHash.equals(n)){Log.w(LightConsensusAgent,`Invalid AccountsTreeChunk (root hash) received from ${this._peer.peerAddress}`);this._peer.channel.close(CloseType.INVALID_ACCOUNTS_TREE_CHUNCK,"AccountsTreeChunk root hash mismatch");return}const i=await this._partialChain.pushAccountsTreeChunk(r);if(i<0){Log.e(`AccountsTree sync failed with error code ${i} from ${this._peer.peerAddress}`);this._peer.channel.close(CloseType.INVALID_ACCOUNTS_TREE_CHUNCK,"AccountsTreeChunk root hash mismatch")}this._busy=!1;this.syncBlockchain()["catch"](Log.e.tag(LightConsensusAgent))}_requestProofBlocks(){Assert.that(this._partialChain&&this._partialChain.state===PartialLightChain.State.PROVE_BLOCKS);this._lastChainHeight===this._partialChain.proofHeadHeight&&this._failedSyncs++;this._lastChainHeight=this._partialChain.proofHeadHeight;if(this._peer.channel.isExpectingMessage(Message.Type.INV)){Log.e(LightConsensusAgent,"Duplicate _requestProofBlocks()");return}this._peer.channel.expectMessage(Message.Type.INV,()=>{this._peer.channel.close(CloseType.GET_BLOCKS_TIMEOUT,"getBlocks timeout")},BaseConsensusAgent.REQUEST_TIMEOUT);const e=this._partialChain.getBlockLocators();this.requestVector(new InvVector(InvVector.Type.BLOCK,e[0]));this._peer.channel.getBlocks(e,this._partialChain.numBlocksNeeded(),!1)}_requestBlocks(){return this._syncing&&!this._onMainChain?super._requestBlocks(1):super._requestBlocks()}async _processBlock(e,t){if(t.height<this._chain.height-Policy.NUM_BLOCKS_VERIFICATION&&(!this._partialChain||this._partialChain.state!==PartialLightChain.State.PROVE_BLOCKS)){this._onMainChain=!1;await this._initChainProofSync();this.syncBlockchain()["catch"](Log.e.tag(LightConsensusAgent));return}this._onMainChain=!0;switch(await this._chain.pushBlock(t)){case FullChain.ERR_INVALID:this._peer.channel.close(CloseType.INVALID_BLOCK,"received invalid block");break;case FullChain.OK_EXTENDED:case FullChain.OK_REBRANCHED:this._syncing&&this._numBlocksExtending++;break;case FullChain.OK_FORKED:if(this._syncing){this._numBlocksForking++;this._forkHead=t}break;case LightChain.ERR_ORPHAN:this._onOrphanBlock(e,t)}}async _onKnownBlockAnnounced(e,t){if(this._syncing&&this._catchup){if(t.height<this._chain.height-Policy.NUM_BLOCKS_VERIFICATION&&(!this._partialChain||this._partialChain.state!==PartialLightChain.State.PROVE_BLOCKS)){this._onMainChain=!1;await this._initChainProofSync();this.syncBlockchain()["catch"](Log.e.tag(LightConsensusAgent));return}this._onMainChain=!0;FullConsensusAgent.prototype._onKnownBlockAnnounced.call(this,e,t)}}_onOrphanBlock(e,t){this._syncing&&!this._catchup?this._orphanedBlocks.push(t):super._onOrphanBlock(e,t)}getHeader(e){Assert.that(!this._headerRequest);return new Promise((t,s)=>{const r=new InvVector(InvVector.Type.BLOCK,e);this._headerRequest={hash:e,resolve:t,reject:s};this._peer.channel.getHeader([r]);this._peer.channel.expectMessage(Message.Type.HEADER,()=>{this._headerRequest=null;this._peer.channel.close(CloseType.GET_HEADER_TIMEOUT,"getHeader timeout");s(new Error("Timeout"))},BaseConsensusAgent.REQUEST_TIMEOUT)})}_onHeader(e){const t=e.header,s=t.hash();if(!this._headerRequest){Log.w(NanoConsensusAgent,`Unsolicited header ${s} received from ${this._peer.peerAddress}, discarding`);return}const{hash:r,resolve:n,reject:i}=this._headerRequest;this._headerRequest=null;if(r.equals(s))n(t);else{Log.w(LightConsensusAgent,`Received wrong header from ${this._peer.peerAddress}`);this._peer.channel.close(CloseType.UNEXPECTED_HEADER,"Received wrong header");i(new Error("Received wrong header"))}}_onClose(){this._partialChain&&this._partialChain.abort()["catch"](Log.w.tag(LightConsensusAgent));super._onClose()}get _chain(){return this._syncing&&!this._catchup&&this._partialChain?this._partialChain:this._blockchain}get syncing(){return this._syncing}}LightConsensusAgent.CHAINPROOF_REQUEST_TIMEOUT=45e3;LightConsensusAgent.CHAINPROOF_CHUNK_TIMEOUT=1e4;LightConsensusAgent.ACCOUNTS_TREE_CHUNK_REQUEST_TIMEOUT=8e3;LightConsensusAgent.SYNC_ATTEMPTS_MAX=5;LightConsensusAgent.GETBLOCKS_VECTORS_MAX=500;LightConsensusAgent.WEAK_PROOFS_MAX=3;Class.register(LightConsensusAgent);class LightConsensus extends BaseConsensus{constructor(e,t,s){super(e,t,s);this._blockchain=e;this._mempool=t;this._producer=new BlockProducer(e,e.accounts,t,s.time)}getBlockTemplate(e,t){return this._producer.getNextBlock(e,t)}async submitBlock(e){return await this.blockchain.pushBlock(e)>=0}getAccounts(e){return Promise.all(e.map(e=>this._blockchain.accounts.get(e)))}async getPendingTransactions(e){return e.map(e=>this._mempool.getTransaction(e)).filter(e=>null!=e)}async getPendingTransactionsByAddress(e,t){return this._mempool.getTransactionsByAddresses([e],t)}async sendTransaction(e){switch(await this._mempool.pushTransaction(e)){case Mempool.ReturnCode.ACCEPTED:return await new Promise(t=>{let s;s=this.on("transaction-relayed",r=>{if(r.equals(e)){this.off("transaction-relayed",s);t(!0)}});setTimeout(()=>{this.off("transaction-relayed",s);t(!1)},BaseConsensus.TRANSACTION_RELAY_TIMEOUT)})?BaseConsensus.SendTransactionResult.RELAYED:BaseConsensus.SendTransactionResult.PENDING_LOCAL;case Mempool.ReturnCode.KNOWN:return BaseConsensus.SendTransactionResult.KNOWN;case Mempool.ReturnCode.FEE_TOO_LOW:case Mempool.ReturnCode.FILTERED:return BaseConsensus.SendTransactionResult.REJECTED_LOCAL;case Mempool.ReturnCode.MINED:return BaseConsensus.SendTransactionResult.ALREADY_MINED;case Mempool.ReturnCode.EXPIRED:return BaseConsensus.SendTransactionResult.EXPIRED;case Mempool.ReturnCode.INVALID:return BaseConsensus.SendTransactionResult.INVALID}return BaseConsensus.SendTransactionResult.NONE}getMempoolContents(){return this._mempool.getTransactions()}_newConsensusAgent(e){return new LightConsensusAgent(this._blockchain,this._mempool,this._network.time,e,this._invRequestManager,this._subscription)}_onPeerJoined(e){const t=super._onPeerJoined(e);this.bubble(t,"sync-chain-proof","verify-chain-proof","sync-accounts-tree","verify-accounts-tree","sync-finalize");return t}get blockchain(){return this._blockchain}get mempool(){return this._mempool}}Class.register(LightConsensus);class PartialLightChain extends LightChain{constructor(e,t,s,r,n){super(e.transaction(!1),t,s);this._proof=r;this._state=PartialLightChain.State.PROVE_CHAIN;this._partialTree=null;this._accountsTx=null;this._proofHead=null;this._commitSynchronizer=n}pushProof(e){return this._synchronizer.push(0,this._pushProof.bind(this,e))}async _pushProof(e){const t=[];for(let i=0;i<e.prefix.length;++i){const s=e.prefix.blocks[i],r=s.hash();await this._store.getBlock(r)||s.header._pow||t.push(s.header)}for(let i=0;i<e.suffix.length;++i){const s=e.suffix.headers[i],r=s.hash();await this._store.getBlock(r)||s._pow||t.push(s)}await BaseChain.manyPow(t);for(let i=0;i<e.prefix.length;i++){const t=e.prefix.blocks[i],s=t.hash(),r=await this._store.getBlock(s);if(r)e.prefix.blocks[i]=r.toLight();else if(!(await t.verify(this._time))){Log.w(PartialLightChain,"Rejecting proof - prefix contains invalid block");return!1}}for(let i=0;i<e.suffix.length;i++){const t=e.suffix.headers[i],s=t.hash(),r=await this._store.getBlock(s);if(r)e.suffix.headers[i]=r.header;else if(!(await t.verifyProofOfWork())){Log.w(PartialLightChain,"Rejecting proof - suffix contains invalid header");return!1}}if(!(await e.verify())){Log.w(PartialLightChain,"Rejecting proof - verification failed");return!1}if(e.suffix.length!==Policy.K&&e.suffix.length!==e.head.height-1){Log.w(PartialLightChain,"Rejecting proof - invalid suffix length");return!1}if(e.prefix.denseSuffix().length<Policy.M&&e.prefix.length>0&&e.prefix.head.height>=Policy.M){Log.w(NanoChain,"Rejecting proof - dense suffix too short");return!1}const s=[];let r=e.prefix.head;for(const i of e.suffix.headers){const e=await r.getNextInterlink(i.target,i.version),t=e.hash();if(!i.interlinkHash.equals(t)){Log.w(PartialLightChain,"Rejecting proof - invalid interlink hash in proof suffix");return!1}r=new Block(i,e);s.push(r)}const n=this._proof||await this._getChainProof();if(await BaseChain.isBetterProof(e,n,Policy.M))await this._acceptProof(e,s);else{await this.abort();this._state=PartialLightChain.State.WEAK_PROOF}return!0}async _acceptProof(e,t){await this._store.truncate();const s=e.prefix.denseSuffix();let r=new SuperBlockCounts;for(let i=0;i<e.prefix.length-s.length;i++){const t=e.prefix.blocks[i],s=t.hash(),n=BlockUtils.getHashDepth(await t.pow());r=r.copyAndAdd(n);const o=new ChainData(t,new BigNumber(-1),new BigNumber(-1),r,!0);await this._store.putChainData(s,o)}const n=s[0];this._headHash=n.hash();this._mainChain=await ChainData.initial(n,r);await this._store.putChainData(this._headHash,this._mainChain);for(let i=1;i<s.length;i++){const e=s[i],t=await this._pushLightBlock(e);Assert.that(t>=0)}for(const i of t){const e=await this._pushLightBlock(i);Assert.that(e>=0)}this._state=PartialLightChain.State.PROVE_ACCOUNTS_TREE;this._partialTree=await this._accounts.partialAccountsTree();this._proofHead=this._mainChain;await this._store.setHead(this.headHash);this._proof=e}async _pushLightBlock(e){const t=e.hash();if(await this._store.getBlock(t))return NanoChain.OK_KNOWN;const s=await this._store.getChainData(e.prevHash);return!s||s.totalDifficulty.lte(0)?NanoChain.ERR_ORPHAN:this._pushBlockInternal(e,t,s)}async _pushBlockInternal(e,t,s){const r=await s.nextChainData(e);if(e.prevHash.equals(this.headHash)){r.onMainChain=!0;s.mainChainSuccessor=t;await this._store.putChainData(t,r);await this._store.putChainData(e.prevHash,s,!1);this._mainChain=r;this._headHash=t;if(this._proof){const t=this._proof.head.hash();e.prevHash.equals(t)&&(this._proof=await this._extendChainProof(this._proof,e.header))}this.fire("head-changed",this.head,!1);return NanoChain.OK_EXTENDED}throw new Error("Invalid call to _pushBlockInternal")}_pushBlock(e){if(this._state===PartialLightChain.State.PROVE_BLOCKS){const t=e.hash();if(this._proofHead.head.prevHash.equals(t))return this._pushBlockBackwards(e);if(this._proofHead.head.hash().equals(t))return this._pushHeadBlock(e)}return FullChain.ERR_ORPHAN}async _pushHeadBlock(e){const t=e.hash();if(!e.isFull()){Log.w(PartialLightChain,"Rejecting block - body missing");return FullChain.ERR_INVALID}if(!(await e.verify(this._time)))return FullChain.ERR_INVALID;if(!(await this._verifyInterlink(e))){Log.w(PartialLightChain,"Rejecting block - interlink verification failed");return FullChain.ERR_INVALID}const s=await this._store.getChainData(e.prevHash);if(!s){Log.w(PartialLightChain,"Rejecting block - unknown predecessor");return FullChain.ERR_ORPHAN}const r=s.head;if(!(await e.isImmediateSuccessorOf(r))){Log.w(PartialLightChain,"Rejecting block - not a valid immediate successor");return FullChain.ERR_INVALID}const n=await this.getNextTarget(r);if(BlockUtils.isValidTarget(n)){if(e.nBits!==BlockUtils.targetToCompact(n)){Log.w(PartialLightChain,"Rejecting block - difficulty mismatch");return FullChain.ERR_INVALID}}else Log.w(PartialLightChain,"Skipping difficulty verification - not enough blocks available");const i=await s.nextChainData(e);if(!(await this._prepend(t,i)))return FullChain.ERR_INVALID;this._mainChain=i;this._proofHead=i;this._headHash=t;if(!this.needsMoreBlocks()){if(!(await this._complete()))return FullChain.ERR_INVALID}return FullChain.OK_EXTENDED}async _pushBlockBackwards(e){const t=e.hash();if(!e.isFull()){Log.w(PartialLightChain,"Rejecting block - body missing");return FullChain.ERR_INVALID}if(!(await e.verify(this._time)))return FullChain.ERR_INVALID;if(!(await this._verifyInterlink(e))){Log.w(PartialLightChain,"Rejecting block - interlink verification failed");return FullChain.ERR_INVALID}if(!(await this._proofHead.head.isImmediateSuccessorOf(e))){Log.w(PartialLightChain,"Rejecting block - not a valid immediate predecessor");return FullChain.ERR_INVALID}const s=await this.getNextTarget(e);if(BlockUtils.isValidTarget(s)){if(this._proofHead.head.nBits!==BlockUtils.targetToCompact(s)){Log.w(PartialLightChain,"Rejecting block - difficulty mismatch");return FullChain.ERR_INVALID}}else Log.w(PartialLightChain,"Skipping difficulty verification - not enough blocks available");const r=await this._proofHead.previousChainData(e);return await this._prepend(t,r)?FullChain.OK_EXTENDED:FullChain.ERR_INVALID}async _prepend(e,t){try{const e=new TransactionCache;await this._accountsTx.revertBlock(t.head,e)}catch(s){Log.w(PartialLightChain,`Rejecting block - failed to commit to AccountsTree: ${s.message||s}`);return!1}t.onMainChain=!0;t.mainChainSuccessor=t.head.hash().equals(this._proofHead.head.hash())?null:this._proofHead.head.hash();await this._store.putChainData(e,t);this._proofHead=t;return!!this.needsMoreBlocks()||this._complete()}async pushAccountsTreeChunk(e){if(this._state!==PartialLightChain.State.PROVE_ACCOUNTS_TREE)return PartialAccountsTree.Status.ERR_INCORRECT_PROOF;const t=await this._partialTree.pushChunk(e);if(t===PartialAccountsTree.Status.OK_COMPLETE){this._state=PartialLightChain.State.PROVE_BLOCKS;this._accountsTx=new Accounts(this._partialTree.transaction(!1))}return t}async _complete(){this._transactionCache=new TransactionCache;let e=this._proofHead;for(;e;){for(const t of e.head.transactions)if(this._transactionCache.containsTransaction(t)){Log.w(PartialLightChain,"Rejecting block - Double Transaction Error!");return!1}this._transactionCache.pushBlock(e.head);e=e.mainChainSuccessor?await this._store.getChainData(e.mainChainSuccessor,!0):null}this._state=PartialLightChain.State.COMPLETE;if(this._accountsTx){await this._accountsTx.abort();this._accountsTx=null}const t=this._proof||await this._getChainProof();this.fire("complete",t,this._headHash,this._mainChain,this._transactionCache);return!0}async commit(){return this._commitSynchronizer.push(0,this._commit.bind(this))}async _commit(){if(this._accountsTx){await this._accountsTx.abort();this._accountsTx=null}const e=await JDB.JungleDB.commitCombined(...this._store.txs,this._partialTree.tx);this._partialTree=null;const t=this._proof||await this._getChainProof();e&&this.fire("committed",t,this._headHash,this._mainChain,this._transactionCache);return e}async abort(){if(this._state!==PartialLightChain.State.ABORTED){this._state=PartialLightChain.State.ABORTED;if(this._accountsTx){await this._accountsTx.abort();this._accountsTx=null}if(this._partialTree){await this._partialTree.abort();this._partialTree=null}await this._store.abort();this.fire("aborted")}}getMissingAccountsPrefix(){return this._partialTree?this._partialTree.missingPrefix:""}getBlockLocators(){return this._proofHead?[this._proofHead.head.hash()]:[this.headHash]}numBlocksNeeded(){if(!this._proofHead)return Policy.NUM_BLOCKS_VERIFICATION;let e=Policy.NUM_BLOCKS_VERIFICATION-(this.height-this._proofHead.head.height+1);this._proofHead.head.isFull()||e++;return e}needsMoreBlocks(){return this.numBlocksNeeded()>0}get state(){return this._state}get proofHeadHeight(){return this._proofHead.head.height}}PartialLightChain.State={WEAK_PROOF:-2,ABORTED:-1,PROVE_CHAIN:0,PROVE_ACCOUNTS_TREE:1,PROVE_BLOCKS:2,COMPLETE:3};Class.register(PartialLightChain);class NanoChain extends BaseChain{constructor(e){super(ChainDataStore.createVolatile());this._time=e;this._proof=new ChainProof(new BlockChain([GenesisConfig.GENESIS_BLOCK.toLight()]),new HeaderChain([]));this._headHash=GenesisConfig.GENESIS_HASH;this._synchronizer=new PrioritySynchronizer(2,NanoChain.SYNCHRONIZER_THROTTLE_AFTER,NanoChain.SYNCHRONIZER_THROTTLE_WAIT);return this._init()}async _init(){this._mainChain=await ChainData.initial(GenesisConfig.GENESIS_BLOCK);await this._store.putChainData(GenesisConfig.GENESIS_HASH,this._mainChain);return this}pushProof(e){return this._synchronizer.push(0,this._pushProof.bind(this,e))}async _pushProof(e){const t=[];for(let i=0;i<e.prefix.length;++i){const s=e.prefix.blocks[i],r=s.hash();await this._store.getBlock(r)||s.header._pow||t.push(s.header)}for(let i=0;i<e.suffix.length;++i){const s=e.suffix.headers[i],r=s.hash();await this._store.getBlock(r)||s._pow||t.push(s)}await BaseChain.manyPow(t);for(let i=0;i<e.prefix.length;i++){i%1e3==999&&await EventLoopHelper.webYield();const t=e.prefix.blocks[i],s=t.hash(),r=await this._store.getBlock(s);if(r)e.prefix.blocks[i]=r.toLight();else if(!(await t.verify(this._time))){Log.w(NanoChain,"Rejecting proof - prefix contains invalid block");return!1}}for(let i=0;i<e.suffix.length;i++){const t=e.suffix.headers[i],s=t.hash(),r=await this._store.getBlock(s);if(r)e.suffix.headers[i]=r.header;else if(!(await t.verifyProofOfWork())){Log.w(NanoChain,"Rejecting proof - suffix contains invalid header");return!1}}if(!(await e.verify())){Log.w(NanoChain,"Rejecting proof - verification failed");return!1}if(e.suffix.length!==Policy.K&&e.suffix.length!==e.head.height-1){Log.w(NanoChain,"Rejecting proof - invalid suffix length");return!1}if(e.prefix.denseSuffix().length<Policy.M&&e.prefix.length>0&&e.prefix.head.height>=Policy.M){Log.w(NanoChain,"Rejecting proof - dense suffix too short");return!1}const s=[];let r=e.prefix.head;for(const i of e.suffix.headers){const e=await r.getNextInterlink(i.target,i.version),t=e.hash();if(!i.interlinkHash.equals(t)){Log.w(NanoChain,"Rejecting proof - invalid interlink hash in proof suffix");return!1}r=new Block(i,e);s.push(r)}await EventLoopHelper.webYield();const n=this._proof||await this._getChainProof();await BaseChain.isBetterProof(e,n,Policy.M)&&await this._acceptProof(e,s);return!0}async _acceptProof(e,t){this._proof=e;const s=e.prefix.head.hash(),r=await this._store.getChainData(s);if(!r||r.totalDifficulty.lte(0)){await this._store.truncate();const t=e.prefix.denseSuffix();let s=new SuperBlockCounts;for(let n=0;n<e.prefix.length-t.length;n++){n%100==99&&await EventLoopHelper.webYield();const t=e.prefix.blocks[n],r=t.hash(),i=BlockUtils.getHashDepth(await t.pow());s=s.copyAndAdd(i);const o=new ChainData(t,new BigNumber(-1),new BigNumber(-1),s,!0);await this._store.putChainData(r,o)}const r=t[0];this._headHash=r.hash();this._mainChain=await ChainData.initial(r,s);await this._store.putChainData(this._headHash,this._mainChain);for(let e=1;e<t.length;e++){e%50==49&&await EventLoopHelper.webYield();const s=t[e],r=await this._pushBlock(s);Assert.that(r>=0)}}for(const n of t){n.height%50==49&&await EventLoopHelper.webYield();const e=await this._pushBlock(n);Assert.that(e>=0)}}async _pushBlock(e){const t=await e.hash();if(await this._store.getBlock(t))return NanoChain.OK_KNOWN;const s=await this._store.getChainData(e.prevHash);return!s||s.totalDifficulty.lte(0)?NanoChain.ERR_ORPHAN:this._pushBlockInternal(e,t,s)}pushHeader(e){return this._synchronizer.push(0,this._pushHeader.bind(this,e))}async _pushHeader(e){const t=e.hash();if(await this._store.getBlock(t))return NanoChain.OK_KNOWN;if(!(await e.verifyProofOfWork())){Log.w(NanoChain,"Rejecting header - PoW verification failed");return NanoChain.ERR_INVALID}const s=await this._store.getChainData(e.prevHash);if(!s||s.totalDifficulty.lte(0)){Log.w(NanoChain,"Rejecting header - unknown predecessor");return NanoChain.ERR_ORPHAN}const r=s.head;if(!e.isImmediateSuccessorOf(r.header)){Log.w(NanoChain,"Rejecting header - not a valid successor");return NanoChain.ERR_INVALID}const n=await this.getNextTarget(r);if(BlockUtils.isValidTarget(n)){if(e.nBits!==BlockUtils.targetToCompact(n)){Log.w(NanoChain,"Rejecting header - difficulty mismatch");return NanoChain.ERR_INVALID}}else Log.w(NanoChain,"Skipping difficulty verification - not enough blocks available");const i=await r.getNextInterlink(e.target,e.version);if(!i.hash().equals(e.interlinkHash)){Log.w(NanoChain,"Rejecting header - interlink verification failed");return NanoChain.ERR_INVALID}const o=new Block(e,i);return this._pushBlockInternal(o,t,s)}async _pushBlockInternal(e,t,s){const r=await s.nextChainData(e);if(e.prevHash.equals(this.headHash)){r.onMainChain=!0;s.mainChainSuccessor=t;const n=this._store.synchronousTransaction();n.putChainDataSync(t,r);n.putChainDataSync(e.prevHash,s);await n.commit();this._mainChain=r;this._headHash=t;if(this._proof){const t=this._proof.head.hash();e.prevHash.equals(t)&&(this._proof=await this._extendChainProof(this._proof,e.header))}await this.fire("head-changed",this.head,!1);await this.fire("block",t);await this.fire("extended",this.head);return NanoChain.OK_EXTENDED}if(r.totalDifficulty.gt(this._mainChain.totalDifficulty)){await this._rebranch(t,r);return NanoChain.OK_REBRANCHED}Log.v(NanoChain,`Creating/extending fork with block ${t}, height=${e.height}, totalDifficulty=${r.totalDifficulty}, totalWork=${r.totalWork}`);await this._store.putChainData(t,r);await this.fire("block",t);return NanoChain.OK_FORKED}async _rebranch(e,t){Log.v(NanoChain,`Rebranching to fork ${e}, height=${t.head.height}, totalDifficulty=${t.totalDifficulty}, totalWork=${t.totalWork}`);const s=[],r=[];let n=t,i=e;for(;!n.onMainChain;){s.push(n);r.push(i);i=n.head.prevHash;n=await this._store.getChainData(i);Assert.that(!!n,"Failed to find fork predecessor while rebranching")}Log.v(NanoChain,()=>`Found common ancestor ${i.toBase64()} ${s.length} blocks up`);const o=n,a=i,c=this._store.synchronousTransaction(!1),h=[];let l=this._headHash,u=this._mainChain;for(;!l.equals(a);){u.onMainChain=!1;u.mainChainSuccessor=null;c.putChainDataSync(l,u);h.push(u);l=u.head.prevHash;u=await this._store.getChainData(l);Assert.that(!!u,"Failed to find main chain predecessor while rebranching")}o.mainChainSuccessor=r[r.length-1];c.putChainDataSync(a,o);for(let f=s.length-1;f>=0;f--){const e=s[f];e.onMainChain=!0;e.mainChainSuccessor=f>0?r[f-1]:null;c.putChainDataSync(r[f],e)}await c.commit();this._proof=null;const d=[];for(const f of h){await this.fire("block-reverted",f.head);d.push(f.head)}const _=[];for(let f=s.length-1;f>=0;f--){this._mainChain=s[f];this._headHash=r[f];await this.fire("head-changed",this.head,f>0);_.push(this.head)}await this.fire("block",e);await this.fire("rebranched",d,_,e)}getChainProof(){return this._synchronizer.push(1,async()=>{this._proof||(this._proof=await this._getChainProof());return this._proof})}get head(){return this._mainChain.head}get headHash(){return this._headHash}get height(){return this._mainChain.head.height}}NanoChain.ERR_ORPHAN=-2;NanoChain.ERR_INVALID=-1;NanoChain.OK_KNOWN=0;NanoChain.OK_EXTENDED=1;NanoChain.OK_REBRANCHED=2;NanoChain.OK_FORKED=3;NanoChain.SYNCHRONIZER_THROTTLE_AFTER=500;NanoChain.SYNCHRONIZER_THROTTLE_WAIT=30;Class.register(NanoChain);class NanoConsensusAgent extends BaseMiniConsensusAgent{constructor(e,t,s,r,n,i){super(e,t,s,r,n,i);this._blockchain=e;this._mempool=t;this._syncing=!1;this._orphanedBlocks=[];this._requestedChainProof=!1;this._onToDisconnect(r.channel,"chain-proof",e=>this._onChainProof(e));this._onToDisconnect(r.channel,"get-chain-proof",e=>this._onGetChainProof(e));this._subscribeTarget()}async syncBlockchain(){if(!this.providesServices(Services.CHAIN_PROOF)){this._syncFinished();return}this._syncing=!0;if(await this._blockchain.getBlock(this._peer.headHash))this._syncFinished();else{this._requestChainProof();this.fire("sync-chain-proof",this._peer.peerAddress)}}_syncFinished(){this._syncing=!1;this._synced=!0;this.requestMempool();this.fire("sync")}_requestChainProof(){if(!this._requestedChainProof){this._peer.channel.getChainProof();this._requestedChainProof=!0;this._peer.channel.expectMessage(Message.Type.CHAIN_PROOF,()=>{this._peer.channel.close(CloseType.GET_CHAIN_PROOF_TIMEOUT,"getChainProof timeout")},NanoConsensusAgent.CHAINPROOF_REQUEST_TIMEOUT,NanoConsensusAgent.CHAINPROOF_CHUNK_TIMEOUT)}}async _onChainProof(e){Log.d(NanoConsensusAgent,`[CHAIN-PROOF] Received from ${this._peer.peerAddress}: ${e.proof}`);if(this._requestedChainProof){this._requestedChainProof=!1;this._syncing&&this.fire("verify-chain-proof",this._peer.peerAddress);if(await this._blockchain.pushProof(e.proof)){await this._applyOrphanedBlocks();this._syncing&&this._syncFinished()}else{Log.w(NanoConsensusAgent,`Invalid chain proof received from ${this._peer.peerAddress} - verification failed`);this._peer.channel.close(CloseType.INVALID_CHAIN_PROOF,"Invalid chain proof")}}else Log.w(NanoConsensusAgent,`Unsolicited chain proof received from ${this._peer.peerAddress}`)}async _applyOrphanedBlocks(){for(const e of this._orphanedBlocks){if(await this._blockchain.pushHeader(e)===NanoChain.ERR_INVALID){this._peer.channel.close(CloseType.INVALID_BLOCK,"received invalid block");break}}this._orphanedBlocks=[]}_willRequestHeaders(){return!0}_getBlock(e,t=!1,s=!1){return this._blockchain.getBlock(e,t,s)}_getRawBlock(e,t=!1){return this._blockchain.getRawBlock(e,t)}_getTransaction(e){return this._mempool.getTransaction(e)}async _processHeader(e,t){const s=await this._blockchain.pushHeader(t);if(s===NanoChain.ERR_INVALID)this._peer.channel.close(CloseType.INVALID_HEADER,"received invalid header");else if(s===NanoChain.ERR_ORPHAN){this._orphanedBlocks.push(t);this._synced&&this._requestChainProof()}}async _processTransaction(e,t){await this._mempool.pushTransaction(t)}async _onGetChainProof(e){const t=await this._blockchain.getChainProof();t&&this._peer.channel.chainProof(t)}_onClose(){this._synchronizer.clear();super._onClose()}get syncing(){return this._syncing}}NanoConsensusAgent.CHAINPROOF_REQUEST_TIMEOUT=45e3;NanoConsensusAgent.CHAINPROOF_CHUNK_TIMEOUT=1e4;Class.register(NanoConsensusAgent);class NanoConsensus extends BaseMiniConsensus{constructor(e,t,s){super(e,t,s);this._blockchain=e;this._mempool=t}_newConsensusAgent(e){return new NanoConsensusAgent(this._blockchain,this._mempool,this._network.time,e,this._invRequestManager,this._subscription)}_onPeerJoined(e){const t=super._onPeerJoined(e);this.bubble(t,"sync-chain-proof","verify-chain-proof");return t}get blockchain(){return this._blockchain}get mempool(){return this._mempool}}Class.register(NanoConsensus);class NanoMempool extends Observable{constructor(e){super();this._blockchain=e;this._transactionsByHash=new HashMap;this._transactionSetBySender=new HashMap;this._transactionSetByRecipient=new HashMap}async pushTransaction(e){const t=e.hash();if(this._transactionsByHash.contains(t)){Log.v(Mempool,()=>`Ignoring known transaction ${t.toBase64()}`);return Mempool.ReturnCode.KNOWN}if(this._blockchain.height>=e.validityStartHeight+Policy.TRANSACTION_VALIDITY_WINDOW){Log.v(Mempool,()=>`Ignoring expired transaction ${t.toBase64()}`);return Mempool.ReturnCode.EXPIRED}if(!e.verify())return Mempool.ReturnCode.INVALID;this._transactionsByHash.put(t,e);const s=this._transactionSetBySender.get(e.sender)||new MempoolTransactionSet;s.add(e);this._transactionSetBySender.put(e.sender,s);const r=this._transactionSetByRecipient.get(e.recipient)||new HashSet;r.add(e);this._transactionSetByRecipient.put(e.recipient,r);this.fire("transaction-added",e);return Mempool.ReturnCode.ACCEPTED}getTransaction(e){return this._transactionsByHash.get(e)}getTransactions(e=5e3){return this._transactionsByHash.values().sort((e,t)=>e.compare(t)).slice(0,e)}getPendingTransactions(e){return this.getTransactionsBySender(e)}getTransactionsBySender(e){const t=this._transactionSetBySender.get(e);return t?t.transactions:[]}getTransactionsByRecipient(e){const t=this._transactionSetByRecipient.get(e);return t?t.values():[]}getTransactionsByAddresses(e,t=Infinity){const s=[];for(const r of e){const e=this.getTransactionsBySender(r);for(const r of e){if(s.length>=t)return s;s.push(r)}const n=this.getTransactionsByRecipient(r);for(const r of n){if(s.length>=t)return s;s.push(r)}}return s}async changeHead(e,t){await this._evictTransactions(e,t)}removeTransaction(e){this._transactionsByHash.remove(e.hash());const t=this._transactionSetBySender.get(e.sender);t.remove(e);0===t.length&&this._transactionSetBySender.remove(e.sender);const s=this._transactionSetByRecipient.get(e.recipient);s.remove(e);0===s.length&&this._transactionSetByRecipient.remove(e.recipient);this.fire("transaction-removed",e)}evictExceptAddresses(e){const t=new HashSet;t.addAll(e);for(const s of this._transactionsByHash.values())t.contains(s.sender)||t.contains(s.recipient)||this.removeTransaction(s)}async _evictTransactions(e,t){for(const s of this._transactionsByHash.values())if(e.height>=s.validityStartHeight+Policy.TRANSACTION_VALIDITY_WINDOW){this.removeTransaction(s);this.fire("transaction-expired",s)}for(const s of t){const t=s.hash();if(this._transactionsByHash.contains(t)){this.removeTransaction(s);this.fire("transaction-mined",s,e)}}}get length(){return this._transactionsByHash.length}}Class.register(NanoMempool);class PicoChain extends BaseChain{constructor(e){super(ChainDataStore.createVolatile());this._time=e;this._synchronizer=new Synchronizer;this._mainChain=null;return this._init()}async reset(){this._mainChain=await ChainData.initial(GenesisConfig.GENESIS_BLOCK);await this._store.putChainData(GenesisConfig.GENESIS_HASH,this._mainChain)}async _init(){await this.reset();return this}async pushBlock(e){return this._synchronizer.push(()=>this._pushBlock(e))}async _pushBlock(e){if(await this._store.getChainData(e.hash()))return PicoChain.OK_KNOWN;if(!(await e.verify(this._time)))return PicoChain.ERR_INVALID;const t=await this._store.getChainData(e.prevHash);if(this.height<=1){this._mainChain=await ChainData.initial(e);await this._store.putChainData(this._mainChain.head.hash(),this._mainChain);Log.d(PicoChain,`Choosing initial block height=${e.height}, hash=${e.hash().toHex()}`);this.fire("head-changed",this.head);await this.fire("block",e.hash());await this.fire("extended",this.head);return PicoChain.OK_EXTENDED}if(await e.isImmediateSuccessorOf(this.head)){this._mainChain.mainChainSuccessor=e.hash();await this._store.putChainData(this._mainChain.head.hash(),this._mainChain);this._mainChain=await this._mainChain.nextChainData(e);this._mainChain.onMainChain=!0;await this._store.putChainData(this._mainChain.head.hash(),this._mainChain);Log.d(PicoChain,`Appending block height=${e.height}, hash=${e.hash().toHex()}`);this.fire("head-changed",this.head);await this.fire("block",e.hash());await this.fire("extended",this.head);return PicoChain.OK_EXTENDED}if(await this.head.isImmediateSuccessorOf(e)){const t=await ChainData.initial(e);t.mainChainSuccessor=this.head.hash();await this._store.putChainData(t.head.hash(),t);this._mainChain=await t.nextChainData(this.head);this._mainChain.onMainChain=!0;await this._store.putChainData(this._mainChain.head.hash(),this._mainChain);Log.d(PicoChain,`Prepending block height=${e.height}, hash=${e.hash().toHex()}`);await this.fire("block",e.hash());return PicoChain.OK_KNOWN}if(t){const r=await t.nextChainData(e);await this._store.putChainData(e.hash(),r);Log.d(PicoChain,`Storing block height=${e.height}, hash=${e.hash().toHex()}`);if(r.totalWork.gt(this._mainChain.totalWork)){try{await this._rebranch(e.hash(),r)}catch(s){Log.w(PicoChain,"Error while rebranching",s);return PicoChain.ERR_INCONSISTENT}return PicoChain.OK_REBRANCHED}await this.fire("block",e.hash());return PicoChain.OK_FORKED}Log.w(PicoChain,`Inconsistency between block height=${e.height}, hash=${e.hash().toHex()} and block height=${this.height}, hash=${this.headHash.toHex()}`);return PicoChain.ERR_INCONSISTENT}async _rebranch(e,t){Log.d(PicoChain,`Rebranching to fork ${e}, height=${t.head.height}, totalDifficulty=${t.totalDifficulty}, totalWork=${t.totalWork}`);const s=[],r=[];let n=t,i=e;for(;!n.onMainChain;){s.push(n);r.push(i);i=n.head.prevHash;n=await this._store.getChainData(i);Assert.that(!!n,"Failed to find fork predecessor while rebranching")}Log.v(PicoChain,()=>`Found common ancestor ${i.toBase64()} ${s.length} blocks up`);const o=n,a=i,c=this._store.synchronousTransaction(!1),h=[];let l=this.headHash,u=this._mainChain;for(;!l.equals(a);){u.onMainChain=!1;u.mainChainSuccessor=null;c.putChainDataSync(l,u);h.push(u);l=u.head.prevHash;u=await this._store.getChainData(l);Assert.that(!!u,"Failed to find main chain predecessor while rebranching")}o.mainChainSuccessor=r[r.length-1];c.putChainDataSync(a,o);for(let f=s.length-1;f>=0;f--){const e=s[f];e.onMainChain=!0;e.mainChainSuccessor=f>0?r[f-1]:null;c.putChainDataSync(r[f],e)}await c.commit();const d=[];for(const f of h){this.fire("block-reverted",f.head);d.push(f.head)}const _=[];for(let f=s.length-1;f>=0;f--){this._mainChain=s[f];this.fire("head-changed",this.head,f>0);_.push(this.head)}await this.fire("block",e);await this.fire("rebranched",d,_,e)}get head(){return this._mainChain.head}get headHash(){return this.head.hash()}get height(){return this.head.height}}PicoChain.ERR_INCONSISTENT=-2;PicoChain.ERR_INVALID=-1;PicoChain.OK_KNOWN=0;PicoChain.OK_EXTENDED=1;PicoChain.OK_REBRANCHED=2;PicoChain.OK_FORKED=3;Class.register(PicoChain);class PicoConsensusAgent extends BaseMiniConsensusAgent{constructor(e,t,s){super(e.blockchain,e.mempool,e.network.time,t,e.invRequestManager,s);this._consensus=e}async _processBlock(e,t){if(this._peer.headHash.equals(e)){const e=await this._blockchain.pushBlock(t);e===PicoChain.ERR_INVALID?this._peer.channel.close(CloseType.INVALID_BLOCK,"received invalid block"):e===PicoChain.ERR_INCONSISTENT?this.fire("consensus-failed"):this._syncing&&this._syncFinished()}else await this._blockchain.pushBlock(t)===PicoChain.ERR_INVALID&&this._peer.channel.close(CloseType.INVALID_BLOCK,"received invalid block")}async syncBlockchain(){this._syncing=!0;if(await this._getBlock(this._peer.headHash,!0))this._syncFinished();else try{const t=this._peer.headHash,s=await this.requestBlock(t);await this._processBlock(t,s)}catch(e){this._peer.channel.close(CloseType.ABORTED_SYNC,"aborted sync")}}_syncFinished(){this._syncing=!1;this._synced=!0;this.requestMempool();this.fire("sync")}async _processTransaction(e,t){await this._consensus.mempool.pushTransaction(t)}_getBlock(e,t=!1,s=!1){return this._blockchain.getBlock(e,t,s)}_getRawBlock(e,t=!1){return this._blockchain.getRawBlock(e,t)}_getTransaction(e){return this._consensus.mempool.getTransaction(e)}}Class.register(PicoConsensusAgent);class PicoConsensus extends BaseMiniConsensus{constructor(e,t,s){super(e,t,s);this._blockchain=e;this._mempool=t;this._failed=!1}_newConsensusAgent(e){return new PicoConsensusAgent(this,e,this._subscription)}_onPeerJoined(e){const t=super._onPeerJoined(e);t.on("consensus-failed",()=>this._onConsensusFailed());this._agents.length>=3&&this._syncBlockchain();return t}async _onPeerLeft(e){super._onPeerLeft(e);0===this._agents.length&&await this._blockchain.reset()}_syncBlockchain(){this._failed||super._syncBlockchain()}_hasEnoughPeers(e,t){return super._hasEnoughPeers(e,t)&&t>=PicoConsensus.MIN_SYNCED_NODES}_onConsensusFailed(){this._failed=!0;this._syncPeer=null;this.fire("consensus-failed")}get blockchain(){return this._blockchain}get mempool(){return this._mempool}}PicoConsensus.MIN_SYNCED_NODES=3;Class.register(PicoConsensus);class ConsensusDB extends JDB.JungleDB{static async getFull(e=""){ConsensusDB._instance||(ConsensusDB._instance=await new ConsensusDB(e,!1));return ConsensusDB._instance}static async getLight(e=""){ConsensusDB._instance||(ConsensusDB._instance=await new ConsensusDB(e,!0));return ConsensusDB._instance}constructor(e,t){super(ConsensusDB._getDbName(e,t),ConsensusDB.VERSION,{maxDbSize:ConsensusDB.INITIAL_DB_SIZE,autoResize:!0,useWritemap:PlatformUtils.isNodeJs()&&PlatformUtils.isWindows(),minResize:ConsensusDB.MIN_RESIZE,onUpgradeNeeded:ConsensusDB._onUpgradeNeeded.bind(null,t)});return this._init()}async _init(){AccountsTreeStore.initPersistent(this);ChainDataStore.initPersistent(this);TransactionStore.initPersistent(this);await this.connect();return this}static _getDbName(e,t){return e+(t?"light":"full")+"-consensus"}static async _onUpgradeNeeded(e,t,s,r){if(0!==t){Log.i(ConsensusDB,`Upgrade needed: version ${t} -> ${s}`);if(t<7)if(e){const e=r.getObjectStore("Accounts").transaction(!1);await e.truncate();const t=r.getObjectStore("ChainData").transaction(!1);await t.truncate();const s=r.getObjectStore("Block").transaction(!1);await s.truncate();await JDB.JungleDB.commitCombined(e,t,s)}else{Log.i(ConsensusDB,"Upgrading database, this may take a while...");await UpgradeHelper.recomputeTotals(r)}if(t<8&&!e){Log.i(ConsensusDB,"Upgrading transaction store, this may take a while...");await UpgradeHelper.restoreTransactions(r)}}}}ConsensusDB._instance=null;ConsensusDB.VERSION=8;ConsensusDB.INITIAL_DB_SIZE=524288e3;ConsensusDB.MIN_RESIZE=1<<30;Class.register(ConsensusDB);class UpgradeHelper{static async recomputeTotals(e){const t=ChainDataStore.getPersistent(e).synchronousTransaction(!1);try{await this._recomputeTotals(t,GenesisConfig.GENESIS_BLOCK,new BigNumber(0),new BigNumber(0));return t.commit()}catch(s){await t.abort();throw s}}static async _recomputeTotals(e,t,s,r){const n=t.hash(),i=await e.getChainData(n);if(!i)return Promise.resolve();const o=s.plus(t.difficulty),a=r.plus(BlockUtils.realDifficulty(await t.pow()));i._totalDifficulty=o;i._totalWork=a;e.putChainDataSync(n,i,!1);const c=(await e.getSuccessorBlocks(t)).map(t=>UpgradeHelper._recomputeTotals(e,t,o,a));return Promise.all(c)}static async restoreTransactions(e){const t=ChainDataStore.getPersistent(e),s=TransactionStore.getPersistent(e);let r=s.transaction(!1);const n=await t.getHead(),i=(await t.getBlock(n)).height;try{let e=GenesisConfig.GENESIS_HASH,n=0;for(;e;){const o=await t.getChainData(e,!0);e=o.mainChainSuccessor;n=o.head.height;await r.put(o.head);if(n%1e3==0){await r.commit();r=s.transaction(!1);Log.i(UpgradeHelper,`Upgrade at ${Math.round(n/i*100)}% (block ${n}/${i})`)}}if(n%1e3!=0){await r.commit();Log.i(UpgradeHelper,`Upgrade at ${Math.round(n/i*100)}% (block ${n}/${i})`)}Log.i(UpgradeHelper,"Upgrade finished")}catch(o){await r.abort();throw o}}}class Consensus{static async full(e=NetworkConfig.getDefault()){e.services=new Services(Services.PROVIDES_FULL,Services.ACCEPTS_FULL);await e.initPersistent();const t=new Time,s=await ConsensusDB.getFull(`${GenesisConfig.NETWORK_NAME}-`),r=await Accounts.getPersistent(s),n=await TransactionStore.getPersistent(s),i=await FullChain.getPersistent(s,r,t,n),o=new Mempool(i,r),a=new Network(i,e,t);return new FullConsensus(i,o,a)}static async light(e=NetworkConfig.getDefault()){e.services=new Services(Services.PROVIDES_LIGHT,Services.ACCEPTS_LIGHT);await e.initPersistent();const t=new Time,s=await ConsensusDB.getLight(`${GenesisConfig.NETWORK_NAME}-`),r=await Accounts.getPersistent(s),n=await LightChain.getPersistent(s,r,t),i=new Mempool(n,r),o=new Network(n,e,t);return new LightConsensus(n,i,o)}static async nano(e=NetworkConfig.getDefault()){e.services=new Services(Services.PROVIDES_NANO,Services.ACCEPTS_NANO);await e.initPersistent();const t=new Time,s=await new NanoChain(t),r=new NanoMempool(s),n=new Network(s,e,t);return new NanoConsensus(s,r,n)}static async pico(e=NetworkConfig.getDefault()){e.services=new Services(Services.PROVIDES_PICO,Services.ACCEPTS_PICO);await e.initPersistent();const t=new Time,s=await new PicoChain(t),r=new NanoMempool(s),n=new Network(s,e,t);return new PicoConsensus(s,r,n)}static async volatileFull(e=NetworkConfig.getDefault()){e.services=new Services(Services.PROVIDES_FULL,Services.ACCEPTS_FULL);await e.initVolatile();const t=new Time,s=await Accounts.createVolatile(),r=await TransactionStore.createVolatile(),n=await FullChain.createVolatile(s,t,r),i=new Mempool(n,s),o=new Network(n,e,t);return new FullConsensus(n,i,o)}static async volatileLight(e=NetworkConfig.getDefault()){e.services=new Services(Services.PROVIDES_LIGHT,Services.ACCEPTS_LIGHT);await e.initVolatile();const t=new Time,s=await Accounts.createVolatile(),r=await LightChain.createVolatile(s,t),n=new Mempool(r,s),i=new Network(r,e,t);return new LightConsensus(r,n,i)}static async volatileNano(e=NetworkConfig.getDefault()){e.services=new Services(Services.PROVIDES_NANO,Services.ACCEPTS_NANO);await e.initVolatile();const t=new Time,s=await new NanoChain(t),r=new NanoMempool(s),n=new Network(s,e,t);return new NanoConsensus(s,r,n)}static async volatilePico(e=NetworkConfig.getDefault()){e.services=new Services(Services.PROVIDES_PICO,Services.ACCEPTS_PICO);await e.initVolatile();const t=new Time,s=await new PicoChain(t),r=new NanoMempool(s),n=new Network(s,e,t);return new PicoConsensus(s,r,n)}}Class.register(Consensus);class Protocol{}Protocol.DUMB=0;Protocol.WSS=1;Protocol.RTC=2;Protocol.WS=4;Class.register(Protocol);class Message{constructor(e){if(!NumberUtils.isUint64(e))throw new Error("Malformed type");this._type=e}static peekType(e){const t=e.readPos;e.readPos=4;const s=e.readVarUint();e.readPos=t;return s}static peekLength(e){const t=e.readPos;e.readPos=4;e.readVarUint();const s=e.readUint32();e.readPos=t;return s}static unserialize(e){Assert.that(0===e.readPos,"Message.unserialize() requires buf.readPos == 0");const t=e.readUint32(),s=e.readVarUint();e.readUint32();const r=e.readUint32();if(t!==Message.MAGIC)throw new Error("Malformed magic");Message._writeChecksum(s,e,0);if(r!==CRC32.compute(e))throw new Error("Invalid checksum");return new Message(s)}serialize(e){e=e||new SerialBuffer(this.serializedSize);Assert.that(0===e.writePos,"Message.serialize() requires buf.writePos == 0");e.writeUint32(Message.MAGIC);e.writeVarUint(this._type);e.writeUint32(this.serializedSize);e.writeUint32(0);return e}get serializedSize(){return 4+SerialBuffer.varUintSize(this._type)+4+4}_setChecksum(e){const t=CRC32.compute(e);Message._writeChecksum(this._type,e,t)}static _writeChecksum(e,t,s){const r=t.writePos;t.writePos=4+SerialBuffer.varUintSize(e)+4;t.writeUint32(s);t.writePos=r}get type(){return this._type}toString(){return`Message{type=${this.type}, size=${this.serializedSize}}`}}Message.MAGIC=1107566658;Message.Type={VERSION:0,INV:1,GET_DATA:2,GET_HEADER:3,NOT_FOUND:4,GET_BLOCKS:5,BLOCK:6,HEADER:7,TX:8,MEMPOOL:9,REJECT:10,SUBSCRIBE:11,ADDR:20,GET_ADDR:21,PING:22,PONG:23,SIGNAL:30,GET_CHAIN_PROOF:40,CHAIN_PROOF:41,GET_ACCOUNTS_PROOF:42,ACCOUNTS_PROOF:43,GET_ACCOUNTS_TREE_CHUNK:44,ACCOUNTS_TREE_CHUNK:45,GET_TRANSACTIONS_PROOF:47,GET_TRANSACTIONS_PROOF_BY_ADDRESSES:47,TRANSACTIONS_PROOF:48,GET_TRANSACTION_RECEIPTS:49,GET_TRANSACTION_RECEIPTS_BY_ADDRESS:49,TRANSACTION_RECEIPTS:50,GET_BLOCK_PROOF:51,BLOCK_PROOF:52,GET_TRANSACTIONS_PROOF_BY_HASHES:53,GET_TRANSACTION_RECEIPTS_BY_HASHES:54,GET_BLOCK_PROOF_AT:55,GET_HEAD:60,HEAD:61,VERACK:90};Class.register(Message);class AddrMessage extends Message{constructor(e){super(Message.Type.ADDR);if(!e||!NumberUtils.isUint16(e.length)||e.length>AddrMessage.ADDRESSES_MAX_COUNT||e.some(e=>!(e instanceof PeerAddress)))throw new Error("Malformed addresses");this._addresses=e}static unserialize(e){Message.unserialize(e);const t=e.readUint16();if(t>AddrMessage.ADDRESSES_MAX_COUNT)throw new Error("Malformed count");const s=new Array(t);for(let r=0;r<t;r++)s[r]=PeerAddress.unserialize(e);return new AddrMessage(s)}serialize(e){e=e||new SerialBuffer(this.serializedSize);super.serialize(e);e.writeUint16(this._addresses.length);for(const t of this._addresses)t.serialize(e);super._setChecksum(e);return e}get serializedSize(){let e=super.serializedSize+2;for(const t of this._addresses)e+=t.serializedSize;return e}get addresses(){return this._addresses}toString(){return`AddrMessage{size=${this._addresses.length}}`}}AddrMessage.ADDRESSES_MAX_COUNT=1e3;Class.register(AddrMessage);class BlockMessage extends Message{constructor(e){super(Message.Type.BLOCK);this._block=e}static unserialize(e){Message.unserialize(e);const t=Block.unserialize(e);return new BlockMessage(t)}serialize(e){e=e||new SerialBuffer(this.serializedSize);super.serialize(e);this._block.serialize(e);super._setChecksum(e);return e}get serializedSize(){return super.serializedSize+this._block.serializedSize}get block(){return this._block}toString(){return`BlockMessage{height=${this._block.height}, hash=${this._block.hash()}}`}}Class.register(BlockMessage);class RawBlockMessage extends Message{constructor(e){super(Message.Type.BLOCK);this._block=e}serialize(e){e=e||new SerialBuffer(this.serializedSize);super.serialize(e);e.write(this._block);super._setChecksum(e);return e}get serializedSize(){return super.serializedSize+this._block.length}get block(){return Block.unserialize(new SerialBuffer(this._block))}}Class.register(RawBlockMessage);class GetAddrMessage extends Message{constructor(e,t,s){super(Message.Type.GET_ADDR);if(!NumberUtils.isUint8(e))throw new Error("Malformed protocolMask");if(!NumberUtils.isUint32(t))throw new Error("Malformed serviceMask");if(!NumberUtils.isUint16(s))throw new Error("Malformed maxResults");this._protocolMask=e;this._serviceMask=t;this._maxResults=s}static unserialize(e){Message.unserialize(e);const t=e.readUint8(),s=e.readUint32();let r=NetworkAgent.NUM_ADDR_PER_REQUEST;e.readPos!==e.byteLength&&(r=e.readUint16());return new GetAddrMessage(t,s,r)}serialize(e){e=e||new SerialBuffer(this.serializedSize);super.serialize(e);e.writeUint8(this._protocolMask);e.writeUint32(this._serviceMask);e.writeUint16(this._maxResults);super._setChecksum(e);return e}get serializedSize(){return super.serializedSize+1+4+2}get protocolMask(){return this._protocolMask}get serviceMask(){return this._serviceMask}get maxResults(){return this._maxResults}toString(){return`GetAddrMessage{protocol=${this._protocolMask}, services=${this._serviceMask}, maxResults=${this._maxResults}}`}}Class.register(GetAddrMessage);class GetBlocksMessage extends Message{constructor(e,t=BaseInventoryMessage.VECTORS_MAX_COUNT,s=GetBlocksMessage.Direction.FORWARD){super(Message.Type.GET_BLOCKS);if(!e||!NumberUtils.isUint16(e.length)||e.length>GetBlocksMessage.LOCATORS_MAX_COUNT||e.some(e=>!Hash.isHash(e)))throw new Error("Malformed locators");if(!NumberUtils.isUint16(t))throw new Error("Malformed maxInvSize");if(!NumberUtils.isUint8(s))throw new Error("Malformed direction");this._locators=e;this._maxInvSize=t;this._direction=s}static unserialize(e){Message.unserialize(e);const t=e.readUint16();if(t>GetBlocksMessage.LOCATORS_MAX_COUNT)throw new Error("Malformed count");const s=new Array(t);for(let i=0;i<t;i++)s[i]=Hash.unserialize(e);const r=e.readUint16(),n=e.readUint8();return new GetBlocksMessage(s,r,n)}serialize(e){e=e||new SerialBuffer(this.serializedSize);super.serialize(e);e.writeUint16(this._locators.length);for(const t of this._locators)t.serialize(e);e.writeUint16(this._maxInvSize);e.writeUint8(this._direction);super._setChecksum(e);return e}get serializedSize(){let e=super.serializedSize+2+1+2;for(const t of this._locators)e+=t.serializedSize;return e}get locators(){return this._locators}get direction(){return this._direction}get maxInvSize(){return this._maxInvSize}toString(){return`GetBlocksMessage{direction=${this._direction===GetBlocksMessage.Direction.FORWARD?"forward":"backward"}, maxInvSize=${this._maxInvSize}}`}}GetBlocksMessage.Direction={FORWARD:1,BACKWARD:2};GetBlocksMessage.LOCATORS_MAX_COUNT=128;Class.register(GetBlocksMessage);class HeaderMessage extends Message{constructor(e){super(Message.Type.HEADER);this._header=e}static unserialize(e){Message.unserialize(e);const t=BlockHeader.unserialize(e);return new HeaderMessage(t)}serialize(e){e=e||new SerialBuffer(this.serializedSize);super.serialize(e);this._header.serialize(e);super._setChecksum(e);return e}get serializedSize(){return super.serializedSize+this._header.serializedSize}get header(){return this._header}toString(){return`HeaderMessage{height=${this._header.height}, hash=${this._header.hash()}}`}}Class.register(HeaderMessage);class InvVector{static fromBlock(e){const t=e.hash();return new InvVector(InvVector.Type.BLOCK,t)}static fromHeader(e){const t=e.hash();return new InvVector(InvVector.Type.BLOCK,t)}static fromTransaction(e){const t=e.hash();return new InvVector(InvVector.Type.TRANSACTION,t)}constructor(e,t){if(!Hash.isHash(t))throw new Error("Malformed hash");this._type=e;this._hash=t}static unserialize(e){const t=InvVector.Type.unserialize(e),s=Hash.unserialize(e);return new InvVector(t,s)}serialize(e){(e=e||new SerialBuffer(this.serializedSize)).writeUint32(this._type);this._hash.serialize(e);return e}equals(e){return e instanceof InvVector&&this._type===e.type&&this._hash.equals(e.hash)}hashCode(){return`${this._type}|${this._hash.toBase64()}`}toString(){return`InvVector{type=${this._type}, hash=${this._hash}}`}get serializedSize(){return 4+this._hash.serializedSize}get type(){return this._type}get hash(){return this._hash}}InvVector.Type={ERROR:0,TRANSACTION:1,BLOCK:2,unserialize:function(e){return e.readUint32()}};Class.register(InvVector);class BaseInventoryMessage extends Message{constructor(e,t){super(e);if(!Array.isArray(t)||!NumberUtils.isUint16(t.length)||t.length>BaseInventoryMessage.VECTORS_MAX_COUNT||t.some(e=>!(e instanceof InvVector)))throw new Error("Malformed vectors");this._vectors=t}serialize(e){e=e||new SerialBuffer(this.serializedSize);super.serialize(e);e.writeUint16(this._vectors.length);for(const t of this._vectors)t.serialize(e);super._setChecksum(e);return e}get serializedSize(){let e=super.serializedSize+2;for(const t of this._vectors)e+=t.serializedSize;return e}get vectors(){return this._vectors}toString(e="InventoryMessage"){return`${e}{transactions=${this._vectors.filter(e=>e.type===InvVector.Type.TRANSACTION).length}, blocks=${this._vectors.filter(e=>e.type===InvVector.Type.BLOCK).length}}`}}BaseInventoryMessage.VECTORS_MAX_COUNT=1e3;Class.register(BaseInventoryMessage);class InvMessage extends BaseInventoryMessage{constructor(e){super(Message.Type.INV,e)}static unserialize(e){Message.unserialize(e);const t=e.readUint16();if(t>BaseInventoryMessage.VECTORS_MAX_COUNT)throw new Error("Malformed count");const s=new Array(t);for(let r=0;r<t;r++)s[r]=InvVector.unserialize(e);return new InvMessage(s)}toString(){return super.toString("InvMessage")}}Class.register(InvMessage);class GetDataMessage extends BaseInventoryMessage{constructor(e){super(Message.Type.GET_DATA,e)}static unserialize(e){Message.unserialize(e);const t=e.readUint16();if(t>BaseInventoryMessage.VECTORS_MAX_COUNT)throw new Error("Malformed count");const s=new Array(t);for(let r=0;r<t;r++)s[r]=InvVector.unserialize(e);return new GetDataMessage(s)}toString(){return super.toString("GetDataMessage")}}Class.register(GetDataMessage);class GetHeaderMessage extends BaseInventoryMessage{constructor(e){super(Message.Type.GET_HEADER,e)}static unserialize(e){Message.unserialize(e);const t=e.readUint16();if(t>BaseInventoryMessage.VECTORS_MAX_COUNT)throw new Error("Malformed count");const s=new Array(t);for(let r=0;r<t;r++)s[r]=InvVector.unserialize(e);return new GetHeaderMessage(s)}toString(){return super.toString("GetHeaderMessage")}}Class.register(GetHeaderMessage);class NotFoundMessage extends BaseInventoryMessage{constructor(e){super(Message.Type.NOT_FOUND,e)}static unserialize(e){Message.unserialize(e);const t=e.readUint16();if(t>BaseInventoryMessage.VECTORS_MAX_COUNT)throw new Error("Malformed count");const s=new Array(t);for(let r=0;r<t;r++)s[r]=InvVector.unserialize(e);return new NotFoundMessage(s)}toString(){return super.toString("NotFoundMessage")}}Class.register(NotFoundMessage);class MempoolMessage extends Message{constructor(){super(Message.Type.MEMPOOL)}static unserialize(e){Message.unserialize(e);return new MempoolMessage}serialize(e){e=e||new SerialBuffer(this.serializedSize);super.serialize(e);super._setChecksum(e);return e}get serializedSize(){return super.serializedSize}toString(){return"MempoolMessage{}"}}Class.register(MempoolMessage);class PingMessage extends Message{constructor(e){super(Message.Type.PING);if(!NumberUtils.isUint32(e))throw new Error("Malformed nonce");this._nonce=e}static unserialize(e){Message.unserialize(e);const t=e.readUint32();return new PingMessage(t)}serialize(e){e=e||new SerialBuffer(this.serializedSize);super.serialize(e);e.writeUint32(this._nonce);super._setChecksum(e);return e}get serializedSize(){return super.serializedSize+4}get nonce(){return this._nonce}toString(){return`PingMessage{nonce=${this._nonce}}`}}Class.register(PingMessage);class PongMessage extends Message{constructor(e){super(Message.Type.PONG);if(!NumberUtils.isUint32(e))throw new Error("Malformed nonce");this._nonce=e}static unserialize(e){Message.unserialize(e);const t=e.readUint32();return new PongMessage(t)}serialize(e){e=e||new SerialBuffer(this.serializedSize);super.serialize(e);e.writeUint32(this._nonce);super._setChecksum(e);return e}get serializedSize(){return super.serializedSize+4}get nonce(){return this._nonce}toString(){return`PongMessage{nonce=${this._nonce}}`}}Class.register(PongMessage);class RejectMessage extends Message{constructor(e,t,s,r=new Uint8Array(0)){super(Message.Type.REJECT);if(!NumberUtils.isUint64(e))throw new Error("Malformed type");if(!NumberUtils.isUint8(t))throw new Error("Malformed code");if(StringUtils.isMultibyte(s)||s.length>255)throw new Error("Malformed reason");if(!(r instanceof Uint8Array&&NumberUtils.isUint16(r.byteLength)))throw new Error("Malformed extraData");this._messageType=e;this._code=t;this._reason=s;this._extraData=r}static unserialize(e){Message.unserialize(e);const t=e.readVarUint(),s=e.readUint8(),r=e.readVarLengthString(),n=e.readUint16(),i=e.read(n);return new RejectMessage(t,s,r,i)}serialize(e){e=e||new SerialBuffer(this.serializedSize);super.serialize(e);e.writeVarUint(this._messageType);e.writeUint8(this._code);e.writeVarLengthString(this._reason);e.writeUint16(this._extraData.byteLength);e.write(this._extraData);super._setChecksum(e);return e}get serializedSize(){return super.serializedSize+SerialBuffer.varUintSize(this._messageType)+1+SerialBuffer.varLengthStringSize(this._reason)+2+this._extraData.byteLength}get messageType(){return this._messageType}get code(){return this._code}get reason(){return this._reason}get extraData(){return this._extraData}toString(){return`RejectMessage{type=${this._messageType}, code=${this._code}, reason=${this._reason}}`}}RejectMessage.Code={REJECT_MALFORMED:1,REJECT_INVALID:16,REJECT_OBSOLETE:17,REJECT_DOUBLE:18,REJECT_DUST:65,REJECT_INSUFFICIENT_FEE:66};Class.register(RejectMessage);class SignalMessage extends Message{constructor(e,t,s,r,n=0,i=new Uint8Array(0),o,a){super(Message.Type.SIGNAL);if(!(e instanceof PeerId))throw new Error("Malformed senderId");if(!(t instanceof PeerId))throw new Error("Malformed recipientId");if(!NumberUtils.isUint32(s))throw new Error("Malformed nonce");if(!NumberUtils.isUint8(r))throw new Error("Malformed ttl");if(!NumberUtils.isUint8(n))throw new Error("Malformed flags");if(!(i instanceof Uint8Array&&NumberUtils.isUint16(i.byteLength)))throw new Error("Malformed payload");const c=i.byteLength>0;if(c&&!(a instanceof Signature))throw new Error("Malformed signature");if(c&&!(o instanceof PublicKey))throw new Error("Malformed public key");this._senderId=e;this._recipientId=t;this._nonce=s;this._ttl=r;this._flags=n;this._payload=i;this._senderPubKey=c?o:undefined;this._signature=c?a:undefined}static unserialize(e){Message.unserialize(e);const t=PeerId.unserialize(e),s=PeerId.unserialize(e),r=e.readUint32(),n=e.readUint8(),i=e.readUint8(),o=e.readUint16(),a=e.read(o),c=o>0?PublicKey.unserialize(e):undefined,h=o>0?Signature.unserialize(e):undefined;return new SignalMessage(t,s,r,n,i,a,c,h)}serialize(e){e=e||new SerialBuffer(this.serializedSize);super.serialize(e);this._senderId.serialize(e);this._recipientId.serialize(e);e.writeUint32(this._nonce);e.writeUint8(this._ttl);e.writeUint8(this._flags);e.writeUint16(this._payload.byteLength);e.write(this._payload);if(this._payload.byteLength>0){this._senderPubKey.serialize(e);this._signature.serialize(e)}super._setChecksum(e);return e}get serializedSize(){return super.serializedSize+this._senderId.serializedSize+this._recipientId.serializedSize+4+1+1+2+this._payload.byteLength+(this._payload.byteLength>0?this._senderPubKey.serializedSize:0)+(this._payload.byteLength>0?this._signature.serializedSize:0)}verifySignature(){return!!this._signature&&(this._signature.verify(this._senderPubKey,this._payload)&&this._senderId.equals(this._senderPubKey.toPeerId()))}get senderId(){return this._senderId}get recipientId(){return this._recipientId}get nonce(){return this._nonce}get ttl(){return this._ttl}get flags(){return this._flags}get payload(){return this._payload}get signature(){return this._signature}get senderPubKey(){return this._senderPubKey}hasPayload(){return this._payload.byteLength>0}isUnroutable(){return 0!=(this._flags&SignalMessage.Flag.UNROUTABLE)}isTtlExceeded(){return 0!=(this._flags&SignalMessage.Flag.TTL_EXCEEDED)}toString(){return`SignalMessage{sender=${this._senderId}, recipient=${this._recipientId}, nonce=${this._nonce}, ttl=${this._ttl}, flags=${this._flags}}`}}SignalMessage.Flag={UNROUTABLE:1,TTL_EXCEEDED:2};Class.register(SignalMessage);class SubscribeMessage extends Message{constructor(e){super(Message.Type.SUBSCRIBE);this._subscription=e}static unserialize(e){Message.unserialize(e);const t=Subscription.unserialize(e);return new SubscribeMessage(t)}serialize(e){e=e||new SerialBuffer(this.serializedSize);super.serialize(e);this._subscription.serialize(e);super._setChecksum(e);return e}get serializedSize(){return super.serializedSize+this._subscription.serializedSize}get subscription(){return this._subscription}toString(){return`SubscribeMessage{${this._subscription}}`}}Class.register(SubscribeMessage);class TxMessage extends Message{constructor(e,t){super(Message.Type.TX);this._transaction=e;this._accountsProof=t}static unserialize(e){Message.unserialize(e);const t=Transaction.unserialize(e);if(1===e.readUint8()){const s=AccountsProof.unserialize(e);return new TxMessage(t,s)}return new TxMessage(t)}serialize(e){e=e||new SerialBuffer(this.serializedSize);super.serialize(e);this._transaction.serialize(e);e.writeUint8(this._accountsProof?1:0);this._accountsProof&&this._accountsProof.serialize(e);super._setChecksum(e);return e}get serializedSize(){let e=super.serializedSize+this._transaction.serializedSize+1;this._accountsProof&&(e+=this._accountsProof.serializedSize);return e}get transaction(){return this._transaction}get hasAccountsProof(){return!!this._accountsProof}get accountsProof(){return this._accountsProof}toString(){return`TxMessage{hash=${this._transaction.hash()}}`}}Class.register(TxMessage);class VersionMessage extends Message{constructor(e,t,s,r,n,i){super(Message.Type.VERSION);if(!NumberUtils.isUint32(e))throw new Error("Malformed version");if(!(t instanceof PeerAddress))throw new Error("Malformed peerAddress");if(!Hash.isHash(s))throw new Error("Malformed genesisHash");if(!Hash.isHash(r))throw new Error("Malformed headHash");if(!(n instanceof Uint8Array)||32!==n.byteLength)throw new Error("Malformed challenge nonce");if(i&&("string"!=typeof i||StringUtils.isMultibyte(i)||!NumberUtils.isUint8(i.length)))throw new Error("Malformed user agent");this._version=e;this._peerAddress=t;this._genesisHash=s;this._headHash=r;this._challengeNonce=n;this._userAgent=i}static unserialize(e){Message.unserialize(e);const t=e.readUint32(),s=PeerAddress.unserialize(e),r=Hash.unserialize(e),n=Hash.unserialize(e),i=e.read(VersionMessage.CHALLENGE_SIZE),o=e.readPos!==e.byteLength?e.readVarLengthString():undefined;return new VersionMessage(t,s,r,n,i,o)}serialize(e){e=e||new SerialBuffer(this.serializedSize);super.serialize(e);e.writeUint32(this._version);this._peerAddress.serialize(e);this._genesisHash.serialize(e);this._headHash.serialize(e);e.write(this._challengeNonce);this._userAgent&&e.writeVarLengthString(this._userAgent);super._setChecksum(e);return e}get serializedSize(){return super.serializedSize+4+this._peerAddress.serializedSize+this._genesisHash.serializedSize+this._headHash.serializedSize+VersionMessage.CHALLENGE_SIZE+(this._userAgent?SerialBuffer.varLengthStringSize(this._userAgent):0)}get version(){return this._version}get peerAddress(){return this._peerAddress}get genesisHash(){return this._genesisHash}get headHash(){return this._headHash}get challengeNonce(){return this._challengeNonce}get userAgent(){return this._userAgent}toString(){return`VersionMessage{version=${this._version}, peer=${this._peerAddress}, genesis=${this._genesisHash}, head=${this._headHash}, userAgent=${this._userAgent}}`}}VersionMessage.CHALLENGE_SIZE=32;Class.register(VersionMessage);class VerAckMessage extends Message{constructor(e,t){super(Message.Type.VERACK);this._publicKey=e;this._signature=t}static unserialize(e){Message.unserialize(e);const t=PublicKey.unserialize(e),s=Signature.unserialize(e);return new VerAckMessage(t,s)}serialize(e){e=e||new SerialBuffer(this.serializedSize);super.serialize(e);this.publicKey.serialize(e);this.signature.serialize(e);super._setChecksum(e);return e}get serializedSize(){return super.serializedSize+this._publicKey.serializedSize+this._signature.serializedSize}get publicKey(){return this._publicKey}get signature(){return this._signature}toString(){return"VerAckMessage{}"}}Class.register(VerAckMessage);class AccountsProofMessage extends Message{constructor(e,t=null){super(Message.Type.ACCOUNTS_PROOF);if(!(e instanceof Hash))throw new Error("Malformed blockHash");if(t&&!(t instanceof AccountsProof))throw new Error("Malformed proof");this._blockHash=e;this._accountsProof=t}static unserialize(e){Message.unserialize(e);const t=Hash.unserialize(e);let s=null;0!==e.readUint8()&&(s=AccountsProof.unserialize(e));return new AccountsProofMessage(t,s)}serialize(e){e=e||new SerialBuffer(this.serializedSize);super.serialize(e);this._blockHash.serialize(e);e.writeUint8(this.hasProof()?1:0);this.hasProof()&&this._accountsProof.serialize(e);super._setChecksum(e);return e}get serializedSize(){return super.serializedSize+1+this._blockHash.serializedSize+(this.hasProof()?this._accountsProof.serializedSize:0)}hasProof(){return!!this._accountsProof}get blockHash(){return this._blockHash}get proof(){return this._accountsProof}}Class.register(AccountsProofMessage);class GetAccountsProofMessage extends Message{constructor(e,t){super(Message.Type.GET_ACCOUNTS_PROOF);if(!(e&&e instanceof Hash))throw new Error("Malformed block hash");if(!t||!NumberUtils.isUint16(t.length)||t.length<1||t.length>GetAccountsProofMessage.ADDRESSES_MAX_COUNT||t.some(e=>!(e instanceof Address)))throw new Error("Malformed addresses");this._blockHash=e;this._addresses=t}static unserialize(e){Message.unserialize(e);const t=Hash.unserialize(e),s=e.readUint16(),r=[];for(let n=0;n<s;n++)r.push(Address.unserialize(e));return new GetAccountsProofMessage(t,r)}serialize(e){e=e||new SerialBuffer(this.serializedSize);super.serialize(e);this._blockHash.serialize(e);e.writeUint16(this._addresses.length);for(const t of this._addresses)t.serialize(e);super._setChecksum(e);return e}get serializedSize(){return super.serializedSize+this._blockHash.serializedSize+2+this._addresses.reduce((e,t)=>e+t.serializedSize,0)}get addresses(){return this._addresses}get blockHash(){return this._blockHash}}GetAccountsProofMessage.ADDRESSES_MAX_COUNT=256;Class.register(GetAccountsProofMessage);class ChainProofMessage extends Message{constructor(e){super(Message.Type.CHAIN_PROOF);if(!(e instanceof ChainProof))throw new Error("Malformed chainProof");this._proof=e}static unserialize(e){Message.unserialize(e);const t=ChainProof.unserialize(e);return new ChainProofMessage(t)}serialize(e){e=e||new SerialBuffer(this.serializedSize);super.serialize(e);this._proof.serialize(e);super._setChecksum(e);return e}get serializedSize(){return super.serializedSize+this._proof.serializedSize}get proof(){return this._proof}}Class.register(ChainProofMessage);class GetChainProofMessage extends Message{constructor(){super(Message.Type.GET_CHAIN_PROOF)}static unserialize(e){Message.unserialize(e);return new GetChainProofMessage}serialize(e){e=e||new SerialBuffer(this.serializedSize);super.serialize(e);super._setChecksum(e);return e}get serializedSize(){return super.serializedSize}}Class.register(GetChainProofMessage);class AccountsTreeChunkMessage extends Message{constructor(e,t=null){super(Message.Type.ACCOUNTS_TREE_CHUNK);if(!(e instanceof Hash))throw new Error("Malformed blockHash");if(t&&!(t instanceof AccountsTreeChunk))throw new Error("Malformed chunk");this._blockHash=e;this._accountsTreeChunk=t}static unserialize(e){Message.unserialize(e);const t=Hash.unserialize(e);let s=null;0!==e.readUint8()&&(s=AccountsTreeChunk.unserialize(e));return new AccountsTreeChunkMessage(t,s)}serialize(e){e=e||new SerialBuffer(this.serializedSize);super.serialize(e);this._blockHash.serialize(e);e.writeUint8(this.hasChunk()?1:0);this.hasChunk()&&this._accountsTreeChunk.serialize(e);super._setChecksum(e);return e}get serializedSize(){return super.serializedSize+1+this._blockHash.serializedSize+(this.hasChunk()?this._accountsTreeChunk.serializedSize:0)}hasChunk(){return!!this._accountsTreeChunk}get blockHash(){return this._blockHash}get chunk(){return this._accountsTreeChunk}}Class.register(AccountsTreeChunkMessage);class GetAccountsTreeChunkMessage extends Message{constructor(e,t){super(Message.Type.GET_ACCOUNTS_TREE_CHUNK);if(!(e&&e instanceof Hash))throw new Error("Malformed block hash");if(StringUtils.isMultibyte(t)||!NumberUtils.isUint8(t.length))throw new Error("Malformed start prefix");this._blockHash=e;this._startPrefix=t}static unserialize(e){Message.unserialize(e);const t=Hash.unserialize(e),s=e.readVarLengthString();return new GetAccountsTreeChunkMessage(t,s)}serialize(e){e=e||new SerialBuffer(this.serializedSize);super.serialize(e);this._blockHash.serialize(e);e.writeVarLengthString(this._startPrefix);super._setChecksum(e);return e}get serializedSize(){return super.serializedSize+this._blockHash.serializedSize+SerialBuffer.varLengthStringSize(this._startPrefix)}get blockHash(){return this._blockHash}get startPrefix(){return this._startPrefix}}Class.register(GetAccountsTreeChunkMessage);class TransactionsProofMessage extends Message{constructor(e,t=null){super(Message.Type.TRANSACTIONS_PROOF);if(!(e instanceof Hash))throw new Error("Malformed blockHash");if(t&&!(t instanceof TransactionsProof))throw new Error("Malformed proof");this._blockHash=e;this._proof=t}static unserialize(e){Message.unserialize(e);const t=Hash.unserialize(e);let s=null;0!==e.readUint8()&&(s=TransactionsProof.unserialize(e));return new TransactionsProofMessage(t,s)}serialize(e){e=e||new SerialBuffer(this.serializedSize);super.serialize(e);this._blockHash.serialize(e);e.writeUint8(this.hasProof()?1:0);this.hasProof()&&this._proof.serialize(e);super._setChecksum(e);return e}get serializedSize(){return super.serializedSize+1+this._blockHash.serializedSize+(this.hasProof()?this._proof.serializedSize:0)}hasProof(){return!!this._proof}get blockHash(){return this._blockHash}get proof(){return this._proof}}Class.register(TransactionsProofMessage);class GetTransactionsProofByAddressesMessage extends Message{constructor(e,t){super(Message.Type.GET_TRANSACTIONS_PROOF_BY_ADDRESSES);if(!(e&&e instanceof Hash))throw new Error("Malformed block hash");if(!Array.isArray(t)||!NumberUtils.isUint16(t.length)||t.length>GetTransactionsProofByAddressesMessage.ADDRESSES_MAX_COUNT||t.some(e=>!(e instanceof Address)))throw new Error("Malformed addresses");this._blockHash=e;this._addresses=t}static unserialize(e){Message.unserialize(e);const t=Hash.unserialize(e),s=e.readUint16();if(s>GetTransactionsProofByAddressesMessage.ADDRESSES_MAX_COUNT)throw new Error("Malformed count");const r=new Array(s);for(let n=0;n<s;n++)r[n]=Address.unserialize(e);return new GetTransactionsProofByAddressesMessage(t,r)}serialize(e){e=e||new SerialBuffer(this.serializedSize);super.serialize(e);this._blockHash.serialize(e);e.writeUint16(this._addresses.length);for(const t of this._addresses)t.serialize(e);super._setChecksum(e);return e}get serializedSize(){return super.serializedSize+this._blockHash.serializedSize+2+this._addresses.reduce((e,t)=>e+t.serializedSize,0)}get addresses(){return this._addresses}get blockHash(){return this._blockHash}}GetTransactionsProofByAddressesMessage.ADDRESSES_MAX_COUNT=255;Class.register(GetTransactionsProofByAddressesMessage);class GetTransactionsProofByHashesMessage extends Message{constructor(e,t){super(Message.Type.GET_TRANSACTIONS_PROOF_BY_HASHES);if(!(e&&e instanceof Hash))throw new Error("Malformed block hash");if(!Array.isArray(t)||0===t.length||!NumberUtils.isUint16(t.length)||t.length>GetTransactionsProofByHashesMessage.HASHES_MAX_COUNT||t.some(e=>!(e instanceof Hash)))throw new Error("Malformed hashes");this._blockHash=e;this._hashes=t}static unserialize(e){Message.unserialize(e);const t=Hash.unserialize(e),s=e.readUint16();if(s>GetTransactionsProofByHashesMessage.HASHES_MAX_COUNT)throw new Error("Malformed count");const r=new Array(s);for(let n=0;n<s;n++)r[n]=Hash.unserialize(e);return new GetTransactionsProofByHashesMessage(t,r)}serialize(e){e=e||new SerialBuffer(this.serializedSize);super.serialize(e);this._blockHash.serialize(e);e.writeUint16(this._hashes.length);for(const t of this._hashes)t.serialize(e);super._setChecksum(e);return e}get serializedSize(){return super.serializedSize+this._blockHash.serializedSize+2+this._hashes.reduce((e,t)=>e+t.serializedSize,0)}get hashes(){return this._hashes}get blockHash(){return this._blockHash}}GetTransactionsProofByHashesMessage.HASHES_MAX_COUNT=255;Class.register(GetTransactionsProofByHashesMessage);class GetTransactionReceiptsByAddressMessage extends Message{constructor(e,t=0){super(Message.Type.GET_TRANSACTION_RECEIPTS_BY_ADDRESS);if(!(e instanceof Address))throw new Error("Malformed address");if(!NumberUtils.isUint32(t))throw new Error("Malformed offset");this._address=e;this._offset=t}static unserialize(e){Message.unserialize(e);const t=Address.unserialize(e),s=e.readUint32();return new GetTransactionReceiptsByAddressMessage(t,s)}serialize(e){e=e||new SerialBuffer(this.serializedSize);super.serialize(e);this._address.serialize(e);e.writeUint32(this._offset);super._setChecksum(e);return e}get serializedSize(){return super.serializedSize+this._address.serializedSize+4}get address(){return this._address}get offset(){return this._offset}}Class.register(GetTransactionReceiptsByAddressMessage);class GetTransactionReceiptsByHashesMessage extends Message{constructor(e){super(Message.Type.GET_TRANSACTION_RECEIPTS_BY_HASHES);if(!Array.isArray(e)||0===e.length||!NumberUtils.isUint16(e.length)||e.length>GetTransactionReceiptsByHashesMessage.HASHES_MAX_COUNT||e.some(e=>!(e instanceof Hash)))throw new Error("Malformed hashes");this._hashes=e}static unserialize(e){Message.unserialize(e);const t=e.readUint16();if(t>GetTransactionReceiptsByHashesMessage.HASHES_MAX_COUNT)throw new Error("Malformed count");const s=new Array(t);for(let r=0;r<t;r++)s[r]=Hash.unserialize(e);return new GetTransactionReceiptsByHashesMessage(s)}serialize(e){e=e||new SerialBuffer(this.serializedSize);super.serialize(e);e.writeUint16(this._hashes.length);for(const t of this._hashes)t.serialize(e);super._setChecksum(e);return e}get serializedSize(){return super.serializedSize+2+this._hashes.reduce((e,t)=>e+t.serializedSize,0)}get hashes(){return this._hashes}}GetTransactionReceiptsByHashesMessage.HASHES_MAX_COUNT=255;Class.register(GetTransactionReceiptsByHashesMessage);class TransactionReceiptsMessage extends Message{constructor(e=null){super(Message.Type.TRANSACTION_RECEIPTS);if(e&&(!Array.isArray(e)||!NumberUtils.isUint16(e.length)||e.length>TransactionReceiptsMessage.RECEIPTS_MAX_COUNT||e.some(e=>!(e instanceof TransactionReceipt))))throw new Error("Malformed receipts");this._receipts=e}static unserialize(e){Message.unserialize(e);let t=null;if(0!==e.readUint8()){const s=e.readUint16();if(s>TransactionReceiptsMessage.RECEIPTS_MAX_COUNT)throw new Error("Malformed count");t=new Array(s);for(let r=0;r<s;r++)t[r]=TransactionReceipt.unserialize(e)}return new TransactionReceiptsMessage(t)}serialize(e){e=e||new SerialBuffer(this.serializedSize);super.serialize(e);e.writeUint8(this.hasReceipts()?1:0);if(this.hasReceipts()){e.writeUint16(this._receipts.length);for(const t of this._receipts)t.serialize(e)}super._setChecksum(e);return e}get serializedSize(){return super.serializedSize+1+(this.hasReceipts()?2+this._receipts.reduce((e,t)=>e+t.serializedSize,0):0)}hasReceipts(){return!!this._receipts}get receipts(){return this._receipts}}Class.register(TransactionReceiptsMessage);TransactionReceiptsMessage.RECEIPTS_MAX_COUNT=500;class GetBlockProofMessage extends Message{constructor(e,t){super(Message.Type.GET_BLOCK_PROOF);if(!(e instanceof Hash))throw new Error("Malformed blockHashToProve");if(!(t instanceof Hash))throw new Error("Malformed knownBlockHash");this._blockHashToProve=e;this._knownBlockHash=t}static unserialize(e){Message.unserialize(e);const t=Hash.unserialize(e),s=Hash.unserialize(e);return new GetBlockProofMessage(t,s)}serialize(e){e=e||new SerialBuffer(this.serializedSize);super.serialize(e);this._blockHashToProve.serialize(e);this._knownBlockHash.serialize(e);super._setChecksum(e);return e}get serializedSize(){return super.serializedSize+this._blockHashToProve.serializedSize+this._knownBlockHash.serializedSize}get blockHashToProve(){return this._blockHashToProve}get knownBlockHash(){return this._knownBlockHash}}Class.register(GetBlockProofMessage);class GetBlockProofAtMessage extends Message{constructor(e,t){super(Message.Type.GET_BLOCK_PROOF_AT);if(!NumberUtils.isUint32(e))throw new Error("Malformed blockHeightToProve");if(!(t instanceof Hash))throw new Error("Malformed knownBlockHash");this._blockHeightToProve=e;this._knownBlockHash=t}static unserialize(e){Message.unserialize(e);const t=e.readUint32(),s=Hash.unserialize(e);return new GetBlockProofAtMessage(t,s)}serialize(e){e=e||new SerialBuffer(this.serializedSize);super.serialize(e);e.writeUint32(this._blockHeightToProve);this._knownBlockHash.serialize(e);super._setChecksum(e);return e}get serializedSize(){return super.serializedSize+4+this._knownBlockHash.serializedSize}get blockHeightToProve(){return this._blockHeightToProve}get knownBlockHash(){return this._knownBlockHash}}Class.register(GetBlockProofAtMessage);class BlockProofMessage extends Message{constructor(e){super(Message.Type.BLOCK_PROOF);if(e&&!(e instanceof BlockChain))throw new Error("Malformed proof");this._proof=e}static unserialize(e){Message.unserialize(e);if(1===e.readUint8()){const t=BlockChain.unserialize(e);return new BlockProofMessage(t)}return new BlockProofMessage}serialize(e){e=e||new SerialBuffer(this.serializedSize);super.serialize(e);if(this._proof){e.writeUint8(1);this._proof.serialize(e)}else e.writeUint8(0);super._setChecksum(e);return e}get serializedSize(){return super.serializedSize+1+(this._proof?this._proof.serializedSize:0)}hasProof(){return!!this._proof}get proof(){return this._proof}}Class.register(BlockProofMessage);class GetHeadMessage extends Message{constructor(){super(Message.Type.GET_HEAD)}static unserialize(e){Message.unserialize(e);return new GetHeadMessage}serialize(e){e=e||new SerialBuffer(this.serializedSize);super.serialize(e);super._setChecksum(e);return e}toString(){return"GetHeadMessage{}"}}Class.register(GetHeadMessage);class HeadMessage extends Message{constructor(e){super(Message.Type.HEAD);this._header=e}static unserialize(e){Message.unserialize(e);const t=BlockHeader.unserialize(e);return new HeadMessage(t)}serialize(e){e=e||new SerialBuffer(this.serializedSize);super.serialize(e);this._header.serialize(e);super._setChecksum(e);return e}get serializedSize(){return super.serializedSize+this._header.serializedSize}get header(){return this._header}toString(){return`HeadMessage{height=${this._header.height}, hash=${this._header.hash()}}`}}Class.register(HeadMessage);class MessageFactory{static peekType(e){return Message.peekType(e)}static parse(e){const t=Message.peekType(e),s=MessageFactory.CLASSES[t];if(!s||!s.unserialize)throw new Error(`Invalid message type: ${t}`);return s.unserialize(e)}}MessageFactory.CLASSES={};MessageFactory.CLASSES[Message.Type.VERSION]=VersionMessage;MessageFactory.CLASSES[Message.Type.INV]=InvMessage;MessageFactory.CLASSES[Message.Type.GET_DATA]=GetDataMessage;MessageFactory.CLASSES[Message.Type.GET_HEADER]=GetHeaderMessage;MessageFactory.CLASSES[Message.Type.NOT_FOUND]=NotFoundMessage;MessageFactory.CLASSES[Message.Type.BLOCK]=BlockMessage;MessageFactory.CLASSES[Message.Type.HEADER]=HeaderMessage;MessageFactory.CLASSES[Message.Type.TX]=TxMessage;MessageFactory.CLASSES[Message.Type.GET_BLOCKS]=GetBlocksMessage;MessageFactory.CLASSES[Message.Type.MEMPOOL]=MempoolMessage;MessageFactory.CLASSES[Message.Type.REJECT]=RejectMessage;MessageFactory.CLASSES[Message.Type.SUBSCRIBE]=SubscribeMessage;MessageFactory.CLASSES[Message.Type.ADDR]=AddrMessage;MessageFactory.CLASSES[Message.Type.GET_ADDR]=GetAddrMessage;MessageFactory.CLASSES[Message.Type.PING]=PingMessage;MessageFactory.CLASSES[Message.Type.PONG]=PongMessage;MessageFactory.CLASSES[Message.Type.SIGNAL]=SignalMessage;MessageFactory.CLASSES[Message.Type.GET_CHAIN_PROOF]=GetChainProofMessage;MessageFactory.CLASSES[Message.Type.CHAIN_PROOF]=ChainProofMessage;MessageFactory.CLASSES[Message.Type.GET_ACCOUNTS_PROOF]=GetAccountsProofMessage;MessageFactory.CLASSES[Message.Type.ACCOUNTS_PROOF]=AccountsProofMessage;MessageFactory.CLASSES[Message.Type.GET_ACCOUNTS_TREE_CHUNK]=GetAccountsTreeChunkMessage;MessageFactory.CLASSES[Message.Type.ACCOUNTS_TREE_CHUNK]=AccountsTreeChunkMessage;MessageFactory.CLASSES[Message.Type.GET_TRANSACTIONS_PROOF_BY_ADDRESSES]=GetTransactionsProofByAddressesMessage;MessageFactory.CLASSES[Message.Type.TRANSACTIONS_PROOF]=TransactionsProofMessage;MessageFactory.CLASSES[Message.Type.GET_TRANSACTION_RECEIPTS_BY_ADDRESS]=GetTransactionReceiptsByAddressMessage;MessageFactory.CLASSES[Message.Type.TRANSACTION_RECEIPTS]=TransactionReceiptsMessage;MessageFactory.CLASSES[Message.Type.GET_BLOCK_PROOF]=GetBlockProofMessage;MessageFactory.CLASSES[Message.Type.BLOCK_PROOF]=BlockProofMessage;MessageFactory.CLASSES[Message.Type.GET_TRANSACTIONS_PROOF_BY_HASHES]=GetTransactionsProofByHashesMessage;MessageFactory.CLASSES[Message.Type.GET_TRANSACTION_RECEIPTS_BY_HASHES]=GetTransactionReceiptsByHashesMessage;MessageFactory.CLASSES[Message.Type.GET_BLOCK_PROOF_AT]=GetBlockProofAtMessage;MessageFactory.CLASSES[Message.Type.GET_HEAD]=GetHeadMessage;MessageFactory.CLASSES[Message.Type.HEAD]=HeadMessage;MessageFactory.CLASSES[Message.Type.VERACK]=VerAckMessage;Class.register(MessageFactory);class WebRtcConnector extends Observable{constructor(e){super();this._networkConfig=e;this._connectors=new HashMap;this._timers=new Timers}connect(e,t){if(e.protocol!==Protocol.RTC)throw new Error("Malformed peerAddress");const s=e.peerId;if(this._connectors.contains(s))return!1;if(this._connectors.length>=WebRtcConnector.CONNECTORS_MAX)return!1;const r=new OutboundPeerConnector(this._networkConfig,e,t);r.on("connection",e=>this._onConnection(e,s));this._connectors.put(s,r);this._timers.setTimeout(`connect_${s}`,()=>{this._connectors.remove(s);this._timers.clearTimeout(`connect_${s}`);r.close();this.fire("error",e,"timeout")},WebRtcConnector.CONNECT_TIMEOUT);return!0}isValidSignal(e){return this._connectors.contains(e.senderId)&&this._connectors.get(e.senderId).nonce===e.nonce}onSignal(e,t){if(t.isUnroutable()||t.isTtlExceeded()){if(this.isValidSignal(t)&&this._connectors.get(t.senderId)instanceof OutboundPeerConnector){const e=this._connectors.get(t.senderId),s=e.peerAddress;this._connectors.remove(t.senderId);this._timers.clearTimeout(`connect_${t.senderId}`);e.close();const r=t.isUnroutable()?"unroutable":"ttl exceeded";this.fire("error",s,r)}return}let s;try{s=JSON.parse(BufferUtils.toAscii(t.payload))}catch(r){Log.e(WebRtcConnector,`Failed to parse signal payload from ${t.senderId}`);return}if(s)if("offer"===s.type){let r=this._connectors.get(t.senderId);if(r){if(t.recipientId.compare(t.senderId)>0){Log.d(WebRtcConnector,`Simultaneous connection, discarding offer from ${t.senderId} (<${t.recipientId})`);return}if(r instanceof InboundPeerConnector){Log.w(WebRtcConnector,`Duplicate offer received from ${t.senderId}`);r.onSignal(s);return}Log.d(WebRtcConnector,`Simultaneous connection, accepting offer from ${t.senderId} (>${t.recipientId})`);this._timers.clearTimeout(`connect_${t.senderId}`);r.close();this.fire("error",r.peerAddress,"simultaneous inbound connection")}if(this._connectors.length>=WebRtcConnector.CONNECTORS_MAX){Log.d(WebRtcConnector,`Rejecting offer from ${t.senderId} - max connectors exceeded`);return}if(this._connectors.length>=WebRtcConnector.INBOUND_CONNECTORS_MAX){let e=0;for(const t of this._connectors.valueIterator())t instanceof InboundPeerConnector&&e++;if(e>=WebRtcConnector.INBOUND_CONNECTORS_MAX){Log.d(WebRtcConnector,`Rejecting offer from ${t.senderId} - max inbound connectors exceeded`);return}}(r=new InboundPeerConnector(this._networkConfig,e,t.senderId,s)).on("connection",e=>this._onConnection(e,t.senderId));this._connectors.put(t.senderId,r);this._timers.setTimeout(`connect_${t.senderId}`,()=>{this._timers.clearTimeout(`connect_${t.senderId}`);this._connectors.remove(t.senderId);r.close()},WebRtcConnector.CONNECT_TIMEOUT)}else this._connectors.contains(t.senderId)&&this._connectors.get(t.senderId).onSignal(s);else Log.d(WebRtcConnector,`Discarding signal from ${t.senderId} - empty payload`)}_onConnection(e,t){this._timers.clearTimeout(`connect_${t}`);e.on("close",()=>this._onClose(t));this.fire("connection",e)}_onClose(e){this._connectors.remove(e);this._timers.clearTimeout(`connect_${e}`)}}WebRtcConnector.CONNECT_TIMEOUT=8e3;WebRtcConnector.CONNECTORS_MAX=6;WebRtcConnector.INBOUND_CONNECTORS_MAX=3;Class.register(WebRtcConnector);class PeerConnector extends Observable{constructor(e,t,s,r){super();this._networkConfig=e;this._signalChannel=t;this._peerId=s;this._peerAddress=r;this._nonce=NumberUtils.randomUint32();this._rtcConnection=WebRtcFactory.newPeerConnection(this._networkConfig.rtcConfig);this._rtcConnection.onicecandidate=(e=>this._onIceCandidate(e));this._rtcConnection.onconnectionstatechange=(e=>this._onConnectionStateChange(e));this._rtcConnection.onicegatheringstatechange=(e=>this._onIceGatheringStateChange(e));this._lastIceCandidate=null;this._iceCandidateQueue=[];this._localIceCandidates=[];this._timers=new Timers}onSignal(e){if(this._rtcConnection)if(e.sdp)this._rtcConnection.setRemoteDescription(WebRtcFactory.newSessionDescription(e)).then(()=>{"offer"===e.type&&this._rtcConnection.createAnswer().then(e=>this._onDescription(e))["catch"](Log.e.tag(PeerConnector));this._handleCandidateQueue()["catch"](Log.w.tag(PeerConnector))})["catch"](Log.e.tag(PeerConnector));else if(e.candidate){if(e.otherCandidates)for(const t of e.otherCandidates)this._addIceCandidate(t)["catch"](Log.w.tag(PeerConnector));this._addIceCandidate(e)["catch"](Log.w.tag(PeerConnector))}}_onConnectionStateChange(e){if(this._rtcConnection)switch(this._rtcConnection.connectionState){case"failed":case"disconnected":case"closed":this.close()}}close(){if(this._rtcConnection){this._rtcConnection.onicecandidate=null;this._rtcConnection.onconnectionstatechange=null;this._rtcConnection.onicegatheringstatechange=null;this._rtcConnection.close();this._rtcConnection=null;this._signalChannel=null;this._timers.clearAll();this._offAll()}}_addIceCandidate(e){if(!this._rtcConnection)return Promise.resolve();this._lastIceCandidate=WebRtcFactory.newIceCandidate(e);if(!this._rtcConnection.remoteDescription||!this._rtcConnection.remoteDescription.type){this._iceCandidateQueue.push(e);return Promise.resolve()}return this._rtcConnection.addIceCandidate(this._lastIceCandidate)["catch"](Log.e.tag(PeerConnector))}async _handleCandidateQueue(){if(this._rtcConnection){for(const e of this._iceCandidateQueue)await this._addIceCandidate(e);this._iceCandidateQueue=[]}}_signal(e){if(!this._rtcConnection)return;const t=BufferUtils.fromAscii(JSON.stringify(e)),s=this._networkConfig.keyPair,r=this._networkConfig.peerId;this._signalChannel.signal(r,this._peerId,this._nonce,Network.SIGNAL_TTL_INITIAL,0,t,s.publicKey,Signature.create(s.privateKey,s.publicKey,t))}_onIceCandidate(e){if(this._rtcConnection&&null!==e.candidate){this._localIceCandidates.push(e.candidate);this._timers.timeoutExists("ice-gathering")||this._timers.setTimeout("ice-gathering",this._sendIceCandidates.bind(this),PeerConnector.ICE_GATHERING_TIMEOUT)}}_onIceGatheringStateChange(e){this._rtcConnection&&"complete"===this._rtcConnection.iceGatheringState&&this._sendIceCandidates()}_sendIceCandidates(){this._timers.clearTimeout("ice-gathering");if(this._localIceCandidates.length>0){let e=this._localIceCandidates.pop();(e=e.toJSON?e.toJSON():JSON.parse(JSON.stringify(e))).otherCandidates=this._localIceCandidates;this._signal(e);this._localIceCandidates=[]}}_onDescription(e){this._rtcConnection&&this._rtcConnection.setLocalDescription(e).then(()=>this._signal(this._rtcConnection.localDescription))["catch"](Log.e.tag(PeerConnector))}_onDataChannel(e){if(!this._rtcConnection)return;const t=new WebRtcDataChannel(e.channel||e.target);t.on("close",()=>{this._rtcConnection&&this.close()});let s=null;if(this._lastIceCandidate)try{s=WebRtcUtils.candidateToNetAddress(this._lastIceCandidate)}catch(n){Log.w(PeerConnector,`Failed to parse IP from ICE candidate: ${this._lastIceCandidate}`)}else Log.d(PeerConnector,"No ICE candidate seen for RTC connection");const r=new NetworkConnection(t,Protocol.RTC,s,this._peerAddress);this.fire("connection",r)}get nonce(){return this._nonce}get peerAddress(){return this._peerAddress}}PeerConnector.ICE_GATHERING_TIMEOUT=1e3;PeerConnector.CONNECTION_OPEN_DELAY=200;Class.register(PeerConnector);class OutboundPeerConnector extends PeerConnector{constructor(e,t,s){super(e,s,t.peerId,t);this._peerAddress=t;this._channel=this._rtcConnection.createDataChannel("data-channel");this._channel.binaryType="arraybuffer";this._channel.onopen=(e=>this._onDataChannel(e));this._rtcConnection.createOffer().then(e=>this._onDescription(e))["catch"](Log.e.tag(OutboundPeerConnector))}close(){super.close();if(this._channel){this._channel.onopen=null;this._channel=null}}}Class.register(OutboundPeerConnector);class InboundPeerConnector extends PeerConnector{constructor(e,t,s,r){super(e,t,s,null);this._rtcConnection.ondatachannel=(e=>{e.channel.onopen=(e=>this._onDataChannel(e))});this.onSignal(r)}}Class.register(InboundPeerConnector);class WebRtcDataChannel extends DataChannel{constructor(e){super();Assert.that(e.ordered,"WebRtc data channel not ordered");this._channel=e;this._channel.onmessage=(e=>this._onMessage(e.data||e));this._channel.onclose=(()=>this.close());this._channel.onerror=(e=>this.fire("error",e,this))}_onMessage(e){if(e instanceof Blob){const t=new FileReader;t.onloadend=(()=>super._onMessage(t.result));t.readAsArrayBuffer(e)}else super._onMessage(e)}sendChunk(e){if(!this._channel)throw new Error("Channel is dead");this._channel.send(e)}_close(){this._channel.onmessage=null;this._channel.onclose=null;this._channel.onerror=null;this._channel.close();this._channel=null}get readyState(){return DataChannel.ReadyState.fromString(this._channel.readyState)}}Class.register(WebRtcDataChannel);class WebRtcUtils{static candidateToNetAddress(e){const t=e.candidate.split(" ");return t.length<6?null:NetAddress.fromIP(t[4],!0)}}Class.register(WebRtcUtils);class WebSocketConnector extends Observable{constructor(e,t,s){super();this._protocol=e;this._protocolPrefix=t;this._networkConfig=s;if(s.peerAddress.protocol===this._protocol){this._wss=WebSocketFactory.newWebSocketServer(s);this._wss.on("connection",(e,t)=>this._onConnection(e,t));Log.d(WebSocketConnector,`${this._protocolPrefix.toUpperCase()}-Connector listening on port ${s.peerAddress.port}`)}this._sockets=new HashMap;this._timers=new Timers}connect(e){if(e.protocol!==this._protocol)throw new Error("Malformed peerAddress");const t=`connect_${e}`;if(this._timers.timeoutExists(t)){Log.w(WebSocketConnector,`Already connecting to ${e}`);return!1}const s=WebSocketFactory.newWebSocket(`${this._protocolPrefix}://${e.host}:${e.port}`,{handshakeTimeout:WebSocketConnector.CONNECT_TIMEOUT},this._networkConfig);s.binaryType="arraybuffer";s.onopen=(()=>{this._timers.clearTimeout(t);this._sockets.remove(e);s.onerror=(()=>{});const r=s._socket&&s._socket.remoteAddress?NetAddress.fromIP(s._socket.remoteAddress,!0):null,n=new NetworkConnection(new WebSocketDataChannel(s),this._protocol,r,e);this.fire("connection",n)});s.onerror=(s=>{this._timers.clearTimeout(t);this._sockets.remove(e);this.fire("error",e,s)});this._sockets.put(e,s);this._timers.setTimeout(t,()=>{this._timers.clearTimeout(t);this._sockets.remove(e);s.onerror=(()=>{});s.onopen=(()=>{Log.d(WebSocketConnector,()=>`Connection to ${e} succeeded after timeout - closing it`);s.close()});this.fire("error",e,"timeout")},WebSocketConnector.CONNECT_TIMEOUT);return!0}abort(e){const t=this._sockets.get(e);if(t){this._timers.clearTimeout(`connect_${e}`);this._sockets.remove(e);t.onerror=(()=>{});t.onopen=(()=>{Log.d(WebSocketConnector,()=>`Connection to ${e} succeeded after aborting - closing it`);t.close()});t.close();this.fire("error",e,"aborted")}}_onConnection(e,t){let s=t.connection.remoteAddress;if(s){if(this._networkConfig.reverseProxy.enabled){const r=this._networkConfig.reverseProxy.addresses;if(!r.includes(s)){Log.e(WebSocketConnector,`Received connection from ${s} when all connections were expected from the reverse proxy at ${r}: closing the connection`);e.close();return}{const r=this._networkConfig.reverseProxy.header;if(!t.headers[r]){Log.e(WebSocketConnector,`Expected header '${r}' to contain the real IP from the connecting client: closing the connection`);e.close();return}s=t.headers[r].split(/\s*,\s*/)[0]}}try{const t=NetAddress.fromIP(s,!0),n=new NetworkConnection(new WebSocketDataChannel(e),this._protocol,t,null);this.fire("connection",n)}catch(r){Log.e(WebSocketConnector,`Error on connection from ${s}: ${r.message||r}`);e.close()}}else{Log.e(WebSocketConnector,"Expected req.connection.remoteAddress to be set and it is not: closing the connection");e.close()}}}WebSocketConnector.CONNECT_TIMEOUT=5e3;Class.register(WebSocketConnector);class WebSocketDataChannel extends DataChannel{constructor(e){super();this._ws=e;this._ws.onmessage=(e=>this._onMessage(e.data||e));this._ws.onclose=(()=>this.close());this._ws.onerror=(e=>this.fire("error",e))}_close(){this._ws.onmessage=null;this._ws.onclose=null;this._ws.onerror=null;this._ws.close();this._ws=null}sendChunk(e){this._ws.send(e)}get readyState(){return this._ws.readyState}}Class.register(WebSocketDataChannel);class NetAddress{static fromIP(e,t=!1){const s=NetUtils.ipToBytes(e),r=NetUtils.isIPv4Address(s)?NetAddress.Type.IPv4:NetAddress.Type.IPv6;return new NetAddress(r,s,t)}constructor(e,t=null,s=!1){switch(e){case NetAddress.Type.IPv4:if(!(t instanceof Uint8Array)||t.length!==NetUtils.IPv4_LENGTH)throw new Error("Malformed ip");break;case NetAddress.Type.IPv6:if(!(t instanceof Uint8Array)||t.length!==NetUtils.IPv6_LENGTH)throw new Error("Malformed ip");break;case NetAddress.Type.UNKNOWN:case NetAddress.Type.UNSPECIFIED:t=null;break;default:throw new Error("Malformed type")}this._type=e;this._ip=t;this._reliable=s}static unserialize(e){const t=e.readUint8();let s=null;switch(t){case NetAddress.Type.IPv4:s=e.read(NetUtils.IPv4_LENGTH);break;case NetAddress.Type.IPv6:s=e.read(NetUtils.IPv6_LENGTH)}return new NetAddress(t,s)}serialize(e){(e=e||new SerialBuffer(this.serializedSize)).writeUint8(this._type);this._ip&&e.write(this._ip);return e}get serializedSize(){return 1+(this._ip?this._ip.length:0)}equals(e){return e instanceof NetAddress&&this._type===e._type&&BufferUtils.equals(this._ip,e.ip)}hashCode(){return this.toString()}toString(){return this._type===NetAddress.Type.UNKNOWN?"<unknown>":this._type===NetAddress.Type.UNSPECIFIED?"":NetUtils.bytesToIp(this._ip)}get ip(){return this._ip}get type(){return this._type}get reliable(){return this._reliable}isPseudo(){return!this._ip}isPrivate(){return this.isPseudo()||NetUtils.isPrivateIP(this._ip)}isIPv6(){return this._ip&&NetUtils.isIPv6Address(this._ip)}isIPv4(){return this._ip&&NetUtils.isIPv4Address(this._ip)}subnet(e){const t=this._ip?NetUtils.ipToSubnet(this._ip,e):null;return new NetAddress(this._type,t,this._reliable)}}NetAddress.Type={IPv4:0,IPv6:1,UNSPECIFIED:2,UNKNOWN:3};NetAddress.UNSPECIFIED=new NetAddress(NetAddress.Type.UNSPECIFIED);NetAddress.UNKNOWN=new NetAddress(NetAddress.Type.UNKNOWN);Class.register(NetAddress);class PeerId extends Serializable{static copy(e){if(!e)return e;const t=new Uint8Array(e._obj);return new PeerId(t)}constructor(e){super();if(!(e instanceof Uint8Array))throw new Error("Primitive: Invalid type");if(e.length!==PeerId.SERIALIZED_SIZE)throw new Error("Primitive: Invalid length");this._obj=e}static unserialize(e){return new PeerId(e.read(PeerId.SERIALIZED_SIZE))}serialize(e){(e=e||new SerialBuffer(this.serializedSize)).write(this._obj);return e}subarray(e,t){return this._obj.subarray(e,t)}get serializedSize(){return PeerId.SERIALIZED_SIZE}equals(e){return e instanceof PeerId&&super.equals(e)}toString(){return this.toHex()}static fromBase64(e){return new PeerId(BufferUtils.fromBase64(e))}static fromHex(e){return new PeerId(BufferUtils.fromHex(e))}}PeerId.SERIALIZED_SIZE=16;Class.register(PeerId);class PeerAddress{constructor(e,t,s,r,n,i,o){if(!NumberUtils.isUint8(i))throw new Error("Malformed distance");if(null!==n&&!(n instanceof PublicKey))throw new Error("Malformed publicKey");this._protocol=e;this._services=t;this._timestamp=s;this._netAddress=r||NetAddress.UNSPECIFIED;this._publicKey=n;this._distance=i;this._signature=o}static unserialize(e){const t=e.readUint8();switch(t){case Protocol.WSS:return WssPeerAddress.unserialize(e);case Protocol.RTC:return RtcPeerAddress.unserialize(e);case Protocol.WS:return WsPeerAddress.unserialize(e);case Protocol.DUMB:return DumbPeerAddress.unserialize(e);default:throw`Malformed PeerAddress protocol ${t}`}}serialize(e){if(!this._publicKey)throw new Error("PeerAddress without publicKey may not be serialized.");if(!this._signature)throw new Error("PeerAddress without signature may not be serialized.");(e=e||new SerialBuffer(this.serializedSize)).writeUint8(this._protocol);e.writeUint32(this._services);e.writeUint64(this._timestamp);this._netAddress.isPrivate()?NetAddress.UNSPECIFIED.serialize(e):this._netAddress.serialize(e);this._publicKey.serialize(e);e.writeUint8(this._distance);this._signature.serialize(e);return e}serializeContent(e){(e=e||new SerialBuffer(this.serializedContentSize)).writeUint8(this._protocol);e.writeUint32(this._services);e.writeUint64(this._timestamp);return e}get serializedSize(){return 13+this._netAddress.serializedSize+this._publicKey.serializedSize+1+this._signature.serializedSize}get serializedContentSize(){return 13}equals(e){return e instanceof PeerAddress&&this.protocol===e.protocol&&(!this.publicKey||!e.publicKey||this.publicKey.equals(e.publicKey))&&(!this.peerId||!e.peerId||this.peerId.equals(e.peerId))}hashCode(){throw new Error("unimplemented")}verifySignature(){this._signatureVerified===undefined&&(this._signatureVerified=this.signature.verify(this.publicKey,this.serializeContent()));return this._signatureVerified}get protocol(){return this._protocol}get services(){return this._services}get timestamp(){return this._timestamp}get netAddress(){return this._netAddress.isPseudo()?null:this._netAddress}set netAddress(e){this._netAddress=e||NetAddress.UNSPECIFIED}get publicKey(){return this._publicKey}get peerId(){return this._publicKey?this._publicKey.toPeerId():null}get distance(){return this._distance}get signature(){return this._signature}set signature(e){if(0===this._distance){this._signature=e;this._signatureVerified=undefined}}set distance(e){this._distance=e}isSeed(){return 0===this._timestamp}exceedsAge(){if(this.isSeed())return!1;const e=Date.now()-this.timestamp;switch(this.protocol){case Protocol.WSS:return e>PeerAddressBook.MAX_AGE_WEBSOCKET;case Protocol.RTC:return e>PeerAddressBook.MAX_AGE_WEBRTC;case Protocol.WS:return e>PeerAddressBook.MAX_AGE_WEBSOCKET;case Protocol.DUMB:return e>PeerAddressBook.MAX_AGE_DUMB}return!1}}Class.register(PeerAddress);class WsBasePeerAddress extends PeerAddress{constructor(e,t,s,r,n,i,o,a,c){if(e!==Protocol.WS&&e!==Protocol.WSS)throw new Error("Malformed protocol");super(e,t,s,r,n,i,c);if(!o)throw new Error("Malformed host");if(!NumberUtils.isUint16(a))throw new Error("Malformed port");this._host=o;this._port=a}static fromSeedString(e){const t=/^(wss?:)\/\/([^:/?#]+):([0-9]{1,5})\/?([a-f0-9]*)$/i.exec(e);if(!t)throw new Error(`Malformed PeerAddress ${e}`);try{const[r,n,i,o,a]=t;return("ws:"===n?WsPeerAddress:WssPeerAddress).seed(i,parseInt(o),a)}catch(s){throw new Error(`Malformed PeerAddress ${e}`)}}toSeedString(){return`${this.protocolPrefix}://${this._host}:${this._port}/${this.publicKey?this.publicKey.toHex():""}`}serialize(e){e=e||new SerialBuffer(this.serializedSize);super.serialize(e);e.writeVarLengthString(this._host);e.writeUint16(this._port);return e}serializeContent(e){e=e||new SerialBuffer(this.serializedContentSize);super.serializeContent(e);e.writeVarLengthString(this._host);e.writeUint16(this._port);return e}globallyReachable(){return NetUtils.hostGloballyReachable(this.host)}get serializedSize(){return super.serializedSize+SerialBuffer.varLengthStringSize(this._host)+2}get serializedContentSize(){return super.serializedContentSize+SerialBuffer.varLengthStringSize(this._host)+2}equals(e){return super.equals(e)&&(!!this.peerId&&!!e.peerId||this._host===e.host&&this._port===e.port)}hashCode(){return this.peerId?`${this.protocolPrefix}:///${this.peerId}`:`${this.protocolPrefix}://${this._host}:${this._port}/`}toString(){return`${this.protocolPrefix}://${this._host}:${this._port}/${this.peerId?this.peerId:""}`}get host(){return this._host}get port(){return this._port}get protocolPrefix(){return this.protocol===Protocol.WS?"ws":"wss"}}Class.register(WsBasePeerAddress);class WssPeerAddress extends WsBasePeerAddress{static seed(e,t,s){const r=s?new PublicKey(BufferUtils.fromHex(s)):null;return new WssPeerAddress(Services.PROVIDES_FULL,0,NetAddress.UNSPECIFIED,r,0,e,t)}constructor(e,t,s,r,n,i,o,a){super(Protocol.WSS,e,t,s,r,n,i,o,a)}static unserialize(e){const t=e.readUint32(),s=e.readUint64(),r=NetAddress.unserialize(e),n=PublicKey.unserialize(e),i=e.readUint8(),o=Signature.unserialize(e),a=e.readVarLengthString(),c=e.readUint16();return new WssPeerAddress(t,s,r,n,i,a,c,o)}equals(e){return super.equals(e)&&e instanceof WssPeerAddress}withoutId(){return new WssPeerAddress(this.services,this.timestamp,this.netAddress,null,this.distance,this.host,this.port)}}Class.register(WssPeerAddress);class WsPeerAddress extends WsBasePeerAddress{static seed(e,t,s){const r=s?new PublicKey(BufferUtils.fromHex(s)):null;return new WsPeerAddress(Services.PROVIDES_FULL,0,NetAddress.UNSPECIFIED,r,0,e,t)}constructor(e,t,s,r,n,i,o,a){super(Protocol.WS,e,t,s,r,n,i,o,a)}static unserialize(e){const t=e.readUint32(),s=e.readUint64(),r=NetAddress.unserialize(e),n=PublicKey.unserialize(e),i=e.readUint8(),o=Signature.unserialize(e),a=e.readVarLengthString(),c=e.readUint16();return new WsPeerAddress(t,s,r,n,i,a,c,o)}globallyReachable(){return(NetUtils.isIPv4Address(this.host)||NetUtils.isIPv6Address(this.host))&&!NetUtils.isPrivateIP(this.host)||NetUtils.hostGloballyReachable(this.host)}equals(e){return super.equals(e)&&e instanceof WsPeerAddress}withoutId(){return new WsPeerAddress(this.services,this.timestamp,this.netAddress,null,this.distance,this.host,this.port)}}Class.register(WsPeerAddress);class RtcPeerAddress extends PeerAddress{constructor(e,t,s,r,n,i){super(Protocol.RTC,e,t,s,r,n,i)}static unserialize(e){const t=e.readUint32(),s=e.readUint64(),r=NetAddress.unserialize(e),n=PublicKey.unserialize(e),i=e.readUint8(),o=Signature.unserialize(e);return new RtcPeerAddress(t,s,r,n,i,o)}serialize(e){e=e||new SerialBuffer(this.serializedSize);super.serialize(e);return e}get serializedSize(){return super.serializedSize}equals(e){return super.equals(e)&&e instanceof RtcPeerAddress}hashCode(){return this.toString()}toString(){return`rtc:///${this.peerId}`}}Class.register(RtcPeerAddress);class DumbPeerAddress extends PeerAddress{constructor(e,t,s,r,n,i){super(Protocol.DUMB,e,t,s,r,n,i)}static unserialize(e){const t=e.readUint32(),s=e.readUint64(),r=NetAddress.unserialize(e),n=PublicKey.unserialize(e),i=e.readUint8(),o=Signature.unserialize(e);return new DumbPeerAddress(t,s,r,n,i,o)}serialize(e){e=e||new SerialBuffer(this.serializedSize);super.serialize(e);return e}get serializedSize(){return super.serializedSize}equals(e){return super.equals(e)&&e instanceof DumbPeerAddress}hashCode(){return this.toString()}toString(){return`dumb:///${this.peerId}`}}Class.register(DumbPeerAddress);class PeerAddressState{constructor(e){this.peerAddress=e;this.state=PeerAddressState.NEW;this.lastConnected=-1;this.bannedUntil=-1;this.banBackoff=PeerAddressBook.INITIAL_FAILED_BACKOFF;this._signalRouter=new SignalRouter(e);this._failedAttempts=0;this._closeTypes=new Map;this._addedBy=new HashSet}get signalRouter(){return this._signalRouter}get maxFailedAttempts(){switch(this.peerAddress.protocol){case Protocol.RTC:return PeerAddressBook.MAX_FAILED_ATTEMPTS_RTC;case Protocol.WS:case Protocol.WSS:return PeerAddressBook.MAX_FAILED_ATTEMPTS_WS;default:return 0}}get failedAttempts(){return this._signalRouter.bestRoute?this._signalRouter.bestRoute.failedAttempts:this._failedAttempts}set failedAttempts(e){if(this._signalRouter.bestRoute){this._signalRouter.bestRoute.failedAttempts=e;this._signalRouter.updateBestRoute()}else this._failedAttempts=e}close(e){if(e){this._closeTypes.has(e)?this._closeTypes.set(e,this._closeTypes.get(e)+1):this._closeTypes.set(e,1);this.state!==PeerAddressState.BANNED&&(CloseType.isBanningType(e)?this.state=PeerAddressState.BANNED:CloseType.isFailingType(e)?this.state=PeerAddressState.FAILED:this.state=PeerAddressState.TRIED)}}equals(e){return e instanceof PeerAddressState&&this.peerAddress.equals(e.peerAddress)}hashCode(){return this.peerAddress.hashCode()}toString(){return`PeerAddressState{peerAddress=${this.peerAddress}, state=${this.state}, `+`lastConnected=${this.lastConnected}, failedAttempts=${this.failedAttempts}, `+`bannedUntil=${this.bannedUntil}}`}get addedBy(){return this._addedBy}}PeerAddressState.NEW=1;PeerAddressState.ESTABLISHED=2;PeerAddressState.TRIED=3;PeerAddressState.FAILED=4;PeerAddressState.BANNED=5;Class.register(PeerAddressState);class SignalRouter{constructor(e){this.peerAddress=e;this._bestRoute=null;this._routes=new HashSet}get bestRoute(){return this._bestRoute}addRoute(e,t,s){const r=this._routes.get(e),n=new SignalRoute(e,t,s);r&&(n.failedAttempts=r.failedAttempts);this._routes.add(n);if(!this._bestRoute||n.score>this._bestRoute.score||n.score===this._bestRoute.score&&s>this._bestRoute.timestamp){this._bestRoute=n;this.peerAddress.distance=this._bestRoute.distance;return!0}return!1}deleteBestRoute(){this._bestRoute&&this.deleteRoute(this._bestRoute.signalChannel)}deleteRoute(e){this._routes.remove(e);this._bestRoute&&this._bestRoute.signalChannel.equals(e)&&this.updateBestRoute()}deleteAllRoutes(){this._bestRoute=null;this._routes=new HashSet}hasRoute(){return this._routes.length>0}updateBestRoute(){let e=null;for(const t of this._routes.valueIterator())(null===e||t.score>e.score||t.score===e.score&&t.timestamp>e.timestamp)&&(e=t);this._bestRoute=e;this._bestRoute?this.peerAddress.distance=this._bestRoute.distance:this.peerAddress.distance=PeerAddressBook.MAX_DISTANCE+1}equals(e){return e instanceof PeerAddressState&&this.peerAddress.equals(e.peerAddress)}hashCode(){return this.peerAddress.hashCode()}toString(){return`PeerAddressState{peerAddress=${this.peerAddress}, state=${this.state}, `+`lastConnected=${this.lastConnected}, failedAttempts=${this.failedAttempts}, `+`bannedUntil=${this.bannedUntil}}`}}Class.register(SignalRouter);class SignalRoute{constructor(e,t,s){this.failedAttempts=0;this.timestamp=s;this._signalChannel=e;this._distance=t}get signalChannel(){return this._signalChannel}get distance(){return this._distance}get score(){return(PeerAddressBook.MAX_DISTANCE-this._distance)/2*(1-this.failedAttempts/PeerAddressBook.MAX_FAILED_ATTEMPTS_RTC)}equals(e){return e instanceof SignalRoute&&this._signalChannel.equals(e._signalChannel)}hashCode(){return this._signalChannel.hashCode()}toString(){return`SignalRoute{signalChannel=${this._signalChannel}, distance=${this._distance}, timestamp=${this.timestamp}, failedAttempts=${this.failedAttempts}}`}}Class.register(SignalRoute);class SeedList{static async retrieve(e,t){return SeedList.parse(await HttpRequest.get(e,SeedList.REQUEST_TIMEOUT,SeedList.MAX_SIZE),t)}static parse(e,t){const s=[],r=e.split(/\r\n|\n|\r/).filter(e=>e.length>0&&!e.startsWith("#"));for(let c=0;c<r.length-1;c++){const e=r[c];try{s.push(WsBasePeerAddress.fromSeedString(e.trim()))}catch(a){Log.w(SeedList,`Ignoring malformed seed address ${e}`)}}const n=r[r.length-1];let i=null;try{i=new Signature(BufferUtils.fromHex(n.trim()))}catch(a){}if(!i)try{s.push(WsBasePeerAddress.fromSeedString(n.trim()))}catch(a){Log.w(SeedList,`Ignoring malformed signature/seed address ${n}`)}if(!t)return new SeedList(s,null,i);if(!i)throw new Error("Missing signature");const o=SeedList._serializeSeeds(s);if(!i.verify(t,o))throw new Error("Invalid signature");return new SeedList(s,t,i)}static _serializeSeeds(e){return BufferUtils.fromAscii(e.map(e=>e.toSeedString()).join("\n"))}constructor(e,t,s){this._seeds=e;this._publicKey=t;this._signature=s}serializeContent(){return SeedList._serializeSeeds(this._seeds)}get seeds(){return this._seeds}get publicKey(){return this._publicKey}get signature(){return this._signature}}SeedList.MAX_SIZE=131072;SeedList.REQUEST_TIMEOUT=8e3;Class.register(SeedList);class SeedListUrl{constructor(e,t){this._url=e;this._publicKey=t?new PublicKey(BufferUtils.fromHex(t)):null}get url(){return this._url}get publicKey(){return this._publicKey}}Class.register(SeedListUrl);class PeerAddressSeeder extends Observable{async collect(){if(!GenesisConfig.SEED_LISTS){this.fire("end");return}const e=[];for(const t of GenesisConfig.SEED_LISTS)e.push(SeedList.retrieve(t.url,t.publicKey).then(e=>{Log.i(PeerAddressSeeder,`Got ${e.seeds.length} seed peers from ${t.url}`+(e.publicKey&&e.signature?" (signed)":""));this.fire("seeds",e.seeds)})["catch"](e=>Log.w(PeerAddressSeeder,`Failed to retrieve seed list from ${t.url}: ${e.message||e}`)));await Promise.all(e);this.fire("end")}}Class.register(PeerAddressSeeder);class PeerAddressBook extends Observable{constructor(e){super();this._networkConfig=e;this._store=new HashSet;this._wsStates=new HashSet;this._wssStates=new HashSet;this._rtcStates=new HashSet;this._stateByPeerId=new HashMap;this._statesByNetAddress=new HashMap;this._seeded=!1;this.add(null,GenesisConfig.SEED_PEERS);const t=()=>{this._seeded=!0;this.fire("seeded")},s=new PeerAddressSeeder;s.on("seeds",e=>this.add(null,e));s.on("end",t);s.collect()["catch"](Log.e.tag(PeerAddressBook));setTimeout(t,PeerAddressBook.SEEDING_TIMEOUT);setInterval(()=>this._housekeeping(),PeerAddressBook.HOUSEKEEPING_INTERVAL)}iterator(){return this._store.valueIterator()}wsIterator(){return this._wsStates.valueIterator()}wssIterator(){return this._wssStates.valueIterator()}rtcIterator(){return this._rtcStates.valueIterator()}_get(e){if(e instanceof WssPeerAddress||e instanceof WsPeerAddress){const t=this._store.get(e.withoutId());if(t)return t}return this._store.get(e)}getState(e){return this._get(e)}get(e){const t=this._get(e);return t?t.peerAddress:null}getByPeerId(e){const t=this._stateByPeerId.get(e);return t?t.peerAddress:null}getChannelByPeerId(e){const t=this._stateByPeerId.get(e);return t&&t.signalRouter.bestRoute?t.signalRouter.bestRoute.signalChannel:null}query(e,t,s=NetworkAgent.MAX_ADDR_PER_MESSAGE){let r,n;switch(e){case Protocol.WSS:r=this.wssIterator();n=this.knownWssAddressesCount;break;case Protocol.WS:r=this.wsIterator();n=this.knownWsAddressesCount;break;case Protocol.WS|Protocol.WSS:r=IteratorUtils.alternate(this.wsIterator(),this.wssIterator());n=this.knownWsAddressesCount+this.knownWssAddressesCount;break;case Protocol.RTC:r=this.rtcIterator();n=this.knownRtcAddressesCount;break;case Protocol.RTC|Protocol.WS:r=IteratorUtils.alternate(this.rtcIterator(),this.wsIterator());n=this.knownRtcAddressesCount+this.knownWsAddressesCount;break;case Protocol.RTC|Protocol.WSS:r=IteratorUtils.alternate(this.rtcIterator(),this.wssIterator());n=this.knownRtcAddressesCount+this.knownWssAddressesCount;break;default:r=this.iterator();n=this.knownAddressesCount}let i=0,o=n;n>s&&(o=((i=Math.floor(Math.random()*n))+s)%n);const a=i>o,c=[];let h=-1;for(const l of r){h++;if(!a&&h<i)continue;if(!a&&h>=o)break;if(a&&h>=o&&h<i)continue;if(l.state===PeerAddressState.BANNED||l.state===PeerAddressState.FAILED)continue;const s=l.peerAddress;if(s.isSeed())continue;if(0==(s.protocol&e))continue;const r=t&Services.ALL_LEGACY;if(r>0&&0==(s.services&r))continue;const n=t&Services.ALL_CURRENT;0===r&&n>0&&(s.services&n)!==n||(s.protocol===Protocol.RTC&&s.distance>=PeerAddressBook.MAX_DISTANCE||s.exceedsAge()||c.push(s))}Log.v(PeerAddressBook,()=>`Returned ${c.length} valid addresses from ${n} that were considered`);return c}add(e,t){const s=Array.isArray(t)?t:[t],r=[];for(const n of s)this._add(e,n)&&r.push(n);r.length&&this.fire("added",r,this)}_add(e,t){if(this._networkConfig.peerAddress.equals(t))return!1;if(e&&t.exceedsAge()){Log.v(PeerAddressBook,()=>`Ignoring address ${t} - too old (${new Date(t.timestamp)})`);return!1}if(t.timestamp>Date.now()+PeerAddressBook.MAX_TIMESTAMP_DRIFT){Log.v(PeerAddressBook,()=>`Ignoring addresses ${t} - timestamp in the future`);return!1}if(t.protocol===Protocol.RTC){t.distance++;if(t.distance>PeerAddressBook.MAX_DISTANCE){Log.v(PeerAddressBook,()=>`Ignoring address ${t} - max distance exceeded`);const s=this._get(t);s&&s.signalRouter.deleteRoute(e);return!1}}const s=e&&e.netAddress&&e.netAddress.reliable?e.netAddress:null;let r=this._get(t),n=null,i=!1;if(r){n=r.peerAddress;if(r.state===PeerAddressState.BANNED)return!1;if(n.isSeed())return!1;!n.netAddress||t.netAddress&&!n.netAddress.reliable||(t.netAddress=n.netAddress)}else{if(this._store.length>=PeerAddressBook.MAX_SIZE)return!1;switch(t.protocol){case Protocol.WSS:if(this._wssStates.length>=PeerAddressBook.MAX_SIZE_WSS)return!1;break;case Protocol.WS:if(this._wsStates.length>=PeerAddressBook.MAX_SIZE_WS)return!1;break;case Protocol.RTC:if(this._rtcStates.length>=PeerAddressBook.MAX_SIZE_RTC)return!1}if(s){const e=this._statesByNetAddress.get(s);if(e&&e.size>=PeerAddressBook.MAX_SIZE_PER_IP){Log.v(PeerAddressBook,()=>`Ignoring address ${t} - max count per IP ${s} reached`);return!1}}r=new PeerAddressState(t);this._addToStore(r);i=!0}if(!n||n.timestamp<t.timestamp){r.peerAddress=t;i=!0}t.protocol===Protocol.RTC&&(i=r.signalRouter.addRoute(e,t.distance,t.timestamp)||i);this._trackByNetAddress(r,s);return i}_addToStore(e){this._store.add(e);e.peerAddress.peerId&&this._stateByPeerId.put(e.peerAddress.peerId,e);switch(e.peerAddress.protocol){case Protocol.WSS:this._wssStates.add(e);break;case Protocol.WS:this._wsStates.add(e);break;case Protocol.RTC:this._rtcStates.add(e)}}_trackByNetAddress(e,t){if(!t)return;e.addedBy.add(t);let s=this._statesByNetAddress.get(t);if(!s){s=new Set;this._statesByNetAddress.put(t,s)}s.add(e)}established(e,t){let s=this._get(t);if(!s){s=new PeerAddressState(t);this._addToStore(s)}const r=e&&e.netAddress&&e.netAddress.reliable?e.netAddress:null;this._trackByNetAddress(s,r);s.state=PeerAddressState.ESTABLISHED;s.lastConnected=Date.now();s.failedAttempts=0;s.bannedUntil=-1;s.banBackoff=PeerAddressBook.INITIAL_FAILED_BACKOFF;s.peerAddress.isSeed()||(s.peerAddress=t);t.protocol===Protocol.RTC&&s.signalRouter.addRoute(e,t.distance,t.timestamp)}close(e,t,s=null){const r=this._get(t);if(r){r.close(s);e&&this._removeBySignalChannel(e);if(CloseType.isBanningType(s))this._ban(t);else if(CloseType.isFailingType(s)){r.failedAttempts++;if(r.failedAttempts>=r.maxFailedAttempts)if(r.banBackoff>=PeerAddressBook.MAX_FAILED_BACKOFF)this._removeFromStore(t);else{r.bannedUntil=Date.now()+r.banBackoff;r.banBackoff=Math.min(PeerAddressBook.MAX_FAILED_BACKOFF,2*r.banBackoff)}}t.protocol===Protocol.DUMB&&this._removeFromStore(t)}}unroutable(e,t){if(!t)return;const s=this._get(t);if(s)if(s.signalRouter.bestRoute&&s.signalRouter.bestRoute.signalChannel.equals(e)){s.signalRouter.deleteBestRoute();s.signalRouter.hasRoute()||this._removeFromStore(s.peerAddress)}else Log.d(PeerAddressBook,()=>`Got unroutable for ${t} on a channel other than the best route.`)}_ban(e,t=PeerAddressBook.DEFAULT_BAN_TIME){let s=this._get(e);if(!s){s=new PeerAddressState(e);this._store.add(s)}s.state=PeerAddressState.BANNED;s.bannedUntil=Date.now()+t;s.signalRouter.deleteAllRoutes()}isBanned(e){const t=this._get(e);return t&&t.state===PeerAddressState.BANNED&&!t.peerAddress.isSeed()}_removeFromStore(e){const t=this._get(e);if(t)if(t.peerAddress.isSeed())this._ban(e,t.banBackoff);else{e.peerId&&this._stateByPeerId.remove(e.peerId);for(const e of t.addedBy){const s=this._statesByNetAddress.get(e);if(s){s["delete"](t);0===s.size&&this._statesByNetAddress.remove(e)}}switch(t.peerAddress.protocol){case Protocol.WSS:this._wssStates.remove(t);break;case Protocol.WS:this._wsStates.remove(t);break;case Protocol.RTC:this._rtcStates.remove(t)}if(t.state!==PeerAddressState.BANNED){this._store.remove(e);this.fire("removed",e,this)}}}_removeBySignalChannel(e){for(const t of this._store.valueIterator())if(t.peerAddress.protocol===Protocol.RTC){t.signalRouter.deleteRoute(e);t.signalRouter.hasRoute()||this._removeFromStore(t.peerAddress)}}_housekeeping(){const e=Date.now(),t=[];for(const s of this._store.valueIterator()){const r=s.peerAddress;switch(s.state){case PeerAddressState.NEW:case PeerAddressState.TRIED:case PeerAddressState.FAILED:if(r.exceedsAge()){this._removeFromStore(r);continue}if(s.state===PeerAddressState.FAILED&&s.failedAttempts>=s.maxFailedAttempts&&s.bannedUntil>0&&s.bannedUntil<=e){s.bannedUntil=-1;s.failedAttempts=0;t.push(r)}break;case PeerAddressState.BANNED:if(s.bannedUntil<=e)if(r.isSeed()){s.state=PeerAddressState.NEW;s.failedAttempts=0;s.bannedUntil=-1;t.push(r)}else this._removeFromStore(r);break;case PeerAddressState.ESTABLISHED:s.signalRouter.bestRoute&&(s.signalRouter.bestRoute.timestamp=e)}}t.length&&this.fire("added",t,this)}get knownAddressesCount(){return this._store.length}get knownWsAddressesCount(){return this._wsStates.length}get knownWssAddressesCount(){return this._wssStates.length}get knownRtcAddressesCount(){return this._rtcStates.length}get seeded(){return this._seeded}}PeerAddressBook.MAX_AGE_WEBSOCKET=18e5;PeerAddressBook.MAX_AGE_WEBRTC=9e5;PeerAddressBook.MAX_AGE_DUMB=6e4;PeerAddressBook.MAX_DISTANCE=4;PeerAddressBook.MAX_FAILED_ATTEMPTS_WS=3;PeerAddressBook.MAX_FAILED_ATTEMPTS_RTC=2;PeerAddressBook.MAX_TIMESTAMP_DRIFT=6e5;PeerAddressBook.HOUSEKEEPING_INTERVAL=6e4;PeerAddressBook.DEFAULT_BAN_TIME=6e5;PeerAddressBook.INITIAL_FAILED_BACKOFF=3e4;PeerAddressBook.MAX_FAILED_BACKOFF=6e5;PeerAddressBook.MAX_SIZE_WS=PlatformUtils.isBrowser()?1e3:1e4;PeerAddressBook.MAX_SIZE_WSS=PlatformUtils.isBrowser()?1e3:1e4;PeerAddressBook.MAX_SIZE_RTC=PlatformUtils.isBrowser()?1e3:1e4;PeerAddressBook.MAX_SIZE=PlatformUtils.isBrowser()?2500:20500;PeerAddressBook.MAX_SIZE_PER_IP=250;PeerAddressBook.SEEDING_TIMEOUT=3e3;Class.register(PeerAddressBook);class GenesisConfig{static main(){GenesisConfig.init(GenesisConfig.CONFIGS.main)}static test(){GenesisConfig.init(GenesisConfig.CONFIGS.test)}static dev(){GenesisConfig.init(GenesisConfig.CONFIGS.dev)}static init(e){if(GenesisConfig._config)throw new Error("GenesisConfig already initialized");if(!e.NETWORK_ID)throw new Error("Config is missing network id");if(!e.NETWORK_NAME)throw new Error("Config is missing network name");if(!e.GENESIS_BLOCK)throw new Error("Config is missing genesis block");if(!e.GENESIS_ACCOUNTS)throw new Error("Config is missing genesis accounts");if(!e.SEED_PEERS)throw new Error("Config is missing seed peers");GenesisConfig._config=e}static get NETWORK_ID(){if(!GenesisConfig._config)throw new Error("GenesisConfig not initialized");return GenesisConfig._config.NETWORK_ID}static get NETWORK_NAME(){if(!GenesisConfig._config)throw new Error("GenesisConfig not initialized");return GenesisConfig._config.NETWORK_NAME}static get GENESIS_BLOCK(){if(!GenesisConfig._config)throw new Error("GenesisConfig not initialized");return GenesisConfig._config.GENESIS_BLOCK}static get GENESIS_HASH(){if(!GenesisConfig._config)throw new Error("GenesisConfig not initialized");GenesisConfig._config.GENESIS_HASH||(GenesisConfig._config.GENESIS_HASH=GenesisConfig._config.GENESIS_BLOCK.hash());return GenesisConfig._config.GENESIS_HASH}static get GENESIS_ACCOUNTS(){if(!GenesisConfig._config)throw new Error("GenesisConfig not initialized");return GenesisConfig._config.GENESIS_ACCOUNTS}static get SEED_PEERS(){if(!GenesisConfig._config)throw new Error("GenesisConfig not initialized");return GenesisConfig._config.SEED_PEERS}static get SEED_LISTS(){if(!GenesisConfig._config)throw new Error("GenesisConfig not initialized");return GenesisConfig._config.SEED_LISTS}static networkIdToNetworkName(e){for(const t of Object.keys(GenesisConfig.CONFIGS)){const s=GenesisConfig.CONFIGS[t];if(e===s.NETWORK_ID)return s.NETWORK_NAME}throw new Error(`Unable to find networkName for networkId ${e}`)}static networkIdFromAny(e){if("number"==typeof e)return e;if(GenesisConfig.CONFIGS[e])return GenesisConfig.CONFIGS[e].NETWORK_ID;throw new Error(`Unable to find networkId for ${e}`)}}Class.register(GenesisConfig);GenesisConfig.CONFIGS={main:{NETWORK_ID:12,NETWORK_NAME:"main",SEED_PEERS:[],SEED_LISTS:[],GENESIS_BLOCK:new Block(new BlockHeader(new Hash(null),new Hash(null),Hash.fromBase64("B5Nsxzy9moSfaW9aiKaOBBdnt49C9KLJcodqWYn89ho="),Hash.fromBase64("kJ4HmfCa5gsw9jfAZTFOf2yIek/3W7cVBcurUgeRDFk="),BlockUtils.difficultyToCompact(1),1,1727060400,72437,BlockHeader.Version.V1),new BlockInterlink([],new Hash(null)),new BlockBody(Address.fromBase64("AAAAAAAAAAAAAAAAAAAAAAAAAAA="),[],BufferUtils.fromBase64("UURFeU1URmtiR009"))),GENESIS_ACCOUNTS:"AAA="},test:{NETWORK_ID:1,NETWORK_NAME:"test",SEED_PEERS:[WsPeerAddress.seed("0.0.0.0",12011,"044e14e7d889b29ed7e1fdd8214d81f649955ec2bf5ffc6f42c396442ad1e95b119fe88e404158922062afc46d61053b0a8f2d65ad49c6c65917cf0efe1e4f39b8")],SEED_LISTS:[],GENESIS_BLOCK:new Block(new BlockHeader(new Hash(null),new Hash(null),Hash.fromBase64("9rorv34UeKIJBXAARx1z+9wo3wtxd0fZKc/egpxBIPY="),Hash.fromBase64("kJ4HmfCa5gsw9jfAZTFOf2yIek/3W7cVBcurUgeRDFk="),BlockUtils.difficultyToCompact(1),1,1720681200,97603,BlockHeader.Version.V1),new BlockInterlink([],new Hash(null)),new BlockBody(Address.fromBase64("AAAAAAAAAAAAAAAAAAAAAAAAAAA="),[],BufferUtils.fromBase64("VGVzdE5ldA=="))),GENESIS_ACCOUNTS:"AAA="},dev:{NETWORK_ID:2,NETWORK_NAME:"dev",SEED_PEERS:[],SEED_LISTS:[],GENESIS_BLOCK:new Block(new BlockHeader(new Hash(null),new Hash(null),Hash.fromBase64("JvMr9c9l2m8HWNdFAGTEastKH+aDZvln9EopXelhVIg="),Hash.fromBase64("1t/Zm91tN0p178+ePcxyR5bPxvC6jFLskqiidFFO3wY="),BlockUtils.difficultyToCompact(1),1,1522338300,12432,BlockHeader.Version.V1),new BlockInterlink([],new Hash(null)),new BlockBody(Address.fromBase64("AAAAAAAAAAAAAAAAAAAAAAAAAAA="),[],BufferUtils.fromBase64("RGV2TmV0"))),GENESIS_ACCOUNTS:"AAA="}};class CloseType{static isBanningType(e){return e>=100&&e<200}static isFailingType(e){return e>=200}}CloseType.GET_BLOCKS_TIMEOUT=1;CloseType.GET_HEADER_TIMEOUT=2;CloseType.GET_CHAIN_PROOF_TIMEOUT=3;CloseType.GET_ACCOUNTS_PROOF_TIMEOUT=4;CloseType.GET_ACCOUNTS_TREE_CHUNK_TIMEOUT=5;CloseType.GET_TRANSACTIONS_PROOF_TIMEOUT=6;CloseType.GET_TRANSACTION_RECEIPTS_TIMEOUT=7;CloseType.SENDING_PING_MESSAGE_FAILED=10;CloseType.SENDING_OF_VERSION_MESSAGE_FAILED=11;CloseType.SIMULTANEOUS_CONNECTION=20;CloseType.DUPLICATE_CONNECTION=21;CloseType.INVALID_CONNECTION_STATE=22;CloseType.PEER_BANNED=30;CloseType.IP_BANNED=31;CloseType.MAX_PEER_COUNT_REACHED=40;CloseType.PEER_CONNECTION_RECYCLED=41;CloseType.PEER_CONNECTION_RECYCLED_INBOUND_EXCHANGE=42;CloseType.INBOUND_CONNECTIONS_BLOCKED=43;CloseType.MANUAL_NETWORK_DISCONNECT=50;CloseType.MANUAL_WEBSOCKET_DISCONNECT=51;CloseType.MANUAL_PEER_DISCONNECT=52;CloseType.INCOMPATIBLE_VERSION=100;CloseType.DIFFERENT_GENESIS_BLOCK=101;CloseType.INVALID_PEER_ADDRESS_IN_VERSION_MESSAGE=102;CloseType.UNEXPECTED_PEER_ADDRESS_IN_VERSION_MESSAGE=103;CloseType.INVALID_PUBLIC_KEY_IN_VERACK_MESSAGE=104;CloseType.INVALID_SIGNATURE_IN_VERACK_MESSAGE=105;CloseType.ADDR_MESSAGE_TOO_LARGE=110;CloseType.ADDR_NOT_GLOBALLY_REACHABLE=111;CloseType.INVALID_ADDR=112;CloseType.INVALID_SIGNAL_TTL=113;CloseType.INVALID_BLOCK=120;CloseType.INVALID_HEADER=121;CloseType.INVALID_ACCOUNTS_TREE_CHUNCK=122;CloseType.INVALID_ACCOUNTS_PROOF=123;CloseType.INVALID_CHAIN_PROOF=124;CloseType.INVALID_TRANSACTION_PROOF=125;CloseType.INVALID_BLOCK_PROOF=126;CloseType.INVALID_TRANSACTION_RECEIPTS=127;CloseType.RATE_LIMIT_EXCEEDED=130;CloseType.BLOCKCHAIN_SYNC_FAILED=140;CloseType.MANUAL_PEER_BAN=150;CloseType.CONNECTION_FAILED=200;CloseType.CLOSED_BY_REMOTE=201;CloseType.NETWORK_ERROR=202;CloseType.CHANNEL_CLOSING=203;CloseType.VERSION_TIMEOUT=210;CloseType.VERACK_TIMEOUT=211;CloseType.PING_TIMEOUT=212;CloseType.CONNECTION_LIMIT_PER_IP=220;CloseType.CONNECTION_LIMIT_DUMB=221;CloseType.FAILED_TO_PARSE_MESSAGE_TYPE=230;CloseType.UNEXPECTED_ACCOUNTS_TREE_CHUNK=231;CloseType.UNEXPECTED_HEADER=232;CloseType.TRANSACTION_NOT_MATCHING_SUBSCRIPTION=233;CloseType.ABORTED_SYNC=240;CloseType.MANUAL_PEER_FAIL=250;Class.register(CloseType);class NetworkConnection extends Observable{constructor(e,t,s,r){super();this._channel=e;this._protocol=t;this._netAddress=s;this._peerAddress=r;this._bytesSent=0;this._bytesReceived=0;this._inbound=!r;this._closed=!1;this._lastError=null;this._id=NetworkConnection._instanceCount++;this._channel.on("message",e=>this._onMessage(e));this._channel.on("error",e=>this._onError(e));this._channel.on("close",()=>this._close(CloseType.CLOSED_BY_REMOTE,"Closed by remote"))}_onMessage(e){if(!this._closed){this._bytesReceived+=e.byteLength||e.length;this.fire("message",e,this)}}_onError(e){if(!this._closed){this._lastError=e;this.fire("error",e,this)}}_close(e,t){if(!this._closed){this._closed=!0;this._channel.close();this._channel=null;if(e===CloseType.CLOSED_BY_REMOTE&&this._lastError){e=CloseType.NETWORK_ERROR;t=this._lastError}t&&"string"!=typeof t&&(t="string"==typeof t.message?t.message:"");this.fire("close",e,t,this);this._offAll()}}close(e,t){if(!this._closed){const s=this._inbound?"inbound":"outbound";Log.d(NetworkConnection,`Closing ${s} connection #${this._id} ${this._peerAddress||this._netAddress}`+(t?` - ${t}`:"")+` (${e})`)}this._close(e,t)}_isChannelOpen(){return this._channel&&this._channel.readyState===DataChannel.ReadyState.OPEN}_isChannelClosing(){return this._channel&&this._channel.readyState===DataChannel.ReadyState.CLOSING}_isChannelClosed(){return!this._channel||this._channel.readyState===DataChannel.ReadyState.CLOSED}send(e){const t=this._peerAddress||this._netAddress;if(this._closed)return!1;if(this._isChannelClosing()||this._isChannelClosed()){Log.d(NetworkConnection,()=>`Not sending data to ${t} - channel closing/closed (${this._channel.readyState})`);this._close(CloseType.CHANNEL_CLOSING,"channel closing");return!1}if(!this._isChannelOpen()){Log.d(NetworkConnection,()=>`Not sending data to ${t} - channel not open (${this._channel.readyState})`);return!1}try{this._channel.send(e);this._bytesSent+=e.byteLength||e.length;return!0}catch(s){Log.e(NetworkConnection,`Failed to send data to ${t}: ${s.message||s}`);return!1}}expectMessage(e,t,s,r){this._closed?setTimeout(t):this._channel.expectMessage(e,t,s,r)}isExpectingMessage(e){return!this._closed&&this._channel.isExpectingMessage(e)}confirmExpectedMessage(e,t){this._closed||this._channel.confirmExpectedMessage(e,t)}equals(e){return e instanceof NetworkConnection&&this._id===e.id}hashCode(){return this._id.toString()}toString(){return`NetworkConnection{id=${this._id}, protocol=${this._protocol}, peerAddress=${this._peerAddress}, netAddress=${this._netAddress}}`}get id(){return this._id}get protocol(){return this._protocol}get peerAddress(){return this._peerAddress}set peerAddress(e){this._peerAddress=e}get netAddress(){return this._netAddress}set netAddress(e){this._netAddress=e}get bytesSent(){return this._bytesSent}get bytesReceived(){return this._bytesReceived}get inbound(){return this._inbound}get outbound(){return!this._inbound}get closed(){return this._closed}get lastMessageReceivedAt(){return this._closed?0:this._channel.lastMessageReceivedAt}}NetworkConnection._instanceCount=0;Class.register(NetworkConnection);class PeerChannel extends Observable{constructor(e){super();this._conn=e;this._conn.on("message",e=>this._onMessage(e));this.bubble(this._conn,"close","error")}async _onMessage(e){const t=Date.now();let s=null,r=null;try{const t=new SerialBuffer(e);r=MessageFactory.peekType(t);s=MessageFactory.parse(t)}catch(n){Log.d(PeerChannel,()=>`Failed to parse '${PeerChannel.Event[r]}' message from ${this.peerAddress||this.netAddress}`,n.message||n);this._conn.confirmExpectedMessage(r,!1);if(null===r||r===Message.Type.REJECT){this.close(CloseType.FAILED_TO_PARSE_MESSAGE_TYPE,"Failed to parse message type");return}this.reject(r,RejectMessage.Code.REJECT_MALFORMED,n.message||n);return}if(s){this._conn.confirmExpectedMessage(r,!0);try{await this.fire(PeerChannel.Event[s.type],s,this);this.fire("message-log",s,this,Date.now()-t,e.byteLength)}catch(n){Log.w(PeerChannel,`Error while processing '${PeerChannel.Event[s.type]}' message from ${this.peerAddress||this.netAddress}: ${n}`)}}}expectMessage(e,t,s,r){this._conn.expectMessage(e,t,s,r)}isExpectingMessage(e){return this._conn.isExpectingMessage(e)}_send(e){return this._conn.send(e.serialize())}close(e,t){this._conn.close(e,t);this._offAll()}version(e,t,s,r){return this._send(new VersionMessage(Version.CODE,e,GenesisConfig.GENESIS_HASH,t,s,Version.createUserAgent(r)))}verack(e,t){return this._send(new VerAckMessage(e,t))}inv(e){return this._send(new InvMessage(e))}notFound(e){return this._send(new NotFoundMessage(e))}getData(e){return this._send(new GetDataMessage(e))}getHeader(e){return this._send(new GetHeaderMessage(e))}block(e){return this._send(new BlockMessage(e))}rawBlock(e){return this._send(new RawBlockMessage(e))}header(e){return this._send(new HeaderMessage(e))}tx(e,t){return this._send(new TxMessage(e,t))}getBlocks(e,t=BaseInventoryMessage.VECTORS_MAX_COUNT,s=!0){return this._send(new GetBlocksMessage(e,t,s?GetBlocksMessage.Direction.FORWARD:GetBlocksMessage.Direction.BACKWARD))}mempool(){return this._send(new MempoolMessage)}reject(e,t,s,r){return this._send(new RejectMessage(e,t,s,r))}subscribe(e){return this._send(new SubscribeMessage(e))}addr(e){return this._send(new AddrMessage(e))}getAddr(e,t,s){return this._send(new GetAddrMessage(e,t,s))}ping(e){return this._send(new PingMessage(e))}pong(e){return this._send(new PongMessage(e))}signal(e,t,s,r,n,i,o,a){return this._send(new SignalMessage(e,t,s,r,n,i,o,a))}getAccountsProof(e,t){return this._send(new GetAccountsProofMessage(e,t))}accountsProof(e,t){return this._send(new AccountsProofMessage(e,t))}getChainProof(){return this._send(new GetChainProofMessage)}chainProof(e){return this._send(new ChainProofMessage(e))}getAccountsTreeChunk(e,t){return this._send(new GetAccountsTreeChunkMessage(e,t))}accountsTreeChunk(e,t){return this._send(new AccountsTreeChunkMessage(e,t))}getTransactionsProof(e,t){return this.getTransactionsProofByAddresses(e,t)}getTransactionsProofByAddresses(e,t){return this._send(new GetTransactionsProofByAddressesMessage(e,t))}getTransactionsProofByHashes(e,t){return this._send(new GetTransactionsProofByHashesMessage(e,t))}transactionsProof(e,t){return this._send(new TransactionsProofMessage(e,t))}getTransactionReceipts(e){return this.getTransactionReceiptsByAddress(e)}getTransactionReceiptsByAddress(e){return this._send(new GetTransactionReceiptsByAddressMessage(e))}getTransactionReceiptsByHashes(e){return this._send(new GetTransactionReceiptsByHashesMessage(e))}transactionReceipts(e){return this._send(new TransactionReceiptsMessage(e))}getBlockProof(e,t){return this._send(new GetBlockProofMessage(e,t))}getBlockProofAt(e,t){return this._send(new GetBlockProofAtMessage(e,t))}blockProof(e){return this._send(new BlockProofMessage(e))}getHead(){return this._send(new GetHeadMessage)}head(e){return this._send(new HeadMessage(e))}equals(e){return e instanceof PeerChannel&&this._conn.equals(e.connection)}hashCode(){return this._conn.hashCode()}toString(){return`PeerChannel{conn=${this._conn}}`}get connection(){return this._conn}get id(){return this._conn.id}get protocol(){return this._conn.protocol}get peerAddress(){return this._conn.peerAddress}set peerAddress(e){this._conn.peerAddress=e}get netAddress(){return this._conn.netAddress}set netAddress(e){this._conn.netAddress=e}get closed(){return this._conn.closed}get lastMessageReceivedAt(){return this._conn.lastMessageReceivedAt}}Class.register(PeerChannel);PeerChannel.Event={};PeerChannel.Event[Message.Type.VERSION]="version";PeerChannel.Event[Message.Type.INV]="inv";PeerChannel.Event[Message.Type.GET_DATA]="get-data";PeerChannel.Event[Message.Type.GET_HEADER]="get-header";PeerChannel.Event[Message.Type.NOT_FOUND]="not-found";PeerChannel.Event[Message.Type.GET_BLOCKS]="get-blocks";PeerChannel.Event[Message.Type.BLOCK]="block";PeerChannel.Event[Message.Type.HEADER]="header";PeerChannel.Event[Message.Type.TX]="tx";PeerChannel.Event[Message.Type.MEMPOOL]="mempool";PeerChannel.Event[Message.Type.REJECT]="reject";PeerChannel.Event[Message.Type.SUBSCRIBE]="subscribe";PeerChannel.Event[Message.Type.ADDR]="addr";PeerChannel.Event[Message.Type.GET_ADDR]="get-addr";PeerChannel.Event[Message.Type.PING]="ping";PeerChannel.Event[Message.Type.PONG]="pong";PeerChannel.Event[Message.Type.SIGNAL]="signal";PeerChannel.Event[Message.Type.GET_CHAIN_PROOF]="get-chain-proof";PeerChannel.Event[Message.Type.CHAIN_PROOF]="chain-proof";PeerChannel.Event[Message.Type.GET_ACCOUNTS_PROOF]="get-accounts-proof";PeerChannel.Event[Message.Type.ACCOUNTS_PROOF]="accounts-proof";PeerChannel.Event[Message.Type.GET_ACCOUNTS_TREE_CHUNK]="get-accounts-tree-chunk";PeerChannel.Event[Message.Type.ACCOUNTS_TREE_CHUNK]="accounts-tree-chunk";PeerChannel.Event[Message.Type.GET_TRANSACTIONS_PROOF_BY_ADDRESSES]="get-transactions-proof";PeerChannel.Event[Message.Type.TRANSACTIONS_PROOF]="transactions-proof";PeerChannel.Event[Message.Type.GET_TRANSACTION_RECEIPTS_BY_ADDRESS]="get-transaction-receipts";PeerChannel.Event[Message.Type.TRANSACTION_RECEIPTS]="transaction-receipts";PeerChannel.Event[Message.Type.GET_BLOCK_PROOF]="get-block-proof";PeerChannel.Event[Message.Type.BLOCK_PROOF]="block-proof";PeerChannel.Event[Message.Type.GET_TRANSACTIONS_PROOF_BY_HASHES]="get-transactions-proof-by-hashes";PeerChannel.Event[Message.Type.GET_TRANSACTION_RECEIPTS_BY_HASHES]="get-transaction-receipts-by-hashes";PeerChannel.Event[Message.Type.GET_BLOCK_PROOF_AT]="get-block-proof-at";PeerChannel.Event[Message.Type.GET_HEAD]="get-head";PeerChannel.Event[Message.Type.HEAD]="head";PeerChannel.Event[Message.Type.VERACK]="verack";class NetworkAgent extends Observable{constructor(e,t,s,r){super();this._blockchain=e;this._addresses=t;this._networkConfig=s;this._channel=r;this._peer=null;this._timers=new Timers;this._versionReceived=!1;this._verackReceived=!1;this._versionSent=!1;this._verackSent=!1;this._versionAttempts=0;this._peerAddressVerified=!1;this._peerChallengeNonce=null;this._pingTimes=new Map;this._addressRequest=null;this._getAddrLimit=new RateLimit(NetworkAgent.GETADDR_RATE_LIMIT);this._challengeNonce=new Uint8Array(VersionMessage.CHALLENGE_SIZE);CryptoWorker.lib.getRandomValues(this._challengeNonce);r.on("version",e=>this._onVersion(e));r.on("verack",e=>this._onVerAck(e));r.on("addr",e=>this._onAddr(e));r.on("get-addr",e=>this._onGetAddr(e));r.on("ping",e=>this._onPing(e));r.on("pong",e=>this._onPong(e));r.on("close",()=>this._onClose())}handshake(){if(!this._versionSent)if(this._channel.version(this._networkConfig.peerAddress,this._blockchain.headHash,this._challengeNonce,this._networkConfig.appAgent)){this._versionSent=!0;this._versionReceived?this._peerAddressVerified&&this._sendVerAck():this._timers.setTimeout("version",()=>{this._timers.clearTimeout("version");this._channel.close(CloseType.VERSION_TIMEOUT,"version timeout")},NetworkAgent.HANDSHAKE_TIMEOUT);this._timers.setTimeout("verack",()=>{this._timers.clearTimeout("verack");this._channel.close(CloseType.VERACK_TIMEOUT,"verack timeout")},2*NetworkAgent.HANDSHAKE_TIMEOUT)}else{this._versionAttempts++;if(this._versionAttempts>=NetworkAgent.VERSION_ATTEMPTS_MAX||this._channel.closed){this._channel.close(CloseType.SENDING_OF_VERSION_MESSAGE_FAILED,"sending of version message failed");return}setTimeout(this.handshake.bind(this),NetworkAgent.VERSION_RETRY_DELAY)}}_onVersion(e){Log.v(NetworkAgent,()=>`[VERSION] ${e.peerAddress} ${e.headHash.toBase64()}`);const t=Date.now();if(!this._canAcceptMessage(e))return;if(this._versionReceived){Log.d(NetworkAgent,()=>`Ignoring duplicate version message from ${this._channel.peerAddress}`);return}this._timers.clearTimeout("version");if(!Version.isCompatible(e.version)){this._channel.reject(Message.Type.VERSION,RejectMessage.Code.REJECT_OBSOLETE,`incompatible version (ours=${Version.CODE}, theirs=${e.version})`);this._channel.close(CloseType.INCOMPATIBLE_VERSION,`incompatible version (ours=${Version.CODE}, theirs=${e.version})`);return}if(!GenesisConfig.GENESIS_HASH.equals(e.genesisHash)){this._channel.close(CloseType.DIFFERENT_GENESIS_BLOCK,`different genesis block (${e.genesisHash})`);return}if(!e.peerAddress.verifySignature()){this._channel.close(CloseType.INVALID_PEER_ADDRESS_IN_VERSION_MESSAGE,"invalid peerAddress in version message");return}const s=e.peerAddress;if(this._channel.peerAddress){if(!this._channel.peerAddress.equals(s)){this._channel.close(CloseType.UNEXPECTED_PEER_ADDRESS_IN_VERSION_MESSAGE,"unexpected peerAddress in version message");return}this._peerAddressVerified=!0}if(!s.netAddress){const e=this._addresses.get(s);e&&e.netAddress&&(s.netAddress=e.netAddress)}this._channel.peerAddress=s;this._peer=new Peer(this._channel,e.version,e.headHash,s.timestamp-t,e.userAgent);this._peerChallengeNonce=e.challengeNonce;this._versionReceived=!0;this.fire("version",this._peer,this);if(!this._channel.closed)if(this._versionSent){this._peerAddressVerified&&this._sendVerAck();this._verackReceived&&this._finishHandshake()}else this.handshake()}_sendVerAck(){Assert.that(this._peerAddressVerified);const e=BufferUtils.concatTypedArrays(this._channel.peerAddress.peerId.serialize(),this._peerChallengeNonce),t=Signature.create(this._networkConfig.keyPair.privateKey,this._networkConfig.keyPair.publicKey,e);this._channel.verack(this._networkConfig.keyPair.publicKey,t);this._verackSent=!0}_onVerAck(e){Log.v(NetworkAgent,()=>`[VERACK] from ${this._channel.peerAddress}`);if(!this._canAcceptMessage(e))return;if(this._verackReceived){Log.d(NetworkAgent,()=>`Ignoring duplicate verack message from ${this._channel.peerAddress}`);return}this._timers.clearTimeout("verack");if(!e.publicKey.toPeerId().equals(this._channel.peerAddress.peerId)){this._channel.close(CloseType.INVALID_PUBLIC_KEY_IN_VERACK_MESSAGE,"Invalid public key in verack message");return}const t=BufferUtils.concatTypedArrays(this._networkConfig.peerAddress.peerId.serialize(),this._challengeNonce);if(e.signature.verify(e.publicKey,t)){if(!this._peerAddressVerified){this._peerAddressVerified=!0;this._sendVerAck()}this._verackReceived=!0;this._verackSent&&this._finishHandshake()}else this._channel.close(CloseType.INVALID_SIGNATURE_IN_VERACK_MESSAGE,"Invalid signature in verack message")}_finishHandshake(){this._timers.setInterval("connectivity",()=>this._checkConnectivity(),NetworkAgent.CONNECTIVITY_CHECK_INTERVAL);this._timers.setInterval("announce-addr",()=>this._channel.addr([this._networkConfig.peerAddress]),NetworkAgent.ANNOUNCE_ADDR_INTERVAL);this.fire("handshake",this._peer,this);this.requestAddresses()}requestAddresses(e=NetworkAgent.NUM_ADDR_PER_REQUEST){Log.d(Network,()=>`Requesting addresses from ${this._peer.peerAddress}`);this._addressRequest={maxResults:e};let t=this._networkConfig.services.accepted;this._peer.version<2&&(t&=Services.ALL_LEGACY);this._channel.getAddr(this._networkConfig.protocolMask,t,e)}_onAddr(e){if(!this._canAcceptMessage(e))return;const t=1===e.addresses.length&&this._peer.peerAddress.equals(e.addresses[0]);if(!this._addressRequest&&!t)return;const{maxResults:s=NetworkAgent.MAX_ADDR_PER_REQUEST}=this._addressRequest||{};t||(this._addressRequest=null);if(e.addresses.length>NetworkAgent.MAX_ADDR_PER_MESSAGE){Log.w(NetworkAgent,"Rejecting addr message - too many addresses");this._channel.close(CloseType.ADDR_MESSAGE_TOO_LARGE,"addr message too large");return}Log.v(NetworkAgent,()=>`[ADDR] ${e.addresses.length} addresses from ${this._peer.peerAddress}`);const r=e.addresses.slice(0,s);for(const n of r){if(!n.verifySignature()){this._channel.close(CloseType.INVALID_ADDR,"invalid addr");return}if((n.protocol===Protocol.WS||n.protocol===Protocol.WSS)&&!n.globallyReachable()){this._channel.close(CloseType.ADDR_NOT_GLOBALLY_REACHABLE,"addr not globally reachable");return}}this._addresses.add(this._channel,r);t&&(this._peer.peerAddress=r[0]);this.fire("addr",r,this)}_onGetAddr(e){if(!this._canAcceptMessage(e))return;if(!this._getAddrLimit.note()){Log.w(NetworkAgent,"Rejecting getaddr message - rate limit exceeded");return}const t=Math.min(e.maxResults,NetworkAgent.MAX_ADDR_PER_REQUEST),s=this._addresses.query(e.protocolMask,e.serviceMask,t);this._channel.addr(s)}_checkConnectivity(){const e=NumberUtils.randomUint32();if(!this._channel.ping(e)){this._channel.close(CloseType.SENDING_PING_MESSAGE_FAILED,"sending ping message failed");return}const t=Date.now();this._pingTimes.set(e,t);this._channel.lastMessageReceivedAt<t-NetworkAgent.CONNECTIVITY_CHECK_INTERVAL&&this._timers.setTimeout(`ping_${e}`,()=>{this._timers.clearTimeout(`ping_${e}`);this._pingTimes["delete"](e);this._channel.close(CloseType.PING_TIMEOUT,"ping timeout")},NetworkAgent.PING_TIMEOUT)}_onPing(e){this._canAcceptMessage(e)&&this._channel.pong(e.nonce)}_onPong(e){this._timers.clearTimeout(`ping_${e.nonce}`);const t=this._pingTimes.get(e.nonce);if(t){const s=Date.now()-t;s>0&&this.fire("ping-pong",s);this._pingTimes["delete"](e.nonce)}}_onClose(){this._timers.clearAll()}_canAcceptMessage(e){if(!this._versionReceived&&e.type!==Message.Type.VERSION){Log.w(NetworkAgent,`Discarding '${PeerChannel.Event[e.type]||e.type}' message from ${this._channel.peerAddress||this._channel.netAddress}`+" - no version message received previously");return!1}if(this._versionReceived&&!this._verackReceived&&e.type!==Message.Type.VERACK){Log.w(NetworkAgent,`Discarding '${PeerChannel.Event[e.type]||e.type}' message from ${this._channel.peerAddress||this._channel.netAddress}`+" - no verack message received previously");return!1}return!0}get channel(){return this._channel}get peer(){return this._peer}}NetworkAgent.HANDSHAKE_TIMEOUT=4e3;NetworkAgent.PING_TIMEOUT=1e4;NetworkAgent.CONNECTIVITY_CHECK_INTERVAL=6e4;NetworkAgent.ANNOUNCE_ADDR_INTERVAL=6e5;NetworkAgent.VERSION_ATTEMPTS_MAX=10;NetworkAgent.VERSION_RETRY_DELAY=500;NetworkAgent.GETADDR_RATE_LIMIT=3;NetworkAgent.MAX_ADDR_PER_MESSAGE=1e3;NetworkAgent.MAX_ADDR_PER_REQUEST=500;NetworkAgent.NUM_ADDR_PER_REQUEST=200;Class.register(NetworkAgent);class PeerConnectionStatistics{constructor(){this._latencies=[];this._messages=new HashMap}reset(){this._latencies=[];this._messages=new HashMap}addLatency(e){this._latencies.push(e)}addMessage(e){this._messages.put(e.type,this._messages.contains(e.type)?this._messages.get(e.type)+1:1)}getMessageCount(e){return this._messages.contains(e)?this._messages.get(e):0}get latencyMedian(){const e=this._latencies.length;if(0===e)return 0;this._latencies.sort((e,t)=>e-t);let t;return t=e%2==0?Math.round((this._latencies[e/2-1]+this._latencies[e/2])/2):this._latencies[(e-1)/2]}}Class.register(PeerConnectionStatistics);class PeerConnection{static getOutbound(e){const t=new PeerConnection;t._peerAddress=e;t._state=PeerConnectionState.CONNECTING;return t}static getInbound(e){const t=new PeerConnection;t._networkConnection=e;return t}constructor(){this._id=PeerConnection._instanceCount++;this._peerAddress=null;this._networkConnection=null;this._peerChannel=null;this._networkAgent=null;this._peer=null;this._state=PeerConnectionState.NEW;this._score=null;this._establishedSince=null;this._statistics=new PeerConnectionStatistics}get id(){return this._id}get state(){return this._state}get peerAddress(){return this._peerAddress}set peerAddress(e){this._peerAddress=e}get networkConnection(){return this._networkConnection}set networkConnection(e){this._networkConnection=e;this._state=PeerConnectionState.CONNECTED}get peerChannel(){return this._peerChannel}set peerChannel(e){this._peerChannel=e}get networkAgent(){return this._networkAgent}set networkAgent(e){this._networkAgent=e}negotiating(){Assert.that(this._state===PeerConnectionState.CONNECTED);this._state=PeerConnectionState.NEGOTIATING}get peer(){return this._peer}set peer(e){this._peer=e;this._state=PeerConnectionState.ESTABLISHED;this._establishedSince=Date.now();this._networkAgent.on("ping-pong",e=>this._statistics.addLatency(e));this._peerChannel.on("message-log",e=>this._statistics.addMessage(e))}get score(){return this._score}set score(e){this._score=e}get establishedSince(){return this._establishedSince}get ageEstablished(){return Date.now()-this.establishedSince}get statistics(){return this._statistics}close(){this._state=PeerConnectionState.CLOSED;this._networkConnection=null;this._networkAgent=null;this._peerChannel=null;this._peer=null}}PeerConnection._instanceCount=0;Class.register(PeerConnection);class PeerConnectionState{}PeerConnectionState.NEW=1;PeerConnectionState.CONNECTING=2;PeerConnectionState.CONNECTED=3;PeerConnectionState.NEGOTIATING=4;PeerConnectionState.ESTABLISHED=5;PeerConnectionState.CLOSED=6;Class.register(PeerConnectionState);class SignalProcessor{constructor(e,t,s){this._addresses=e;this._networkConfig=t;this._rtcConnector=s;this._forwards=new SignalStore}onSignal(e,t){if(t.ttl>Network.SIGNAL_TTL_INITIAL){e.close(CloseType.INVALID_SIGNAL_TTL,"invalid signal ttl");return}const s=this._networkConfig.peerId;if(t.senderId.equals(s)){Log.d(SignalProcessor,()=>`Received signal from myself to ${t.recipientId} from ${e.peerAddress} (myId: ${s})`);return}if(t.isUnroutable()&&this._forwards.signalForwarded(t.recipientId,t.senderId,t.nonce)){const s=this._addresses.getByPeerId(t.senderId);this._addresses.unroutable(e,s)}if(t.recipientId.equals(s)){if(this._networkConfig.protocol!==Protocol.RTC)return;if(t.hasPayload()&&!t.verifySignature()){Log.d(SignalProcessor,()=>`Discarding signal from ${t.senderId} received via ${e.peerAddress} - invalid signature`);return}if(this._rtcConnector.isValidSignal(t)&&(t.isUnroutable()||t.isTtlExceeded())){const s=this._addresses.getByPeerId(t.senderId);this._addresses.unroutable(e,s)}this._rtcConnector.onSignal(e,t);return}if(t.ttl<=0){Log.d(SignalProcessor,()=>`Discarding signal from ${t.senderId} to ${t.recipientId} - TTL reached`);0===t.flags&&e.signal(t.recipientId,t.senderId,t.nonce,Network.SIGNAL_TTL_INITIAL,SignalMessage.Flag.TTL_EXCEEDED);return}const r=this._addresses.getChannelByPeerId(t.recipientId);if(r)if(r.peerAddress.equals(e.peerAddress)){Log.d(SignalProcessor,()=>`Discarding signal from ${t.senderId} to ${t.recipientId} - shortest route via sending peer`);0===t.flags&&e.signal(t.recipientId,t.senderId,t.nonce,Network.SIGNAL_TTL_INITIAL,SignalMessage.Flag.UNROUTABLE)}else{r.signal(t.senderId,t.recipientId,t.nonce,t.ttl-1,t.flags,t.payload,t.senderPubKey,t.signature);0===t.flags&&this._forwards.add(t.senderId,t.recipientId,t.nonce)}else{Log.d(SignalProcessor,()=>`Failed to forward signal from ${t.senderId} to ${t.recipientId} - no route found`);0===t.flags&&e.signal(t.recipientId,t.senderId,t.nonce,Network.SIGNAL_TTL_INITIAL,SignalMessage.Flag.UNROUTABLE)}}}Class.register(SignalProcessor);class SignalStore{constructor(e=1e3){this._maxSize=e;this._queue=new UniqueQueue;this._store=new HashMap}get length(){return this._queue.length}add(e,t,s){if(this.contains(e,t,s)){const r=new ForwardedSignal(e,t,s);this._store.put(r,Date.now());this._queue.requeue(r);return}if(this.length>=this._maxSize){const e=this._queue.dequeue();this._store.remove(e)}const r=new ForwardedSignal(e,t,s);this._queue.enqueue(r);this._store.put(r,Date.now())}contains(e,t,s){const r=new ForwardedSignal(e,t,s);return this._store.contains(r)}signalForwarded(e,t,s){const r=new ForwardedSignal(e,t,s),n=this._store.get(r);if(!n)return!1;const i=n+ForwardedSignal.SIGNAL_MAX_AGE>Date.now();if(!i){let e;do{e=this._queue.dequeue();this._store.remove(e)}while(this._queue.length>0&&!r.equals(e))}return i}}SignalStore.SIGNAL_MAX_AGE=10;Class.register(SignalStore);class ForwardedSignal{constructor(e,t,s){this._senderId=e;this._recipientId=t;this._nonce=s}equals(e){return e instanceof ForwardedSignal&&this._senderId.equals(e._senderId)&&this._recipientId.equals(e._recipientId)&&this._nonce===e._nonce}hashCode(){return this.toString()}toString(){return`ForwardedSignal{senderId=${this._senderId}, recipientId=${this._recipientId}, nonce=${this._nonce}}`}}Class.register(ForwardedSignal);class ConnectionPool extends Observable{constructor(e,t,s){super();this._addresses=e;this._networkConfig=t;this._blockchain=s;this._connectionsByPeerAddress=new HashMap;this._connectionsByNetAddress=new HashMap;this._connectionsBySubnet=new HashMap;this._bytesSent=0;this._bytesReceived=0;this._wssConnector=new WebSocketConnector(Protocol.WSS,"wss",this._networkConfig);this._wssConnector.on("connection",e=>this._onConnection(e));this._wssConnector.on("error",(e,t)=>this._onConnectError(e,t));this._wsConnector=new WebSocketConnector(Protocol.WS,"ws",this._networkConfig);this._wsConnector.on("connection",e=>this._onConnection(e));this._wsConnector.on("error",(e,t)=>this._onConnectError(e,t));this._rtcConnector=new WebRtcConnector(this._networkConfig);this._rtcConnector.on("connection",e=>this._onConnection(e));this._rtcConnector.on("error",(e,t)=>this._onConnectError(e,t));this._peerCountWs=0;this._peerCountWss=0;this._peerCountRtc=0;this._peerCountDumb=0;this._peerCountFull=0;this._peerCountLight=0;this._peerCountNano=0;this._peerCountOutbound=0;this._peerCountFullWsOutbound=0;this._connectingCount=0;this._inboundCount=0;this._signalProcessor=new SignalProcessor(e,t,this._rtcConnector);this._allowInboundExchange=!1;this._allowInboundConnections=!1;this._bannedIPv4IPs=new HashMap;this._bannedIPv6IPs=new HashMap;setInterval(()=>this._checkUnbanIps(),ConnectionPool.UNBAN_IPS_INTERVAL)}values(){return Array.from(this._connectionsByPeerAddress.values())}valueIterator(){return this._connectionsByPeerAddress.valueIterator()}getConnectionByPeerAddress(e){return this._connectionsByPeerAddress.get(e)}getConnectionsByNetAddress(e){return this._connectionsByNetAddress.get(e)||[]}getConnectionsBySubnet(e){return this._connectionsBySubnet.get(this._getSubnetAddress(e))||[]}getOutboundConnectionsBySubnet(e){return(this._connectionsBySubnet.get(this._getSubnetAddress(e))||[]).filter(e=>e.networkConnection.outbound)}_getSubnetAddress(e){return e.subnet(e.isIPv4()?Network.IPV4_SUBNET_MASK:Network.IPV6_SUBNET_MASK)}_add(e){e.peerAddress&&this._connectionsByPeerAddress.put(e.peerAddress,e)}_remove(e){e.peerAddress&&this._connectionsByPeerAddress.remove(e.peerAddress);e.networkConnection&&e.networkConnection.netAddress&&this._removeNetAddress(e,e.networkConnection.netAddress)}_addNetAddress(e,t){if(t.isPseudo()||!t.reliable)return;this._connectionsByNetAddress.contains(t)?this._connectionsByNetAddress.get(t).push(e):this._connectionsByNetAddress.put(t,[e]);const s=this._getSubnetAddress(t);this._connectionsBySubnet.contains(s)?this._connectionsBySubnet.get(s).push(e):this._connectionsBySubnet.put(s,[e])}_removeNetAddress(e,t){if(t.isPseudo()||!t.reliable)return;if(this._connectionsByNetAddress.contains(t)){const s=this._connectionsByNetAddress.get(t),r=s.indexOf(e);r>=0&&s.splice(r,1);0===s.length&&this._connectionsByNetAddress.remove(t)}const s=this._getSubnetAddress(t);if(this._connectionsBySubnet.contains(s)){const t=this._connectionsBySubnet.get(s),r=t.indexOf(e);r>=0&&t.splice(r,1);0===t.length&&this._connectionsBySubnet.remove(s)}}_checkOutboundConnectionRequest(e){if(null===e)return!1;if(e.protocol!==Protocol.WS&&e.protocol!==Protocol.WSS&&e.protocol!==Protocol.RTC){Log.e(ConnectionPool,`Cannot connect to ${e} - unsupported protocol`);return!1}if(this._addresses.isBanned(e)){Log.e(ConnectionPool,`Connecting to banned address ${e}`);return!1}if(this.getConnectionByPeerAddress(e)){Log.e(ConnectionPool,`Duplicate connection to ${e}`);return!1}if(e.netAddress&&e.netAddress.reliable){if(this.getConnectionsByNetAddress(e.netAddress).length>=Network.PEER_COUNT_PER_IP_MAX){Log.e(ConnectionPool,`connection limit per ip (${Network.PEER_COUNT_PER_IP_MAX}) reached`);return!1}if(this.getOutboundConnectionsBySubnet(e.netAddress).length>=Network.OUTBOUND_PEER_COUNT_PER_SUBNET_MAX){Log.e(ConnectionPool,`connection limit per ip (${Network.OUTBOUND_PEER_COUNT_PER_SUBNET_MAX}) reached`);return!1}}return!0}connectOutbound(e){if(!this._checkOutboundConnectionRequest(e))return!1;const t=PeerConnection.getOutbound(e);this._add(t);let s=!1;if(e.protocol===Protocol.WSS)s=this._wssConnector.connect(e);else if(e.protocol===Protocol.WS)s=this._wsConnector.connect(e);else{const t=this._addresses.getChannelByPeerId(e.peerId);s=this._rtcConnector.connect(e,t)}if(!s){this._remove(t);Log.d(Network,()=>`Outbound attempt not connecting: ${e}`);return!1}this._connectingCount++;return!0}_checkConnection(e){const t=e.networkConnection;if(t.inbound&&!this._allowInboundConnections&&t.protocol!==Protocol.RTC){t.close(CloseType.INBOUND_CONNECTIONS_BLOCKED,"inbound connections are blocked temporarily");return!1}if(t.netAddress&&!t.netAddress.isPseudo()&&t.netAddress.reliable){if(this._isIpBanned(t.netAddress)){t.close(CloseType.IP_BANNED,`connection with banned IP ${t.netAddress}`);return!1}if(!t.netAddress.isPrivate()&&this.getConnectionsByNetAddress(t.netAddress).length>=Network.PEER_COUNT_PER_IP_MAX){t.close(CloseType.CONNECTION_LIMIT_PER_IP,`connection limit per IP (${Network.PEER_COUNT_PER_IP_MAX}) reached`);return!1}if(!t.netAddress.isPrivate()&&this.getConnectionsBySubnet(t.netAddress).length>=Network.INBOUND_PEER_COUNT_PER_SUBNET_MAX){t.close(CloseType.CONNECTION_LIMIT_PER_IP,`connection limit per subnet (${Network.INBOUND_PEER_COUNT_PER_SUBNET_MAX}) reached`);return!1}}if(this.peerCount>=Network.PEER_COUNT_MAX&&!t.outbound&&(!t.inbound||!this._allowInboundExchange)){t.close(CloseType.MAX_PEER_COUNT_REACHED,`max peer count reached (${Network.PEER_COUNT_MAX})`);return!1}return!0}_onConnection(e){let t;if(e.outbound){if(!(t=this.getConnectionByPeerAddress(e.peerAddress))){e.close(CloseType.INVALID_CONNECTION_STATE,`No PeerConnection present for outgoing connection (${e.peerAddress})`);return}if(t.state!==PeerConnectionState.CONNECTING){e.close(CloseType.INVALID_CONNECTION_STATE,`PeerConnection state not CONNECTING, but ${t.state} (${e.peerAddress})`);return}this._connectingCount--;Assert.that(this._connectingCount>=0,"connectingCount < 0")}else{t=PeerConnection.getInbound(e);this._inboundCount++}t.networkConnection=e;e.on("close",(e,s)=>this._onClose(t,e,s));if(!this._checkConnection(t))return;e.netAddress&&!e.netAddress.isPseudo()&&this._addNetAddress(t,e.netAddress);const s=e.inbound?"inbound":"outbound";Log.d(ConnectionPool,()=>`Connection established (${s}) #${e.id} ${e.netAddress||e.peerAddress||"<pending>"}`);this.fire("connection",e);const r=new PeerChannel(e);t.peerChannel=r;const n=new NetworkAgent(this._blockchain,this._addresses,this._networkConfig,r);n.on("version",e=>this._checkHandshake(t,e));n.on("handshake",e=>this._onHandshake(t,e));t.networkAgent=n;n.handshake()}_checkHandshake(e,t){if(this._addresses.isBanned(t.peerAddress)){e.peerChannel.close(CloseType.PEER_BANNED,`connection with banned address ${t.peerAddress} (post version)`);return!1}const s=this.getConnectionByPeerAddress(t.peerAddress);if(s&&s.id!==e.id&&s.state===PeerConnectionState.ESTABLISHED){e.peerChannel.close(CloseType.DUPLICATE_CONNECTION,"duplicate connection (post version)");return!1}if(t.peerAddress.protocol===Protocol.DUMB&&this.peerCountDumb>=Network.PEER_COUNT_DUMB_MAX){e.peerChannel.close(CloseType.CONNECTION_LIMIT_DUMB,`connection limit for dumb peers (${Network.PEER_COUNT_DUMB_MAX}) reached`);return!1}e.negotiating();return!0}_onHandshake(e,t){if(e.networkConnection.inbound){if(this.peerCount>=Network.PEER_COUNT_MAX&&!this._allowInboundExchange){e.peerChannel.close(CloseType.MAX_PEER_COUNT_REACHED,`max peer count reached (${Network.PEER_COUNT_MAX})`);return}const s=this.getConnectionByPeerAddress(t.peerAddress);if(s&&s.id!==e.id)switch(s.state){case PeerConnectionState.CONNECTING:Assert.that(t.peerAddress.protocol===Protocol.WSS||t.peerAddress.protocol===Protocol.WS,"Duplicate connection to non-WS node");Log.d(ConnectionPool,()=>`Aborting connection attempt to ${t.peerAddress}, simultaneous inbound connection succeeded`);t.peerAddress.protocol===Protocol.WSS?this._wssConnector.abort(t.peerAddress):this._wsConnector.abort(t.peerAddress);Assert.that(!this.getConnectionByPeerAddress(t.peerAddress),"PeerConnection not removed");break;case PeerConnectionState.ESTABLISHED:e.peerChannel.close(CloseType.DUPLICATE_CONNECTION,"duplicate connection (post handshake)");return;case PeerConnectionState.NEGOTIATING:if(!(this._networkConfig.peerAddress.peerId.compare(t.peerAddress.peerId)<0)){e.peerChannel.close(CloseType.SIMULTANEOUS_CONNECTION,"simultaneous connection (post handshake) - higher peerId");return}s.peerChannel.close(CloseType.SIMULTANEOUS_CONNECTION,"simultaneous connection (post handshake) - lower peerId");Assert.that(!this.getConnectionByPeerAddress(t.peerAddress),"PeerConnection not removed");break;default:s.peerChannel.close(CloseType.SIMULTANEOUS_CONNECTION,`simultaneous connection (post handshake) - state ${s.state}`);Assert.that(!this.getConnectionByPeerAddress(t.peerAddress),"PeerConnection not removed")}Assert.that(!this.getConnectionByPeerAddress(t.peerAddress),`PeerConnection ${t.peerAddress} already exists`);e.peerAddress=t.peerAddress;this._add(e);this._inboundCount--;Assert.that(this._inboundCount>=0,"inboundCount < 0")}this.peerCount>=Network.PEER_COUNT_MAX&&this.fire("recycling-request");e.peer=t;t.netAddress&&!t.netAddress.isPseudo()&&this.getConnectionsByNetAddress(t.netAddress).indexOf(e)<0&&this._addNetAddress(e,t.netAddress);this._updateConnectedPeerCount(e,1);Network.SIGNALING_ENABLED&&e.peerChannel.on("signal",t=>this._signalProcessor.onSignal(e.peerChannel,t));this._addresses.established(t.channel,t.peerAddress);Log.d(ConnectionPool,()=>`[PEER-JOINED] ${t.peerAddress} ${t.netAddress} (version=${t.version}, services=${t.peerAddress.services}, userAgent=${t.userAgent||"<unknown>"}, headHash=${t.headHash.toBase64()})`);this.fire("peer-joined",t);this.fire("peers-changed")}_onClose(e,t,s){this._bytesSent+=e.networkConnection.bytesSent;this._bytesReceived+=e.networkConnection.bytesReceived;e.peerAddress&&this._addresses.close(e.peerChannel,e.peerAddress,t);this._remove(e);if(e.state===PeerConnectionState.ESTABLISHED){CloseType.isBanningType(t)&&e.peer.netAddress&&this._banIp(e.peer.netAddress);this._updateConnectedPeerCount(e,-1);const r=((e.networkConnection.bytesSent+e.networkConnection.bytesReceived)/1e3).toFixed(2);Log.d(ConnectionPool,()=>`[PEER-LEFT] ${e.peerAddress} ${e.peer.netAddress} `+`(transferred=${r} kB, closeType=${t} ${s})`);this.fire("peer-left",e.peer);this.fire("peers-changed")}else if(e.networkConnection.inbound){this._inboundCount--;Log.d(ConnectionPool,()=>`Inbound connection #${e.networkConnection.id} closed pre-handshake: ${s} (${t})`)}else{Log.d(ConnectionPool,()=>`Connection #${e.networkConnection.id} to ${e.peerAddress} closed pre-handshake: ${s} (${t})`);this.fire("connect-error",e.peerAddress,`${s} (${t})`)}this.fire("close",e,t,s);e.close()}_banIp(e){if(!e.isPseudo()&&e.reliable){Log.w(ConnectionPool,`Banning IP ${e}`);e.isIPv4()?this._bannedIPv4IPs.put(e,Date.now()+ConnectionPool.DEFAULT_BAN_TIME):e.isIPv6()&&this._bannedIPv6IPs.put(e.ip.subarray(0,8),Date.now()+ConnectionPool.DEFAULT_BAN_TIME)}}_isIpBanned(e){if(e.isPseudo())return!1;if(e.isIPv4())return this._bannedIPv4IPs.contains(e);if(e.isIPv6()){const t=e.ip.subarray(0,8);return this._bannedIPv6IPs.contains(t)}return!1}_checkUnbanIps(){const e=Date.now();for(const t of this._bannedIPv4IPs.keys())this._bannedIPv4IPs.get(t)<e&&this._bannedIPv4IPs.remove(t);for(const t of this._bannedIPv6IPs.keys())this._bannedIPv6IPs.get(t)<e&&this._bannedIPv6IPs.remove(t)}_onConnectError(e,t){Log.d(ConnectionPool,()=>`Connection to ${e} failed`+("string"==typeof t?` - ${t}`:""));const s=this.getConnectionByPeerAddress(e);Assert.that(!!s,`PeerAddress not stored ${e}`);if(s.state===PeerConnectionState.CONNECTING){this._remove(s);this._connectingCount--;Assert.that(this._connectingCount>=0,"connectingCount < 0");this._addresses.close(null,e,CloseType.CONNECTION_FAILED);this.fire("connect-error",e,t)}else Log.e(ConnectionPool,`PeerConnection state not CONNECTING, but ${s.state} (${e})`)}_updateConnectedPeerCount(e,t){const s=e.peerAddress;switch(s.protocol){case Protocol.WS:this._peerCountWs+=t;Assert.that(this._peerCountWs>=0,"peerCountWs < 0");break;case Protocol.WSS:this._peerCountWss+=t;Assert.that(this._peerCountWss>=0,"peerCountWs < 0");break;case Protocol.RTC:this._peerCountRtc+=t;Assert.that(this._peerCountRtc>=0,"peerCountRtc < 0");break;case Protocol.DUMB:this._peerCountDumb+=t;Assert.that(this._peerCountDumb>=0,"peerCountDumb < 0");break;default:Log.w(PeerAddressBook,`Unknown protocol ${s.protocol}`)}if(Services.isFullNode(s.services)){this._peerCountFull+=t;Assert.that(this._peerCountFull>=0,"peerCountFull < 0")}else if(Services.isLightNode(s.services)){this._peerCountLight+=t;Assert.that(this._peerCountLight>=0,"peerCountLight < 0")}else{this._peerCountNano+=t;Assert.that(this._peerCountNano>=0,"peerCountNano < 0")}if(e.networkConnection.outbound){this._peerCountOutbound+=t;!Services.isFullNode(s.services)||s.protocol!==Protocol.WSS&&s.protocol!==Protocol.WS||(this._peerCountFullWsOutbound+=t)}}disconnect(e){for(const t of this.valueIterator())t.peerChannel&&t.peerChannel.close(CloseType.MANUAL_NETWORK_DISCONNECT,e||"manual network disconnect")}disconnectWebSocket(){for(const e of this.valueIterator())e.peerChannel&&e.peerAddress&&(e.peerAddress.protocol===Protocol.WSS||e.peerAddress.protocol===Protocol.WS)&&e.peerChannel.close(CloseType.MANUAL_WEBSOCKET_DISCONNECT,"manual websocket disconnect")}get peerCountWs(){return this._peerCountWs}get peerCountWss(){return this._peerCountWss}get peerCountRtc(){return this._peerCountRtc}get peerCountDumb(){return this._peerCountDumb}get peerCount(){return this._peerCountWs+this._peerCountWss+this._peerCountRtc+this._peerCountDumb}get peerCountFull(){return this._peerCountFull}get peerCountLight(){return this._peerCountLight}get peerCountNano(){return this._peerCountNano}get peerCountOutbound(){return this._peerCountOutbound}get peerCountFullWsOutbound(){return this._peerCountFullWsOutbound}get connectingCount(){return this._connectingCount}get count(){return this._connectionsByPeerAddress.length+this._inboundCount}get bytesSent(){let e=this._bytesSent;for(const t of this.valueIterator())t.networkConnection&&(e+=t.networkConnection.bytesSent);return e}get bytesReceived(){let e=this._bytesReceived;for(const t of this.valueIterator())t.networkConnection&&(e+=t.networkConnection.bytesReceived);return e}set allowInboundExchange(e){this._allowInboundExchange=e}get allowInboundConnections(){return this._allowInboundConnections}set allowInboundConnections(e){this._allowInboundConnections=e}}ConnectionPool.DEFAULT_BAN_TIME=6e5;ConnectionPool.UNBAN_IPS_INTERVAL=6e4;Class.register(ConnectionPool);class PeerScorer{constructor(e,t,s){this._networkConfig=e;this._addresses=t;this._connections=s;this._connectionScores=null}pickAddress(){let e,t;switch(this._networkConfig.protocolMask){case Protocol.WSS:e=this._addresses.wssIterator();t=this._addresses.knownWssAddressesCount;break;case Protocol.WS:e=this._addresses.wsIterator();t=this._addresses.knownWsAddressesCount;break;case Protocol.WS|Protocol.WSS:e=IteratorUtils.alternate(this._addresses.wsIterator(),this._addresses.wssIterator());t=this._addresses.knownWsAddressesCount+this._addresses.knownWssAddressesCount;break;case Protocol.RTC:e=this._addresses.rtcIterator();t=this._addresses.knownRtcAddressesCount;break;case Protocol.RTC|Protocol.WS:e=IteratorUtils.alternate(this._addresses.rtcIterator(),this._addresses.wsIterator());t=this._addresses.knownRtcAddressesCount+this._addresses.knownWsAddressesCount;break;case Protocol.RTC|Protocol.WSS:e=IteratorUtils.alternate(this._addresses.rtcIterator(),this._addresses.wssIterator());t=this._addresses.knownRtcAddressesCount+this._addresses.knownWssAddressesCount;break;default:e=this._addresses.iterator();t=this._addresses.knownAddressesCount}const s=(e,t,s,r=!1)=>{let n=0,i=t;t>s&&(i=((n=Math.floor(Math.random()*t))+s)%t);const o=n>i,a=[];let c=-1;for(const h of e){c++;if(!o&&c<n)continue;if(!o&&c>=i)break;if(o&&c>=i&&c<n)continue;const e=this._scoreAddress(h,r);if(e>=0){a.push({score:e,addressState:h});if(a.length>=s)break}}return a};let r=s(e,t,1e3);if(0===r.length&&this.needsGoodPeers()){switch(this._networkConfig.protocolMask){case Protocol.WSS:e=this._addresses.wssIterator();break;case Protocol.WS:e=this._addresses.wsIterator();break;case Protocol.WS|Protocol.WSS:e=IteratorUtils.alternate(this._addresses.wsIterator(),this._addresses.wssIterator());break;case Protocol.RTC:e=this._addresses.rtcIterator();break;case Protocol.RTC|Protocol.WS:e=IteratorUtils.alternate(this._addresses.rtcIterator(),this._addresses.wsIterator());break;case Protocol.RTC|Protocol.WSS:e=IteratorUtils.alternate(this._addresses.rtcIterator(),this._addresses.wssIterator());break;default:e=this._addresses.iterator()}r=s(e,t,1e3,!0)}if(0===r.length)return null;const n=r.sort((e,t)=>t.score-e.score).slice(0,PeerScorer.PICK_SELECTION_SIZE);return ArrayUtils.randomElement(n).addressState.peerAddress}_scoreAddress(e,t=!1){const s=e.peerAddress;if(!this._networkConfig.canConnect(s.protocol))return-1;if(!Services.providesServices(s.services,this._networkConfig.services.accepted))return-1;if(s.exceedsAge())return-1;if(this._connections.getConnectionByPeerAddress(s))return-1;if(this.needsGoodPeers()&&!this.isGoodPeer(s)&&!t)return-1;switch(e.state){case PeerAddressState.BANNED:return-1;case PeerAddressState.NEW:case PeerAddressState.TRIED:return 1;case PeerAddressState.FAILED:return 1*(1-(e.failedAttempts+1)/e.maxFailedAttempts);default:return-1}}isGoodPeerSet(){return!this.needsGoodPeers()&&!this.needsMorePeers()}needsGoodPeers(){return this._connections.peerCountFullWsOutbound<PeerScorer.PEER_COUNT_MIN_FULL_WS_OUTBOUND}needsMorePeers(){return this._connections.peerCountOutbound<PeerScorer.PEER_COUNT_MIN_OUTBOUND}isGoodPeer(e){return Services.isFullNode(e.services)&&(e.protocol===Protocol.WS||e.protocol===Protocol.WSS)}scoreConnections(){const e=[];for(const t of this._connections.valueIterator())if(t.state===PeerConnectionState.ESTABLISHED){if(t.ageEstablished>PeerScorer._getMinAge(t.peerAddress)){t.score=this._scoreConnection(t);e.push(t)}t.statistics.reset()}this._connectionScores=e.sort((e,t)=>t.score-e.score)}recycleConnections(e,t,s){if(this._connectionScores)for(;e>0&&this._connectionScores.length>0;){const r=this._connectionScores.pop();if(r.state===PeerConnectionState.ESTABLISHED){r.peerChannel.close(t,`${s}`);e--}}}_scoreConnection(e){const t=this._scoreConnectionAge(e),s=e.networkConnection.inbound?0:1,r=e.peerAddress,n=Services.isFullNode(r.services)?1:Services.isLightNode(r.services)?.5:0;let i;switch(r.protocol){case Protocol.WS:case Protocol.WSS:i=.6;break;case Protocol.RTC:i=.3;break;case Protocol.DUMB:default:i=0}if(r.protocol===Protocol.WS||r.protocol===Protocol.WSS){((this._connections.peerCountWs+this._connections.peerCountWss)/this._connections.peerCount<PeerScorer.BEST_PROTOCOL_WS_DISTRIBUTION||this._connections.peerCountFullWsOutbound<=PeerScorer.PEER_COUNT_MIN_FULL_WS_OUTBOUND)&&(i=1)}const o=e.statistics.latencyMedian;let a=0;o>0&&o<NetworkAgent.PING_TIMEOUT&&(a=1-o/NetworkAgent.PING_TIMEOUT);return.15*t+.25*s+.2*n+.2*i+.2*a}_scoreConnectionAge(e){const t=(e,t,s)=>Math.max(Math.min(1-(e-t)/s,1),0),s=e.ageEstablished,r=e.peerAddress.services;return Services.isFullNode(r)?s/(2*PeerScorer.BEST_AGE_FULL)+.5:Services.isLightNode(r)?t(s,PeerScorer.BEST_AGE_LIGHT,PeerScorer.MAX_AGE_LIGHT):t(s,PeerScorer.BEST_AGE_NANO,PeerScorer.MAX_AGE_NANO)}static _getMinAge(e){return Services.isFullNode(e.services)?PeerScorer.MIN_AGE_FULL:Services.isLightNode(e.services)?PeerScorer.MIN_AGE_LIGHT:PeerScorer.MIN_AGE_NANO}get lowestConnectionScore(){if(!this._connectionScores)return null;for(;this._connectionScores.length>0&&this._connectionScores[this._connectionScores.length-1].state!==PeerConnectionState.ESTABLISHED;)this._connectionScores.pop();return this._connectionScores.length>0?this._connectionScores[this._connectionScores.length-1].score:null}get connectionScores(){return this._connectionScores}}PeerScorer.PEER_COUNT_MIN_FULL_WS_OUTBOUND=PlatformUtils.isNodeJs()?12:3;PeerScorer.PEER_COUNT_MIN_OUTBOUND=PlatformUtils.isNodeJs()?12:6;PeerScorer.PICK_SELECTION_SIZE=100;PeerScorer.MIN_AGE_FULL=3e5;PeerScorer.BEST_AGE_FULL=864e5;PeerScorer.MIN_AGE_LIGHT=12e4;PeerScorer.BEST_AGE_LIGHT=9e5;PeerScorer.MAX_AGE_LIGHT=216e5;PeerScorer.MIN_AGE_NANO=6e4;PeerScorer.BEST_AGE_NANO=3e5;PeerScorer.MAX_AGE_NANO=18e5;PeerScorer.BEST_PROTOCOL_WS_DISTRIBUTION=.15;Class.register(PeerScorer);class NetworkConfig{static getDefault(){return PlatformUtils.supportsWebRTC()?new RtcNetworkConfig:new DumbNetworkConfig}constructor(e){this._protocolMask=e;this._keyPair=null;this._peerId=null;this._services=null;this._appAgent=null}async initPersistent(){const e=await PeerKeyStore.getPersistent();await this._init(e)}async initVolatile(){const e=PeerKeyStore.createVolatile();await this._init(e)}async _init(e){if(this._keyPair)return;let t=await e.get("keys");if(!t){t=KeyPair.generate();await e.put("keys",t)}this._keyPair=t;this._peerId=t.publicKey.toPeerId()}get protocol(){throw new Error("Unimplemented")}get protocolMask(){return this._protocolMask}get keyPair(){return this._keyPair}get publicKey(){return this._keyPair.publicKey}get peerId(){return this._peerId}get services(){return this._services}set services(e){this._services=e}get peerAddress(){throw new Error("Not implemented")}canConnect(e){return 0!=(e&this._protocolMask)}get appAgent(){return this._appAgent}set appAgent(e){this._appAgent=e}}Class.register(NetworkConfig);class WsNetworkConfig extends NetworkConfig{constructor(e,t,s){super(Protocol.WS|Protocol.WSS);this._host=e;this._port=t;this._reverseProxy=s}get protocol(){return Protocol.WS}get port(){return this._port}get reverseProxy(){return this._reverseProxy}get peerAddress(){if(!this._services||!this._keyPair)throw new Error("PeerAddress is not configured.");const e=this._reverseProxy.enabled?this._reverseProxy.port:this._port,t=new WsPeerAddress(this._services.provided,Date.now(),NetAddress.UNSPECIFIED,this.publicKey,0,this._host,e);if(!t.globallyReachable())throw new Error("PeerAddress not globally reachable.");t.signature=Signature.create(this._keyPair.privateKey,this.publicKey,t.serializeContent());return t}get secure(){return!1}}Class.register(WsNetworkConfig);class WssNetworkConfig extends WsNetworkConfig{constructor(e,t,s,r,n){super(e,t,n);this._key=s;this._cert=r;this._ssl={key:this._key,cert:this._cert}}get protocol(){return Protocol.WSS}get ssl(){return this._ssl}get peerAddress(){if(!this._services||!this._keyPair)throw new Error("PeerAddress is not configured.");const e=this._reverseProxy.enabled?this._reverseProxy.port:this._port,t=new WssPeerAddress(this._services.provided,Date.now(),NetAddress.UNSPECIFIED,this.publicKey,0,this._host,e);if(!t.globallyReachable())throw new Error("PeerAddress not globally reachable.");t.signature=Signature.create(this._keyPair.privateKey,this.publicKey,t.serializeContent());return t}get secure(){return!0}}Class.register(WssNetworkConfig);class RtcNetworkConfig extends NetworkConfig{constructor(){super((PlatformUtils.supportsWS()?Protocol.WS|Protocol.WSS:Protocol.WSS)|Protocol.RTC);this._rtcConfig={iceServers:[{urls:"stun:stun.l.google.com:19302"}]}}get protocol(){return Protocol.RTC}get rtcConfig(){return this._rtcConfig}get peerAddress(){if(!this._services||!this._keyPair)throw new Error("PeerAddress is not configured.");const e=new RtcPeerAddress(this._services.provided,Date.now(),NetAddress.UNSPECIFIED,this.publicKey,0);e.signature=Signature.create(this._keyPair.privateKey,this.publicKey,e.serializeContent());return e}}Class.register(RtcNetworkConfig);class DumbNetworkConfig extends NetworkConfig{constructor(){super(PlatformUtils.supportsWS()?Protocol.WS|Protocol.WSS:Protocol.WSS)}get protocol(){return Protocol.DUMB}get peerAddress(){if(!this._services||!this._keyPair)throw new Error("PeerAddress is not configured.");const e=new DumbPeerAddress(this._services.provided,Date.now(),NetAddress.UNSPECIFIED,this.publicKey,0);e.signature=Signature.create(this._keyPair.privateKey,this.publicKey,e.serializeContent());return e}}Class.register(DumbNetworkConfig);class Network extends Observable{constructor(e,t,s){super();this._blockchain=e;this._networkConfig=t;this._time=s;this._autoConnect=!1;this._backoff=Network.CONNECT_BACKOFF_INITIAL;this._backedOff=!1;this._addresses=new PeerAddressBook(this._networkConfig);this._addresses.on("seeded",()=>this._checkPeerCount());this._addresses.on("added",()=>setTimeout(this._checkPeerCount.bind(this),Network.CONNECT_THROTTLE));this._connections=new ConnectionPool(this._addresses,t,e);this._connections.on("peer-joined",e=>this._onPeerJoined(e));this._connections.on("peer-left",e=>this._onPeerLeft(e));this._connections.on("peers-changed",()=>this._onPeersChanged());this._connections.on("recycling-request",()=>this._onRecyclingRequest());this._connections.on("connect-error",()=>setTimeout(this._checkPeerCount.bind(this),Network.CONNECT_THROTTLE));this._scorer=new PeerScorer(this._networkConfig,this._addresses,this._connections);this._houseKeepingIntervalId=null;this._timers=new Timers}connect(){this._autoConnect=!0;this._houseKeepingIntervalId=setInterval(()=>this._housekeeping(),Network.HOUSEKEEPING_INTERVAL);this._checkPeerCount()}disconnect(e){this._autoConnect=!1;clearInterval(this._houseKeepingIntervalId);this._connections.disconnect(e);this._connections.allowInboundConnections=!1}disconnectWebSocket(){this._autoConnect=!1;this._connections.disconnectWebSocket()}_onPeerJoined(e){this._updateTimeOffset();this.fire("peer-joined",e)}_onPeerLeft(e){this._updateTimeOffset();this.fire("peer-left",e)}_onPeersChanged(){setTimeout(this._checkPeerCount.bind(this),Network.CONNECT_THROTTLE);this.fire("peers-changed")}_onRecyclingRequest(){this._scorer.recycleConnections(1,CloseType.PEER_CONNECTION_RECYCLED_INBOUND_EXCHANGE,"Peer connection recycled inbound exchange");this._connections.allowInboundExchange=null!==this._scorer.lowestConnectionScore&&this._scorer.lowestConnectionScore<Network.SCORE_INBOUND_EXCHANGE}_checkPeerCount(){if(this._autoConnect&&this._addresses.seeded&&!this._scorer.isGoodPeerSet()&&this._connections.connectingCount<Network.CONNECTING_COUNT_MAX){const e=this._scorer.pickAddress(),t=this._scorer.needsGoodPeers()&&!this._scorer.needsMorePeers();if(!e||t&&!this._scorer.isGoodPeer(e)){if(!this._backedOff){this._backedOff=!0;const e=this._backoff;this._backoff=Math.min(Network.CONNECT_BACKOFF_MAX,2*e);setTimeout(()=>{this._backedOff=!1;this._checkPeerCount()},e);if(0===this._connections.count){this.fire("disconnected");this._connections.allowInboundConnections=!0}}return}if(!this._connections.connectOutbound(e)){this._addresses.close(null,e,CloseType.CONNECTION_FAILED);setTimeout(()=>this._checkPeerCount(),Network.CONNECT_THROTTLE)}}this._backoff=Network.CONNECT_BACKOFF_INITIAL}_updateTimeOffset(){const e=this._connections.values(),t=[0];e.forEach(e=>{e.state===PeerConnectionState.ESTABLISHED&&t.push(e.networkAgent.peer.timeOffset)});const s=t.length;t.sort((e,t)=>e-t);let r;r=s%2==0?Math.round((t[s/2-1]+t[s/2])/2):t[(s-1)/2];this._time.offset=Math.max(Math.min(r,Network.TIME_OFFSET_MAX),-Network.TIME_OFFSET_MAX)}_housekeeping(){this._scorer.scoreConnections();if(this.peerCount>Network.PEER_COUNT_RECYCLING_ACTIVE){const e=(this.peerCount-Network.PEER_COUNT_RECYCLING_ACTIVE)*(Network.RECYCLING_PERCENTAGE_MAX-Network.RECYCLING_PERCENTAGE_MIN)/(Network.PEER_COUNT_MAX-Network.PEER_COUNT_RECYCLING_ACTIVE)+Network.RECYCLING_PERCENTAGE_MIN,t=Math.ceil(this.peerCount*e);this._scorer.recycleConnections(t,CloseType.PEER_CONNECTION_RECYCLED,"Peer connection recycled")}this._connections.allowInboundExchange=null!==this._scorer.lowestConnectionScore&&this._scorer.lowestConnectionScore<Network.SCORE_INBOUND_EXCHANGE;this._refreshAddresses()}_refreshAddresses(){if(this._scorer.connectionScores&&this._scorer.connectionScores.length>0){const e=Math.min(2*(this._connections.peerCountWs+this._connections.peerCountWss),Network.ADDRESS_REQUEST_CUTOFF),t=Math.min(this._scorer.connectionScores.length,e);for(let s=0;s<Math.min(Network.ADDRESS_REQUEST_PEERS,this._scorer.connectionScores.length);s++){const e=Math.floor(Math.random()*t),s=this._scorer.connectionScores[e];Log.v(Network,()=>`Requesting addresses from ${s.peerAddress} (score idx ${e})`);s.networkAgent.requestAddresses()}}else{const e=Math.floor(Math.random()*Math.min(this._connections.count,10));let t,s=0;for(const r of this._connections.valueIterator()){r.state===PeerConnectionState.ESTABLISHED&&(t=r);if(s>=e&&t)break;s++}if(t){Log.v(Network,()=>`Requesting addresses from ${t.peerAddress} (rand idx ${e})`);t.networkAgent.requestAddresses()}}}get time(){return this._time}get peerCount(){return this._connections.peerCount}get peerCountWebSocket(){return this._connections.peerCountWs}get peerCountWebSocketSecure(){return this._connections.peerCountWss}get peerCountWebRtc(){return this._connections.peerCountRtc}get peerCountDumb(){return this._connections.peerCountDumb}get peerCountConnecting(){return this._connections.connectingCount}get knownAddressesCount(){return this._addresses.knownAddressesCount}get bytesSent(){return this._connections.bytesSent}get bytesReceived(){return this._connections.bytesReceived}get allowInboundConnections(){return this._connections.allowInboundConnections}set allowInboundConnections(e){this._connections.allowInboundConnections=e}get addresses(){return this._addresses}get connections(){return this._connections}get config(){return this._networkConfig}}Network.PEER_COUNT_MAX=PlatformUtils.isBrowser()?12:4e3;Network.INBOUND_PEER_COUNT_PER_SUBNET_MAX=PlatformUtils.isBrowser()?2:100;Network.OUTBOUND_PEER_COUNT_PER_SUBNET_MAX=2;Network.PEER_COUNT_PER_IP_MAX=PlatformUtils.isBrowser()?1:10;Network.PEER_COUNT_DUMB_MAX=1e3;Network.IPV4_SUBNET_MASK=24;Network.IPV6_SUBNET_MASK=96;Network.PEER_COUNT_RECYCLING_ACTIVE=PlatformUtils.isBrowser()?5:1e3;Network.RECYCLING_PERCENTAGE_MIN=.01;Network.RECYCLING_PERCENTAGE_MAX=.2;Network.CONNECTING_COUNT_MAX=2;Network.SIGNAL_TTL_INITIAL=3;Network.CONNECT_BACKOFF_INITIAL=2e3;Network.CONNECT_BACKOFF_MAX=6e5;Network.TIME_OFFSET_MAX=6e5;Network.HOUSEKEEPING_INTERVAL=3e5;Network.SCORE_INBOUND_EXCHANGE=.5;Network.CONNECT_THROTTLE=500;Network.ADDRESS_REQUEST_CUTOFF=250;Network.ADDRESS_REQUEST_PEERS=2;Network.SIGNALING_ENABLED=1;Class.register(Network);class NetUtils{static isPrivateIP(e){e instanceof Uint8Array||(e=NetUtils.ipToBytes(e));if(NetUtils.isLocalIP(e))return!0;if(NetUtils.isIPv4Address(e)){for(const t of NetUtils.IPv4_PRIVATE_NETWORK)if(NetUtils.isIPv4inSubnet(e,t))return!0;return!1}if(NetUtils.isIPv6Address(e))return 252==(254&e[0])||254===e[0]&&128==(192&e[1]);throw new Error(`Malformed IP address ${e}`)}static isLocalIP(e){e instanceof Uint8Array||(e=NetUtils.ipToBytes(e));if(e.length===NetUtils.IPv4_LENGTH)return 127===e[0]&&0===e[1]&&0===e[2]&&1===e[3];if(e.length===NetUtils.IPv6_LENGTH){for(let t=0;t<NetUtils.IPv6_LENGTH-1;t++)if(0!==e[t])return!1;return 1===e[NetUtils.IPv6_LENGTH-1]}return!1}static isIPv4inSubnet(e,t){e instanceof Uint8Array||(e=NetUtils.ipToBytes(e));let[s,r]=t.split("/");r=-1<<32-parseInt(r);return(NetUtils._IPv4toLong(e)&r)===NetUtils._IPv4toLong(s)}static isIPv4Address(e){if(e instanceof Uint8Array)return e.length===NetUtils.IPv4_LENGTH;const t=e.match(/^(\d+)\.(\d+)\.(\d+)\.(\d+)$/);return!!t&&parseInt(t[1])<=255&&parseInt(t[2])<=255&&parseInt(t[3])<=255&&parseInt(t[4])<=255}static isIPv6Address(e){if(e instanceof Uint8Array)return e.length===NetUtils.IPv6_LENGTH;const t=e.toLowerCase().split(":");if(t.length>8||t.length<3)return!1;const s=NetUtils.isIPv4Address(t[t.length-1]);let r=!1;for(let n=0;n<t.length;++n){if(!(/^[a-f0-9]{0,4}$/.test(t[n])||n===t.length-1&&s&&t.length<8))return!1;if(0===t[n].length&&n>0&&n<t.length-1){if(r)return!1;r=!0}}if(s)for(let n=0;n<t.length-2;++n)if(!/^0{0,4}$/.test(t[n]))return!1;return 0===t[0].length?0===t[1].length:0===t[t.length-1].length?0===t[t.length-2].length:s&&t.length<7?r:!(t.length<8)||r}static hostGloballyReachable(e){return!NetUtils.isIPv4Address(e)&&!NetUtils.isIPv6Address(e)&&!!e.match(/.+\..+$/)}static _IPv4toLong(e){e instanceof Uint8Array||(e=NetUtils.ipToBytes(e));return(e[0]<<24)+(e[1]<<16)+(e[2]<<8)+e[3]}static _IPv4toIPv6(e){let t=e.split(".");t=t.map(e=>parseInt(e));const s=[];for(let r=0;r<4;r++)s.push(("00"+t[r].toString(16)).slice(-2));return`${s[0]}${s[1]}:${s[2]}${s[3]}`}static ipToBytes(e){if(NetUtils.isIPv4Address(e)){const t=e.split(".");return new Uint8Array(t.map(e=>parseInt(e)))}if(NetUtils.isIPv6Address(e)){let t=e.toLowerCase().split(":");if(NetUtils.isIPv4Address(t[t.length-1]))return NetUtils.ipToBytes(t[t.length-1]);t=(t=NetUtils._extendIPv6(t)).map(e=>parseInt(e,16));const s=[];for(let e=0;e<8;e++){s.push(t[e]>>8);s.push(255&t[e])}return new Uint8Array(s)}throw new Error(`Malformed IP address ${e}`)}static bytesToIp(e){if(NetUtils.isIPv4Address(e))return e.join(".");if(NetUtils.isIPv6Address(e)){const t=Array.from(e,e=>("00"+e.toString(16)).slice(-2)),s=[];for(let e=0;e<8;e++)s.push(t[2*e]+t[2*e+1]);return s.join(":")}throw new Error(`Malformed IP address ${e}`)}static _extendIPv6(e){if(NetUtils.isIPv4Address(e[e.length-1])){const t=e[e.length-1],s=NetUtils._IPv4toIPv6(t);ip=ip.replace(t,s);e=ip.toLowerCase().split(":")}let t=e.indexOf("");if(t>=0){e[t]="0";for(let s=e.length;s<8;s++)e.splice(t,0,"0")}t=e.indexOf("");for(;t>=0;){e[t]="0";t=e.indexOf("")}return e}static ipToSubnet(e,t){let s=!1;if(!(e instanceof Uint8Array)){e=NetUtils.ipToBytes(e);s=!0}const r=[];for(let i=0;i<e.byteLength;i++){const s=Math.min(t,8);r.push(e[i]&256-Math.pow(2,8-s));t-=s}const n=new Uint8Array(r);return s?NetUtils.bytesToIp(n):n}}NetUtils.IPv4_LENGTH=4;NetUtils.IPv6_LENGTH=16;NetUtils.IPv4_PRIVATE_NETWORK=["10.0.0.0/8","172.16.0.0/12","192.168.0.0/16","100.64.0.0/10","169.254.0.0/16"];Class.register(NetUtils);class PeerKeyStore{static async getPersistent(){if(!PeerKeyStore._instance){const e=new JDB.JungleDB("peer-key",PeerKeyStore.VERSION,{maxDbSize:PeerKeyStore.INITIAL_DB_SIZE});e.createObjectStore(PeerKeyStore.KEY_DATABASE,{codec:new PeerKeyStoreCodec});await e.connect();PeerKeyStore._instance=new PeerKeyStore(e.getObjectStore(PeerKeyStore.KEY_DATABASE))}return PeerKeyStore._instance}static createVolatile(){const e=JDB.JungleDB.createVolatileObjectStore();return new PeerKeyStore(e)}constructor(e){this._store=e}get(e){return this._store.get(e)}put(e,t){return this._store.put(e,t)}}PeerKeyStore._instance=null;PeerKeyStore.VERSION=2;PeerKeyStore.KEY_DATABASE="keys";PeerKeyStore.INITIAL_DB_SIZE=10485760;Class.register(PeerKeyStore);class PeerKeyStoreCodec{encode(e){return e.serialize()}decode(e,t){return KeyPair.unserialize(new SerialBuffer(e))}get leveldbValueEncoding(){return"binary"}get lmdbValueEncoding(){return JDB.JungleDB.BINARY_ENCODING}}class Peer{constructor(e,t,s,r,n){this._channel=e;this._version=t;this._headHash=s;this._head=null;this._timeOffset=r;this._userAgent=n;this._setNetAddress()}_setNetAddress(){if(this.channel.netAddress){this.peerAddress.netAddress&&!this.peerAddress.netAddress.equals(this.channel.netAddress)&&Log.w(Peer,`Got different netAddress ${this.channel.netAddress} for ${this.peerAddress} `+`- advertised was ${this.peerAddress.netAddress}`);this.channel.netAddress.isPrivate()||(this.peerAddress.netAddress=this.channel.netAddress)}else this.channel.peerAddress.netAddress?this.channel.netAddress=this.channel.peerAddress.netAddress:this.channel.netAddress=NetAddress.UNKNOWN}get channel(){return this._channel}get version(){return this._version}get headHash(){return this._headHash}get head(){return this._head}set head(e){this._head=e;this._headHash=e.hash()}get timeOffset(){return this._timeOffset}get id(){return this._channel.id}get peerAddress(){return this._channel.peerAddress}set peerAddress(e){this._channel.peerAddress=e}get netAddress(){return this._channel.netAddress}get userAgent(){return this._userAgent}equals(e){return e instanceof Peer&&this._channel.equals(e.channel)}hashCode(){return this._channel.hashCode()}toString(){return`Peer{version=${this._version}, headHash=${this._headHash}, `+`peerAddress=${this.peerAddress}, netAddress=${this.netAddress}}`}}Class.register(Peer);class Miner extends Observable{constructor(e,t,s,r,n,i=new Uint8Array(0)){super();this._blockchain=e;this._accounts=t;this._mempool=s;this._time=r;this._producer=new BlockProducer(e,t,s,r);this._address=n;this._extraData=i;this._hashCount=0;this._lastHashrate=0;this._hashrateWorker=null;this._hashrate=0;this._lastHashCounts=[];this._totalHashCount=0;this._lastElapsed=[];this._totalElapsed=0;this._workerPool=new MinerWorkerPool;const o=PlatformUtils.hardwareConcurrency;this._cores=o;this.threads=Math.ceil(o/2);1===o&&(this.throttleAfter=2);this._workerPool.on("share",e=>this.onWorkerShare(e));this._workerPool.on("no-share",e=>this.onWorkerShare(e));this._mempoolChanged=!1;this._restarting=!1;this._lastRestart=0;this._submittingBlock=!1;this._shareCompact=0;this._shareCompactSet=!1;this._numBlocksMined=0;this._activeConfigChanges=!1;this._pendingConfigChanges=!1;if(this._mempool){this._mempool.on("transactions-ready",()=>this._startWork());this._mempool.on("transaction-added",()=>this._mempoolChanged=!0)}}startWork(){if(!this.working){this._hashCount=0;this._lastElapsed=[];this._lastHashCounts=[];this._totalHashCount=0;this._totalElapsed=0;this._lastHashrate=Date.now();this._hashrateWorker=setInterval(()=>this._updateHashrate(),1e3);this._retry=0;this.fire("start",this);this._startWork()["catch"](Log.w.tag(Miner))}}async _startWork(){if(this.working&&!this._restarting)try{this._lastRestart=Date.now();this._restarting=!0;this._mempoolChanged=!1;this._retry=0;const t=await this.getNextBlock();if(null===t){this._stopWork();return}t.isFull()?Log.d(Miner,`Starting work on block #${t.header.height} / ${t.minerAddr.toUserFriendlyAddress()} / ${BufferUtils.toBase64(t.body.extraData)} with ${t.transactionCount} transactions (${this._hashrate} H/s)`):Log.d(Miner,`Starting work on block #${t.header.height} from pool (${this._hashrate} H/s)`);this._workerPool.startMiningOnBlock(t,this._shareCompactSet?this._shareCompact:undefined)["catch"](Log.w.tag(Miner))}catch(e){Log.e(Miner,e);Log.w(Miner,"Failed to start work, retrying in 100ms");this._stopWork();setTimeout(()=>this.startWork(),100)}finally{this._restarting=!1}}async onWorkerShare(e){this._hashCount+=this._workerPool.noncesPerRun;if(e.block&&e.block.prevHash.equals(this._blockchain.headHash)){Log.d(Miner,()=>`Received share: ${e.nonce} / ${e.hash.toHex()}`);if(!this._submittingBlock){e.block.header.nonce=e.nonce;let t=!1;if(e.block.isFull()&&BlockUtils.isProofOfWork(e.hash,e.block.target)){this._submittingBlock=!0;if(await e.block.header.verifyProofOfWork()){this._numBlocksMined++;t=!0;this.fire("block-mined",e.block,this);if(await this._blockchain.pushBlock(e.block)<0){this._submittingBlock=!1;this._startWork()["catch"](Log.w.tag(Miner));return}this._submittingBlock=!1}else Log.d(Miner,`Ignoring invalid share: ${await e.block.header.pow()}`)}this.fire("share",e.block,t,this)}}this._mempoolChanged&&this._lastRestart+Miner.MIN_TIME_ON_BLOCK<Date.now()&&this._startWork()["catch"](Log.w.tag(Miner))}async getNextBlock(e=this._address,t=this._extraData){this._retry++;try{return this._producer.getNextBlock(e,t)}catch(s){if(this._retry<=3)return this.getNextBlock(e,t);throw s}}stopWork(){this._stopWork()}_stopWork(){if(this.working){clearInterval(this._hashrateWorker);this._hashrateWorker=null;this._hashrate=0;this._lastElapsed=[];this._lastHashCounts=[];this._totalHashCount=0;this._totalElapsed=0;this._workerPool.stop();this.fire("stop",this);Log.d(Miner,"Stopped work")}}_updateHashrate(){const e=(Date.now()-this._lastHashrate)/1e3,t=this._hashCount;this._hashCount=0;this._lastHashrate=Date.now();this._lastElapsed.push(e);this._lastHashCounts.push(t);this._totalElapsed+=e;this._totalHashCount+=t;if(this._lastElapsed.length>Miner.MOVING_AVERAGE_MAX_SIZE){const e=this._lastElapsed.shift(),t=this._lastHashCounts.shift();this._totalElapsed-=e;this._totalHashCount-=t}this._hashrate=Math.round(this._totalHashCount/this._totalElapsed);this.fire("hashrate-changed",this._hashrate,this)}startConfigChanges(){this._activeConfigChanges=!0;this._pendingConfigChanges=!1}finishConfigChanges(){this._pendingConfigChanges&&this._startWork()["catch"](Log.w.tag(Miner));this._activeConfigChanges=!1}get address(){return this._address}set address(e){if(e&&!e.equals(this._address)){this._address=e;this._activeConfigChanges?this._pendingConfigChanges=!0:this._startWork()["catch"](Log.w.tag(Miner))}}get working(){return!!this._hashrateWorker}get hashrate(){return this._hashrate}get threads(){return this._workerPool.poolSize}set threads(e){this._workerPool.poolSize=e}get throttleWait(){return this._workerPool.cycleWait}set throttleWait(e){this._workerPool.cycleWait=e}get throttleAfter(){return this._workerPool.runsPerCycle}set throttleAfter(e){this._workerPool.runsPerCycle=e}get extraData(){return this._extraData}set extraData(e){if(!BufferUtils.equals(e,this._extraData)){this._extraData=e;this._activeConfigChanges?this._pendingConfigChanges=!0:this._startWork()["catch"](Log.w.tag(Miner))}}get shareCompact(){return this._shareCompactSet?this._shareCompact:undefined}set shareCompact(e){if(e){this._shareCompact=e;this._shareCompactSet=!0}else this._shareCompactSet=!1}get numBlocksMined(){return this._numBlocksMined}get totalCores(){return this._cores}}Miner.MIN_TIME_ON_BLOCK=1e4;Miner.MOVING_AVERAGE_MAX_SIZE=10;Class.register(Miner);class BasePoolMiner extends Miner{constructor(e,t,s,r,n,i,o,a,c=new Uint8Array(0)){super(t,s,r,n,i,c);this._ourAddress=i;this._ourExtraData=c;this._ws=null;this._deviceId=o;this._deviceData=a;this.mode=e;this.connectionState=BasePoolMiner.ConnectionState.CLOSED;this._reconnectTimeout=null;this._exponentialBackoffReconnect=BasePoolMiner.RECONNECT_TIMEOUT}requestPayout(){this._send({message:"payout"})}_send(e){if(this._ws)try{this._ws.send(JSON.stringify(e))}catch(t){Log.w(BasePoolMiner,"Error sending:",t.message||t)}}connect(e,t){if(this._ws)throw new Error("Call disconnect() first");this._host=e;this._port=t;const s=this._ws=new WebSocket(`wss://${e}:${t}`);this._ws.onopen=(()=>this._onOpen(s));this._ws.onerror=(e=>this._onError(s,e));this._ws.onmessage=(e=>this._onMessage(s,e.data));this._ws.onclose=(e=>this._onClose(s,e));this._changeConnectionState(BasePoolMiner.ConnectionState.CONNECTING)}_onOpen(e){e!==this._ws?e.close():this._register()}_register(){this._send({message:"register",mode:this.mode,address:this._ourAddress.toUserFriendlyAddress(),deviceId:this._deviceId,deviceData:this._deviceData,genesisHash:BufferUtils.toBase64(GenesisConfig.GENESIS_HASH.serialize())})}_onError(e,t){Log.d(BasePoolMiner,"WebSocket connection errored",t.message||t);e===this._ws&&this._timeoutReconnect();try{e.close()}catch(s){Log.w(BasePoolMiner,s.message||s)}}_onClose(e,t){Log.d(BasePoolMiner,"WebSocket connection closed",t.message||t);if(e===this._ws){this._changeConnectionState(BasePoolMiner.ConnectionState.CLOSED);Log.w(BasePoolMiner,"Disconnected from pool");this._timeoutReconnect()}}_timeoutReconnect(){this.disconnect();this._reconnectTimeout=setTimeout(()=>{this._ws||this.connect(this._host,this._port)},this._exponentialBackoffReconnect);this._exponentialBackoffReconnect=Math.min(2*this._exponentialBackoffReconnect,BasePoolMiner.RECONNECT_TIMEOUT_MAX)}disconnect(){this._turnPoolOff();if(this._ws){this._changeConnectionState(BasePoolMiner.ConnectionState.CLOSED);Log.w(BasePoolMiner,"Disconnected from pool");const t=this._ws;this._ws=null;try{t.close()}catch(e){Log.w(BasePoolMiner,e.message||e)}}clearTimeout(this._reconnectTimeout)}_onMessage(e,t){if(e===this._ws)try{const r=JSON.parse(t);if(r&&r.message)switch(r.message){case"settings":if(r.address&&r.extraData){this._onNewPoolSettings(Address.fromUserFriendlyAddress(r.address),BufferUtils.fromBase64(r.extraData),r.targetCompact||BlockUtils.targetToCompact(new BigNumber(r.target)),r.nonce);Log.d(BasePoolMiner,`Received settings from pool: address ${r.address}, target ${r.target}, extraData ${r.extraData}`)}else{this._turnPoolOff();this._ws.close()}break;case"balance":if(r.balance===undefined||r.confirmedBalance===undefined){this._turnPoolOff();this._ws.close()}else{this._onBalance(r.balance,r.confirmedBalance,r.payoutRequestActive);Log.d(BasePoolMiner,`Received balance from pool: ${r.balance} (${r.confirmedBalance} confirmed), payout request active: ${r.payoutRequestActive}`)}break;case"registered":this._changeConnectionState(BasePoolMiner.ConnectionState.CONNECTED);this._exponentialBackoffReconnect=BasePoolMiner.RECONNECT_TIMEOUT;Log.i(BasePoolMiner,"Connected to pool");break;case"error":Log.w(BasePoolMiner,"Error from pool:",r.reason)}else{Log.w(BasePoolMiner,"Received unknown message from pool server:",JSON.stringify(r));this._ws.close()}}catch(s){this._onError(e,s)}}_onBalance(e,t,s){const r=this.balance||0,n=this.confirmedBalance||0;this.balance=new BigNumber(e);this.confirmedBalance=new BigNumber(t);this.payoutRequestActive=s;this.balance.eq(r)&&this.confirmedBalance.eq(n)||Log.i(BasePoolMiner,`Pool balance: ${Policy.satoshisToCoins(this.balance).toString()} BTCK (confirmed ${Policy.satoshisToCoins(this.confirmedBalance).toString()} BTCK)`);this.balance.eq(r)||this.fire("balance",e);this.confirmedBalance.eq(n)||this.fire("confirmed-balance",t)}_turnPoolOff(){this.startConfigChanges();super.address=this._ourAddress;super.extraData=this._ourExtraData;super.shareCompact=null;this.finishConfigChanges()}_onNewPoolSettings(e,t,s,r){this.startConfigChanges();super.address=e;super.extraData=t;super.shareCompact=s;super.nonce=r;this.finishConfigChanges()}_changeConnectionState(e){this.connectionState=e;this.fire("connection-state",e)}isConnected(){return this.connectionState===BasePoolMiner.ConnectionState.CONNECTED}isDisconnected(){return this.connectionState===BasePoolMiner.ConnectionState.CLOSED}get host(){return this._host}get port(){return this._port}get address(){return this._ourAddress}set address(e){this._ourAddress=e;if(this.isConnected()){this.disconnect();this.connect(this._host,this._port)}else super.address=e}static generateDeviceId(e){return Hash.blake2b([BufferUtils.fromAscii("pool_device_id"),e.keyPair.privateKey.serialize()].reduce(BufferUtils.concatTypedArrays)).serialize().readUint32()}}BasePoolMiner.PAYOUT_NONCE_PREFIX="POOL_PAYOUT";BasePoolMiner.RECONNECT_TIMEOUT=3e3;BasePoolMiner.RECONNECT_TIMEOUT_MAX=3e4;BasePoolMiner.ConnectionState={CONNECTED:0,CONNECTING:1,CLOSED:2};BasePoolMiner.Mode={NANO:"nano",SMART:"smart"};Class.register(BasePoolMiner);class SmartPoolMiner extends BasePoolMiner{constructor(e,t,s,r,n,i,o,a=new Uint8Array(0)){super(BasePoolMiner.Mode.SMART,e,t,s,r,n,i,o,a);this.on("share",(e,t)=>this._onBlockMined(e,t))}async _onBlockMined(e,t){this._send({message:"share",blockHeader:BufferUtils.toBase64(e.header.serialize()),minerAddrProof:BufferUtils.toBase64((await MerklePath.compute(e.body.getMerkleLeafs(),e.minerAddr)).serialize()),extraDataProof:BufferUtils.toBase64((await MerklePath.compute(e.body.getMerkleLeafs(),e.body.extraData)).serialize()),block:t?BufferUtils.toBase64(e.serialize()):undefined})}}Class.register(SmartPoolMiner);class NanoPoolMiner extends BasePoolMiner{constructor(e,t,s,r,n){super(BasePoolMiner.Mode.NANO,e,null,null,t,s,r,n);this.on("share",e=>this._onBlockMined(e));this._shouldWork=!1}startWork(){this._shouldWork=!0;super.startWork()}stopWork(){this._shouldWork=!1;super.stopWork()}_onBlockMined(e){this._send({message:"share",block:BufferUtils.toBase64(e.serialize())})}_onMessage(e,t){if(this._ws===e)try{const r=JSON.parse(t);r&&"new-block"===r.message?this._handleNewBlock(r):super._onMessage(e,t)}catch(s){this._onError(e,s)}}async _handleNewBlock(e){const t=Block.unserialize(BufferUtils.fromBase64(e.previousBlock));Log.d(NanoPoolMiner,`New base block from pool server, on top of ${t.hash()}`);let s;if(this._blockchain.headHash.equals(t.hash()))this._poolNextTarget=await this._blockchain.getNextTarget();else if(this._blockchain.headHash.equals(t.prevHash)){if(!(await t.isImmediateSuccessorOf(this._blockchain.head))){Log.w(NanoPoolMiner,`${t.hash()} (from pool) is not an immediate successor of ${this._blockchain.headHash}, but is announced as such.`);super.stopWork();return}this._poolNextTarget=await this._blockchain.getNextTarget(this._blockchain.head,t)}else{if(this._blockchain.head.prevHash.equals(t.hash())){super.stopWork();return}if(this._blockchain.height!==t.height||!(s=await this._blockchain.getBlock(t.prevHash))){if(s=await this._blockchain.getBlock(t.prevHash,!0)){Log.w(NanoPoolMiner,`${t.hash()} (from pool) is a known fork, we don't mine on forks.`);super.stopWork();return}Log.w(NanoPoolMiner,`${t.hash()} (from pool) is unknown and not a successor of the head`);super.stopWork();return}if(!(await t.isImmediateSuccessorOf(s))){Log.w(NanoPoolMiner,`${t.hash()} (from pool) is not an immediate successor of ${s}, but is announced as such.`);super.stopWork();return}}this._poolNextInterlink=await t.getNextInterlink(this._poolNextTarget);this._poolPrevBlock=t;this._poolAccountsHash=Hash.unserialize(BufferUtils.fromBase64(e.accountsHash));this._poolBodyHash=Hash.unserialize(BufferUtils.fromBase64(e.bodyHash));this.working?this._startWork()["catch"](Log.w.tag(Miner)):this._shouldWork&&super.startWork()}getNextBlock(){return this._poolPrevBlock?new Block(new BlockHeader(this._poolPrevBlock.hash(),this._poolNextInterlink.hash(),this._poolBodyHash,this._poolAccountsHash,BlockUtils.targetToCompact(this._poolNextTarget),this._poolPrevBlock.height+1,Math.max(this._producer._getNextTimestamp(),this._poolPrevBlock.timestamp+1),0),this._poolNextInterlink):null}_turnPoolOff(){this.stopWork();super._turnPoolOff()}}Class.register(NanoPoolMiner);class Wallet{static generate(){return new Wallet(KeyPair.generate())}static loadPlain(e){"string"==typeof e&&(e=BufferUtils.fromHex(e));if(!e||0===e.byteLength)throw new Error("Invalid wallet seed");return new Wallet(KeyPair.unserialize(new SerialBuffer(e)))}static importPrivateKey(e){"string"==typeof e&&(e=BufferUtils.fromHex(e,32));if(!e||e.byteLength<PrivateKey.SIZE)return null;const t=PrivateKey.unserialize(new SerialBuffer(e)),s=PublicKey.derive(t);return new Wallet(new KeyPair(t,s))}static importFromSeed(e){if(!(e=BufferUtils.fromHex(e))||e.byteLength!=PrivateKey.SIZE)return null;const t=PrivateKey.unserialize(new SerialBuffer(e)),s=PublicKey.derive(t);return new Wallet(new KeyPair(t,s))}static async loadEncrypted(e,t){"string"==typeof e&&(e=BufferUtils.fromHex(e));"string"==typeof t&&(t=BufferUtils.fromUtf8(t));return new Wallet(await KeyPair.fromEncrypted(new SerialBuffer(e),t))}constructor(e){this._keyPair=e;this._address=this._keyPair.publicKey.toAddress()}createTransaction(e,t,s){const r=new BasicTransaction(this._keyPair.publicKey,e,t,s);r.signature=Signature.create(this._keyPair.privateKey,this._keyPair.publicKey,r.serializeContent());return r}signTransaction(e){const t=Signature.create(this._keyPair.privateKey,this._keyPair.publicKey,e.serializeContent());return SignatureProof.singleSig(this._keyPair.publicKey,t)}exportPlain(){return this._keyPair.serialize()}exportEncrypted(e){"string"==typeof e&&(e=BufferUtils.fromUtf8(e));return this._keyPair.exportEncrypted(e)}get isLocked(){return this.keyPair.isLocked}lock(e){"string"==typeof e&&(e=BufferUtils.fromUtf8(e));return this.keyPair.lock(e)}relock(){this.keyPair.relock()}unlock(e){"string"==typeof e&&(e=BufferUtils.fromUtf8(e));return this.keyPair.unlock(e)}equals(e){return e instanceof Wallet&&this.keyPair.equals(e.keyPair)&&this.address.equals(e.address)}get address(){return this._address}get publicKey(){return this._keyPair.publicKey}get keyPair(){return this._keyPair}}Class.register(Wallet);class MultiSigWallet extends Wallet{static fromPublicKeys(e,t,s){if(0===s.length)throw new Error("publicKeys may not be empty");if(t<=0)throw new Error("minSignatures must be greater than 0");if(!s.some(t=>t.equals(e.publicKey)))throw new Error("Own publicKey must be part of publicKeys");(s=s.slice()).sort((e,t)=>e.compare(t));const r=[...ArrayUtils.k_combinations(s,t)].map(e=>PublicKey.sum(e));return new MultiSigWallet(e,t,r)}static _loadMultiSig(e,t){const s=t.readUint8(),r=t.readUint8(),n=[];for(let i=0;i<r;++i)n.push(PublicKey.unserialize(t));return new MultiSigWallet(e,s,n)}static loadPlain(e){"string"==typeof e&&(e=BufferUtils.fromHex(e));if(!e||0===e.byteLength)throw new Error("Invalid wallet seed");const t=new SerialBuffer(e),s=KeyPair.unserialize(t);return MultiSigWallet._loadMultiSig(s,t)}static async loadEncrypted(e,t){"string"==typeof e&&(e=BufferUtils.fromHex(e));"string"==typeof t&&(t=BufferUtils.fromUtf8(t));const s=new SerialBuffer(e),r=await KeyPair.fromEncrypted(s,t);return MultiSigWallet._loadMultiSig(r,s)}constructor(e,t,s){super(e);this._minSignatures=t;this._publicKeys=s;this._publicKeys.sort((e,t)=>e.compare(t));const r=MerkleTree.computeRoot(this._publicKeys);this._address=Address.fromHash(r)}exportPlain(){const e=new SerialBuffer(this.exportedSize);this._keyPair.serialize(e);e.writeUint8(this._minSignatures);e.writeUint8(this._publicKeys.length);for(const t of this._publicKeys)t.serialize(e);return e}get exportedSize(){return this._keyPair.serializedSize+1+1+this._publicKeys.reduce((e,t)=>e+t.serializedSize,0)}async exportEncrypted(e){"string"==typeof e&&(e=BufferUtils.fromUtf8(e));const t=new SerialBuffer(this.encryptedSize);t.write(await this._keyPair.exportEncrypted(e));t.writeUint8(this._minSignatures);t.writeUint8(this._publicKeys.length);for(const s of this._publicKeys)s.serialize(t);return t}get encryptedSize(){return this._keyPair.encryptedSize+1+1+this._publicKeys.reduce((e,t)=>e+t.serializedSize,0)}createTransaction(e,t,s){return new ExtendedTransaction(this._address,Account.Type.BASIC,e,Account.Type.BASIC,t,s,Transaction.Flag.NONE,new Uint8Array(0))}createCommitment(){return CommitmentPair.generate()}partiallySignTransaction(e,t,s,r){(t=t.slice()).sort((e,t)=>e.compare(t));return PartialSignature.create(this._keyPair.privateKey,this._keyPair.publicKey,t,r,s,e.serializeContent())}signTransaction(e,t,s,r){if(r.length!==this._minSignatures)throw new Error("Not enough signatures to complete this transaction");const n=Signature.fromPartialSignatures(s,r);return SignatureProof.multiSig(t,this._publicKeys,n)}completeTransaction(e,t,s,r){const n=this.signTransaction(e,t,s,r);e.proof=n.serialize();return e}get minSignatures(){return this._minSignatures}get publicKeys(){return this._publicKeys}}Class.register(MultiSigWallet);class WalletStore{constructor(e="wallet"){this._jdb=new JDB.JungleDB(e,WalletStore.VERSION,{maxDbSize:WalletStore.INITIAL_DB_SIZE,autoResize:!0,minResize:WalletStore.MIN_RESIZE});this._walletStore=null;this._multiSigStore=null;return this._init()}async _init(){this._walletStore=this._jdb.createObjectStore(WalletStore.WALLET_DATABASE,{codec:new WalletStoreCodec});this._multiSigStore=this._jdb.createObjectStore(WalletStore.MULTISIG_WALLET_DATABASE,{codec:new WalletStoreCodec});await this._jdb.connect();return this}async hasDefault(){return!!(await this._walletStore.get("default"))}async getDefault(e){const t=await this._walletStore.get("default");if(!t){const e=Wallet.generate();await this.put(e);await this.setDefault(e.address);return e}const s=new Address(t);return this.get(s,e)}setDefault(e){const t=e.serialize();return this._walletStore.put("default",t)}async get(e,t){const s=e.toBase64(),r=await this._walletStore.get(s);if(!r)return null;if(t)return Wallet.loadEncrypted(r,t);try{return Wallet.loadPlain(r)}catch(n){return null}}async put(e,t,s){const r=e.address.toBase64();let n=null;n=t?await e.exportEncrypted(t,s):e.exportPlain();return this._walletStore.put(r,n)}async remove(e){const t=e.toBase64(),s=this._walletStore.transaction();s.removeSync(t);let r=await this._walletStore.get("default");if(r){r=new Address(r);e.equals(r)&&s.removeSync("default")}return s.commit()}async list(){const e=await this._walletStore.keys();return Array.from(e).filter(e=>"default"!==e).map(e=>Address.fromBase64(e))}async getMultiSig(e,t){const s=e.toBase64(),r=await this._multiSigStore.get(s);return r?t?MultiSigWallet.loadEncrypted(r,t):MultiSigWallet.loadPlain(r):null}async putMultiSig(e,t,s){const r=e.address.toBase64();let n=null;n=t?await e.exportEncrypted(t,s):e.exportPlain();return this._multiSigStore.put(r,n)}removeMultiSig(e){const t=e.toBase64();return this._multiSigStore.remove(t)}async listMultiSig(){const e=await this._multiSigStore.keys();return Array.from(e).map(e=>Address.fromBase64(e))}close(){return this._jdb.close()}}Class.register(WalletStore);WalletStore._instance=null;WalletStore.VERSION=1;WalletStore.INITIAL_DB_SIZE=10485760;WalletStore.MIN_RESIZE=10485760;WalletStore.WALLET_DATABASE="wallets";WalletStore.MULTISIG_WALLET_DATABASE="multisig-wallets";class WalletStoreCodec{encode(e){return e}decode(e,t){return new Uint8Array(e)}get leveldbValueEncoding(){return"binary"}get lmdbValueEncoding(){return JDB.JungleDB.BINARY_ENCODING}}class MinerWorker{async multiMine(e,t,s,r){}}Class.register(MinerWorker);class MinerWorkerImpl extends(IWorker.Stub(MinerWorker)){constructor(){super();this._superInit=super.init}async init(e){await this._superInit.call(this,e);PlatformUtils.isBrowser()&&await WasmHelper.doImportBrowser()}async multiMine(e,t,s,r){const n=new Uint8Array(32);let i,o;try{i=Module._malloc(n.length);o=Module._malloc(e.length);Module.HEAPU8.set(e,o);const c=Module._krypton_argon2_target(i,o,e.length,t,s,r,512);if(c===r)return!1;n.set(new Uint8Array(Module.HEAPU8.buffer,i,n.length));return{hash:n,nonce:c}}catch(a){Log.w(MinerWorkerImpl,a);throw a}finally{i!==undefined&&Module._free(i);o!==undefined&&Module._free(o)}}}IWorker.prepareForWorkerUse(MinerWorker,new MinerWorkerImpl);class MinerWorkerPool extends(IWorker.Pool(MinerWorker)){constructor(e=1){super(e=>IWorker.startWorkerForProxy(MinerWorker,e),"miner",e);this._miningEnabled=!1;this._activeNonces=[];this._block=null;this._noncesPerRun=256;this._observable=new Observable;this._shareCompact=Policy.BLOCK_TARGET_MAX;this._runsPerCycle=Infinity;this._cycleWait=100;this._superUpdateToSize=super._updateToSize;if(PlatformUtils.isNodeJs()){Log.i(MinerWorkerPool,`Using add-on optimized for instruction set: ${cpuSupport}`);this.multiMine=function(e,t,s,r){return new Promise((n,i)=>{NodeNative.node_argon2_target_async(async t=>{try{if(t===r)n(!1);else{e.writePos-=4;e.writeUint32(t);const s=await(await CryptoWorker.getInstanceAsync()).computeArgon2d(e);n({hash:s,nonce:t})}}catch(s){i(s)}},e,t,s,r,512)})}}}get noncesPerRun(){return this._noncesPerRun}set noncesPerRun(e){this._noncesPerRun=e}get runsPerCycle(){return this._runsPerCycle}set runsPerCycle(e){this._runsPerCycle=e}get cycleWait(){return this._cycleWait}set cycleWait(e){this._cycleWait=e}on(e,t){return this._observable.on(e,t)}off(e,t){this._observable.off(e,t)}async startMiningOnBlock(e,t){this._block=e;this._shareCompact=t||e.nBits;if(this._miningEnabled)this._activeNonces=[{minNonce:0,maxNonce:0}];else{await this._updateToSize();this._activeNonces=[];this._miningEnabled=!0;for(let e=0;e<this.poolSize;++e)this._startMiner()}}stop(){this._miningEnabled=!1}async _updateToSize(){PlatformUtils.isNodeJs()||await this._superUpdateToSize.call(this);for(;this._miningEnabled&&this._activeNonces.length<this.poolSize;)this._startMiner()}_startMiner(){if(this._activeNonces.length>=this.poolSize)return;const e=0===this._activeNonces.length?0:Math.max.apply(null,this._activeNonces.map(e=>e.maxNonce)),t={minNonce:e,maxNonce:e+this._noncesPerRun};this._activeNonces.push(t);this._singleMiner(t)["catch"](e=>Log.e(MinerWorkerPool,e))}async _singleMiner(e){let t=0;for(;this._miningEnabled&&(IWorker.areWorkersAsync||PlatformUtils.isNodeJs()||0===t)&&t<this._runsPerCycle;){t++;const s=this._block,r=await this.multiMine(s.header.serialize(),this._shareCompact,e.minNonce,e.maxNonce);if(r){const e=new Hash(r.hash);this._observable.fire("share",{block:s,nonce:r.nonce,hash:e})}else this._observable.fire("no-share",{nonce:e.maxNonce});if(this._activeNonces.length>this.poolSize){this._activeNonces.splice(this._activeNonces.indexOf(e),1);return}{const t=Math.max.apply(null,this._activeNonces.map(e=>e.maxNonce)),s={minNonce:t,maxNonce:t+this._noncesPerRun};this._activeNonces.splice(this._activeNonces.indexOf(e),1,s);e=s}}this._miningEnabled&&setTimeout(()=>this._singleMiner(e),this._cycleWait)}}Class.register(MinerWorkerPool);class Client{constructor(e,t){this._consensus=t||e.createConsensus();this._consensusListenerIds=[];this._consensusSynchronizer=new Synchronizer;this._subscribedAddresses=new HashSet;this._config=e;this._consensusChangedListeners=new HashMap;this._blockListeners=new HashMap;this._headChangedListeners=new HashMap;this._transactionListeners=new HashMap;this._listenerId=0;this._consensusState=Client.ConsensusState.CONNECTING;this._headHash=null;this._transactionConfirmWaiting=new HashMap;this._transactionExpireWaiting=new HashMap;this._transactionSynchronizer=new Synchronizer;this._network=new Client.Network(this);this._mempool=new Client.Mempool(this);this._consensusSynchronizer.push(()=>this._setupConsensus()["catch"](Log.w.tag(Client)))["catch"](Log.w.tag(Client))}resetConsensus(){return this._consensusSynchronizer.push(()=>this._replaceConsensus(this._config.createConsensus()))}async _setupConsensus(){const e=await this._consensus;this._consensusOn(e,"block",e=>this._onBlock(e));this._consensusOn(e,"established",()=>this._onConsensusChanged(Client.ConsensusState.ESTABLISHED));this._consensusOn(e,"waiting",()=>this._onConsensusChanged(Client.ConsensusState.CONNECTING));this._consensusOn(e,"syncing",()=>this._onConsensusChanged(Client.ConsensusState.SYNCING));this._consensusOn(e,"head-changed",(e,t,s,r)=>this._onHeadChanged(e,t,s,r));this._consensusOn(e,"transaction-added",e=>this._onPendingTransaction(e));this._consensusOn(e,"transaction-added",e=>this._mempool._onTransactionAdded(e));this._consensusOn(e,"transaction-removed",e=>this._mempool._onTransactionRemoved(e));this._consensusOn(e,"transaction-mined",(e,t,s)=>this._onMinedTransaction(t,e,s));this._consensusOn(e,"consensus-failed",()=>this._onConsensusFailed());this._onConsensusChanged(e.established?Client.ConsensusState.ESTABLISHED:Client.ConsensusState.CONNECTING);this._config.hasFeature(Client.Feature.PASSIVE)?e.network.allowInboundConnections=!0:e.network.connect()}_consensusOn(e,t,s){this._consensusListenerIds.push({type:t,id:e.on(t,s)})}async _replaceConsensus(e){const t=await this._consensus;for(const{type:r,id:n}of this._consensusListenerIds)t.off(r,n);this._consensusListenerIds=[];this._consensus=e;const s=await this._consensus;t.handoverTo(s);return this._setupConsensus()}_txExpiresAt(e){return e.validityStartHeight+Policy.TRANSACTION_VALIDITY_WINDOW+this._config.requiredBlockConfirmations-1}_txWaitForExpire(e){const t=this._transactionExpireWaiting.get(this._txExpiresAt(e))||new HashSet;t.add(e);this._transactionExpireWaiting.put(this._txExpiresAt(e),t)}_txClearFromExpire(e){if(this._transactionExpireWaiting.contains(this._txExpiresAt(e))){const t=this._transactionExpireWaiting.get(this._txExpiresAt(e));t.remove(e);0===t.length&&this._transactionExpireWaiting.remove(this._txExpiresAt(e))}}_txConfirmsAt(e){return e+this._config.requiredBlockConfirmations-1}_txWaitForConfirm(e,t){const s=this._transactionConfirmWaiting.get(this._txConfirmsAt(t))||new HashSet;s.add(e);this._transactionConfirmWaiting.put(this._txConfirmsAt(t),s)}_txClearFromConfirm(e){for(const[t,s]of this._transactionConfirmWaiting.entryIterator())if(s.contains(e)){s.remove(e);if(0===s.length){this._transactionConfirmWaiting.remove(t);break}}}_onBlock(e){for(const t of this._blockListeners.values())t(e)}_onConsensusChanged(e){this._consensusSynchronizer.push(async()=>{const t=await this._consensus;if(e!==this._consensusState){if(t.established){t.getSubscription().type===Subscription.Type.ADDRESSES&&t.subscribe(Subscription.fromAddresses(this._subscribedAddresses.values()))}this._consensusState=e;for(const t of this._consensusChangedListeners.values())try{await t(e)}catch(s){Log.e(Client,`Error in listener: ${s}`)}if(t.established){const e=await t.getHeadHash();if(e.equals(this._headHash))return;this._headHash=e;for(const t of this._headChangedListeners.values())try{await t(e,"established",[],[e])}catch(s){Log.e(Client,`Error in listener: ${s}`)}}}})["catch"](Log.e.tag(Client))}_onConsensusFailed(){this._consensusSynchronizer.push(async()=>{const e=await this._consensus;if(e instanceof PicoConsensus){Log.w(Client,"Pico consensus failed, automatically upgrading to nano consensus");const t=new NanoConsensus(await new NanoChain(e.network.time),e.mempool,e.network);await this._replaceConsensus(Promise.resolve(t))}})["catch"](Log.e.tag(Client))}async _onHeadChanged(e,t,s,r){this._consensusSynchronizer.push(async()=>{if(this._consensusState===Client.ConsensusState.ESTABLISHED&&!e.equals(this._headHash)){this._headHash=e;for(const i of this._headChangedListeners.values())try{await i(e,t,s.map(e=>e.hash()),r.map(e=>e.hash()))}catch(n){Log.e(Client,`Error in listener: ${n}`)}}if(this._transactionListeners.length>0){const e=new HashSet,t=new HashSet(e=>e.tx instanceof Transaction?e.tx.hash().hashCode():e.hash().hashCode()),n=await this._consensus;for(const r of s){!r.isFull()||n instanceof PicoConsensus||e.addAll(r.transactions);const t=this._transactionConfirmWaiting.get(this._txConfirmsAt(r.height));if(t){for(const s of t.valueIterator())e.add(s);this._transactionConfirmWaiting.remove(this._txConfirmsAt(r.height))}}for(const s of r)if(s.isFull()&&!(n instanceof PicoConsensus))for(const r of s.transactions){e.contains(r)&&e.remove(r);t.add({tx:r,block:s})}for(const s of e.valueIterator())this._onPendingTransaction(s,r[r.length-1]);for(const s of r){const e=this._transactionConfirmWaiting.get(s.height);if(e){for(const t of e.valueIterator())this._onConfirmedTransaction(s,t,r[r.length-1]);this._transactionConfirmWaiting.remove(s.height)}}for(const{tx:s,block:i}of t.valueIterator())this._onMinedTransaction(i,s,r[r.length-1]);for(const s of r){const e=this._transactionExpireWaiting.get(s.height);if(e){for(const t of e.valueIterator())this._onExpiredTransaction(s,t);this._transactionExpireWaiting.remove(s.height)}}}})["catch"](Log.e.tag(Client))}_onPendingTransaction(e,t){let s,r=[];for(const{listener:n,addresses:i}of this._transactionListeners.values())if(i.contains(e.sender)||i.contains(e.recipient)){s=t&&t.height>=this._txExpiresAt(e)?s||new Client.TransactionDetails(e,Client.TransactionState.EXPIRED):s||new Client.TransactionDetails(e,Client.TransactionState.PENDING);r.push(async()=>{try{await n(s)}catch(e){Log.e(Client,`Error in listener: ${e}`)}})}this._txClearFromConfirm(e);s&&s.state===Client.TransactionState.PENDING&&this._txWaitForExpire(e);r.length>0&&this._transactionSynchronizer.push(()=>r.forEach(e=>e()))["catch"](Log.e.tag(Client))}_onMinedTransaction(e,t,s){let r,n=[];for(const{listener:i,addresses:o}of this._transactionListeners.values())if(o.contains(t.sender)||o.contains(t.recipient)){let o=Client.TransactionState.MINED,a=1;s&&(o=(a=s.height-e.height+1)>=this._config.requiredBlockConfirmations?Client.TransactionState.CONFIRMED:Client.TransactionState.MINED);r=r||new Client.TransactionDetails(t,o,e.hash(),e.height,a,e.timestamp);n.push(async()=>{try{await i(r)}catch(e){Log.e(Client,`Error in listener: ${e}`)}})}this._txClearFromExpire(t);r&&r.state===Client.TransactionState.MINED&&this._txWaitForConfirm(t,e.height);n.length>0&&this._transactionSynchronizer.push(()=>n.forEach(e=>e()))["catch"](Log.e.tag(Client))}_onConfirmedTransaction(e,t,s){let r,n=[];for(const{listener:i,addresses:o}of this._transactionListeners.values())if(o.contains(t.sender)||o.contains(t.recipient)){r=r||new Client.TransactionDetails(t,Client.TransactionState.CONFIRMED,e.hash(),e.height,s.height-e.height+this._config.requiredBlockConfirmations,e.timestamp);n.push(async()=>{try{await i(r)}catch(e){Log.e(Client,`Error in listener: ${e}`)}})}n.length>0&&this._transactionSynchronizer.push(()=>n.forEach(e=>e()))["catch"](Log.e.tag(Client))}_onExpiredTransaction(e,t){let s,r=[];for(const{listener:n,addresses:i}of this._transactionListeners.values())if(i.contains(t.sender)||i.contains(t.recipient)){s=s||new Client.TransactionDetails(t,Client.TransactionState.EXPIRED);r.push(async()=>{try{await n(s)}catch(e){Log.e(Client,`Error in listener: ${e}`)}})}r.length>0&&this._transactionSynchronizer.push(()=>r.forEach(e=>e()))["catch"](Log.e.tag(Client))}async getHeadHash(){return(await this._consensus).getHeadHash()}async getHeadHeight(){return(await this._consensus).getHeadHeight()}async getHeadBlock(e=!0){const t=await this._consensus,s=await t.getHeadHash();return t.getBlock(s,e)}async getBlock(e,t=!0){e=Hash.fromAny(e);return(await this._consensus).getBlock(e,t)}async getBlockAt(e,t){return(await this._consensus).getBlockAt(e,t)}async getBlockTemplate(e,t){this._config.requireFeatures(Client.Feature.MINING,Client.Feature.MEMPOOL);e=Address.fromAny(e);if("string"==typeof t)t=BufferUtils.fromHex(t);else if(t&&!(t instanceof Uint8Array))throw new Error("Invalid extra data");return(await this._consensus).getBlockTemplate(e,t)}async submitBlock(e){this._config.requireFeatures(Client.Feature.MINING);e=Block.fromAny(e);return(await this._consensus).submitBlock(e)}async getAccount(e){return(await this.getAccounts([e]))[0]}async getAccounts(e){e=e.map(e=>Address.fromAny(e));return(await this._consensus).getAccounts(e)}async getTransaction(e,t,s){e=Hash.fromAny(e);t&&(t=Hash.fromAny(t));const r=await this._consensus;if(!t){const n=await r.getTransactionReceiptsByHashes([e]);if(n&&1===n.length&&n[0]){t=n[0].blockHash;s=n[0].blockHeight}}if(!t){const t=await r.getPendingTransactions([e]);if(t&&t[0]){this._txWaitForExpire(t[0]);return new Client.TransactionDetails(t[0],Client.TransactionState.PENDING)}throw new Error("Unknown transaction hash")}const n=await r.getBlock(t,!1,!0,s);if(!n)throw new Error("Unknown block hash");s=n.height;const i=await r.getTransactionsFromBlock([e],t,s,n);if(i&&i[0]){const e=i[0],o=await r.getHeadHeight()-s+1,a=o>=this._config.requiredBlockConfirmations;a||this._txWaitForConfirm(e,s);return new Client.TransactionDetails(e,a?Client.TransactionState.CONFIRMED:Client.TransactionState.MINED,t,s,o,n.timestamp)}throw new Error("Unknown transaction hash")}async getTransactionReceipt(e){e=Hash.fromAny(e);return(await this.getTransactionReceiptsByHashes([e]))[0]}async getTransactionReceiptsByAddress(e,t=Infinity){e=Address.fromAny(e);return(await this._consensus).getTransactionReceiptsByAddress(e,t)}async getTransactionReceiptsByHashes(e){e=e.map(e=>Hash.fromAny(e));return(await this._consensus).getTransactionReceiptsByHashes(e)}async getTransactionsByAddress(e,t=0,s,r=Infinity){e=Address.fromAny(e);const n=new HashMap;if(s){s=s.map(e=>Client.TransactionDetails.fromPlain(e));for(const e of s)n.put(e.transactionHash,e)}const i=await this._consensus,o=new HashSet(e=>e instanceof Hash?e.hashCode():e.transactionHash.hashCode());try{const t=await i.getPendingTransactionsByAddress(e,r);for(const e of t){this._txWaitForExpire(e);o.add(new Client.TransactionDetails(e,Client.TransactionState.PENDING))}}catch(u){}const a=new HashSet(e=>e.transactionHash.hashCode());o.length<r&&a.addAll(await i.getTransactionReceiptsByAddress(e,r-o.length));const c=new HashMap,h=new HashMap;for(const d of a.valueIterator()){const e=n.get(d.transactionHash);if((!e||e.state!==Client.TransactionState.CONFIRMED||!d.blockHash.equals(e.blockHash))&&d.blockHeight>=t){const e=c.get(d.blockHash.toBase64())||new HashSet;e.add(d.transactionHash);c.put(d.blockHash.toBase64(),e);h.put(d.blockHash.toBase64(),d.blockHeight)}}for(const d of n.valueIterator())if((d.state===Client.TransactionState.MINED||d.state===Client.TransactionState.CONFIRMED)&&d.blockHeight>=t&&!a.contains(d)){const e=c.get(d.blockHash.toBase64())||new HashSet;e.add(d.transactionHash);c.put(d.blockHash.toBase64(),e);h.put(d.blockHash.toBase64(),d.blockHeight)}const l=await i.getHeadHeight();for(const[d,_]of c.entryIterator()){const e=Hash.fromBase64(d);if(e.equals(Hash.NULL))throw new Error(`Illegal request for ${d} vs ${e}`);const t=h.get(d),s=await i.getBlock(e,!1,!0,t),r=await i.getTransactionsFromBlock(_.values(),e,t,s),n=l-t+1,a=n>=this._config.requiredBlockConfirmations;for(const i of r){a||this._txWaitForConfirm(i,t);o.add(new Client.TransactionDetails(i,a?Client.TransactionState.CONFIRMED:Client.TransactionState.MINED,e,t,n,s.timestamp))}}for(const d of n.valueIterator())d.state!==Client.TransactionState.NEW&&d.state!==Client.TransactionState.PENDING||o.contains(d)||(this._txExpiresAt(d)<=l?o.add(new Client.TransactionDetails(d.transaction,Client.TransactionState.EXPIRED)):o.add(await this.sendTransaction(d.transaction)));return o.values()}async sendTransaction(e){e=Transaction.fromAny(e);const t=await this._consensus;switch(await t.sendTransaction(e)){case BaseConsensus.SendTransactionResult.EXPIRED:return new Client.TransactionDetails(e,Client.TransactionState.EXPIRED);case BaseConsensus.SendTransactionResult.INVALID:return new Client.TransactionDetails(e,Client.TransactionState.INVALIDATED);case BaseConsensus.SendTransactionResult.KNOWN:case BaseConsensus.SendTransactionResult.RELAYED:case BaseConsensus.SendTransactionResult.PENDING_LOCAL:return new Client.TransactionDetails(e,Client.TransactionState.PENDING);case BaseConsensus.SendTransactionResult.ALREADY_MINED:return this.getTransaction(e.hash())}return new Client.TransactionDetails(e,Client.TransactionState.NEW)}async addBlockListener(e){const t=this._listenerId++;this._blockListeners.put(t,e);return t}async addConsensusChangedListener(e){const t=this._listenerId++;this._consensusChangedListeners.put(t,e);return t}async addHeadChangedListener(e){const t=this._listenerId++;this._headChangedListeners.put(t,e);return t}async addTransactionListener(e,t){t=t.map(e=>Address.fromAny(e));const s=new HashSet;s.addAll(t);this._subscribedAddresses.addAll(s);await this._consensusSynchronizer.push(async()=>{const e=await this._consensus;if(e.established){e.getSubscription().type===Subscription.Type.ADDRESSES&&e.subscribe(Subscription.fromAddresses(this._subscribedAddresses.values()))}});const r=this._listenerId++;this._transactionListeners.put(r,{listener:e,addresses:s});return r}async removeListener(e){this._blockListeners.remove(e);this._consensusChangedListeners.remove(e);this._headChangedListeners.remove(e);this._transactionListeners.remove(e);if(0===this._transactionListeners.length){this._transactionConfirmWaiting.clear();this._transactionExpireWaiting.clear()}}waitForConsensusEstablished(){return new Promise(e=>{if(this._consensusState===Client.ConsensusState.ESTABLISHED)e();else{let t;t=this.addConsensusChangedListener(async s=>{if(s===Client.ConsensusState.ESTABLISHED){await this.removeListener(t);e()}})}})}get network(){return this._network}get mempool(){this._config.requireFeatures(Client.Feature.MEMPOOL);return this._mempool}}Client.ConsensusState={CONNECTING:"connecting",SYNCING:"syncing",ESTABLISHED:"established"};Class.register(Client);Client.Configuration=class Configuration{constructor(e,t=[],s=!1,r=10){this._networkConfig=e;this._features=t;this._useVolatileStorage=s;this._requiredBlockConfirmations=r}get features(){return this._features}get requiredBlockConfirmations(){return this._requiredBlockConfirmations}get networkConfig(){return this._networkConfig}createConsensus(){return this._useVolatileStorage?this._features.includes(Client.Feature.MEMPOOL)||this._features.includes(Client.Feature.MINING)?Consensus.volatileLight(this._networkConfig):Consensus.volatilePico(this._networkConfig):this._features.includes(Client.Feature.LOCAL_HISTORY)?Consensus.full(this._networkConfig):this._features.includes(Client.Feature.MEMPOOL)||this._features.includes(Client.Feature.MINING)?Consensus.light(this._networkConfig):Consensus.pico(this._networkConfig)}hasFeature(e){return this._features.includes(e)}requireFeatures(...e){for(const t of e)if(!this.hasFeature(t))throw new Error(`Missing required client feature: ${t}`)}instantiateClient(){return new Client(this)}static builder(){return new Client.ConfigurationBuilder}};Client.ConfigurationBuilder=class ConfigurationBuilder{constructor(){this._features=new HashSet}dumb(){return this.protocol("dumb")}rtc(){return this.protocol("rtc")}ws(e,t=12011){return this.protocol("ws",e,t)}wss(e,t=12011,s,r){return this.protocol("wss",e,t,s,r)}protocol(e,t,s=12011,r,n){if(this._protocol)throw new Error("Protocol already configured");this._protocol=this._requiredSet(e,"protocol","dumb","rtc","ws","wss");if("ws"===this._protocol||"wss"===this._protocol){this._host=this._requiredType(t,"host","string");this._port=this._requiredType(s,"port","number")}if("wss"===this._protocol){this._tlsKey=this._requiredType(r,"tlsKey","string");this._tlsCert=this._requiredType(n,"tlsCert","string")}return this}volatile(e=!0){if("undefined"!=typeof this._volatile)throw new Error("volatile already set");this._volatile=this._requiredType(e,"volatile","boolean");return this}blockConfirmations(e){if("undefined"!=typeof this._blockConfirmations)throw new Error("blockConfirmations already set.");this._blockConfirmations=this._requiredType(e,"confirmations","number");return this}feature(...e){this._features.addAll(e);return this}reverseProxy(e,t,...s){if("ws"!==this._protocol&&"wss"!==this._protocol)throw new Error("Protocol must be ws or wss for reverse proxy.");this._reverseProxy={enabled:!0,port:this._requiredType(e,"port","number"),header:this._requiredType(t,"header","string"),addresses:s};return this}build(){if(this._volatile&&this._features.contains(Client.Feature.LOCAL_HISTORY))throw new Error("Local history is not available with volatile storage");this._protocol||(PlatformUtils.supportsWebRTC()?this._protocol="rtc":this._protocol="dumb");this._reverseProxy||(this._reverseProxy={enabled:!1});"number"!=typeof this._blockConfirmations&&(this._blockConfirmations=10);let e;switch(this._protocol){case"dumb":e=new DumbNetworkConfig;break;case"rtc":if(!PlatformUtils.supportsWebRTC())throw new Error("WebRTC not supported on this platform");e=new RtcNetworkConfig;break;case"ws":e=new WsNetworkConfig(this._host,this._port,this._reverseProxy);break;case"wss":e=new WssNetworkConfig(this._host,this._port,this._tlsKey,this._tlsCert,this._reverseProxy)}return new Client.Configuration(e,this._features.values(),!!this._volatile,this._blockConfirmations)}instantiateClient(){return this.build().instantiateClient()}_requiredType(e,t,s){if(typeof e!==s)throw new Error(`Type of ${t} must be ${s}, but is ${typeof e}`);return e}_requiredSet(e,t,...s){if(!e)throw new Error(`${t} is required`);if(!s.includes(e))throw new Error(`${t} must be one of: ${s.join(", ")}`);return e}};Client.Feature={MINING:"MINING",LOCAL_HISTORY:"LOCAL_HISTORY",MEMPOOL:"MEMPOOL",PASSIVE:"PASSIVE"};Client.Mempool=class Mempool{constructor(e){this._client=e;this._transactionAddedListeners=new HashMap;this._transactionRemovedListeners=new HashMap;this._listenerId=0}_onTransactionAdded(e){for(const t of this._transactionAddedListeners.valueIterator())t(e.hash())}_onTransactionRemoved(e){for(const t of this._transactionRemovedListeners.valueIterator())t(e.hash())}async getTransactions(){return(await this._client._consensus).getMempoolContents().map(e=>e.hash())}async getStatistics(){const e=await this._client._consensus,t=await e.getHeadHeight();return new Client.MempoolStatistics(e.getMempoolContents(),t)}async addTransactionAddedListener(e){const t=this._listenerId++;this._transactionAddedListeners.put(t,e);return t}async addTransactionRemovedListener(e){const t=this._listenerId++;this._transactionRemovedListeners.put(t,e);return t}removeListener(e){this._transactionAddedListeners.remove(e);this._transactionRemovedListeners.remove(e)}};Client.MempoolStatistics=class MempoolStatistics{constructor(e,t){const s=[1e4,5e3,2e3,1e3,500,200,100,50,20,10,5,2,1,0];this._countPerBucket={buckets:[]};this._sizePerBucket={buckets:[]};this._totalCount=e.length;this._totalSize=0;this._requiredFeePerByte=0;const r=Policy.blockSize(t);for(const n of e){let e=0;for(;e<s.length&&n.feePerByte.lt(s[e]);)e++;const t=s[e];if(t!==undefined){if(!this._countPerBucket[t]){this._countPerBucket[t]=0;this._countPerBucket.buckets.push(t);this._sizePerBucket[t]=0;this._sizePerBucket.buckets.push(t)}this._countPerBucket[t]++;this._sizePerBucket[t]+=n.serializedSize}this._totalSize+=n.serializedSize;this._totalSize<r&&(this._requiredFeePerByte=n.feePerByte)}this._totalSize<r&&(this._requiredFeePerByte=0)}get count(){return this._totalCount}get size(){return this._totalSize}get requiredFeePerByte(){return this._requiredFeePerByte}get countInBuckets(){return this._countPerBucket}get sizeInBuckets(){return this._sizePerBucket}};Client.Network=class Network{constructor(e){this._client=e}async getPeers(){const e=await this._client._consensus,t=[];for(const s of e.network.connections.valueIterator())t.push(new Client.PeerInfo(s));return t}async getPeer(e){const t=(await this._client._consensus).network.connections.getConnectionByPeerAddress(await this._toPeerAddress(e));return t?new Client.PeerInfo(t):null}async getAddresses(){const e=await this._client._consensus,t=[];for(const s of e.network.addresses.iterator())t.push(new Client.AddressInfo(s));return t}async getAddress(e){const t=(await this._client._consensus).network.addresses.getState(await this._toPeerAddress(e));return t?new Client.AddressInfo(t):null}async getOwnAddress(){const e=await this._client._consensus;return new Client.BasicAddress(e.network.config.peerAddress)}async getStatistics(){const e=await this._client._consensus;return new Client.NetworkStatistics(e.network)}async connect(e){(await this._client._consensus).network.connections.connectOutbound(await this._toPeerAddress(e))}async disconnect(e){const t=(await this._client._consensus).network.connections.getConnectionByPeerAddress(await this._toPeerAddress(e));t&&t.peerChannel.close(CloseType.MANUAL_PEER_DISCONNECT)}async ban(e){const t=await this._client._consensus,s=await this._toPeerAddress(e),r=t.network.connections.getConnectionByPeerAddress(s);if(r)r.peerChannel.close(CloseType.MANUAL_PEER_BAN);else{t.network.addresses.getState(s).state=PeerAddressState.BANNED}}async unban(e){(await this._client._consensus).network.addresses.getState(await this._toPeerAddress(e)).state=PeerAddressState.TRIED}async _toPeerAddress(e){const t=await this._client._consensus;let s;if(e instanceof PeerAddress)s=t.network.addresses.get(e);else if(e instanceof Client.BasicAddress)s=t.network.addresses.get(e.peerAddress);else if("string"==typeof e)for(const r of t.network.addresses.iterator())if(r.peerAddress.toString()===e){s=r.peerAddress;break}if(!s)throw new Error("Invalid or unknown peer address");return s}};Client.BasicAddress=class BasicAddress{constructor(e){this._address=e}get peerAddress(){return this._address}get peerId(){return this._address.peerId}get services(){return Services.toNameArray(Services.legacyProvideToCurrent(this._address.services))}get netAddress(){return this._address.netAddress}toPlain(){return{peerAddress:this.peerAddress.toString(),peerId:this.peerId.toString(),services:this.services,netAddress:this.netAddress?{ip:this.netAddress.ip,reliable:this.netAddress.reliable}:null}}};Client.AddressInfo=class AddressInfo extends Client.BasicAddress{constructor(e){super(e.peerAddress);this._state=e.state}get banned(){return this._state===PeerAddressState.BANNED}get connected(){return this._state===PeerAddressState.ESTABLISHED}get state(){return this._state}toPlain(){const e=super.toPlain();e.banned=this.banned;e.connected=this.connected;return e}};Client.PeerInfo=class PeerInfo extends Client.BasicAddress{constructor(e){super(e.peerAddress);this._connection=e;const t=this._connection.networkConnection,s=this._connection.peer;this._bytesReceived=t?t.bytesReceived:0;this._bytesSent=t?t.bytesSent:0;this._latency=this._connection.statistics.latencyMedian;this._state=this._connection.state;this._version=s?s.version:undefined;this._timeOffset=s?s.timeOffset:undefined;this._headHash=s?s.headHash:undefined;this._userAgent=s?s.userAgent:undefined}get connectionSince(){return this._connection.establishedSince}get netAddress(){return this._connection.networkConnection.netAddress}get bytesReceived(){return this._bytesReceived}get bytesSent(){return this._bytesSent}get latency(){return this._latency}get version(){return this._version}get state(){return this._state}get timeOffset(){return this._timeOffset}get headHash(){return this._headHash}get userAgent(){return this._userAgent}toPlain(){const e=super.toPlain();e.connectionSince=this.connectionSince;e.bytesReceived=this.bytesReceived;e.bytesSent=this.bytesSent;e.latency=this.latency;e.version=this.version;e.state=this.state;e.timeOffset=this.timeOffset;e.headHash=this.headHash.toPlain();e.userAgent=this.userAgent;return e}};Client.NetworkStatistics=class NetworkStatistics{constructor(e){this._bytesReceived=e.bytesReceived;this._bytesSent=e.bytesSent;this._peerCounts={total:e.peerCount,connecting:e.peerCountConnecting,dumb:e.peerCountDumb,rtc:e.peerCountWebRtc,ws:e.peerCountWebSocket,wss:e.peerCountWebSocketSecure};this._knownAddressesCounts={total:e.knownAddressesCount,rtc:e.addresses.knownRtcAddressesCount,ws:e.addresses.knownWsAddressesCount,wss:e.addresses.knownWssAddressesCount};this._timeOffset=e.time.offset}get bytesReceived(){return this._bytesReceived}get bytesSent(){return this._bytesSent}get totalPeerCount(){return this._peerCounts.total}get peerCountsByType(){return this._peerCounts}get totalKnownAddresses(){return this._knownAddressesCounts.total}get knownAddressesByType(){return this._knownAddressesCounts}get timeOffset(){return this._timeOffset}toPlain(){return{bytesReceived:this.bytesReceived,bytesSent:this.bytesSent,totalPeerCount:this.totalPeerCount,peerCountsByType:this.peerCountsByType,totalKnownAddresses:this.totalKnownAddresses,knownAddressesByType:this.knownAddressesByType,timeOffset:this.timeOffset}}};Client.TransactionDetails=class TransactionDetails{constructor(e,t,s,r,n,i){this._transaction=e;this._state=t;this._blockHash=s;this._blockHeight=r;this._confirmations=n;this._timestamp=i}get transactionHash(){return this._transaction.hash()}get format(){return this._transaction.format}get sender(){return this._transaction.sender}get senderType(){return this._transaction.senderType}get recipient(){return this._transaction.recipient}get recipientType(){return this._transaction.recipientType}get value(){return this._transaction.value}get fee(){return this._transaction.fee}get feePerByte(){return this._transaction.feePerByte}get validityStartHeight(){return this._transaction.validityStartHeight}get network(){return this._transaction.networkId}get flags(){return this._transaction.flags}get data(){const e=Account.TYPE_MAP.get(this.recipientType).dataToPlain(this._transaction.data);e.raw=this._transaction.data;return e}get proof(){const e=Account.TYPE_MAP.get(this.senderType).proofToPlain(this._transaction.proof);e.raw=this._transaction.proof;return e}get size(){return this._transaction.serializedSize}get valid(){return this._transaction.verify()}get transaction(){return this._transaction}get state(){return this._state}get blockHash(){return this._blockHash}get blockHeight(){return this._blockHeight}get confirmations(){return this._confirmations}get timestamp(){return this._timestamp}toPlain(){const e=this._transaction.toPlain();e.state=this._state;e.blockHash=this._blockHash?this._blockHash.toPlain():null;e.blockHeight=this._blockHeight;e.confirmations=this._confirmations;e.timestamp=this._timestamp;return e}static fromPlain(e){return new Client.TransactionDetails(Transaction.fromPlain(e),e.state||Client.TransactionState.NEW,e.blockHash?Hash.fromAny(e.blockHash):undefined,e.blockHeight||undefined,e.confirmations||undefined,e.timestamp||undefined)}};Client.TransactionState={NEW:"new",PENDING:"pending",MINED:"mined",INVALIDATED:"invalidated",EXPIRED:"expired",CONFIRMED:"confirmed"};Krypton.load=function(e){"undefined"!=typeof window&&(window.Krypton=Krypton);e&&(Krypton._path=e);return Krypton.WasmHelper.doImportBrowser()};export default Krypton;
|
2
|
+
//# sourceMappingURL=web.esm.js.map
|