@galacticcouncil/sdk 5.5.0 → 5.6.0

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/build/index.cjs CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";var ke=Object.defineProperty;var at=Object.getOwnPropertyDescriptor;var lt=Object.getOwnPropertyNames;var ut=Object.prototype.hasOwnProperty;var ct=(l,e)=>{for(var t in e)ke(l,t,{get:e[t],enumerable:!0})},mt=(l,e,t,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of lt(e))!ut.call(l,r)&&r!==t&&ke(l,r,{get:()=>e[r],enumerable:!(s=at(e,r))||s.enumerable});return l};var pt=l=>mt(ke({},"__esModule",{value:!0}),l);var At={};ct(At,{AssetClient:()=>X,AssetNotFound:()=>qe,BASILISK_PARACHAIN_ID:()=>Pt,BalanceClient:()=>Y,BigNumber:()=>x.BigNumber,CachingPoolService:()=>Re,DECIMAL_PLACES:()=>$e,DENOMINATOR:()=>be,FarmClient:()=>Pe,HUB_ASSET_ID:()=>le,HYDRADX_OMNIPOOL_ADDRESS:()=>ue,HYDRADX_PARACHAIN_ID:()=>bt,HYDRADX_SS58_PREFIX:()=>Z,INFINITY:()=>dt,LbpMath:()=>C,LbpPool:()=>ee,ONE:()=>E,OmniMath:()=>O,OmniPool:()=>te,PoolConfigNotFound:()=>Ge,PoolError:()=>$,PoolFactory:()=>ie,PoolNotFound:()=>ce,PoolService:()=>Q,PoolType:()=>k,ProviderConfigNotFound:()=>We,RUNTIME_DECIMALS:()=>J,RouteNotFound:()=>K,Router:()=>j,SYSTEM_ASSET_DECIMALS:()=>ht,SYSTEM_ASSET_ID:()=>L,StableMath:()=>R,StableSwap:()=>se,StorageConfigNotFound:()=>He,SubscriptionNotSupported:()=>ze,TRADEABLE_DEFAULT:()=>he,TradeRouter:()=>pe,TradeType:()=>Le,XykMath:()=>z,XykPool:()=>re,ZERO:()=>P,bnum:()=>m,buildRoute:()=>Oe,calculateBuyFee:()=>je,calculateDiffToAvg:()=>wt,calculateDiffToRef:()=>ne,calculateSellFee:()=>Ye,findNestedKey:()=>vt,findNestedObj:()=>It,scale:()=>I});module.exports=pt(At);var ge=class{constructor(e=1/0){this.capacity=e}storage=[];enqueue(e){if(this.size()===this.capacity)throw Error("Queue has reached max capacity, you cannot add more items");this.storage.push(e)}dequeue(){return this.storage.shift()}size(){return this.storage.length}};var gt=5,oe=class{isNotVisited(e,t){let s=!0;return t.forEach(r=>{(r[0]===e[0]||r[1]===e[1])&&(s=!1)}),s}findPaths(e,t,s){let r=[],i=new ge,n=[];for(n.push([t,""]),i.enqueue(n);i.size()>0;){let a=i.dequeue();if(a==null||a.length>gt)return r;let o=a[a.length-1];(s===null||o[0]===s)&&r.push(a),e.get(o[0])?.forEach(c=>{if(this.isNotVisited(c,a)){let p=[...a];p.push(c),i.enqueue(p)}})}return r}buildAndPopulateGraph(e,t){let s=new Map;for(let r of e)s.set(parseInt(r),[]);for(let[r,i,n]of t){let a=parseInt(i),o=parseInt(n);s.get(a)?.push([o,r])}return s}};function Me(l){let e={};for(let t of l){let s=t.tokens.length;for(let r=0;r<s;r++){e[t.tokens[r].id]||(e[t.tokens[r].id]=[]);for(let i=0;i<s;i++){if(r==i)continue;let n=[t.address,t.tokens[r].id,t.tokens[i].id];e[t.tokens[r].id].push(n)}}}return e}var ae=class{getProposals(e,t,s){let r=Me(s),i=Object.keys(r),n=i.map(c=>r[c]).flat(),a=new oe,o=a.buildAndPopulateGraph(i,n),u=a.findPaths(o,parseInt(e),t?parseInt(t):null);return this.parsePaths(u)}parsePaths(e){let t=[];for(let s of e){let r=[];for(let i=0;i<s.length;i++){let n=s[i],a=s[i+1];if(a==null)break;r.push(this.toEdge(n,a))}t.push(r)}return t}toEdge(e,t){return[t[1],e[0].toString(),t[0].toString()]}};var de=(l,e=new Map)=>t=>{let s;return e.has(t)?e.get(t):(e.set(t,s=l(t)),s)};var x=require("bignumber.js"),$e=12;x.BigNumber.config({EXPONENTIAL_AT:[-100,100],ROUNDING_MODE:4,DECIMAL_PLACES:$e});var P=m(0),E=m(1),dt=m("Infinity");function I(l,e){let t=new x.BigNumber(e.toString()),s=new x.BigNumber(10).pow(t);return l.times(s)}function m(l){return new x.BigNumber(l.toString())}var k=(r=>(r.XYK="Xyk",r.LBP="Lbp",r.Stable="Stableswap",r.Omni="Omnipool",r))(k||{}),$=(i=>(i.UnknownError="UnknownError",i.InsufficientTradingAmount="InsufficientTradingAmount",i.MaxInRatioExceeded="MaxInRatioExceeded",i.MaxOutRatioExceeded="MaxOutRatioExceeded",i.TradeNotAllowed="TradeNotAllowed",i))($||{}),Le=(t=>(t.Buy="Buy",t.Sell="Sell",t))(Le||{});var q=require("@galacticcouncil/math-lbp"),C=class{static getSpotPrice(e,t,s,r,i){return(0,q.get_spot_price)(e,t,s,r,i)}static calculateInGivenOut(e,t,s,r,i){return(0,q.calculate_in_given_out)(e,t,s,r,i)}static calculateOutGivenIn(e,t,s,r,i){return(0,q.calculate_out_given_in)(e,t,s,r,i)}static calculateLinearWeights(e,t,s,r,i){return(0,q.calculate_linear_weights)(e,t,s,r,i)}static calculatePoolTradeFee(e,t,s){return(0,q.calculate_pool_trade_fee)(e,t,s)}};var Je=require("@polkadot/util-crypto"),Ze=require("@polkadot/util"),J=18,he=15,L="0",ht=12,le="1",bt=2034,Z=63,Pt=2090,be=1e3,ue=(0,Je.encodeAddress)((0,Ze.stringToU8a)("modlomnipool".padEnd(32,"\0")),Z);var Zt=require("@galacticcouncil/api-augment/hydradx"),Kt=require("@galacticcouncil/api-augment/basilisk"),U=class{api;constructor(e){this.api=e}get chainDecimals(){return this.api.registry.chainDecimals[0]}get chainToken(){return this.api.registry.chainTokens[0]}};var X=class extends U{SUPPORTED_TYPES=["StableSwap","Bond","Token","External","Erc20"];constructor(e){super(e)}async safeSharesQuery(){try{let e=await this.api.query.stableswap.pools.entries();return new Map(e.map(([{args:[t]},s])=>[t.toString(),s.unwrap()]))}catch{return new Map([])}}async safeBondsQuery(){try{let e=await this.api.query.bonds.bonds.entries();return new Map(e.map(([{args:[t]},s])=>[t.toString(),s.unwrap()]))}catch{return new Map([])}}async metadataQuery(){try{let e=await this.api.query.assetRegistry.assetMetadataMap.entries();return new Map(e.map(([{args:[t]},s])=>{let{decimals:r,symbol:i}=s.unwrap();return[t.toString(),{decimals:r.toNumber(),symbol:i.toHuman()}]}))}catch{return new Map([])}}async locationsQuery(){try{let e=await this.api.query.assetRegistry.assetLocations.entries();return new Map(e.map(([{args:[t]},s])=>[t.toString(),s.unwrap()]))}catch{return new Map([])}}getSystemTokenName(e){switch(e){case"HDX":return"Hydration";case"BSX":return"Basilisk";default:return e}}getToken(e,t,s,r){if(e==L){let p=this.api.consts.balances.existentialDeposit;return{id:L,name:this.getSystemTokenName(this.chainToken),symbol:this.chainToken,decimals:this.chainDecimals,icon:this.chainToken,type:"Token",isSufficient:!0,existentialDeposit:p.toString()}}let{name:i,assetType:n,isSufficient:a,existentialDeposit:o}=t,{symbol:u,decimals:c}=s.get(e)??{};return{id:e,name:i.toHuman(),symbol:u,decimals:c,icon:u,type:n.toHuman(),isSufficient:a?a.toHuman():!0,location:r?.toJSON(),existentialDeposit:o.toString()}}getBond(e,t,s,r){let[i,n]=r,{assetType:a,isSufficient:o,existentialDeposit:u}=t,{symbol:c,decimals:p}=this.getToken(i.toString(),t,s),d=n.toNumber(),g=new Intl.DateTimeFormat("en-GB"),h=[c,"Bond",g.format(d)].join(" ");return{id:e,name:h,symbol:c+"b",decimals:p,icon:c,type:a.toString(),isSufficient:o.toHuman(),existentialDeposit:u.toString(),underlyingAssetId:i.toString(),maturity:d}}getShares(e,t,s,r){let{assets:i}=r,{name:n,symbol:a,assetType:o,isSufficient:u,existentialDeposit:c}=t,d=i.map(y=>y.toString()).map(y=>{let{symbol:S}=this.getToken(y,t,s);return[y,S]}),g=Object.fromEntries(d),h=Object.values(g);return{id:e,name:h.join(", "),symbol:a?.isSome?a.toHuman():n.toHuman(),decimals:18,icon:h.join("/"),type:o.toString(),isSufficient:u.toHuman(),existentialDeposit:c.toString(),meta:g}}getExternal(e,t,s,r){let i=this.getToken(e,t,new Map,r),n=s?.find(a=>a.internalId===i.id);return n?{...i,decimals:n.decimals,name:n.name,symbol:n.symbol,icon:n.symbol,isWhiteListed:n.isWhiteListed}:i}normalizeMetadata(e,t){return t.size?t:new Map(e.map(([{args:[s]},r])=>{let{decimals:i,symbol:n}=r.unwrap();return[s.toString(),{decimals:Number(i.toString()),symbol:n.toHuman()}]}))}getSupportedAssets(e){return e.filter(([t,s])=>{if(s.isNone)return!1;let r=s.unwrap();return this.isSupportedAsset(r)})}async getOnChainAssets(e,t){let[s,r,i,n,a]=await Promise.all([this.api.query.assetRegistry.assets.entries(),this.locationsQuery(),this.safeSharesQuery(),this.safeBondsQuery(),this.metadataQuery()]),o=this.getSupportedAssets(s),u=this.normalizeMetadata(o,a),c=o.map(([{args:[p]},d])=>{let g=d.unwrap(),h=r.get(p.toString()),{assetType:y}=g;switch(y.toString()){case"Bond":let S=n.get(p.toString());return this.getBond(p.toString(),g,u,S);case"StableSwap":let B=i.get(p.toString());return this.getShares(p.toString(),g,u,B);case"External":return this.getExternal(p.toString(),g,t,h);default:return this.getToken(p.toString(),g,u,h)}});return e?c:c.filter(p=>this.isValidAsset(p))}isValidAsset(e){let t=Math.sign(e.decimals);return!!e.symbol&&(t===0||t===1)}isSupportedAsset(e){let t=e.assetType.toString();return this.SUPPORTED_TYPES.includes(t)}};var Y=class extends U{constructor(e){super(e)}async getBalance(e,t){let s=await this.api.query.assetRegistry.assets(t),{assetType:r}=s.unwrap();return r.toString()==="Erc20"?this.getErc20Balance(e,t):t===L?this.getSystemBalance(e):this.getTokenBalance(e,t)}async getSystemBalance(e){let{data:t}=await this.api.query.system.account(e);return this.calculateFreeBalance(t)}async getTokenBalance(e,t){let{free:s,reserved:r,frozen:i}=await this.api.query.tokens.accounts(e,t);return this.calculateFreeBalance({free:s,feeFrozen:r,frozen:i})}async getErc20Balance(e,t){let{free:s,reserved:r,frozen:i}=await this.getTokenBalanceData(e,t);return this.calculateFreeBalance({free:s,feeFrozen:r,frozen:i})}async subscribeSystemBalance(e,t){return this.api.query.system.account(e,({data:s})=>t(L,this.calculateFreeBalance(s)))}async subscribeTokenBalance(e,t,s){let i=t.filter(n=>n.type!=="Erc20").filter(n=>n.id!==L).map(n=>[e,n.id]);return this.api.query.tokens.accounts.multi(i,n=>{let a=[];n.forEach((o,u)=>{let c=this.calculateFreeBalance(o),p=i[u][1];a.push([p,c])}),s(a)})}async subscribeErc20Balance(e,t,s){let r=t.filter(n=>n.type==="Erc20"),i=async()=>{let n=[];(await Promise.all(r.map(async o=>[o.id,await this.getErc20Balance(e,o.id)]))).forEach(([o,u])=>{n.push([o,u])}),s(n)};return await i(),this.api.rpc.chain.subscribeNewHeads(async()=>{i()})}async getTokenBalanceData(e,t){return this.api.call.currenciesApi.account(t,e)}calculateFreeBalance(e){let{free:t,miscFrozen:s,feeFrozen:r,frozen:i}=e,n=new x.BigNumber(t),a=new x.BigNumber(s||i),o=new x.BigNumber(r||0n),u=a.gt(o)?a:o;return n.minus(u)}};var De=require("@polkadot/util-crypto"),Ce=require("@galacticcouncil/math-liquidity-mining");var Pe=class extends U{constructor(e){super(e)}secondsInYear=new x.BigNumber(365.2425).times(24).times(60).times(60);async getOmnipoolFarms(e){let t=await this.api.query.omnipoolWarehouseLM.activeYieldFarm.entries(e);return await Promise.all(t.map(async([r,i])=>{let[,n]=r.args,a=i.unwrap().toString(),o=n.toString(),u=(await this.api.query.omnipoolWarehouseLM.globalFarm(o)).unwrap(),c=(await this.api.query.omnipoolWarehouseLM.yieldFarm(e,o,a)).unwrap(),p=await this.getOraclePrice(u)??u.priceAdjustment.toString();return{assetId:e,globalFarm:u,yieldFarm:c,priceAdjustment:p}}))}async getIsolatedPoolFarms(e){let t=await this.api.query.xykWarehouseLM.activeYieldFarm.entries(e);return await Promise.all(t.map(async([r,i])=>{let[,n]=r.args,a=i.unwrap().toString(),o=n.toString(),u=(await this.api.query.xykWarehouseLM.globalFarm(o)).unwrap(),c=(await this.api.query.xykWarehouseLM.yieldFarm(e,o,a)).unwrap(),p=await this.getOraclePrice(u)??u.priceAdjustment.toString();return{assetId:e,globalFarm:u,yieldFarm:c,priceAdjustment:p}}))}async getOraclePrice(e){let t=e.rewardCurrency.toString(),s=e.incentivizedAsset.toString(),r=[t,s].sort();if(t===s)return new x.BigNumber(1).shiftedBy(18).toString();let i=await this.api.query.emaOracle.oracles("omnipool",r,"TenMinutes");if(i.isNone)return;let[n]=i.unwrap(),a=n.price.n.toString(),o=n.price.d.toString(),u;return Number(t)<Number(s)?u=(0,Ce.fixed_from_rational)(a,o):u=(0,Ce.fixed_from_rational)(o,a),u}getGlobalRewardPerPeriod(e,t,s,r){let n=e.times(t).shiftedBy(-18).times(r).shiftedBy(-18);return n.gte(s)?s:n}getPoolYieldPerPeriod(e,t,s,r){return e.times(t).div(s.times(r).shiftedBy(-18))}async getFarmApr(e,t){if(t==="isolatedpool"&&!(0,De.isAddress)(e))throw new Error("You must pass an address of isolated pool as id");if(t==="omnipool"&&(0,De.isAddress)(e))throw new Error("You must pass an asset id of omnipool");let s=6,r=t==="omnipool"?await this.getOmnipoolFarms(e):await this.getIsolatedPoolFarms(e);return r.length?r.map(({yieldFarm:a,globalFarm:o,priceAdjustment:u})=>{let c=new x.BigNumber(o.totalSharesZ.toString()),p=o.plannedYieldingPeriods.toString(),d=new x.BigNumber(o.yieldPerPeriod.toString()),g=new x.BigNumber(o.maxRewardPerPeriod.toString()),h=o.blocksPerPeriod.toString(),y=new x.BigNumber(a.multiplier.toString()).shiftedBy(-18),S=this.secondsInYear.div(new x.BigNumber(s).times(h)),B;if(c.isZero())B=d.times(y).times(S);else{let W=this.getGlobalRewardPerPeriod(c,d,g,u);B=this.getPoolYieldPerPeriod(W,y,c,u).times(S)}let b=new x.BigNumber(o.pendingRewards.toString()).plus(o.accumulatedPaidRewards.toString()),v=g.times(p);return b.div(v).gte(.99)?P:B.times(100)}).reduce((a,o)=>a.plus(o),P).toString():void 0}};var H=class extends Y{pools=[];subs=[];assets=new Map([]);mem=0;memPools=de(e=>(console.log(this.getPoolType(),"mem pools",e,"\u2705"),this.getPools()));constructor(e){super(e)}get augmentedPools(){return this.pools.filter(e=>this.isValidPool(e)).map(e=>this.withMetadata(e))}async withAssets(e){this.assets=new Map(e.map(t=>[t.id,t])),this.mem=this.mem+1}async getPoolsMem(){return this.memPools(this.mem)}async getPools(){this.unsubscribe(),this.pools=await this.loadPools(),this.subs=this.subscribe();let e=this.getPoolType();return console.log(e,`pools(${this.augmentedPools.length})`,"\u2705"),console.log(e,`subs(${this.subs.length})`,"\u2705"),this.augmentedPools}subscribe(){return this.augmentedPools.map(t=>{let s=[this.subscribeTokensPoolBalance(t)];try{let r=this.subscribePoolChange(t);s.push(r)}catch{}if(this.hasSystemAsset(t)){let r=this.subscribeSystemPoolBalance(t);s.push(r)}if(this.hasErc20Asset(t)){let r=this.subscribeErc20PoolBalance(t);s.push(r)}if(this.hasShareAsset(t)){let r=this.subscribeSharePoolBalance(t);s.push(r)}return this.subscribeLog(t),s}).flat()}hasSystemAsset(e){return e.tokens.some(t=>t.id==="0")}hasShareAsset(e){return e.type==="Stableswap"&&e.id}hasErc20Asset(e){return e.tokens.some(t=>t.type==="Erc20")}unsubscribe(){this.subs.forEach(e=>{e.then(t=>t())})}subscribeLog(e){let t=e.address.substring(0,10).concat("...");console.log(`${e.type} [${t}] balance subscribed`)}subscribeSystemPoolBalance(e){return this.subscribeSystemBalance(e.address,this.updateBalanceCallback(e))}subscribeTokensPoolBalance(e){let t=(s,r)=>s.id!==r;return this.subscribeTokenBalance(e.address,e.tokens,this.updateBalancesCallback(e,t))}subscribeErc20PoolBalance(e){return this.subscribeErc20Balance(e.address,e.tokens,this.updateBalancesCallback(e,()=>!0))}subscribeSharePoolBalance(e){let t=this.assets.get(e.id);return this.subscribeTokenBalance(ue,[t],this.updateBalancesCallback(e,()=>!0))}isValidPool(e){return e.type==="Xyk"?e.tokens.every(t=>this.assets.get(t.id)):!0}withMetadata(e){return e.tokens=e.tokens.map(t=>{let s=this.assets.get(t.id);return{...t,...s}}),e}updateBalancesCallback(e,t){return function(s){s.forEach(([r,i])=>{let n=e.tokens.findIndex(a=>a.id==r);n>=0&&t(e,r)&&(e.tokens[n].balance=i.toString())})}}updateBalanceCallback(e){return function(t,s){let r=e.tokens.findIndex(i=>i.id==t);r>=0&&(e.tokens[r].balance=s.toString())}}};var fe=class extends H{MAX_FINAL_WEIGHT=I(m(100),6);poolsData=new Map([]);isSupported(){return this.api.query.lbp!==void 0}async loadPools(){let[e,t]=await Promise.all([this.api.query.lbp.poolData.entries(),this.api.query.parachainSystem.validationData()]),{relayParentNumber:s}=t.unwrap(),r=e.filter(([i,n])=>this.isActivePool(n.unwrap(),s)).map(async([{args:[i]},n])=>{let a=n.unwrap(),o=i.toString(),u=await this.getPoolDelta(o,a,s.toString());return this.poolsData.set(i.toString(),a),{address:o,type:"Lbp",fee:a.fee.toJSON(),...u,...this.getPoolLimits()}});return Promise.all(r)}async getPoolFees(e,t){let s=this.pools.find(r=>r.address===t);return{repayFee:this.getRepayFee(),exchangeFee:s.fee}}getPoolType(){return"Lbp"}async subscribePoolChange(e){return this.api.query.parachainSystem.validationData(async t=>{let{relayParentNumber:s}=t.unwrap(),r=this.poolsData.get(e.address);if(this.isActivePool(r,s)){let n=await this.getPoolDelta(e.address,r,s.toString());Object.assign(e,n)}else{let n=this.pools.findIndex(a=>a.address==e.address);this.pools.splice(n,1)}})}async getPoolDelta(e,t,s){let{start:r,end:i,assets:n,initialWeight:a,finalWeight:o,repayTarget:u,feeCollector:c}=t,p=C.calculateLinearWeights(r.toString(),i.toString(),a.toString(),o.toString(),s),[d,g]=n,h=d.toString(),y=m(p),S=g.toString(),B=this.MAX_FINAL_WEIGHT.minus(m(y)),[b,v,F]=await Promise.all([this.isRepayFeeApplied(h,u.toString(),c.toString()),this.getBalance(e,h),this.getBalance(e,S)]);return{repayFeeApply:b,tokens:[{id:h,weight:y,balance:v.toString()},{id:S,weight:B,balance:F.toString()}]}}isActivePool(e,t){if(e.start.isEmpty||e.end.isEmpty)return!1;let s=e.start.unwrap().toNumber(),r=e.end.unwrap().toNumber();return t.toNumber()>=s&&t.toNumber()<r}async isRepayFeeApplied(e,t,s){let r=m(t);if(r.isZero())return!1;try{return(await this.getBalance(e,s)).isLessThan(r)}catch{return!0}}getRepayFee(){return this.api.consts.lbp.repayFee.toJSON()}getPoolLimits(){let e=this.api.consts.lbp.maxInRatio.toJSON(),t=this.api.consts.lbp.maxOutRatio.toJSON(),s=this.api.consts.lbp.minTradingLimit.toJSON();return{maxInRatio:e,maxOutRatio:t,minTradingLimit:s}}};var Ke=require("@polkadot/util-crypto"),Qe=require("@polkadot/util");function _(l,e){return l.shiftedBy(-1*e).toString()}function N(l){return l[0]/l[1]*100}function M(l){return l[0]/l[1]}function D(l){return[l/be,be]}var f=require("@galacticcouncil/math-omnipool");var O=class{static calculateSpotPrice(e,t,s,r){return(0,f.calculate_spot_price)(e,t,s,r)}static calculateLrnaSpotPrice(e,t){return(0,f.calculate_lrna_spot_price)(e,t)}static calculateInGivenOut(e,t,s,r,i,n,a,o,u){return(0,f.calculate_in_given_out)(e,t,s,r,i,n,a,o,u)}static calculateLrnaInGivenOut(e,t,s,r,i){return(0,f.calculate_lrna_in_given_out)(e,t,s,r,i)}static calculateOutGivenIn(e,t,s,r,i,n,a,o,u){return(0,f.calculate_out_given_in)(e,t,s,r,i,n,a,o,u)}static calculateOutGivenLrnaIn(e,t,s,r,i){return(0,f.calculate_out_given_lrna_in)(e,t,s,r,i)}static calculatePoolTradeFee(e,t,s){return(0,f.calculate_pool_trade_fee)(e,t,s)}static calculateShares(e,t,s,r){return(0,f.calculate_shares)(e,t,s,r)}static calculateLiquidityOut(e,t,s,r,i,n,a,o){return(0,f.calculate_liquidity_out)(e,t,s,r,i,n,a,o)}static calculateLiquidityLRNAOut(e,t,s,r,i,n,a,o){return(0,f.calculate_liquidity_lrna_out)(e,t,s,r,i,n,a,o)}static calculateCapDifference(e,t,s,r){let i=(0,x.BigNumber)(t),n=(0,x.BigNumber)(e),a=(0,x.BigNumber)(r),u=(0,x.BigNumber)(s).shiftedBy(-18);if(i.div(a).lt(u)){let p=u.times(a).minus(i).times(n),d=i.times((0,x.BigNumber)(1).minus(u));return p.div(d).toFixed(0)}else return"0"}static calculateLimitHubIn(e,t,s,r){return(0,f.calculate_liquidity_hub_in)(e,t,s,r)}static isSellAllowed(e){return(0,f.is_sell_allowed)(e)}static isBuyAllowed(e){return(0,f.is_buy_allowed)(e)}static isAddLiquidityAllowed(e){return(0,f.is_add_liquidity_allowed)(e)}static isRemoveLiquidityAllowed(e){return(0,f.is_remove_liquidity_allowed)(e)}static recalculateAssetFee(e,t,s,r,i,n,a,o,u,c,p){return(0,f.recalculate_asset_fee)(e,t,s,r,i,n,a,o,u,c,p)}static recalculateProtocolFee(e,t,s,r,i,n,a,o,u,c,p){return(0,f.recalculate_protocol_fee)(e,t,s,r,i,n,a,o,u,c,p)}static verifyAssetCap(e,t,s,r){return(0,f.verify_asset_cap)(e,t,s,r)}};var ye=class extends H{isSupported(){return this.api.query.omnipool!==void 0}async loadPools(){let e=this.api.consts.omnipool.hubAssetId.toString(),t=this.getPoolId(),[s,r,i]=await Promise.all([this.api.query.omnipool.assets.entries(),this.api.query.omnipool.hubAssetTradability(),this.getBalance(t,e)]),n=s.map(async([{args:[o]},u])=>{let{hubReserve:c,shares:p,tradable:d,cap:g,protocolShares:h}=u.unwrap(),y=await this.getBalance(t,o.toString());return{id:o.toString(),hubReserves:m(c.toString()),shares:m(p.toString()),tradeable:d.bits.toNumber(),balance:y.toString(),cap:m(g.toString()),protocolShares:m(h.toString())}}),a=await Promise.all(n);return a.push({id:e,tradeable:r.bits.toNumber(),balance:i.toString()}),[{address:t,type:"Omnipool",hubAssetId:e,tokens:a,...this.getPoolLimits()}]}async getPoolFees(e,t){let s=e.assetOut,r=e.assetIn,i="omnipool",n="Short",a=F=>F===L?[L,le]:[le,F],[o,u,c,p]=await Promise.all([this.api.query.system.number(),this.api.query.dynamicFees.assetFee(s),this.api.query.emaOracle.oracles(i,a(s),n),this.api.query.emaOracle.oracles(i,a(r),n)]),[d,g,h]=this.getAssetFee(e,o.toNumber(),u,c),[y,S,B]=r===le?[0,0,0]:this.getProtocolFee(e,o.toNumber(),u,p),b=d+y,v=h+B;return{assetFee:D(g),protocolFee:D(S),min:D(b),max:D(v)}}getPoolType(){return"Omnipool"}async subscribePoolChange(e){let t=e.tokens.map(s=>s.id);return this.api.query.omnipool.assets.multi(t,s=>{e.tokens=s.map((r,i)=>{let n=e.tokens[i];if(r.isNone)return n;let a=r.unwrap();return this.updateTokenState(n,a)})})}updateTokenState(e,t){let{hubReserve:s,shares:r,tradable:i,cap:n,protocolShares:a}=t;return{...e,hubReserves:m(s.toString()),shares:m(r.toString()),cap:m(n.toString()),protocolShares:m(a.toString()),tradeable:i.bits.toNumber()}}getAssetFee(e,t,s,r){let{assetOut:i,balanceOut:n}=e,{minFee:a,maxFee:o,decay:u,amplification:c}=this.api.consts.dynamicFees.assetFeeParameters,p=D(a.toNumber()),d=D(o.toNumber());if(s.isNone||r.isNone)return[a.toNumber(),a.toNumber(),o.toNumber()];let[g]=r.unwrap(),{assetFee:h,timestamp:y}=s.unwrap(),S=t-y.toNumber(),B=g.volume.bIn.toString(),b=g.volume.bOut.toString(),v=g.liquidity.b.toString();i===L&&(B=g.volume.aIn.toString(),b=g.volume.aOut.toString(),v=g.liquidity.a.toString());let F=D(h.toNumber()),W=O.recalculateAssetFee(B,b,v,"9",n.toString(),N(F).toString(),S.toString(),N(p).toString(),N(d).toString(),u.toString(),c.toString());return[a.toNumber(),Number(W)*1e4,o.toNumber()]}getProtocolFee(e,t,s,r){let{assetIn:i,balanceIn:n}=e,{minFee:a,maxFee:o,decay:u,amplification:c}=this.api.consts.dynamicFees.protocolFeeParameters,p=D(a.toNumber()),d=D(o.toNumber());if(s.isNone||r.isNone)return[a.toNumber(),a.toNumber(),o.toNumber()];let[g]=r.unwrap(),{protocolFee:h,timestamp:y}=s.unwrap(),S=t-y.toNumber(),B=g.volume.bIn.toString(),b=g.volume.bOut.toString(),v=g.liquidity.b.toString();i===L&&(B=g.volume.aIn.toString(),b=g.volume.aOut.toString(),v=g.liquidity.a.toString());let F=D(h.toNumber()),W=O.recalculateProtocolFee(B,b,v,"9",n.toString(),N(F).toString(),S.toString(),N(p).toString(),N(d).toString(),u.toString(),c.toString());return[a.toNumber(),Number(W)*1e4,o.toNumber()]}getPoolId(){return(0,Ke.encodeAddress)((0,Qe.stringToU8a)("modlomnipool".padEnd(32,"\0")),Z)}getPoolLimits(){let e=this.api.consts.omnipool.maxInRatio.toJSON(),t=this.api.consts.omnipool.maxOutRatio.toJSON(),s=this.api.consts.omnipool.minimumTradingLimit.toJSON();return{maxInRatio:e,maxOutRatio:t,minTradingLimit:s}}};var Se=class extends H{isSupported(){return this.api.query.xyk!==void 0}async loadPools(){let t=(await this.api.query.xyk.poolAssets.entries()).map(async([{args:[s]},r])=>{let i=s.toString(),[n,a]=r.unwrap(),[o,u]=await Promise.all([this.getBalance(i,n.toString()),this.getBalance(i,a.toString())]);return{address:i,type:"Xyk",tokens:[{id:n.toString(),balance:o.toString()},{id:a.toString(),balance:u.toString()}],...this.getPoolLimits()}});return Promise.all(t)}async getPoolFees(e,t){return{exchangeFee:this.getExchangeFee()}}getPoolType(){return"Xyk"}subscribePoolChange(e){throw new Error("Pool change subscription not supported!")}getExchangeFee(){return this.api.consts.xyk.getExchangeFee.toJSON()}getPoolLimits(){let e=this.api.consts.xyk.maxInRatio.toJSON(),t=this.api.consts.xyk.maxOutRatio.toJSON(),s=this.api.consts.xyk.minTradingLimit.toJSON();return{maxInRatio:e,maxOutRatio:t,minTradingLimit:s}}};var xe=require("@polkadot/util-crypto");var A=require("@galacticcouncil/math-stableswap"),R=class{static getPoolAddress(e){return(0,A.pool_account_name)(e)}static calculateAmplification(e,t,s,r,i){return(0,A.calculate_amplification)(e,t,s,r,i)}static calculateInGivenOut(e,t,s,r,i,n){return(0,A.calculate_in_given_out)(e,t,s,r,i,n)}static calculateAddOneAsset(e,t,s,r,i,n){return(0,A.calculate_add_one_asset)(e,t,s,r,i,n)}static calculateSharesForAmount(e,t,s,r,i,n){return(0,A.calculate_shares_for_amount)(e,t,s,r,i,n)}static calculateOutGivenIn(e,t,s,r,i,n){return(0,A.calculate_out_given_in)(e,t,s,r,i,n)}static calculateLiquidityOutOneAsset(e,t,s,r,i,n){return(0,A.calculate_liquidity_out_one_asset)(e,t,s,r,i,n)}static calculateShares(e,t,s,r,i){return(0,A.calculate_shares)(e,t,s,r,i)}static calculateSpotPriceWithFee(e,t,s,r,i,n,a){return(0,A.calculate_spot_price_with_fee)(e,t,s,r,i,n,a)}static calculatePoolTradeFee(e,t,s){return(0,A.calculate_pool_trade_fee)(e,t,s)}};var Be=class extends H{stablePools=new Map([]);isSupported(){return this.api.query.stableswap!==void 0}async loadPools(){let[e,t]=await Promise.all([this.api.query.stableswap.pools.entries(),this.api.query.system.number()]),s=t.toNumber(),r=e.map(async([{args:[i]},n])=>{let a=n.unwrap(),o=i.toString(),u=this.getPoolAddress(o),[c,p]=await Promise.all([this.getPoolDelta(o,a,s.toString()),this.getPoolTokens(u,o,a)]);return this.stablePools.set(u,a),{address:u,id:o,type:"Stableswap",fee:D(a.fee.toNumber()),tokens:p,...c,...this.getPoolLimits()}});return Promise.all(r)}async getPoolFees(e,t){return{fee:this.pools.find(r=>r.address===t).fee}}getPoolType(){return"Stableswap"}async subscribePoolChange(e){return this.api.query.system.number(async t=>{let s=t.toNumber(),r=this.stablePools.get(e.address),i=await this.getPoolDelta(e.id,r,s.toString());Object.assign(e,i)})}async getPoolDelta(e,t,s){let{initialAmplification:r,finalAmplification:i,initialBlock:n,finalBlock:a}=t,o=R.calculateAmplification(r.toString(),i.toString(),n.toString(),a.toString(),s),u=await this.api.query.tokens.totalIssuance(e);return{amplification:o,totalIssuance:u.toString()}}async getPoolTokens(e,t,s){let{assets:r}=s,i=r.map(async o=>{let[u,c]=await Promise.all([this.api.query.stableswap.assetTradability(t,o.toString()),this.getBalance(e,o.toString())]);return{id:o.toString(),tradeable:u.bits.toNumber(),balance:c.toString()}}),n=await Promise.all(i),a=await this.api.query.omnipool.assets(t);if(a.isSome){let{tradable:o}=a.unwrap(),u=await this.getBalance(ue,t);n.push({id:t,tradeable:o.bits.toNumber(),balance:u.toString()})}return n}getPoolAddress(e){let t=Number(e),s=R.getPoolAddress(t);return(0,xe.encodeAddress)((0,xe.blake2AsHex)(s),Z)}getPoolLimits(){return{maxInRatio:0,maxOutRatio:0,minTradingLimit:this.api.consts.stableswap.minTradingLimit.toJSON()}}};function Oe(l){return l.map(({assetIn:e,assetOut:t,pool:s,poolId:r})=>s==="Stableswap"?{pool:{Stableswap:r},assetIn:e,assetOut:t}:{pool:s,assetIn:e,assetOut:t})}var ce=class extends Error{constructor(e){super(),this.message=`${e} pool invalid`,this.name="PoolNotFound"}},Ge=class extends Error{constructor(e,t){super(),this.message=`${e} pool missing ${t}`,this.name="PoolConfigNotFound"}},K=class extends Error{constructor(e,t){super(),this.message=`Route from ${e} to ${t} not found in pool configuration`,this.name="RouteNotFound"}},qe=class extends Error{constructor(e){super(),this.message=`Asset ${e} not available in current network`,this.name="AssetNotFound"}},He=class extends Error{constructor(e){super(),this.message=`Storage missing ${e}`,this.name="StorageConfigNotFound"}},ze=class extends Error{constructor(e){super(),this.message=`Subscription type "${e}" not supported`,this.name="SubscriptionNotSupported"}},We=class extends Error{constructor(e){super(),this.message=`${e}`,this.name="ProviderConfigNotFound"}};var Q=class{api;assetClient;xykClient;omniClient;lbpClient;stableClient;clients=[];onChainAssets=[];memRegistry=de(e=>(console.log("Registry mem sync",e,"\u2705"),this.syncRegistry()));constructor(e){this.api=e,this.assetClient=new X(this.api),this.xykClient=new Se(this.api),this.omniClient=new ye(this.api),this.lbpClient=new fe(this.api),this.stableClient=new Be(this.api),this.clients=[this.xykClient,this.omniClient,this.lbpClient,this.stableClient]}get assets(){return this.onChainAssets}get isRegistrySynced(){return this.onChainAssets.length>0}async syncRegistry(e){let t=await this.assetClient.getOnChainAssets(!1,e);this.clients.forEach(s=>s.withAssets(t)),this.onChainAssets=t}async getPools(e){return this.isRegistrySynced||await this.memRegistry(1),e.length==0?(await Promise.all(this.clients.filter(r=>r.isSupported()).map(r=>r.getPoolsMem()))).flat():(await Promise.all(this.clients.filter(s=>e.some(r=>r===s.getPoolType())).map(s=>s.getPoolsMem()))).flat()}unsubscribe(){this.xykClient.unsubscribe(),this.omniClient.unsubscribe(),this.lbpClient.unsubscribe(),this.stableClient.unsubscribe()}async getPoolFees(e,t){switch(t.type){case"Xyk":return this.xykClient.getPoolFees(e,t.address);case"Omnipool":return this.omniClient.getPoolFees(e,t.address);case"Lbp":return this.lbpClient.getPoolFees(e,t.address);case"Stableswap":return this.stableClient.getPoolFees(e,t.address);default:throw new ce(t.type)}}isDirectOmnipoolTrade(e){return e.length==1&&e[0].pool=="Omnipool"}buildBuyTx(e,t,s,r,i){let n;this.isDirectOmnipoolTrade(i)?n=this.api.tx.omnipool.buy(t,e,s.toFixed(),r.toFixed()):n=this.api.tx.router.buy(e,t,s.toFixed(),r.toFixed(),Oe(i));let a=()=>n;return{hex:n.toHex(),name:"RouterBuy",get:a}}buildSellTx(e,t,s,r,i){let n;this.isDirectOmnipoolTrade(i)?n=this.api.tx.omnipool.sell(e,t,s.toFixed(),r.toFixed()):n=this.api.tx.router.sell(e,t,s.toFixed(),r.toFixed(),Oe(i));let a=()=>n;return{hex:n.toHex(),name:"RouterSell",get:a}}};var me=(l,e)=>l===e?0:l==null?e==null?0:-1:e==null?l==null?0:1:typeof l.compare=="function"?l.compare(e):typeof e.compare=="function"?-e.compare(l):l<e?-1:l>e?1:0;var we=(l,e=t=>t!==void 0?": "+t:"")=>class extends Error{origMessage;constructor(t){super(l(t)+e(t)),this.origMessage=t!==void 0?String(t):""}};var ft=we(()=>"illegal argument(s)"),Ve=l=>{throw new ft(l)};var yt=we(()=>"index out of bounds"),Ue=l=>{throw new yt(l)},ve=(l,e,t)=>(l<e||l>=t)&&Ue(l);var et=23283064365386963e-26,Ie=class{float(e=1){return this.int()*et*e}probability(e){return this.float()<e}norm(e=1){return(this.int()*et-.5)*2*e}normMinMax(e,t){let s=this.minmax(e,t);return this.float()<.5?s:-s}minmax(e,t){return this.float()*(t-e)+e}minmaxInt(e,t){e|=0;let s=(t|0)-e;return s?e+this.int()%s:e}minmaxUint(e,t){e>>>=0;let s=(t>>>0)-e;return s?e+this.int()%s:e}};var Ae=class extends Ie{constructor(e){super(),this.rnd=e}float(e=1){return this.rnd()*e}norm(e=1){return(this.rnd()-.5)*2*e}int(){return this.rnd()*4294967296>>>0}};var tt=new Ae(Math.random);var st=l=>l!=null&&typeof l!="function"&&l.length!==void 0;var rt=Object.getPrototypeOf({}),Te="function",it="string",V=(l,e)=>{let t;if(l===e)return!0;if(l!=null){if(typeof l.equiv===Te)return l.equiv(e)}else return l==e;if(e!=null){if(typeof e.equiv===Te)return e.equiv(l)}else return l==e;return typeof l===it||typeof e===it?!1:(t=Object.getPrototypeOf(l),(t==null||t===rt)&&(t=Object.getPrototypeOf(e),t==null||t===rt)?Ot(l,e):typeof l!==Te&&l.length!==void 0&&typeof e!==Te&&e.length!==void 0?St(l,e):l instanceof Set&&e instanceof Set?Bt(l,e):l instanceof Map&&e instanceof Map?xt(l,e):l instanceof Date&&e instanceof Date?l.getTime()===e.getTime():l instanceof RegExp&&e instanceof RegExp?l.toString()===e.toString():l!==l&&e!==e)},St=(l,e,t=V)=>{let s=l.length;if(s===e.length)for(;s-- >0&&t(l[s],e[s]););return s<0},Bt=(l,e,t=V)=>l.size===e.size&&t([...l.keys()].sort(),[...e.keys()].sort()),xt=(l,e,t=V)=>l.size===e.size&&t([...l].sort(),[...e].sort()),Ot=(l,e,t=V)=>{if(Object.keys(l).length!==Object.keys(e).length)return!1;for(let s in l)if(!e.hasOwnProperty(s)||!t(l[s],e[s]))return!1;return!0};var Xe=class{value;constructor(e){this.value=e}deref(){return this.value}};var nt=l=>l instanceof Xe;var Ne=class l{_head;_length=0;constructor(e){e&&this.into(e)}get length(){return this._length}get head(){return this._head}[Symbol.iterator](){return ot("next",this._head)}reverseIterator(){return ot("prev",this.tail)}clear(){this.release()}compare(e,t=me){let s=this._length;if(s<e._length)return-1;if(s>e._length)return 1;if(s===0)return 0;{let r=this._head,i=e._head,n=0;for(;s-- >0&&n===0;)n=t(r.value,i.value),r=r.next,i=i.next;return n}}concat(...e){let t=this.copy();for(let s of e)t.into(s);return t}equiv(e){if(!(e instanceof l||st(e))||this._length!==e.length)return!1;if(!this._length||this===e)return!0;let t=e[Symbol.iterator](),s=this._head;for(let r=this._length;r-- >0;){if(!V(s.value,t.next().value))return!1;s=s.next}return!0}filter(e){let t=this.empty();return this.traverse(s=>(e(s.value)&&t.append(s.value),!0)),t}find(e){return this.traverse(t=>t.value!==e)}findWith(e){return this.traverse(t=>!e(t.value))}first(){return this._head&&this._head.value}insertSorted(e,t){t=t||me;for(let s=this._head,r=this._length;r-- >0;){if(t(e,s.value)<=0)return this.insertBefore(s,e);s=s.next}return this.append(e)}into(e){for(let t of e)this.append(t);return this}nth(e,t){let s=this.nthCell(e);return s?s.value:t}nthCellUnsafe(e){let t,s;for(e<=this._length>>>1?(t=this._head,s="next"):(t=this.tail,s="prev",e=this._length-e-1);e-- >0&&t;)t=t[s];return t}peek(){return this.tail&&this.tail.value}$reduce(e,t){let s=this._head;for(let r=this._length;r-- >0&&!nt(t);)t=e(t,s.value),s=s.next;return t}reduce(e,t){return this.$reduce(e,t)}release(){let e=this._head;if(!e)return!0;let t;for(let s=this._length;s-- >0;)t=e.next,delete e.value,delete e.prev,delete e.next,e=t;return this._head=void 0,this._length=0,!0}reverse(){let e=this._head,t=this.tail,s=(this._length>>>1)+(this._length&1);for(;e&&t&&s>0;){let r=e.value;e.value=t.value,t.value=r,e=e.next,t=t.prev,s--}return this}setHead(e){let t=this._head;return t?(t.value=e,t):this.prepend(e)}setNth(e,t){let s=this.nthCell(e);return!s&&Ue(e),s.value=t,s}setTail(e){let t=this.tail;return t?(t.value=e,t):this.append(e)}swap(e,t){if(e!==t){let s=e.value;e.value=t.value,t.value=s}return this}toArray(e=[]){return this.traverse(t=>(e.push(t.value),!0)),e}toJSON(){return this.toArray()}toString(){let e=[];return this.traverse(t=>(e.push(String(t.value)),!0)),e.join(", ")}traverse(e,t=this._head,s){if(!this._head)return;let r=t;do{if(!e(r))break;r=r.next}while(r!==s);return r}_map(e,t){return this.traverse(s=>(e.append(t(s.value)),!0)),e}};function*ot(l,e){for(;e;)yield e.value,e=e[l]}var Fe=class l extends Ne{_tail;constructor(e){super(),e&&this.into(e)}get tail(){return this._tail}append(e){if(this._tail){let t={value:e,prev:this._tail};return this._tail.next=t,this._tail=t,this._length++,t}else return this.prepend(e)}asHead(e){return e===this._head?this:(this.remove(e),this._head.prev=e,e.next=this._head,e.prev=void 0,this._head=e,this._length++,this)}asTail(e){return e===this._tail?this:(this.remove(e),this._tail.next=e,e.prev=this._tail,e.next=void 0,this._tail=e,this._length++,this)}cons(e){return this.prepend(e),this}copy(){return new l(this)}*cycle(){for(;;)yield*this}drop(){let e=this._head;if(e)return this._head=e.next,this._head?this._head.prev=void 0:this._tail=void 0,this._length--,e.value}empty(){return new l}insertAfter(e,t){let s={value:t,next:e.next,prev:e};return e.next?e.next.prev=s:this._tail=s,e.next=s,this._length++,s}insertAfterNth(e,t){return e<0&&(e+=this._length),e>=this._length-1?this.append(t):(ve(e,0,this._length),this.insertAfter(this.nthCellUnsafe(e),t))}insertBefore(e,t){let s={value:t,next:e,prev:e.prev};return e.prev?e.prev.next=s:this._head=s,e.prev=s,this._length++,s}insertBeforeNth(e,t){return e<0&&(e+=this._length),e<=0?this.prepend(t):(ve(e,0,this._length),this.insertBefore(this.nthCellUnsafe(e),t))}map(e){return this._map(new l,e)}nth(e,t){let s=this.nthCell(e);return s?s.value:t}nthCell(e){if(e<0&&(e+=this._length),!(e<0||e>=this._length))return this.nthCellUnsafe(e)}pop(){let e=this._tail;if(e)return this._tail=e.prev,this._tail?this._tail.next=void 0:this._head=void 0,this._length--,e.value}prepend(e){let t={value:e,next:this._head};return this._head?this._head.prev=t:this._tail=t,this._head=t,this._length++,t}push(e){return this.append(e),this}release(){return this._tail=void 0,super.release()}remove(e){return e.prev?e.prev.next=e.next:this._head=e.next,e.next?e.next.prev=e.prev:this._tail=e.prev,this._length--,this}rotateLeft(){switch(this._length){case 0:case 1:return this;case 2:return this.swap(this._head,this._tail);default:return this.push(this.drop())}}rotateRight(){switch(this._length){case 0:case 1:return this;case 2:return this.swap(this._head,this._tail);default:let e=this.peek();return this.pop(),this.prepend(e),this}}seq(e=0,t=this.length){if(e>=t||e<0)return;let s=this.nthCell(e),r=this.nthCell(t-1),i=n=>({first(){return n.value},next(){return n!==r&&n.next?i(n.next):void 0}});return s?i(s):void 0}shuffle(e,t=tt){if(this._length<2)return this;for(e=e!==void 0?e:Math.ceil(1.5*Math.log2(this._length));e>0;e--){let s=this._head;for(;s;){let r=s.next;t.probability(.5)?this.asHead(s):this.asTail(s),s=r}}return this}slice(e=0,t=this.length){let s=e<0?e+this._length:e,r=t<0?t+this._length:t;(s<0||r<0)&&Ve("invalid indices: ${from} / ${to}");let i=new l,n=this.nthCell(s);for(;n&&++s<=r;)i.push(n.value),n=n.next;return i}sort(e=me){if(!this._length)return this;let t=1;for(;;){let s=this._head;this._head=void 0,this._tail=void 0;let r=0;for(;s;){r++;let i=s,n=0;for(let o=0;o<t&&(n++,i=i.next,!!i);o++);let a=t;for(;n>0||a>0&&i;){let o;n===0?(o=i,i=i.next,a--):!i||a===0||e(s.value,i.value)<=0?(o=s,s=s.next,n--):(o=i,i=i.next,a--),this._tail?this._tail.next=o:this._head=o,o.prev=this._tail,this._tail=o}s=i}if(this._tail.next=void 0,r<=1)return this;t*=2}}splice(e,t=0,s){let r;typeof e=="number"?(e<0&&(e+=this._length),ve(e,0,this._length),r=this.nthCellUnsafe(e)):r=e;let i=new l;if(t>0)for(;r&&t-- >0;)this.remove(r),i.push(r.value),r=r.next;else r&&(r=r.next);if(s)if(r)for(let n of s)this.insertBefore(r,n);else for(let n of s)this.push(n);return i}};var _e=class l{map;items;opts;_size;constructor(e,t){let s={maxlen:1/0,maxsize:1/0,map:()=>new Map,ksize:()=>0,vsize:()=>0,...t};this.map=s.map(),this.items=new Fe,this._size=0,this.opts=s,e&&this.into(e)}get length(){return this.items.length}get size(){return this._size}[Symbol.iterator](){return this.entries()}*entries(){for(let e of this.items)yield[e.k,e]}*keys(){for(let e of this.items)yield e.k}*values(){for(let e of this.items)yield e.v}copy(){let e=this.empty();e.items=this.items.copy();let t=e.items.head;for(;t;)e.map.set(t.value.k,t),t=t.next;return e}empty(){return new l(null,this.opts)}release(){this._size=0,this.map.clear();let e=this.opts.release;if(e){let t;for(;t=this.items.drop();)e(t.k,t.v);return!0}return this.items.release()}has(e){return this.map.has(e)}get(e,t){let s=this.map.get(e);return s?this.resetEntry(s):t}set(e,t){let s=this.opts.ksize(e)+this.opts.vsize(t),r=this.map.get(e),i=Math.max(0,s-(r?r.value.s:0));return this._size+=i,this.ensureSize()?this.doSetEntry(r,e,t,s):this._size-=i,t}into(e){for(let t of e)this.set(t[0],t[1]);return this}async getSet(e,t){let s=this.map.get(e);return s?this.resetEntry(s):this.set(e,await t())}delete(e){let t=this.map.get(e);return t?(this.removeEntry(t),!0):!1}resetEntry(e){return this.items.asTail(e),e.value.v}ensureSize(){let{release:e,maxsize:t,maxlen:s}=this.opts;for(;this._size>t||this.length>=s;){let r=this.items.drop();if(!r)return!1;this.map.delete(r.k),e?.(r.k,r.v),this._size-=r.s}return!0}removeEntry(e){let t=e.value;this.map.delete(t.k),this.items.remove(e),this.opts.release?.(t.k,t.v),this._size-=t.s}doSetEntry(e,t,s,r){e?(this.opts.update?.(t,e.value.v,s),e.value.v=s,e.value.s=r,this.items.asTail(e)):(this.items.push({k:t,v:s,s:r}),this.map.set(t,this.items.tail))}};var Re=class extends Q{feeCache;disconnectSubscribeNewHeads=null;constructor(e){super(e),this.feeCache=new _e(null),this.api.rpc.chain.subscribeNewHeads(async t=>{this.feeCache.release()}).then(t=>{this.disconnectSubscribeNewHeads=t})}async getPoolFees(e,t){let s=[t.address,e.assetIn,e.assetOut].join("-");if(this.feeCache.has(s))return this.feeCache.get(s);{let i=await super.getPoolFees(e,t);return this.feeCache.set(s,i),i}}async destroy(){console.log(`Destroying pool cache!
2
- Items: [${this.feeCache.length}]`),this.feeCache.release(),this.disconnectSubscribeNewHeads?.()}};var ee=class l{type;address;tokens;maxInRatio;maxOutRatio;minTradingLimit;fee;repayFeeApply;static fromPool(e){return new l(e.address,e.tokens,e.maxInRatio,e.maxOutRatio,e.minTradingLimit,e.fee,e.repayFeeApply)}constructor(e,t,s,r,i,n,a){this.type="Lbp",this.address=e,this.tokens=t,this.maxInRatio=s,this.maxOutRatio=r,this.minTradingLimit=i,this.fee=n,this.repayFeeApply=a}validatePair(e,t){return!0}parsePair(e,t){let s=new Map(this.tokens.map(o=>[o.id,o])),r=s.get(e),i=s.get(t);if(r==null)throw new Error("Pool does not contain tokenIn");if(i==null)throw new Error("Pool does not contain tokenOut");let n=m(r.balance),a=m(i.balance);return{assetIn:e,assetOut:t,balanceIn:n,balanceOut:a,decimalsIn:r.decimals,decimalsOut:i.decimals,weightIn:r.weight,weightOut:i.weight}}validateAndBuy(e,t,s){let r=this.tokens[0].id,i=[];t.isLessThan(this.minTradingLimit)&&i.push("InsufficientTradingAmount");let n=e.balanceOut.div(this.maxOutRatio);if(t.isGreaterThan(n)&&i.push("MaxOutRatioExceeded"),r===e.assetOut){let a=this.calculateTradeFee(t,s),o=N(this.repayFeeApply?s.repayFee:s.exchangeFee),u=t.plus(a),c=this.calculateInGivenOut(e,u),p=e.balanceIn.div(this.maxInRatio);return c.isGreaterThan(p)&&i.push("MaxInRatioExceeded"),{amountIn:c,calculatedIn:c,amountOut:t,feePct:o,errors:i}}else{let a=this.calculateInGivenOut(e,t),o=e.balanceIn.div(this.maxInRatio);return a.isGreaterThan(o)&&i.push("MaxInRatioExceeded"),{amountIn:a,calculatedIn:a,amountOut:t,feePct:0,errors:i}}}validateAndSell(e,t,s){let r=this.tokens[0].id,i=[];t.isLessThan(this.minTradingLimit)&&i.push("InsufficientTradingAmount");let n=e.balanceIn.div(this.maxInRatio);if(t.isGreaterThan(n)&&i.push("MaxInRatioExceeded"),r===e.assetIn){let a=this.calculateOutGivenIn(e,t),o=e.balanceOut.div(this.maxOutRatio);return a.isGreaterThan(o)&&i.push("MaxOutRatioExceeded"),{amountIn:t,calculatedOut:a,amountOut:a,feePct:0,errors:i}}else{let a=this.calculateOutGivenIn(e,t),o=this.calculateTradeFee(a,s),u=N(this.repayFeeApply?s.repayFee:s.exchangeFee),c=a.minus(o),p=e.balanceOut.div(this.maxOutRatio);return c.isGreaterThan(p)&&i.push("MaxOutRatioExceeded"),{amountIn:t,calculatedOut:a,amountOut:c,feePct:u,errors:i}}}calculateInGivenOut(e,t){let s=C.calculateInGivenOut(e.balanceIn.toString(),e.balanceOut.toString(),e.weightIn.toString(),e.weightOut.toString(),t.toFixed(0)),r=m(s);return r.isNegative()?P:r}calculateOutGivenIn(e,t){let s=C.calculateOutGivenIn(e.balanceIn.toString(),e.balanceOut.toString(),e.weightIn.toString(),e.weightOut.toString(),t.toFixed(0)),r=m(s);return r.isNegative()?P:r}spotPriceInGivenOut(e){let t=C.getSpotPrice(e.balanceOut.toString(),e.balanceIn.toString(),e.weightOut.toString(),e.weightIn.toString(),I(E,e.decimalsOut).toString());return m(t)}spotPriceOutGivenIn(e){let t=C.getSpotPrice(e.balanceIn.toString(),e.balanceOut.toString(),e.weightIn.toString(),e.weightOut.toString(),I(E,e.decimalsIn).toString());return m(t)}calculateTradeFee(e,t){let s=C.calculatePoolTradeFee(e.toString(),this.repayFeeApply?t.repayFee[0]:t.exchangeFee[0],this.repayFeeApply?t.repayFee[1]:t.exchangeFee[1]);return m(s)}};var te=class l{type;address;tokens;maxInRatio;maxOutRatio;minTradingLimit;hubAssetId;static fromPool(e){return new l(e.address,e.tokens,e.maxInRatio,e.maxOutRatio,e.minTradingLimit,e.hubAssetId)}constructor(e,t,s,r,i,n){this.type="Omnipool",this.address=e,this.tokens=t,this.maxInRatio=s,this.maxOutRatio=r,this.minTradingLimit=i,this.hubAssetId=n}validatePair(e,t){return this.hubAssetId!=t}parsePair(e,t){let s=new Map(this.tokens.map(c=>[c.id,c])),r=s.get(e),i=s.get(t);if(r==null)throw new Error("Pool does not contain tokenIn");if(i==null)throw new Error("Pool does not contain tokenOut");let n=m(r.balance),a=m(i.balance),o=m(r.existentialDeposit),u=m(i.existentialDeposit);return{assetIn:e,assetOut:t,hubReservesIn:r.hubReserves,hubReservesOut:i.hubReserves,sharesIn:r.shares,sharesOut:i.shares,decimalsIn:r.decimals,decimalsOut:i.decimals,balanceIn:n,balanceOut:a,tradeableIn:r.tradeable,tradeableOut:i.tradeable,assetInED:o,assetOutED:u}}validateAndBuy(e,t,s){let r=this.calculateInGivenOut(e,t),i=this.calculateInGivenOut(e,t,s),n=i.minus(r),a=r===P?P:n.div(r).multipliedBy(100).decimalPlaces(2),o=[],u=O.isSellAllowed(e.tradeableIn),c=O.isBuyAllowed(e.tradeableOut);(!u||!c)&&o.push("TradeNotAllowed"),(t.isLessThan(this.minTradingLimit)||r.isLessThan(e.assetInED))&&o.push("InsufficientTradingAmount");let p=e.balanceOut.div(this.maxOutRatio);t.isGreaterThan(p)&&o.push("MaxOutRatioExceeded");let d=e.balanceIn.div(this.maxInRatio);return i.isGreaterThan(d)&&o.push("MaxInRatioExceeded"),{amountIn:i,calculatedIn:r,amountOut:t,feePct:a.toNumber(),errors:o}}validateAndSell(e,t,s){let r=this.calculateOutGivenIn(e,t),i=this.calculateOutGivenIn(e,t,s),a=r.minus(i).div(r).multipliedBy(100).decimalPlaces(2),o=[],u=O.isSellAllowed(e.tradeableIn),c=O.isBuyAllowed(e.tradeableOut);(!u||!c)&&o.push("TradeNotAllowed"),(t.isLessThan(this.minTradingLimit)||r.isLessThan(e.assetOutED))&&o.push("InsufficientTradingAmount");let p=e.balanceIn.div(this.maxInRatio);t.isGreaterThan(p)&&o.push("MaxInRatioExceeded");let d=e.balanceOut.div(this.maxOutRatio);return i.isGreaterThan(d)&&o.push("MaxOutRatioExceeded"),{amountIn:t,calculatedOut:r,amountOut:i,feePct:a.toNumber(),errors:o}}calculateInGivenOut(e,t,s){if(e.assetIn==this.hubAssetId)return this.calculateLrnaInGivenOut(e,t,s);let r=O.calculateInGivenOut(e.balanceIn.toString(),e.hubReservesIn.toString(),e.sharesIn.toString(),e.balanceOut.toString(),e.hubReservesOut.toString(),e.sharesOut.toString(),t.toFixed(0),s?M(s.assetFee).toString():P.toString(),s?M(s.protocolFee).toString():P.toString()),i=m(r);return i.isNegative()?P:i}calculateLrnaInGivenOut(e,t,s){let r=O.calculateLrnaInGivenOut(e.balanceOut.toString(),e.hubReservesOut.toString(),e.sharesOut.toString(),t.toFixed(0),s?M(s.assetFee).toString():P.toString()),i=m(r);return i.isNegative()?P:i}calculateOutGivenIn(e,t,s){if(e.assetIn==this.hubAssetId)return this.calculateOutGivenLrnaIn(e,t,s);let r=O.calculateOutGivenIn(e.balanceIn.toString(),e.hubReservesIn.toString(),e.sharesIn.toString(),e.balanceOut.toString(),e.hubReservesOut.toString(),e.sharesOut.toString(),t.toFixed(0),s?M(s.assetFee).toString():P.toString(),s?M(s.protocolFee).toString():P.toString()),i=m(r);return i.isNegative()?P:i}calculateOutGivenLrnaIn(e,t,s){let r=O.calculateOutGivenLrnaIn(e.balanceOut.toString(),e.hubReservesOut.toString(),e.sharesOut.toString(),t.toFixed(0),s?M(s.assetFee).toString():P.toString()),i=m(r);return i.isNegative()?P:i}spotPriceInGivenOut(e){if(e.assetIn==this.hubAssetId)return this.spotPriceLrnaInGivenOut(e);let t=O.calculateSpotPrice(e.balanceOut.toString(),e.hubReservesOut.toString(),e.balanceIn.toString(),e.hubReservesIn.toString());return m(t).shiftedBy(-1*(J-e.decimalsOut)).decimalPlaces(0,1)}spotPriceLrnaInGivenOut(e){let t=O.calculateLrnaSpotPrice(e.hubReservesOut.toString(),e.balanceOut.toString());return m(t).shiftedBy(-1*(J-e.decimalsOut)).decimalPlaces(0,1)}spotPriceOutGivenIn(e){if(e.assetIn==this.hubAssetId)return this.spotPriceOutGivenLrnaIn(e);let t=O.calculateSpotPrice(e.balanceIn.toString(),e.hubReservesIn.toString(),e.balanceOut.toString(),e.hubReservesOut.toString());return m(t).shiftedBy(-1*(J-e.decimalsIn)).decimalPlaces(0,1)}spotPriceOutGivenLrnaIn(e){let t=O.calculateLrnaSpotPrice(e.balanceOut.toString(),e.hubReservesOut.toString());return m(t).shiftedBy(-1*(J-e.decimalsIn)).decimalPlaces(0,1)}};var se=class l{type;address;tokens;maxInRatio;maxOutRatio;minTradingLimit;amplification;id;fee;totalIssuance;static fromPool(e){return new l(e.address,e.tokens,e.maxInRatio,e.maxOutRatio,e.minTradingLimit,e.amplification,e.id,e.fee,e.totalIssuance)}constructor(e,t,s,r,i,n,a,o,u){this.type="Stableswap",this.address=e,this.tokens=t,this.maxInRatio=s,this.maxOutRatio=r,this.minTradingLimit=i,this.amplification=n,this.id=a,this.fee=o,this.totalIssuance=u}validatePair(e,t){return!0}parsePair(e,t){let s=new Map(this.tokens.map(c=>[c.id,c])),r=s.get(e),i=s.get(t);if(r==null)throw new Error("Pool does not contain tokenIn");if(i==null)throw new Error("Pool does not contain tokenOut");let n=m(r.balance),a=m(i.balance),o=m(r.existentialDeposit),u=m(i.existentialDeposit);return{assetIn:e,assetOut:t,balanceIn:n,balanceOut:a,decimalsIn:r.decimals,decimalsOut:i.decimals,tradeableIn:this.id===e?he:r.tradeable,tradeableOut:this.id===t?he:i.tradeable,assetInED:o,assetOutED:u}}validateAndBuy(e,t,s){let r=this.calculateInGivenOut(e,t),i=this.calculateInGivenOut(e,t,s),n=N(s.fee),a=[],o=O.isSellAllowed(e.tradeableIn),u=O.isBuyAllowed(e.tradeableOut);return(!o||!u)&&a.push("TradeNotAllowed"),(t.isLessThan(this.minTradingLimit)||r.isLessThan(e.assetInED))&&a.push("InsufficientTradingAmount"),{amountIn:i,calculatedIn:r,amountOut:t,feePct:n,errors:a}}validateAndSell(e,t,s){let r=this.calculateOutGivenIn(e,t),i=this.calculateOutGivenIn(e,t,s),n=N(s.fee),a=[],o=O.isSellAllowed(e.tradeableIn),u=O.isBuyAllowed(e.tradeableOut);return(!o||!u)&&a.push("TradeNotAllowed"),(t.isLessThan(this.minTradingLimit)||r.isLessThan(e.assetOutED))&&a.push("InsufficientTradingAmount"),{amountIn:t,calculatedOut:r,amountOut:i,feePct:n,errors:a}}calculateIn(e,t,s){let r=R.calculateInGivenOut(this.getReserves(),Number(e.assetIn),Number(e.assetOut),t.toFixed(0),this.amplification,s?M(s.fee).toString():P.toString()),i=m(r);return i.isNegative()?P:i}calculateAddOneAsset(e,t,s){let r=R.calculateAddOneAsset(this.getReserves(),t.toFixed(0),Number(e.assetIn),this.amplification,this.totalIssuance,s?M(s.fee).toString():P.toString()),i=m(r);return i.isNegative()?P:i}calculateSharesForAmount(e,t,s){let r=R.calculateSharesForAmount(this.getReserves(),Number(e.assetOut),t.toFixed(0),this.amplification,this.totalIssuance,s?M(s.fee).toString():P.toString()),i=m(r);return i.isNegative()?P:i}calculateInGivenOut(e,t,s){return e.assetOut==this.id?this.calculateAddOneAsset(e,t,s):e.assetIn==this.id?this.calculateSharesForAmount(e,t,s):this.calculateIn(e,t,s)}spotPriceInGivenOut(e){let t=R.calculateSpotPriceWithFee(this.id,this.getReserves(),this.amplification,e.assetOut,e.assetIn,this.totalIssuance,"0");if(e.assetOut==this.id)return m(t);if(e.assetIn==this.id){let r=I(E,e.decimalsIn-e.decimalsOut);return m(t).div(r)}let s=I(E,18-e.decimalsIn);return m(t).div(s)}calculateOut(e,t,s){let r=R.calculateOutGivenIn(this.getReserves(),Number(e.assetIn),Number(e.assetOut),t.toFixed(0),this.amplification,s?M(s.fee).toString():P.toString()),i=m(r);return i.isNegative()?P:i}calculateWithdrawOneAsset(e,t,s){let r=R.calculateLiquidityOutOneAsset(this.getReserves(),t.toFixed(0),Number(e.assetOut),this.amplification,this.totalIssuance,s?M(s.fee).toString():P.toString()),i=m(r);return i.isNegative()?P:i}calculateShares(e,t,s){let r=R.calculateShares(this.getReserves(),this.getAssets(e.assetIn,t),this.amplification,this.totalIssuance,s?M(s.fee).toString():P.toString()),i=m(r);return i.isNegative()?P:i}calculateOutGivenIn(e,t,s){return e.assetIn==this.id?this.calculateWithdrawOneAsset(e,t,s):e.assetOut==this.id?this.calculateShares(e,t,s):this.calculateOut(e,t,s)}spotPriceOutGivenIn(e){let t=R.calculateSpotPriceWithFee(this.id,this.getReserves(),this.amplification,e.assetIn,e.assetOut,this.totalIssuance,"0");if(e.assetIn==this.id)return m(t);if(e.assetOut==this.id){let r=I(E,e.decimalsOut-e.decimalsIn);return m(t).div(r)}let s=I(E,18-e.decimalsOut);return m(t).div(s)}calculateTradeFee(e,t){let s=R.calculatePoolTradeFee(e.toString(),t.fee[0],t.fee[1]);return m(s)}getReserves(){let e=this.tokens.filter(t=>t.id!=this.id).map(({id:t,balance:s,decimals:r})=>({asset_id:Number(t),amount:s,decimals:r}));return JSON.stringify(e)}getAssets(e,t){let s={asset_id:Number(e),amount:t.toFixed(0)};return JSON.stringify([s])}};var T=require("@galacticcouncil/math-xyk"),z=class{static getSpotPrice(e,t,s){return(0,T.get_spot_price)(e,t,s)}static calculateInGivenOut(e,t,s){return(0,T.calculate_in_given_out)(e,t,s)}static calculateOutGivenIn(e,t,s){return(0,T.calculate_out_given_in)(e,t,s)}static calculatePoolTradeFee(e,t,s){return(0,T.calculate_pool_trade_fee)(e,t,s)}static calculateLiquidityIn(e,t,s){return(0,T.calculate_liquidity_in)(e,t,s)}static calculateSpotPrice(e,t){return(0,T.calculate_spot_price)(e,t)}static calculateSpotPriceWithFee(e,t,s,r){return(0,T.calculate_spot_price_with_fee)(e,t,s,r)}static calculateShares(e,t,s){return(0,T.calculate_shares)(e,t,s)}static calculateLiquidityOutAssetA(e,t,s,r){return(0,T.calculate_liquidity_out_asset_a)(e,t,s,r)}static calculateLiquidityOutAssetB(e,t,s,r){return(0,T.calculate_liquidity_out_asset_b)(e,t,s,r)}};var re=class l{type;address;tokens;maxInRatio;maxOutRatio;minTradingLimit;static fromPool(e){return new l(e.address,e.tokens,e.maxInRatio,e.maxOutRatio,e.minTradingLimit)}constructor(e,t,s,r,i){this.type="Xyk",this.address=e,this.tokens=t,this.maxInRatio=s,this.maxOutRatio=r,this.minTradingLimit=i}validatePair(e,t){return!0}parsePair(e,t){let s=new Map(this.tokens.map(c=>[c.id,c])),r=s.get(e),i=s.get(t);if(r==null)throw new Error("Pool does not contain tokenIn");if(i==null)throw new Error("Pool does not contain tokenOut");let n=m(r.balance),a=m(i.balance),o=m(r.existentialDeposit),u=m(i.existentialDeposit);return{assetIn:e,assetOut:t,decimalsIn:r.decimals,decimalsOut:i.decimals,balanceIn:n,balanceOut:a,assetInED:o,assetOutED:u}}validateAndBuy(e,t,s){let r=this.calculateInGivenOut(e,t),i=this.calculateTradeFee(r,s),n=N(s.exchangeFee),a=r.plus(i),o=[];(t.isLessThan(this.minTradingLimit)||r.isLessThan(e.assetInED))&&o.push("InsufficientTradingAmount");let u=e.balanceOut.div(this.maxOutRatio);t.isGreaterThan(u)&&o.push("MaxOutRatioExceeded");let c=e.balanceIn.div(this.maxInRatio);return a.isGreaterThan(c)&&o.push("MaxInRatioExceeded"),{amountIn:a,calculatedIn:r,amountOut:t,feePct:n,errors:o}}validateAndSell(e,t,s){let r=this.calculateOutGivenIn(e,t),i=this.calculateTradeFee(r,s),n=N(s.exchangeFee),a=r.minus(i),o=[];(t.isLessThan(this.minTradingLimit)||r.isLessThan(e.assetOutED))&&o.push("InsufficientTradingAmount");let u=e.balanceIn.div(this.maxInRatio);t.isGreaterThan(u)&&o.push("MaxInRatioExceeded");let c=e.balanceOut.div(this.maxOutRatio);return a.isGreaterThan(c)&&o.push("MaxOutRatioExceeded"),{amountIn:t,calculatedOut:r,amountOut:a,feePct:n,errors:o}}calculateInGivenOut(e,t){let s=z.calculateInGivenOut(e.balanceIn.toString(),e.balanceOut.toString(),t.toFixed(0)),r=m(s);return r.isNegative()?P:r}calculateOutGivenIn(e,t){let s=z.calculateOutGivenIn(e.balanceIn.toString(),e.balanceOut.toString(),t.toFixed(0)),r=m(s);return r.isNegative()?P:r}spotPriceInGivenOut(e){let t=z.calculateSpotPrice(e.balanceOut.toString(),e.balanceIn.toString()),s=I(E,18-e.decimalsOut);return m(t).div(s)}spotPriceOutGivenIn(e){let t=z.calculateSpotPrice(e.balanceIn.toString(),e.balanceOut.toString()),s=I(E,18-e.decimalsIn);return m(t).div(s)}calculateTradeFee(e,t){let s=z.calculatePoolTradeFee(e.toString(),t.exchangeFee[0],t.exchangeFee[1]);return m(s)}};var ie=class{static get(e){switch(e.type){case"Xyk":return re.fromPool(e);case"Omnipool":return te.fromPool(e);case"Lbp":return ee.fromPool(e);case"Stableswap":return se.fromPool(e);default:throw new Error("Pool type "+e.type+" is not supported yet")}}};var j=class{routeSuggester;routerOptions;poolService;defaultRouterOptions={includeOnly:[]};constructor(e,t){this.poolService=e,this.routeSuggester=new ae,this.routerOptions={...this.defaultRouterOptions,...t}}async getPools(){let e=this.routerOptions.includeOnly;return await this.poolService.getPools(e)}async getAllAssets(){let e=await this.getPools();if(e.length===0)throw new Error("No pools configured");let t=await this.getAssets(e);return[...new Map(t).values()]}async getAssetPairs(e){let t=await this.getPools();if(t.length===0)throw new Error("No pools configured");let{assets:s,poolsMap:r}=await this.validateToken(e,t),n=this.getPaths(e,null,r,t).map(a=>a[a.length-1].assetOut);return this.toAssets([...new Set(n)],s)}async getAllPaths(e,t){let s=await this.getPools();if(s.length===0)throw new Error("No pools configured");let{poolsMap:r}=await this.validateTokenPair(e,t,s);return this.getPaths(e,t,r,s)}async getAssets(e){let t=e.map(s=>s.tokens.map(r=>({id:r.id,name:r.name,symbol:r.symbol,decimals:r.decimals,icon:r.icon,type:r.type,isSufficient:r.isSufficient,existentialDeposit:r.existentialDeposit,meta:r.meta,location:r.location,isWhiteListed:r.isWhiteListed}))).flat();return new Map(t.map(s=>[s.id,s]))}getPaths(e,t,s,r){return this.routeSuggester.getProposals(e,t,r).filter(a=>this.validPath(a,s)).map(a=>this.toHops(a,s))}async validateTokenPair(e,t,s){let r=await this.getAssets(s);if(r.get(e)==null)throw new Error(e+" is not supported token");if(r.get(t)==null)throw new Error(t+" is not supported token");let i=this.getPoolMap(s);return{assets:r,poolsMap:i}}async validateToken(e,t){let s=await this.getAssets(t);if(s.get(e)==null)throw new Error(e+" is not supported token");let r=this.getPoolMap(t);return{assets:s,poolsMap:r}}getPoolMap(e){return new Map(e.map(t=>[t.address,ie.get(t)]))}validPath(e,t){return e.length>0&&e.map(s=>this.validEdge(s,t)).reduce((s,r)=>s&&r)}validEdge([e,t,s],r){return r.get(e)?.validatePair(t,s)||!1}toHops(e,t){return e.map(([s,r,i])=>{let n=t.get(s);return{poolAddress:s,poolId:n?.id,pool:n?.type,assetIn:r,assetOut:i}})}toAssets(e,t){return e.map(s=>t.get(s))}};function wt(l,e){return l.minus(e).abs().div(l.plus(e).div(2)).multipliedBy(100).decimalPlaces(2)}function ne(l,e){return l.minus(e).div(e).multipliedBy(100).decimalPlaces(2)}function Ye(l,e){return E.minus(e.div(l)).multipliedBy(100).decimalPlaces(2)}function je(l,e){return e.div(l).minus(E).multipliedBy(100).decimalPlaces(2)}var pe=class extends j{isDirectTrade(e){return e.length==1}findBestSellRoute(e){let t=e.sort((s,r)=>{let i=s[s.length-1].amountOut,n=r[r.length-1].amountOut;return i.isGreaterThan(n)?-1:1});return t.find(s=>s.every(r=>r.errors.length==0))||t[0]}getRouteFeeRange(e){if(e.filter(s=>s.tradeFeeRange).length>0){let s=e.map(i=>i.tradeFeeRange?.[0]??i.tradeFeePct).reduce((i,n)=>i+n),r=e.map(i=>i.tradeFeeRange?.[1]??i.tradeFeePct).reduce((i,n)=>i+n);return[s,r]}}getPoolFeeRange(e){let t=e.min?N(e.min):void 0,s=e.max?N(e.max):void 0;if(t&&s)return[t,s]}async getBestSell(e,t,s){return this.getSell(e,t,s)}async getSell(e,t,s,r){let i=await super.getPools();if(i.length===0)throw new Error("No pools configured");let{poolsMap:n}=await super.validateTokenPair(e,t,i),a=super.getPaths(e,t,n,i);if(a.length===0)throw new K(e,t);let o;if(r)o=await this.toSellSwaps(s,r,n);else{let w=a.map(async Ee=>await this.toSellSwaps(s,Ee,n)),G=await Promise.all(w);o=this.findBestSellRoute(G)}let u=o[0],c=o[o.length-1],p=this.isDirectTrade(o),d=o.map(w=>w.spotPrice.shiftedBy(-1*w.assetOutDecimals)).reduce((w,G)=>w.multipliedBy(G)),g=I(d,c.assetOutDecimals),h=p?c.calculatedOut:this.calculateDelta0Y(u.amountIn,o,n),y=c.amountOut,S=p?c.tradeFeePct:Ye(h,y).toNumber(),B=h.minus(y),b=this.getRouteFeeRange(o),v=u.amountIn.shiftedBy(-1*u.assetInDecimals).multipliedBy(g),F=ne(h,v),W=w=>this.poolService.buildSellTx(e,t,u.amountIn,w,o.map(G=>G));return{type:"Sell",amountIn:u.amountIn,amountOut:c.amountOut,spotPrice:g,tradeFee:B,tradeFeePct:S,tradeFeeRange:b,priceImpactPct:F.toNumber(),swaps:o,toTx:W,toHuman(){return{type:"Sell",amountIn:_(u.amountIn,u.assetInDecimals),amountOut:_(c.amountOut,c.assetOutDecimals),spotPrice:_(g,c.assetOutDecimals),tradeFee:_(B,c.assetOutDecimals),tradeFeePct:S,tradeFeeRange:b,priceImpactPct:F.toNumber(),swaps:o.map(w=>w.toHuman())}}}}calculateDelta0Y(e,t,s){let r=[];for(let i=0;i<t.length;i++){let n=t[i],a=s.get(n.poolAddress);if(a==null)throw new Error("Pool does not exit");let o=a.parsePair(n.assetIn,n.assetOut),u;i>0?u=r[i-1]:u=e;let c=a.calculateOutGivenIn(o,u);r.push(c)}return r[r.length-1]}async toSellSwaps(e,t,s){let r=[];for(let i=0;i<t.length;i++){let n=t[i],a=s.get(n.poolAddress);if(a==null)throw new Error("Pool does not exit");let o=a.parsePair(n.assetIn,n.assetOut),u;i>0?u=r[i-1].amountOut:u=I(m(e),o.decimalsIn).decimalPlaces(0,1);let c=await this.poolService.getPoolFees(o,a),{amountOut:p,calculatedOut:d,feePct:g,errors:h}=a.validateAndSell(o,u,c),y=this.getPoolFeeRange(c),S=a.spotPriceOutGivenIn(o),B=u.shiftedBy(-1*o.decimalsIn).multipliedBy(S),b=ne(d,B);r.push({...n,assetInDecimals:o.decimalsIn,assetOutDecimals:o.decimalsOut,amountIn:u,calculatedOut:d,amountOut:p,spotPrice:S,tradeFeePct:g,tradeFeeRange:y,priceImpactPct:b.toNumber(),errors:h,toHuman(){return{...n,amountIn:_(u,o.decimalsIn),calculatedOut:_(d,o.decimalsOut),amountOut:_(p,o.decimalsOut),spotPrice:_(S,o.decimalsOut),tradeFeePct:g,tradeFeeRange:y,priceImpactPct:b.toNumber(),errors:h}}})}return r}async getBestSpotPrice(e,t){let s=await super.getPools();if(s.length===0)throw new Error("No pools configured");let{poolsMap:r}=await super.validateTokenPair(e,t,s),i=super.getPaths(e,t,r,s);if(i.length===0)return Promise.resolve(void 0);let n=s.map(b=>b.tokens.find(v=>v.id===e)).filter(b=>!!b).sort((b,v)=>Number(v.balance)-Number(b.balance)),{balance:a,decimals:o}=n[0],c=m(a).shiftedBy(-1*o).div(100).multipliedBy(.1),p=i.map(async b=>await this.toSellSwaps(c,b,r)),d=await Promise.all(p),g=this.findBestSellRoute(d),h=await this.toSellSwaps("1",g,r),y=h.map(b=>b.spotPrice.shiftedBy(-1*b.assetOutDecimals)).reduce((b,v)=>b.multipliedBy(v)),S=h[h.length-1].assetOutDecimals;return{amount:I(y,S),decimals:S}}findBestBuyRoute(e){let t=e.sort((s,r)=>{let i=s[0].amountIn,n=r[0].amountIn;return i.isGreaterThan(n)?1:-1});return t.find(s=>s.every(r=>r.errors.length==0))||t[0]}async getBestBuy(e,t,s){return this.getBuy(e,t,s)}async getBuy(e,t,s,r){let i=await super.getPools();if(i.length===0)throw new Error("No pools configured");let{poolsMap:n}=await super.validateTokenPair(e,t,i),a=super.getPaths(e,t,n,i);if(a.length===0)throw new K(e,t);let o;if(r)o=await this.toBuySwaps(s,r,n);else{let w=a.map(async Ee=>await this.toBuySwaps(s,Ee,n)),G=await Promise.all(w);o=this.findBestBuyRoute(G)}let u=o[o.length-1],c=o[0],p=this.isDirectTrade(o),d=o.map(w=>w.spotPrice.shiftedBy(-1*w.assetInDecimals)).reduce((w,G)=>w.multipliedBy(G)),g=I(d,c.assetInDecimals),h=p?c.calculatedIn:this.calculateDelta0X(u.amountOut,o,n),y=c.amountIn,S=p?c.tradeFeePct:je(h,y).toNumber(),B=y.minus(h),b=this.getRouteFeeRange(o),v=u.amountOut.shiftedBy(-1*u.assetOutDecimals).multipliedBy(g),F;h.isZero()?F=-100:F=ne(v,h).toNumber();let W=w=>this.poolService.buildBuyTx(e,t,u.amountOut,w,o.map(G=>G));return{type:"Buy",amountOut:u.amountOut,amountIn:c.amountIn,spotPrice:g,tradeFee:B,tradeFeePct:S,tradeFeeRange:b,priceImpactPct:F,swaps:o,toTx:W,toHuman(){return{type:"Buy",amountOut:_(u.amountOut,u.assetOutDecimals),amountIn:_(c.amountIn,c.assetInDecimals),spotPrice:_(g,c.assetInDecimals),tradeFee:_(B,c.assetInDecimals),tradeFeePct:S,tradeFeeRange:b,priceImpactPct:F,swaps:o.map(w=>w.toHuman())}}}}calculateDelta0X(e,t,s){let r=[];for(let i=t.length-1;i>=0;i--){let n=t[i],a=s.get(n.poolAddress);if(a==null)throw new Error("Pool does not exit");let o=a.parsePair(n.assetIn,n.assetOut),u;i==t.length-1?u=e:u=r[0];let c=a.calculateInGivenOut(o,u);r.unshift(c)}return r[0]}async toBuySwaps(e,t,s){let r=[];for(let i=t.length-1;i>=0;i--){let n=t[i],a=s.get(n.poolAddress);if(a==null)throw new Error("Pool does not exit");let o=a.parsePair(n.assetIn,n.assetOut),u;i==t.length-1?u=I(m(e),o.decimalsOut).decimalPlaces(0,1):u=r[0].amountIn;let c=await this.poolService.getPoolFees(o,a),{amountIn:p,calculatedIn:d,feePct:g,errors:h}=a.validateAndBuy(o,u,c),y=this.getPoolFeeRange(c),S=a.spotPriceInGivenOut(o),B=u.shiftedBy(-1*o.decimalsOut).multipliedBy(S),b;d.isZero()?b=-100:b=ne(B,d).toNumber(),r.unshift({...n,assetInDecimals:o.decimalsIn,assetOutDecimals:o.decimalsOut,amountOut:u,calculatedIn:d,amountIn:p,spotPrice:S,tradeFeePct:g,tradeFeeRange:y,priceImpactPct:b,errors:h,toHuman(){return{...n,amountOut:_(u,o.decimalsOut),calculatedIn:_(d,o.decimalsIn),amountIn:_(p,o.decimalsIn),spotPrice:_(S,o.decimalsIn),tradeFeePct:g,tradeFeeRange:y,priceImpactPct:b,errors:h}}})}return r}};function vt(l,e){let t=[];return JSON.stringify(l,(s,r)=>(r&&r[e]&&t.push(r),r)),t[0]}function It(l,e,t){let s;return JSON.stringify(l,(r,i)=>(i&&i[e]===t&&(s=i),i)),s}0&&(module.exports={AssetClient,AssetNotFound,BASILISK_PARACHAIN_ID,BalanceClient,BigNumber,CachingPoolService,DECIMAL_PLACES,DENOMINATOR,FarmClient,HUB_ASSET_ID,HYDRADX_OMNIPOOL_ADDRESS,HYDRADX_PARACHAIN_ID,HYDRADX_SS58_PREFIX,INFINITY,LbpMath,LbpPool,ONE,OmniMath,OmniPool,PoolConfigNotFound,PoolError,PoolFactory,PoolNotFound,PoolService,PoolType,ProviderConfigNotFound,RUNTIME_DECIMALS,RouteNotFound,Router,SYSTEM_ASSET_DECIMALS,SYSTEM_ASSET_ID,StableMath,StableSwap,StorageConfigNotFound,SubscriptionNotSupported,TRADEABLE_DEFAULT,TradeRouter,TradeType,XykMath,XykPool,ZERO,bnum,buildRoute,calculateBuyFee,calculateDiffToAvg,calculateDiffToRef,calculateSellFee,findNestedKey,findNestedObj,scale});
1
+ "use strict";var ke=Object.defineProperty;var at=Object.getOwnPropertyDescriptor;var lt=Object.getOwnPropertyNames;var ut=Object.prototype.hasOwnProperty;var ct=(l,e)=>{for(var t in e)ke(l,t,{get:e[t],enumerable:!0})},mt=(l,e,t,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of lt(e))!ut.call(l,r)&&r!==t&&ke(l,r,{get:()=>e[r],enumerable:!(s=at(e,r))||s.enumerable});return l};var pt=l=>mt(ke({},"__esModule",{value:!0}),l);var At={};ct(At,{AssetClient:()=>X,AssetNotFound:()=>Ge,BASILISK_PARACHAIN_ID:()=>Pt,BalanceClient:()=>Y,BigNumber:()=>x.BigNumber,CachingPoolService:()=>Re,DECIMAL_PLACES:()=>$e,DENOMINATOR:()=>be,FarmClient:()=>Pe,HUB_ASSET_ID:()=>le,HYDRADX_OMNIPOOL_ADDRESS:()=>ue,HYDRADX_PARACHAIN_ID:()=>bt,HYDRADX_SS58_PREFIX:()=>K,INFINITY:()=>dt,LbpMath:()=>C,LbpPool:()=>ee,ONE:()=>E,OmniMath:()=>O,OmniPool:()=>te,PoolConfigNotFound:()=>qe,PoolError:()=>J,PoolFactory:()=>ie,PoolNotFound:()=>ce,PoolService:()=>Q,PoolType:()=>k,ProviderConfigNotFound:()=>We,RUNTIME_DECIMALS:()=>Z,RouteNotFound:()=>j,Router:()=>$,SYSTEM_ASSET_DECIMALS:()=>ht,SYSTEM_ASSET_ID:()=>L,StableMath:()=>_,StableSwap:()=>se,StorageConfigNotFound:()=>He,SubscriptionNotSupported:()=>ze,TRADEABLE_DEFAULT:()=>he,TradeRouter:()=>pe,TradeType:()=>Le,XykMath:()=>z,XykPool:()=>re,ZERO:()=>b,bnum:()=>m,buildRoute:()=>Oe,calculateBuyFee:()=>je,calculateDiffToAvg:()=>wt,calculateDiffToRef:()=>ne,calculateSellFee:()=>Ye,findNestedKey:()=>vt,findNestedObj:()=>It,scale:()=>v});module.exports=pt(At);var ge=class{constructor(e=1/0){this.capacity=e}storage=[];enqueue(e){if(this.size()===this.capacity)throw Error("Queue has reached max capacity, you cannot add more items");this.storage.push(e)}dequeue(){return this.storage.shift()}size(){return this.storage.length}};var gt=5,oe=class{isNotVisited(e,t){let s=!0;return t.forEach(r=>{(r[0]===e[0]||r[1]===e[1])&&(s=!1)}),s}findPaths(e,t,s){let r=[],i=new ge,n=[];for(n.push([t,""]),i.enqueue(n);i.size()>0;){let a=i.dequeue();if(a==null||a.length>gt)return r;let o=a[a.length-1];(s===null||o[0]===s)&&r.push(a),e.get(o[0])?.forEach(c=>{if(this.isNotVisited(c,a)){let p=[...a];p.push(c),i.enqueue(p)}})}return r}buildAndPopulateGraph(e,t){let s=new Map;for(let r of e)s.set(parseInt(r),[]);for(let[r,i,n]of t){let a=parseInt(i),o=parseInt(n);s.get(a)?.push([o,r])}return s}};function Me(l){let e={};for(let t of l){let s=t.tokens.length;for(let r=0;r<s;r++){e[t.tokens[r].id]||(e[t.tokens[r].id]=[]);for(let i=0;i<s;i++){if(r==i)continue;let n=[t.address,t.tokens[r].id,t.tokens[i].id];e[t.tokens[r].id].push(n)}}}return e}var ae=class{getProposals(e,t,s){let r=Me(s),i=Object.keys(r),n=i.map(c=>r[c]).flat(),a=new oe,o=a.buildAndPopulateGraph(i,n),u=a.findPaths(o,parseInt(e),t?parseInt(t):null);return this.parsePaths(u)}parsePaths(e){let t=[];for(let s of e){let r=[];for(let i=0;i<s.length;i++){let n=s[i],a=s[i+1];if(a==null)break;r.push(this.toEdge(n,a))}t.push(r)}return t}toEdge(e,t){return[t[1],e[0].toString(),t[0].toString()]}};var de=(l,e=new Map)=>t=>{let s;return e.has(t)?e.get(t):(e.set(t,s=l(t)),s)};var x=require("bignumber.js"),$e=12;x.BigNumber.config({EXPONENTIAL_AT:[-100,100],ROUNDING_MODE:4,DECIMAL_PLACES:$e});var b=m(0),E=m(1),dt=m("Infinity");function v(l,e){let t=new x.BigNumber(e.toString()),s=new x.BigNumber(10).pow(t);return l.times(s)}function m(l){return new x.BigNumber(l.toString())}var k=(r=>(r.XYK="Xyk",r.LBP="Lbp",r.Stable="Stableswap",r.Omni="Omnipool",r))(k||{}),J=(i=>(i.UnknownError="UnknownError",i.InsufficientTradingAmount="InsufficientTradingAmount",i.MaxInRatioExceeded="MaxInRatioExceeded",i.MaxOutRatioExceeded="MaxOutRatioExceeded",i.TradeNotAllowed="TradeNotAllowed",i))(J||{}),Le=(t=>(t.Buy="Buy",t.Sell="Sell",t))(Le||{});var G=require("@galacticcouncil/math-lbp"),C=class{static getSpotPrice(e,t,s,r,i){return(0,G.get_spot_price)(e,t,s,r,i)}static calculateInGivenOut(e,t,s,r,i){return(0,G.calculate_in_given_out)(e,t,s,r,i)}static calculateOutGivenIn(e,t,s,r,i){return(0,G.calculate_out_given_in)(e,t,s,r,i)}static calculateLinearWeights(e,t,s,r,i){return(0,G.calculate_linear_weights)(e,t,s,r,i)}static calculatePoolTradeFee(e,t,s){return(0,G.calculate_pool_trade_fee)(e,t,s)}};var Je=require("@polkadot/util-crypto"),Ze=require("@polkadot/util"),Z=18,he=15,L="0",ht=12,le="1",bt=2034,K=63,Pt=2090,be=1e3,ue=(0,Je.encodeAddress)((0,Ze.stringToU8a)("modlomnipool".padEnd(32,"\0")),K);var Zt=require("@galacticcouncil/api-augment/hydradx"),Kt=require("@galacticcouncil/api-augment/basilisk"),U=class{api;constructor(e){this.api=e}get chainDecimals(){return this.api.registry.chainDecimals[0]}get chainToken(){return this.api.registry.chainTokens[0]}};var X=class extends U{SUPPORTED_TYPES=["StableSwap","Bond","Token","External","Erc20"];constructor(e){super(e)}async safeSharesQuery(){try{let e=await this.api.query.stableswap.pools.entries();return new Map(e.map(([{args:[t]},s])=>[t.toString(),s.unwrap()]))}catch{return new Map([])}}async safeBondsQuery(){try{let e=await this.api.query.bonds.bonds.entries();return new Map(e.map(([{args:[t]},s])=>[t.toString(),s.unwrap()]))}catch{return new Map([])}}async metadataQuery(){try{let e=await this.api.query.assetRegistry.assetMetadataMap.entries();return new Map(e.map(([{args:[t]},s])=>{let{decimals:r,symbol:i}=s.unwrap();return[t.toString(),{decimals:r.toNumber(),symbol:i.toHuman()}]}))}catch{return new Map([])}}async locationsQuery(){try{let e=await this.api.query.assetRegistry.assetLocations.entries();return new Map(e.map(([{args:[t]},s])=>[t.toString(),s.unwrap()]))}catch{return new Map([])}}getSystemTokenName(e){switch(e){case"HDX":return"Hydration";case"BSX":return"Basilisk";default:return e}}getToken(e,t,s,r){if(e==L){let p=this.api.consts.balances.existentialDeposit;return{id:L,name:this.getSystemTokenName(this.chainToken),symbol:this.chainToken,decimals:this.chainDecimals,icon:this.chainToken,type:"Token",isSufficient:!0,existentialDeposit:p.toString()}}let{name:i,assetType:n,isSufficient:a,existentialDeposit:o}=t,{symbol:u,decimals:c}=s.get(e)??{};return{id:e,name:i.toHuman(),symbol:u,decimals:c,icon:u,type:n.toHuman(),isSufficient:a?a.toHuman():!0,location:r?.toJSON(),existentialDeposit:o.toString()}}getBond(e,t,s,r){let[i,n]=r,{assetType:a,isSufficient:o,existentialDeposit:u}=t,{symbol:c,decimals:p}=this.getToken(i.toString(),t,s),h=n.toNumber(),d=new Intl.DateTimeFormat("en-GB"),g=[c,"Bond",d.format(h)].join(" ");return{id:e,name:g,symbol:c+"b",decimals:p,icon:c,type:a.toString(),isSufficient:o.toHuman(),existentialDeposit:u.toString(),underlyingAssetId:i.toString(),maturity:h}}getShares(e,t,s,r){let{assets:i}=r,{name:n,symbol:a,assetType:o,isSufficient:u,existentialDeposit:c}=t,h=i.map(P=>P.toString()).map(P=>{let{symbol:y}=this.getToken(P,t,s);return[P,y]}),d=Object.fromEntries(h),g=Object.values(d);return{id:e,name:g.join(", "),symbol:a?.isSome?a.toHuman():n.toHuman(),decimals:18,icon:g.join("/"),type:o.toString(),isSufficient:u.toHuman(),existentialDeposit:c.toString(),meta:d}}getExternal(e,t,s,r){let i=this.getToken(e,t,new Map,r),n=s?.find(a=>a.internalId===i.id);return n?{...i,decimals:n.decimals,name:n.name,symbol:n.symbol,icon:n.symbol,isWhiteListed:n.isWhiteListed}:i}normalizeMetadata(e,t){return t.size?t:new Map(e.map(([{args:[s]},r])=>{let{decimals:i,symbol:n}=r.unwrap();return[s.toString(),{decimals:Number(i.toString()),symbol:n.toHuman()}]}))}getSupportedAssets(e){return e.filter(([t,s])=>{if(s.isNone)return!1;let r=s.unwrap();return this.isSupportedAsset(r)})}async getOnChainAssets(e,t){let[s,r,i,n,a]=await Promise.all([this.api.query.assetRegistry.assets.entries(),this.locationsQuery(),this.safeSharesQuery(),this.safeBondsQuery(),this.metadataQuery()]),o=this.getSupportedAssets(s),u=this.normalizeMetadata(o,a),c=o.map(([{args:[p]},h])=>{let d=h.unwrap(),g=r.get(p.toString()),{assetType:P}=d;switch(P.toString()){case"Bond":let y=n.get(p.toString());return this.getBond(p.toString(),d,u,y);case"StableSwap":let S=i.get(p.toString());return this.getShares(p.toString(),d,u,S);case"External":return this.getExternal(p.toString(),d,t,g);default:return this.getToken(p.toString(),d,u,g)}});return e?c:c.filter(p=>this.isValidAsset(p))}isValidAsset(e){let t=Math.sign(e.decimals);return!!e.symbol&&(t===0||t===1)}isSupportedAsset(e){let t=e.assetType.toString();return this.SUPPORTED_TYPES.includes(t)}};var Y=class extends U{constructor(e){super(e)}async getBalance(e,t){let s=await this.api.query.assetRegistry.assets(t),{assetType:r}=s.unwrap();return r.toString()==="Erc20"?this.getErc20Balance(e,t):t===L?this.getSystemBalance(e):this.getTokenBalance(e,t)}async getSystemBalance(e){let{data:t}=await this.api.query.system.account(e);return this.calculateFreeBalance(t)}async getTokenBalance(e,t){let{free:s,reserved:r,frozen:i}=await this.api.query.tokens.accounts(e,t);return this.calculateFreeBalance({free:s,feeFrozen:r,frozen:i})}async getErc20Balance(e,t){let{free:s,reserved:r,frozen:i}=await this.getTokenBalanceData(e,t);return this.calculateFreeBalance({free:s,feeFrozen:r,frozen:i})}async subscribeSystemBalance(e,t){return this.api.query.system.account(e,({data:s})=>t(L,this.calculateFreeBalance(s)))}async subscribeTokenBalance(e,t,s){let i=t.filter(n=>n.type!=="Erc20").filter(n=>n.id!==L).map(n=>[e,n.id]);return this.api.query.tokens.accounts.multi(i,n=>{let a=[];n.forEach((o,u)=>{let c=this.calculateFreeBalance(o),p=i[u][1];a.push([p,c])}),s(a)})}async subscribeErc20Balance(e,t,s){let r=t.filter(n=>n.type==="Erc20"),i=async()=>{let n=[];(await Promise.all(r.map(async o=>[o.id,await this.getErc20Balance(e,o.id)]))).forEach(([o,u])=>{n.push([o,u])}),s(n)};return await i(),this.api.rpc.chain.subscribeNewHeads(async()=>{i()})}async getTokenBalanceData(e,t){return this.api.call.currenciesApi.account(t,e)}calculateFreeBalance(e){let{free:t,miscFrozen:s,feeFrozen:r,frozen:i}=e,n=new x.BigNumber(t),a=new x.BigNumber(s||i),o=new x.BigNumber(r||0n),u=a.gt(o)?a:o;return n.minus(u)}};var De=require("@polkadot/util-crypto"),Ce=require("@galacticcouncil/math-liquidity-mining");var Pe=class extends U{constructor(e){super(e)}secondsInYear=new x.BigNumber(365.2425).times(24).times(60).times(60);async getOmnipoolFarms(e){let t=await this.api.query.omnipoolWarehouseLM.activeYieldFarm.entries(e);return await Promise.all(t.map(async([r,i])=>{let[,n]=r.args,a=i.unwrap().toString(),o=n.toString(),u=(await this.api.query.omnipoolWarehouseLM.globalFarm(o)).unwrap(),c=(await this.api.query.omnipoolWarehouseLM.yieldFarm(e,o,a)).unwrap(),p=await this.getOraclePrice(u)??u.priceAdjustment.toString();return{assetId:e,globalFarm:u,yieldFarm:c,priceAdjustment:p}}))}async getIsolatedPoolFarms(e){let t=await this.api.query.xykWarehouseLM.activeYieldFarm.entries(e);return await Promise.all(t.map(async([r,i])=>{let[,n]=r.args,a=i.unwrap().toString(),o=n.toString(),u=(await this.api.query.xykWarehouseLM.globalFarm(o)).unwrap(),c=(await this.api.query.xykWarehouseLM.yieldFarm(e,o,a)).unwrap(),p=await this.getOraclePrice(u)??u.priceAdjustment.toString();return{assetId:e,globalFarm:u,yieldFarm:c,priceAdjustment:p}}))}async getOraclePrice(e){let t=e.rewardCurrency.toString(),s=e.incentivizedAsset.toString(),r=[t,s].sort();if(t===s)return new x.BigNumber(1).shiftedBy(18).toString();let i=await this.api.query.emaOracle.oracles("omnipool",r,"TenMinutes");if(i.isNone)return;let[n]=i.unwrap(),a=n.price.n.toString(),o=n.price.d.toString(),u;return Number(t)<Number(s)?u=(0,Ce.fixed_from_rational)(a,o):u=(0,Ce.fixed_from_rational)(o,a),u}getGlobalRewardPerPeriod(e,t,s,r){let n=e.times(t).shiftedBy(-18).times(r).shiftedBy(-18);return n.gte(s)?s:n}getPoolYieldPerPeriod(e,t,s,r){return e.times(t).div(s.times(r).shiftedBy(-18))}async getFarmApr(e,t){if(t==="isolatedpool"&&!(0,De.isAddress)(e))throw new Error("You must pass an address of isolated pool as id");if(t==="omnipool"&&(0,De.isAddress)(e))throw new Error("You must pass an asset id of omnipool");let s=6,r=t==="omnipool"?await this.getOmnipoolFarms(e):await this.getIsolatedPoolFarms(e);return r.length?r.map(({yieldFarm:a,globalFarm:o,priceAdjustment:u})=>{let c=new x.BigNumber(o.totalSharesZ.toString()),p=o.plannedYieldingPeriods.toString(),h=new x.BigNumber(o.yieldPerPeriod.toString()),d=new x.BigNumber(o.maxRewardPerPeriod.toString()),g=o.blocksPerPeriod.toString(),P=new x.BigNumber(a.multiplier.toString()).shiftedBy(-18),y=this.secondsInYear.div(new x.BigNumber(s).times(g)),S;if(c.isZero())S=h.times(P).times(y);else{let W=this.getGlobalRewardPerPeriod(c,h,d,u);S=this.getPoolYieldPerPeriod(W,P,c,u).times(y)}let B=new x.BigNumber(o.pendingRewards.toString()).plus(o.accumulatedPaidRewards.toString()),R=d.times(p);return B.div(R).gte(.99)?b:S.times(100)}).reduce((a,o)=>a.plus(o),b).toString():void 0}};var H=class extends Y{pools=[];subs=[];assets=new Map([]);mem=0;memPools=de(e=>(console.log(this.getPoolType(),"mem pools",e,"\u2705"),this.getPools()));constructor(e){super(e)}get augmentedPools(){return this.pools.filter(e=>this.isValidPool(e)).map(e=>this.withMetadata(e))}async withAssets(e){this.assets=new Map(e.map(t=>[t.id,t])),this.mem=this.mem+1}async getPoolsMem(){return this.memPools(this.mem)}async getPools(){this.unsubscribe(),this.pools=await this.loadPools(),this.subs=this.subscribe();let e=this.getPoolType();return console.log(e,`pools(${this.augmentedPools.length})`,"\u2705"),console.log(e,`subs(${this.subs.length})`,"\u2705"),this.augmentedPools}subscribe(){return this.augmentedPools.map(t=>{let s=[this.subscribeTokensPoolBalance(t)];try{let r=this.subscribePoolChange(t);s.push(r)}catch{}if(this.hasSystemAsset(t)){let r=this.subscribeSystemPoolBalance(t);s.push(r)}if(this.hasErc20Asset(t)){let r=this.subscribeErc20PoolBalance(t);s.push(r)}if(this.hasShareAsset(t)){let r=this.subscribeSharePoolBalance(t);s.push(r)}return this.subscribeLog(t),s}).flat()}hasSystemAsset(e){return e.tokens.some(t=>t.id==="0")}hasShareAsset(e){return e.type==="Stableswap"&&e.id}hasErc20Asset(e){return e.tokens.some(t=>t.type==="Erc20")}unsubscribe(){this.subs.forEach(e=>{e.then(t=>t())})}subscribeLog(e){let t=e.address.substring(0,10).concat("...");console.log(`${e.type} [${t}] balance subscribed`)}subscribeSystemPoolBalance(e){return this.subscribeSystemBalance(e.address,this.updateBalanceCallback(e))}subscribeTokensPoolBalance(e){let t=(s,r)=>s.id!==r;return this.subscribeTokenBalance(e.address,e.tokens,this.updateBalancesCallback(e,t))}subscribeErc20PoolBalance(e){return this.subscribeErc20Balance(e.address,e.tokens,this.updateBalancesCallback(e,()=>!0))}subscribeSharePoolBalance(e){let t=this.assets.get(e.id);return this.subscribeTokenBalance(ue,[t],this.updateBalancesCallback(e,()=>!0))}isValidPool(e){return e.type==="Xyk"?e.tokens.every(t=>this.assets.get(t.id)):!0}withMetadata(e){return e.tokens=e.tokens.map(t=>{let s=this.assets.get(t.id);return{...t,...s}}),e}updateBalancesCallback(e,t){return function(s){s.forEach(([r,i])=>{let n=e.tokens.findIndex(a=>a.id==r);n>=0&&t(e,r)&&(e.tokens[n].balance=i.toString())})}}updateBalanceCallback(e){return function(t,s){let r=e.tokens.findIndex(i=>i.id==t);r>=0&&(e.tokens[r].balance=s.toString())}}};var fe=class extends H{MAX_FINAL_WEIGHT=v(m(100),6);poolsData=new Map([]);isSupported(){return this.api.query.lbp!==void 0}async loadPools(){let[e,t]=await Promise.all([this.api.query.lbp.poolData.entries(),this.api.query.parachainSystem.validationData()]),{relayParentNumber:s}=t.unwrap(),r=e.filter(([i,n])=>this.isActivePool(n.unwrap(),s)).map(async([{args:[i]},n])=>{let a=n.unwrap(),o=i.toString(),u=await this.getPoolDelta(o,a,s.toString());return this.poolsData.set(i.toString(),a),{address:o,type:"Lbp",fee:a.fee.toJSON(),...u,...this.getPoolLimits()}});return Promise.all(r)}async getPoolFees(e,t){let s=this.pools.find(r=>r.address===t);return{repayFee:this.getRepayFee(),exchangeFee:s.fee}}getPoolType(){return"Lbp"}async subscribePoolChange(e){return this.api.query.parachainSystem.validationData(async t=>{let{relayParentNumber:s}=t.unwrap(),r=this.poolsData.get(e.address);if(this.isActivePool(r,s)){let n=await this.getPoolDelta(e.address,r,s.toString());Object.assign(e,n)}else{let n=this.pools.findIndex(a=>a.address==e.address);this.pools.splice(n,1)}})}async getPoolDelta(e,t,s){let{start:r,end:i,assets:n,initialWeight:a,finalWeight:o,repayTarget:u,feeCollector:c}=t,p=C.calculateLinearWeights(r.toString(),i.toString(),a.toString(),o.toString(),s),[h,d]=n,g=h.toString(),P=m(p),y=d.toString(),S=this.MAX_FINAL_WEIGHT.minus(m(P)),[B,R,N]=await Promise.all([this.isRepayFeeApplied(g,u.toString(),c.toString()),this.getBalance(e,g),this.getBalance(e,y)]);return{repayFeeApply:B,tokens:[{id:g,weight:P,balance:R.toString()},{id:y,weight:S,balance:N.toString()}]}}isActivePool(e,t){if(e.start.isEmpty||e.end.isEmpty)return!1;let s=e.start.unwrap().toNumber(),r=e.end.unwrap().toNumber();return t.toNumber()>=s&&t.toNumber()<r}async isRepayFeeApplied(e,t,s){let r=m(t);if(r.isZero())return!1;try{return(await this.getBalance(e,s)).isLessThan(r)}catch{return!0}}getRepayFee(){return this.api.consts.lbp.repayFee.toJSON()}getPoolLimits(){let e=this.api.consts.lbp.maxInRatio.toJSON(),t=this.api.consts.lbp.maxOutRatio.toJSON(),s=this.api.consts.lbp.minTradingLimit.toJSON();return{maxInRatio:e,maxOutRatio:t,minTradingLimit:s}}};var Ke=require("@polkadot/util-crypto"),Qe=require("@polkadot/util");function F(l,e){return l.shiftedBy(-1*e).toString()}function T(l){return l[0]/l[1]*100}function M(l){return l[0]/l[1]}function D(l){return[l/be,be]}var f=require("@galacticcouncil/math-omnipool");var O=class{static calculateSpotPrice(e,t,s,r){return(0,f.calculate_spot_price)(e,t,s,r)}static calculateLrnaSpotPrice(e,t){return(0,f.calculate_lrna_spot_price)(e,t)}static calculateInGivenOut(e,t,s,r,i,n,a,o,u){return(0,f.calculate_in_given_out)(e,t,s,r,i,n,a,o,u)}static calculateLrnaInGivenOut(e,t,s,r,i){return(0,f.calculate_lrna_in_given_out)(e,t,s,r,i)}static calculateOutGivenIn(e,t,s,r,i,n,a,o,u){return(0,f.calculate_out_given_in)(e,t,s,r,i,n,a,o,u)}static calculateOutGivenLrnaIn(e,t,s,r,i){return(0,f.calculate_out_given_lrna_in)(e,t,s,r,i)}static calculatePoolTradeFee(e,t,s){return(0,f.calculate_pool_trade_fee)(e,t,s)}static calculateShares(e,t,s,r){return(0,f.calculate_shares)(e,t,s,r)}static calculateLiquidityOut(e,t,s,r,i,n,a,o){return(0,f.calculate_liquidity_out)(e,t,s,r,i,n,a,o)}static calculateLiquidityLRNAOut(e,t,s,r,i,n,a,o){return(0,f.calculate_liquidity_lrna_out)(e,t,s,r,i,n,a,o)}static calculateCapDifference(e,t,s,r){let i=(0,x.BigNumber)(t),n=(0,x.BigNumber)(e),a=(0,x.BigNumber)(r),u=(0,x.BigNumber)(s).shiftedBy(-18);if(i.div(a).lt(u)){let p=u.times(a).minus(i).times(n),h=i.times((0,x.BigNumber)(1).minus(u));return p.div(h).toFixed(0)}else return"0"}static calculateLimitHubIn(e,t,s,r){return(0,f.calculate_liquidity_hub_in)(e,t,s,r)}static isSellAllowed(e){return(0,f.is_sell_allowed)(e)}static isBuyAllowed(e){return(0,f.is_buy_allowed)(e)}static isAddLiquidityAllowed(e){return(0,f.is_add_liquidity_allowed)(e)}static isRemoveLiquidityAllowed(e){return(0,f.is_remove_liquidity_allowed)(e)}static recalculateAssetFee(e,t,s,r,i,n,a,o,u,c,p){return(0,f.recalculate_asset_fee)(e,t,s,r,i,n,a,o,u,c,p)}static recalculateProtocolFee(e,t,s,r,i,n,a,o,u,c,p){return(0,f.recalculate_protocol_fee)(e,t,s,r,i,n,a,o,u,c,p)}static verifyAssetCap(e,t,s,r){return(0,f.verify_asset_cap)(e,t,s,r)}};var ye=class extends H{isSupported(){return this.api.query.omnipool!==void 0}async loadPools(){let e=this.api.consts.omnipool.hubAssetId.toString(),t=this.getPoolId(),[s,r,i]=await Promise.all([this.api.query.omnipool.assets.entries(),this.api.query.omnipool.hubAssetTradability(),this.getBalance(t,e)]),n=s.map(async([{args:[o]},u])=>{let{hubReserve:c,shares:p,tradable:h,cap:d,protocolShares:g}=u.unwrap(),P=await this.getBalance(t,o.toString());return{id:o.toString(),hubReserves:m(c.toString()),shares:m(p.toString()),tradeable:h.bits.toNumber(),balance:P.toString(),cap:m(d.toString()),protocolShares:m(g.toString())}}),a=await Promise.all(n);return a.push({id:e,tradeable:r.bits.toNumber(),balance:i.toString()}),[{address:t,type:"Omnipool",hubAssetId:e,tokens:a,...this.getPoolLimits()}]}async getPoolFees(e,t){let s=e.assetOut,r=e.assetIn,i="omnipool",n="Short",a=N=>N===L?[L,le]:[le,N],[o,u,c,p]=await Promise.all([this.api.query.system.number(),this.api.query.dynamicFees.assetFee(s),this.api.query.emaOracle.oracles(i,a(s),n),this.api.query.emaOracle.oracles(i,a(r),n)]),[h,d,g]=this.getAssetFee(e,o.toNumber(),u,c),[P,y,S]=r===le?[0,0,0]:this.getProtocolFee(e,o.toNumber(),u,p),B=h+P,R=g+S;return{assetFee:D(d),protocolFee:D(y),min:D(B),max:D(R)}}getPoolType(){return"Omnipool"}async subscribePoolChange(e){let t=e.tokens.map(s=>s.id);return this.api.query.omnipool.assets.multi(t,s=>{e.tokens=s.map((r,i)=>{let n=e.tokens[i];if(r.isNone)return n;let a=r.unwrap();return this.updateTokenState(n,a)})})}updateTokenState(e,t){let{hubReserve:s,shares:r,tradable:i,cap:n,protocolShares:a}=t;return{...e,hubReserves:m(s.toString()),shares:m(r.toString()),cap:m(n.toString()),protocolShares:m(a.toString()),tradeable:i.bits.toNumber()}}getAssetFee(e,t,s,r){let{assetOut:i,balanceOut:n}=e,{minFee:a,maxFee:o,decay:u,amplification:c}=this.api.consts.dynamicFees.assetFeeParameters,p=D(a.toNumber()),h=D(o.toNumber());if(s.isNone||r.isNone)return[a.toNumber(),a.toNumber(),o.toNumber()];let[d]=r.unwrap(),{assetFee:g,timestamp:P}=s.unwrap(),y=t-P.toNumber(),S=d.volume.bIn.toString(),B=d.volume.bOut.toString(),R=d.liquidity.b.toString();i===L&&(S=d.volume.aIn.toString(),B=d.volume.aOut.toString(),R=d.liquidity.a.toString());let N=D(g.toNumber()),W=O.recalculateAssetFee(S,B,R,"9",n.toString(),T(N).toString(),y.toString(),T(p).toString(),T(h).toString(),u.toString(),c.toString());return[a.toNumber(),Number(W)*1e4,o.toNumber()]}getProtocolFee(e,t,s,r){let{assetIn:i,balanceIn:n}=e,{minFee:a,maxFee:o,decay:u,amplification:c}=this.api.consts.dynamicFees.protocolFeeParameters,p=D(a.toNumber()),h=D(o.toNumber());if(s.isNone||r.isNone)return[a.toNumber(),a.toNumber(),o.toNumber()];let[d]=r.unwrap(),{protocolFee:g,timestamp:P}=s.unwrap(),y=t-P.toNumber(),S=d.volume.bIn.toString(),B=d.volume.bOut.toString(),R=d.liquidity.b.toString();i===L&&(S=d.volume.aIn.toString(),B=d.volume.aOut.toString(),R=d.liquidity.a.toString());let N=D(g.toNumber()),W=O.recalculateProtocolFee(S,B,R,"9",n.toString(),T(N).toString(),y.toString(),T(p).toString(),T(h).toString(),u.toString(),c.toString());return[a.toNumber(),Number(W)*1e4,o.toNumber()]}getPoolId(){return(0,Ke.encodeAddress)((0,Qe.stringToU8a)("modlomnipool".padEnd(32,"\0")),K)}getPoolLimits(){let e=this.api.consts.omnipool.maxInRatio.toJSON(),t=this.api.consts.omnipool.maxOutRatio.toJSON(),s=this.api.consts.omnipool.minimumTradingLimit.toJSON();return{maxInRatio:e,maxOutRatio:t,minTradingLimit:s}}};var Se=class extends H{isSupported(){return this.api.query.xyk!==void 0}async loadPools(){let t=(await this.api.query.xyk.poolAssets.entries()).map(async([{args:[s]},r])=>{let i=s.toString(),[n,a]=r.unwrap(),[o,u]=await Promise.all([this.getBalance(i,n.toString()),this.getBalance(i,a.toString())]);return{address:i,type:"Xyk",tokens:[{id:n.toString(),balance:o.toString()},{id:a.toString(),balance:u.toString()}],...this.getPoolLimits()}});return Promise.all(t)}async getPoolFees(e,t){return{exchangeFee:this.getExchangeFee()}}getPoolType(){return"Xyk"}subscribePoolChange(e){throw new Error("Pool change subscription not supported!")}getExchangeFee(){return this.api.consts.xyk.getExchangeFee.toJSON()}getPoolLimits(){let e=this.api.consts.xyk.maxInRatio.toJSON(),t=this.api.consts.xyk.maxOutRatio.toJSON(),s=this.api.consts.xyk.minTradingLimit.toJSON();return{maxInRatio:e,maxOutRatio:t,minTradingLimit:s}}};var xe=require("@polkadot/util-crypto");var I=require("@galacticcouncil/math-stableswap"),_=class{static getPoolAddress(e){return(0,I.pool_account_name)(e)}static calculateAmplification(e,t,s,r,i){return(0,I.calculate_amplification)(e,t,s,r,i)}static calculateInGivenOut(e,t,s,r,i,n){return(0,I.calculate_in_given_out)(e,t,s,r,i,n)}static calculateAddOneAsset(e,t,s,r,i,n){return(0,I.calculate_add_one_asset)(e,t,s,r,i,n)}static calculateSharesForAmount(e,t,s,r,i,n){return(0,I.calculate_shares_for_amount)(e,t,s,r,i,n)}static calculateOutGivenIn(e,t,s,r,i,n){return(0,I.calculate_out_given_in)(e,t,s,r,i,n)}static calculateLiquidityOutOneAsset(e,t,s,r,i,n){return(0,I.calculate_liquidity_out_one_asset)(e,t,s,r,i,n)}static calculateShares(e,t,s,r,i){return(0,I.calculate_shares)(e,t,s,r,i)}static calculateSpotPriceWithFee(e,t,s,r,i,n,a){return(0,I.calculate_spot_price_with_fee)(e,t,s,r,i,n,a)}static calculatePoolTradeFee(e,t,s){return(0,I.calculate_pool_trade_fee)(e,t,s)}};var Be=class extends H{stablePools=new Map([]);isSupported(){return this.api.query.stableswap!==void 0}async loadPools(){let[e,t]=await Promise.all([this.api.query.stableswap.pools.entries(),this.api.query.system.number()]),s=t.toNumber(),r=e.map(async([{args:[i]},n])=>{let a=n.unwrap(),o=i.toString(),u=this.getPoolAddress(o),[c,p]=await Promise.all([this.getPoolDelta(o,a,s.toString()),this.getPoolTokens(u,o,a)]);return this.stablePools.set(u,a),{address:u,id:o,type:"Stableswap",fee:D(a.fee.toNumber()),tokens:p,...c,...this.getPoolLimits()}});return Promise.all(r)}async getPoolFees(e,t){return{fee:this.pools.find(r=>r.address===t).fee}}getPoolType(){return"Stableswap"}async subscribePoolChange(e){return this.api.query.system.number(async t=>{let s=t.toNumber(),r=this.stablePools.get(e.address),i=await this.getPoolDelta(e.id,r,s.toString());Object.assign(e,i)})}async getPoolDelta(e,t,s){let{initialAmplification:r,finalAmplification:i,initialBlock:n,finalBlock:a}=t,o=_.calculateAmplification(r.toString(),i.toString(),n.toString(),a.toString(),s),u=await this.api.query.tokens.totalIssuance(e);return{amplification:o,totalIssuance:u.toString()}}async getPoolTokens(e,t,s){let{assets:r}=s,i=r.map(async o=>{let[u,c]=await Promise.all([this.api.query.stableswap.assetTradability(t,o.toString()),this.getBalance(e,o.toString())]);return{id:o.toString(),tradeable:u.bits.toNumber(),balance:c.toString()}}),n=await Promise.all(i),a=await this.api.query.omnipool.assets(t);if(a.isSome){let{tradable:o}=a.unwrap(),u=await this.getBalance(ue,t);n.push({id:t,tradeable:o.bits.toNumber(),balance:u.toString()})}return n}getPoolAddress(e){let t=Number(e),s=_.getPoolAddress(t);return(0,xe.encodeAddress)((0,xe.blake2AsHex)(s),K)}getPoolLimits(){return{maxInRatio:0,maxOutRatio:0,minTradingLimit:this.api.consts.stableswap.minTradingLimit.toJSON()}}};function Oe(l){return l.map(({assetIn:e,assetOut:t,pool:s,poolId:r})=>s==="Stableswap"?{pool:{Stableswap:r},assetIn:e,assetOut:t}:{pool:s,assetIn:e,assetOut:t})}var ce=class extends Error{constructor(e){super(),this.message=`${e} pool invalid`,this.name="PoolNotFound"}},qe=class extends Error{constructor(e,t){super(),this.message=`${e} pool missing ${t}`,this.name="PoolConfigNotFound"}},j=class extends Error{constructor(e,t){super(),this.message=`Route from ${e} to ${t} not found in pool configuration`,this.name="RouteNotFound"}},Ge=class extends Error{constructor(e){super(),this.message=`Asset ${e} not available in current network`,this.name="AssetNotFound"}},He=class extends Error{constructor(e){super(),this.message=`Storage missing ${e}`,this.name="StorageConfigNotFound"}},ze=class extends Error{constructor(e){super(),this.message=`Subscription type "${e}" not supported`,this.name="SubscriptionNotSupported"}},We=class extends Error{constructor(e){super(),this.message=`${e}`,this.name="ProviderConfigNotFound"}};var Q=class{api;assetClient;xykClient;omniClient;lbpClient;stableClient;clients=[];onChainAssets=[];memRegistry=de(e=>(console.log("Registry mem sync",e,"\u2705"),this.syncRegistry()));constructor(e){this.api=e,this.assetClient=new X(this.api),this.xykClient=new Se(this.api),this.omniClient=new ye(this.api),this.lbpClient=new fe(this.api),this.stableClient=new Be(this.api),this.clients=[this.xykClient,this.omniClient,this.lbpClient,this.stableClient]}get assets(){return this.onChainAssets}get isRegistrySynced(){return this.onChainAssets.length>0}async syncRegistry(e){let t=await this.assetClient.getOnChainAssets(!1,e);this.clients.forEach(s=>s.withAssets(t)),this.onChainAssets=t}async getPools(e){return this.isRegistrySynced||await this.memRegistry(1),e.length==0?(await Promise.all(this.clients.filter(r=>r.isSupported()).map(r=>r.getPoolsMem()))).flat():(await Promise.all(this.clients.filter(s=>e.some(r=>r===s.getPoolType())).map(s=>s.getPoolsMem()))).flat()}unsubscribe(){this.xykClient.unsubscribe(),this.omniClient.unsubscribe(),this.lbpClient.unsubscribe(),this.stableClient.unsubscribe()}async getPoolFees(e,t){switch(t.type){case"Xyk":return this.xykClient.getPoolFees(e,t.address);case"Omnipool":return this.omniClient.getPoolFees(e,t.address);case"Lbp":return this.lbpClient.getPoolFees(e,t.address);case"Stableswap":return this.stableClient.getPoolFees(e,t.address);default:throw new ce(t.type)}}isDirectOmnipoolTrade(e){return e.length==1&&e[0].pool=="Omnipool"}buildBuyTx(e,t,s,r,i){let n;this.isDirectOmnipoolTrade(i)?n=this.api.tx.omnipool.buy(t,e,s.toFixed(),r.toFixed()):n=this.api.tx.router.buy(e,t,s.toFixed(),r.toFixed(),Oe(i));let a=()=>n;return{hex:n.toHex(),name:"RouterBuy",get:a}}buildSellTx(e,t,s,r,i){let n;this.isDirectOmnipoolTrade(i)?n=this.api.tx.omnipool.sell(e,t,s.toFixed(),r.toFixed()):n=this.api.tx.router.sell(e,t,s.toFixed(),r.toFixed(),Oe(i));let a=()=>n;return{hex:n.toHex(),name:"RouterSell",get:a}}};var me=(l,e)=>l===e?0:l==null?e==null?0:-1:e==null?l==null?0:1:typeof l.compare=="function"?l.compare(e):typeof e.compare=="function"?-e.compare(l):l<e?-1:l>e?1:0;var we=(l,e=t=>t!==void 0?": "+t:"")=>class extends Error{origMessage;constructor(t){super(l(t)+e(t)),this.origMessage=t!==void 0?String(t):""}};var ft=we(()=>"illegal argument(s)"),Ve=l=>{throw new ft(l)};var yt=we(()=>"index out of bounds"),Ue=l=>{throw new yt(l)},ve=(l,e,t)=>(l<e||l>=t)&&Ue(l);var et=23283064365386963e-26,Ie=class{float(e=1){return this.int()*et*e}probability(e){return this.float()<e}norm(e=1){return(this.int()*et-.5)*2*e}normMinMax(e,t){let s=this.minmax(e,t);return this.float()<.5?s:-s}minmax(e,t){return this.float()*(t-e)+e}minmaxInt(e,t){e|=0;let s=(t|0)-e;return s?e+this.int()%s:e}minmaxUint(e,t){e>>>=0;let s=(t>>>0)-e;return s?e+this.int()%s:e}};var Ae=class extends Ie{constructor(e){super(),this.rnd=e}float(e=1){return this.rnd()*e}norm(e=1){return(this.rnd()-.5)*2*e}int(){return this.rnd()*4294967296>>>0}};var tt=new Ae(Math.random);var st=l=>l!=null&&typeof l!="function"&&l.length!==void 0;var rt=Object.getPrototypeOf({}),Te="function",it="string",V=(l,e)=>{let t;if(l===e)return!0;if(l!=null){if(typeof l.equiv===Te)return l.equiv(e)}else return l==e;if(e!=null){if(typeof e.equiv===Te)return e.equiv(l)}else return l==e;return typeof l===it||typeof e===it?!1:(t=Object.getPrototypeOf(l),(t==null||t===rt)&&(t=Object.getPrototypeOf(e),t==null||t===rt)?Ot(l,e):typeof l!==Te&&l.length!==void 0&&typeof e!==Te&&e.length!==void 0?St(l,e):l instanceof Set&&e instanceof Set?Bt(l,e):l instanceof Map&&e instanceof Map?xt(l,e):l instanceof Date&&e instanceof Date?l.getTime()===e.getTime():l instanceof RegExp&&e instanceof RegExp?l.toString()===e.toString():l!==l&&e!==e)},St=(l,e,t=V)=>{let s=l.length;if(s===e.length)for(;s-- >0&&t(l[s],e[s]););return s<0},Bt=(l,e,t=V)=>l.size===e.size&&t([...l.keys()].sort(),[...e.keys()].sort()),xt=(l,e,t=V)=>l.size===e.size&&t([...l].sort(),[...e].sort()),Ot=(l,e,t=V)=>{if(Object.keys(l).length!==Object.keys(e).length)return!1;for(let s in l)if(!e.hasOwnProperty(s)||!t(l[s],e[s]))return!1;return!0};var Xe=class{value;constructor(e){this.value=e}deref(){return this.value}};var nt=l=>l instanceof Xe;var Ne=class l{_head;_length=0;constructor(e){e&&this.into(e)}get length(){return this._length}get head(){return this._head}[Symbol.iterator](){return ot("next",this._head)}reverseIterator(){return ot("prev",this.tail)}clear(){this.release()}compare(e,t=me){let s=this._length;if(s<e._length)return-1;if(s>e._length)return 1;if(s===0)return 0;{let r=this._head,i=e._head,n=0;for(;s-- >0&&n===0;)n=t(r.value,i.value),r=r.next,i=i.next;return n}}concat(...e){let t=this.copy();for(let s of e)t.into(s);return t}equiv(e){if(!(e instanceof l||st(e))||this._length!==e.length)return!1;if(!this._length||this===e)return!0;let t=e[Symbol.iterator](),s=this._head;for(let r=this._length;r-- >0;){if(!V(s.value,t.next().value))return!1;s=s.next}return!0}filter(e){let t=this.empty();return this.traverse(s=>(e(s.value)&&t.append(s.value),!0)),t}find(e){return this.traverse(t=>t.value!==e)}findWith(e){return this.traverse(t=>!e(t.value))}first(){return this._head&&this._head.value}insertSorted(e,t){t=t||me;for(let s=this._head,r=this._length;r-- >0;){if(t(e,s.value)<=0)return this.insertBefore(s,e);s=s.next}return this.append(e)}into(e){for(let t of e)this.append(t);return this}nth(e,t){let s=this.nthCell(e);return s?s.value:t}nthCellUnsafe(e){let t,s;for(e<=this._length>>>1?(t=this._head,s="next"):(t=this.tail,s="prev",e=this._length-e-1);e-- >0&&t;)t=t[s];return t}peek(){return this.tail&&this.tail.value}$reduce(e,t){let s=this._head;for(let r=this._length;r-- >0&&!nt(t);)t=e(t,s.value),s=s.next;return t}reduce(e,t){return this.$reduce(e,t)}release(){let e=this._head;if(!e)return!0;let t;for(let s=this._length;s-- >0;)t=e.next,delete e.value,delete e.prev,delete e.next,e=t;return this._head=void 0,this._length=0,!0}reverse(){let e=this._head,t=this.tail,s=(this._length>>>1)+(this._length&1);for(;e&&t&&s>0;){let r=e.value;e.value=t.value,t.value=r,e=e.next,t=t.prev,s--}return this}setHead(e){let t=this._head;return t?(t.value=e,t):this.prepend(e)}setNth(e,t){let s=this.nthCell(e);return!s&&Ue(e),s.value=t,s}setTail(e){let t=this.tail;return t?(t.value=e,t):this.append(e)}swap(e,t){if(e!==t){let s=e.value;e.value=t.value,t.value=s}return this}toArray(e=[]){return this.traverse(t=>(e.push(t.value),!0)),e}toJSON(){return this.toArray()}toString(){let e=[];return this.traverse(t=>(e.push(String(t.value)),!0)),e.join(", ")}traverse(e,t=this._head,s){if(!this._head)return;let r=t;do{if(!e(r))break;r=r.next}while(r!==s);return r}_map(e,t){return this.traverse(s=>(e.append(t(s.value)),!0)),e}};function*ot(l,e){for(;e;)yield e.value,e=e[l]}var Fe=class l extends Ne{_tail;constructor(e){super(),e&&this.into(e)}get tail(){return this._tail}append(e){if(this._tail){let t={value:e,prev:this._tail};return this._tail.next=t,this._tail=t,this._length++,t}else return this.prepend(e)}asHead(e){return e===this._head?this:(this.remove(e),this._head.prev=e,e.next=this._head,e.prev=void 0,this._head=e,this._length++,this)}asTail(e){return e===this._tail?this:(this.remove(e),this._tail.next=e,e.prev=this._tail,e.next=void 0,this._tail=e,this._length++,this)}cons(e){return this.prepend(e),this}copy(){return new l(this)}*cycle(){for(;;)yield*this}drop(){let e=this._head;if(e)return this._head=e.next,this._head?this._head.prev=void 0:this._tail=void 0,this._length--,e.value}empty(){return new l}insertAfter(e,t){let s={value:t,next:e.next,prev:e};return e.next?e.next.prev=s:this._tail=s,e.next=s,this._length++,s}insertAfterNth(e,t){return e<0&&(e+=this._length),e>=this._length-1?this.append(t):(ve(e,0,this._length),this.insertAfter(this.nthCellUnsafe(e),t))}insertBefore(e,t){let s={value:t,next:e,prev:e.prev};return e.prev?e.prev.next=s:this._head=s,e.prev=s,this._length++,s}insertBeforeNth(e,t){return e<0&&(e+=this._length),e<=0?this.prepend(t):(ve(e,0,this._length),this.insertBefore(this.nthCellUnsafe(e),t))}map(e){return this._map(new l,e)}nth(e,t){let s=this.nthCell(e);return s?s.value:t}nthCell(e){if(e<0&&(e+=this._length),!(e<0||e>=this._length))return this.nthCellUnsafe(e)}pop(){let e=this._tail;if(e)return this._tail=e.prev,this._tail?this._tail.next=void 0:this._head=void 0,this._length--,e.value}prepend(e){let t={value:e,next:this._head};return this._head?this._head.prev=t:this._tail=t,this._head=t,this._length++,t}push(e){return this.append(e),this}release(){return this._tail=void 0,super.release()}remove(e){return e.prev?e.prev.next=e.next:this._head=e.next,e.next?e.next.prev=e.prev:this._tail=e.prev,this._length--,this}rotateLeft(){switch(this._length){case 0:case 1:return this;case 2:return this.swap(this._head,this._tail);default:return this.push(this.drop())}}rotateRight(){switch(this._length){case 0:case 1:return this;case 2:return this.swap(this._head,this._tail);default:let e=this.peek();return this.pop(),this.prepend(e),this}}seq(e=0,t=this.length){if(e>=t||e<0)return;let s=this.nthCell(e),r=this.nthCell(t-1),i=n=>({first(){return n.value},next(){return n!==r&&n.next?i(n.next):void 0}});return s?i(s):void 0}shuffle(e,t=tt){if(this._length<2)return this;for(e=e!==void 0?e:Math.ceil(1.5*Math.log2(this._length));e>0;e--){let s=this._head;for(;s;){let r=s.next;t.probability(.5)?this.asHead(s):this.asTail(s),s=r}}return this}slice(e=0,t=this.length){let s=e<0?e+this._length:e,r=t<0?t+this._length:t;(s<0||r<0)&&Ve("invalid indices: ${from} / ${to}");let i=new l,n=this.nthCell(s);for(;n&&++s<=r;)i.push(n.value),n=n.next;return i}sort(e=me){if(!this._length)return this;let t=1;for(;;){let s=this._head;this._head=void 0,this._tail=void 0;let r=0;for(;s;){r++;let i=s,n=0;for(let o=0;o<t&&(n++,i=i.next,!!i);o++);let a=t;for(;n>0||a>0&&i;){let o;n===0?(o=i,i=i.next,a--):!i||a===0||e(s.value,i.value)<=0?(o=s,s=s.next,n--):(o=i,i=i.next,a--),this._tail?this._tail.next=o:this._head=o,o.prev=this._tail,this._tail=o}s=i}if(this._tail.next=void 0,r<=1)return this;t*=2}}splice(e,t=0,s){let r;typeof e=="number"?(e<0&&(e+=this._length),ve(e,0,this._length),r=this.nthCellUnsafe(e)):r=e;let i=new l;if(t>0)for(;r&&t-- >0;)this.remove(r),i.push(r.value),r=r.next;else r&&(r=r.next);if(s)if(r)for(let n of s)this.insertBefore(r,n);else for(let n of s)this.push(n);return i}};var _e=class l{map;items;opts;_size;constructor(e,t){let s={maxlen:1/0,maxsize:1/0,map:()=>new Map,ksize:()=>0,vsize:()=>0,...t};this.map=s.map(),this.items=new Fe,this._size=0,this.opts=s,e&&this.into(e)}get length(){return this.items.length}get size(){return this._size}[Symbol.iterator](){return this.entries()}*entries(){for(let e of this.items)yield[e.k,e]}*keys(){for(let e of this.items)yield e.k}*values(){for(let e of this.items)yield e.v}copy(){let e=this.empty();e.items=this.items.copy();let t=e.items.head;for(;t;)e.map.set(t.value.k,t),t=t.next;return e}empty(){return new l(null,this.opts)}release(){this._size=0,this.map.clear();let e=this.opts.release;if(e){let t;for(;t=this.items.drop();)e(t.k,t.v);return!0}return this.items.release()}has(e){return this.map.has(e)}get(e,t){let s=this.map.get(e);return s?this.resetEntry(s):t}set(e,t){let s=this.opts.ksize(e)+this.opts.vsize(t),r=this.map.get(e),i=Math.max(0,s-(r?r.value.s:0));return this._size+=i,this.ensureSize()?this.doSetEntry(r,e,t,s):this._size-=i,t}into(e){for(let t of e)this.set(t[0],t[1]);return this}async getSet(e,t){let s=this.map.get(e);return s?this.resetEntry(s):this.set(e,await t())}delete(e){let t=this.map.get(e);return t?(this.removeEntry(t),!0):!1}resetEntry(e){return this.items.asTail(e),e.value.v}ensureSize(){let{release:e,maxsize:t,maxlen:s}=this.opts;for(;this._size>t||this.length>=s;){let r=this.items.drop();if(!r)return!1;this.map.delete(r.k),e?.(r.k,r.v),this._size-=r.s}return!0}removeEntry(e){let t=e.value;this.map.delete(t.k),this.items.remove(e),this.opts.release?.(t.k,t.v),this._size-=t.s}doSetEntry(e,t,s,r){e?(this.opts.update?.(t,e.value.v,s),e.value.v=s,e.value.s=r,this.items.asTail(e)):(this.items.push({k:t,v:s,s:r}),this.map.set(t,this.items.tail))}};var Re=class extends Q{feeCache;disconnectSubscribeNewHeads=null;constructor(e){super(e),this.feeCache=new _e(null),this.api.rpc.chain.subscribeNewHeads(async t=>{this.feeCache.release()}).then(t=>{this.disconnectSubscribeNewHeads=t})}async getPoolFees(e,t){let s=[t.address,e.assetIn,e.assetOut].join("-");if(this.feeCache.has(s))return this.feeCache.get(s);{let i=await super.getPoolFees(e,t);return this.feeCache.set(s,i),i}}async destroy(){console.log(`Destroying pool cache!
2
+ Items: [${this.feeCache.length}]`),this.feeCache.release(),this.disconnectSubscribeNewHeads?.()}};var ee=class l{type;address;tokens;maxInRatio;maxOutRatio;minTradingLimit;fee;repayFeeApply;static fromPool(e){return new l(e.address,e.tokens,e.maxInRatio,e.maxOutRatio,e.minTradingLimit,e.fee,e.repayFeeApply)}constructor(e,t,s,r,i,n,a){this.type="Lbp",this.address=e,this.tokens=t,this.maxInRatio=s,this.maxOutRatio=r,this.minTradingLimit=i,this.fee=n,this.repayFeeApply=a}validatePair(e,t){return!0}parsePair(e,t){let s=new Map(this.tokens.map(o=>[o.id,o])),r=s.get(e),i=s.get(t);if(r==null)throw new Error("Pool does not contain tokenIn");if(i==null)throw new Error("Pool does not contain tokenOut");let n=m(r.balance),a=m(i.balance);return{assetIn:e,assetOut:t,balanceIn:n,balanceOut:a,decimalsIn:r.decimals,decimalsOut:i.decimals,weightIn:r.weight,weightOut:i.weight}}validateAndBuy(e,t,s){let r=this.tokens[0].id,i=[];t.isLessThan(this.minTradingLimit)&&i.push("InsufficientTradingAmount");let n=e.balanceOut.div(this.maxOutRatio);if(t.isGreaterThan(n)&&i.push("MaxOutRatioExceeded"),r===e.assetOut){let a=this.calculateTradeFee(t,s),o=T(this.repayFeeApply?s.repayFee:s.exchangeFee),u=t.plus(a),c=this.calculateInGivenOut(e,u),p=e.balanceIn.div(this.maxInRatio);return c.isGreaterThan(p)&&i.push("MaxInRatioExceeded"),{amountIn:c,calculatedIn:c,amountOut:t,feePct:o,errors:i}}else{let a=this.calculateInGivenOut(e,t),o=e.balanceIn.div(this.maxInRatio);return a.isGreaterThan(o)&&i.push("MaxInRatioExceeded"),{amountIn:a,calculatedIn:a,amountOut:t,feePct:0,errors:i}}}validateAndSell(e,t,s){let r=this.tokens[0].id,i=[];t.isLessThan(this.minTradingLimit)&&i.push("InsufficientTradingAmount");let n=e.balanceIn.div(this.maxInRatio);if(t.isGreaterThan(n)&&i.push("MaxInRatioExceeded"),r===e.assetIn){let a=this.calculateOutGivenIn(e,t),o=e.balanceOut.div(this.maxOutRatio);return a.isGreaterThan(o)&&i.push("MaxOutRatioExceeded"),{amountIn:t,calculatedOut:a,amountOut:a,feePct:0,errors:i}}else{let a=this.calculateOutGivenIn(e,t),o=this.calculateTradeFee(a,s),u=T(this.repayFeeApply?s.repayFee:s.exchangeFee),c=a.minus(o),p=e.balanceOut.div(this.maxOutRatio);return c.isGreaterThan(p)&&i.push("MaxOutRatioExceeded"),{amountIn:t,calculatedOut:a,amountOut:c,feePct:u,errors:i}}}calculateInGivenOut(e,t){let s=C.calculateInGivenOut(e.balanceIn.toString(),e.balanceOut.toString(),e.weightIn.toString(),e.weightOut.toString(),t.toFixed(0)),r=m(s);return r.isNegative()?b:r}calculateOutGivenIn(e,t){let s=C.calculateOutGivenIn(e.balanceIn.toString(),e.balanceOut.toString(),e.weightIn.toString(),e.weightOut.toString(),t.toFixed(0)),r=m(s);return r.isNegative()?b:r}spotPriceInGivenOut(e){let t=C.getSpotPrice(e.balanceOut.toString(),e.balanceIn.toString(),e.weightOut.toString(),e.weightIn.toString(),v(E,e.decimalsOut).toString());return m(t)}spotPriceOutGivenIn(e){let t=C.getSpotPrice(e.balanceIn.toString(),e.balanceOut.toString(),e.weightIn.toString(),e.weightOut.toString(),v(E,e.decimalsIn).toString());return m(t)}calculateTradeFee(e,t){let s=C.calculatePoolTradeFee(e.toString(),this.repayFeeApply?t.repayFee[0]:t.exchangeFee[0],this.repayFeeApply?t.repayFee[1]:t.exchangeFee[1]);return m(s)}};var te=class l{type;address;tokens;maxInRatio;maxOutRatio;minTradingLimit;hubAssetId;static fromPool(e){return new l(e.address,e.tokens,e.maxInRatio,e.maxOutRatio,e.minTradingLimit,e.hubAssetId)}constructor(e,t,s,r,i,n){this.type="Omnipool",this.address=e,this.tokens=t,this.maxInRatio=s,this.maxOutRatio=r,this.minTradingLimit=i,this.hubAssetId=n}validatePair(e,t){return this.hubAssetId!=t}parsePair(e,t){let s=new Map(this.tokens.map(c=>[c.id,c])),r=s.get(e),i=s.get(t);if(r==null)throw new Error("Pool does not contain tokenIn");if(i==null)throw new Error("Pool does not contain tokenOut");let n=m(r.balance),a=m(i.balance),o=m(r.existentialDeposit),u=m(i.existentialDeposit);return{assetIn:e,assetOut:t,hubReservesIn:r.hubReserves,hubReservesOut:i.hubReserves,sharesIn:r.shares,sharesOut:i.shares,decimalsIn:r.decimals,decimalsOut:i.decimals,balanceIn:n,balanceOut:a,tradeableIn:r.tradeable,tradeableOut:i.tradeable,assetInED:o,assetOutED:u}}validateAndBuy(e,t,s){let r=this.calculateInGivenOut(e,t),i=this.calculateInGivenOut(e,t,s),n=i.minus(r),a=r===b?b:n.div(r).multipliedBy(100).decimalPlaces(2),o=[],u=O.isSellAllowed(e.tradeableIn),c=O.isBuyAllowed(e.tradeableOut);(!u||!c)&&o.push("TradeNotAllowed"),(t.isLessThan(this.minTradingLimit)||r.isLessThan(e.assetInED))&&o.push("InsufficientTradingAmount");let p=e.balanceOut.div(this.maxOutRatio);t.isGreaterThan(p)&&o.push("MaxOutRatioExceeded");let h=e.balanceIn.div(this.maxInRatio);return i.isGreaterThan(h)&&o.push("MaxInRatioExceeded"),{amountIn:i,calculatedIn:r,amountOut:t,feePct:a.toNumber(),errors:o}}validateAndSell(e,t,s){let r=this.calculateOutGivenIn(e,t),i=this.calculateOutGivenIn(e,t,s),a=r.minus(i).div(r).multipliedBy(100).decimalPlaces(2),o=[],u=O.isSellAllowed(e.tradeableIn),c=O.isBuyAllowed(e.tradeableOut);(!u||!c)&&o.push("TradeNotAllowed"),(t.isLessThan(this.minTradingLimit)||r.isLessThan(e.assetOutED))&&o.push("InsufficientTradingAmount");let p=e.balanceIn.div(this.maxInRatio);t.isGreaterThan(p)&&o.push("MaxInRatioExceeded");let h=e.balanceOut.div(this.maxOutRatio);return i.isGreaterThan(h)&&o.push("MaxOutRatioExceeded"),{amountIn:t,calculatedOut:r,amountOut:i,feePct:a.toNumber(),errors:o}}calculateInGivenOut(e,t,s){if(e.assetIn==this.hubAssetId)return this.calculateLrnaInGivenOut(e,t,s);let r=O.calculateInGivenOut(e.balanceIn.toString(),e.hubReservesIn.toString(),e.sharesIn.toString(),e.balanceOut.toString(),e.hubReservesOut.toString(),e.sharesOut.toString(),t.toFixed(0),s?M(s.assetFee).toString():b.toString(),s?M(s.protocolFee).toString():b.toString()),i=m(r);return i.isNegative()?b:i}calculateLrnaInGivenOut(e,t,s){let r=O.calculateLrnaInGivenOut(e.balanceOut.toString(),e.hubReservesOut.toString(),e.sharesOut.toString(),t.toFixed(0),s?M(s.assetFee).toString():b.toString()),i=m(r);return i.isNegative()?b:i}calculateOutGivenIn(e,t,s){if(e.assetIn==this.hubAssetId)return this.calculateOutGivenLrnaIn(e,t,s);let r=O.calculateOutGivenIn(e.balanceIn.toString(),e.hubReservesIn.toString(),e.sharesIn.toString(),e.balanceOut.toString(),e.hubReservesOut.toString(),e.sharesOut.toString(),t.toFixed(0),s?M(s.assetFee).toString():b.toString(),s?M(s.protocolFee).toString():b.toString()),i=m(r);return i.isNegative()?b:i}calculateOutGivenLrnaIn(e,t,s){let r=O.calculateOutGivenLrnaIn(e.balanceOut.toString(),e.hubReservesOut.toString(),e.sharesOut.toString(),t.toFixed(0),s?M(s.assetFee).toString():b.toString()),i=m(r);return i.isNegative()?b:i}spotPriceInGivenOut(e){if(e.assetIn==this.hubAssetId)return this.spotPriceLrnaInGivenOut(e);let t=O.calculateSpotPrice(e.balanceOut.toString(),e.hubReservesOut.toString(),e.balanceIn.toString(),e.hubReservesIn.toString());return m(t).shiftedBy(-1*(Z-e.decimalsOut)).decimalPlaces(0,1)}spotPriceLrnaInGivenOut(e){let t=O.calculateLrnaSpotPrice(e.hubReservesOut.toString(),e.balanceOut.toString());return m(t).shiftedBy(-1*(Z-e.decimalsOut)).decimalPlaces(0,1)}spotPriceOutGivenIn(e){if(e.assetIn==this.hubAssetId)return this.spotPriceOutGivenLrnaIn(e);let t=O.calculateSpotPrice(e.balanceIn.toString(),e.hubReservesIn.toString(),e.balanceOut.toString(),e.hubReservesOut.toString());return m(t).shiftedBy(-1*(Z-e.decimalsIn)).decimalPlaces(0,1)}spotPriceOutGivenLrnaIn(e){let t=O.calculateLrnaSpotPrice(e.balanceOut.toString(),e.hubReservesOut.toString());return m(t).shiftedBy(-1*(Z-e.decimalsIn)).decimalPlaces(0,1)}};var se=class l{type;address;tokens;maxInRatio;maxOutRatio;minTradingLimit;amplification;id;fee;totalIssuance;static fromPool(e){return new l(e.address,e.tokens,e.maxInRatio,e.maxOutRatio,e.minTradingLimit,e.amplification,e.id,e.fee,e.totalIssuance)}constructor(e,t,s,r,i,n,a,o,u){this.type="Stableswap",this.address=e,this.tokens=t,this.maxInRatio=s,this.maxOutRatio=r,this.minTradingLimit=i,this.amplification=n,this.id=a,this.fee=o,this.totalIssuance=u}validatePair(e,t){return!0}parsePair(e,t){let s=new Map(this.tokens.map(c=>[c.id,c])),r=s.get(e),i=s.get(t);if(r==null)throw new Error("Pool does not contain tokenIn");if(i==null)throw new Error("Pool does not contain tokenOut");let n=m(r.balance),a=m(i.balance),o=m(r.existentialDeposit),u=m(i.existentialDeposit);return{assetIn:e,assetOut:t,balanceIn:n,balanceOut:a,decimalsIn:r.decimals,decimalsOut:i.decimals,tradeableIn:this.id===e?he:r.tradeable,tradeableOut:this.id===t?he:i.tradeable,assetInED:o,assetOutED:u}}validateAndBuy(e,t,s){let r=this.calculateInGivenOut(e,t),i=this.calculateInGivenOut(e,t,s),n=T(s.fee),a=[],o=O.isSellAllowed(e.tradeableIn),u=O.isBuyAllowed(e.tradeableOut);return(!o||!u)&&a.push("TradeNotAllowed"),(t.isLessThan(this.minTradingLimit)||r.isLessThan(e.assetInED))&&a.push("InsufficientTradingAmount"),{amountIn:i,calculatedIn:r,amountOut:t,feePct:n,errors:a}}validateAndSell(e,t,s){let r=this.calculateOutGivenIn(e,t),i=this.calculateOutGivenIn(e,t,s),n=T(s.fee),a=[],o=O.isSellAllowed(e.tradeableIn),u=O.isBuyAllowed(e.tradeableOut);return(!o||!u)&&a.push("TradeNotAllowed"),(t.isLessThan(this.minTradingLimit)||r.isLessThan(e.assetOutED))&&a.push("InsufficientTradingAmount"),{amountIn:t,calculatedOut:r,amountOut:i,feePct:n,errors:a}}calculateIn(e,t,s){let r=_.calculateInGivenOut(this.getReserves(),Number(e.assetIn),Number(e.assetOut),t.toFixed(0),this.amplification,s?M(s.fee).toString():b.toString()),i=m(r);return i.isNegative()?b:i}calculateAddOneAsset(e,t,s){let r=_.calculateAddOneAsset(this.getReserves(),t.toFixed(0),Number(e.assetIn),this.amplification,this.totalIssuance,s?M(s.fee).toString():b.toString()),i=m(r);return i.isNegative()?b:i}calculateSharesForAmount(e,t,s){let r=_.calculateSharesForAmount(this.getReserves(),Number(e.assetOut),t.toFixed(0),this.amplification,this.totalIssuance,s?M(s.fee).toString():b.toString()),i=m(r);return i.isNegative()?b:i}calculateInGivenOut(e,t,s){return e.assetOut==this.id?this.calculateAddOneAsset(e,t,s):e.assetIn==this.id?this.calculateSharesForAmount(e,t,s):this.calculateIn(e,t,s)}spotPriceInGivenOut(e){let t=_.calculateSpotPriceWithFee(this.id,this.getReserves(),this.amplification,e.assetOut,e.assetIn,this.totalIssuance,"0");if(e.assetOut==this.id)return m(t);if(e.assetIn==this.id){let r=v(E,e.decimalsIn-e.decimalsOut);return m(t).div(r)}let s=v(E,18-e.decimalsIn);return m(t).div(s)}calculateOut(e,t,s){let r=_.calculateOutGivenIn(this.getReserves(),Number(e.assetIn),Number(e.assetOut),t.toFixed(0),this.amplification,s?M(s.fee).toString():b.toString()),i=m(r);return i.isNegative()?b:i}calculateWithdrawOneAsset(e,t,s){let r=_.calculateLiquidityOutOneAsset(this.getReserves(),t.toFixed(0),Number(e.assetOut),this.amplification,this.totalIssuance,s?M(s.fee).toString():b.toString()),i=m(r);return i.isNegative()?b:i}calculateShares(e,t,s){let r=_.calculateShares(this.getReserves(),this.getAssets(e.assetIn,t),this.amplification,this.totalIssuance,s?M(s.fee).toString():b.toString()),i=m(r);return i.isNegative()?b:i}calculateOutGivenIn(e,t,s){return e.assetIn==this.id?this.calculateWithdrawOneAsset(e,t,s):e.assetOut==this.id?this.calculateShares(e,t,s):this.calculateOut(e,t,s)}spotPriceOutGivenIn(e){let t=_.calculateSpotPriceWithFee(this.id,this.getReserves(),this.amplification,e.assetIn,e.assetOut,this.totalIssuance,"0");if(e.assetIn==this.id)return m(t);if(e.assetOut==this.id){let r=v(E,e.decimalsOut-e.decimalsIn);return m(t).div(r)}let s=v(E,18-e.decimalsOut);return m(t).div(s)}calculateTradeFee(e,t){let s=_.calculatePoolTradeFee(e.toString(),t.fee[0],t.fee[1]);return m(s)}getReserves(){let e=this.tokens.filter(t=>t.id!=this.id).map(({id:t,balance:s,decimals:r})=>({asset_id:Number(t),amount:s,decimals:r}));return JSON.stringify(e)}getAssets(e,t){let s={asset_id:Number(e),amount:t.toFixed(0)};return JSON.stringify([s])}};var A=require("@galacticcouncil/math-xyk"),z=class{static getSpotPrice(e,t,s){return(0,A.get_spot_price)(e,t,s)}static calculateInGivenOut(e,t,s){return(0,A.calculate_in_given_out)(e,t,s)}static calculateOutGivenIn(e,t,s){return(0,A.calculate_out_given_in)(e,t,s)}static calculatePoolTradeFee(e,t,s){return(0,A.calculate_pool_trade_fee)(e,t,s)}static calculateLiquidityIn(e,t,s){return(0,A.calculate_liquidity_in)(e,t,s)}static calculateSpotPrice(e,t){return(0,A.calculate_spot_price)(e,t)}static calculateSpotPriceWithFee(e,t,s,r){return(0,A.calculate_spot_price_with_fee)(e,t,s,r)}static calculateShares(e,t,s){return(0,A.calculate_shares)(e,t,s)}static calculateLiquidityOutAssetA(e,t,s,r){return(0,A.calculate_liquidity_out_asset_a)(e,t,s,r)}static calculateLiquidityOutAssetB(e,t,s,r){return(0,A.calculate_liquidity_out_asset_b)(e,t,s,r)}};var re=class l{type;address;tokens;maxInRatio;maxOutRatio;minTradingLimit;static fromPool(e){return new l(e.address,e.tokens,e.maxInRatio,e.maxOutRatio,e.minTradingLimit)}constructor(e,t,s,r,i){this.type="Xyk",this.address=e,this.tokens=t,this.maxInRatio=s,this.maxOutRatio=r,this.minTradingLimit=i}validatePair(e,t){return!0}parsePair(e,t){let s=new Map(this.tokens.map(c=>[c.id,c])),r=s.get(e),i=s.get(t);if(r==null)throw new Error("Pool does not contain tokenIn");if(i==null)throw new Error("Pool does not contain tokenOut");let n=m(r.balance),a=m(i.balance),o=m(r.existentialDeposit),u=m(i.existentialDeposit);return{assetIn:e,assetOut:t,decimalsIn:r.decimals,decimalsOut:i.decimals,balanceIn:n,balanceOut:a,assetInED:o,assetOutED:u}}validateAndBuy(e,t,s){let r=this.calculateInGivenOut(e,t),i=this.calculateTradeFee(r,s),n=T(s.exchangeFee),a=r.plus(i),o=[];(t.isLessThan(this.minTradingLimit)||r.isLessThan(e.assetInED))&&o.push("InsufficientTradingAmount");let u=e.balanceOut.div(this.maxOutRatio);t.isGreaterThan(u)&&o.push("MaxOutRatioExceeded");let c=e.balanceIn.div(this.maxInRatio);return a.isGreaterThan(c)&&o.push("MaxInRatioExceeded"),{amountIn:a,calculatedIn:r,amountOut:t,feePct:n,errors:o}}validateAndSell(e,t,s){let r=this.calculateOutGivenIn(e,t),i=this.calculateTradeFee(r,s),n=T(s.exchangeFee),a=r.minus(i),o=[];(t.isLessThan(this.minTradingLimit)||r.isLessThan(e.assetOutED))&&o.push("InsufficientTradingAmount");let u=e.balanceIn.div(this.maxInRatio);t.isGreaterThan(u)&&o.push("MaxInRatioExceeded");let c=e.balanceOut.div(this.maxOutRatio);return a.isGreaterThan(c)&&o.push("MaxOutRatioExceeded"),{amountIn:t,calculatedOut:r,amountOut:a,feePct:n,errors:o}}calculateInGivenOut(e,t){let s=z.calculateInGivenOut(e.balanceIn.toString(),e.balanceOut.toString(),t.toFixed(0)),r=m(s);return r.isNegative()?b:r}calculateOutGivenIn(e,t){let s=z.calculateOutGivenIn(e.balanceIn.toString(),e.balanceOut.toString(),t.toFixed(0)),r=m(s);return r.isNegative()?b:r}spotPriceInGivenOut(e){let t=z.calculateSpotPrice(e.balanceOut.toString(),e.balanceIn.toString()),s=v(E,18-e.decimalsOut);return m(t).div(s)}spotPriceOutGivenIn(e){let t=z.calculateSpotPrice(e.balanceIn.toString(),e.balanceOut.toString()),s=v(E,18-e.decimalsIn);return m(t).div(s)}calculateTradeFee(e,t){let s=z.calculatePoolTradeFee(e.toString(),t.exchangeFee[0],t.exchangeFee[1]);return m(s)}};var ie=class{static get(e){switch(e.type){case"Xyk":return re.fromPool(e);case"Omnipool":return te.fromPool(e);case"Lbp":return ee.fromPool(e);case"Stableswap":return se.fromPool(e);default:throw new Error("Pool type "+e.type+" is not supported yet")}}};var $=class{routeSuggester;routerOptions;poolService;defaultRouterOptions={includeOnly:[]};constructor(e,t){this.poolService=e,this.routeSuggester=new ae,this.routerOptions={...this.defaultRouterOptions,...t}}async getPools(){let e=this.routerOptions.includeOnly;return await this.poolService.getPools(e)}async getAllAssets(){let e=await this.getPools();if(e.length===0)throw new Error("No pools configured");let t=await this.getAssets(e);return[...new Map(t).values()]}async getAssetPairs(e){let t=await this.getPools();if(t.length===0)throw new Error("No pools configured");let{assets:s,poolsMap:r}=await this.validateToken(e,t),n=this.getPaths(e,null,r,t).map(a=>a[a.length-1].assetOut);return this.toAssets([...new Set(n)],s)}async getAllPaths(e,t){let s=await this.getPools();if(s.length===0)throw new Error("No pools configured");let{poolsMap:r}=await this.validateTokenPair(e,t,s);return this.getPaths(e,t,r,s)}async getAssets(e){let t=e.map(s=>s.tokens.map(r=>({id:r.id,name:r.name,symbol:r.symbol,decimals:r.decimals,icon:r.icon,type:r.type,isSufficient:r.isSufficient,existentialDeposit:r.existentialDeposit,meta:r.meta,location:r.location,isWhiteListed:r.isWhiteListed}))).flat();return new Map(t.map(s=>[s.id,s]))}getPaths(e,t,s,r){return this.routeSuggester.getProposals(e,t,r).filter(a=>this.validPath(a,s)).map(a=>this.toHops(a,s))}async validateTokenPair(e,t,s){let r=await this.getAssets(s);if(r.get(e)==null)throw new Error(e+" is not supported token");if(r.get(t)==null)throw new Error(t+" is not supported token");let i=this.getPoolMap(s);return{assets:r,poolsMap:i}}async validateToken(e,t){let s=await this.getAssets(t);if(s.get(e)==null)throw new Error(e+" is not supported token");let r=this.getPoolMap(t);return{assets:s,poolsMap:r}}getPoolMap(e){return new Map(e.map(t=>[t.address,ie.get(t)]))}validPath(e,t){return e.length>0&&e.map(s=>this.validEdge(s,t)).reduce((s,r)=>s&&r)}validEdge([e,t,s],r){return r.get(e)?.validatePair(t,s)||!1}toHops(e,t){return e.map(([s,r,i])=>{let n=t.get(s);return{poolAddress:s,poolId:n?.id,pool:n?.type,assetIn:r,assetOut:i}})}toAssets(e,t){return e.map(s=>t.get(s))}};function wt(l,e){return l.minus(e).abs().div(l.plus(e).div(2)).multipliedBy(100).decimalPlaces(2)}function ne(l,e){return l.minus(e).div(e).multipliedBy(100).decimalPlaces(2)}function Ye(l,e){return E.minus(e.div(l)).multipliedBy(100).decimalPlaces(2)}function je(l,e){return e.div(l).minus(E).multipliedBy(100).decimalPlaces(2)}var pe=class extends ${isDirectTrade(e){return e.length==1}findBestSellRoute(e){let t=e.sort((s,r)=>{let i=s[s.length-1].amountOut,n=r[r.length-1].amountOut;return i.isGreaterThan(n)?-1:1});return t.find(s=>s.every(r=>r.errors.length==0))||t[0]}getRouteFeeRange(e){if(e.filter(s=>s.tradeFeeRange).length>0){let s=e.map(i=>i.tradeFeeRange?.[0]??i.tradeFeePct).reduce((i,n)=>i+n),r=e.map(i=>i.tradeFeeRange?.[1]??i.tradeFeePct).reduce((i,n)=>i+n);return[s,r]}}getPoolFeeRange(e){let t=e.min?T(e.min):void 0,s=e.max?T(e.max):void 0;if(t&&s)return[t,s]}async getBestSell(e,t,s){return this.getSell(e,t,s)}async getSell(e,t,s,r){let i=await super.getPools();if(i.length===0)throw new Error("No pools configured");let{poolsMap:n}=await super.validateTokenPair(e,t,i),a=super.getPaths(e,t,n,i);if(a.length===0)throw new j(e,t);let o;if(r)o=await this.toSellSwaps(s,r,n);else{let w=a.map(async Ee=>await this.toSellSwaps(s,Ee,n)),q=await Promise.all(w);o=this.findBestSellRoute(q)}let u=o[0],c=o[o.length-1],p=this.isDirectTrade(o),h=o.map(w=>w.spotPrice.shiftedBy(-1*w.assetOutDecimals)).reduce((w,q)=>w.multipliedBy(q)),d=v(h,c.assetOutDecimals),g=p?c.calculatedOut:this.calculateDelta0Y(u.amountIn,o,n),P=c.amountOut,y=p?c.tradeFeePct:Ye(g,P).toNumber(),S=g.minus(P),B=this.getRouteFeeRange(o),R=u.amountIn.shiftedBy(-1*u.assetInDecimals).multipliedBy(d),N=ne(g,R),W=w=>this.poolService.buildSellTx(e,t,u.amountIn,w,o.map(q=>q));return{type:"Sell",amountIn:u.amountIn,amountOut:c.amountOut,spotPrice:d,tradeFee:S,tradeFeePct:y,tradeFeeRange:B,priceImpactPct:N.toNumber(),swaps:o,toTx:W,toHuman(){return{type:"Sell",amountIn:F(u.amountIn,u.assetInDecimals),amountOut:F(c.amountOut,c.assetOutDecimals),spotPrice:F(d,c.assetOutDecimals),tradeFee:F(S,c.assetOutDecimals),tradeFeePct:y,tradeFeeRange:B,priceImpactPct:N.toNumber(),swaps:o.map(w=>w.toHuman())}}}}calculateDelta0Y(e,t,s){let r=[];for(let i=0;i<t.length;i++){let n=t[i],a=s.get(n.poolAddress);if(a==null)throw new Error("Pool does not exit");let o=a.parsePair(n.assetIn,n.assetOut),u;i>0?u=r[i-1]:u=e;let c=a.calculateOutGivenIn(o,u);r.push(c)}return r[r.length-1]}async toSellSwaps(e,t,s){let r=[];for(let i=0;i<t.length;i++){let n=t[i],a=s.get(n.poolAddress);if(a==null)throw new Error("Pool does not exit");let o=a.parsePair(n.assetIn,n.assetOut),u;i>0?u=r[i-1].amountOut:u=v(m(e),o.decimalsIn).decimalPlaces(0,1);let c=await this.poolService.getPoolFees(o,a),{amountOut:p,calculatedOut:h,feePct:d,errors:g}=a.validateAndSell(o,u,c),P=this.getPoolFeeRange(c),y=a.spotPriceOutGivenIn(o),S=u.shiftedBy(-1*o.decimalsIn).multipliedBy(y),B=ne(h,S);r.push({...n,assetInDecimals:o.decimalsIn,assetOutDecimals:o.decimalsOut,amountIn:u,calculatedOut:h,amountOut:p,spotPrice:y,tradeFeePct:d,tradeFeeRange:P,priceImpactPct:B.toNumber(),errors:g,toHuman(){return{...n,amountIn:F(u,o.decimalsIn),calculatedOut:F(h,o.decimalsOut),amountOut:F(p,o.decimalsOut),spotPrice:F(y,o.decimalsOut),tradeFeePct:d,tradeFeeRange:P,priceImpactPct:B.toNumber(),errors:g}}})}return r}async getMostLiquidRoute(e,t){let s=await super.getPools(),{poolsMap:r}=await super.validateTokenPair(e,t,s),i=super.getPaths(e,t,r,s);if(i.length===0)throw new j(e,t);let n=s.map(g=>g.tokens.find(P=>P.id===e)).filter(g=>!!g).sort((g,P)=>Number(P.balance)-Number(g.balance)),{balance:a,decimals:o}=n[0],c=m(a).shiftedBy(-1*o).div(100).multipliedBy(.1),p=i.map(async g=>await this.toSellSwaps(c,g,r)),h=await Promise.all(p);return this.findBestSellRoute(h).map(g=>({poolAddress:g.poolAddress,poolId:g?.poolId,pool:g.pool,assetIn:g.assetIn,assetOut:g.assetOut}))}async getBestSpotPrice(e,t){let s=await super.getPools();if(s.length===0)throw new Error("No pools configured");let{poolsMap:r}=await super.validateTokenPair(e,t,s);if(super.getPaths(e,t,r,s).length===0)return Promise.resolve(void 0);let n=await this.getMostLiquidRoute(e,t),a=await this.toSellSwaps("1",n,r),o=a.map(p=>p.spotPrice.shiftedBy(-1*p.assetOutDecimals)).reduce((p,h)=>p.multipliedBy(h)),u=a[a.length-1].assetOutDecimals;return{amount:v(o,u),decimals:u}}findBestBuyRoute(e){let t=e.sort((s,r)=>{let i=s[0].amountIn,n=r[0].amountIn;return i.isGreaterThan(n)?1:-1});return t.find(s=>s.every(r=>r.errors.length==0))||t[0]}async getBestBuy(e,t,s){return this.getBuy(e,t,s)}async getBuy(e,t,s,r){let i=await super.getPools();if(i.length===0)throw new Error("No pools configured");let{poolsMap:n}=await super.validateTokenPair(e,t,i),a=super.getPaths(e,t,n,i);if(a.length===0)throw new j(e,t);let o;if(r)o=await this.toBuySwaps(s,r,n);else{let w=a.map(async Ee=>await this.toBuySwaps(s,Ee,n)),q=await Promise.all(w);o=this.findBestBuyRoute(q)}let u=o[o.length-1],c=o[0],p=this.isDirectTrade(o),h=o.map(w=>w.spotPrice.shiftedBy(-1*w.assetInDecimals)).reduce((w,q)=>w.multipliedBy(q)),d=v(h,c.assetInDecimals),g=p?c.calculatedIn:this.calculateDelta0X(u.amountOut,o,n),P=c.amountIn,y=p?c.tradeFeePct:je(g,P).toNumber(),S=P.minus(g),B=this.getRouteFeeRange(o),R=u.amountOut.shiftedBy(-1*u.assetOutDecimals).multipliedBy(d),N;g.isZero()?N=-100:N=ne(R,g).toNumber();let W=w=>this.poolService.buildBuyTx(e,t,u.amountOut,w,o.map(q=>q));return{type:"Buy",amountOut:u.amountOut,amountIn:c.amountIn,spotPrice:d,tradeFee:S,tradeFeePct:y,tradeFeeRange:B,priceImpactPct:N,swaps:o,toTx:W,toHuman(){return{type:"Buy",amountOut:F(u.amountOut,u.assetOutDecimals),amountIn:F(c.amountIn,c.assetInDecimals),spotPrice:F(d,c.assetInDecimals),tradeFee:F(S,c.assetInDecimals),tradeFeePct:y,tradeFeeRange:B,priceImpactPct:N,swaps:o.map(w=>w.toHuman())}}}}calculateDelta0X(e,t,s){let r=[];for(let i=t.length-1;i>=0;i--){let n=t[i],a=s.get(n.poolAddress);if(a==null)throw new Error("Pool does not exit");let o=a.parsePair(n.assetIn,n.assetOut),u;i==t.length-1?u=e:u=r[0];let c=a.calculateInGivenOut(o,u);r.unshift(c)}return r[0]}async toBuySwaps(e,t,s){let r=[];for(let i=t.length-1;i>=0;i--){let n=t[i],a=s.get(n.poolAddress);if(a==null)throw new Error("Pool does not exit");let o=a.parsePair(n.assetIn,n.assetOut),u;i==t.length-1?u=v(m(e),o.decimalsOut).decimalPlaces(0,1):u=r[0].amountIn;let c=await this.poolService.getPoolFees(o,a),{amountIn:p,calculatedIn:h,feePct:d,errors:g}=a.validateAndBuy(o,u,c),P=this.getPoolFeeRange(c),y=a.spotPriceInGivenOut(o),S=u.shiftedBy(-1*o.decimalsOut).multipliedBy(y),B;h.isZero()?B=-100:B=ne(S,h).toNumber(),r.unshift({...n,assetInDecimals:o.decimalsIn,assetOutDecimals:o.decimalsOut,amountOut:u,calculatedIn:h,amountIn:p,spotPrice:y,tradeFeePct:d,tradeFeeRange:P,priceImpactPct:B,errors:g,toHuman(){return{...n,amountOut:F(u,o.decimalsOut),calculatedIn:F(h,o.decimalsIn),amountIn:F(p,o.decimalsIn),spotPrice:F(y,o.decimalsIn),tradeFeePct:d,tradeFeeRange:P,priceImpactPct:B,errors:g}}})}return r}};function vt(l,e){let t=[];return JSON.stringify(l,(s,r)=>(r&&r[e]&&t.push(r),r)),t[0]}function It(l,e,t){let s;return JSON.stringify(l,(r,i)=>(i&&i[e]===t&&(s=i),i)),s}0&&(module.exports={AssetClient,AssetNotFound,BASILISK_PARACHAIN_ID,BalanceClient,BigNumber,CachingPoolService,DECIMAL_PLACES,DENOMINATOR,FarmClient,HUB_ASSET_ID,HYDRADX_OMNIPOOL_ADDRESS,HYDRADX_PARACHAIN_ID,HYDRADX_SS58_PREFIX,INFINITY,LbpMath,LbpPool,ONE,OmniMath,OmniPool,PoolConfigNotFound,PoolError,PoolFactory,PoolNotFound,PoolService,PoolType,ProviderConfigNotFound,RUNTIME_DECIMALS,RouteNotFound,Router,SYSTEM_ASSET_DECIMALS,SYSTEM_ASSET_ID,StableMath,StableSwap,StorageConfigNotFound,SubscriptionNotSupported,TRADEABLE_DEFAULT,TradeRouter,TradeType,XykMath,XykPool,ZERO,bnum,buildRoute,calculateBuyFee,calculateDiffToAvg,calculateDiffToRef,calculateSellFee,findNestedKey,findNestedObj,scale});
package/build/index.mjs CHANGED
@@ -1,2 +1,2 @@
1
- var re=class{constructor(e=1/0){this.capacity=e}storage=[];enqueue(e){if(this.size()===this.capacity)throw Error("Queue has reached max capacity, you cannot add more items");this.storage.push(e)}dequeue(){return this.storage.shift()}size(){return this.storage.length}};var Te=5,U=class{isNotVisited(e,t){let s=!0;return t.forEach(r=>{(r[0]===e[0]||r[1]===e[1])&&(s=!1)}),s}findPaths(e,t,s){let r=[],i=new re,o=[];for(o.push([t,""]),i.enqueue(o);i.size()>0;){let a=i.dequeue();if(a==null||a.length>Te)return r;let n=a[a.length-1];(s===null||n[0]===s)&&r.push(a),e.get(n[0])?.forEach(c=>{if(this.isNotVisited(c,a)){let p=[...a];p.push(c),i.enqueue(p)}})}return r}buildAndPopulateGraph(e,t){let s=new Map;for(let r of e)s.set(parseInt(r),[]);for(let[r,i,o]of t){let a=parseInt(i),n=parseInt(o);s.get(a)?.push([n,r])}return s}};function ge(m){let e={};for(let t of m){let s=t.tokens.length;for(let r=0;r<s;r++){e[t.tokens[r].id]||(e[t.tokens[r].id]=[]);for(let i=0;i<s;i++){if(r==i)continue;let o=[t.address,t.tokens[r].id,t.tokens[i].id];e[t.tokens[r].id].push(o)}}}return e}var Y=class{getProposals(e,t,s){let r=ge(s),i=Object.keys(r),o=i.map(c=>r[c]).flat(),a=new U,n=a.buildAndPopulateGraph(i,o),l=a.findPaths(n,parseInt(e),t?parseInt(t):null);return this.parsePaths(l)}parsePaths(e){let t=[];for(let s of e){let r=[];for(let i=0;i<s.length;i++){let o=s[i],a=s[i+1];if(a==null)break;r.push(this.toEdge(o,a))}t.push(r)}return t}toEdge(e,t){return[t[1],e[0].toString(),t[0].toString()]}};import{memoize1 as Pt}from"@thi.ng/memoize";import{BigNumber as O}from"bignumber.js";var ve=12;O.config({EXPONENTIAL_AT:[-100,100],ROUNDING_MODE:4,DECIMAL_PLACES:ve});var P=u(0),v=u(1),zt=u("Infinity");function x(m,e){let t=new O(e.toString()),s=new O(10).pow(t);return m.times(s)}function u(m){return new O(m.toString())}var E=(r=>(r.XYK="Xyk",r.LBP="Lbp",r.Stable="Stableswap",r.Omni="Omnipool",r))(E||{}),z=(i=>(i.UnknownError="UnknownError",i.InsufficientTradingAmount="InsufficientTradingAmount",i.MaxInRatioExceeded="MaxInRatioExceeded",i.MaxOutRatioExceeded="MaxOutRatioExceeded",i.TradeNotAllowed="TradeNotAllowed",i))(z||{}),ye=(t=>(t.Buy="Buy",t.Sell="Sell",t))(ye||{});import{calculate_in_given_out as Re,calculate_out_given_in as Ee,calculate_linear_weights as ke,calculate_pool_trade_fee as _e,get_spot_price as Le}from"@galacticcouncil/math-lbp";var D=class{static getSpotPrice(e,t,s,r,i){return Le(e,t,s,r,i)}static calculateInGivenOut(e,t,s,r,i){return Re(e,t,s,r,i)}static calculateOutGivenIn(e,t,s,r,i){return Ee(e,t,s,r,i)}static calculateLinearWeights(e,t,s,r,i){return ke(e,t,s,r,i)}static calculatePoolTradeFee(e,t,s){return _e(e,t,s)}};import{memoize1 as Ce}from"@thi.ng/memoize";import{encodeAddress as De}from"@polkadot/util-crypto";import{stringToU8a as Me}from"@polkadot/util";var J=18,de=15,_="0",Vt=12,ie="1",es=2034,j=63,ts=2090,be=1e3,oe=De(Me("modlomnipool".padEnd(32,"\0")),j);import"@galacticcouncil/api-augment/hydradx";import"@galacticcouncil/api-augment/basilisk";var q=class{api;constructor(e){this.api=e}get chainDecimals(){return this.api.registry.chainDecimals[0]}get chainToken(){return this.api.registry.chainTokens[0]}};var H=class extends q{SUPPORTED_TYPES=["StableSwap","Bond","Token","External","Erc20"];constructor(e){super(e)}async safeSharesQuery(){try{let e=await this.api.query.stableswap.pools.entries();return new Map(e.map(([{args:[t]},s])=>[t.toString(),s.unwrap()]))}catch{return new Map([])}}async safeBondsQuery(){try{let e=await this.api.query.bonds.bonds.entries();return new Map(e.map(([{args:[t]},s])=>[t.toString(),s.unwrap()]))}catch{return new Map([])}}async metadataQuery(){try{let e=await this.api.query.assetRegistry.assetMetadataMap.entries();return new Map(e.map(([{args:[t]},s])=>{let{decimals:r,symbol:i}=s.unwrap();return[t.toString(),{decimals:r.toNumber(),symbol:i.toHuman()}]}))}catch{return new Map([])}}async locationsQuery(){try{let e=await this.api.query.assetRegistry.assetLocations.entries();return new Map(e.map(([{args:[t]},s])=>[t.toString(),s.unwrap()]))}catch{return new Map([])}}getSystemTokenName(e){switch(e){case"HDX":return"Hydration";case"BSX":return"Basilisk";default:return e}}getToken(e,t,s,r){if(e==_){let p=this.api.consts.balances.existentialDeposit;return{id:_,name:this.getSystemTokenName(this.chainToken),symbol:this.chainToken,decimals:this.chainDecimals,icon:this.chainToken,type:"Token",isSufficient:!0,existentialDeposit:p.toString()}}let{name:i,assetType:o,isSufficient:a,existentialDeposit:n}=t,{symbol:l,decimals:c}=s.get(e)??{};return{id:e,name:i.toHuman(),symbol:l,decimals:c,icon:l,type:o.toHuman(),isSufficient:a?a.toHuman():!0,location:r?.toJSON(),existentialDeposit:n.toString()}}getBond(e,t,s,r){let[i,o]=r,{assetType:a,isSufficient:n,existentialDeposit:l}=t,{symbol:c,decimals:p}=this.getToken(i.toString(),t,s),d=o.toNumber(),g=new Intl.DateTimeFormat("en-GB"),b=[c,"Bond",g.format(d)].join(" ");return{id:e,name:b,symbol:c+"b",decimals:p,icon:c,type:a.toString(),isSufficient:n.toHuman(),existentialDeposit:l.toString(),underlyingAssetId:i.toString(),maturity:d}}getShares(e,t,s,r){let{assets:i}=r,{name:o,symbol:a,assetType:n,isSufficient:l,existentialDeposit:c}=t,d=i.map(f=>f.toString()).map(f=>{let{symbol:y}=this.getToken(f,t,s);return[f,y]}),g=Object.fromEntries(d),b=Object.values(g);return{id:e,name:b.join(", "),symbol:a?.isSome?a.toHuman():o.toHuman(),decimals:18,icon:b.join("/"),type:n.toString(),isSufficient:l.toHuman(),existentialDeposit:c.toString(),meta:g}}getExternal(e,t,s,r){let i=this.getToken(e,t,new Map,r),o=s?.find(a=>a.internalId===i.id);return o?{...i,decimals:o.decimals,name:o.name,symbol:o.symbol,icon:o.symbol,isWhiteListed:o.isWhiteListed}:i}normalizeMetadata(e,t){return t.size?t:new Map(e.map(([{args:[s]},r])=>{let{decimals:i,symbol:o}=r.unwrap();return[s.toString(),{decimals:Number(i.toString()),symbol:o.toHuman()}]}))}getSupportedAssets(e){return e.filter(([t,s])=>{if(s.isNone)return!1;let r=s.unwrap();return this.isSupportedAsset(r)})}async getOnChainAssets(e,t){let[s,r,i,o,a]=await Promise.all([this.api.query.assetRegistry.assets.entries(),this.locationsQuery(),this.safeSharesQuery(),this.safeBondsQuery(),this.metadataQuery()]),n=this.getSupportedAssets(s),l=this.normalizeMetadata(n,a),c=n.map(([{args:[p]},d])=>{let g=d.unwrap(),b=r.get(p.toString()),{assetType:f}=g;switch(f.toString()){case"Bond":let y=o.get(p.toString());return this.getBond(p.toString(),g,l,y);case"StableSwap":let S=i.get(p.toString());return this.getShares(p.toString(),g,l,S);case"External":return this.getExternal(p.toString(),g,t,b);default:return this.getToken(p.toString(),g,l,b)}});return e?c:c.filter(p=>this.isValidAsset(p))}isValidAsset(e){let t=Math.sign(e.decimals);return!!e.symbol&&(t===0||t===1)}isSupportedAsset(e){let t=e.assetType.toString();return this.SUPPORTED_TYPES.includes(t)}};var W=class extends q{constructor(e){super(e)}async getBalance(e,t){let s=await this.api.query.assetRegistry.assets(t),{assetType:r}=s.unwrap();return r.toString()==="Erc20"?this.getErc20Balance(e,t):t===_?this.getSystemBalance(e):this.getTokenBalance(e,t)}async getSystemBalance(e){let{data:t}=await this.api.query.system.account(e);return this.calculateFreeBalance(t)}async getTokenBalance(e,t){let{free:s,reserved:r,frozen:i}=await this.api.query.tokens.accounts(e,t);return this.calculateFreeBalance({free:s,feeFrozen:r,frozen:i})}async getErc20Balance(e,t){let{free:s,reserved:r,frozen:i}=await this.getTokenBalanceData(e,t);return this.calculateFreeBalance({free:s,feeFrozen:r,frozen:i})}async subscribeSystemBalance(e,t){return this.api.query.system.account(e,({data:s})=>t(_,this.calculateFreeBalance(s)))}async subscribeTokenBalance(e,t,s){let i=t.filter(o=>o.type!=="Erc20").filter(o=>o.id!==_).map(o=>[e,o.id]);return this.api.query.tokens.accounts.multi(i,o=>{let a=[];o.forEach((n,l)=>{let c=this.calculateFreeBalance(n),p=i[l][1];a.push([p,c])}),s(a)})}async subscribeErc20Balance(e,t,s){let r=t.filter(o=>o.type==="Erc20"),i=async()=>{let o=[];(await Promise.all(r.map(async n=>[n.id,await this.getErc20Balance(e,n.id)]))).forEach(([n,l])=>{o.push([n,l])}),s(o)};return await i(),this.api.rpc.chain.subscribeNewHeads(async()=>{i()})}async getTokenBalanceData(e,t){return this.api.call.currenciesApi.account(t,e)}calculateFreeBalance(e){let{free:t,miscFrozen:s,feeFrozen:r,frozen:i}=e,o=new O(t),a=new O(s||i),n=new O(r||0n),l=a.gt(n)?a:n;return o.minus(l)}};import{isAddress as Se}from"@polkadot/util-crypto";import{fixed_from_rational as Be}from"@galacticcouncil/math-liquidity-mining";var he=class extends q{constructor(e){super(e)}secondsInYear=new O(365.2425).times(24).times(60).times(60);async getOmnipoolFarms(e){let t=await this.api.query.omnipoolWarehouseLM.activeYieldFarm.entries(e);return await Promise.all(t.map(async([r,i])=>{let[,o]=r.args,a=i.unwrap().toString(),n=o.toString(),l=(await this.api.query.omnipoolWarehouseLM.globalFarm(n)).unwrap(),c=(await this.api.query.omnipoolWarehouseLM.yieldFarm(e,n,a)).unwrap(),p=await this.getOraclePrice(l)??l.priceAdjustment.toString();return{assetId:e,globalFarm:l,yieldFarm:c,priceAdjustment:p}}))}async getIsolatedPoolFarms(e){let t=await this.api.query.xykWarehouseLM.activeYieldFarm.entries(e);return await Promise.all(t.map(async([r,i])=>{let[,o]=r.args,a=i.unwrap().toString(),n=o.toString(),l=(await this.api.query.xykWarehouseLM.globalFarm(n)).unwrap(),c=(await this.api.query.xykWarehouseLM.yieldFarm(e,n,a)).unwrap(),p=await this.getOraclePrice(l)??l.priceAdjustment.toString();return{assetId:e,globalFarm:l,yieldFarm:c,priceAdjustment:p}}))}async getOraclePrice(e){let t=e.rewardCurrency.toString(),s=e.incentivizedAsset.toString(),r=[t,s].sort();if(t===s)return new O(1).shiftedBy(18).toString();let i=await this.api.query.emaOracle.oracles("omnipool",r,"TenMinutes");if(i.isNone)return;let[o]=i.unwrap(),a=o.price.n.toString(),n=o.price.d.toString(),l;return Number(t)<Number(s)?l=Be(a,n):l=Be(n,a),l}getGlobalRewardPerPeriod(e,t,s,r){let o=e.times(t).shiftedBy(-18).times(r).shiftedBy(-18);return o.gte(s)?s:o}getPoolYieldPerPeriod(e,t,s,r){return e.times(t).div(s.times(r).shiftedBy(-18))}async getFarmApr(e,t){if(t==="isolatedpool"&&!Se(e))throw new Error("You must pass an address of isolated pool as id");if(t==="omnipool"&&Se(e))throw new Error("You must pass an asset id of omnipool");let s=6,r=t==="omnipool"?await this.getOmnipoolFarms(e):await this.getIsolatedPoolFarms(e);return r.length?r.map(({yieldFarm:a,globalFarm:n,priceAdjustment:l})=>{let c=new O(n.totalSharesZ.toString()),p=n.plannedYieldingPeriods.toString(),d=new O(n.yieldPerPeriod.toString()),g=new O(n.maxRewardPerPeriod.toString()),b=n.blocksPerPeriod.toString(),f=new O(a.multiplier.toString()).shiftedBy(-18),y=this.secondsInYear.div(new O(s).times(b)),S;if(c.isZero())S=d.times(f).times(y);else{let C=this.getGlobalRewardPerPeriod(c,d,g,l);S=this.getPoolYieldPerPeriod(C,f,c,l).times(y)}let h=new O(n.pendingRewards.toString()).plus(n.accumulatedPaidRewards.toString()),I=g.times(p);return h.div(I).gte(.99)?P:S.times(100)}).reduce((a,n)=>a.plus(n),P).toString():void 0}};var M=class extends W{pools=[];subs=[];assets=new Map([]);mem=0;memPools=Ce(e=>(console.log(this.getPoolType(),"mem pools",e,"\u2705"),this.getPools()));constructor(e){super(e)}get augmentedPools(){return this.pools.filter(e=>this.isValidPool(e)).map(e=>this.withMetadata(e))}async withAssets(e){this.assets=new Map(e.map(t=>[t.id,t])),this.mem=this.mem+1}async getPoolsMem(){return this.memPools(this.mem)}async getPools(){this.unsubscribe(),this.pools=await this.loadPools(),this.subs=this.subscribe();let e=this.getPoolType();return console.log(e,`pools(${this.augmentedPools.length})`,"\u2705"),console.log(e,`subs(${this.subs.length})`,"\u2705"),this.augmentedPools}subscribe(){return this.augmentedPools.map(t=>{let s=[this.subscribeTokensPoolBalance(t)];try{let r=this.subscribePoolChange(t);s.push(r)}catch{}if(this.hasSystemAsset(t)){let r=this.subscribeSystemPoolBalance(t);s.push(r)}if(this.hasErc20Asset(t)){let r=this.subscribeErc20PoolBalance(t);s.push(r)}if(this.hasShareAsset(t)){let r=this.subscribeSharePoolBalance(t);s.push(r)}return this.subscribeLog(t),s}).flat()}hasSystemAsset(e){return e.tokens.some(t=>t.id==="0")}hasShareAsset(e){return e.type==="Stableswap"&&e.id}hasErc20Asset(e){return e.tokens.some(t=>t.type==="Erc20")}unsubscribe(){this.subs.forEach(e=>{e.then(t=>t())})}subscribeLog(e){let t=e.address.substring(0,10).concat("...");console.log(`${e.type} [${t}] balance subscribed`)}subscribeSystemPoolBalance(e){return this.subscribeSystemBalance(e.address,this.updateBalanceCallback(e))}subscribeTokensPoolBalance(e){let t=(s,r)=>s.id!==r;return this.subscribeTokenBalance(e.address,e.tokens,this.updateBalancesCallback(e,t))}subscribeErc20PoolBalance(e){return this.subscribeErc20Balance(e.address,e.tokens,this.updateBalancesCallback(e,()=>!0))}subscribeSharePoolBalance(e){let t=this.assets.get(e.id);return this.subscribeTokenBalance(oe,[t],this.updateBalancesCallback(e,()=>!0))}isValidPool(e){return e.type==="Xyk"?e.tokens.every(t=>this.assets.get(t.id)):!0}withMetadata(e){return e.tokens=e.tokens.map(t=>{let s=this.assets.get(t.id);return{...t,...s}}),e}updateBalancesCallback(e,t){return function(s){s.forEach(([r,i])=>{let o=e.tokens.findIndex(a=>a.id==r);o>=0&&t(e,r)&&(e.tokens[o].balance=i.toString())})}}updateBalanceCallback(e){return function(t,s){let r=e.tokens.findIndex(i=>i.id==t);r>=0&&(e.tokens[r].balance=s.toString())}}};var ne=class extends M{MAX_FINAL_WEIGHT=x(u(100),6);poolsData=new Map([]);isSupported(){return this.api.query.lbp!==void 0}async loadPools(){let[e,t]=await Promise.all([this.api.query.lbp.poolData.entries(),this.api.query.parachainSystem.validationData()]),{relayParentNumber:s}=t.unwrap(),r=e.filter(([i,o])=>this.isActivePool(o.unwrap(),s)).map(async([{args:[i]},o])=>{let a=o.unwrap(),n=i.toString(),l=await this.getPoolDelta(n,a,s.toString());return this.poolsData.set(i.toString(),a),{address:n,type:"Lbp",fee:a.fee.toJSON(),...l,...this.getPoolLimits()}});return Promise.all(r)}async getPoolFees(e,t){let s=this.pools.find(r=>r.address===t);return{repayFee:this.getRepayFee(),exchangeFee:s.fee}}getPoolType(){return"Lbp"}async subscribePoolChange(e){return this.api.query.parachainSystem.validationData(async t=>{let{relayParentNumber:s}=t.unwrap(),r=this.poolsData.get(e.address);if(this.isActivePool(r,s)){let o=await this.getPoolDelta(e.address,r,s.toString());Object.assign(e,o)}else{let o=this.pools.findIndex(a=>a.address==e.address);this.pools.splice(o,1)}})}async getPoolDelta(e,t,s){let{start:r,end:i,assets:o,initialWeight:a,finalWeight:n,repayTarget:l,feeCollector:c}=t,p=D.calculateLinearWeights(r.toString(),i.toString(),a.toString(),n.toString(),s),[d,g]=o,b=d.toString(),f=u(p),y=g.toString(),S=this.MAX_FINAL_WEIGHT.minus(u(f)),[h,I,F]=await Promise.all([this.isRepayFeeApplied(b,l.toString(),c.toString()),this.getBalance(e,b),this.getBalance(e,y)]);return{repayFeeApply:h,tokens:[{id:b,weight:f,balance:I.toString()},{id:y,weight:S,balance:F.toString()}]}}isActivePool(e,t){if(e.start.isEmpty||e.end.isEmpty)return!1;let s=e.start.unwrap().toNumber(),r=e.end.unwrap().toNumber();return t.toNumber()>=s&&t.toNumber()<r}async isRepayFeeApplied(e,t,s){let r=u(t);if(r.isZero())return!1;try{return(await this.getBalance(e,s)).isLessThan(r)}catch{return!0}}getRepayFee(){return this.api.consts.lbp.repayFee.toJSON()}getPoolLimits(){let e=this.api.consts.lbp.maxInRatio.toJSON(),t=this.api.consts.lbp.maxOutRatio.toJSON(),s=this.api.consts.lbp.minTradingLimit.toJSON();return{maxInRatio:e,maxOutRatio:t,minTradingLimit:s}}};import{encodeAddress as rt}from"@polkadot/util-crypto";import{stringToU8a as it}from"@polkadot/util";function N(m,e){return m.shiftedBy(-1*e).toString()}function A(m){return m[0]/m[1]*100}function R(m){return m[0]/m[1]}function k(m){return[m/be,be]}import{calculate_in_given_out as Ge,calculate_lrna_in_given_out as qe,calculate_out_given_in as He,calculate_out_given_lrna_in as We,calculate_pool_trade_fee as Xe,calculate_spot_price as Ue,calculate_lrna_spot_price as Ye,calculate_shares as ze,calculate_liquidity_out as Je,calculate_liquidity_lrna_out as je,calculate_liquidity_hub_in as $e,is_sell_allowed as Ze,is_buy_allowed as Ke,is_add_liquidity_allowed as Qe,is_remove_liquidity_allowed as Ve,recalculate_asset_fee as et,recalculate_protocol_fee as tt,verify_asset_cap as st}from"@galacticcouncil/math-omnipool";var B=class{static calculateSpotPrice(e,t,s,r){return Ue(e,t,s,r)}static calculateLrnaSpotPrice(e,t){return Ye(e,t)}static calculateInGivenOut(e,t,s,r,i,o,a,n,l){return Ge(e,t,s,r,i,o,a,n,l)}static calculateLrnaInGivenOut(e,t,s,r,i){return qe(e,t,s,r,i)}static calculateOutGivenIn(e,t,s,r,i,o,a,n,l){return He(e,t,s,r,i,o,a,n,l)}static calculateOutGivenLrnaIn(e,t,s,r,i){return We(e,t,s,r,i)}static calculatePoolTradeFee(e,t,s){return Xe(e,t,s)}static calculateShares(e,t,s,r){return ze(e,t,s,r)}static calculateLiquidityOut(e,t,s,r,i,o,a,n){return Je(e,t,s,r,i,o,a,n)}static calculateLiquidityLRNAOut(e,t,s,r,i,o,a,n){return je(e,t,s,r,i,o,a,n)}static calculateCapDifference(e,t,s,r){let i=O(t),o=O(e),a=O(r),l=O(s).shiftedBy(-18);if(i.div(a).lt(l)){let p=l.times(a).minus(i).times(o),d=i.times(O(1).minus(l));return p.div(d).toFixed(0)}else return"0"}static calculateLimitHubIn(e,t,s,r){return $e(e,t,s,r)}static isSellAllowed(e){return Ze(e)}static isBuyAllowed(e){return Ke(e)}static isAddLiquidityAllowed(e){return Qe(e)}static isRemoveLiquidityAllowed(e){return Ve(e)}static recalculateAssetFee(e,t,s,r,i,o,a,n,l,c,p){return et(e,t,s,r,i,o,a,n,l,c,p)}static recalculateProtocolFee(e,t,s,r,i,o,a,n,l,c,p){return tt(e,t,s,r,i,o,a,n,l,c,p)}static verifyAssetCap(e,t,s,r){return st(e,t,s,r)}};var ae=class extends M{isSupported(){return this.api.query.omnipool!==void 0}async loadPools(){let e=this.api.consts.omnipool.hubAssetId.toString(),t=this.getPoolId(),[s,r,i]=await Promise.all([this.api.query.omnipool.assets.entries(),this.api.query.omnipool.hubAssetTradability(),this.getBalance(t,e)]),o=s.map(async([{args:[n]},l])=>{let{hubReserve:c,shares:p,tradable:d,cap:g,protocolShares:b}=l.unwrap(),f=await this.getBalance(t,n.toString());return{id:n.toString(),hubReserves:u(c.toString()),shares:u(p.toString()),tradeable:d.bits.toNumber(),balance:f.toString(),cap:u(g.toString()),protocolShares:u(b.toString())}}),a=await Promise.all(o);return a.push({id:e,tradeable:r.bits.toNumber(),balance:i.toString()}),[{address:t,type:"Omnipool",hubAssetId:e,tokens:a,...this.getPoolLimits()}]}async getPoolFees(e,t){let s=e.assetOut,r=e.assetIn,i="omnipool",o="Short",a=F=>F===_?[_,ie]:[ie,F],[n,l,c,p]=await Promise.all([this.api.query.system.number(),this.api.query.dynamicFees.assetFee(s),this.api.query.emaOracle.oracles(i,a(s),o),this.api.query.emaOracle.oracles(i,a(r),o)]),[d,g,b]=this.getAssetFee(e,n.toNumber(),l,c),[f,y,S]=r===ie?[0,0,0]:this.getProtocolFee(e,n.toNumber(),l,p),h=d+f,I=b+S;return{assetFee:k(g),protocolFee:k(y),min:k(h),max:k(I)}}getPoolType(){return"Omnipool"}async subscribePoolChange(e){let t=e.tokens.map(s=>s.id);return this.api.query.omnipool.assets.multi(t,s=>{e.tokens=s.map((r,i)=>{let o=e.tokens[i];if(r.isNone)return o;let a=r.unwrap();return this.updateTokenState(o,a)})})}updateTokenState(e,t){let{hubReserve:s,shares:r,tradable:i,cap:o,protocolShares:a}=t;return{...e,hubReserves:u(s.toString()),shares:u(r.toString()),cap:u(o.toString()),protocolShares:u(a.toString()),tradeable:i.bits.toNumber()}}getAssetFee(e,t,s,r){let{assetOut:i,balanceOut:o}=e,{minFee:a,maxFee:n,decay:l,amplification:c}=this.api.consts.dynamicFees.assetFeeParameters,p=k(a.toNumber()),d=k(n.toNumber());if(s.isNone||r.isNone)return[a.toNumber(),a.toNumber(),n.toNumber()];let[g]=r.unwrap(),{assetFee:b,timestamp:f}=s.unwrap(),y=t-f.toNumber(),S=g.volume.bIn.toString(),h=g.volume.bOut.toString(),I=g.liquidity.b.toString();i===_&&(S=g.volume.aIn.toString(),h=g.volume.aOut.toString(),I=g.liquidity.a.toString());let F=k(b.toNumber()),C=B.recalculateAssetFee(S,h,I,"9",o.toString(),A(F).toString(),y.toString(),A(p).toString(),A(d).toString(),l.toString(),c.toString());return[a.toNumber(),Number(C)*1e4,n.toNumber()]}getProtocolFee(e,t,s,r){let{assetIn:i,balanceIn:o}=e,{minFee:a,maxFee:n,decay:l,amplification:c}=this.api.consts.dynamicFees.protocolFeeParameters,p=k(a.toNumber()),d=k(n.toNumber());if(s.isNone||r.isNone)return[a.toNumber(),a.toNumber(),n.toNumber()];let[g]=r.unwrap(),{protocolFee:b,timestamp:f}=s.unwrap(),y=t-f.toNumber(),S=g.volume.bIn.toString(),h=g.volume.bOut.toString(),I=g.liquidity.b.toString();i===_&&(S=g.volume.aIn.toString(),h=g.volume.aOut.toString(),I=g.liquidity.a.toString());let F=k(b.toNumber()),C=B.recalculateProtocolFee(S,h,I,"9",o.toString(),A(F).toString(),y.toString(),A(p).toString(),A(d).toString(),l.toString(),c.toString());return[a.toNumber(),Number(C)*1e4,n.toNumber()]}getPoolId(){return rt(it("modlomnipool".padEnd(32,"\0")),j)}getPoolLimits(){let e=this.api.consts.omnipool.maxInRatio.toJSON(),t=this.api.consts.omnipool.maxOutRatio.toJSON(),s=this.api.consts.omnipool.minimumTradingLimit.toJSON();return{maxInRatio:e,maxOutRatio:t,minTradingLimit:s}}};var le=class extends M{isSupported(){return this.api.query.xyk!==void 0}async loadPools(){let t=(await this.api.query.xyk.poolAssets.entries()).map(async([{args:[s]},r])=>{let i=s.toString(),[o,a]=r.unwrap(),[n,l]=await Promise.all([this.getBalance(i,o.toString()),this.getBalance(i,a.toString())]);return{address:i,type:"Xyk",tokens:[{id:o.toString(),balance:n.toString()},{id:a.toString(),balance:l.toString()}],...this.getPoolLimits()}});return Promise.all(t)}async getPoolFees(e,t){return{exchangeFee:this.getExchangeFee()}}getPoolType(){return"Xyk"}subscribePoolChange(e){throw new Error("Pool change subscription not supported!")}getExchangeFee(){return this.api.consts.xyk.getExchangeFee.toJSON()}getPoolLimits(){let e=this.api.consts.xyk.maxInRatio.toJSON(),t=this.api.consts.xyk.maxOutRatio.toJSON(),s=this.api.consts.xyk.minTradingLimit.toJSON();return{maxInRatio:e,maxOutRatio:t,minTradingLimit:s}}};import{blake2AsHex as bt,encodeAddress as ht}from"@polkadot/util-crypto";import{calculate_in_given_out as ot,calculate_out_given_in as nt,calculate_amplification as at,calculate_add_one_asset as lt,calculate_liquidity_out_one_asset as ct,calculate_pool_trade_fee as ut,calculate_shares as mt,calculate_shares_for_amount as pt,calculate_spot_price_with_fee as gt,pool_account_name as dt}from"@galacticcouncil/math-stableswap";var T=class{static getPoolAddress(e){return dt(e)}static calculateAmplification(e,t,s,r,i){return at(e,t,s,r,i)}static calculateInGivenOut(e,t,s,r,i,o){return ot(e,t,s,r,i,o)}static calculateAddOneAsset(e,t,s,r,i,o){return lt(e,t,s,r,i,o)}static calculateSharesForAmount(e,t,s,r,i,o){return pt(e,t,s,r,i,o)}static calculateOutGivenIn(e,t,s,r,i,o){return nt(e,t,s,r,i,o)}static calculateLiquidityOutOneAsset(e,t,s,r,i,o){return ct(e,t,s,r,i,o)}static calculateShares(e,t,s,r,i){return mt(e,t,s,r,i)}static calculateSpotPriceWithFee(e,t,s,r,i,o,a){return gt(e,t,s,r,i,o,a)}static calculatePoolTradeFee(e,t,s){return ut(e,t,s)}};var ce=class extends M{stablePools=new Map([]);isSupported(){return this.api.query.stableswap!==void 0}async loadPools(){let[e,t]=await Promise.all([this.api.query.stableswap.pools.entries(),this.api.query.system.number()]),s=t.toNumber(),r=e.map(async([{args:[i]},o])=>{let a=o.unwrap(),n=i.toString(),l=this.getPoolAddress(n),[c,p]=await Promise.all([this.getPoolDelta(n,a,s.toString()),this.getPoolTokens(l,n,a)]);return this.stablePools.set(l,a),{address:l,id:n,type:"Stableswap",fee:k(a.fee.toNumber()),tokens:p,...c,...this.getPoolLimits()}});return Promise.all(r)}async getPoolFees(e,t){return{fee:this.pools.find(r=>r.address===t).fee}}getPoolType(){return"Stableswap"}async subscribePoolChange(e){return this.api.query.system.number(async t=>{let s=t.toNumber(),r=this.stablePools.get(e.address),i=await this.getPoolDelta(e.id,r,s.toString());Object.assign(e,i)})}async getPoolDelta(e,t,s){let{initialAmplification:r,finalAmplification:i,initialBlock:o,finalBlock:a}=t,n=T.calculateAmplification(r.toString(),i.toString(),o.toString(),a.toString(),s),l=await this.api.query.tokens.totalIssuance(e);return{amplification:n,totalIssuance:l.toString()}}async getPoolTokens(e,t,s){let{assets:r}=s,i=r.map(async n=>{let[l,c]=await Promise.all([this.api.query.stableswap.assetTradability(t,n.toString()),this.getBalance(e,n.toString())]);return{id:n.toString(),tradeable:l.bits.toNumber(),balance:c.toString()}}),o=await Promise.all(i),a=await this.api.query.omnipool.assets(t);if(a.isSome){let{tradable:n}=a.unwrap(),l=await this.getBalance(oe,t);o.push({id:t,tradeable:n.bits.toNumber(),balance:l.toString()})}return o}getPoolAddress(e){let t=Number(e),s=T.getPoolAddress(t);return ht(bt(s),j)}getPoolLimits(){return{maxInRatio:0,maxOutRatio:0,minTradingLimit:this.api.consts.stableswap.minTradingLimit.toJSON()}}};function Pe(m){return m.map(({assetIn:e,assetOut:t,pool:s,poolId:r})=>s==="Stableswap"?{pool:{Stableswap:r},assetIn:e,assetOut:t}:{pool:s,assetIn:e,assetOut:t})}var ue=class extends Error{constructor(e){super(),this.message=`${e} pool invalid`,this.name="PoolNotFound"}},Oe=class extends Error{constructor(e,t){super(),this.message=`${e} pool missing ${t}`,this.name="PoolConfigNotFound"}},$=class extends Error{constructor(e,t){super(),this.message=`Route from ${e} to ${t} not found in pool configuration`,this.name="RouteNotFound"}},we=class extends Error{constructor(e){super(),this.message=`Asset ${e} not available in current network`,this.name="AssetNotFound"}},Ie=class extends Error{constructor(e){super(),this.message=`Storage missing ${e}`,this.name="StorageConfigNotFound"}},xe=class extends Error{constructor(e){super(),this.message=`Subscription type "${e}" not supported`,this.name="SubscriptionNotSupported"}},Ae=class extends Error{constructor(e){super(),this.message=`${e}`,this.name="ProviderConfigNotFound"}};var Z=class{api;assetClient;xykClient;omniClient;lbpClient;stableClient;clients=[];onChainAssets=[];memRegistry=Pt(e=>(console.log("Registry mem sync",e,"\u2705"),this.syncRegistry()));constructor(e){this.api=e,this.assetClient=new H(this.api),this.xykClient=new le(this.api),this.omniClient=new ae(this.api),this.lbpClient=new ne(this.api),this.stableClient=new ce(this.api),this.clients=[this.xykClient,this.omniClient,this.lbpClient,this.stableClient]}get assets(){return this.onChainAssets}get isRegistrySynced(){return this.onChainAssets.length>0}async syncRegistry(e){let t=await this.assetClient.getOnChainAssets(!1,e);this.clients.forEach(s=>s.withAssets(t)),this.onChainAssets=t}async getPools(e){return this.isRegistrySynced||await this.memRegistry(1),e.length==0?(await Promise.all(this.clients.filter(r=>r.isSupported()).map(r=>r.getPoolsMem()))).flat():(await Promise.all(this.clients.filter(s=>e.some(r=>r===s.getPoolType())).map(s=>s.getPoolsMem()))).flat()}unsubscribe(){this.xykClient.unsubscribe(),this.omniClient.unsubscribe(),this.lbpClient.unsubscribe(),this.stableClient.unsubscribe()}async getPoolFees(e,t){switch(t.type){case"Xyk":return this.xykClient.getPoolFees(e,t.address);case"Omnipool":return this.omniClient.getPoolFees(e,t.address);case"Lbp":return this.lbpClient.getPoolFees(e,t.address);case"Stableswap":return this.stableClient.getPoolFees(e,t.address);default:throw new ue(t.type)}}isDirectOmnipoolTrade(e){return e.length==1&&e[0].pool=="Omnipool"}buildBuyTx(e,t,s,r,i){let o;this.isDirectOmnipoolTrade(i)?o=this.api.tx.omnipool.buy(t,e,s.toFixed(),r.toFixed()):o=this.api.tx.router.buy(e,t,s.toFixed(),r.toFixed(),Pe(i));let a=()=>o;return{hex:o.toHex(),name:"RouterBuy",get:a}}buildSellTx(e,t,s,r,i){let o;this.isDirectOmnipoolTrade(i)?o=this.api.tx.omnipool.sell(e,t,s.toFixed(),r.toFixed()):o=this.api.tx.router.sell(e,t,s.toFixed(),r.toFixed(),Pe(i));let a=()=>o;return{hex:o.toHex(),name:"RouterSell",get:a}}};import{LRUCache as ft}from"@thi.ng/cache";var fe=class extends Z{feeCache;disconnectSubscribeNewHeads=null;constructor(e){super(e),this.feeCache=new ft(null),this.api.rpc.chain.subscribeNewHeads(async t=>{this.feeCache.release()}).then(t=>{this.disconnectSubscribeNewHeads=t})}async getPoolFees(e,t){let s=[t.address,e.assetIn,e.assetOut].join("-");if(this.feeCache.has(s))return this.feeCache.get(s);{let i=await super.getPoolFees(e,t);return this.feeCache.set(s,i),i}}async destroy(){console.log(`Destroying pool cache!
2
- Items: [${this.feeCache.length}]`),this.feeCache.release(),this.disconnectSubscribeNewHeads?.()}};var K=class m{type;address;tokens;maxInRatio;maxOutRatio;minTradingLimit;fee;repayFeeApply;static fromPool(e){return new m(e.address,e.tokens,e.maxInRatio,e.maxOutRatio,e.minTradingLimit,e.fee,e.repayFeeApply)}constructor(e,t,s,r,i,o,a){this.type="Lbp",this.address=e,this.tokens=t,this.maxInRatio=s,this.maxOutRatio=r,this.minTradingLimit=i,this.fee=o,this.repayFeeApply=a}validatePair(e,t){return!0}parsePair(e,t){let s=new Map(this.tokens.map(n=>[n.id,n])),r=s.get(e),i=s.get(t);if(r==null)throw new Error("Pool does not contain tokenIn");if(i==null)throw new Error("Pool does not contain tokenOut");let o=u(r.balance),a=u(i.balance);return{assetIn:e,assetOut:t,balanceIn:o,balanceOut:a,decimalsIn:r.decimals,decimalsOut:i.decimals,weightIn:r.weight,weightOut:i.weight}}validateAndBuy(e,t,s){let r=this.tokens[0].id,i=[];t.isLessThan(this.minTradingLimit)&&i.push("InsufficientTradingAmount");let o=e.balanceOut.div(this.maxOutRatio);if(t.isGreaterThan(o)&&i.push("MaxOutRatioExceeded"),r===e.assetOut){let a=this.calculateTradeFee(t,s),n=A(this.repayFeeApply?s.repayFee:s.exchangeFee),l=t.plus(a),c=this.calculateInGivenOut(e,l),p=e.balanceIn.div(this.maxInRatio);return c.isGreaterThan(p)&&i.push("MaxInRatioExceeded"),{amountIn:c,calculatedIn:c,amountOut:t,feePct:n,errors:i}}else{let a=this.calculateInGivenOut(e,t),n=e.balanceIn.div(this.maxInRatio);return a.isGreaterThan(n)&&i.push("MaxInRatioExceeded"),{amountIn:a,calculatedIn:a,amountOut:t,feePct:0,errors:i}}}validateAndSell(e,t,s){let r=this.tokens[0].id,i=[];t.isLessThan(this.minTradingLimit)&&i.push("InsufficientTradingAmount");let o=e.balanceIn.div(this.maxInRatio);if(t.isGreaterThan(o)&&i.push("MaxInRatioExceeded"),r===e.assetIn){let a=this.calculateOutGivenIn(e,t),n=e.balanceOut.div(this.maxOutRatio);return a.isGreaterThan(n)&&i.push("MaxOutRatioExceeded"),{amountIn:t,calculatedOut:a,amountOut:a,feePct:0,errors:i}}else{let a=this.calculateOutGivenIn(e,t),n=this.calculateTradeFee(a,s),l=A(this.repayFeeApply?s.repayFee:s.exchangeFee),c=a.minus(n),p=e.balanceOut.div(this.maxOutRatio);return c.isGreaterThan(p)&&i.push("MaxOutRatioExceeded"),{amountIn:t,calculatedOut:a,amountOut:c,feePct:l,errors:i}}}calculateInGivenOut(e,t){let s=D.calculateInGivenOut(e.balanceIn.toString(),e.balanceOut.toString(),e.weightIn.toString(),e.weightOut.toString(),t.toFixed(0)),r=u(s);return r.isNegative()?P:r}calculateOutGivenIn(e,t){let s=D.calculateOutGivenIn(e.balanceIn.toString(),e.balanceOut.toString(),e.weightIn.toString(),e.weightOut.toString(),t.toFixed(0)),r=u(s);return r.isNegative()?P:r}spotPriceInGivenOut(e){let t=D.getSpotPrice(e.balanceOut.toString(),e.balanceIn.toString(),e.weightOut.toString(),e.weightIn.toString(),x(v,e.decimalsOut).toString());return u(t)}spotPriceOutGivenIn(e){let t=D.getSpotPrice(e.balanceIn.toString(),e.balanceOut.toString(),e.weightIn.toString(),e.weightOut.toString(),x(v,e.decimalsIn).toString());return u(t)}calculateTradeFee(e,t){let s=D.calculatePoolTradeFee(e.toString(),this.repayFeeApply?t.repayFee[0]:t.exchangeFee[0],this.repayFeeApply?t.repayFee[1]:t.exchangeFee[1]);return u(s)}};var Q=class m{type;address;tokens;maxInRatio;maxOutRatio;minTradingLimit;hubAssetId;static fromPool(e){return new m(e.address,e.tokens,e.maxInRatio,e.maxOutRatio,e.minTradingLimit,e.hubAssetId)}constructor(e,t,s,r,i,o){this.type="Omnipool",this.address=e,this.tokens=t,this.maxInRatio=s,this.maxOutRatio=r,this.minTradingLimit=i,this.hubAssetId=o}validatePair(e,t){return this.hubAssetId!=t}parsePair(e,t){let s=new Map(this.tokens.map(c=>[c.id,c])),r=s.get(e),i=s.get(t);if(r==null)throw new Error("Pool does not contain tokenIn");if(i==null)throw new Error("Pool does not contain tokenOut");let o=u(r.balance),a=u(i.balance),n=u(r.existentialDeposit),l=u(i.existentialDeposit);return{assetIn:e,assetOut:t,hubReservesIn:r.hubReserves,hubReservesOut:i.hubReserves,sharesIn:r.shares,sharesOut:i.shares,decimalsIn:r.decimals,decimalsOut:i.decimals,balanceIn:o,balanceOut:a,tradeableIn:r.tradeable,tradeableOut:i.tradeable,assetInED:n,assetOutED:l}}validateAndBuy(e,t,s){let r=this.calculateInGivenOut(e,t),i=this.calculateInGivenOut(e,t,s),o=i.minus(r),a=r===P?P:o.div(r).multipliedBy(100).decimalPlaces(2),n=[],l=B.isSellAllowed(e.tradeableIn),c=B.isBuyAllowed(e.tradeableOut);(!l||!c)&&n.push("TradeNotAllowed"),(t.isLessThan(this.minTradingLimit)||r.isLessThan(e.assetInED))&&n.push("InsufficientTradingAmount");let p=e.balanceOut.div(this.maxOutRatio);t.isGreaterThan(p)&&n.push("MaxOutRatioExceeded");let d=e.balanceIn.div(this.maxInRatio);return i.isGreaterThan(d)&&n.push("MaxInRatioExceeded"),{amountIn:i,calculatedIn:r,amountOut:t,feePct:a.toNumber(),errors:n}}validateAndSell(e,t,s){let r=this.calculateOutGivenIn(e,t),i=this.calculateOutGivenIn(e,t,s),a=r.minus(i).div(r).multipliedBy(100).decimalPlaces(2),n=[],l=B.isSellAllowed(e.tradeableIn),c=B.isBuyAllowed(e.tradeableOut);(!l||!c)&&n.push("TradeNotAllowed"),(t.isLessThan(this.minTradingLimit)||r.isLessThan(e.assetOutED))&&n.push("InsufficientTradingAmount");let p=e.balanceIn.div(this.maxInRatio);t.isGreaterThan(p)&&n.push("MaxInRatioExceeded");let d=e.balanceOut.div(this.maxOutRatio);return i.isGreaterThan(d)&&n.push("MaxOutRatioExceeded"),{amountIn:t,calculatedOut:r,amountOut:i,feePct:a.toNumber(),errors:n}}calculateInGivenOut(e,t,s){if(e.assetIn==this.hubAssetId)return this.calculateLrnaInGivenOut(e,t,s);let r=B.calculateInGivenOut(e.balanceIn.toString(),e.hubReservesIn.toString(),e.sharesIn.toString(),e.balanceOut.toString(),e.hubReservesOut.toString(),e.sharesOut.toString(),t.toFixed(0),s?R(s.assetFee).toString():P.toString(),s?R(s.protocolFee).toString():P.toString()),i=u(r);return i.isNegative()?P:i}calculateLrnaInGivenOut(e,t,s){let r=B.calculateLrnaInGivenOut(e.balanceOut.toString(),e.hubReservesOut.toString(),e.sharesOut.toString(),t.toFixed(0),s?R(s.assetFee).toString():P.toString()),i=u(r);return i.isNegative()?P:i}calculateOutGivenIn(e,t,s){if(e.assetIn==this.hubAssetId)return this.calculateOutGivenLrnaIn(e,t,s);let r=B.calculateOutGivenIn(e.balanceIn.toString(),e.hubReservesIn.toString(),e.sharesIn.toString(),e.balanceOut.toString(),e.hubReservesOut.toString(),e.sharesOut.toString(),t.toFixed(0),s?R(s.assetFee).toString():P.toString(),s?R(s.protocolFee).toString():P.toString()),i=u(r);return i.isNegative()?P:i}calculateOutGivenLrnaIn(e,t,s){let r=B.calculateOutGivenLrnaIn(e.balanceOut.toString(),e.hubReservesOut.toString(),e.sharesOut.toString(),t.toFixed(0),s?R(s.assetFee).toString():P.toString()),i=u(r);return i.isNegative()?P:i}spotPriceInGivenOut(e){if(e.assetIn==this.hubAssetId)return this.spotPriceLrnaInGivenOut(e);let t=B.calculateSpotPrice(e.balanceOut.toString(),e.hubReservesOut.toString(),e.balanceIn.toString(),e.hubReservesIn.toString());return u(t).shiftedBy(-1*(J-e.decimalsOut)).decimalPlaces(0,1)}spotPriceLrnaInGivenOut(e){let t=B.calculateLrnaSpotPrice(e.hubReservesOut.toString(),e.balanceOut.toString());return u(t).shiftedBy(-1*(J-e.decimalsOut)).decimalPlaces(0,1)}spotPriceOutGivenIn(e){if(e.assetIn==this.hubAssetId)return this.spotPriceOutGivenLrnaIn(e);let t=B.calculateSpotPrice(e.balanceIn.toString(),e.hubReservesIn.toString(),e.balanceOut.toString(),e.hubReservesOut.toString());return u(t).shiftedBy(-1*(J-e.decimalsIn)).decimalPlaces(0,1)}spotPriceOutGivenLrnaIn(e){let t=B.calculateLrnaSpotPrice(e.balanceOut.toString(),e.hubReservesOut.toString());return u(t).shiftedBy(-1*(J-e.decimalsIn)).decimalPlaces(0,1)}};var V=class m{type;address;tokens;maxInRatio;maxOutRatio;minTradingLimit;amplification;id;fee;totalIssuance;static fromPool(e){return new m(e.address,e.tokens,e.maxInRatio,e.maxOutRatio,e.minTradingLimit,e.amplification,e.id,e.fee,e.totalIssuance)}constructor(e,t,s,r,i,o,a,n,l){this.type="Stableswap",this.address=e,this.tokens=t,this.maxInRatio=s,this.maxOutRatio=r,this.minTradingLimit=i,this.amplification=o,this.id=a,this.fee=n,this.totalIssuance=l}validatePair(e,t){return!0}parsePair(e,t){let s=new Map(this.tokens.map(c=>[c.id,c])),r=s.get(e),i=s.get(t);if(r==null)throw new Error("Pool does not contain tokenIn");if(i==null)throw new Error("Pool does not contain tokenOut");let o=u(r.balance),a=u(i.balance),n=u(r.existentialDeposit),l=u(i.existentialDeposit);return{assetIn:e,assetOut:t,balanceIn:o,balanceOut:a,decimalsIn:r.decimals,decimalsOut:i.decimals,tradeableIn:this.id===e?de:r.tradeable,tradeableOut:this.id===t?de:i.tradeable,assetInED:n,assetOutED:l}}validateAndBuy(e,t,s){let r=this.calculateInGivenOut(e,t),i=this.calculateInGivenOut(e,t,s),o=A(s.fee),a=[],n=B.isSellAllowed(e.tradeableIn),l=B.isBuyAllowed(e.tradeableOut);return(!n||!l)&&a.push("TradeNotAllowed"),(t.isLessThan(this.minTradingLimit)||r.isLessThan(e.assetInED))&&a.push("InsufficientTradingAmount"),{amountIn:i,calculatedIn:r,amountOut:t,feePct:o,errors:a}}validateAndSell(e,t,s){let r=this.calculateOutGivenIn(e,t),i=this.calculateOutGivenIn(e,t,s),o=A(s.fee),a=[],n=B.isSellAllowed(e.tradeableIn),l=B.isBuyAllowed(e.tradeableOut);return(!n||!l)&&a.push("TradeNotAllowed"),(t.isLessThan(this.minTradingLimit)||r.isLessThan(e.assetOutED))&&a.push("InsufficientTradingAmount"),{amountIn:t,calculatedOut:r,amountOut:i,feePct:o,errors:a}}calculateIn(e,t,s){let r=T.calculateInGivenOut(this.getReserves(),Number(e.assetIn),Number(e.assetOut),t.toFixed(0),this.amplification,s?R(s.fee).toString():P.toString()),i=u(r);return i.isNegative()?P:i}calculateAddOneAsset(e,t,s){let r=T.calculateAddOneAsset(this.getReserves(),t.toFixed(0),Number(e.assetIn),this.amplification,this.totalIssuance,s?R(s.fee).toString():P.toString()),i=u(r);return i.isNegative()?P:i}calculateSharesForAmount(e,t,s){let r=T.calculateSharesForAmount(this.getReserves(),Number(e.assetOut),t.toFixed(0),this.amplification,this.totalIssuance,s?R(s.fee).toString():P.toString()),i=u(r);return i.isNegative()?P:i}calculateInGivenOut(e,t,s){return e.assetOut==this.id?this.calculateAddOneAsset(e,t,s):e.assetIn==this.id?this.calculateSharesForAmount(e,t,s):this.calculateIn(e,t,s)}spotPriceInGivenOut(e){let t=T.calculateSpotPriceWithFee(this.id,this.getReserves(),this.amplification,e.assetOut,e.assetIn,this.totalIssuance,"0");if(e.assetOut==this.id)return u(t);if(e.assetIn==this.id){let r=x(v,e.decimalsIn-e.decimalsOut);return u(t).div(r)}let s=x(v,18-e.decimalsIn);return u(t).div(s)}calculateOut(e,t,s){let r=T.calculateOutGivenIn(this.getReserves(),Number(e.assetIn),Number(e.assetOut),t.toFixed(0),this.amplification,s?R(s.fee).toString():P.toString()),i=u(r);return i.isNegative()?P:i}calculateWithdrawOneAsset(e,t,s){let r=T.calculateLiquidityOutOneAsset(this.getReserves(),t.toFixed(0),Number(e.assetOut),this.amplification,this.totalIssuance,s?R(s.fee).toString():P.toString()),i=u(r);return i.isNegative()?P:i}calculateShares(e,t,s){let r=T.calculateShares(this.getReserves(),this.getAssets(e.assetIn,t),this.amplification,this.totalIssuance,s?R(s.fee).toString():P.toString()),i=u(r);return i.isNegative()?P:i}calculateOutGivenIn(e,t,s){return e.assetIn==this.id?this.calculateWithdrawOneAsset(e,t,s):e.assetOut==this.id?this.calculateShares(e,t,s):this.calculateOut(e,t,s)}spotPriceOutGivenIn(e){let t=T.calculateSpotPriceWithFee(this.id,this.getReserves(),this.amplification,e.assetIn,e.assetOut,this.totalIssuance,"0");if(e.assetIn==this.id)return u(t);if(e.assetOut==this.id){let r=x(v,e.decimalsOut-e.decimalsIn);return u(t).div(r)}let s=x(v,18-e.decimalsOut);return u(t).div(s)}calculateTradeFee(e,t){let s=T.calculatePoolTradeFee(e.toString(),t.fee[0],t.fee[1]);return u(s)}getReserves(){let e=this.tokens.filter(t=>t.id!=this.id).map(({id:t,balance:s,decimals:r})=>({asset_id:Number(t),amount:s,decimals:r}));return JSON.stringify(e)}getAssets(e,t){let s={asset_id:Number(e),amount:t.toFixed(0)};return JSON.stringify([s])}};import{calculate_in_given_out as yt,calculate_out_given_in as St,calculate_pool_trade_fee as Bt,get_spot_price as Ot,calculate_liquidity_in as wt,calculate_shares as It,calculate_spot_price as xt,calculate_spot_price_with_fee as At,calculate_liquidity_out_asset_a as Ft,calculate_liquidity_out_asset_b as Nt}from"@galacticcouncil/math-xyk";var G=class{static getSpotPrice(e,t,s){return Ot(e,t,s)}static calculateInGivenOut(e,t,s){return yt(e,t,s)}static calculateOutGivenIn(e,t,s){return St(e,t,s)}static calculatePoolTradeFee(e,t,s){return Bt(e,t,s)}static calculateLiquidityIn(e,t,s){return wt(e,t,s)}static calculateSpotPrice(e,t){return xt(e,t)}static calculateSpotPriceWithFee(e,t,s,r){return At(e,t,s,r)}static calculateShares(e,t,s){return It(e,t,s)}static calculateLiquidityOutAssetA(e,t,s,r){return Ft(e,t,s,r)}static calculateLiquidityOutAssetB(e,t,s,r){return Nt(e,t,s,r)}};var ee=class m{type;address;tokens;maxInRatio;maxOutRatio;minTradingLimit;static fromPool(e){return new m(e.address,e.tokens,e.maxInRatio,e.maxOutRatio,e.minTradingLimit)}constructor(e,t,s,r,i){this.type="Xyk",this.address=e,this.tokens=t,this.maxInRatio=s,this.maxOutRatio=r,this.minTradingLimit=i}validatePair(e,t){return!0}parsePair(e,t){let s=new Map(this.tokens.map(c=>[c.id,c])),r=s.get(e),i=s.get(t);if(r==null)throw new Error("Pool does not contain tokenIn");if(i==null)throw new Error("Pool does not contain tokenOut");let o=u(r.balance),a=u(i.balance),n=u(r.existentialDeposit),l=u(i.existentialDeposit);return{assetIn:e,assetOut:t,decimalsIn:r.decimals,decimalsOut:i.decimals,balanceIn:o,balanceOut:a,assetInED:n,assetOutED:l}}validateAndBuy(e,t,s){let r=this.calculateInGivenOut(e,t),i=this.calculateTradeFee(r,s),o=A(s.exchangeFee),a=r.plus(i),n=[];(t.isLessThan(this.minTradingLimit)||r.isLessThan(e.assetInED))&&n.push("InsufficientTradingAmount");let l=e.balanceOut.div(this.maxOutRatio);t.isGreaterThan(l)&&n.push("MaxOutRatioExceeded");let c=e.balanceIn.div(this.maxInRatio);return a.isGreaterThan(c)&&n.push("MaxInRatioExceeded"),{amountIn:a,calculatedIn:r,amountOut:t,feePct:o,errors:n}}validateAndSell(e,t,s){let r=this.calculateOutGivenIn(e,t),i=this.calculateTradeFee(r,s),o=A(s.exchangeFee),a=r.minus(i),n=[];(t.isLessThan(this.minTradingLimit)||r.isLessThan(e.assetOutED))&&n.push("InsufficientTradingAmount");let l=e.balanceIn.div(this.maxInRatio);t.isGreaterThan(l)&&n.push("MaxInRatioExceeded");let c=e.balanceOut.div(this.maxOutRatio);return a.isGreaterThan(c)&&n.push("MaxOutRatioExceeded"),{amountIn:t,calculatedOut:r,amountOut:a,feePct:o,errors:n}}calculateInGivenOut(e,t){let s=G.calculateInGivenOut(e.balanceIn.toString(),e.balanceOut.toString(),t.toFixed(0)),r=u(s);return r.isNegative()?P:r}calculateOutGivenIn(e,t){let s=G.calculateOutGivenIn(e.balanceIn.toString(),e.balanceOut.toString(),t.toFixed(0)),r=u(s);return r.isNegative()?P:r}spotPriceInGivenOut(e){let t=G.calculateSpotPrice(e.balanceOut.toString(),e.balanceIn.toString()),s=x(v,18-e.decimalsOut);return u(t).div(s)}spotPriceOutGivenIn(e){let t=G.calculateSpotPrice(e.balanceIn.toString(),e.balanceOut.toString()),s=x(v,18-e.decimalsIn);return u(t).div(s)}calculateTradeFee(e,t){let s=G.calculatePoolTradeFee(e.toString(),t.exchangeFee[0],t.exchangeFee[1]);return u(s)}};var te=class{static get(e){switch(e.type){case"Xyk":return ee.fromPool(e);case"Omnipool":return Q.fromPool(e);case"Lbp":return K.fromPool(e);case"Stableswap":return V.fromPool(e);default:throw new Error("Pool type "+e.type+" is not supported yet")}}};var X=class{routeSuggester;routerOptions;poolService;defaultRouterOptions={includeOnly:[]};constructor(e,t){this.poolService=e,this.routeSuggester=new Y,this.routerOptions={...this.defaultRouterOptions,...t}}async getPools(){let e=this.routerOptions.includeOnly;return await this.poolService.getPools(e)}async getAllAssets(){let e=await this.getPools();if(e.length===0)throw new Error("No pools configured");let t=await this.getAssets(e);return[...new Map(t).values()]}async getAssetPairs(e){let t=await this.getPools();if(t.length===0)throw new Error("No pools configured");let{assets:s,poolsMap:r}=await this.validateToken(e,t),o=this.getPaths(e,null,r,t).map(a=>a[a.length-1].assetOut);return this.toAssets([...new Set(o)],s)}async getAllPaths(e,t){let s=await this.getPools();if(s.length===0)throw new Error("No pools configured");let{poolsMap:r}=await this.validateTokenPair(e,t,s);return this.getPaths(e,t,r,s)}async getAssets(e){let t=e.map(s=>s.tokens.map(r=>({id:r.id,name:r.name,symbol:r.symbol,decimals:r.decimals,icon:r.icon,type:r.type,isSufficient:r.isSufficient,existentialDeposit:r.existentialDeposit,meta:r.meta,location:r.location,isWhiteListed:r.isWhiteListed}))).flat();return new Map(t.map(s=>[s.id,s]))}getPaths(e,t,s,r){return this.routeSuggester.getProposals(e,t,r).filter(a=>this.validPath(a,s)).map(a=>this.toHops(a,s))}async validateTokenPair(e,t,s){let r=await this.getAssets(s);if(r.get(e)==null)throw new Error(e+" is not supported token");if(r.get(t)==null)throw new Error(t+" is not supported token");let i=this.getPoolMap(s);return{assets:r,poolsMap:i}}async validateToken(e,t){let s=await this.getAssets(t);if(s.get(e)==null)throw new Error(e+" is not supported token");let r=this.getPoolMap(t);return{assets:s,poolsMap:r}}getPoolMap(e){return new Map(e.map(t=>[t.address,te.get(t)]))}validPath(e,t){return e.length>0&&e.map(s=>this.validEdge(s,t)).reduce((s,r)=>s&&r)}validEdge([e,t,s],r){return r.get(e)?.validatePair(t,s)||!1}toHops(e,t){return e.map(([s,r,i])=>{let o=t.get(s);return{poolAddress:s,poolId:o?.id,pool:o?.type,assetIn:r,assetOut:i}})}toAssets(e,t){return e.map(s=>t.get(s))}};function Go(m,e){return m.minus(e).abs().div(m.plus(e).div(2)).multipliedBy(100).decimalPlaces(2)}function se(m,e){return m.minus(e).div(e).multipliedBy(100).decimalPlaces(2)}function Fe(m,e){return v.minus(e.div(m)).multipliedBy(100).decimalPlaces(2)}function Ne(m,e){return e.div(m).minus(v).multipliedBy(100).decimalPlaces(2)}var me=class extends X{isDirectTrade(e){return e.length==1}findBestSellRoute(e){let t=e.sort((s,r)=>{let i=s[s.length-1].amountOut,o=r[r.length-1].amountOut;return i.isGreaterThan(o)?-1:1});return t.find(s=>s.every(r=>r.errors.length==0))||t[0]}getRouteFeeRange(e){if(e.filter(s=>s.tradeFeeRange).length>0){let s=e.map(i=>i.tradeFeeRange?.[0]??i.tradeFeePct).reduce((i,o)=>i+o),r=e.map(i=>i.tradeFeeRange?.[1]??i.tradeFeePct).reduce((i,o)=>i+o);return[s,r]}}getPoolFeeRange(e){let t=e.min?A(e.min):void 0,s=e.max?A(e.max):void 0;if(t&&s)return[t,s]}async getBestSell(e,t,s){return this.getSell(e,t,s)}async getSell(e,t,s,r){let i=await super.getPools();if(i.length===0)throw new Error("No pools configured");let{poolsMap:o}=await super.validateTokenPair(e,t,i),a=super.getPaths(e,t,o,i);if(a.length===0)throw new $(e,t);let n;if(r)n=await this.toSellSwaps(s,r,o);else{let w=a.map(async pe=>await this.toSellSwaps(s,pe,o)),L=await Promise.all(w);n=this.findBestSellRoute(L)}let l=n[0],c=n[n.length-1],p=this.isDirectTrade(n),d=n.map(w=>w.spotPrice.shiftedBy(-1*w.assetOutDecimals)).reduce((w,L)=>w.multipliedBy(L)),g=x(d,c.assetOutDecimals),b=p?c.calculatedOut:this.calculateDelta0Y(l.amountIn,n,o),f=c.amountOut,y=p?c.tradeFeePct:Fe(b,f).toNumber(),S=b.minus(f),h=this.getRouteFeeRange(n),I=l.amountIn.shiftedBy(-1*l.assetInDecimals).multipliedBy(g),F=se(b,I),C=w=>this.poolService.buildSellTx(e,t,l.amountIn,w,n.map(L=>L));return{type:"Sell",amountIn:l.amountIn,amountOut:c.amountOut,spotPrice:g,tradeFee:S,tradeFeePct:y,tradeFeeRange:h,priceImpactPct:F.toNumber(),swaps:n,toTx:C,toHuman(){return{type:"Sell",amountIn:N(l.amountIn,l.assetInDecimals),amountOut:N(c.amountOut,c.assetOutDecimals),spotPrice:N(g,c.assetOutDecimals),tradeFee:N(S,c.assetOutDecimals),tradeFeePct:y,tradeFeeRange:h,priceImpactPct:F.toNumber(),swaps:n.map(w=>w.toHuman())}}}}calculateDelta0Y(e,t,s){let r=[];for(let i=0;i<t.length;i++){let o=t[i],a=s.get(o.poolAddress);if(a==null)throw new Error("Pool does not exit");let n=a.parsePair(o.assetIn,o.assetOut),l;i>0?l=r[i-1]:l=e;let c=a.calculateOutGivenIn(n,l);r.push(c)}return r[r.length-1]}async toSellSwaps(e,t,s){let r=[];for(let i=0;i<t.length;i++){let o=t[i],a=s.get(o.poolAddress);if(a==null)throw new Error("Pool does not exit");let n=a.parsePair(o.assetIn,o.assetOut),l;i>0?l=r[i-1].amountOut:l=x(u(e),n.decimalsIn).decimalPlaces(0,1);let c=await this.poolService.getPoolFees(n,a),{amountOut:p,calculatedOut:d,feePct:g,errors:b}=a.validateAndSell(n,l,c),f=this.getPoolFeeRange(c),y=a.spotPriceOutGivenIn(n),S=l.shiftedBy(-1*n.decimalsIn).multipliedBy(y),h=se(d,S);r.push({...o,assetInDecimals:n.decimalsIn,assetOutDecimals:n.decimalsOut,amountIn:l,calculatedOut:d,amountOut:p,spotPrice:y,tradeFeePct:g,tradeFeeRange:f,priceImpactPct:h.toNumber(),errors:b,toHuman(){return{...o,amountIn:N(l,n.decimalsIn),calculatedOut:N(d,n.decimalsOut),amountOut:N(p,n.decimalsOut),spotPrice:N(y,n.decimalsOut),tradeFeePct:g,tradeFeeRange:f,priceImpactPct:h.toNumber(),errors:b}}})}return r}async getBestSpotPrice(e,t){let s=await super.getPools();if(s.length===0)throw new Error("No pools configured");let{poolsMap:r}=await super.validateTokenPair(e,t,s),i=super.getPaths(e,t,r,s);if(i.length===0)return Promise.resolve(void 0);let o=s.map(h=>h.tokens.find(I=>I.id===e)).filter(h=>!!h).sort((h,I)=>Number(I.balance)-Number(h.balance)),{balance:a,decimals:n}=o[0],c=u(a).shiftedBy(-1*n).div(100).multipliedBy(.1),p=i.map(async h=>await this.toSellSwaps(c,h,r)),d=await Promise.all(p),g=this.findBestSellRoute(d),b=await this.toSellSwaps("1",g,r),f=b.map(h=>h.spotPrice.shiftedBy(-1*h.assetOutDecimals)).reduce((h,I)=>h.multipliedBy(I)),y=b[b.length-1].assetOutDecimals;return{amount:x(f,y),decimals:y}}findBestBuyRoute(e){let t=e.sort((s,r)=>{let i=s[0].amountIn,o=r[0].amountIn;return i.isGreaterThan(o)?1:-1});return t.find(s=>s.every(r=>r.errors.length==0))||t[0]}async getBestBuy(e,t,s){return this.getBuy(e,t,s)}async getBuy(e,t,s,r){let i=await super.getPools();if(i.length===0)throw new Error("No pools configured");let{poolsMap:o}=await super.validateTokenPair(e,t,i),a=super.getPaths(e,t,o,i);if(a.length===0)throw new $(e,t);let n;if(r)n=await this.toBuySwaps(s,r,o);else{let w=a.map(async pe=>await this.toBuySwaps(s,pe,o)),L=await Promise.all(w);n=this.findBestBuyRoute(L)}let l=n[n.length-1],c=n[0],p=this.isDirectTrade(n),d=n.map(w=>w.spotPrice.shiftedBy(-1*w.assetInDecimals)).reduce((w,L)=>w.multipliedBy(L)),g=x(d,c.assetInDecimals),b=p?c.calculatedIn:this.calculateDelta0X(l.amountOut,n,o),f=c.amountIn,y=p?c.tradeFeePct:Ne(b,f).toNumber(),S=f.minus(b),h=this.getRouteFeeRange(n),I=l.amountOut.shiftedBy(-1*l.assetOutDecimals).multipliedBy(g),F;b.isZero()?F=-100:F=se(I,b).toNumber();let C=w=>this.poolService.buildBuyTx(e,t,l.amountOut,w,n.map(L=>L));return{type:"Buy",amountOut:l.amountOut,amountIn:c.amountIn,spotPrice:g,tradeFee:S,tradeFeePct:y,tradeFeeRange:h,priceImpactPct:F,swaps:n,toTx:C,toHuman(){return{type:"Buy",amountOut:N(l.amountOut,l.assetOutDecimals),amountIn:N(c.amountIn,c.assetInDecimals),spotPrice:N(g,c.assetInDecimals),tradeFee:N(S,c.assetInDecimals),tradeFeePct:y,tradeFeeRange:h,priceImpactPct:F,swaps:n.map(w=>w.toHuman())}}}}calculateDelta0X(e,t,s){let r=[];for(let i=t.length-1;i>=0;i--){let o=t[i],a=s.get(o.poolAddress);if(a==null)throw new Error("Pool does not exit");let n=a.parsePair(o.assetIn,o.assetOut),l;i==t.length-1?l=e:l=r[0];let c=a.calculateInGivenOut(n,l);r.unshift(c)}return r[0]}async toBuySwaps(e,t,s){let r=[];for(let i=t.length-1;i>=0;i--){let o=t[i],a=s.get(o.poolAddress);if(a==null)throw new Error("Pool does not exit");let n=a.parsePair(o.assetIn,o.assetOut),l;i==t.length-1?l=x(u(e),n.decimalsOut).decimalPlaces(0,1):l=r[0].amountIn;let c=await this.poolService.getPoolFees(n,a),{amountIn:p,calculatedIn:d,feePct:g,errors:b}=a.validateAndBuy(n,l,c),f=this.getPoolFeeRange(c),y=a.spotPriceInGivenOut(n),S=l.shiftedBy(-1*n.decimalsOut).multipliedBy(y),h;d.isZero()?h=-100:h=se(S,d).toNumber(),r.unshift({...o,assetInDecimals:n.decimalsIn,assetOutDecimals:n.decimalsOut,amountOut:l,calculatedIn:d,amountIn:p,spotPrice:y,tradeFeePct:g,tradeFeeRange:f,priceImpactPct:h,errors:b,toHuman(){return{...o,amountOut:N(l,n.decimalsOut),calculatedIn:N(d,n.decimalsIn),amountIn:N(p,n.decimalsIn),spotPrice:N(y,n.decimalsIn),tradeFeePct:g,tradeFeeRange:f,priceImpactPct:h,errors:b}}})}return r}};import{memoize1 as an}from"@thi.ng/memoize";function Pn(m,e){let t=[];return JSON.stringify(m,(s,r)=>(r&&r[e]&&t.push(r),r)),t[0]}function fn(m,e,t){let s;return JSON.stringify(m,(r,i)=>(i&&i[e]===t&&(s=i),i)),s}export{H as AssetClient,we as AssetNotFound,ts as BASILISK_PARACHAIN_ID,W as BalanceClient,O as BigNumber,fe as CachingPoolService,ve as DECIMAL_PLACES,be as DENOMINATOR,he as FarmClient,ie as HUB_ASSET_ID,oe as HYDRADX_OMNIPOOL_ADDRESS,es as HYDRADX_PARACHAIN_ID,j as HYDRADX_SS58_PREFIX,zt as INFINITY,D as LbpMath,K as LbpPool,v as ONE,B as OmniMath,Q as OmniPool,Oe as PoolConfigNotFound,z as PoolError,te as PoolFactory,ue as PoolNotFound,Z as PoolService,E as PoolType,Ae as ProviderConfigNotFound,J as RUNTIME_DECIMALS,$ as RouteNotFound,X as Router,Vt as SYSTEM_ASSET_DECIMALS,_ as SYSTEM_ASSET_ID,T as StableMath,V as StableSwap,Ie as StorageConfigNotFound,xe as SubscriptionNotSupported,de as TRADEABLE_DEFAULT,me as TradeRouter,ye as TradeType,G as XykMath,ee as XykPool,P as ZERO,u as bnum,Pe as buildRoute,Ne as calculateBuyFee,Go as calculateDiffToAvg,se as calculateDiffToRef,Fe as calculateSellFee,Pn as findNestedKey,fn as findNestedObj,x as scale};
1
+ var re=class{constructor(e=1/0){this.capacity=e}storage=[];enqueue(e){if(this.size()===this.capacity)throw Error("Queue has reached max capacity, you cannot add more items");this.storage.push(e)}dequeue(){return this.storage.shift()}size(){return this.storage.length}};var Te=5,Y=class{isNotVisited(e,t){let s=!0;return t.forEach(r=>{(r[0]===e[0]||r[1]===e[1])&&(s=!1)}),s}findPaths(e,t,s){let r=[],i=new re,o=[];for(o.push([t,""]),i.enqueue(o);i.size()>0;){let n=i.dequeue();if(n==null||n.length>Te)return r;let a=n[n.length-1];(s===null||a[0]===s)&&r.push(n),e.get(a[0])?.forEach(c=>{if(this.isNotVisited(c,n)){let u=[...n];u.push(c),i.enqueue(u)}})}return r}buildAndPopulateGraph(e,t){let s=new Map;for(let r of e)s.set(parseInt(r),[]);for(let[r,i,o]of t){let n=parseInt(i),a=parseInt(o);s.get(n)?.push([a,r])}return s}};function ge(p){let e={};for(let t of p){let s=t.tokens.length;for(let r=0;r<s;r++){e[t.tokens[r].id]||(e[t.tokens[r].id]=[]);for(let i=0;i<s;i++){if(r==i)continue;let o=[t.address,t.tokens[r].id,t.tokens[i].id];e[t.tokens[r].id].push(o)}}}return e}var z=class{getProposals(e,t,s){let r=ge(s),i=Object.keys(r),o=i.map(c=>r[c]).flat(),n=new Y,a=n.buildAndPopulateGraph(i,o),l=n.findPaths(a,parseInt(e),t?parseInt(t):null);return this.parsePaths(l)}parsePaths(e){let t=[];for(let s of e){let r=[];for(let i=0;i<s.length;i++){let o=s[i],n=s[i+1];if(n==null)break;r.push(this.toEdge(o,n))}t.push(r)}return t}toEdge(e,t){return[t[1],e[0].toString(),t[0].toString()]}};import{memoize1 as Pt}from"@thi.ng/memoize";import{BigNumber as O}from"bignumber.js";var ve=12;O.config({EXPONENTIAL_AT:[-100,100],ROUNDING_MODE:4,DECIMAL_PLACES:ve});var P=m(0),v=m(1),zt=m("Infinity");function I(p,e){let t=new O(e.toString()),s=new O(10).pow(t);return p.times(s)}function m(p){return new O(p.toString())}var E=(r=>(r.XYK="Xyk",r.LBP="Lbp",r.Stable="Stableswap",r.Omni="Omnipool",r))(E||{}),J=(i=>(i.UnknownError="UnknownError",i.InsufficientTradingAmount="InsufficientTradingAmount",i.MaxInRatioExceeded="MaxInRatioExceeded",i.MaxOutRatioExceeded="MaxOutRatioExceeded",i.TradeNotAllowed="TradeNotAllowed",i))(J||{}),ye=(t=>(t.Buy="Buy",t.Sell="Sell",t))(ye||{});import{calculate_in_given_out as Re,calculate_out_given_in as Ee,calculate_linear_weights as ke,calculate_pool_trade_fee as _e,get_spot_price as Le}from"@galacticcouncil/math-lbp";var D=class{static getSpotPrice(e,t,s,r,i){return Le(e,t,s,r,i)}static calculateInGivenOut(e,t,s,r,i){return Re(e,t,s,r,i)}static calculateOutGivenIn(e,t,s,r,i){return Ee(e,t,s,r,i)}static calculateLinearWeights(e,t,s,r,i){return ke(e,t,s,r,i)}static calculatePoolTradeFee(e,t,s){return _e(e,t,s)}};import{memoize1 as Ce}from"@thi.ng/memoize";import{encodeAddress as De}from"@polkadot/util-crypto";import{stringToU8a as Me}from"@polkadot/util";var j=18,de=15,_="0",Vt=12,ie="1",es=2034,$=63,ts=2090,be=1e3,oe=De(Me("modlomnipool".padEnd(32,"\0")),$);import"@galacticcouncil/api-augment/hydradx";import"@galacticcouncil/api-augment/basilisk";var q=class{api;constructor(e){this.api=e}get chainDecimals(){return this.api.registry.chainDecimals[0]}get chainToken(){return this.api.registry.chainTokens[0]}};var H=class extends q{SUPPORTED_TYPES=["StableSwap","Bond","Token","External","Erc20"];constructor(e){super(e)}async safeSharesQuery(){try{let e=await this.api.query.stableswap.pools.entries();return new Map(e.map(([{args:[t]},s])=>[t.toString(),s.unwrap()]))}catch{return new Map([])}}async safeBondsQuery(){try{let e=await this.api.query.bonds.bonds.entries();return new Map(e.map(([{args:[t]},s])=>[t.toString(),s.unwrap()]))}catch{return new Map([])}}async metadataQuery(){try{let e=await this.api.query.assetRegistry.assetMetadataMap.entries();return new Map(e.map(([{args:[t]},s])=>{let{decimals:r,symbol:i}=s.unwrap();return[t.toString(),{decimals:r.toNumber(),symbol:i.toHuman()}]}))}catch{return new Map([])}}async locationsQuery(){try{let e=await this.api.query.assetRegistry.assetLocations.entries();return new Map(e.map(([{args:[t]},s])=>[t.toString(),s.unwrap()]))}catch{return new Map([])}}getSystemTokenName(e){switch(e){case"HDX":return"Hydration";case"BSX":return"Basilisk";default:return e}}getToken(e,t,s,r){if(e==_){let u=this.api.consts.balances.existentialDeposit;return{id:_,name:this.getSystemTokenName(this.chainToken),symbol:this.chainToken,decimals:this.chainDecimals,icon:this.chainToken,type:"Token",isSufficient:!0,existentialDeposit:u.toString()}}let{name:i,assetType:o,isSufficient:n,existentialDeposit:a}=t,{symbol:l,decimals:c}=s.get(e)??{};return{id:e,name:i.toHuman(),symbol:l,decimals:c,icon:l,type:o.toHuman(),isSufficient:n?n.toHuman():!0,location:r?.toJSON(),existentialDeposit:a.toString()}}getBond(e,t,s,r){let[i,o]=r,{assetType:n,isSufficient:a,existentialDeposit:l}=t,{symbol:c,decimals:u}=this.getToken(i.toString(),t,s),b=o.toNumber(),d=new Intl.DateTimeFormat("en-GB"),g=[c,"Bond",d.format(b)].join(" ");return{id:e,name:g,symbol:c+"b",decimals:u,icon:c,type:n.toString(),isSufficient:a.toHuman(),existentialDeposit:l.toString(),underlyingAssetId:i.toString(),maturity:b}}getShares(e,t,s,r){let{assets:i}=r,{name:o,symbol:n,assetType:a,isSufficient:l,existentialDeposit:c}=t,b=i.map(h=>h.toString()).map(h=>{let{symbol:f}=this.getToken(h,t,s);return[h,f]}),d=Object.fromEntries(b),g=Object.values(d);return{id:e,name:g.join(", "),symbol:n?.isSome?n.toHuman():o.toHuman(),decimals:18,icon:g.join("/"),type:a.toString(),isSufficient:l.toHuman(),existentialDeposit:c.toString(),meta:d}}getExternal(e,t,s,r){let i=this.getToken(e,t,new Map,r),o=s?.find(n=>n.internalId===i.id);return o?{...i,decimals:o.decimals,name:o.name,symbol:o.symbol,icon:o.symbol,isWhiteListed:o.isWhiteListed}:i}normalizeMetadata(e,t){return t.size?t:new Map(e.map(([{args:[s]},r])=>{let{decimals:i,symbol:o}=r.unwrap();return[s.toString(),{decimals:Number(i.toString()),symbol:o.toHuman()}]}))}getSupportedAssets(e){return e.filter(([t,s])=>{if(s.isNone)return!1;let r=s.unwrap();return this.isSupportedAsset(r)})}async getOnChainAssets(e,t){let[s,r,i,o,n]=await Promise.all([this.api.query.assetRegistry.assets.entries(),this.locationsQuery(),this.safeSharesQuery(),this.safeBondsQuery(),this.metadataQuery()]),a=this.getSupportedAssets(s),l=this.normalizeMetadata(a,n),c=a.map(([{args:[u]},b])=>{let d=b.unwrap(),g=r.get(u.toString()),{assetType:h}=d;switch(h.toString()){case"Bond":let f=o.get(u.toString());return this.getBond(u.toString(),d,l,f);case"StableSwap":let y=i.get(u.toString());return this.getShares(u.toString(),d,l,y);case"External":return this.getExternal(u.toString(),d,t,g);default:return this.getToken(u.toString(),d,l,g)}});return e?c:c.filter(u=>this.isValidAsset(u))}isValidAsset(e){let t=Math.sign(e.decimals);return!!e.symbol&&(t===0||t===1)}isSupportedAsset(e){let t=e.assetType.toString();return this.SUPPORTED_TYPES.includes(t)}};var W=class extends q{constructor(e){super(e)}async getBalance(e,t){let s=await this.api.query.assetRegistry.assets(t),{assetType:r}=s.unwrap();return r.toString()==="Erc20"?this.getErc20Balance(e,t):t===_?this.getSystemBalance(e):this.getTokenBalance(e,t)}async getSystemBalance(e){let{data:t}=await this.api.query.system.account(e);return this.calculateFreeBalance(t)}async getTokenBalance(e,t){let{free:s,reserved:r,frozen:i}=await this.api.query.tokens.accounts(e,t);return this.calculateFreeBalance({free:s,feeFrozen:r,frozen:i})}async getErc20Balance(e,t){let{free:s,reserved:r,frozen:i}=await this.getTokenBalanceData(e,t);return this.calculateFreeBalance({free:s,feeFrozen:r,frozen:i})}async subscribeSystemBalance(e,t){return this.api.query.system.account(e,({data:s})=>t(_,this.calculateFreeBalance(s)))}async subscribeTokenBalance(e,t,s){let i=t.filter(o=>o.type!=="Erc20").filter(o=>o.id!==_).map(o=>[e,o.id]);return this.api.query.tokens.accounts.multi(i,o=>{let n=[];o.forEach((a,l)=>{let c=this.calculateFreeBalance(a),u=i[l][1];n.push([u,c])}),s(n)})}async subscribeErc20Balance(e,t,s){let r=t.filter(o=>o.type==="Erc20"),i=async()=>{let o=[];(await Promise.all(r.map(async a=>[a.id,await this.getErc20Balance(e,a.id)]))).forEach(([a,l])=>{o.push([a,l])}),s(o)};return await i(),this.api.rpc.chain.subscribeNewHeads(async()=>{i()})}async getTokenBalanceData(e,t){return this.api.call.currenciesApi.account(t,e)}calculateFreeBalance(e){let{free:t,miscFrozen:s,feeFrozen:r,frozen:i}=e,o=new O(t),n=new O(s||i),a=new O(r||0n),l=n.gt(a)?n:a;return o.minus(l)}};import{isAddress as Se}from"@polkadot/util-crypto";import{fixed_from_rational as Be}from"@galacticcouncil/math-liquidity-mining";var he=class extends q{constructor(e){super(e)}secondsInYear=new O(365.2425).times(24).times(60).times(60);async getOmnipoolFarms(e){let t=await this.api.query.omnipoolWarehouseLM.activeYieldFarm.entries(e);return await Promise.all(t.map(async([r,i])=>{let[,o]=r.args,n=i.unwrap().toString(),a=o.toString(),l=(await this.api.query.omnipoolWarehouseLM.globalFarm(a)).unwrap(),c=(await this.api.query.omnipoolWarehouseLM.yieldFarm(e,a,n)).unwrap(),u=await this.getOraclePrice(l)??l.priceAdjustment.toString();return{assetId:e,globalFarm:l,yieldFarm:c,priceAdjustment:u}}))}async getIsolatedPoolFarms(e){let t=await this.api.query.xykWarehouseLM.activeYieldFarm.entries(e);return await Promise.all(t.map(async([r,i])=>{let[,o]=r.args,n=i.unwrap().toString(),a=o.toString(),l=(await this.api.query.xykWarehouseLM.globalFarm(a)).unwrap(),c=(await this.api.query.xykWarehouseLM.yieldFarm(e,a,n)).unwrap(),u=await this.getOraclePrice(l)??l.priceAdjustment.toString();return{assetId:e,globalFarm:l,yieldFarm:c,priceAdjustment:u}}))}async getOraclePrice(e){let t=e.rewardCurrency.toString(),s=e.incentivizedAsset.toString(),r=[t,s].sort();if(t===s)return new O(1).shiftedBy(18).toString();let i=await this.api.query.emaOracle.oracles("omnipool",r,"TenMinutes");if(i.isNone)return;let[o]=i.unwrap(),n=o.price.n.toString(),a=o.price.d.toString(),l;return Number(t)<Number(s)?l=Be(n,a):l=Be(a,n),l}getGlobalRewardPerPeriod(e,t,s,r){let o=e.times(t).shiftedBy(-18).times(r).shiftedBy(-18);return o.gte(s)?s:o}getPoolYieldPerPeriod(e,t,s,r){return e.times(t).div(s.times(r).shiftedBy(-18))}async getFarmApr(e,t){if(t==="isolatedpool"&&!Se(e))throw new Error("You must pass an address of isolated pool as id");if(t==="omnipool"&&Se(e))throw new Error("You must pass an asset id of omnipool");let s=6,r=t==="omnipool"?await this.getOmnipoolFarms(e):await this.getIsolatedPoolFarms(e);return r.length?r.map(({yieldFarm:n,globalFarm:a,priceAdjustment:l})=>{let c=new O(a.totalSharesZ.toString()),u=a.plannedYieldingPeriods.toString(),b=new O(a.yieldPerPeriod.toString()),d=new O(a.maxRewardPerPeriod.toString()),g=a.blocksPerPeriod.toString(),h=new O(n.multiplier.toString()).shiftedBy(-18),f=this.secondsInYear.div(new O(s).times(g)),y;if(c.isZero())y=b.times(h).times(f);else{let C=this.getGlobalRewardPerPeriod(c,b,d,l);y=this.getPoolYieldPerPeriod(C,h,c,l).times(f)}let S=new O(a.pendingRewards.toString()).plus(a.accumulatedPaidRewards.toString()),T=d.times(u);return S.div(T).gte(.99)?P:y.times(100)}).reduce((n,a)=>n.plus(a),P).toString():void 0}};var M=class extends W{pools=[];subs=[];assets=new Map([]);mem=0;memPools=Ce(e=>(console.log(this.getPoolType(),"mem pools",e,"\u2705"),this.getPools()));constructor(e){super(e)}get augmentedPools(){return this.pools.filter(e=>this.isValidPool(e)).map(e=>this.withMetadata(e))}async withAssets(e){this.assets=new Map(e.map(t=>[t.id,t])),this.mem=this.mem+1}async getPoolsMem(){return this.memPools(this.mem)}async getPools(){this.unsubscribe(),this.pools=await this.loadPools(),this.subs=this.subscribe();let e=this.getPoolType();return console.log(e,`pools(${this.augmentedPools.length})`,"\u2705"),console.log(e,`subs(${this.subs.length})`,"\u2705"),this.augmentedPools}subscribe(){return this.augmentedPools.map(t=>{let s=[this.subscribeTokensPoolBalance(t)];try{let r=this.subscribePoolChange(t);s.push(r)}catch{}if(this.hasSystemAsset(t)){let r=this.subscribeSystemPoolBalance(t);s.push(r)}if(this.hasErc20Asset(t)){let r=this.subscribeErc20PoolBalance(t);s.push(r)}if(this.hasShareAsset(t)){let r=this.subscribeSharePoolBalance(t);s.push(r)}return this.subscribeLog(t),s}).flat()}hasSystemAsset(e){return e.tokens.some(t=>t.id==="0")}hasShareAsset(e){return e.type==="Stableswap"&&e.id}hasErc20Asset(e){return e.tokens.some(t=>t.type==="Erc20")}unsubscribe(){this.subs.forEach(e=>{e.then(t=>t())})}subscribeLog(e){let t=e.address.substring(0,10).concat("...");console.log(`${e.type} [${t}] balance subscribed`)}subscribeSystemPoolBalance(e){return this.subscribeSystemBalance(e.address,this.updateBalanceCallback(e))}subscribeTokensPoolBalance(e){let t=(s,r)=>s.id!==r;return this.subscribeTokenBalance(e.address,e.tokens,this.updateBalancesCallback(e,t))}subscribeErc20PoolBalance(e){return this.subscribeErc20Balance(e.address,e.tokens,this.updateBalancesCallback(e,()=>!0))}subscribeSharePoolBalance(e){let t=this.assets.get(e.id);return this.subscribeTokenBalance(oe,[t],this.updateBalancesCallback(e,()=>!0))}isValidPool(e){return e.type==="Xyk"?e.tokens.every(t=>this.assets.get(t.id)):!0}withMetadata(e){return e.tokens=e.tokens.map(t=>{let s=this.assets.get(t.id);return{...t,...s}}),e}updateBalancesCallback(e,t){return function(s){s.forEach(([r,i])=>{let o=e.tokens.findIndex(n=>n.id==r);o>=0&&t(e,r)&&(e.tokens[o].balance=i.toString())})}}updateBalanceCallback(e){return function(t,s){let r=e.tokens.findIndex(i=>i.id==t);r>=0&&(e.tokens[r].balance=s.toString())}}};var ne=class extends M{MAX_FINAL_WEIGHT=I(m(100),6);poolsData=new Map([]);isSupported(){return this.api.query.lbp!==void 0}async loadPools(){let[e,t]=await Promise.all([this.api.query.lbp.poolData.entries(),this.api.query.parachainSystem.validationData()]),{relayParentNumber:s}=t.unwrap(),r=e.filter(([i,o])=>this.isActivePool(o.unwrap(),s)).map(async([{args:[i]},o])=>{let n=o.unwrap(),a=i.toString(),l=await this.getPoolDelta(a,n,s.toString());return this.poolsData.set(i.toString(),n),{address:a,type:"Lbp",fee:n.fee.toJSON(),...l,...this.getPoolLimits()}});return Promise.all(r)}async getPoolFees(e,t){let s=this.pools.find(r=>r.address===t);return{repayFee:this.getRepayFee(),exchangeFee:s.fee}}getPoolType(){return"Lbp"}async subscribePoolChange(e){return this.api.query.parachainSystem.validationData(async t=>{let{relayParentNumber:s}=t.unwrap(),r=this.poolsData.get(e.address);if(this.isActivePool(r,s)){let o=await this.getPoolDelta(e.address,r,s.toString());Object.assign(e,o)}else{let o=this.pools.findIndex(n=>n.address==e.address);this.pools.splice(o,1)}})}async getPoolDelta(e,t,s){let{start:r,end:i,assets:o,initialWeight:n,finalWeight:a,repayTarget:l,feeCollector:c}=t,u=D.calculateLinearWeights(r.toString(),i.toString(),n.toString(),a.toString(),s),[b,d]=o,g=b.toString(),h=m(u),f=d.toString(),y=this.MAX_FINAL_WEIGHT.minus(m(h)),[S,T,A]=await Promise.all([this.isRepayFeeApplied(g,l.toString(),c.toString()),this.getBalance(e,g),this.getBalance(e,f)]);return{repayFeeApply:S,tokens:[{id:g,weight:h,balance:T.toString()},{id:f,weight:y,balance:A.toString()}]}}isActivePool(e,t){if(e.start.isEmpty||e.end.isEmpty)return!1;let s=e.start.unwrap().toNumber(),r=e.end.unwrap().toNumber();return t.toNumber()>=s&&t.toNumber()<r}async isRepayFeeApplied(e,t,s){let r=m(t);if(r.isZero())return!1;try{return(await this.getBalance(e,s)).isLessThan(r)}catch{return!0}}getRepayFee(){return this.api.consts.lbp.repayFee.toJSON()}getPoolLimits(){let e=this.api.consts.lbp.maxInRatio.toJSON(),t=this.api.consts.lbp.maxOutRatio.toJSON(),s=this.api.consts.lbp.minTradingLimit.toJSON();return{maxInRatio:e,maxOutRatio:t,minTradingLimit:s}}};import{encodeAddress as rt}from"@polkadot/util-crypto";import{stringToU8a as it}from"@polkadot/util";function F(p,e){return p.shiftedBy(-1*e).toString()}function x(p){return p[0]/p[1]*100}function R(p){return p[0]/p[1]}function k(p){return[p/be,be]}import{calculate_in_given_out as Ge,calculate_lrna_in_given_out as qe,calculate_out_given_in as He,calculate_out_given_lrna_in as We,calculate_pool_trade_fee as Xe,calculate_spot_price as Ue,calculate_lrna_spot_price as Ye,calculate_shares as ze,calculate_liquidity_out as Je,calculate_liquidity_lrna_out as je,calculate_liquidity_hub_in as $e,is_sell_allowed as Ze,is_buy_allowed as Ke,is_add_liquidity_allowed as Qe,is_remove_liquidity_allowed as Ve,recalculate_asset_fee as et,recalculate_protocol_fee as tt,verify_asset_cap as st}from"@galacticcouncil/math-omnipool";var B=class{static calculateSpotPrice(e,t,s,r){return Ue(e,t,s,r)}static calculateLrnaSpotPrice(e,t){return Ye(e,t)}static calculateInGivenOut(e,t,s,r,i,o,n,a,l){return Ge(e,t,s,r,i,o,n,a,l)}static calculateLrnaInGivenOut(e,t,s,r,i){return qe(e,t,s,r,i)}static calculateOutGivenIn(e,t,s,r,i,o,n,a,l){return He(e,t,s,r,i,o,n,a,l)}static calculateOutGivenLrnaIn(e,t,s,r,i){return We(e,t,s,r,i)}static calculatePoolTradeFee(e,t,s){return Xe(e,t,s)}static calculateShares(e,t,s,r){return ze(e,t,s,r)}static calculateLiquidityOut(e,t,s,r,i,o,n,a){return Je(e,t,s,r,i,o,n,a)}static calculateLiquidityLRNAOut(e,t,s,r,i,o,n,a){return je(e,t,s,r,i,o,n,a)}static calculateCapDifference(e,t,s,r){let i=O(t),o=O(e),n=O(r),l=O(s).shiftedBy(-18);if(i.div(n).lt(l)){let u=l.times(n).minus(i).times(o),b=i.times(O(1).minus(l));return u.div(b).toFixed(0)}else return"0"}static calculateLimitHubIn(e,t,s,r){return $e(e,t,s,r)}static isSellAllowed(e){return Ze(e)}static isBuyAllowed(e){return Ke(e)}static isAddLiquidityAllowed(e){return Qe(e)}static isRemoveLiquidityAllowed(e){return Ve(e)}static recalculateAssetFee(e,t,s,r,i,o,n,a,l,c,u){return et(e,t,s,r,i,o,n,a,l,c,u)}static recalculateProtocolFee(e,t,s,r,i,o,n,a,l,c,u){return tt(e,t,s,r,i,o,n,a,l,c,u)}static verifyAssetCap(e,t,s,r){return st(e,t,s,r)}};var ae=class extends M{isSupported(){return this.api.query.omnipool!==void 0}async loadPools(){let e=this.api.consts.omnipool.hubAssetId.toString(),t=this.getPoolId(),[s,r,i]=await Promise.all([this.api.query.omnipool.assets.entries(),this.api.query.omnipool.hubAssetTradability(),this.getBalance(t,e)]),o=s.map(async([{args:[a]},l])=>{let{hubReserve:c,shares:u,tradable:b,cap:d,protocolShares:g}=l.unwrap(),h=await this.getBalance(t,a.toString());return{id:a.toString(),hubReserves:m(c.toString()),shares:m(u.toString()),tradeable:b.bits.toNumber(),balance:h.toString(),cap:m(d.toString()),protocolShares:m(g.toString())}}),n=await Promise.all(o);return n.push({id:e,tradeable:r.bits.toNumber(),balance:i.toString()}),[{address:t,type:"Omnipool",hubAssetId:e,tokens:n,...this.getPoolLimits()}]}async getPoolFees(e,t){let s=e.assetOut,r=e.assetIn,i="omnipool",o="Short",n=A=>A===_?[_,ie]:[ie,A],[a,l,c,u]=await Promise.all([this.api.query.system.number(),this.api.query.dynamicFees.assetFee(s),this.api.query.emaOracle.oracles(i,n(s),o),this.api.query.emaOracle.oracles(i,n(r),o)]),[b,d,g]=this.getAssetFee(e,a.toNumber(),l,c),[h,f,y]=r===ie?[0,0,0]:this.getProtocolFee(e,a.toNumber(),l,u),S=b+h,T=g+y;return{assetFee:k(d),protocolFee:k(f),min:k(S),max:k(T)}}getPoolType(){return"Omnipool"}async subscribePoolChange(e){let t=e.tokens.map(s=>s.id);return this.api.query.omnipool.assets.multi(t,s=>{e.tokens=s.map((r,i)=>{let o=e.tokens[i];if(r.isNone)return o;let n=r.unwrap();return this.updateTokenState(o,n)})})}updateTokenState(e,t){let{hubReserve:s,shares:r,tradable:i,cap:o,protocolShares:n}=t;return{...e,hubReserves:m(s.toString()),shares:m(r.toString()),cap:m(o.toString()),protocolShares:m(n.toString()),tradeable:i.bits.toNumber()}}getAssetFee(e,t,s,r){let{assetOut:i,balanceOut:o}=e,{minFee:n,maxFee:a,decay:l,amplification:c}=this.api.consts.dynamicFees.assetFeeParameters,u=k(n.toNumber()),b=k(a.toNumber());if(s.isNone||r.isNone)return[n.toNumber(),n.toNumber(),a.toNumber()];let[d]=r.unwrap(),{assetFee:g,timestamp:h}=s.unwrap(),f=t-h.toNumber(),y=d.volume.bIn.toString(),S=d.volume.bOut.toString(),T=d.liquidity.b.toString();i===_&&(y=d.volume.aIn.toString(),S=d.volume.aOut.toString(),T=d.liquidity.a.toString());let A=k(g.toNumber()),C=B.recalculateAssetFee(y,S,T,"9",o.toString(),x(A).toString(),f.toString(),x(u).toString(),x(b).toString(),l.toString(),c.toString());return[n.toNumber(),Number(C)*1e4,a.toNumber()]}getProtocolFee(e,t,s,r){let{assetIn:i,balanceIn:o}=e,{minFee:n,maxFee:a,decay:l,amplification:c}=this.api.consts.dynamicFees.protocolFeeParameters,u=k(n.toNumber()),b=k(a.toNumber());if(s.isNone||r.isNone)return[n.toNumber(),n.toNumber(),a.toNumber()];let[d]=r.unwrap(),{protocolFee:g,timestamp:h}=s.unwrap(),f=t-h.toNumber(),y=d.volume.bIn.toString(),S=d.volume.bOut.toString(),T=d.liquidity.b.toString();i===_&&(y=d.volume.aIn.toString(),S=d.volume.aOut.toString(),T=d.liquidity.a.toString());let A=k(g.toNumber()),C=B.recalculateProtocolFee(y,S,T,"9",o.toString(),x(A).toString(),f.toString(),x(u).toString(),x(b).toString(),l.toString(),c.toString());return[n.toNumber(),Number(C)*1e4,a.toNumber()]}getPoolId(){return rt(it("modlomnipool".padEnd(32,"\0")),$)}getPoolLimits(){let e=this.api.consts.omnipool.maxInRatio.toJSON(),t=this.api.consts.omnipool.maxOutRatio.toJSON(),s=this.api.consts.omnipool.minimumTradingLimit.toJSON();return{maxInRatio:e,maxOutRatio:t,minTradingLimit:s}}};var le=class extends M{isSupported(){return this.api.query.xyk!==void 0}async loadPools(){let t=(await this.api.query.xyk.poolAssets.entries()).map(async([{args:[s]},r])=>{let i=s.toString(),[o,n]=r.unwrap(),[a,l]=await Promise.all([this.getBalance(i,o.toString()),this.getBalance(i,n.toString())]);return{address:i,type:"Xyk",tokens:[{id:o.toString(),balance:a.toString()},{id:n.toString(),balance:l.toString()}],...this.getPoolLimits()}});return Promise.all(t)}async getPoolFees(e,t){return{exchangeFee:this.getExchangeFee()}}getPoolType(){return"Xyk"}subscribePoolChange(e){throw new Error("Pool change subscription not supported!")}getExchangeFee(){return this.api.consts.xyk.getExchangeFee.toJSON()}getPoolLimits(){let e=this.api.consts.xyk.maxInRatio.toJSON(),t=this.api.consts.xyk.maxOutRatio.toJSON(),s=this.api.consts.xyk.minTradingLimit.toJSON();return{maxInRatio:e,maxOutRatio:t,minTradingLimit:s}}};import{blake2AsHex as bt,encodeAddress as ht}from"@polkadot/util-crypto";import{calculate_in_given_out as ot,calculate_out_given_in as nt,calculate_amplification as at,calculate_add_one_asset as lt,calculate_liquidity_out_one_asset as ct,calculate_pool_trade_fee as ut,calculate_shares as mt,calculate_shares_for_amount as pt,calculate_spot_price_with_fee as gt,pool_account_name as dt}from"@galacticcouncil/math-stableswap";var N=class{static getPoolAddress(e){return dt(e)}static calculateAmplification(e,t,s,r,i){return at(e,t,s,r,i)}static calculateInGivenOut(e,t,s,r,i,o){return ot(e,t,s,r,i,o)}static calculateAddOneAsset(e,t,s,r,i,o){return lt(e,t,s,r,i,o)}static calculateSharesForAmount(e,t,s,r,i,o){return pt(e,t,s,r,i,o)}static calculateOutGivenIn(e,t,s,r,i,o){return nt(e,t,s,r,i,o)}static calculateLiquidityOutOneAsset(e,t,s,r,i,o){return ct(e,t,s,r,i,o)}static calculateShares(e,t,s,r,i){return mt(e,t,s,r,i)}static calculateSpotPriceWithFee(e,t,s,r,i,o,n){return gt(e,t,s,r,i,o,n)}static calculatePoolTradeFee(e,t,s){return ut(e,t,s)}};var ce=class extends M{stablePools=new Map([]);isSupported(){return this.api.query.stableswap!==void 0}async loadPools(){let[e,t]=await Promise.all([this.api.query.stableswap.pools.entries(),this.api.query.system.number()]),s=t.toNumber(),r=e.map(async([{args:[i]},o])=>{let n=o.unwrap(),a=i.toString(),l=this.getPoolAddress(a),[c,u]=await Promise.all([this.getPoolDelta(a,n,s.toString()),this.getPoolTokens(l,a,n)]);return this.stablePools.set(l,n),{address:l,id:a,type:"Stableswap",fee:k(n.fee.toNumber()),tokens:u,...c,...this.getPoolLimits()}});return Promise.all(r)}async getPoolFees(e,t){return{fee:this.pools.find(r=>r.address===t).fee}}getPoolType(){return"Stableswap"}async subscribePoolChange(e){return this.api.query.system.number(async t=>{let s=t.toNumber(),r=this.stablePools.get(e.address),i=await this.getPoolDelta(e.id,r,s.toString());Object.assign(e,i)})}async getPoolDelta(e,t,s){let{initialAmplification:r,finalAmplification:i,initialBlock:o,finalBlock:n}=t,a=N.calculateAmplification(r.toString(),i.toString(),o.toString(),n.toString(),s),l=await this.api.query.tokens.totalIssuance(e);return{amplification:a,totalIssuance:l.toString()}}async getPoolTokens(e,t,s){let{assets:r}=s,i=r.map(async a=>{let[l,c]=await Promise.all([this.api.query.stableswap.assetTradability(t,a.toString()),this.getBalance(e,a.toString())]);return{id:a.toString(),tradeable:l.bits.toNumber(),balance:c.toString()}}),o=await Promise.all(i),n=await this.api.query.omnipool.assets(t);if(n.isSome){let{tradable:a}=n.unwrap(),l=await this.getBalance(oe,t);o.push({id:t,tradeable:a.bits.toNumber(),balance:l.toString()})}return o}getPoolAddress(e){let t=Number(e),s=N.getPoolAddress(t);return ht(bt(s),$)}getPoolLimits(){return{maxInRatio:0,maxOutRatio:0,minTradingLimit:this.api.consts.stableswap.minTradingLimit.toJSON()}}};function Pe(p){return p.map(({assetIn:e,assetOut:t,pool:s,poolId:r})=>s==="Stableswap"?{pool:{Stableswap:r},assetIn:e,assetOut:t}:{pool:s,assetIn:e,assetOut:t})}var ue=class extends Error{constructor(e){super(),this.message=`${e} pool invalid`,this.name="PoolNotFound"}},Oe=class extends Error{constructor(e,t){super(),this.message=`${e} pool missing ${t}`,this.name="PoolConfigNotFound"}},X=class extends Error{constructor(e,t){super(),this.message=`Route from ${e} to ${t} not found in pool configuration`,this.name="RouteNotFound"}},we=class extends Error{constructor(e){super(),this.message=`Asset ${e} not available in current network`,this.name="AssetNotFound"}},Ie=class extends Error{constructor(e){super(),this.message=`Storage missing ${e}`,this.name="StorageConfigNotFound"}},xe=class extends Error{constructor(e){super(),this.message=`Subscription type "${e}" not supported`,this.name="SubscriptionNotSupported"}},Ae=class extends Error{constructor(e){super(),this.message=`${e}`,this.name="ProviderConfigNotFound"}};var Z=class{api;assetClient;xykClient;omniClient;lbpClient;stableClient;clients=[];onChainAssets=[];memRegistry=Pt(e=>(console.log("Registry mem sync",e,"\u2705"),this.syncRegistry()));constructor(e){this.api=e,this.assetClient=new H(this.api),this.xykClient=new le(this.api),this.omniClient=new ae(this.api),this.lbpClient=new ne(this.api),this.stableClient=new ce(this.api),this.clients=[this.xykClient,this.omniClient,this.lbpClient,this.stableClient]}get assets(){return this.onChainAssets}get isRegistrySynced(){return this.onChainAssets.length>0}async syncRegistry(e){let t=await this.assetClient.getOnChainAssets(!1,e);this.clients.forEach(s=>s.withAssets(t)),this.onChainAssets=t}async getPools(e){return this.isRegistrySynced||await this.memRegistry(1),e.length==0?(await Promise.all(this.clients.filter(r=>r.isSupported()).map(r=>r.getPoolsMem()))).flat():(await Promise.all(this.clients.filter(s=>e.some(r=>r===s.getPoolType())).map(s=>s.getPoolsMem()))).flat()}unsubscribe(){this.xykClient.unsubscribe(),this.omniClient.unsubscribe(),this.lbpClient.unsubscribe(),this.stableClient.unsubscribe()}async getPoolFees(e,t){switch(t.type){case"Xyk":return this.xykClient.getPoolFees(e,t.address);case"Omnipool":return this.omniClient.getPoolFees(e,t.address);case"Lbp":return this.lbpClient.getPoolFees(e,t.address);case"Stableswap":return this.stableClient.getPoolFees(e,t.address);default:throw new ue(t.type)}}isDirectOmnipoolTrade(e){return e.length==1&&e[0].pool=="Omnipool"}buildBuyTx(e,t,s,r,i){let o;this.isDirectOmnipoolTrade(i)?o=this.api.tx.omnipool.buy(t,e,s.toFixed(),r.toFixed()):o=this.api.tx.router.buy(e,t,s.toFixed(),r.toFixed(),Pe(i));let n=()=>o;return{hex:o.toHex(),name:"RouterBuy",get:n}}buildSellTx(e,t,s,r,i){let o;this.isDirectOmnipoolTrade(i)?o=this.api.tx.omnipool.sell(e,t,s.toFixed(),r.toFixed()):o=this.api.tx.router.sell(e,t,s.toFixed(),r.toFixed(),Pe(i));let n=()=>o;return{hex:o.toHex(),name:"RouterSell",get:n}}};import{LRUCache as ft}from"@thi.ng/cache";var fe=class extends Z{feeCache;disconnectSubscribeNewHeads=null;constructor(e){super(e),this.feeCache=new ft(null),this.api.rpc.chain.subscribeNewHeads(async t=>{this.feeCache.release()}).then(t=>{this.disconnectSubscribeNewHeads=t})}async getPoolFees(e,t){let s=[t.address,e.assetIn,e.assetOut].join("-");if(this.feeCache.has(s))return this.feeCache.get(s);{let i=await super.getPoolFees(e,t);return this.feeCache.set(s,i),i}}async destroy(){console.log(`Destroying pool cache!
2
+ Items: [${this.feeCache.length}]`),this.feeCache.release(),this.disconnectSubscribeNewHeads?.()}};var K=class p{type;address;tokens;maxInRatio;maxOutRatio;minTradingLimit;fee;repayFeeApply;static fromPool(e){return new p(e.address,e.tokens,e.maxInRatio,e.maxOutRatio,e.minTradingLimit,e.fee,e.repayFeeApply)}constructor(e,t,s,r,i,o,n){this.type="Lbp",this.address=e,this.tokens=t,this.maxInRatio=s,this.maxOutRatio=r,this.minTradingLimit=i,this.fee=o,this.repayFeeApply=n}validatePair(e,t){return!0}parsePair(e,t){let s=new Map(this.tokens.map(a=>[a.id,a])),r=s.get(e),i=s.get(t);if(r==null)throw new Error("Pool does not contain tokenIn");if(i==null)throw new Error("Pool does not contain tokenOut");let o=m(r.balance),n=m(i.balance);return{assetIn:e,assetOut:t,balanceIn:o,balanceOut:n,decimalsIn:r.decimals,decimalsOut:i.decimals,weightIn:r.weight,weightOut:i.weight}}validateAndBuy(e,t,s){let r=this.tokens[0].id,i=[];t.isLessThan(this.minTradingLimit)&&i.push("InsufficientTradingAmount");let o=e.balanceOut.div(this.maxOutRatio);if(t.isGreaterThan(o)&&i.push("MaxOutRatioExceeded"),r===e.assetOut){let n=this.calculateTradeFee(t,s),a=x(this.repayFeeApply?s.repayFee:s.exchangeFee),l=t.plus(n),c=this.calculateInGivenOut(e,l),u=e.balanceIn.div(this.maxInRatio);return c.isGreaterThan(u)&&i.push("MaxInRatioExceeded"),{amountIn:c,calculatedIn:c,amountOut:t,feePct:a,errors:i}}else{let n=this.calculateInGivenOut(e,t),a=e.balanceIn.div(this.maxInRatio);return n.isGreaterThan(a)&&i.push("MaxInRatioExceeded"),{amountIn:n,calculatedIn:n,amountOut:t,feePct:0,errors:i}}}validateAndSell(e,t,s){let r=this.tokens[0].id,i=[];t.isLessThan(this.minTradingLimit)&&i.push("InsufficientTradingAmount");let o=e.balanceIn.div(this.maxInRatio);if(t.isGreaterThan(o)&&i.push("MaxInRatioExceeded"),r===e.assetIn){let n=this.calculateOutGivenIn(e,t),a=e.balanceOut.div(this.maxOutRatio);return n.isGreaterThan(a)&&i.push("MaxOutRatioExceeded"),{amountIn:t,calculatedOut:n,amountOut:n,feePct:0,errors:i}}else{let n=this.calculateOutGivenIn(e,t),a=this.calculateTradeFee(n,s),l=x(this.repayFeeApply?s.repayFee:s.exchangeFee),c=n.minus(a),u=e.balanceOut.div(this.maxOutRatio);return c.isGreaterThan(u)&&i.push("MaxOutRatioExceeded"),{amountIn:t,calculatedOut:n,amountOut:c,feePct:l,errors:i}}}calculateInGivenOut(e,t){let s=D.calculateInGivenOut(e.balanceIn.toString(),e.balanceOut.toString(),e.weightIn.toString(),e.weightOut.toString(),t.toFixed(0)),r=m(s);return r.isNegative()?P:r}calculateOutGivenIn(e,t){let s=D.calculateOutGivenIn(e.balanceIn.toString(),e.balanceOut.toString(),e.weightIn.toString(),e.weightOut.toString(),t.toFixed(0)),r=m(s);return r.isNegative()?P:r}spotPriceInGivenOut(e){let t=D.getSpotPrice(e.balanceOut.toString(),e.balanceIn.toString(),e.weightOut.toString(),e.weightIn.toString(),I(v,e.decimalsOut).toString());return m(t)}spotPriceOutGivenIn(e){let t=D.getSpotPrice(e.balanceIn.toString(),e.balanceOut.toString(),e.weightIn.toString(),e.weightOut.toString(),I(v,e.decimalsIn).toString());return m(t)}calculateTradeFee(e,t){let s=D.calculatePoolTradeFee(e.toString(),this.repayFeeApply?t.repayFee[0]:t.exchangeFee[0],this.repayFeeApply?t.repayFee[1]:t.exchangeFee[1]);return m(s)}};var Q=class p{type;address;tokens;maxInRatio;maxOutRatio;minTradingLimit;hubAssetId;static fromPool(e){return new p(e.address,e.tokens,e.maxInRatio,e.maxOutRatio,e.minTradingLimit,e.hubAssetId)}constructor(e,t,s,r,i,o){this.type="Omnipool",this.address=e,this.tokens=t,this.maxInRatio=s,this.maxOutRatio=r,this.minTradingLimit=i,this.hubAssetId=o}validatePair(e,t){return this.hubAssetId!=t}parsePair(e,t){let s=new Map(this.tokens.map(c=>[c.id,c])),r=s.get(e),i=s.get(t);if(r==null)throw new Error("Pool does not contain tokenIn");if(i==null)throw new Error("Pool does not contain tokenOut");let o=m(r.balance),n=m(i.balance),a=m(r.existentialDeposit),l=m(i.existentialDeposit);return{assetIn:e,assetOut:t,hubReservesIn:r.hubReserves,hubReservesOut:i.hubReserves,sharesIn:r.shares,sharesOut:i.shares,decimalsIn:r.decimals,decimalsOut:i.decimals,balanceIn:o,balanceOut:n,tradeableIn:r.tradeable,tradeableOut:i.tradeable,assetInED:a,assetOutED:l}}validateAndBuy(e,t,s){let r=this.calculateInGivenOut(e,t),i=this.calculateInGivenOut(e,t,s),o=i.minus(r),n=r===P?P:o.div(r).multipliedBy(100).decimalPlaces(2),a=[],l=B.isSellAllowed(e.tradeableIn),c=B.isBuyAllowed(e.tradeableOut);(!l||!c)&&a.push("TradeNotAllowed"),(t.isLessThan(this.minTradingLimit)||r.isLessThan(e.assetInED))&&a.push("InsufficientTradingAmount");let u=e.balanceOut.div(this.maxOutRatio);t.isGreaterThan(u)&&a.push("MaxOutRatioExceeded");let b=e.balanceIn.div(this.maxInRatio);return i.isGreaterThan(b)&&a.push("MaxInRatioExceeded"),{amountIn:i,calculatedIn:r,amountOut:t,feePct:n.toNumber(),errors:a}}validateAndSell(e,t,s){let r=this.calculateOutGivenIn(e,t),i=this.calculateOutGivenIn(e,t,s),n=r.minus(i).div(r).multipliedBy(100).decimalPlaces(2),a=[],l=B.isSellAllowed(e.tradeableIn),c=B.isBuyAllowed(e.tradeableOut);(!l||!c)&&a.push("TradeNotAllowed"),(t.isLessThan(this.minTradingLimit)||r.isLessThan(e.assetOutED))&&a.push("InsufficientTradingAmount");let u=e.balanceIn.div(this.maxInRatio);t.isGreaterThan(u)&&a.push("MaxInRatioExceeded");let b=e.balanceOut.div(this.maxOutRatio);return i.isGreaterThan(b)&&a.push("MaxOutRatioExceeded"),{amountIn:t,calculatedOut:r,amountOut:i,feePct:n.toNumber(),errors:a}}calculateInGivenOut(e,t,s){if(e.assetIn==this.hubAssetId)return this.calculateLrnaInGivenOut(e,t,s);let r=B.calculateInGivenOut(e.balanceIn.toString(),e.hubReservesIn.toString(),e.sharesIn.toString(),e.balanceOut.toString(),e.hubReservesOut.toString(),e.sharesOut.toString(),t.toFixed(0),s?R(s.assetFee).toString():P.toString(),s?R(s.protocolFee).toString():P.toString()),i=m(r);return i.isNegative()?P:i}calculateLrnaInGivenOut(e,t,s){let r=B.calculateLrnaInGivenOut(e.balanceOut.toString(),e.hubReservesOut.toString(),e.sharesOut.toString(),t.toFixed(0),s?R(s.assetFee).toString():P.toString()),i=m(r);return i.isNegative()?P:i}calculateOutGivenIn(e,t,s){if(e.assetIn==this.hubAssetId)return this.calculateOutGivenLrnaIn(e,t,s);let r=B.calculateOutGivenIn(e.balanceIn.toString(),e.hubReservesIn.toString(),e.sharesIn.toString(),e.balanceOut.toString(),e.hubReservesOut.toString(),e.sharesOut.toString(),t.toFixed(0),s?R(s.assetFee).toString():P.toString(),s?R(s.protocolFee).toString():P.toString()),i=m(r);return i.isNegative()?P:i}calculateOutGivenLrnaIn(e,t,s){let r=B.calculateOutGivenLrnaIn(e.balanceOut.toString(),e.hubReservesOut.toString(),e.sharesOut.toString(),t.toFixed(0),s?R(s.assetFee).toString():P.toString()),i=m(r);return i.isNegative()?P:i}spotPriceInGivenOut(e){if(e.assetIn==this.hubAssetId)return this.spotPriceLrnaInGivenOut(e);let t=B.calculateSpotPrice(e.balanceOut.toString(),e.hubReservesOut.toString(),e.balanceIn.toString(),e.hubReservesIn.toString());return m(t).shiftedBy(-1*(j-e.decimalsOut)).decimalPlaces(0,1)}spotPriceLrnaInGivenOut(e){let t=B.calculateLrnaSpotPrice(e.hubReservesOut.toString(),e.balanceOut.toString());return m(t).shiftedBy(-1*(j-e.decimalsOut)).decimalPlaces(0,1)}spotPriceOutGivenIn(e){if(e.assetIn==this.hubAssetId)return this.spotPriceOutGivenLrnaIn(e);let t=B.calculateSpotPrice(e.balanceIn.toString(),e.hubReservesIn.toString(),e.balanceOut.toString(),e.hubReservesOut.toString());return m(t).shiftedBy(-1*(j-e.decimalsIn)).decimalPlaces(0,1)}spotPriceOutGivenLrnaIn(e){let t=B.calculateLrnaSpotPrice(e.balanceOut.toString(),e.hubReservesOut.toString());return m(t).shiftedBy(-1*(j-e.decimalsIn)).decimalPlaces(0,1)}};var V=class p{type;address;tokens;maxInRatio;maxOutRatio;minTradingLimit;amplification;id;fee;totalIssuance;static fromPool(e){return new p(e.address,e.tokens,e.maxInRatio,e.maxOutRatio,e.minTradingLimit,e.amplification,e.id,e.fee,e.totalIssuance)}constructor(e,t,s,r,i,o,n,a,l){this.type="Stableswap",this.address=e,this.tokens=t,this.maxInRatio=s,this.maxOutRatio=r,this.minTradingLimit=i,this.amplification=o,this.id=n,this.fee=a,this.totalIssuance=l}validatePair(e,t){return!0}parsePair(e,t){let s=new Map(this.tokens.map(c=>[c.id,c])),r=s.get(e),i=s.get(t);if(r==null)throw new Error("Pool does not contain tokenIn");if(i==null)throw new Error("Pool does not contain tokenOut");let o=m(r.balance),n=m(i.balance),a=m(r.existentialDeposit),l=m(i.existentialDeposit);return{assetIn:e,assetOut:t,balanceIn:o,balanceOut:n,decimalsIn:r.decimals,decimalsOut:i.decimals,tradeableIn:this.id===e?de:r.tradeable,tradeableOut:this.id===t?de:i.tradeable,assetInED:a,assetOutED:l}}validateAndBuy(e,t,s){let r=this.calculateInGivenOut(e,t),i=this.calculateInGivenOut(e,t,s),o=x(s.fee),n=[],a=B.isSellAllowed(e.tradeableIn),l=B.isBuyAllowed(e.tradeableOut);return(!a||!l)&&n.push("TradeNotAllowed"),(t.isLessThan(this.minTradingLimit)||r.isLessThan(e.assetInED))&&n.push("InsufficientTradingAmount"),{amountIn:i,calculatedIn:r,amountOut:t,feePct:o,errors:n}}validateAndSell(e,t,s){let r=this.calculateOutGivenIn(e,t),i=this.calculateOutGivenIn(e,t,s),o=x(s.fee),n=[],a=B.isSellAllowed(e.tradeableIn),l=B.isBuyAllowed(e.tradeableOut);return(!a||!l)&&n.push("TradeNotAllowed"),(t.isLessThan(this.minTradingLimit)||r.isLessThan(e.assetOutED))&&n.push("InsufficientTradingAmount"),{amountIn:t,calculatedOut:r,amountOut:i,feePct:o,errors:n}}calculateIn(e,t,s){let r=N.calculateInGivenOut(this.getReserves(),Number(e.assetIn),Number(e.assetOut),t.toFixed(0),this.amplification,s?R(s.fee).toString():P.toString()),i=m(r);return i.isNegative()?P:i}calculateAddOneAsset(e,t,s){let r=N.calculateAddOneAsset(this.getReserves(),t.toFixed(0),Number(e.assetIn),this.amplification,this.totalIssuance,s?R(s.fee).toString():P.toString()),i=m(r);return i.isNegative()?P:i}calculateSharesForAmount(e,t,s){let r=N.calculateSharesForAmount(this.getReserves(),Number(e.assetOut),t.toFixed(0),this.amplification,this.totalIssuance,s?R(s.fee).toString():P.toString()),i=m(r);return i.isNegative()?P:i}calculateInGivenOut(e,t,s){return e.assetOut==this.id?this.calculateAddOneAsset(e,t,s):e.assetIn==this.id?this.calculateSharesForAmount(e,t,s):this.calculateIn(e,t,s)}spotPriceInGivenOut(e){let t=N.calculateSpotPriceWithFee(this.id,this.getReserves(),this.amplification,e.assetOut,e.assetIn,this.totalIssuance,"0");if(e.assetOut==this.id)return m(t);if(e.assetIn==this.id){let r=I(v,e.decimalsIn-e.decimalsOut);return m(t).div(r)}let s=I(v,18-e.decimalsIn);return m(t).div(s)}calculateOut(e,t,s){let r=N.calculateOutGivenIn(this.getReserves(),Number(e.assetIn),Number(e.assetOut),t.toFixed(0),this.amplification,s?R(s.fee).toString():P.toString()),i=m(r);return i.isNegative()?P:i}calculateWithdrawOneAsset(e,t,s){let r=N.calculateLiquidityOutOneAsset(this.getReserves(),t.toFixed(0),Number(e.assetOut),this.amplification,this.totalIssuance,s?R(s.fee).toString():P.toString()),i=m(r);return i.isNegative()?P:i}calculateShares(e,t,s){let r=N.calculateShares(this.getReserves(),this.getAssets(e.assetIn,t),this.amplification,this.totalIssuance,s?R(s.fee).toString():P.toString()),i=m(r);return i.isNegative()?P:i}calculateOutGivenIn(e,t,s){return e.assetIn==this.id?this.calculateWithdrawOneAsset(e,t,s):e.assetOut==this.id?this.calculateShares(e,t,s):this.calculateOut(e,t,s)}spotPriceOutGivenIn(e){let t=N.calculateSpotPriceWithFee(this.id,this.getReserves(),this.amplification,e.assetIn,e.assetOut,this.totalIssuance,"0");if(e.assetIn==this.id)return m(t);if(e.assetOut==this.id){let r=I(v,e.decimalsOut-e.decimalsIn);return m(t).div(r)}let s=I(v,18-e.decimalsOut);return m(t).div(s)}calculateTradeFee(e,t){let s=N.calculatePoolTradeFee(e.toString(),t.fee[0],t.fee[1]);return m(s)}getReserves(){let e=this.tokens.filter(t=>t.id!=this.id).map(({id:t,balance:s,decimals:r})=>({asset_id:Number(t),amount:s,decimals:r}));return JSON.stringify(e)}getAssets(e,t){let s={asset_id:Number(e),amount:t.toFixed(0)};return JSON.stringify([s])}};import{calculate_in_given_out as yt,calculate_out_given_in as St,calculate_pool_trade_fee as Bt,get_spot_price as Ot,calculate_liquidity_in as wt,calculate_shares as It,calculate_spot_price as xt,calculate_spot_price_with_fee as At,calculate_liquidity_out_asset_a as Ft,calculate_liquidity_out_asset_b as Nt}from"@galacticcouncil/math-xyk";var G=class{static getSpotPrice(e,t,s){return Ot(e,t,s)}static calculateInGivenOut(e,t,s){return yt(e,t,s)}static calculateOutGivenIn(e,t,s){return St(e,t,s)}static calculatePoolTradeFee(e,t,s){return Bt(e,t,s)}static calculateLiquidityIn(e,t,s){return wt(e,t,s)}static calculateSpotPrice(e,t){return xt(e,t)}static calculateSpotPriceWithFee(e,t,s,r){return At(e,t,s,r)}static calculateShares(e,t,s){return It(e,t,s)}static calculateLiquidityOutAssetA(e,t,s,r){return Ft(e,t,s,r)}static calculateLiquidityOutAssetB(e,t,s,r){return Nt(e,t,s,r)}};var ee=class p{type;address;tokens;maxInRatio;maxOutRatio;minTradingLimit;static fromPool(e){return new p(e.address,e.tokens,e.maxInRatio,e.maxOutRatio,e.minTradingLimit)}constructor(e,t,s,r,i){this.type="Xyk",this.address=e,this.tokens=t,this.maxInRatio=s,this.maxOutRatio=r,this.minTradingLimit=i}validatePair(e,t){return!0}parsePair(e,t){let s=new Map(this.tokens.map(c=>[c.id,c])),r=s.get(e),i=s.get(t);if(r==null)throw new Error("Pool does not contain tokenIn");if(i==null)throw new Error("Pool does not contain tokenOut");let o=m(r.balance),n=m(i.balance),a=m(r.existentialDeposit),l=m(i.existentialDeposit);return{assetIn:e,assetOut:t,decimalsIn:r.decimals,decimalsOut:i.decimals,balanceIn:o,balanceOut:n,assetInED:a,assetOutED:l}}validateAndBuy(e,t,s){let r=this.calculateInGivenOut(e,t),i=this.calculateTradeFee(r,s),o=x(s.exchangeFee),n=r.plus(i),a=[];(t.isLessThan(this.minTradingLimit)||r.isLessThan(e.assetInED))&&a.push("InsufficientTradingAmount");let l=e.balanceOut.div(this.maxOutRatio);t.isGreaterThan(l)&&a.push("MaxOutRatioExceeded");let c=e.balanceIn.div(this.maxInRatio);return n.isGreaterThan(c)&&a.push("MaxInRatioExceeded"),{amountIn:n,calculatedIn:r,amountOut:t,feePct:o,errors:a}}validateAndSell(e,t,s){let r=this.calculateOutGivenIn(e,t),i=this.calculateTradeFee(r,s),o=x(s.exchangeFee),n=r.minus(i),a=[];(t.isLessThan(this.minTradingLimit)||r.isLessThan(e.assetOutED))&&a.push("InsufficientTradingAmount");let l=e.balanceIn.div(this.maxInRatio);t.isGreaterThan(l)&&a.push("MaxInRatioExceeded");let c=e.balanceOut.div(this.maxOutRatio);return n.isGreaterThan(c)&&a.push("MaxOutRatioExceeded"),{amountIn:t,calculatedOut:r,amountOut:n,feePct:o,errors:a}}calculateInGivenOut(e,t){let s=G.calculateInGivenOut(e.balanceIn.toString(),e.balanceOut.toString(),t.toFixed(0)),r=m(s);return r.isNegative()?P:r}calculateOutGivenIn(e,t){let s=G.calculateOutGivenIn(e.balanceIn.toString(),e.balanceOut.toString(),t.toFixed(0)),r=m(s);return r.isNegative()?P:r}spotPriceInGivenOut(e){let t=G.calculateSpotPrice(e.balanceOut.toString(),e.balanceIn.toString()),s=I(v,18-e.decimalsOut);return m(t).div(s)}spotPriceOutGivenIn(e){let t=G.calculateSpotPrice(e.balanceIn.toString(),e.balanceOut.toString()),s=I(v,18-e.decimalsIn);return m(t).div(s)}calculateTradeFee(e,t){let s=G.calculatePoolTradeFee(e.toString(),t.exchangeFee[0],t.exchangeFee[1]);return m(s)}};var te=class{static get(e){switch(e.type){case"Xyk":return ee.fromPool(e);case"Omnipool":return Q.fromPool(e);case"Lbp":return K.fromPool(e);case"Stableswap":return V.fromPool(e);default:throw new Error("Pool type "+e.type+" is not supported yet")}}};var U=class{routeSuggester;routerOptions;poolService;defaultRouterOptions={includeOnly:[]};constructor(e,t){this.poolService=e,this.routeSuggester=new z,this.routerOptions={...this.defaultRouterOptions,...t}}async getPools(){let e=this.routerOptions.includeOnly;return await this.poolService.getPools(e)}async getAllAssets(){let e=await this.getPools();if(e.length===0)throw new Error("No pools configured");let t=await this.getAssets(e);return[...new Map(t).values()]}async getAssetPairs(e){let t=await this.getPools();if(t.length===0)throw new Error("No pools configured");let{assets:s,poolsMap:r}=await this.validateToken(e,t),o=this.getPaths(e,null,r,t).map(n=>n[n.length-1].assetOut);return this.toAssets([...new Set(o)],s)}async getAllPaths(e,t){let s=await this.getPools();if(s.length===0)throw new Error("No pools configured");let{poolsMap:r}=await this.validateTokenPair(e,t,s);return this.getPaths(e,t,r,s)}async getAssets(e){let t=e.map(s=>s.tokens.map(r=>({id:r.id,name:r.name,symbol:r.symbol,decimals:r.decimals,icon:r.icon,type:r.type,isSufficient:r.isSufficient,existentialDeposit:r.existentialDeposit,meta:r.meta,location:r.location,isWhiteListed:r.isWhiteListed}))).flat();return new Map(t.map(s=>[s.id,s]))}getPaths(e,t,s,r){return this.routeSuggester.getProposals(e,t,r).filter(n=>this.validPath(n,s)).map(n=>this.toHops(n,s))}async validateTokenPair(e,t,s){let r=await this.getAssets(s);if(r.get(e)==null)throw new Error(e+" is not supported token");if(r.get(t)==null)throw new Error(t+" is not supported token");let i=this.getPoolMap(s);return{assets:r,poolsMap:i}}async validateToken(e,t){let s=await this.getAssets(t);if(s.get(e)==null)throw new Error(e+" is not supported token");let r=this.getPoolMap(t);return{assets:s,poolsMap:r}}getPoolMap(e){return new Map(e.map(t=>[t.address,te.get(t)]))}validPath(e,t){return e.length>0&&e.map(s=>this.validEdge(s,t)).reduce((s,r)=>s&&r)}validEdge([e,t,s],r){return r.get(e)?.validatePair(t,s)||!1}toHops(e,t){return e.map(([s,r,i])=>{let o=t.get(s);return{poolAddress:s,poolId:o?.id,pool:o?.type,assetIn:r,assetOut:i}})}toAssets(e,t){return e.map(s=>t.get(s))}};function qo(p,e){return p.minus(e).abs().div(p.plus(e).div(2)).multipliedBy(100).decimalPlaces(2)}function se(p,e){return p.minus(e).div(e).multipliedBy(100).decimalPlaces(2)}function Fe(p,e){return v.minus(e.div(p)).multipliedBy(100).decimalPlaces(2)}function Ne(p,e){return e.div(p).minus(v).multipliedBy(100).decimalPlaces(2)}var me=class extends U{isDirectTrade(e){return e.length==1}findBestSellRoute(e){let t=e.sort((s,r)=>{let i=s[s.length-1].amountOut,o=r[r.length-1].amountOut;return i.isGreaterThan(o)?-1:1});return t.find(s=>s.every(r=>r.errors.length==0))||t[0]}getRouteFeeRange(e){if(e.filter(s=>s.tradeFeeRange).length>0){let s=e.map(i=>i.tradeFeeRange?.[0]??i.tradeFeePct).reduce((i,o)=>i+o),r=e.map(i=>i.tradeFeeRange?.[1]??i.tradeFeePct).reduce((i,o)=>i+o);return[s,r]}}getPoolFeeRange(e){let t=e.min?x(e.min):void 0,s=e.max?x(e.max):void 0;if(t&&s)return[t,s]}async getBestSell(e,t,s){return this.getSell(e,t,s)}async getSell(e,t,s,r){let i=await super.getPools();if(i.length===0)throw new Error("No pools configured");let{poolsMap:o}=await super.validateTokenPair(e,t,i),n=super.getPaths(e,t,o,i);if(n.length===0)throw new X(e,t);let a;if(r)a=await this.toSellSwaps(s,r,o);else{let w=n.map(async pe=>await this.toSellSwaps(s,pe,o)),L=await Promise.all(w);a=this.findBestSellRoute(L)}let l=a[0],c=a[a.length-1],u=this.isDirectTrade(a),b=a.map(w=>w.spotPrice.shiftedBy(-1*w.assetOutDecimals)).reduce((w,L)=>w.multipliedBy(L)),d=I(b,c.assetOutDecimals),g=u?c.calculatedOut:this.calculateDelta0Y(l.amountIn,a,o),h=c.amountOut,f=u?c.tradeFeePct:Fe(g,h).toNumber(),y=g.minus(h),S=this.getRouteFeeRange(a),T=l.amountIn.shiftedBy(-1*l.assetInDecimals).multipliedBy(d),A=se(g,T),C=w=>this.poolService.buildSellTx(e,t,l.amountIn,w,a.map(L=>L));return{type:"Sell",amountIn:l.amountIn,amountOut:c.amountOut,spotPrice:d,tradeFee:y,tradeFeePct:f,tradeFeeRange:S,priceImpactPct:A.toNumber(),swaps:a,toTx:C,toHuman(){return{type:"Sell",amountIn:F(l.amountIn,l.assetInDecimals),amountOut:F(c.amountOut,c.assetOutDecimals),spotPrice:F(d,c.assetOutDecimals),tradeFee:F(y,c.assetOutDecimals),tradeFeePct:f,tradeFeeRange:S,priceImpactPct:A.toNumber(),swaps:a.map(w=>w.toHuman())}}}}calculateDelta0Y(e,t,s){let r=[];for(let i=0;i<t.length;i++){let o=t[i],n=s.get(o.poolAddress);if(n==null)throw new Error("Pool does not exit");let a=n.parsePair(o.assetIn,o.assetOut),l;i>0?l=r[i-1]:l=e;let c=n.calculateOutGivenIn(a,l);r.push(c)}return r[r.length-1]}async toSellSwaps(e,t,s){let r=[];for(let i=0;i<t.length;i++){let o=t[i],n=s.get(o.poolAddress);if(n==null)throw new Error("Pool does not exit");let a=n.parsePair(o.assetIn,o.assetOut),l;i>0?l=r[i-1].amountOut:l=I(m(e),a.decimalsIn).decimalPlaces(0,1);let c=await this.poolService.getPoolFees(a,n),{amountOut:u,calculatedOut:b,feePct:d,errors:g}=n.validateAndSell(a,l,c),h=this.getPoolFeeRange(c),f=n.spotPriceOutGivenIn(a),y=l.shiftedBy(-1*a.decimalsIn).multipliedBy(f),S=se(b,y);r.push({...o,assetInDecimals:a.decimalsIn,assetOutDecimals:a.decimalsOut,amountIn:l,calculatedOut:b,amountOut:u,spotPrice:f,tradeFeePct:d,tradeFeeRange:h,priceImpactPct:S.toNumber(),errors:g,toHuman(){return{...o,amountIn:F(l,a.decimalsIn),calculatedOut:F(b,a.decimalsOut),amountOut:F(u,a.decimalsOut),spotPrice:F(f,a.decimalsOut),tradeFeePct:d,tradeFeeRange:h,priceImpactPct:S.toNumber(),errors:g}}})}return r}async getMostLiquidRoute(e,t){let s=await super.getPools(),{poolsMap:r}=await super.validateTokenPair(e,t,s),i=super.getPaths(e,t,r,s);if(i.length===0)throw new X(e,t);let o=s.map(g=>g.tokens.find(h=>h.id===e)).filter(g=>!!g).sort((g,h)=>Number(h.balance)-Number(g.balance)),{balance:n,decimals:a}=o[0],c=m(n).shiftedBy(-1*a).div(100).multipliedBy(.1),u=i.map(async g=>await this.toSellSwaps(c,g,r)),b=await Promise.all(u);return this.findBestSellRoute(b).map(g=>({poolAddress:g.poolAddress,poolId:g?.poolId,pool:g.pool,assetIn:g.assetIn,assetOut:g.assetOut}))}async getBestSpotPrice(e,t){let s=await super.getPools();if(s.length===0)throw new Error("No pools configured");let{poolsMap:r}=await super.validateTokenPair(e,t,s);if(super.getPaths(e,t,r,s).length===0)return Promise.resolve(void 0);let o=await this.getMostLiquidRoute(e,t),n=await this.toSellSwaps("1",o,r),a=n.map(u=>u.spotPrice.shiftedBy(-1*u.assetOutDecimals)).reduce((u,b)=>u.multipliedBy(b)),l=n[n.length-1].assetOutDecimals;return{amount:I(a,l),decimals:l}}findBestBuyRoute(e){let t=e.sort((s,r)=>{let i=s[0].amountIn,o=r[0].amountIn;return i.isGreaterThan(o)?1:-1});return t.find(s=>s.every(r=>r.errors.length==0))||t[0]}async getBestBuy(e,t,s){return this.getBuy(e,t,s)}async getBuy(e,t,s,r){let i=await super.getPools();if(i.length===0)throw new Error("No pools configured");let{poolsMap:o}=await super.validateTokenPair(e,t,i),n=super.getPaths(e,t,o,i);if(n.length===0)throw new X(e,t);let a;if(r)a=await this.toBuySwaps(s,r,o);else{let w=n.map(async pe=>await this.toBuySwaps(s,pe,o)),L=await Promise.all(w);a=this.findBestBuyRoute(L)}let l=a[a.length-1],c=a[0],u=this.isDirectTrade(a),b=a.map(w=>w.spotPrice.shiftedBy(-1*w.assetInDecimals)).reduce((w,L)=>w.multipliedBy(L)),d=I(b,c.assetInDecimals),g=u?c.calculatedIn:this.calculateDelta0X(l.amountOut,a,o),h=c.amountIn,f=u?c.tradeFeePct:Ne(g,h).toNumber(),y=h.minus(g),S=this.getRouteFeeRange(a),T=l.amountOut.shiftedBy(-1*l.assetOutDecimals).multipliedBy(d),A;g.isZero()?A=-100:A=se(T,g).toNumber();let C=w=>this.poolService.buildBuyTx(e,t,l.amountOut,w,a.map(L=>L));return{type:"Buy",amountOut:l.amountOut,amountIn:c.amountIn,spotPrice:d,tradeFee:y,tradeFeePct:f,tradeFeeRange:S,priceImpactPct:A,swaps:a,toTx:C,toHuman(){return{type:"Buy",amountOut:F(l.amountOut,l.assetOutDecimals),amountIn:F(c.amountIn,c.assetInDecimals),spotPrice:F(d,c.assetInDecimals),tradeFee:F(y,c.assetInDecimals),tradeFeePct:f,tradeFeeRange:S,priceImpactPct:A,swaps:a.map(w=>w.toHuman())}}}}calculateDelta0X(e,t,s){let r=[];for(let i=t.length-1;i>=0;i--){let o=t[i],n=s.get(o.poolAddress);if(n==null)throw new Error("Pool does not exit");let a=n.parsePair(o.assetIn,o.assetOut),l;i==t.length-1?l=e:l=r[0];let c=n.calculateInGivenOut(a,l);r.unshift(c)}return r[0]}async toBuySwaps(e,t,s){let r=[];for(let i=t.length-1;i>=0;i--){let o=t[i],n=s.get(o.poolAddress);if(n==null)throw new Error("Pool does not exit");let a=n.parsePair(o.assetIn,o.assetOut),l;i==t.length-1?l=I(m(e),a.decimalsOut).decimalPlaces(0,1):l=r[0].amountIn;let c=await this.poolService.getPoolFees(a,n),{amountIn:u,calculatedIn:b,feePct:d,errors:g}=n.validateAndBuy(a,l,c),h=this.getPoolFeeRange(c),f=n.spotPriceInGivenOut(a),y=l.shiftedBy(-1*a.decimalsOut).multipliedBy(f),S;b.isZero()?S=-100:S=se(y,b).toNumber(),r.unshift({...o,assetInDecimals:a.decimalsIn,assetOutDecimals:a.decimalsOut,amountOut:l,calculatedIn:b,amountIn:u,spotPrice:f,tradeFeePct:d,tradeFeeRange:h,priceImpactPct:S,errors:g,toHuman(){return{...o,amountOut:F(l,a.decimalsOut),calculatedIn:F(b,a.decimalsIn),amountIn:F(u,a.decimalsIn),spotPrice:F(f,a.decimalsIn),tradeFeePct:d,tradeFeeRange:h,priceImpactPct:S,errors:g}}})}return r}};import{memoize1 as ln}from"@thi.ng/memoize";function fn(p,e){let t=[];return JSON.stringify(p,(s,r)=>(r&&r[e]&&t.push(r),r)),t[0]}function yn(p,e,t){let s;return JSON.stringify(p,(r,i)=>(i&&i[e]===t&&(s=i),i)),s}export{H as AssetClient,we as AssetNotFound,ts as BASILISK_PARACHAIN_ID,W as BalanceClient,O as BigNumber,fe as CachingPoolService,ve as DECIMAL_PLACES,be as DENOMINATOR,he as FarmClient,ie as HUB_ASSET_ID,oe as HYDRADX_OMNIPOOL_ADDRESS,es as HYDRADX_PARACHAIN_ID,$ as HYDRADX_SS58_PREFIX,zt as INFINITY,D as LbpMath,K as LbpPool,v as ONE,B as OmniMath,Q as OmniPool,Oe as PoolConfigNotFound,J as PoolError,te as PoolFactory,ue as PoolNotFound,Z as PoolService,E as PoolType,Ae as ProviderConfigNotFound,j as RUNTIME_DECIMALS,X as RouteNotFound,U as Router,Vt as SYSTEM_ASSET_DECIMALS,_ as SYSTEM_ASSET_ID,N as StableMath,V as StableSwap,Ie as StorageConfigNotFound,xe as SubscriptionNotSupported,de as TRADEABLE_DEFAULT,me as TradeRouter,ye as TradeType,G as XykMath,ee as XykPool,P as ZERO,m as bnum,Pe as buildRoute,Ne as calculateBuyFee,qo as calculateDiffToAvg,se as calculateDiffToRef,Fe as calculateSellFee,fn as findNestedKey,yn as findNestedObj,I as scale};
@@ -1,4 +1,4 @@
1
- import { Asset, IPoolService, PoolBase, Hop, Pool, PoolType } from '../types';
1
+ import { Asset, Hop, IPoolService, PoolBase, Pool, PoolType } from '../types';
2
2
  export type RouterOptions = {
3
3
  includeOnly?: PoolType[];
4
4
  };
@@ -1,5 +1,5 @@
1
1
  import { Router } from './Router';
2
- import { Hop, Trade, Amount } from '../types';
2
+ import { Amount, Hop, Trade } from '../types';
3
3
  import { BigNumber } from '../utils/bignumber';
4
4
  export declare class TradeRouter extends Router {
5
5
  /**
@@ -69,11 +69,19 @@ export declare class TradeRouter extends Router {
69
69
  */
70
70
  private toSellSwaps;
71
71
  /**
72
- * Calculate and return best possible spot price for tokenIn>tokenOut
72
+ * Calculate and return most liquid route for tokenIn>tokenOut
73
73
  *
74
74
  * To avoid routing through the pools with low liquidity, 0.1% from the
75
- * most liquid pool asset is used as reference value to determine ideal
76
- * route to calculate spot.
75
+ * most liquid pool asset is used as reference value to determine the
76
+ * sweet spot.
77
+ *
78
+ * @param {string} assetIn - Storage key of tokenIn
79
+ * @param {string} assetOut - Storage key of tokenOut
80
+ * @return Most liquid route of given token pair
81
+ */
82
+ getMostLiquidRoute(assetIn: string, assetOut: string): Promise<Hop[]>;
83
+ /**
84
+ * Calculate and return best possible spot price for tokenIn>tokenOut
77
85
  *
78
86
  * @param {string} assetIn - Storage key of tokenIn
79
87
  * @param {string} assetOut - Storage key of tokenOut
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@galacticcouncil/sdk",
3
- "version": "5.5.0",
3
+ "version": "5.6.0",
4
4
  "description": "Galactic off-chain routing & optimization of orders across pools for best price execution",
5
5
  "author": "GalacticCouncil",
6
6
  "repository": {