bch-dex-lib
Advanced tools
Comparing version 1.4.0 to 1.4.1
@@ -1,1 +0,1 @@ | ||
!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).BchDexLib=t()}}((function(){var t={exports:{}},e=Object.prototype.hasOwnProperty,r="~";function n(){}function i(t,e,r){this.fn=t,this.context=e,this.once=r||!1}function o(t,e,n,o,s){if("function"!=typeof n)throw new TypeError("The listener must be a function");var a=new i(n,o||t,s),h=r?r+e:e;return t._events[h]?t._events[h].fn?t._events[h]=[t._events[h],a]:t._events[h].push(a):(t._events[h]=a,t._eventsCount++),t}function s(t,e){0==--t._eventsCount?t._events=new n:delete t._events[e]}function a(){this._events=new n,this._eventsCount=0}Object.create&&(n.prototype=Object.create(null),(new n).__proto__||(r=!1)),a.prototype.eventNames=function(){var t,n,i=[];if(0===this._eventsCount)return i;for(n in t=this._events)e.call(t,n)&&i.push(r?n.slice(1):n);return Object.getOwnPropertySymbols?i.concat(Object.getOwnPropertySymbols(t)):i},a.prototype.listeners=function(t){var e=r?r+t:t,n=this._events[e];if(!n)return[];if(n.fn)return[n.fn];for(var i=0,o=n.length,s=new Array(o);i<o;i++)s[i]=n[i].fn;return s},a.prototype.listenerCount=function(t){var e=r?r+t:t,n=this._events[e];return n?n.fn?1:n.length:0},a.prototype.emit=function(t,e,n,i,o,s){var a=r?r+t:t;if(!this._events[a])return!1;var h,u,l=this._events[a],c=arguments.length;if(l.fn){switch(l.once&&this.removeListener(t,l.fn,void 0,!0),c){case 1:return l.fn.call(l.context),!0;case 2:return l.fn.call(l.context,e),!0;case 3:return l.fn.call(l.context,e,n),!0;case 4:return l.fn.call(l.context,e,n,i),!0;case 5:return l.fn.call(l.context,e,n,i,o),!0;case 6:return l.fn.call(l.context,e,n,i,o,s),!0}for(u=1,h=new Array(c-1);u<c;u++)h[u-1]=arguments[u];l.fn.apply(l.context,h)}else{var d,p=l.length;for(u=0;u<p;u++)switch(l[u].once&&this.removeListener(t,l[u].fn,void 0,!0),c){case 1:l[u].fn.call(l[u].context);break;case 2:l[u].fn.call(l[u].context,e);break;case 3:l[u].fn.call(l[u].context,e,n);break;case 4:l[u].fn.call(l[u].context,e,n,i);break;default:if(!h)for(d=1,h=new Array(c-1);d<c;d++)h[d-1]=arguments[d];l[u].fn.apply(l[u].context,h)}}return!0},a.prototype.on=function(t,e,r){return o(this,t,e,r,!1)},a.prototype.once=function(t,e,r){return o(this,t,e,r,!0)},a.prototype.removeListener=function(t,e,n,i){var o=r?r+t:t;if(!this._events[o])return this;if(!e)return s(this,o),this;var a=this._events[o];if(a.fn)a.fn!==e||i&&!a.once||n&&a.context!==n||s(this,o);else{for(var h=0,u=[],l=a.length;h<l;h++)(a[h].fn!==e||i&&!a[h].once||n&&a[h].context!==n)&&u.push(a[h]);u.length?this._events[o]=1===u.length?u[0]:u:s(this,o)}return this},a.prototype.removeAllListeners=function(t){var e;return t?(e=r?r+t:t,this._events[e]&&s(this,e)):(this._events=new n,this._eventsCount=0),this},a.prototype.off=a.prototype.removeListener,a.prototype.addListener=a.prototype.on,a.prefixed=r,a.EventEmitter=a,t.exports=a,t=t.exports;var h={};class u{constructor(){this._queue=[]}enqueue(t,e){const r={priority:(e=Object.assign({priority:0},e)).priority,run:t};if(this.size&&this._queue[this.size-1].priority>=e.priority)return void this._queue.push(r);const n=function(t,e,r){let n=0,i=t.length;for(;i>0;){const r=i/2|0;let s=n+r;o=t[s],e.priority-o.priority<=0?(n=++s,i-=r+1):i=r}var o;return n}(this._queue,r);this._queue.splice(n,0,r)}dequeue(){return this._queue.shift().run}get size(){return this._queue.length}}class l extends t{constructor(t){if(super(),!("number"==typeof(t=Object.assign({carryoverConcurrencyCount:!1,intervalCap:1/0,interval:0,concurrency:1/0,autoStart:!0,queueClass:u},t)).concurrency&&t.concurrency>=1))throw new TypeError(`Expected \`concurrency\` to be a number from 1 and up, got \`${t.concurrency}\` (${typeof t.concurrency})`);if(!("number"==typeof t.intervalCap&&t.intervalCap>=1))throw new TypeError(`Expected \`intervalCap\` to be a number from 1 and up, got \`${t.intervalCap}\` (${typeof t.intervalCap})`);if(!(Number.isFinite(t.interval)&&t.interval>=0))throw new TypeError(`Expected \`interval\` to be a finite number >= 0, got \`${t.interval}\` (${typeof t.interval})`);this._carryoverConcurrencyCount=t.carryoverConcurrencyCount,this._isIntervalIgnored=t.intervalCap===1/0||0===t.interval,this._intervalCount=0,this._intervalCap=t.intervalCap,this._interval=t.interval,this._intervalId=null,this._intervalEnd=0,this._timeoutId=null,this.queue=new t.queueClass,this._queueClass=t.queueClass,this._pendingCount=0,this._concurrency=t.concurrency,this._isPaused=!1===t.autoStart,this._resolveEmpty=()=>{},this._resolveIdle=()=>{}}get _doesIntervalAllowAnother(){return this._isIntervalIgnored||this._intervalCount<this._intervalCap}get _doesConcurrentAllowAnother(){return this._pendingCount<this._concurrency}_next(){this._pendingCount--,this._tryToStartAnother()}_resolvePromises(){this._resolveEmpty(),this._resolveEmpty=()=>{},0===this._pendingCount&&(this._resolveIdle(),this._resolveIdle=()=>{})}_onResumeInterval(){this._onInterval(),this._initializeIntervalIfNeeded(),this._timeoutId=null}_intervalPaused(){const t=Date.now();if(null===this._intervalId){const e=this._intervalEnd-t;if(!(e<0))return null===this._timeoutId&&(this._timeoutId=setTimeout(()=>this._onResumeInterval(),e)),!0;this._intervalCount=this._carryoverConcurrencyCount?this._pendingCount:0}return!1}_tryToStartAnother(){if(0===this.queue.size)return clearInterval(this._intervalId),this._intervalId=null,this._resolvePromises(),!1;if(!this._isPaused){const t=!this._intervalPaused();if(this._doesIntervalAllowAnother&&this._doesConcurrentAllowAnother)return this.emit("active"),this.queue.dequeue()(),t&&this._initializeIntervalIfNeeded(),!0}return!1}_initializeIntervalIfNeeded(){this._isIntervalIgnored||null!==this._intervalId||(this._intervalId=setInterval(()=>this._onInterval(),this._interval),this._intervalEnd=Date.now()+this._interval)}_onInterval(){for(0===this._intervalCount&&0===this._pendingCount&&(clearInterval(this._intervalId),this._intervalId=null),this._intervalCount=this._carryoverConcurrencyCount?this._pendingCount:0;this._tryToStartAnother(););}add(t,e){return new Promise((r,n)=>{this.queue.enqueue(()=>{this._pendingCount++,this._intervalCount++;try{Promise.resolve(t()).then(t=>{r(t),this._next()},t=>{n(t),this._next()})}catch(e){n(e),this._next()}},e),this._tryToStartAnother()})}addAll(t,e){return Promise.all(t.map(t=>this.add(t,e)))}start(){if(this._isPaused)for(this._isPaused=!1;this._tryToStartAnother(););}pause(){this._isPaused=!0}clear(){this.queue=new this._queueClass}onEmpty(){return 0===this.queue.size?Promise.resolve():new Promise(t=>{const e=this._resolveEmpty;this._resolveEmpty=()=>{e(),t()}})}onIdle(){return 0===this._pendingCount&&0===this.queue.size?Promise.resolve():new Promise(t=>{const e=this._resolveIdle;this._resolveIdle=()=>{e(),t()}})}get size(){return this.queue.size}get pending(){return this._pendingCount}get isPaused(){return this._isPaused}}(h=l).default=l;var c={};function d(t,e){"boolean"==typeof e&&(e={forever:e}),this._originalTimeouts=JSON.parse(JSON.stringify(t)),this._timeouts=t,this._options=e||{},this._maxRetryTime=e&&e.maxRetryTime||1/0,this._fn=null,this._errors=[],this._attempts=1,this._operationTimeout=null,this._operationTimeoutCb=null,this._timeout=null,this._operationStart=null,this._timer=null,this._options.forever&&(this._cachedTimeouts=this._timeouts.slice(0))}c=d,d.prototype.reset=function(){this._attempts=1,this._timeouts=this._originalTimeouts.slice(0)},d.prototype.stop=function(){this._timeout&&clearTimeout(this._timeout),this._timer&&clearTimeout(this._timer),this._timeouts=[],this._cachedTimeouts=null},d.prototype.retry=function(t){if(this._timeout&&clearTimeout(this._timeout),!t)return!1;var e=(new Date).getTime();if(t&&e-this._operationStart>=this._maxRetryTime)return this._errors.push(t),this._errors.unshift(new Error("RetryOperation timeout occurred")),!1;this._errors.push(t);var r=this._timeouts.shift();if(void 0===r){if(!this._cachedTimeouts)return!1;this._errors.splice(0,this._errors.length-1),r=this._cachedTimeouts.slice(-1)}var n=this;return this._timer=setTimeout((function(){n._attempts++,n._operationTimeoutCb&&(n._timeout=setTimeout((function(){n._operationTimeoutCb(n._attempts)}),n._operationTimeout),n._options.unref&&n._timeout.unref()),n._fn(n._attempts)}),r),this._options.unref&&this._timer.unref(),!0},d.prototype.attempt=function(t,e){this._fn=t,e&&(e.timeout&&(this._operationTimeout=e.timeout),e.cb&&(this._operationTimeoutCb=e.cb));var r=this;this._operationTimeoutCb&&(this._timeout=setTimeout((function(){r._operationTimeoutCb()}),r._operationTimeout)),this._operationStart=(new Date).getTime(),this._fn(this._attempts)},d.prototype.try=function(t){console.log("Using RetryOperation.try() is deprecated"),this.attempt(t)},d.prototype.start=function(t){console.log("Using RetryOperation.start() is deprecated"),this.attempt(t)},d.prototype.start=d.prototype.try,d.prototype.errors=function(){return this._errors},d.prototype.attempts=function(){return this._attempts},d.prototype.mainError=function(){if(0===this._errors.length)return null;for(var t={},e=null,r=0,n=0;n<this._errors.length;n++){var i=this._errors[n],o=i.message,s=(t[o]||0)+1;t[o]=s,s>=r&&(e=i,r=s)}return e};var p={operation:function(t){var e=p.timeouts(t);return new c(e,{forever:t&&(t.forever||t.retries===1/0),unref:t&&t.unref,maxRetryTime:t&&t.maxRetryTime})},timeouts:function(t){if(t instanceof Array)return[].concat(t);var e={retries:10,factor:2,minTimeout:1e3,maxTimeout:1/0,randomize:!1};for(var r in t)e[r]=t[r];if(e.minTimeout>e.maxTimeout)throw new Error("minTimeout is greater than maxTimeout");for(var n=[],i=0;i<e.retries;i++)n.push(this.createTimeout(i,e));return t&&t.forever&&!n.length&&n.push(this.createTimeout(i,e)),n.sort((function(t,e){return t-e})),n},createTimeout:function(t,e){var r=e.randomize?Math.random()+1:1,n=Math.round(r*Math.max(e.minTimeout,1)*Math.pow(e.factor,t));return Math.min(n,e.maxTimeout)},wrap:function(t,e,r){if(e instanceof Array&&(r=e,e=null),!r)for(var n in r=[],t)"function"==typeof t[n]&&r.push(n);for(var i=0;i<r.length;i++){var o=r[i],s=t[o];t[o]=function(r){var n=p.operation(e),i=Array.prototype.slice.call(arguments,1),o=i.pop();i.push((function(t){n.retry(t)||(t&&(arguments[0]=n.mainError()),o.apply(this,arguments))})),n.attempt((function(){r.apply(t,i)}))}.bind(t,s),t[o].options=e}}},f=p,w={};const m=["Failed to fetch","NetworkError when attempting to fetch resource.","The Internet connection appears to be offline.","Network request failed"];class y extends Error{constructor(t){super(),t instanceof Error?(this.originalError=t,({message:t}=t)):(this.originalError=new Error(t),this.originalError.stack=this.stack),this.name="AbortError",this.message=t}}const _=(t,e)=>new Promise((r,n)=>{e={onFailedAttempt:()=>{},retries:10,...e};const i=f.operation(e);i.attempt(async o=>{try{r(await t(o))}catch(a){if(!(a instanceof Error))return void n(new TypeError(`Non-error was thrown: "${a}". You should only throw errors.`));if(a instanceof y)i.stop(),n(a.originalError);else if(a instanceof TypeError&&(s=a.message,!m.includes(s)))i.stop(),n(a);else{((t,e,r)=>{const n=r.retries-(e-1);t.attemptNumber=e,t.retriesLeft=n})(a,o,e);try{await e.onFailedAttempt(a)}catch(a){return void n(a)}i.retry(a)||n(i.mainError())}}var s})});(w=_).default=_,w.AbortError=y;var b=class{constructor(t={}){let e=1;this.attempts=5,this.retryPeriod=5e3,t.concurrency&&(e=t.concurrency),t.attempts&&(this.attempts=t.attempts),t.retryPeriod&&(this.retryPeriod=t.retryPeriod),this.validationQueue=new h({concurrency:e}),this.pRetry=w,this.addToQueue=this.addToQueue.bind(this),this.retryWrapper=this.retryWrapper.bind(this),this.handleValidationError=this.handleValidationError.bind(this)}async addToQueue(t,e){try{if(!t)throw new Error("function handler is required");if(!e)throw new Error("input object is required");return await this.validationQueue.add(()=>this.retryWrapper(t,e))}catch(r){throw console.error("Error in addToQueue(): ",r),r}}async retryWrapper(t,e){try{if(!t)throw new Error("function handler is required");if(!e)throw new Error("input object is required");return this.pRetry(async()=>await t(e),{onFailedAttempt:this.handleValidationError,retries:this.attempts})}catch(r){throw console.error("Error in retryWrapper(): ",r),r}}async handleValidationError(t){try{console.log("Error object: ",t);const e=`Attempt ${t.attemptNumber} failed. There are ${t.retriesLeft} retries left. Waiting before trying again.`;console.log(e);const r=this.retryPeriod;console.log(`Waiting ${r} milliseconds before trying again.\n`),await this.sleep(r)}catch(e){throw console.error("Error in handleValidationError()"),e}}sleep(t){return new Promise(e=>setTimeout(e,t))}};return class{constructor(t={}){if(!t.bchWallet)throw new Error("Instance of minimal-slp-wallet must be passed as wallet property when instantiating the bch-dex-lib library.");if(this.bchWallet=t.bchWallet,!t.p2wdbRead)throw new Error("Instance of p2wdb must be passed as wallet property when instantiating the bch-dex-lib library.");if(this.p2wdbRead=t.p2wdbRead,!t.p2wdbWrite)throw new Error("Instance of p2wdb Write must be passed as p2wdbWrite property when instantiating the bch-dex-lib library.");this.p2wdbWrite=t.p2wdbWrite;const e={bchWallet:this.bchWallet,p2wdbRead:this.p2wdbRead,p2wdbWrite:this.p2wdbWrite};this.take=new class{constructor(t={}){if(!t.bchWallet)throw new Error("Instance of minimal-slp-wallet must be passed as wallet property when instantiating Take library.");if(this.bchWallet=t.bchWallet,!t.p2wdbRead)throw new Error("Instance of p2wdb Read must be passed as p2wdbRead property when instantiating Take library.");if(this.p2wdbRead=t.p2wdbRead,!t.p2wdbWrite)throw new Error("Instance of p2wdb Write must be passed as p2wdbWrite property when instantiating Take library.");this.p2wdbWrite=t.p2wdbWrite,this.util=new class{constructor(t={}){if(!t.bchWallet)throw new Error("Instance of minimal-slp-wallet must be passed as wallet property when instantiating bch-dex-util library.");if(this.bchWallet=t.bchWallet,!t.p2wdbRead)throw new Error("Instance of p2wdb Read must be passed as p2wdbRead property when instantiating bch-dex-util library.");this.p2wdbRead=t.p2wdbRead,this.getEntryFromP2wdb=this.getEntryFromP2wdb.bind(this),this.validateUtxo=this.validateUtxo.bind(this),this.getKeyPair=this.getKeyPair.bind(this)}async getEntryFromP2wdb(t){const e=await this.p2wdbRead.getByHash(t),r=e.value.data;let n;try{n=JSON.parse(r)}catch(i){n=e.value.data}return n}async validateUtxo(t){return await this.bchWallet.utxoIsValid(t)}async getKeyPair(t=0){const e=this.bchWallet.walletInfo.mnemonic;if(!e)throw new Error("Wallet does not have a mnemonic. Can not generate a new key pair.");const r=await this.bchWallet.bchjs.Mnemonic.toSeed(e),n=this.bchWallet.bchjs.HDNode.fromSeed(r).derivePath("m/44'/245'/0'/0/"+t),i=this.bchWallet.bchjs.HDNode.toCashAddress(n);return console.log("Generating a new key pair for cashAddress: ",i),{cashAddress:i,wif:this.bchWallet.bchjs.HDNode.toWIF(n),hdIndex:t}}}(t),this.retryQueue=new b({attempts:3,retryPeriod:1e3}),this.takeOffer=this.takeOffer.bind(this),this.ensureFunds=this.ensureFunds.bind(this),this.moveBch=this.moveBch.bind(this),this.generatePartialTx=this.generatePartialTx.bind(this),this.uploadCounterOffer=this.uploadCounterOffer.bind(this)}async takeOffer(t){try{const e=await this.retryQueue.addToQueue(this.util.getEntryFromP2wdb,t);console.log("offerData: ",e);const r={tx_hash:e.data.utxoTxid,tx_pos:e.data.utxoVout};if(!await this.retryQueue.addToQueue(this.util.validateUtxo,r))throw new Error("Offer is not valid. UTXO has been spent.");const{hasEnoughFunds:n,bchAddr:i}=await this.retryQueue.addToQueue(this.ensureFunds,e);if(console.log("bchAddr: ",i),!n)throw new Error("This wallet does not have enough BCH to Counter the selected Offer.");const o=await this.retryQueue.addToQueue(this.moveBch,e);console.log("Counter Offer UTXO: ",o);const s=e,a=await this.retryQueue.addToQueue(this.generatePartialTx,{offerInfo:s,utxoInfo:o});console.log("partial tx hex: ",a);const h=t,u=a,l=await this.retryQueue.addToQueue(this.uploadCounterOffer,{offerData:e,partialHex:u,offerCid:h});return console.log("Counter Offer uploaded to P2WDB with this CID: "+l.hash.hash),l}catch(e){throw console.error("Error in bch-dex-lib/take.js takeOffer(): ",e),e}}async uploadCounterOffer(t={}){try{const{offerData:e,partialHex:r,offerCid:n}=t;console.log("uploadCounterOffer() offerData: "+JSON.stringify(e,null,2));const i=Object.assign({},e.data);return i.partialTxHex=r,delete i.p2wdbHash,delete i._id,i.offerHash=n,i.dataType="counter-offer",console.log("counterOfferData: "+JSON.stringify(i,null,2)),await this.p2wdbWrite.bchWallet.initialize(),await this.p2wdbWrite.postEntry(i,e.appId)}catch(e){throw console.error("Error in uploadCounterOffer(): ",e),e}}async generatePartialTx(t={}){try{const{offerInfo:e,utxoInfo:r}=t,n=this.bchWallet.bchjs,i=new n.TransactionBuilder,o=await this.bchWallet.getTxData([e.data.utxoTxid]),s={txid:e.data.utxoTxid,vout:e.data.utxoVout,tokenId:e.data.tokenId,decimals:o[0].tokenDecimals,tokenQty:e.data.numTokens.toString()};let a;if(65===e.data.tokenType)a=n.SLP.NFT1.generateNFTChildSendOpReturn([s],e.data.numTokens.toString());else{if(1!==e.data.tokenType)throw new Error(`Unknown token type of ${e.data.tokenType}. Can not create Counter Offer.`);a=n.SLP.TokenType1.generateSendOpReturn([s],e.data.numTokens.toString())}const h=a.script;if(a.outputs>1)throw new Error("Partial purchase of Offers is not yet supported");const u=e.data.numTokens*parseInt(e.data.rateInBaseUnit);if(isNaN(u))throw new Error("Can not calculate needed sats");i.addInput(e.data.utxoTxid,e.data.utxoVout),i.addInput(r.txid,r.vout);const l=546;i.addOutput(h,0);const c=this.bchWallet.walletInfo.legacyAddress;i.addOutput(c,l);const d=e.data.makerAddr;i.addOutput(d,u);const p=n.ECPair.fromWIF(r.wif);return i.sign(1,p,null,i.hashTypes.SIGHASH_ALL,r.sats),i.transaction.buildIncomplete().toHex()}catch(e){throw console.error("Error in generatePartialTx(): ",e),e}}async moveBch(t={},e=1){let r=t.data.numTokens*parseInt(t.data.rateInBaseUnit);if(isNaN(r))throw new Error("Could not calculate the amount of BCH to generate counter offer");r+=1e3;const n=await this.util.getKeyPair(e),i=[{address:n.cashAddress,amountSat:r}];await this.bchWallet.getUtxos();const o={txid:await this.bchWallet.send(i),vout:0,hdIndex:n.hdIndex,wif:n.wif,sats:r};return console.log(`BCH moved to ${n.cashAddress} with WIF ${n.wif}`),o}async ensureFunds(t){const{hasEnoughPsf:e,hasEnoughBch:r,bchAddr:n}=await this.p2wdbWrite.checkForSufficientFunds();if(!e&&!r)throw new Error("Wallet does not have enough BCH to write to the P2WDB.");let i=0;if(r&&(i=this.bchWallet.bchjs.BitcoinCash.toSatoshi(r)),!t.data.buyOrSell.includes("sell"))throw new Error("Buy offers are not supported yet.");{const e=t.data.numTokens*parseInt(t.data.rateInBaseUnit);if(isNaN(e))throw new Error("Could not calculate sats needed!");const r=await this.bchWallet.getBalance();console.log(`wallet balance: ${r}, sats needed: ${e}`);const n=e+5e3+i;if(n>r)throw new Error(`Wallet does not control enough BCH to purchase the tokens. It has ${r} sats, and needs ${n} sats.`)}return{hasEnoughFunds:!0,bchAddr:n}}}(e),this.flag=new class{constructor(t={}){if(!t.bchWallet)throw new Error("Instance of minimal-slp-wallet must be passed as wallet property when instantiating Flag library.");if(this.bchWallet=t.bchWallet,!t.p2wdbWrite)throw new Error("Instance of p2wdb Write must be passed as p2wdbWrite property when instantiating Flag library.");this.p2wdbWrite=t.p2wdbWrite}async flagOffer(t){try{const e={p2wdbHash:t,nsfw:!0,dataType:"flag"};return await this.p2wdbWrite.bchWallet.initialize(),await this.p2wdbWrite.postEntry(e,"bch-dex-001")}catch(e){throw console.error("Error in bch-dex-lib/flag.js flagOffer(): ",e),e}}}(e),this.tokenData=new class{constructor(t={}){if(!t.bchWallet)throw new Error("Instance of minimal-slp-wallet must be passed as wallet property when instantiating TokenData library.");this.bchWallet=t.bchWallet,this.tokenIdsCache=[],this.tokenDataCache={}}async getTokenData(t={},e){if(!t.tokenId)throw new Error("offer input object must contain a tokenId property when calling getTokenData()");if(!e)throw new Error("callbackFunc required when calling getTokenData()");const r=t.tokenId;if(this.tokenIdsCache.includes(r))return t.tokenData=this.tokenDataCache[r],t;const n=await this.bchWallet.getTokenData2(r);return this.tokenIdsCache.push(r),this.tokenDataCache[r]=n,t.tokenData=n,e(t),!0}}(e)}}})); | ||
!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).BchDexLib=t()}}((function(){var t={exports:{}},e=Object.prototype.hasOwnProperty,r="~";function n(){}function i(t,e,r){this.fn=t,this.context=e,this.once=r||!1}function o(t,e,n,o,s){if("function"!=typeof n)throw new TypeError("The listener must be a function");var a=new i(n,o||t,s),h=r?r+e:e;return t._events[h]?t._events[h].fn?t._events[h]=[t._events[h],a]:t._events[h].push(a):(t._events[h]=a,t._eventsCount++),t}function s(t,e){0==--t._eventsCount?t._events=new n:delete t._events[e]}function a(){this._events=new n,this._eventsCount=0}Object.create&&(n.prototype=Object.create(null),(new n).__proto__||(r=!1)),a.prototype.eventNames=function(){var t,n,i=[];if(0===this._eventsCount)return i;for(n in t=this._events)e.call(t,n)&&i.push(r?n.slice(1):n);return Object.getOwnPropertySymbols?i.concat(Object.getOwnPropertySymbols(t)):i},a.prototype.listeners=function(t){var e=r?r+t:t,n=this._events[e];if(!n)return[];if(n.fn)return[n.fn];for(var i=0,o=n.length,s=new Array(o);i<o;i++)s[i]=n[i].fn;return s},a.prototype.listenerCount=function(t){var e=r?r+t:t,n=this._events[e];return n?n.fn?1:n.length:0},a.prototype.emit=function(t,e,n,i,o,s){var a=r?r+t:t;if(!this._events[a])return!1;var h,l,u=this._events[a],c=arguments.length;if(u.fn){switch(u.once&&this.removeListener(t,u.fn,void 0,!0),c){case 1:return u.fn.call(u.context),!0;case 2:return u.fn.call(u.context,e),!0;case 3:return u.fn.call(u.context,e,n),!0;case 4:return u.fn.call(u.context,e,n,i),!0;case 5:return u.fn.call(u.context,e,n,i,o),!0;case 6:return u.fn.call(u.context,e,n,i,o,s),!0}for(l=1,h=new Array(c-1);l<c;l++)h[l-1]=arguments[l];u.fn.apply(u.context,h)}else{var d,p=u.length;for(l=0;l<p;l++)switch(u[l].once&&this.removeListener(t,u[l].fn,void 0,!0),c){case 1:u[l].fn.call(u[l].context);break;case 2:u[l].fn.call(u[l].context,e);break;case 3:u[l].fn.call(u[l].context,e,n);break;case 4:u[l].fn.call(u[l].context,e,n,i);break;default:if(!h)for(d=1,h=new Array(c-1);d<c;d++)h[d-1]=arguments[d];u[l].fn.apply(u[l].context,h)}}return!0},a.prototype.on=function(t,e,r){return o(this,t,e,r,!1)},a.prototype.once=function(t,e,r){return o(this,t,e,r,!0)},a.prototype.removeListener=function(t,e,n,i){var o=r?r+t:t;if(!this._events[o])return this;if(!e)return s(this,o),this;var a=this._events[o];if(a.fn)a.fn!==e||i&&!a.once||n&&a.context!==n||s(this,o);else{for(var h=0,l=[],u=a.length;h<u;h++)(a[h].fn!==e||i&&!a[h].once||n&&a[h].context!==n)&&l.push(a[h]);l.length?this._events[o]=1===l.length?l[0]:l:s(this,o)}return this},a.prototype.removeAllListeners=function(t){var e;return t?(e=r?r+t:t,this._events[e]&&s(this,e)):(this._events=new n,this._eventsCount=0),this},a.prototype.off=a.prototype.removeListener,a.prototype.addListener=a.prototype.on,a.prefixed=r,a.EventEmitter=a,t.exports=a,t=t.exports;var h={};class l{constructor(){this._queue=[]}enqueue(t,e){const r={priority:(e=Object.assign({priority:0},e)).priority,run:t};if(this.size&&this._queue[this.size-1].priority>=e.priority)return void this._queue.push(r);const n=function(t,e,r){let n=0,i=t.length;for(;i>0;){const r=i/2|0;let s=n+r;o=t[s],e.priority-o.priority<=0?(n=++s,i-=r+1):i=r}var o;return n}(this._queue,r);this._queue.splice(n,0,r)}dequeue(){return this._queue.shift().run}get size(){return this._queue.length}}class u extends t{constructor(t){if(super(),!("number"==typeof(t=Object.assign({carryoverConcurrencyCount:!1,intervalCap:1/0,interval:0,concurrency:1/0,autoStart:!0,queueClass:l},t)).concurrency&&t.concurrency>=1))throw new TypeError(`Expected \`concurrency\` to be a number from 1 and up, got \`${t.concurrency}\` (${typeof t.concurrency})`);if(!("number"==typeof t.intervalCap&&t.intervalCap>=1))throw new TypeError(`Expected \`intervalCap\` to be a number from 1 and up, got \`${t.intervalCap}\` (${typeof t.intervalCap})`);if(!(Number.isFinite(t.interval)&&t.interval>=0))throw new TypeError(`Expected \`interval\` to be a finite number >= 0, got \`${t.interval}\` (${typeof t.interval})`);this._carryoverConcurrencyCount=t.carryoverConcurrencyCount,this._isIntervalIgnored=t.intervalCap===1/0||0===t.interval,this._intervalCount=0,this._intervalCap=t.intervalCap,this._interval=t.interval,this._intervalId=null,this._intervalEnd=0,this._timeoutId=null,this.queue=new t.queueClass,this._queueClass=t.queueClass,this._pendingCount=0,this._concurrency=t.concurrency,this._isPaused=!1===t.autoStart,this._resolveEmpty=()=>{},this._resolveIdle=()=>{}}get _doesIntervalAllowAnother(){return this._isIntervalIgnored||this._intervalCount<this._intervalCap}get _doesConcurrentAllowAnother(){return this._pendingCount<this._concurrency}_next(){this._pendingCount--,this._tryToStartAnother()}_resolvePromises(){this._resolveEmpty(),this._resolveEmpty=()=>{},0===this._pendingCount&&(this._resolveIdle(),this._resolveIdle=()=>{})}_onResumeInterval(){this._onInterval(),this._initializeIntervalIfNeeded(),this._timeoutId=null}_intervalPaused(){const t=Date.now();if(null===this._intervalId){const e=this._intervalEnd-t;if(!(e<0))return null===this._timeoutId&&(this._timeoutId=setTimeout(()=>this._onResumeInterval(),e)),!0;this._intervalCount=this._carryoverConcurrencyCount?this._pendingCount:0}return!1}_tryToStartAnother(){if(0===this.queue.size)return clearInterval(this._intervalId),this._intervalId=null,this._resolvePromises(),!1;if(!this._isPaused){const t=!this._intervalPaused();if(this._doesIntervalAllowAnother&&this._doesConcurrentAllowAnother)return this.emit("active"),this.queue.dequeue()(),t&&this._initializeIntervalIfNeeded(),!0}return!1}_initializeIntervalIfNeeded(){this._isIntervalIgnored||null!==this._intervalId||(this._intervalId=setInterval(()=>this._onInterval(),this._interval),this._intervalEnd=Date.now()+this._interval)}_onInterval(){for(0===this._intervalCount&&0===this._pendingCount&&(clearInterval(this._intervalId),this._intervalId=null),this._intervalCount=this._carryoverConcurrencyCount?this._pendingCount:0;this._tryToStartAnother(););}add(t,e){return new Promise((r,n)=>{this.queue.enqueue(()=>{this._pendingCount++,this._intervalCount++;try{Promise.resolve(t()).then(t=>{r(t),this._next()},t=>{n(t),this._next()})}catch(e){n(e),this._next()}},e),this._tryToStartAnother()})}addAll(t,e){return Promise.all(t.map(t=>this.add(t,e)))}start(){if(this._isPaused)for(this._isPaused=!1;this._tryToStartAnother(););}pause(){this._isPaused=!0}clear(){this.queue=new this._queueClass}onEmpty(){return 0===this.queue.size?Promise.resolve():new Promise(t=>{const e=this._resolveEmpty;this._resolveEmpty=()=>{e(),t()}})}onIdle(){return 0===this._pendingCount&&0===this.queue.size?Promise.resolve():new Promise(t=>{const e=this._resolveIdle;this._resolveIdle=()=>{e(),t()}})}get size(){return this.queue.size}get pending(){return this._pendingCount}get isPaused(){return this._isPaused}}(h=u).default=u;var c={};function d(t,e){"boolean"==typeof e&&(e={forever:e}),this._originalTimeouts=JSON.parse(JSON.stringify(t)),this._timeouts=t,this._options=e||{},this._maxRetryTime=e&&e.maxRetryTime||1/0,this._fn=null,this._errors=[],this._attempts=1,this._operationTimeout=null,this._operationTimeoutCb=null,this._timeout=null,this._operationStart=null,this._timer=null,this._options.forever&&(this._cachedTimeouts=this._timeouts.slice(0))}c=d,d.prototype.reset=function(){this._attempts=1,this._timeouts=this._originalTimeouts.slice(0)},d.prototype.stop=function(){this._timeout&&clearTimeout(this._timeout),this._timer&&clearTimeout(this._timer),this._timeouts=[],this._cachedTimeouts=null},d.prototype.retry=function(t){if(this._timeout&&clearTimeout(this._timeout),!t)return!1;var e=(new Date).getTime();if(t&&e-this._operationStart>=this._maxRetryTime)return this._errors.push(t),this._errors.unshift(new Error("RetryOperation timeout occurred")),!1;this._errors.push(t);var r=this._timeouts.shift();if(void 0===r){if(!this._cachedTimeouts)return!1;this._errors.splice(0,this._errors.length-1),r=this._cachedTimeouts.slice(-1)}var n=this;return this._timer=setTimeout((function(){n._attempts++,n._operationTimeoutCb&&(n._timeout=setTimeout((function(){n._operationTimeoutCb(n._attempts)}),n._operationTimeout),n._options.unref&&n._timeout.unref()),n._fn(n._attempts)}),r),this._options.unref&&this._timer.unref(),!0},d.prototype.attempt=function(t,e){this._fn=t,e&&(e.timeout&&(this._operationTimeout=e.timeout),e.cb&&(this._operationTimeoutCb=e.cb));var r=this;this._operationTimeoutCb&&(this._timeout=setTimeout((function(){r._operationTimeoutCb()}),r._operationTimeout)),this._operationStart=(new Date).getTime(),this._fn(this._attempts)},d.prototype.try=function(t){console.log("Using RetryOperation.try() is deprecated"),this.attempt(t)},d.prototype.start=function(t){console.log("Using RetryOperation.start() is deprecated"),this.attempt(t)},d.prototype.start=d.prototype.try,d.prototype.errors=function(){return this._errors},d.prototype.attempts=function(){return this._attempts},d.prototype.mainError=function(){if(0===this._errors.length)return null;for(var t={},e=null,r=0,n=0;n<this._errors.length;n++){var i=this._errors[n],o=i.message,s=(t[o]||0)+1;t[o]=s,s>=r&&(e=i,r=s)}return e};var p={operation:function(t){var e=p.timeouts(t);return new c(e,{forever:t&&(t.forever||t.retries===1/0),unref:t&&t.unref,maxRetryTime:t&&t.maxRetryTime})},timeouts:function(t){if(t instanceof Array)return[].concat(t);var e={retries:10,factor:2,minTimeout:1e3,maxTimeout:1/0,randomize:!1};for(var r in t)e[r]=t[r];if(e.minTimeout>e.maxTimeout)throw new Error("minTimeout is greater than maxTimeout");for(var n=[],i=0;i<e.retries;i++)n.push(this.createTimeout(i,e));return t&&t.forever&&!n.length&&n.push(this.createTimeout(i,e)),n.sort((function(t,e){return t-e})),n},createTimeout:function(t,e){var r=e.randomize?Math.random()+1:1,n=Math.round(r*Math.max(e.minTimeout,1)*Math.pow(e.factor,t));return Math.min(n,e.maxTimeout)},wrap:function(t,e,r){if(e instanceof Array&&(r=e,e=null),!r)for(var n in r=[],t)"function"==typeof t[n]&&r.push(n);for(var i=0;i<r.length;i++){var o=r[i],s=t[o];t[o]=function(r){var n=p.operation(e),i=Array.prototype.slice.call(arguments,1),o=i.pop();i.push((function(t){n.retry(t)||(t&&(arguments[0]=n.mainError()),o.apply(this,arguments))})),n.attempt((function(){r.apply(t,i)}))}.bind(t,s),t[o].options=e}}},f=p,w={};const y=["Failed to fetch","NetworkError when attempting to fetch resource.","The Internet connection appears to be offline.","Network request failed"];class m extends Error{constructor(t){super(),t instanceof Error?(this.originalError=t,({message:t}=t)):(this.originalError=new Error(t),this.originalError.stack=this.stack),this.name="AbortError",this.message=t}}const b=(t,e)=>new Promise((r,n)=>{e={onFailedAttempt:()=>{},retries:10,...e};const i=f.operation(e);i.attempt(async o=>{try{r(await t(o))}catch(a){if(!(a instanceof Error))return void n(new TypeError(`Non-error was thrown: "${a}". You should only throw errors.`));if(a instanceof m)i.stop(),n(a.originalError);else if(a instanceof TypeError&&(s=a.message,!y.includes(s)))i.stop(),n(a);else{((t,e,r)=>{const n=r.retries-(e-1);t.attemptNumber=e,t.retriesLeft=n})(a,o,e);try{await e.onFailedAttempt(a)}catch(a){return void n(a)}i.retry(a)||n(i.mainError())}}var s})});(w=b).default=b,w.AbortError=m;var _=class{constructor(t={}){let e=1;this.attempts=5,this.retryPeriod=5e3,t.concurrency&&(e=t.concurrency),t.attempts&&(this.attempts=t.attempts),t.retryPeriod&&(this.retryPeriod=t.retryPeriod),this.validationQueue=new h({concurrency:e}),this.pRetry=w,this.addToQueue=this.addToQueue.bind(this),this.retryWrapper=this.retryWrapper.bind(this),this.handleValidationError=this.handleValidationError.bind(this)}async addToQueue(t,e){try{if(!t)throw new Error("function handler is required");if(!e)throw new Error("input object is required");return await this.validationQueue.add(()=>this.retryWrapper(t,e))}catch(r){throw console.error("Error in addToQueue(): ",r),r}}async retryWrapper(t,e){try{if(!t)throw new Error("function handler is required");if(!e)throw new Error("input object is required");return this.pRetry(async()=>await t(e),{onFailedAttempt:this.handleValidationError,retries:this.attempts})}catch(r){throw console.error("Error in retryWrapper(): ",r),r}}async handleValidationError(t){try{console.log("Error object: ",t);const e=`Attempt ${t.attemptNumber} failed. There are ${t.retriesLeft} retries left. Waiting before trying again.`;console.log(e);const r=this.retryPeriod;console.log(`Waiting ${r} milliseconds before trying again.\n`),await this.sleep(r)}catch(e){throw console.error("Error in handleValidationError()"),e}}sleep(t){return new Promise(e=>setTimeout(e,t))}};return class{constructor(t={}){if(!t.bchWallet)throw new Error("Instance of minimal-slp-wallet must be passed as wallet property when instantiating the bch-dex-lib library.");if(this.bchWallet=t.bchWallet,!t.p2wdbRead)throw new Error("Instance of p2wdb must be passed as wallet property when instantiating the bch-dex-lib library.");if(this.p2wdbRead=t.p2wdbRead,!t.p2wdbWrite)throw new Error("Instance of p2wdb Write must be passed as p2wdbWrite property when instantiating the bch-dex-lib library.");this.p2wdbWrite=t.p2wdbWrite;const e={bchWallet:this.bchWallet,p2wdbRead:this.p2wdbRead,p2wdbWrite:this.p2wdbWrite};this.take=new class{constructor(t={}){if(!t.bchWallet)throw new Error("Instance of minimal-slp-wallet must be passed as wallet property when instantiating Take library.");if(this.bchWallet=t.bchWallet,!t.p2wdbRead)throw new Error("Instance of p2wdb Read must be passed as p2wdbRead property when instantiating Take library.");if(this.p2wdbRead=t.p2wdbRead,!t.p2wdbWrite)throw new Error("Instance of p2wdb Write must be passed as p2wdbWrite property when instantiating Take library.");this.p2wdbWrite=t.p2wdbWrite,this.util=new class{constructor(t={}){if(!t.bchWallet)throw new Error("Instance of minimal-slp-wallet must be passed as wallet property when instantiating bch-dex-util library.");if(this.bchWallet=t.bchWallet,!t.p2wdbRead)throw new Error("Instance of p2wdb Read must be passed as p2wdbRead property when instantiating bch-dex-util library.");this.p2wdbRead=t.p2wdbRead,this.getEntryFromP2wdb=this.getEntryFromP2wdb.bind(this),this.validateUtxo=this.validateUtxo.bind(this),this.getKeyPair=this.getKeyPair.bind(this)}async getEntryFromP2wdb(t){const e=await this.p2wdbRead.getByHash(t),r=e.value.data;let n;try{n=JSON.parse(r)}catch(i){n=e.value.data}return n}async validateUtxo(t){return await this.bchWallet.utxoIsValid(t)}async getKeyPair(t=0){const e=this.bchWallet.walletInfo.mnemonic;if(!e)throw new Error("Wallet does not have a mnemonic. Can not generate a new key pair.");const r=await this.bchWallet.bchjs.Mnemonic.toSeed(e),n=this.bchWallet.bchjs.HDNode.fromSeed(r).derivePath("m/44'/245'/0'/0/"+t),i=this.bchWallet.bchjs.HDNode.toCashAddress(n);return console.log("Generating a new key pair for cashAddress: ",i),{cashAddress:i,wif:this.bchWallet.bchjs.HDNode.toWIF(n),hdIndex:t}}}(t),this.retryQueue=new _({attempts:3,retryPeriod:1e3}),this.takeOffer=this.takeOffer.bind(this),this.ensureFunds=this.ensureFunds.bind(this),this.moveBch=this.moveBch.bind(this),this.generatePartialTx=this.generatePartialTx.bind(this),this.uploadCounterOffer=this.uploadCounterOffer.bind(this)}async takeOffer(t){try{const e=await this.retryQueue.addToQueue(this.util.getEntryFromP2wdb,t);console.log("offerData: ",e);const r={tx_hash:e.data.utxoTxid,tx_pos:e.data.utxoVout};if(!await this.retryQueue.addToQueue(this.util.validateUtxo,r))throw new Error("Offer is not valid. UTXO has been spent.");const{hasEnoughFunds:n,bchAddr:i}=await this.retryQueue.addToQueue(this.ensureFunds,e);if(console.log("bchAddr: ",i),!n)throw new Error("This wallet does not have enough BCH to Counter the selected Offer.");const o=await this.retryQueue.addToQueue(this.moveBch,e);console.log("Counter Offer UTXO: ",o);const s=e,a=await this.retryQueue.addToQueue(this.generatePartialTx,{offerInfo:s,utxoInfo:o});console.log("partial tx hex: ",a);const h=t,l=a,u=await this.retryQueue.addToQueue(this.uploadCounterOffer,{offerData:e,partialHex:l,offerCid:h});return console.log("Counter Offer uploaded to P2WDB with this CID: "+u.hash.hash),u}catch(e){throw console.error("Error in bch-dex-lib/take.js takeOffer(): ",e),e}}async uploadCounterOffer(t={}){try{const{offerData:e,partialHex:r,offerCid:n}=t;console.log("uploadCounterOffer() offerData: "+JSON.stringify(e,null,2));const i=Object.assign({},e.data);return i.partialTxHex=r,delete i.p2wdbHash,delete i._id,i.offerHash=n,i.dataType="counter-offer",console.log("counterOfferData: "+JSON.stringify(i,null,2)),await this.p2wdbWrite.bchWallet.initialize(),await this.p2wdbWrite.postEntry(i,e.appId)}catch(e){throw console.error("Error in uploadCounterOffer(): ",e),e}}async generatePartialTx(t={}){try{const{offerInfo:e,utxoInfo:r}=t,n=this.bchWallet.bchjs,i=new n.TransactionBuilder,o=await this.bchWallet.getTxData([e.data.utxoTxid]),s={txid:e.data.utxoTxid,vout:e.data.utxoVout,tokenId:e.data.tokenId,decimals:o[0].tokenDecimals,tokenQty:e.data.numTokens.toString()};let a;if(65===e.data.tokenType)a=n.SLP.NFT1.generateNFTChildSendOpReturn([s],e.data.numTokens.toString());else{if(1!==e.data.tokenType)throw new Error(`Unknown token type of ${e.data.tokenType}. Can not create Counter Offer.`);a=n.SLP.TokenType1.generateSendOpReturn([s],e.data.numTokens.toString())}const h=a.script;if(a.outputs>1)throw new Error("Partial purchase of Offers is not yet supported");const l=Math.ceil(e.data.numTokens*parseInt(e.data.rateInBaseUnit));if(isNaN(l))throw new Error("Can not calculate needed sats");i.addInput(e.data.utxoTxid,e.data.utxoVout),i.addInput(r.txid,r.vout);const u=546;i.addOutput(h,0);const c=this.bchWallet.walletInfo.legacyAddress;console.log("buyerAddr: "+JSON.stringify(c,null,2));const d=n.Address.toLegacyAddress(c);console.log("buyerAddrLegacy: "+d),i.addOutput(d,u);const p=e.data.makerAddr;i.addOutput(p,l);const f=n.ECPair.fromWIF(r.wif);return i.sign(1,f,null,i.hashTypes.SIGHASH_ALL,r.sats),i.transaction.buildIncomplete().toHex()}catch(e){throw console.error("Error in generatePartialTx(): ",e),e}}async moveBch(t={},e=1){let r=Math.ceil(t.data.numTokens*parseInt(t.data.rateInBaseUnit));if(isNaN(r))throw new Error("Could not calculate the amount of BCH to generate counter offer");r+=1e3;const n=await this.util.getKeyPair(e),i=[{address:n.cashAddress,amountSat:r}];console.log("receivers: "+JSON.stringify(i,null,2)),await this.bchWallet.getUtxos();const o={txid:await this.bchWallet.send(i),vout:0,hdIndex:n.hdIndex,wif:n.wif,sats:r};return console.log(`BCH moved to ${n.cashAddress} with WIF ${n.wif}`),o}async ensureFunds(t){const{hasEnoughPsf:e,hasEnoughBch:r,bchAddr:n}=await this.p2wdbWrite.checkForSufficientFunds();if(!e&&!r)throw new Error("Wallet does not have enough BCH to write to the P2WDB.");console.log("ensureFunds() bchAddr: ",n);let i=0;if(r&&(i=this.bchWallet.bchjs.BitcoinCash.toSatoshi(r)),!t.data.buyOrSell.includes("sell"))throw new Error("Buy offers are not supported yet.");{const e=Math.ceil(t.data.numTokens*parseInt(t.data.rateInBaseUnit));if(isNaN(e))throw new Error("Could not calculate sats needed!");const r=await this.bchWallet.getBalance();console.log(`wallet balance: ${r}, sats needed: ${e}`);const n=e+5e3+i;if(n>r)throw new Error(`Wallet does not control enough BCH to purchase the tokens. It has ${r} sats, and needs ${n} sats.`)}return{hasEnoughFunds:!0,bchAddr:n}}}(e),this.flag=new class{constructor(t={}){if(!t.bchWallet)throw new Error("Instance of minimal-slp-wallet must be passed as wallet property when instantiating Flag library.");if(this.bchWallet=t.bchWallet,!t.p2wdbWrite)throw new Error("Instance of p2wdb Write must be passed as p2wdbWrite property when instantiating Flag library.");this.p2wdbWrite=t.p2wdbWrite}async flagOffer(t){try{const e={p2wdbHash:t,nsfw:!0,dataType:"flag"};return await this.p2wdbWrite.bchWallet.initialize(),await this.p2wdbWrite.postEntry(e,"bch-dex-001")}catch(e){throw console.error("Error in bch-dex-lib/flag.js flagOffer(): ",e),e}}}(e),this.tokenData=new class{constructor(t={}){if(!t.bchWallet)throw new Error("Instance of minimal-slp-wallet must be passed as wallet property when instantiating TokenData library.");this.bchWallet=t.bchWallet,this.tokenIdsCache=[],this.tokenDataCache={},this.getTokenData=this.getTokenData.bind(this)}async getTokenData(t={},e){if(!t.tokenId)throw new Error("offer input object must contain a tokenId property when calling getTokenData()");if(!e)throw new Error("callbackFunc required when calling getTokenData()");const r=t.tokenId;if(this.tokenIdsCache.includes(r))return t.tokenData=this.tokenDataCache[r],t;const n=await this.bchWallet.getTokenData2(r);return this.tokenIdsCache.push(r),this.tokenDataCache[r]=n,t.tokenData=n,e(t),!0}}(e)}}})); |
@@ -180,3 +180,3 @@ /* | ||
// Calculate sats needed to pay the offer. | ||
const satsNeeded = offerInfo.data.numTokens * parseInt(offerInfo.data.rateInBaseUnit) | ||
const satsNeeded = Math.ceil(offerInfo.data.numTokens * parseInt(offerInfo.data.rateInBaseUnit)) | ||
if (isNaN(satsNeeded)) throw new Error('Can not calculate needed sats') | ||
@@ -199,7 +199,9 @@ | ||
const buyerAddr = this.bchWallet.walletInfo.legacyAddress | ||
// console.log(`buyAddr: ${JSON.stringify(buyAddr, null, 2)}`) | ||
console.log(`buyerAddr: ${JSON.stringify(buyerAddr, null, 2)}`) | ||
const buyerAddrLegacy = bchjs.Address.toLegacyAddress(buyerAddr) | ||
console.log(`buyerAddrLegacy: ${buyerAddrLegacy}`) | ||
// Send dust transaction representing tokens being sent. | ||
transactionBuilder.addOutput( | ||
buyerAddr, | ||
buyerAddrLegacy, | ||
dust | ||
@@ -247,3 +249,3 @@ ) | ||
// Calculate amount of sats to generate a counter offer. | ||
let satsToMove = offerData.data.numTokens * parseInt(offerData.data.rateInBaseUnit) | ||
let satsToMove = Math.ceil(offerData.data.numTokens * parseInt(offerData.data.rateInBaseUnit)) | ||
if (isNaN(satsToMove)) { | ||
@@ -266,3 +268,3 @@ throw new Error('Could not calculate the amount of BCH to generate counter offer') | ||
}] | ||
// console.log(`receivers: ${JSON.stringify(receivers, null, 2)}`) | ||
console.log(`receivers: ${JSON.stringify(receivers, null, 2)}`) | ||
@@ -301,3 +303,3 @@ // Update the UTXO store of the wallet. | ||
// console.log('hasEnoughBch: ', hasEnoughBch) | ||
// console.log('bchAddr: ', bchAddr) | ||
console.log('ensureFunds() bchAddr: ', bchAddr) | ||
@@ -314,3 +316,3 @@ // Convert BCH cost to sats. | ||
// Calculate the sats needed | ||
const satsNeeded = offerData.data.numTokens * parseInt(offerData.data.rateInBaseUnit) | ||
const satsNeeded = Math.ceil(offerData.data.numTokens * parseInt(offerData.data.rateInBaseUnit)) | ||
if (isNaN(satsNeeded)) { | ||
@@ -317,0 +319,0 @@ throw new Error('Could not calculate sats needed!') |
{ | ||
"name": "bch-dex-lib", | ||
"version": "1.4.0", | ||
"version": "1.4.1", | ||
"description": "An npm JavaScript library for browser and node.js that incorporates the SWaP protocol used by bch-dex.", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -24,2 +24,20 @@ /* | ||
describe('#getTokenData', () => { | ||
it('should resolve data for USDt', async () => { | ||
const tokenId = '9fc89d6b7d5be2eac0b3787c5b8236bca5de641b5bafafc8f450727b63615c11' | ||
const cb = (offer) => { | ||
console.log('offer: ', offer) | ||
assert.property(offer.tokenData, 'tokenStats') | ||
assert.property(offer.tokenData, 'tokenIcon') | ||
assert.property(offer.tokenData, 'optimizedTokenIcon') | ||
assert.equal(offer.tokenData.iconRepoCompatible, true) | ||
assert.equal(offer.tokenData.ps002Compatible, false) | ||
} | ||
const result = await uut.getTokenData({ tokenId }, cb) | ||
console.log('result: ', result) | ||
}) | ||
it('should call callback function after downloading token data', async () => { | ||
@@ -26,0 +44,0 @@ const tokenId = 'd6073900bf75acfdb26314bb1c59ce12e223c31152eded1d20e9ca9b2d453f5c' |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
96521
1715