@galacticcouncil/sdk-next 1.0.0 → 1.0.1

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.
@@ -1 +1 @@
1
- var we=Object.defineProperty;var A=(u,t)=>{for(var e in t)we(u,e,{get:t[e],enumerable:!0})};import Te from"buffer";typeof window<"u"&&(window.Buffer=Te.Buffer);var se={};A(se,{LbpMath:()=>T,LbpPool:()=>Q,LbpPoolClient:()=>st});import{calculate_in_given_out as Ae,calculate_out_given_in as Be,calculate_linear_weights as Fe,calculate_pool_trade_fee as _e,get_spot_price as ke}from"@galacticcouncil/math-lbp";var T=class{static getSpotPrice(t,e,i,s,a){return ke(t,e,i,s,a)}static calculateInGivenOut(t,e,i,s,a){return Ae(t,e,i,s,a)}static calculateOutGivenIn(t,e,i,s,a){return Be(t,e,i,s,a)}static calculateLinearWeights(t,e,i,s,a){return Fe(t,e,i,s,a)}static calculatePoolTradeFee(t,e,i){return _e(t,e,i)}};import{big as $t,RUNTIME_DECIMALS as Ut}from"@galacticcouncil/common";var y=(n=>(n.Aave="Aave",n.LBP="LBP",n.Omni="Omnipool",n.Stable="Stableswap",n.XYK="XYK",n.HSM="HSM",n))(y||{}),H=(c=>(c.UnknownError="UnknownError",c.FacilitatorCapacityExceeded="FacilitatorCapacityExceeded",c.InsufficientTradingAmount="InsufficientTradingAmount",c.InsufficientCollateral="InsufficientCollateral",c.MaxHoldingExceeded="MaxHoldingExceeded",c.MaxInRatioExceeded="MaxInRatioExceeded",c.MaxOutRatioExceeded="MaxOutRatioExceeded",c.TradeNotAllowed="TradeNotAllowed",c.MaxBuyBackExceeded="MaxBuyBackExceeded",c.MaxBuyPriceExceeded="MaxBuyPriceExceeded",c))(H||{});var bt={};A(bt,{withTimeout:()=>Re});function Re(u,t,e="timeout"){return new Promise((i,s)=>{let a=setTimeout(()=>s(new Error(e)),t);u.then(n=>{clearTimeout(a),i(n)},n=>{clearTimeout(a),s(n)})})}import{RUNTIME_DECIMALS as Fa}from"@galacticcouncil/common";var P={};A(P,{FeeUtils:()=>Bt,shiftNeg:()=>Me});import Le from"big.js";var Bt=class u{static toPct(t){let[e,i]=t;return u.safeDivide(e*100,i)}static toRaw(t){let[e,i]=t;return u.safeDivide(e,i)}static fromPermill(t){return[t,1e6]}static fromPerbill(t){return[t,1e9]}static fromRate(t,e){return[t,e]}static safeDivide(t,e,i=12){let s=10**i;return Math.round(t*s/e)/s}static safeRound(t){return parseFloat(t.toPrecision(15))}};function Me(u,t){let e=Le(typeof u=="bigint"?u.toString():u);return t===0?e.toString():e.div(Math.pow(10,t)).toString()}var j={};A(j,{findNestedKey:()=>De,findNestedObj:()=>He,jsonFormatter:()=>Ge});var De=(u,t)=>{let e=[];return JSON.stringify(u,(i,s)=>(s&&s[t]&&e.push(s),s)),e[0]},He=(u,t,e)=>{let i;return JSON.stringify(u,(s,a)=>(a&&a[t]===e&&(i=a),a)),i},Ge=(u,t)=>typeof t=="bigint"?t.toString():t;var D={};A(D,{calculateBuyFee:()=>We,calculateDiffToAvg:()=>qe,calculateDiffToRef:()=>Ne,calculateSellFee:()=>Ve});import E from"big.js";function qe(u,t){let e=E(u.toString()),i=E(t.toString());return e.minus(i).abs().div(e.plus(i).div(2)).mul(100).round(2).toNumber()}function Ne(u,t){if(t===0n)return 0;let e=E(u.toString()),i=E(t.toString());return e.minus(i).div(i).mul(100).round(2).toNumber()}function Ve(u,t){if(u===0n)return 0;let e=E(u.toString()),i=E(t.toString());return E(1).minus(i.div(e)).mul(100).round(2).toNumber()}function We(u,t){if(u===0n)return 0;let e=E(u.toString());return E(t.toString()).div(e).minus(1).mul(100).round(2).toNumber()}import{TLRUCache as Wt}from"@thi.ng/cache";var Pt=class{debug;constructor(t){this.debug=t||!1}log(t,e,i){this.debug&&console.log(t,e,i)}scope(t,e,i,s){let a=new Map,n=s!==void 0?new Wt(null,{ttl:s}):new Wt;return{get:(...c)=>{let p=i(...c);if(a.has(p)){this.log("[live]",t,p);let g=a.get(p);return Promise.resolve(g)}if(n.has(p))return this.log("[memo]",t,p),n.get(p);this.log("[fetch]",t,p);let m=e(...c).catch(g=>{throw n.delete(p),g});return n.set(p,m),m},set:(c,...p)=>{let m=i(...p);this.log("[set-live]",t,m),a.set(m,c)},clear:()=>{this.log("[clear]",t),a.clear(),n.release()}}}};var{FeeUtils:Yt}=P,Q=class u{type;address;tokens;maxInRatio;maxOutRatio;minTradingLimit;fee;repayFeeApply;static fromPool(t){return new u(t)}constructor(t){this.type="LBP",this.address=t.address,this.tokens=t.tokens,this.maxInRatio=t.maxInRatio,this.maxOutRatio=t.maxOutRatio,this.minTradingLimit=t.minTradingLimit,this.fee=t.fee,this.repayFeeApply=t.repayFeeApply}validatePair(t,e){return!0}parsePair(t,e){let i=new Map(this.tokens.map(n=>[n.id,n])),s=i.get(t),a=i.get(e);if(s==null)throw new Error("Pool does not contain tokenIn");if(a==null)throw new Error("Pool does not contain tokenOut");return{assetIn:t,assetOut:e,balanceIn:s.balance,balanceOut:a.balance,decimalsIn:s.decimals,decimalsOut:a.decimals,weightIn:s.weight,weightOut:a.weight}}validateAndBuy(t,e,i){let s=this.tokens[0].id,a=[];e<this.minTradingLimit&&a.push("InsufficientTradingAmount");let n=t.balanceOut/this.maxOutRatio;if(e>n&&a.push("MaxOutRatioExceeded"),s===t.assetOut){let r=this.calculateTradeFee(e,i),o=Yt.toPct(this.repayFeeApply?i.repayFee:i.exchangeFee),l=e+r,c=this.calculateInGivenOut(t,l),p=t.balanceIn/this.maxInRatio;return c>p&&a.push("MaxInRatioExceeded"),{amountIn:c,calculatedIn:c,amountOut:e,feePct:o,errors:a}}else{let r=this.calculateInGivenOut(t,e),o=t.balanceIn/this.maxInRatio;return r>o&&a.push("MaxInRatioExceeded"),{amountIn:r,calculatedIn:r,amountOut:e,feePct:0,errors:a}}}validateAndSell(t,e,i){let s=this.tokens[0].id,a=[];e<this.minTradingLimit&&a.push("InsufficientTradingAmount");let n=t.balanceIn/this.maxInRatio;if(e>n&&a.push("MaxInRatioExceeded"),s===t.assetIn){let r=this.calculateOutGivenIn(t,e),o=t.balanceOut/this.maxOutRatio;return r>o&&a.push("MaxOutRatioExceeded"),{amountIn:e,calculatedOut:r,amountOut:r,feePct:0,errors:a}}else{let r=this.calculateOutGivenIn(t,e),o=this.calculateTradeFee(r,i),l=Yt.toPct(this.repayFeeApply?i.repayFee:i.exchangeFee),c=r-o,p=t.balanceOut/this.maxOutRatio;return c>p&&a.push("MaxOutRatioExceeded"),{amountIn:e,calculatedOut:r,amountOut:c,feePct:l,errors:a}}}calculateInGivenOut(t,e){let i=T.calculateInGivenOut(t.balanceIn.toString(),t.balanceOut.toString(),t.weightIn.toString(),t.weightOut.toString(),e.toString()),s=BigInt(i);return s<0n?0n:s}calculateOutGivenIn(t,e){let i=T.calculateOutGivenIn(t.balanceIn.toString(),t.balanceOut.toString(),t.weightIn.toString(),t.weightOut.toString(),e.toString()),s=BigInt(i);return s<0n?0n:s}spotPriceInGivenOut(t){let e=T.getSpotPrice(t.balanceOut.toString(),t.balanceIn.toString(),t.weightOut.toString(),t.weightIn.toString(),$t.toBigInt(1,Ut).toString());return BigInt(e)}spotPriceOutGivenIn(t){let e=T.getSpotPrice(t.balanceIn.toString(),t.balanceOut.toString(),t.weightIn.toString(),t.weightOut.toString(),$t.toBigInt(1,Ut).toString());return BigInt(e)}calculateTradeFee(t,e){let i=T.calculatePoolTradeFee(t.toString(),this.repayFeeApply?e.repayFee[0]:e.exchangeFee[0],this.repayFeeApply?e.repayFee[1]:e.exchangeFee[1]);return BigInt(i)}};import{CompatibilityLevel as Ei}from"polkadot-api";import{Subscription as Ci,distinctUntilChanged as Li,filter as Mi,map as Di}from"rxjs";import{memoize1 as yi}from"@thi.ng/memoize";import{TLRUCache as fi}from"@thi.ng/cache";import{ReplaySubject as te,Subscription as ee,combineLatest as Si,defer as vi,from as xi,interval as Ii,merge as _t,of as Oi,EMPTY as et}from"rxjs";import{bufferCount as wi,bufferTime as Ti,catchError as it,filter as xt,finalize as kt,map as W,pairwise as Rt,repeat as Et,skip as Ai,share as Bi,startWith as Fi,switchMap as ie,tap as G,throttleTime as _i}from"rxjs/operators";import{hydration as ni,hydrationNext as ri}from"@galacticcouncil/descriptors";import{log as ti}from"@galacticcouncil/common";import{map as ei,shareReplay as ii,tap as si}from"rxjs";import{defer as $e,from as Ue,of as Xt,timer as Ye}from"rxjs";import{catchError as Xe,distinctUntilChanged as ze,expand as Ke,map as Ft,shareReplay as je,skip as Qe,switchMap as Je,timeout as Ze}from"rxjs/operators";function zt(u,{intervalMs:t=5e3,rpcTimeoutMs:e=1e4}={}){let i=()=>$e(()=>Ue(u._request("system_health",[]))).pipe(Ze({first:e}),Ft(()=>"online"),Xe(()=>Xt("offline")));return Xt({state:"offline",delayMs:0}).pipe(Ke(a=>Ye(a.delayMs).pipe(Je(i),Ft(n=>({state:n,delayMs:t})))),Qe(1),Ft(a=>a.state),ze(),je({bufferSize:1,refCount:!0}))}var{logger:ai}=ti,yt=class u{static instance=null;bestBlock$;finalizedBlock$;connection$;constructor(t){this.bestBlock$=this.watched("watcher(bestBlock)",t.getUnsafeApi().query.System.Number.watchValue({at:"best"}).pipe(ei(({value:e})=>e))),this.finalizedBlock$=this.watched("watcher(finalizedBlock)",t.finalizedBlock$),this.connection$=this.watched("watcher(connection)",zt(t))}static getInstance(t){return this.instance||(this.instance=new u(t)),this.instance}watched(t,e){return e.pipe(si({error:i=>ai.error(t,i)}),ii({bufferSize:1,refCount:!0}))}};var B=class{client;api;apiNext;watcher;constructor(t){this.client=t,this.api=this.client.getTypedApi(ni),this.apiNext=this.client.getTypedApi(ri),this.watcher=yt.getInstance(this.client)}};import{getWsProvider as xn}from"polkadot-api/ws";import{withLogsRecorder as On}from"polkadot-api/logs-provider";import{getSmProvider as Bn}from"polkadot-api/sm-provider";import{Binary as Nn}from"polkadot-api";import{log as oi}from"@galacticcouncil/common";import{combineLatest as li,concat as ci,defer as J,from as Kt}from"rxjs";import{bufferCount as jt,distinctUntilChanged as Qt,debounceTime as ui,map as N,retry as pi,startWith as Jt,switchMap as Zt,tap as Z,take as mi,skip as di,connect as gi}from"rxjs/operators";var{logger:V}=oi,tt=class extends B{erc20Ids=null;constructor(t){super(t)}async getBalance(t,e){return e===0?this.getSystemBalance(t):this.getBalanceData(t,e)}async getSystemBalance(t){let e=this.api.query.System.Account,{data:i}=await e.getValue(t,{at:"best"});return this.getBreakdown(i)}async getTokenBalance(t,e){let s=await this.api.query.Tokens.Accounts.getValue(t,e,{at:"best"});return this.getBreakdown(s)}async getErc20Balance(t,e){return this.getBalanceData(t,e)}watchBalance(t){return J(()=>{let e=this.watchSystemBalance(t),i=this.watchTokensBalance(t),s=this.watchErc20Balance(t);return li([e,i,s]).pipe(gi(a=>ci(a.pipe(mi(1)),a.pipe(di(1),ui(250)))))}).pipe(N(e=>e.flat()),Jt([]),jt(2,1),N(([e,i],s)=>s===0?i:this.getDeltas(e,i))).pipe(Z({subscribe:()=>V.debug("balance: subscribe",t),error:e=>V.error("balance",e)}),pi({delay:1e3}))}watchSystemBalance(t){let e=this.api.query.System.Account;return J(()=>e.watchValue(t,{at:"best"})).pipe(N(({value:i})=>({id:0,balance:this.getBreakdown(i.data)})),Z({error:i=>V.error("balance(system)",i)}))}watchTokenBalance(t,e){let i=this.api.query.Tokens.Accounts;return J(()=>i.watchValue(t,e,{at:"best"})).pipe(N(({value:s})=>({id:e,balance:this.getBreakdown(s)})),Z({error:s=>V.error("balance(token)",s)}))}watchTokensBalance(t){let e=this.api.query.Tokens.Accounts;return J(()=>e.watchEntries(t,{at:"best"})).pipe(Qt((i,s)=>!s.deltas),N(({deltas:i})=>{let s=[];return i?.deleted.forEach(a=>{let[n,r]=a.args;s.push({id:r,balance:this.getBreakdown({free:0n,reserved:0n,frozen:0n})})}),i?.upserted.forEach(a=>{let[n,r]=a.args;s.push({id:r,balance:this.getBreakdown(a.value)})}),s}),Z({error:i=>V.error("balance(tokens)",i)}))}watchErc20Balance(t,e){let i=async()=>{if(this.erc20Ids)return this.erc20Ids;let a=await this.api.query.AssetRegistry.Assets.getEntries({at:"best"});return this.erc20Ids=a.filter(({value:n})=>n.asset_type.type==="Erc20").map(({keyArgs:n})=>{let[r]=n;return r}),this.erc20Ids},s=async a=>(await Promise.all(a.map(async r=>[r,await this.getBalanceData(t,r)]))).map(([r,o])=>({id:r,balance:o}));return J(()=>Kt(e?Promise.resolve(e):i()).pipe(Zt(a=>this.watcher.bestBlock$.pipe(Zt(()=>Kt(s(a))))),Jt([]),jt(2,1),N(([a,n],r)=>r===0?n.filter(o=>o.balance.total>0n):this.getDeltas(a,n)),Qt((a,n)=>n.length===0),Z({error:a=>V.error("balance(erc20)",a)})))}async getBalanceData(t,e){let i=await this.api.apis.CurrenciesApi.account(e,t,{at:"best"});return this.getBreakdown(i)}getBreakdown(t){let e=t.free>=t.frozen?t.free-t.frozen:0n,i=t.free+t.reserved;return{free:t.free,reserved:t.reserved,frozen:t.frozen,total:i,transferable:e}}getDeltas(t,e){let i=(a,n)=>a!==void 0&&n!==void 0&&a.transferable===n.transferable&&a.total===n.total,s=t.reduce((a,n)=>(a.set(n.id,n.balance),a),new Map);return e.filter(a=>!i(a.balance,s.get(a.id)))}};import{BehaviorSubject as bi}from"rxjs";var ft=class{store$=new bi([]);updateQueue=Promise.resolve();changeset=new Set;get pools(){return this.store$.value}asObservable(){return this.store$.asObservable()}applyChangeset(t){return this.changeset.size===0?[]:t.filter(e=>this.changeset.has(e.address))}set(t){this.changeset=new Set(t.map(e=>e.address)),this.store$.next(t)}update(t){this.updateQueue=this.updateQueue.then(async()=>{let e=this.store$.value,i=new Map(e.map((r,o)=>[r.address,o])),s=await t(e),a=e.slice(),n=new Set;for(let r of s){let o=i.get(r.address);o===void 0?(i.set(r.address,a.length),a.push(r)):a[o]=r,n.add(r.address)}this.changeset=n,this.store$.next(a)}).catch(console.error)}destroy(){this.store$.complete()}};import{log as hi}from"@galacticcouncil/common";var Pi={Aave:"AAVE",LBP:"LBP",Omnipool:"OMNI",Stableswap:"STBL",XYK:"XYK",HSM:"HSM"},{logger:St}=hi,vt=class{type;constructor(t){this.type=t}prefix(){return this.pad(`pool(${Pi[this.type]})`,10)}trace(t,...e){St.trace(`${this.prefix()} ${t} :`,...e)}debug(t,...e){St.debug(`${this.prefix()} ${t} :`,...e)}info(t,...e){St.info(`${this.prefix()} ${t} :`,...e)}error(t,...e){St.error(`${this.prefix()} ${t} :`,...e)}pad(t,e){return t.length>=e?t:t+" ".repeat(e-t.length)}};var{withTimeout:ki}=bt,Ri=3e3,v=class extends B{evm;balance;store=new ft;log;shared$;resync$=new te(1);resyncAt=0;resyncPending=!1;mem=0;memPoolsCache=new fi(null,{ttl:6*1e3});memPools=yi(t=>(this.log.info("pool_sync",{mem:t}),this.loadPools()),this.memPoolsCache);constructor(t,e){super(t),this.evm=e,this.balance=new tt(t),this.log=new vt(this.getPoolType())}async getMemPools(){return this.memPools(this.mem)}async getPools(){return(await this.getMemPools()).filter(e=>this.hasValidAssets(e))}getSubscriber(){return this.shared$||(this.shared$=this.subscribeStore()),this.shared$.pipe(Fi([]),wi(2,1),W(([t,e])=>t.length===0?e:this.store.applyChangeset(e)),xt(t=>t.length>0),_i(1e3,void 0,{leading:!0,trailing:!0}))}subscribeStore(){return vi(()=>{let t=new ee;return t.add(this.startWatchdog()),this.resync$.next(),this.resync$.pipe(ie(()=>{let e=new ee;return xi(ki(this.getMemPools(),6e4,"getMemPools stalled")).pipe(G(()=>this.log.info("pool_synced",{mem:this.mem})),W(s=>s.filter(a=>this.hasValidAssets(a))),G(s=>this.store.set(s)),it(()=>(this.log.error("pool_seed_error",{mem:this.mem}),this.requestResync(),et))).pipe(G(()=>{e.add(this.subscribeBalances()),e.add(this.subscribeUpdates())}),ie(s=>_t(Oi(s),this.store.asObservable().pipe(Ai(1)))),kt(()=>{e.unsubscribe()}))}),kt(()=>t.unsubscribe()))}).pipe(Bi({connector:()=>new te(1),resetOnRefCountZero:!0}))}subscribeBalances(){let t=this.store.pools.map(e=>{let{address:i}=e,s=[this.balance.watchTokensBalance(i)];if(this.hasSystemAsset(e)){let a=this.balance.watchSystemBalance(i);s.push(a)}if(this.hasErc20Asset(e)){let a=e.tokens.filter(r=>r.type==="Erc20").map(r=>r.id),n=this.balance.watchErc20Balance(i,a);s.push(n)}return Si(s).pipe(W(a=>a.flat()),Rt(),W(([a,n])=>this.balance.getDeltas(a,n)),xt(a=>a.length>0),W(a=>[i,a]))});return _t(...t).pipe(Ti(250),xt(e=>e.length>0),W(e=>new Map(e)),this.watchGuard("balances")).subscribe(e=>{this.store.update(i=>this.updateBalances(i,e))})}hasSystemAsset(t){return t.tokens.some(e=>e.id===0)}hasErc20Asset(t){return t.tokens.some(e=>e.type==="Erc20")}hasValidAssets(t){return t.tokens.every(({decimals:e,balance:i})=>t.type==="XYK"?i>0n&&!!e:!!e)}updateBalances=(t,e)=>{let i=[],s=new Map(t.map(a=>[a.address,a]));for(let[a,n]of e){let r=s.get(a);if(r){let o=r.tokens.map(l=>{let c=n.find(p=>p.id===l.id);return c&&l.id!==r.id?{...l,balance:c.balance.transferable}:l});i.push({...r,tokens:o})}}return i};resync(t=!1){let e=Date.now();!t&&e-this.resyncAt<Ri||(this.resyncAt=e,this.mem++,this.resync$.next())}requestResync(t=!1){this.resyncPending||(this.resyncPending=!0,setTimeout(()=>{this.resyncPending=!1,this.resync(t)},0))}startWatchdog(){let s=this.watcher.connection$.pipe(Rt(),xt(([r,o])=>r==="offline"&&o==="online"),G(()=>{this.log.debug("watchdog_recover_online",{mem:this.mem}),this.requestResync()}),it(r=>(this.log.error("watchdog_recovery_error",r),et)),Et({delay:1e3})),a=this.watcher.finalizedBlock$.pipe(Rt(),G(([r,o])=>{let l=Number(r.number),c=Number(o.number),p=c-l;p>=3&&(this.log.debug("watchdog_gap",{from:l,to:c,gap:p}),this.requestResync())}),it(r=>(this.log.error("watchdog_gap_error",r),et)),Et({delay:1e3})),n=Ii(36e5).pipe(G(()=>{this.log.debug("watchdog_periodic",{mem:this.mem}),this.requestResync()}),it(r=>(this.log.error("watchdog_periodic_error",r),et)),Et({delay:1e3}));return _t(s,a,n).subscribe()}watchGuard(t){return e=>e.pipe(G({error:i=>{this.log.error(t,i),this.requestResync(!0)}}),kt(()=>{this.log.debug(t,"unsub")}),it(()=>et))}};var st=class extends v{MAX_FINAL_WEIGHT=100000000n;poolsData=new Map([]);getPoolType(){return"LBP"}async getPoolLimits(){let[t,e,i]=await Promise.all([this.api.constants.LBP.MaxInRatio(),this.api.constants.LBP.MaxOutRatio(),this.api.constants.LBP.MinTradingLimit()]);return{maxInRatio:t,maxOutRatio:e,minTradingLimit:i}}getPoolWeights(t,e){let{start:i,end:s,initial_weight:a,final_weight:n}=t,r=T.calculateLinearWeights(i?i.toString():"0",s?s.toString():"0",a.toString(),n.toString(),e.toString()),o=BigInt(r),l=this.MAX_FINAL_WEIGHT-BigInt(o);return[o,l]}async isSupported(){return(await this.api.getStaticApis()).compat.query.LBP.PoolData.isCompatible(Ei.BackwardsCompatible)}async loadPools(){let[t,e,i]=await Promise.all([this.api.query.LBP.PoolData.getEntries({at:"best"}),this.api.query.ParachainSystem.ValidationData.getValue({at:"best"}),this.getPoolLimits()]),s=e?.relay_parent_number||0,a=t.filter(({value:n})=>e&&this.isActivePool(n,s)).map(async({keyArgs:n,value:r})=>{let[o]=n,l=o.toString(),c=await this.getPoolDelta(l,r,s);return{address:l,type:"LBP",fee:r.fee,...c,...i}});return Promise.all(a)}async getPoolDelta(t,e,i){let{assets:s,repay_target:a,fee_collector:n}=e,[r,o]=this.getPoolWeights(e,i),[l,c]=s,[p,m,g,d,S]=await Promise.all([this.isRepayFeeApplied(l,a,n.toString()),this.balance.getBalance(t,l),this.api.query.AssetRegistry.Assets.getValue(l),this.balance.getBalance(t,c),this.api.query.AssetRegistry.Assets.getValue(c)]);return{repayFeeApply:p,tokens:[{id:l,decimals:g?.decimals,existentialDeposit:g?.existential_deposit,balance:m.transferable,weight:r,type:g?.asset_type.type},{id:c,decimals:S?.decimals,existentialDeposit:S?.existential_deposit,balance:d.transferable,weight:o,type:S?.asset_type.type}]}}isActivePool(t,e){let{start:i,end:s}=t;return i&&s?e>=i&&e<s:!1}async isRepayFeeApplied(t,e,i){if(e===0n)return!1;try{return(await this.balance.getBalance(i,t)).transferable<e}catch{return!0}}async getRepayFee(){return await this.api.constants.LBP.repay_fee()}async getPoolFees(t,e){let i=this.store.pools.find(a=>a.address===e);return{repayFee:await this.getRepayFee(),exchangeFee:i.fee}}subscribeValidationData(){return this.api.query.ParachainSystem.ValidationData.watchValue({at:"best"}).pipe(Di(({value:t})=>t),Mi(t=>t!==void 0),Li((t,e)=>t.relay_parent_number===e.relay_parent_number),this.watchGuard("parachainSystem.ValidationData")).subscribe(({relay_parent_number:t})=>{this.store.update(async e=>{let i=[];for(let s of e){let a=this.poolsData.get(s.address);if(a){let{assets:n,repay_target:r,fee_collector:o}=a,[l]=n,[c,p]=this.getPoolWeights(a,t),[m,g]=s.tokens,d=[{...m,weight:c},{...g,weight:p}],S=await this.isRepayFeeApplied(l,r,o.toString());i.push({...s,tokens:d,repayFeeApply:S})}}return i})})}subscribeUpdates(){let t=new Ci;return t.add(this.subscribeValidationData()),t}};var le={};A(le,{OmniMath:()=>b,OmniPool:()=>at,OmniPoolClient:()=>nt});import{calculate_in_given_out as Hi,calculate_lrna_in_given_out as Gi,calculate_out_given_in as qi,calculate_out_given_lrna_in as Ni,calculate_spot_price as Vi,calculate_lrna_spot_price as Wi,calculate_shares as $i,calculate_liquidity_out as Ui,calculate_liquidity_lrna_out as Yi,verify_asset_cap as Xi,calculate_liquidity_hub_in as zi,is_sell_allowed as Ki,is_buy_allowed as ji,is_add_liquidity_allowed as Qi,is_remove_liquidity_allowed as Ji,recalculate_asset_fee as Zi,recalculate_protocol_fee as ts}from"@galacticcouncil/math-omnipool";import $ from"big.js";var b=class{static calculateSpotPrice(t,e,i,s){return Vi(t,e,i,s)}static calculateLrnaSpotPrice(t,e){return Wi(t,e)}static calculateInGivenOut(t,e,i,s,a,n,r,o,l,c){return Hi(t,e,i,s,a,n,r,o,l,c)}static calculateLrnaInGivenOut(t,e,i,s,a,n){return Gi(t,e,i,s,a,n)}static calculateOutGivenIn(t,e,i,s,a,n,r,o,l,c){return qi(t,e,i,s,a,n,r,o,l,c)}static calculateOutGivenLrnaIn(t,e,i,s,a,n){return Ni(t,e,i,s,a,n)}static calculateShares(t,e,i,s){return $i(t,e,i,s)}static calculateLiquidityOut(t,e,i,s,a,n,r,o){return Ui(t,e,i,s,a,n,r,o)}static calculateLiquidityLRNAOut(t,e,i,s,a,n,r,o){return Yi(t,e,i,s,a,n,r,o)}static calculateCapDifference(t,e,i,s){let a=$(e),n=$(t),r=$(s),o=$(i),l=$(10).pow(18),c=o.div(l);if(a.div(r).lt(c)){let m=c.times(r).minus(a).times(n),g=a.times($(1).minus(c));return m.div(g).toFixed(0)}else return"0"}static calculateLimitHubIn(t,e,i,s){return zi(t,e,i,s)}static isSellAllowed(t){return Ki(t)}static isBuyAllowed(t){return ji(t)}static isAddLiquidityAllowed(t){return Qi(t)}static isRemoveLiquidityAllowed(t){return Ji(t)}static recalculateAssetFee(t,e,i,s,a,n,r,o,l,c,p){return Zi(t,e,i,s,a,n,r,o,l,c,p)}static recalculateProtocolFee(t,e,i,s,a,n,r,o,l,c,p){return ts(t,e,i,s,a,n,r,o,l,c,p)}static verifyAssetCap(t,e,i,s){return Xi(t,e,i,s)}};import{big as es}from"@galacticcouncil/common";var{FeeUtils:F}=P,at=class u{type;address;tokens;maxInRatio;maxOutRatio;minTradingLimit;hubAssetId;static fromPool(t){return new u(t)}constructor(t){this.type="Omnipool",this.address=t.address,this.tokens=t.tokens,this.maxInRatio=t.maxInRatio,this.maxOutRatio=t.maxOutRatio,this.minTradingLimit=t.minTradingLimit,this.hubAssetId=t.hubAssetId}validatePair(t,e){return this.hubAssetId!=e}parsePair(t,e){let i=new Map(this.tokens.map(n=>[n.id,n])),s=i.get(t),a=i.get(e);if(s==null)throw new Error("Pool does not contain tokenIn");if(a==null)throw new Error("Pool does not contain tokenOut");return{assetIn:t,assetOut:e,hubReservesIn:s.hubReserves,hubReservesOut:a.hubReserves,sharesIn:s.shares,sharesOut:a.shares,decimalsIn:s.decimals,decimalsOut:a.decimals,balanceIn:s.balance,balanceOut:a.balance,tradeableIn:s.tradeable,tradeableOut:a.tradeable,assetInEd:s.existentialDeposit,assetOutEd:a.existentialDeposit}}validateAndBuy(t,e,i){let s=this.calculateInGivenOut(t,e),a=this.calculateInGivenOut(t,e,i),n=s===0n?0:D.calculateBuyFee(s,a),r=[],o=b.isSellAllowed(t.tradeableIn),l=b.isBuyAllowed(t.tradeableOut);(!o||!l)&&r.push("TradeNotAllowed"),(e<this.minTradingLimit||s<t.assetInEd)&&r.push("InsufficientTradingAmount");let c=t.balanceOut/this.maxOutRatio;e>c&&r.push("MaxOutRatioExceeded");let p=t.balanceIn/this.maxInRatio;return a>p&&r.push("MaxInRatioExceeded"),{amountIn:a,calculatedIn:s,amountOut:e,feePct:n,errors:r}}validateAndSell(t,e,i){let s=this.calculateOutGivenIn(t,e),a=this.calculateOutGivenIn(t,e,i),n=D.calculateSellFee(s,a),r=[],o=b.isSellAllowed(t.tradeableIn),l=b.isBuyAllowed(t.tradeableOut);(!o||!l)&&r.push("TradeNotAllowed"),(e<this.minTradingLimit||s<t.assetOutEd)&&r.push("InsufficientTradingAmount");let c=t.balanceIn/this.maxInRatio;e>c&&r.push("MaxInRatioExceeded");let p=t.balanceOut/this.maxOutRatio;return a>p&&r.push("MaxOutRatioExceeded"),{amountIn:e,calculatedOut:s,amountOut:a,feePct:n,errors:r}}calculateInGivenOut(t,e,i){if(t.assetIn==this.hubAssetId)return this.calculateLrnaInGivenOut(t,e,i);let s=b.calculateInGivenOut(t.balanceIn.toString(),t.hubReservesIn.toString(),t.sharesIn.toString(),t.balanceOut.toString(),t.hubReservesOut.toString(),t.sharesOut.toString(),e.toString(),i?F.toRaw(i.assetFee).toString():"0",i?F.toRaw(i.protocolFee).toString():"0",i?F.toRaw(i.maxSlipFee).toString():"0"),a=BigInt(s);return a<0n?0n:a}calculateLrnaInGivenOut(t,e,i){let s=b.calculateLrnaInGivenOut(t.balanceOut.toString(),t.hubReservesOut.toString(),t.sharesOut.toString(),e.toString(),i?F.toRaw(i.assetFee).toString():"0",i?F.toRaw(i.maxSlipFee).toString():"0"),a=BigInt(s);return a<0n?0n:a}calculateOutGivenIn(t,e,i){if(t.assetIn==this.hubAssetId)return this.calculateOutGivenLrnaIn(t,e,i);let s=b.calculateOutGivenIn(t.balanceIn.toString(),t.hubReservesIn.toString(),t.sharesIn.toString(),t.balanceOut.toString(),t.hubReservesOut.toString(),t.sharesOut.toString(),e.toString(),i?F.toRaw(i.assetFee).toString():"0",i?F.toRaw(i.protocolFee).toString():"0",i?F.toRaw(i.maxSlipFee).toString():"0"),a=BigInt(s);return a<0n?0n:a}calculateOutGivenLrnaIn(t,e,i){let s=b.calculateOutGivenLrnaIn(t.balanceOut.toString(),t.hubReservesOut.toString(),t.sharesOut.toString(),e.toString(),i?F.toRaw(i.assetFee).toString():"0",i?F.toRaw(i.maxSlipFee).toString():"0"),a=BigInt(s);return a<0n?0n:a}spotPriceInGivenOut(t){if(t.assetIn==this.hubAssetId)return this.spotPriceLrnaInGivenOut(t);let e=b.calculateSpotPrice(t.balanceOut.toString(),t.hubReservesOut.toString(),t.balanceIn.toString(),t.hubReservesIn.toString());return this.normalizeSpot(BigInt(e),t.decimalsOut,t.decimalsIn)}spotPriceLrnaInGivenOut(t){let e=b.calculateLrnaSpotPrice(t.hubReservesOut.toString(),t.balanceOut.toString());return this.normalizeSpot(BigInt(e),t.decimalsOut,t.decimalsIn)}spotPriceOutGivenIn(t){if(t.assetIn==this.hubAssetId)return this.spotPriceOutGivenLrnaIn(t);let e=b.calculateSpotPrice(t.balanceIn.toString(),t.hubReservesIn.toString(),t.balanceOut.toString(),t.hubReservesOut.toString());return this.normalizeSpot(BigInt(e),t.decimalsIn,t.decimalsOut)}spotPriceOutGivenLrnaIn(t){let e=b.calculateLrnaSpotPrice(t.balanceOut.toString(),t.hubReservesOut.toString());return this.normalizeSpot(BigInt(e),t.decimalsIn,t.decimalsOut)}normalizeSpot(t,e,i){let s=e-i;if(s===0)return t;let a=es.pow10(Math.abs(s));return s>0?t*a:t/a}};import{AccountId as is,Binary as ae,CompatibilityLevel as ne,Enum as ss}from"polkadot-api";import{toHex as as}from"@polkadot-api/utils";import{Subscription as ns,distinctUntilChanged as Lt,filter as rs,finalize as Mt,map as U,merge as os,tap as It}from"rxjs";import{HYDRATION_SS58_PREFIX as ls}from"@galacticcouncil/common";var{FeeUtils:h}=P,re=ae.toHex(ae.fromText("omnipool")),oe=ss("Short"),nt=class extends v{queryBus=new Pt;block=0;dynamicFeesConfig=this.queryBus.scope("DynamicFees.AssetFeeConfiguration",t=>this.api.query.DynamicFees.AssetFeeConfiguration.getValue(t,{at:"best"}),t=>String(t));dynamicFees=this.queryBus.scope("DynamicFees.AssetFee",t=>this.api.query.DynamicFees.AssetFee.getValue(t,{at:"best"}),t=>String(t),6*1e3);maxSlipFee=this.queryBus.scope("Omnipool.SlipFee",()=>this.apiNext.query.Omnipool.SlipFee.getValue({at:"best"}),()=>"slipFee");emaOracles=this.queryBus.scope("EmaOracle.Oracles.Short",t=>this.api.query.EmaOracle.Oracles.getValue(re,t,oe,{at:"best"}),t=>t.join(":"),6*1e3);getPoolType(){return"Omnipool"}getPoolAddress(){let t="modlomnipool".padEnd(32,"\0"),e=new TextEncoder().encode(t),i=as(e);return is(ls).dec(i)}getOraclePair(t){return t===0?[0,1]:[1,t]}async getPoolLimits(){let[t,e,i]=await Promise.all([this.api.constants.Omnipool.MaxInRatio(),this.api.constants.Omnipool.MaxOutRatio(),this.api.constants.Omnipool.MinimumTradingLimit()]);return{maxInRatio:t,maxOutRatio:e,minTradingLimit:i}}async isSupported(){return(await this.api.getStaticApis()).compat.query.Omnipool.Assets.isCompatible(ne.BackwardsCompatible)}async isSlipFeeSupported(){return(await this.apiNext.getStaticApis()).compat.query.Omnipool.SlipFee.isCompatible(ne.Partial)}async loadPools(){let t=await this.api.constants.Omnipool.HubAssetId(),e=this.getPoolAddress(),[i,s,a,n,r]=await Promise.all([this.api.query.Omnipool.Assets.getEntries({at:"best"}),this.api.query.Omnipool.HubAssetTradability.getValue(),this.api.query.AssetRegistry.Assets.getValue(t),this.balance.getBalance(e,t),this.getPoolLimits()]),o=i.map(async({keyArgs:c,value:p})=>{let[m]=c,{hub_reserve:g,shares:d,tradable:S,cap:_,protocol_shares:k}=p,[x,w]=await Promise.all([this.api.query.AssetRegistry.Assets.getValue(m),this.balance.getBalance(e,m)]);return{id:m,decimals:x?.decimals,existentialDeposit:x?.existential_deposit,balance:w.transferable,cap:_,hubReserves:g,protocolShares:k,shares:d,tradeable:S,type:x?.asset_type.type}}),l=await Promise.all(o);return l.push({id:t,decimals:a?.decimals,existentialDeposit:a?.existential_deposit,balance:n.transferable,tradeable:s,type:a?.asset_type.type}),[{address:e,type:"Omnipool",hubAssetId:t,tokens:l,...r}]}async getPoolFees(t){let e=t.assetOut,i=t.assetIn,s=0;await this.isSlipFeeSupported()&&(s=await this.maxSlipFee.get()??0);let n=await this.dynamicFeesConfig.get(e);if(n?.type==="Fixed"){let{asset_fee:I,protocol_fee:R}=n.value;return{assetFee:h.fromPermill(I),protocolFee:h.fromPermill(R),maxSlipFee:h.fromPermill(s)}}let r=this.getOraclePair(e),o=this.getOraclePair(i),[l,c,p]=await Promise.all([this.dynamicFees.get(e),this.emaOracles.get(r),this.emaOracles.get(o)]),[m,g,d]=await this.getAssetFee(t,this.block,l,c,n?.value.asset_fee_params),[S,_,k]=i===1?[0,0,0]:await this.getProtocolFee(t,this.block,l,p,n?.value.protocol_fee_params),x=m+S,w=d+k;return{assetFee:h.fromPermill(g),protocolFee:h.fromPermill(_),maxSlipFee:h.fromPermill(s),min:h.fromPermill(x),max:h.fromPermill(w)}}async getAssetFee(t,e,i,s,a){let{assetOut:n,balanceOut:r}=t,{min_fee:o,max_fee:l,decay:c,amplification:p}=a||await this.api.constants.DynamicFees.AssetFeeParameters();if(!i||!s)return[o,o,l];let m=h.fromPermill(o),g=h.fromPermill(l),[d]=s,{asset_fee:S,timestamp:_}=i,k=Math.max(1,e-_),x=d.volume.b_in.toString(),w=d.volume.b_out.toString(),I=d.liquidity.b.toString();n===0&&(x=d.volume.a_in.toString(),w=d.volume.a_out.toString(),I=d.liquidity.a.toString());let R=h.fromPermill(S),K=b.recalculateAssetFee(x,w,I,"9",r.toString(),h.toRaw(R).toString(),k.toString(),h.toRaw(m).toString(),h.toRaw(g).toString(),c.toString(),p.toString());return[o,Number(K)*1e6,l]}async getProtocolFee(t,e,i,s,a){let{assetIn:n,balanceIn:r}=t,{min_fee:o,max_fee:l,decay:c,amplification:p}=a||await this.api.constants.DynamicFees.ProtocolFeeParameters();if(!i||!s)return[o,o,l];let m=h.fromPermill(o),g=h.fromPermill(l),[d]=s,{protocol_fee:S,timestamp:_}=i,k=Math.max(1,e-_),x=d.volume.b_in.toString(),w=d.volume.b_out.toString(),I=d.liquidity.b.toString();n===0&&(x=d.volume.a_in.toString(),w=d.volume.a_out.toString(),I=d.liquidity.a.toString());let R=h.fromPermill(S),K=b.recalculateProtocolFee(x,w,I,"9",r.toString(),h.toRaw(R).toString(),k.toString(),h.toRaw(m).toString(),h.toRaw(g).toString(),c.toString(),p.toString());return[o,Number(K)*1e6,l]}subscribeEmaOracles(){let[t]=this.store.pools,i=t.tokens.map(s=>s.id).map(s=>this.getOraclePair(s)).map(s=>this.api.query.EmaOracle.Oracles.watchValue(re,s,oe,{at:"best"}).pipe(U(({value:a})=>a),rs(a=>a!==void 0),U((a,n)=>({value:a,index:n})),It(({index:a})=>{a>0&&this.log.trace("emaOracle.Oracles",s.join(":"))}),U(({value:a})=>({pair:s,value:a}))));return os(...i).pipe(Mt(()=>this.emaOracles.clear()),this.watchGuard("emaOracle.Oracles")).subscribe(s=>{let{pair:a,value:n}=s;this.emaOracles.set(n,a)})}subscribeDynamicFees(){return this.api.query.DynamicFees.AssetFee.watchEntries({at:"best"}).pipe(Lt((t,e)=>!e.deltas),U((t,e)=>({value:t,index:e})),It(({value:t,index:e})=>{e>0&&this.log.trace("dynamicFees.AssetFee",t.deltas?.upserted)}),Mt(()=>this.dynamicFees.clear()),this.watchGuard("dynamicFees.AssetFee")).subscribe(({value:{deltas:t}})=>{t?.upserted.forEach(e=>{let[i]=e.args;this.dynamicFees.set(e.value,i)})})}subscribeDynamicFeesConfig(){return this.api.query.DynamicFees.AssetFeeConfiguration.watchEntries({at:"best"}).pipe(Lt((t,e)=>!e.deltas),U((t,e)=>({value:t,index:e})),It(({value:t,index:e})=>{e>0&&this.log.trace("dynamicFees.AssetFeeConfiguration",t.deltas?.upserted)}),Mt(()=>this.dynamicFeesConfig.clear()),this.watchGuard("dynamicFees.AssetFeeConfiguration")).subscribe(({value:{deltas:t}})=>{t?.upserted.forEach(e=>{let[i]=e.args;this.dynamicFeesConfig.set(e.value,i)})})}subscribeBlock(){return this.watcher.bestBlock$.pipe(this.watchGuard("watcher.bestBlock")).subscribe(t=>{this.block=t})}subscribeAssets(){return this.api.query.Omnipool.Assets.watchEntries({at:"best"}).pipe(Lt((t,e)=>!e.deltas),U((t,e)=>({value:t,index:e})),It(({value:t,index:e})=>{e>0&&this.log.trace("omnipool.Assets",t.deltas?.upserted)}),this.watchGuard("omnipool.Assets")).subscribe(({value:{deltas:t}})=>{this.store.update(([e])=>{let i=t?.upserted.reduce((a,n)=>{let[r]=n.args;return a.set(r,n.value),a},new Map),s=e.tokens.map(a=>{let n=i?.get(a.id);return n?this.updateTokenState(a,n):a});return[{...e,tokens:s}]})})}subscribeUpdates(){let t=new ns;return t.add(this.subscribeAssets()),t.add(this.subscribeDynamicFees()),t.add(this.subscribeDynamicFeesConfig()),t.add(this.subscribeEmaOracles()),t.add(this.subscribeBlock()),t}updateTokenState(t,e){let{hub_reserve:i,shares:s,tradable:a,cap:n,protocol_shares:r}=e;return{...t,cap:n,hubReserves:i,protocolShares:r,shares:s,tradeable:a}}};var pe={};A(pe,{StableMath:()=>f,StableSwap:()=>q,StableSwapClient:()=>rt});import{calculate_in_given_out as cs,calculate_out_given_in as us,calculate_amplification as ps,calculate_add_one_asset as ms,calculate_liquidity_out_one_asset as ds,calculate_shares as gs,calculate_shares_for_amount as bs,calculate_spot_price_with_fee as hs,pool_account_name as Ps,recalculate_peg as ys}from"@galacticcouncil/math-stableswap";var f=class{static getPoolAddress(t){return Ps(t)}static defaultPegs(t){let e=[];for(let i=0;i<t;i++)e.push(["1","1"]);return e}static calculateAmplification(t,e,i,s,a){return ps(t,e,i,s,a)}static calculateInGivenOut(t,e,i,s,a,n,r){return cs(t,e,i,s,a,n,r)}static calculateAddOneAsset(t,e,i,s,a,n,r){return ms(t,e,i,s,a,n,r)}static calculateSharesForAmount(t,e,i,s,a,n,r){return bs(t,e,i,s,a,n,r)}static calculateOutGivenIn(t,e,i,s,a,n,r){return us(t,e,i,s,a,n,r)}static calculateLiquidityOutOneAsset(t,e,i,s,a,n,r){return ds(t,e,i,s,a,n,r)}static calculateShares(t,e,i,s,a,n){return gs(t,e,i,s,a,n)}static calculateSpotPriceWithFee(t,e,i,s,a,n,r,o){return hs(t,e,i,s,a,n,r,o)}static recalculatePegs(t,e,i,s,a,n){let r=ys(t,e,i,s,a,n);return JSON.parse(r)}};import{RUNTIME_DECIMALS as fs,big as ce}from"@galacticcouncil/common";var{FeeUtils:Y}=P,q=class u{type;address;tokens;maxInRatio;maxOutRatio;minTradingLimit;amplification;isRampPeriod;id;fee;totalIssuance;pegs;static fromPool(t){return new u(t)}constructor(t){this.type="Stableswap",this.address=t.address,this.tokens=t.tokens,this.maxInRatio=t.maxInRatio,this.maxOutRatio=t.maxOutRatio,this.minTradingLimit=t.minTradingLimit,this.amplification=t.amplification,this.isRampPeriod=t.isRampPeriod,this.id=t.id,this.fee=t.fee,this.totalIssuance=t.totalIssuance,this.pegs=t.pegs}validatePair(t,e){return!0}parsePair(t,e){let i=new Map(this.tokens.map(n=>[n.id,n])),s=i.get(t),a=i.get(e);if(s==null)throw new Error("Pool does not contain tokenIn");if(a==null)throw new Error("Pool does not contain tokenOut");return{assetIn:t,assetOut:e,balanceIn:s.balance,balanceOut:a.balance,decimalsIn:s.decimals,decimalsOut:a.decimals,tradeableIn:this.id===t?15:s.tradeable,tradeableOut:this.id===e?15:a.tradeable,assetInEd:s.existentialDeposit,assetOutEd:a.existentialDeposit}}validateAndBuy(t,e,i){let s=this.calculateInGivenOut(t,e),a=this.calculateInGivenOut(t,e,i),n=s===0n?0:D.calculateBuyFee(s,a),r=[],o=b.isSellAllowed(t.tradeableIn),l=b.isBuyAllowed(t.tradeableOut);return(!o||!l)&&r.push("TradeNotAllowed"),(e<this.minTradingLimit||s<t.assetInEd)&&r.push("InsufficientTradingAmount"),{amountIn:a,calculatedIn:s,amountOut:e,feePct:n,errors:r}}validateAndSell(t,e,i){let s=this.calculateOutGivenIn(t,e),a=this.calculateOutGivenIn(t,e,i),n=D.calculateSellFee(s,a),r=[],o=b.isSellAllowed(t.tradeableIn),l=b.isBuyAllowed(t.tradeableOut);return(!o||!l)&&r.push("TradeNotAllowed"),(e<this.minTradingLimit||s<t.assetOutEd)&&r.push("InsufficientTradingAmount"),{amountIn:e,calculatedOut:s,amountOut:a,feePct:n,errors:r}}calculateIn(t,e,i){let s=f.calculateInGivenOut(this.getReserves(),Number(t.assetIn),Number(t.assetOut),e.toString(),this.amplification.toString(),i?Y.toRaw(i.fee).toString():"0",this.getPegs()),a=BigInt(s);return a<0n?0n:a}calculateAddOneAsset(t,e,i){let s=f.calculateAddOneAsset(this.getReserves(),e.toString(),Number(t.assetIn),this.amplification.toString(),this.totalIssuance.toString(),i?Y.toRaw(i.fee).toString():"0",this.getPegs()),a=BigInt(s);return a<0n?0n:a}calculateSharesForAmount(t,e,i){let s=f.calculateSharesForAmount(this.getReserves(),Number(t.assetOut),e.toString(),this.amplification.toString(),this.totalIssuance.toString(),i?Y.toRaw(i.fee).toString():"0",this.getPegs()),a=BigInt(s);return a<0n?0n:a}calculateInGivenOut(t,e,i){return t.assetOut==this.id?this.calculateAddOneAsset(t,e,i):t.assetIn==this.id?this.calculateSharesForAmount(t,e,i):this.calculateIn(t,e,i)}spotPriceInGivenOut(t){let e=f.calculateSpotPriceWithFee(this.id.toString(),this.getReserves(),this.amplification.toString(),t.assetOut.toString(),t.assetIn.toString(),this.totalIssuance.toString(),"0",this.getPegs());return this.normalizeSpot(BigInt(e),t.assetOut===this.id,t.assetIn===this.id,t.decimalsOut,t.decimalsIn)}calculateOut(t,e,i){let s=f.calculateOutGivenIn(this.getReserves(),Number(t.assetIn),Number(t.assetOut),e.toString(),this.amplification.toString(),i?Y.toRaw(i.fee).toString():"0",this.getPegs()),a=BigInt(s);return a<0n?0n:a}calculateWithdrawOneAsset(t,e,i){let s=f.calculateLiquidityOutOneAsset(this.getReserves(),e.toString(),Number(t.assetOut),this.amplification.toString(),this.totalIssuance.toString(),i?Y.toRaw(i.fee).toString():"0",this.getPegs()),a=BigInt(s);return a<0n?0n:a}calculateShares(t,e,i){let s=f.calculateShares(this.getReserves(),this.getAssets(t.assetIn,e),this.amplification.toString(),this.totalIssuance.toString(),i?Y.toRaw(i.fee).toString():"0",this.getPegs()),a=BigInt(s);return a<0n?0n:a}calculateOutGivenIn(t,e,i){return t.assetIn==this.id?this.calculateWithdrawOneAsset(t,e,i):t.assetOut==this.id?this.calculateShares(t,e,i):this.calculateOut(t,e,i)}spotPriceOutGivenIn(t){let e=f.calculateSpotPriceWithFee(this.id.toString(),this.getReserves(),this.amplification.toString(),t.assetIn.toString(),t.assetOut.toString(),this.totalIssuance.toString(),"0",this.getPegs());return this.normalizeSpot(BigInt(e),t.assetIn===this.id,t.assetOut===this.id,t.decimalsIn,t.decimalsOut)}getPegs(){return JSON.stringify(this.pegs)}getReserves(){let t=this.tokens.filter(e=>e.id!=this.id).map(({id:e,balance:i,decimals:s})=>({asset_id:e,amount:i,decimals:s}));return JSON.stringify(t,j.jsonFormatter)}getAssets(t,e){let i={asset_id:Number(t),amount:e.toString()};return JSON.stringify([i],j.jsonFormatter)}normalizeSpot(t,e,i,s,a){return e?t*ce.pow10(fs-a):i?t/ce.pow10(a-s):t}};import{AccountId as Ss,CompatibilityLevel as vs}from"polkadot-api";import{toHex as xs}from"@polkadot-api/utils";import{blake2b as Is}from"@noble/hashes/blake2b";import{Subscription as Os,distinctUntilChanged as ws,map as wt,merge as Ts,tap as ue}from"rxjs";import{HYDRATION_SS58_PREFIX as As,RUNTIME_DECIMALS as Bs}from"@galacticcouncil/common";var{FeeUtils:Fs}=P,rt=class extends v{poolsData=new Map([]);getPoolType(){return"Stableswap"}getPoolAddress(t){let e=f.getPoolAddress(t),i=Is(e,{dkLen:32}),s=xs(i);return Ss(As).dec(s)}async getPoolLimits(){return{maxInRatio:0n,maxOutRatio:0n,minTradingLimit:await this.api.constants.Stableswap.MinTradingLimit()}}getPoolAmplification(t,e){let{initial_amplification:i,final_amplification:s,initial_block:a,final_block:n}=t,r=f.calculateAmplification(i.toString(),s.toString(),a.toString(),n.toString(),e.toString()),o=Number(r)<s;return{amplification:BigInt(r),isRampPeriod:o}}async getPoolTokens(t,e){let i=this.getPoolAddress(t),s=e.assets.map(async a=>{let[n,r,o]=await Promise.all([this.api.query.Stableswap.AssetTradability.getValue(t,a),this.api.query.AssetRegistry.Assets.getValue(a),this.balance.getBalance(i,a)]);return{id:a,decimals:r?.decimals,existentialDeposit:r?.existential_deposit,balance:o.transferable,tradeable:n,type:r?.asset_type.type}});return Promise.all(s)}async isSupported(){return(await this.api.getStaticApis()).compat.query.Stableswap.Pools.isCompatible(vs.BackwardsCompatible)}async loadPools(){let[t,e,i]=await Promise.all([this.api.query.Stableswap.Pools.getEntries({at:"best"}),this.api.query.System.Number.getValue({at:"best"}),this.getPoolLimits()]),s=t.map(async({keyArgs:a,value:n})=>{let[r]=a,o=this.getPoolAddress(r),[l,c,p]=await Promise.all([this.getPoolTokens(r,n),this.api.query.Stableswap.PoolPegs.getValue(r,{at:"best"}),this.api.query.Tokens.TotalIssuance.getValue(r,{at:"best"})]),m=this.getPoolAmplification(n,e),g=c?this.getRecentPegs(c):this.getDefaultPegs(n);return l.push({id:r,tradeable:15,balance:p,decimals:Bs}),this.poolsData.set(r,n),{address:o,id:r,type:"Stableswap",fee:Fs.fromPermill(n.fee),tokens:l,totalIssuance:p,pegs:g,...i,...m}});return Promise.all(s)}async getPoolFees(t,e){return{fee:this.store.pools.find(s=>s.address===e).fee}}getDefaultPegs(t){return f.defaultPegs(t.assets.length)}getRecentPegs(t){let{current:e}=t;return Array.from(e.entries()).map(([i,s])=>s.map(a=>a.toString()))}subscribeIssuance(){let e=this.store.pools.map(i=>i.id).map(i=>this.api.query.Tokens.TotalIssuance.watchValue(i,{at:"best"}).pipe(wt(({value:s})=>s),wt((s,a)=>({value:s,index:a})),ue(({index:s,value:a})=>{s>0&&this.log.trace("tokens.TotalIssuance",i,a)}),wt(({value:s})=>({id:i,value:s}))));return Ts(...e).pipe(this.watchGuard("tokens.TotalIssuance")).subscribe(i=>{let{id:s,value:a}=i;this.store.update(n=>{let r=[];return n.filter(o=>o.id===s).forEach(o=>{let l=o.tokens.map(c=>c.id===s?{...c,balance:a}:c);r.push({...o,tokens:l,totalIssuance:a})}),r})})}subscribePoolPegs(){return this.api.query.Stableswap.PoolPegs.watchEntries({at:"best"}).pipe(ws((t,e)=>!e.deltas),wt((t,e)=>({value:t,index:e})),ue(({value:t,index:e})=>{e>0&&this.log.trace("stableswap.PoolPegs",t.deltas?.upserted)}),this.watchGuard("stableswap.PoolPegs")).subscribe({error:t=>this.log.error("stableswap.PoolPegs",t),next:({value:{deltas:t}})=>{this.store.update(e=>{let i=[],s=new Map(e.map(a=>[a.id,a]));return t?.upserted.forEach(({args:a,value:n})=>{let[r]=a,o=s.get(r);if(o){let l=this.getRecentPegs(n);i.push({...o,pegs:l})}}),i})}})}subscribeBlock(){return this.watcher.bestBlock$.pipe(this.watchGuard("watcher.bestBlock")).subscribe(t=>{this.store.update(e=>{let i=[];return e.filter(s=>s.isRampPeriod).forEach(s=>{let a=this.poolsData.get(s.id);if(a){let n=this.getPoolAmplification(a,t);i.push({...s,...n})}}),i})})}subscribeUpdates(){let t=new Os;return t.add(this.subscribePoolPegs()),t.add(this.subscribeIssuance()),this.hasOnRamps()&&t.add(this.subscribeBlock()),t}hasOnRamps(){return this.store.pools.filter(t=>t.isRampPeriod).length>0}};var de={};A(de,{XykMath:()=>L,XykPool:()=>ot,XykPoolClient:()=>lt});import{calculate_in_given_out as _s,calculate_out_given_in as ks,calculate_pool_trade_fee as Rs,get_spot_price as Es,calculate_liquidity_in as Cs,calculate_shares as Ls,calculate_spot_price as Ms,calculate_spot_price_with_fee as Ds,calculate_liquidity_out_asset_a as Hs,calculate_liquidity_out_asset_b as Gs}from"@galacticcouncil/math-xyk";var L=class{static getSpotPrice(t,e,i){return Es(t,e,i)}static calculateInGivenOut(t,e,i){return _s(t,e,i)}static calculateOutGivenIn(t,e,i){return ks(t,e,i)}static calculatePoolTradeFee(t,e,i){return Rs(t,e,i)}static calculateLiquidityIn(t,e,i){return Cs(t,e,i)}static calculateSpotPrice(t,e){return Ms(t,e)}static calculateSpotPriceWithFee(t,e,i,s){return Ds(t,e,i,s)}static calculateShares(t,e,i){return Ls(t,e,i)}static calculateLiquidityOutAssetA(t,e,i,s){return Hs(t,e,i,s)}static calculateLiquidityOutAssetB(t,e,i,s){return Gs(t,e,i,s)}};import{big as qs}from"@galacticcouncil/common";var{FeeUtils:me}=P,ot=class u{type;address;tokens;maxInRatio;maxOutRatio;minTradingLimit;static fromPool(t){return new u(t)}constructor(t){this.type="XYK",this.address=t.address,this.tokens=t.tokens,this.maxInRatio=t.maxInRatio,this.maxOutRatio=t.maxOutRatio,this.minTradingLimit=t.minTradingLimit}validatePair(t,e){return!0}parsePair(t,e){let i=new Map(this.tokens.map(n=>[n.id,n])),s=i.get(t),a=i.get(e);if(s==null)throw new Error("Pool does not contain tokenIn");if(a==null)throw new Error("Pool does not contain tokenOut");return{assetIn:t,assetOut:e,decimalsIn:s.decimals,decimalsOut:a.decimals,balanceIn:s.balance,balanceOut:a.balance,assetInEd:s.existentialDeposit,assetOutEd:a.existentialDeposit}}validateAndBuy(t,e,i){let s=this.calculateInGivenOut(t,e),a=this.calculateTradeFee(s,i),n=me.toPct(i.exchangeFee),r=s+a,o=[];(e<this.minTradingLimit||s<t.assetInEd)&&o.push("InsufficientTradingAmount");let l=t.balanceOut/this.maxOutRatio;e>l&&o.push("MaxOutRatioExceeded");let c=t.balanceIn/this.maxInRatio;return r>c&&o.push("MaxInRatioExceeded"),{amountIn:r,calculatedIn:s,amountOut:e,feePct:n,errors:o}}validateAndSell(t,e,i){let s=this.calculateOutGivenIn(t,e),a=this.calculateTradeFee(s,i),n=me.toPct(i.exchangeFee),r=s-a,o=[];(e<this.minTradingLimit||s<t.assetOutEd)&&o.push("InsufficientTradingAmount");let l=t.balanceIn/this.maxInRatio;e>l&&o.push("MaxInRatioExceeded");let c=t.balanceOut/this.maxOutRatio;return r>c&&o.push("MaxOutRatioExceeded"),{amountIn:e,calculatedOut:s,amountOut:r,feePct:n,errors:o}}calculateInGivenOut(t,e){let i=L.calculateInGivenOut(t.balanceIn.toString(),t.balanceOut.toString(),e.toString()),s=BigInt(i);return s<0n?0n:s}calculateOutGivenIn(t,e){let i=L.calculateOutGivenIn(t.balanceIn.toString(),t.balanceOut.toString(),e.toString()),s=BigInt(i);return s<0n?0n:s}spotPriceInGivenOut(t){let e=L.calculateSpotPrice(t.balanceOut.toString(),t.balanceIn.toString());return this.normalizeSpot(BigInt(e),t.decimalsOut,t.decimalsIn)}spotPriceOutGivenIn(t){let e=L.calculateSpotPrice(t.balanceIn.toString(),t.balanceOut.toString());return this.normalizeSpot(BigInt(e),t.decimalsIn,t.decimalsOut)}calculateTradeFee(t,e){let i=L.calculatePoolTradeFee(t.toString(),e.exchangeFee[0],e.exchangeFee[1]);return BigInt(i)}normalizeSpot(t,e,i){let s=e-i;if(s===0)return t;let a=qs.pow10(Math.abs(s));return s>0?t*a:t/a}};import{CompatibilityLevel as Ns}from"polkadot-api";import{Subscription as Vs}from"rxjs";var lt=class extends v{decimals=new Map([]);getPoolType(){return"XYK"}async withOverride(t){this.decimals=t?new Map(t.map(e=>[e.id,e.decimals])):new Map}async getPoolLimits(){let[t,e,i]=await Promise.all([this.api.constants.XYK.MaxInRatio(),this.api.constants.XYK.MaxOutRatio(),this.api.constants.XYK.MinTradingLimit()]);return{maxInRatio:t,maxOutRatio:e,minTradingLimit:i}}async isSupported(){return(await this.api.getStaticApis()).compat.query.XYK.PoolAssets.isCompatible(Ns.BackwardsCompatible)}async loadPools(){let[t,e]=await Promise.all([this.api.query.XYK.PoolAssets.getEntries(),this.getPoolLimits()]),i=t.map(async({keyArgs:s,value:a})=>{let[n]=s,[r,o]=a,[l,c,p,m]=await Promise.all([this.balance.getBalance(n,r),this.api.query.AssetRegistry.Assets.getValue(r),this.balance.getBalance(n,o),this.api.query.AssetRegistry.Assets.getValue(o)]);return{address:n,type:"XYK",tokens:[{id:r,decimals:c?.decimals||this.decimals.get(r),existentialDeposit:c?.existential_deposit,balance:l.transferable,type:c?.asset_type.type},{id:o,decimals:m?.decimals||this.decimals.get(o),existentialDeposit:m?.existential_deposit,balance:p.transferable,type:m?.asset_type.type}],...e}});return Promise.all(i)}async getPoolFees(){return{exchangeFee:await this.getExchangeFee()}}async getExchangeFee(){return await this.api.constants.XYK.GetExchangeFee()}subscribeUpdates(){return Vs.EMPTY}};var Se={};A(Se,{AavePool:()=>ct,AavePoolClient:()=>ut});import{big as ge,RUNTIME_DECIMALS as be}from"@galacticcouncil/common";var ct=class u{type;address;tokens;maxInRatio;maxOutRatio;minTradingLimit;static fromPool(t){return new u(t)}constructor(t){this.type="Aave",this.address=t.address,this.tokens=t.tokens,this.maxInRatio=t.maxInRatio,this.maxOutRatio=t.maxOutRatio,this.minTradingLimit=t.minTradingLimit}validatePair(t,e){return!0}parsePair(t,e){let i=new Map(this.tokens.map(n=>[n.id,n])),s=i.get(t),a=i.get(e);if(s==null)throw new Error("Pool does not contain tokenIn");if(a==null)throw new Error("Pool does not contain tokenOut");return{assetIn:t,assetOut:e,balanceIn:s.balance,balanceOut:a.balance,decimalsIn:s.decimals,decimalsOut:a.decimals,assetInEd:0n,assetOutEd:0n}}validateAndBuy(t,e,i){let s=this.calculateInGivenOut(t,e),a=[];return e>t.balanceOut&&a.push("TradeNotAllowed"),{amountIn:s,calculatedIn:s,amountOut:e,feePct:0,errors:a}}validateAndSell(t,e,i){let s=this.calculateOutGivenIn(t,e),a=[];return s>t.balanceOut&&a.push("TradeNotAllowed"),{amountIn:e,calculatedOut:s,amountOut:s,feePct:0,errors:a}}calculateInGivenOut(t,e){return e}calculateOutGivenIn(t,e){return e}spotPriceInGivenOut(t){return ge.toBigInt(1,be)}spotPriceOutGivenIn(t){return ge.toBigInt(1,be)}calculateTradeFee(t,e){return 0n}};import{AccountId as Ws,Binary as $s}from"polkadot-api";import{toHex as Us}from"@polkadot-api/utils";import{Subscription as Pe,filter as Dt,map as ye,mergeMap as fe}from"rxjs";import{decodeEventLog as Ys}from"viem";import{erc20 as Xs,HYDRATION_SS58_PREFIX as zs}from"@galacticcouncil/common";var he=[{anonymous:!1,inputs:[{indexed:!0,internalType:"address",name:"reserve",type:"address"},{indexed:!1,internalType:"address",name:"user",type:"address"},{indexed:!0,internalType:"address",name:"onBehalfOf",type:"address"},{indexed:!1,internalType:"uint256",name:"amount",type:"uint256"},{indexed:!0,internalType:"uint16",name:"referralCode",type:"uint16"}],name:"Supply",type:"event"},{anonymous:!1,inputs:[{indexed:!0,internalType:"address",name:"reserve",type:"address"},{indexed:!0,internalType:"address",name:"user",type:"address"},{indexed:!0,internalType:"address",name:"to",type:"address"},{indexed:!1,internalType:"uint256",name:"amount",type:"uint256"}],name:"Withdraw",type:"event"},{anonymous:!1,inputs:[{indexed:!0,internalType:"address",name:"reserve",type:"address"},{indexed:!1,internalType:"address",name:"user",type:"address"},{indexed:!0,internalType:"address",name:"onBehalfOf",type:"address"},{indexed:!1,internalType:"uint256",name:"amount",type:"uint256"},{indexed:!1,internalType:"enum DataTypes.InterestRateMode",name:"interestRateMode",type:"uint8"},{indexed:!1,internalType:"uint256",name:"borrowRate",type:"uint256"},{indexed:!0,internalType:"uint16",name:"referralCode",type:"uint16"}],name:"Borrow",type:"event"},{anonymous:!1,inputs:[{indexed:!0,internalType:"address",name:"reserve",type:"address"},{indexed:!0,internalType:"address",name:"user",type:"address"},{indexed:!0,internalType:"address",name:"repayer",type:"address"},{indexed:!1,internalType:"uint256",name:"amount",type:"uint256"},{indexed:!1,internalType:"bool",name:"useATokens",type:"bool"}],name:"Repay",type:"event"}];var{ERC20:Ks}=Xs,js=["Supply","Withdraw","Repay","Borrow"],ut=class extends v{getPoolType(){return"Aave"}async isSupported(){return!0}getPoolId(t,e){let i=t+"/"+e,s=new TextEncoder().encode(i.padEnd(32,"\0")),a=Us(s);return Ws(zs).dec(a)}getPoolLimits(){return{maxInRatio:0n,maxOutRatio:0n,minTradingLimit:0n}}async loadPools(){let e=(await this.api.apis.AaveTradeExecutor.pools({at:"best"})).map(async({reserve:i,atoken:s,liqudity_in:a,liqudity_out:n})=>{let[r,o,l,c]=await Promise.all([this.api.query.AssetRegistry.Assets.getValue(i),this.api.query.AssetRegistry.AssetLocations.getValue(i),this.api.query.AssetRegistry.Assets.getValue(s),this.api.query.AssetRegistry.AssetLocations.getValue(s)]);return{address:this.getPoolId(i,s),type:"Aave",tokens:[{id:i,decimals:r?.decimals,existentialDeposit:r?.existential_deposit,balance:a,location:o,type:r?.asset_type.type},{id:s,decimals:l?.decimals,existentialDeposit:l?.existential_deposit,balance:n,location:c,type:l?.asset_type.type}],...this.getPoolLimits()}});return Promise.all(e)}async getPoolDelta(t){let[e,i]=t.tokens,{liqudity_in:s,liqudity_out:a}=await this.api.apis.AaveTradeExecutor.pool(e.id,i.id,{at:"best"});return t.tokens.map(n=>{let r=n.id===e.id?s:a;return{...n,balance:r}})}async getPoolFees(){return{}}getReserveH160Id(t){if(t.type==="Erc20"&&t.location){let e=t.location.interior;if(e.type==="X1"&&e.value.type==="AccountKey20"){let{value:i}=e.value;return i.key}throw new Error("Invalid aave reserve multilocation")}return Ks.fromAssetId(t.id)}parseRouterLog(t){let{asset_in:e,asset_out:i}=t;return{assetIn:e,assetOut:i,key:`${e}:${i}`}}parseEvmLog(t){let{topics:e,data:i}=t.log,s=e,a=$s.toHex(i);try{let{eventName:n,args:r}=Ys({abi:he,topics:s,data:a}),o=r.reserve.toLowerCase();return{eventName:n,reserve:o,key:`${n}:${o}`}}catch{return}}subscribeRouterExecuted(){let e=this.store.pools.map(i=>i.tokens).map(([i,s])=>s).map(i=>i.id);return this.api.event.Router.Executed.watch().pipe(fe(({events:i})=>i),ye(({payload:i})=>this.parseRouterLog(i)),Dt(({assetIn:i,assetOut:s})=>e.includes(i)||e.includes(s)),this.watchGuard("router.Execute")).subscribe(({assetIn:i,assetOut:s,key:a})=>{this.log.trace("router.Executed",a),this.store.update(async n=>{let r=[];for(let o of n){let[l,c]=o.tokens;if(c.id===i||c.id===s){let m=await this.getPoolDelta(o);r.push({...o,tokens:m})}}return r})})}subscribeEvmLog(){return this.api.event.EVM.Log.watch().pipe(fe(({events:t})=>t),ye(({payload:t})=>this.parseEvmLog(t)),Dt(t=>t!==void 0),Dt(({eventName:t})=>js.includes(t)),this.watchGuard("evm.Log")).subscribe(({reserve:t,eventName:e})=>{this.log.trace(`evm.Log.${e}`,t),this.store.update(async i=>{let s=[];for(let a of i){let[n]=a.tokens;if(this.getReserveH160Id(n).toLowerCase()===t){let o=await this.getPoolDelta(a);s.push({...a,tokens:o})}}return s})})}subscribeBalances(){return Pe.EMPTY}subscribeUpdates(){let t=new Pe;return t.add(this.subscribeRouterExecuted()),t.add(this.subscribeEvmLog()),t}};var Ie={};A(Ie,{HsmMath:()=>O,HsmPool:()=>pt,HsmPoolClient:()=>gt});import{calculate_collateral_in_given_hollar_out as Qs,calculate_collateral_out_given_hollar_in as Js,calculate_hollar_in_given_collateral_out as Zs,calculate_hollar_out_given_collateral_in as ta,calculate_imbalance as ea,calculate_max_price as ia,calculate_buyback_limit as sa,calculate_buyback_price_with_fee as aa}from"@galacticcouncil/math-hsm";var O=class{static calculateCollateralInGivenHollarOut(t,e,i){return Qs(t,e,i)}static calculateCollateralOutGivenHollarIn(t,e,i){return Js(t,e,i)}static calculateHollarOutGivenCollateralIn(t,e,i){return ta(t,e,i)}static calculateHollarInGivenCollateralOut(t,e,i){return Zs(t,e,i)}static calculateImbalance(t,e,i){return ea(t,e,i)}static calculateBuybackLimit(t,e){return sa(t,e)}static calculateBuybackPriceWithFee(t,e,i){return aa(t,e,i)}static calculateMaxPrice(t,e){return ia(t,e)}};import{big as M,RUNTIME_DECIMALS as Tt}from"@galacticcouncil/common";var{FeeUtils:X}=P,pt=class u extends q{hsmAddress;hsmMintCapacity;hollarId;hollarH160;collateralId;collateralBalance;maxBuyPriceCoefficient;maxInHolding;purchaseFee;buyBackFee;buyBackRate;static fromPool(t){return new u(t)}constructor(t){super(t),this.type="HSM",this.hsmAddress=t.hsmAddress,this.hsmMintCapacity=t.hsmMintCapacity,this.hollarId=t.hollarId,this.hollarH160=t.hollarH160,this.collateralId=t.collateralId,this.collateralBalance=t.collateralBalance,this.maxBuyPriceCoefficient=t.maxBuyPriceCoefficient,this.maxInHolding=t.maxInHolding,this.purchaseFee=t.purchaseFee,this.buyBackFee=t.buyBackFee,this.buyBackRate=t.buyBackRate}validatePair(t,e){return!0}parsePair(t,e){return super.parsePair(t,e)}validateTradeHollarIn(t,e,i){let s=this.parsePair(t.assetOut,t.assetIn),a=super.calculateInGivenOut(s,e,{fee:this.fee}),n=this.calculateBuybackLimit(t);e>n&&i.push("MaxBuyBackExceeded");let r=this.calculateMaxPrice(t);return this.calculateBuyPrice(t,e,a)>r&&i.push("MaxBuyPriceExceeded"),a>this.collateralBalance&&i.push("InsufficientCollateral"),i}validateTradeHollarOut(t,e,i){return this.collateralBalance+t>this.maxInHolding&&i.push("MaxHoldingExceeded"),e>this.hsmMintCapacity&&i.push("FacilitatorCapacityExceeded"),i}validateTradeConstraints(t,e,i){let s=[];return t.assetIn===this.hollarId?this.validateTradeHollarIn(t,e,s):this.validateTradeHollarOut(e,i,s)}validateAndBuy(t,e){let i=this.calculateInGivenOut(t,e),s=this.validateTradeConstraints(t,i,e);return{amountIn:i,calculatedIn:i,amountOut:e,feePct:0,errors:s}}validateAndSell(t,e){let i=this.calculateOutGivenIn(t,e),s=this.validateTradeConstraints(t,e,i);return{amountIn:e,calculatedOut:i,amountOut:i,feePct:0,errors:s}}calculateHollarInGivenCollateralOut(t,e){let i=super.calculateInGivenOut(t,e,{fee:this.fee}),s=O.calculateHollarInGivenCollateralOut(e.toString(),i.toString(),X.toRaw(this.buyBackFee).toString());return BigInt(s)}calculateCollateralInGivenHollarOut(t){let e=this.getCollateralPeg(),i=O.calculateCollateralInGivenHollarOut(t.toString(),JSON.stringify(e),X.toRaw(this.purchaseFee).toString());return BigInt(i)}calculateInGivenOut(t,e){return t.assetOut==this.hollarId?this.calculateCollateralInGivenHollarOut(e):this.calculateHollarInGivenCollateralOut(t,e)}calculateCollateralOutGivenHollarIn(t,e){let i=super.calculateOutGivenIn(t,e,{fee:this.fee}),s=O.calculateCollateralOutGivenHollarIn(e.toString(),i.toString(),X.toRaw(this.buyBackFee).toString());return BigInt(s)}calculateHollarOutGivenCollateralIn(t){let e=this.getCollateralPeg(),i=O.calculateHollarOutGivenCollateralIn(t.toString(),JSON.stringify(e),X.toRaw(this.purchaseFee).toString());return BigInt(i)}calculateOutGivenIn(t,e){return t.assetIn==this.hollarId?this.calculateCollateralOutGivenHollarIn(t,e):this.calculateHollarOutGivenCollateralIn(e)}calculateImbalance(t){let e=this.getCollateralPeg(),i=O.calculateImbalance(t.balanceIn.toString(),JSON.stringify(e),t.balanceOut.toString());return BigInt(i)}calculateBuybackLimit(t){let e=this.calculateImbalance(t),i=O.calculateBuybackLimit(e.toString(),X.toRaw(this.buyBackRate).toString());return BigInt(i)}calculateBuyPrice(t,e,i){let s=O.calculateBuybackPriceWithFee(i.toString(),e.toString(),X.toRaw(this.buyBackFee).toString()),[a,n]=JSON.parse(s),r=M.pow10(t.decimalsIn+Tt-t.decimalsOut);return BigInt(a)*r/BigInt(n)}calculateMaxPrice(t){let e=this.getCollateralPeg(),i=O.calculateMaxPrice(JSON.stringify(e),this.maxBuyPriceCoefficient.toString()),[s,a]=JSON.parse(i),n=M.pow10(Tt-t.decimalsOut);return BigInt(s)*n/BigInt(a)}spotPriceInGivenOut(t){let e=M.toBigInt(1,t.decimalsOut),s=this.calculateInGivenOut(t,e)*M.pow10(Tt-t.decimalsOut);return this.normalizeSpotPrice(s,t.decimalsOut,t.decimalsIn)}spotPriceOutGivenIn(t){let e=M.toBigInt(1,t.decimalsIn),s=this.calculateOutGivenIn(t,e)*M.pow10(Tt-t.decimalsIn);return this.normalizeSpotPrice(s,t.decimalsIn,t.decimalsOut)}getCollateralPeg(){let t=this.tokens.findIndex(s=>s.id!==this.hollarId),e=this.pegs[t],i=this.tokens[t].decimals;return this.isDefaultPeg(e)?[M.toBigInt(1,18).toString(),M.toBigInt(1,i).toString()]:e}isDefaultPeg(t){let[e,i]=t;return Array.isArray(t)&&t.length===2&&e==="1"&&i==="1"}normalizeSpotPrice(t,e,i){let s=e-i;if(s===0)return t;let a=M.pow10(Math.abs(s));return s>0?t*a:t/a}};import{AccountId as na,Binary as ra,CompatibilityLevel as oa}from"polkadot-api";import{toHex as la}from"@polkadot-api/utils";import{Subscription as Ht,combineLatest as ca,filter as ve,map as Gt,mergeMap as ua,pairwise as pa}from"rxjs";import{decodeEventLog as ma}from"viem";import{h160 as da,HYDRATION_SS58_PREFIX as ga}from"@galacticcouncil/common";var mt=[{inputs:[{internalType:"address",name:"facilitator",type:"address"}],name:"getFacilitator",outputs:[{type:"tuple",components:[{name:"addr",type:"address"},{name:"label",type:"bytes32"},{name:"bucketCapacity",type:"uint128"},{name:"bucketLevel",type:"uint128"}]}],stateMutability:"view",type:"function"},{inputs:[{internalType:"address",name:"facilitator",type:"address"}],name:"getFacilitatorBucket",outputs:[{internalType:"uint256",name:"",type:"uint256"},{internalType:"uint256",name:"",type:"uint256"}],stateMutability:"view",type:"function"},{inputs:[],name:"getFacilitatorsList",outputs:[{internalType:"address[]",name:"",type:"address[]"}],stateMutability:"view",type:"function"},{anonymous:!1,inputs:[{indexed:!0,internalType:"address",name:"facilitatorAddress",type:"address"},{indexed:!0,internalType:"bytes32",name:"label",type:"bytes32"},{indexed:!1,internalType:"uint256",name:"bucketCapacity",type:"uint256"}],name:"FacilitatorAdded",type:"event"},{anonymous:!1,inputs:[{indexed:!0,internalType:"address",name:"facilitatorAddress",type:"address"},{indexed:!1,internalType:"uint256",name:"oldCapacity",type:"uint256"},{indexed:!1,internalType:"uint256",name:"newCapacity",type:"uint256"}],name:"FacilitatorBucketCapacityUpdated",type:"event"},{anonymous:!1,inputs:[{indexed:!0,internalType:"address",name:"facilitatorAddress",type:"address"},{indexed:!1,internalType:"uint256",name:"oldLevel",type:"uint256"},{indexed:!1,internalType:"uint256",name:"newLevel",type:"uint256"}],name:"FacilitatorBucketLevelUpdated",type:"event"},{anonymous:!1,inputs:[{indexed:!0,internalType:"address",name:"facilitatorAddress",type:"address"}],name:"FacilitatorRemoved",type:"event"}];var dt=class{client;constructor(t){this.client=t.getWsProvider()}async getFacilitatorCapacity(t,e){let[i,s]=await this.client.readContract({abi:mt,address:t,functionName:"getFacilitatorBucket",args:[e]});return i-s}};var{FeeUtils:qt}=P,{H160:xe}=da,ba=["FacilitatorBucketCapacityUpdated","FacilitatorBucketLevelUpdated"],gt=class extends v{ghoClient;stableClient;constructor(t,e,i){super(t,e),this.stableClient=i,this.ghoClient=new dt(e)}getPoolType(){return"HSM"}getPoolId(t){return this.getPoolAddress("hsm:"+t)}getFacilitatorAddress(){return this.getPoolAddress("modlpy/hsmod")}getHollarAddress(t){if(t){let e=t.interior;if(e.type==="X1"&&e.value.type==="AccountKey20"){let{value:i}=e.value;return i.key}}throw Error("Invalid hollar multilocation")}getPoolAddress(t){let e=t.padEnd(32,"\0"),i=new TextEncoder().encode(e),s=la(i);return na(ga).dec(s)}async isSupported(){return(await this.api.getStaticApis()).compat.query.HSM.Collaterals.isCompatible(oa.BackwardsCompatible)}async loadPools(){let t=await this.api.constants.HSM.HollarId(),[e,i,s]=await Promise.all([this.api.query.AssetRegistry.AssetLocations.getValue(t),this.api.query.HSM.Collaterals.getEntries({at:"best"}),this.stableClient.getPools()]);if(i.length===0)return[];let a=this.getFacilitatorAddress(),n=xe.fromAny(a),r=this.getHollarAddress(e),o=await this.ghoClient.getFacilitatorCapacity(r,n),l=i.map(async({keyArgs:p,value:m})=>{let[g]=p,{pool_id:d,max_buy_price_coefficient:S,max_in_holding:_,purchase_fee:k,buy_back_fee:x,buyback_rate:w}=m,I=s.find(R=>R.id===d);if(I){let R=this.getPoolId(d),K=await this.balance.getBalance(a,g);return{...I,address:R,type:"HSM",tokens:I.tokens.filter(Oe=>Oe.id!==d),hsmAddress:a,hsmMintCapacity:o,hollarId:t,hollarH160:r,collateralId:g,collateralBalance:K.transferable,maxBuyPriceCoefficient:S,maxInHolding:_,purchaseFee:qt.fromPermill(k),buyBackFee:qt.fromPermill(x),buyBackRate:qt.fromPerbill(w)}}});return(await Promise.all(l)).filter(p=>p!==null)}async getPoolFees(){return{}}parseEvmLog(t){let{topics:e,data:i}=t.log,s=e,a=ra.toHex(i);try{let{eventName:n,args:r}=ma({abi:mt,topics:s,data:a}),o=r.facilitatorAddress.toLowerCase();return{eventName:n,facilitator:o,key:`${n}:${o}`}}catch{return}}subscribeEvmLog(){return this.api.event.EVM.Log.watch().pipe(ua(({events:t})=>t),Gt(({payload:t})=>this.parseEvmLog(t)),ve(t=>t!==void 0),ve(({eventName:t})=>ba.includes(t)),this.watchGuard("evm.Log")).subscribe(({eventName:t,facilitator:e})=>{this.log.trace(`evm.Log.${t}`,e),this.store.update(async i=>{let s=[],[{hsmAddress:a,hollarH160:n}]=i,r=xe.fromAny(a);if(r.toLowerCase()===e){let l=await this.ghoClient.getFacilitatorCapacity(n,r);for(let c of i)s.push({...c,hsmMintCapacity:l})}return s})})}subscribeCollateralBalance(){let t=[],e=[];this.store.pools.forEach(a=>{let{tokens:n,collateralId:r}=a;n.find(l=>l.id===r).type==="Erc20"?e.push(r):t.push(r)});let[{hsmAddress:i}]=this.store.pools,s=[];if(t.length>0){let a=this.balance.watchTokensBalance(i);s.push(a)}if(e.length>0){let a=this.balance.watchErc20Balance(i,e);s.push(a)}return s.length>0?ca(s).pipe(Gt(a=>a.flat()),pa(),Gt(([a,n])=>this.balance.getDeltas(a,n)),this.watchGuard("balances")).subscribe(a=>{this.store.update(n=>{let r=[],o=new Map(n.map(l=>[l.collateralId,l]));return a.forEach(({id:l,balance:c})=>{let p=o.get(l);p&&(this.log.trace("balances",{id:l,balance:c}),r.push({...p,collateralBalance:c.transferable}))}),r})}):Ht.EMPTY}subscribeStableswapUpdates(){return this.stableClient.getSubscriber().pipe(this.watchGuard("stableswap.updates")).subscribe(t=>{let e=new Map(t.map(i=>[i.id,i]));this.store.update(i=>{let s=[];for(let a of i){let n=e.get(a.id);n&&s.push({...a,fee:n.fee,tokens:n.tokens.filter(r=>r.id!==a.id),totalIssuance:n.totalIssuance,pegs:n.pegs,amplification:n.amplification,isRampPeriod:n.isRampPeriod})}return s})})}subscribeBalances(){return Ht.EMPTY}subscribeUpdates(){let t=new Ht;return t.add(this.subscribeCollateralBalance()),t.add(this.subscribeStableswapUpdates()),t.add(this.subscribeEvmLog()),t}};var Nt=class{static get(t){switch(t.type){case"Aave":return ct.fromPool(t);case"XYK":return ot.fromPool(t);case"Omnipool":return at.fromPool(t);case"LBP":return Q.fromPool(t);case"Stableswap":return q.fromPool(t);case"HSM":return pt.fromPool(t);default:throw new Error("Pool type "+t.type+" is not supported yet")}}};import{log as ha}from"@galacticcouncil/common";import{Subject as Pa,Subscription as z,takeUntil as ya}from"rxjs";var At=class extends Error{constructor(t){super(),this.message=`${t} pool invalid`,this.name="PoolNotFound"}};var{logger:fa}=ha,Vt=class extends B{evm;aave;omnipool;stableswap;hsm;xyk;lbp;active=new Set([]);pools=new Map([]);clients=[];aaveSub=z.EMPTY;omniSub=z.EMPTY;stableSub=z.EMPTY;hsmSub=z.EMPTY;xykSub=z.EMPTY;lbpSub=z.EMPTY;isReady=!1;isDestroyed=new Pa;constructor(t,e){super(t),this.evm=e,this.aave=new ut(t,e),this.omnipool=new nt(t,e),this.stableswap=new rt(t,e),this.hsm=new gt(t,e,this.stableswap),this.xyk=new lt(t,e),this.lbp=new st(t,e),this.clients=[this.aave,this.omnipool,this.stableswap,this.hsm,this.xyk,this.lbp]}subscribe(t){return t.getSubscriber().pipe(ya(this.isDestroyed)).subscribe(e=>{e.forEach(i=>{this.pools.set(i.address,i)})})}withAave(){return this.aaveSub.unsubscribe(),this.aaveSub=this.subscribe(this.aave),this.active.add("Aave"),this}withOmnipool(){return this.omniSub.unsubscribe(),this.omniSub=this.subscribe(this.omnipool),this.active.add("Omnipool"),this}withStableswap(){return this.stableSub.unsubscribe(),this.stableSub=this.subscribe(this.stableswap),this.active.add("Stableswap"),this}withHsm(){return this.active.has("Stableswap")||(fa.info("[PoolContextProvider] auto-activating stableswap"),this.withStableswap()),this.hsmSub.unsubscribe(),this.hsmSub=this.subscribe(this.hsm),this.active.add("HSM"),this}withXyk(t){return this.xyk.withOverride(t),this.xykSub.unsubscribe(),this.xykSub=this.subscribe(this.xyk),this.active.add("XYK"),this}withLbp(){return this.lbpSub.unsubscribe(),this.lbpSub=this.subscribe(this.lbp),this.active.add("LBP"),this}destroy(){this.isDestroyed.next(!0),this.isDestroyed.complete(),this.active.clear(),this.pools.clear(),this.isReady=!1}async getPools(){if(this.isReady){let e=this.pools.values();return Array.from(e)}let t=await Promise.all(this.clients.filter(e=>this.active.has(e.getPoolType())).map(e=>e.getPools()));return this.isReady=!0,t.flat()}async getPoolFees(t,e){let i=this.clients.find(s=>s.getPoolType()===e.type);if(i)return i.getPoolFees(t,e.address);throw new At(e.type)}};export{Vt as PoolContextProvider,H as PoolError,Nt as PoolFactory,y as PoolType,Se as aave,Ie as hsm,se as lbp,le as omni,pe as stable,de as xyk};
1
+ var we=Object.defineProperty;var A=(u,t)=>{for(var e in t)we(u,e,{get:t[e],enumerable:!0})};import Te from"buffer";typeof window<"u"&&(window.Buffer=Te.Buffer);var se={};A(se,{LbpMath:()=>T,LbpPool:()=>Q,LbpPoolClient:()=>st});import{calculate_in_given_out as Ae,calculate_out_given_in as Be,calculate_linear_weights as Fe,calculate_pool_trade_fee as _e,get_spot_price as ke}from"@galacticcouncil/math-lbp";var T=class{static getSpotPrice(t,e,i,s,a){return ke(t,e,i,s,a)}static calculateInGivenOut(t,e,i,s,a){return Ae(t,e,i,s,a)}static calculateOutGivenIn(t,e,i,s,a){return Be(t,e,i,s,a)}static calculateLinearWeights(t,e,i,s,a){return Fe(t,e,i,s,a)}static calculatePoolTradeFee(t,e,i){return _e(t,e,i)}};import{big as $t,RUNTIME_DECIMALS as Ut}from"@galacticcouncil/common";var y=(n=>(n.Aave="Aave",n.LBP="LBP",n.Omni="Omnipool",n.Stable="Stableswap",n.XYK="XYK",n.HSM="HSM",n))(y||{}),H=(c=>(c.UnknownError="UnknownError",c.FacilitatorCapacityExceeded="FacilitatorCapacityExceeded",c.InsufficientTradingAmount="InsufficientTradingAmount",c.InsufficientCollateral="InsufficientCollateral",c.MaxHoldingExceeded="MaxHoldingExceeded",c.MaxInRatioExceeded="MaxInRatioExceeded",c.MaxOutRatioExceeded="MaxOutRatioExceeded",c.TradeNotAllowed="TradeNotAllowed",c.MaxBuyBackExceeded="MaxBuyBackExceeded",c.MaxBuyPriceExceeded="MaxBuyPriceExceeded",c))(H||{});var bt={};A(bt,{withTimeout:()=>Re});function Re(u,t,e="timeout"){return new Promise((i,s)=>{let a=setTimeout(()=>s(new Error(e)),t);u.then(n=>{clearTimeout(a),i(n)},n=>{clearTimeout(a),s(n)})})}import{RUNTIME_DECIMALS as Fa}from"@galacticcouncil/common";var P={};A(P,{FeeUtils:()=>Bt,shiftNeg:()=>Me});import Le from"big.js";var Bt=class u{static toPct(t){let[e,i]=t;return u.safeDivide(e*100,i)}static toRaw(t){let[e,i]=t;return u.safeDivide(e,i)}static fromPermill(t){return[t,1e6]}static fromPerbill(t){return[t,1e9]}static fromRate(t,e){return[t,e]}static safeDivide(t,e,i=12){let s=10**i;return Math.round(t*s/e)/s}static safeRound(t){return parseFloat(t.toPrecision(15))}};function Me(u,t){let e=Le(typeof u=="bigint"?u.toString():u);return t===0?e.toString():e.div(Math.pow(10,t)).toString()}var j={};A(j,{findNestedKey:()=>De,findNestedObj:()=>He,jsonFormatter:()=>Ge});var De=(u,t)=>{let e=[];return JSON.stringify(u,(i,s)=>(s&&s[t]&&e.push(s),s)),e[0]},He=(u,t,e)=>{let i;return JSON.stringify(u,(s,a)=>(a&&a[t]===e&&(i=a),a)),i},Ge=(u,t)=>typeof t=="bigint"?t.toString():t;var D={};A(D,{calculateBuyFee:()=>We,calculateDiffToAvg:()=>qe,calculateDiffToRef:()=>Ne,calculateSellFee:()=>Ve});import E from"big.js";function qe(u,t){let e=E(u.toString()),i=E(t.toString());return e.minus(i).abs().div(e.plus(i).div(2)).mul(100).round(2).toNumber()}function Ne(u,t){if(t===0n)return 0;let e=E(u.toString()),i=E(t.toString());return e.minus(i).div(i).mul(100).round(2).toNumber()}function Ve(u,t){if(u===0n)return 0;let e=E(u.toString()),i=E(t.toString());return E(1).minus(i.div(e)).mul(100).round(2).toNumber()}function We(u,t){if(u===0n)return 0;let e=E(u.toString());return E(t.toString()).div(e).minus(1).mul(100).round(2).toNumber()}import{TLRUCache as Wt}from"@thi.ng/cache";var Pt=class{debug;constructor(t){this.debug=t||!1}log(t,e,i){this.debug&&console.log(t,e,i)}scope(t,e,i,s){let a=new Map,n=s!==void 0?new Wt(null,{ttl:s}):new Wt;return{get:(...c)=>{let p=i(...c);if(a.has(p)){this.log("[live]",t,p);let g=a.get(p);return Promise.resolve(g)}if(n.has(p))return this.log("[memo]",t,p),n.get(p);this.log("[fetch]",t,p);let m=e(...c).catch(g=>{throw n.delete(p),g});return n.set(p,m),m},set:(c,...p)=>{let m=i(...p);this.log("[set-live]",t,m),a.set(m,c)},clear:()=>{this.log("[clear]",t),a.clear(),n.release()}}}};var{FeeUtils:Yt}=P,Q=class u{type;address;tokens;maxInRatio;maxOutRatio;minTradingLimit;fee;repayFeeApply;static fromPool(t){return new u(t)}constructor(t){this.type="LBP",this.address=t.address,this.tokens=t.tokens,this.maxInRatio=t.maxInRatio,this.maxOutRatio=t.maxOutRatio,this.minTradingLimit=t.minTradingLimit,this.fee=t.fee,this.repayFeeApply=t.repayFeeApply}validatePair(t,e){return!0}parsePair(t,e){let i=new Map(this.tokens.map(n=>[n.id,n])),s=i.get(t),a=i.get(e);if(s==null)throw new Error("Pool does not contain tokenIn");if(a==null)throw new Error("Pool does not contain tokenOut");return{assetIn:t,assetOut:e,balanceIn:s.balance,balanceOut:a.balance,decimalsIn:s.decimals,decimalsOut:a.decimals,weightIn:s.weight,weightOut:a.weight}}validateAndBuy(t,e,i){let s=this.tokens[0].id,a=[];e<this.minTradingLimit&&a.push("InsufficientTradingAmount");let n=t.balanceOut/this.maxOutRatio;if(e>n&&a.push("MaxOutRatioExceeded"),s===t.assetOut){let r=this.calculateTradeFee(e,i),o=Yt.toPct(this.repayFeeApply?i.repayFee:i.exchangeFee),l=e+r,c=this.calculateInGivenOut(t,l),p=t.balanceIn/this.maxInRatio;return c>p&&a.push("MaxInRatioExceeded"),{amountIn:c,calculatedIn:c,amountOut:e,feePct:o,errors:a}}else{let r=this.calculateInGivenOut(t,e),o=t.balanceIn/this.maxInRatio;return r>o&&a.push("MaxInRatioExceeded"),{amountIn:r,calculatedIn:r,amountOut:e,feePct:0,errors:a}}}validateAndSell(t,e,i){let s=this.tokens[0].id,a=[];e<this.minTradingLimit&&a.push("InsufficientTradingAmount");let n=t.balanceIn/this.maxInRatio;if(e>n&&a.push("MaxInRatioExceeded"),s===t.assetIn){let r=this.calculateOutGivenIn(t,e),o=t.balanceOut/this.maxOutRatio;return r>o&&a.push("MaxOutRatioExceeded"),{amountIn:e,calculatedOut:r,amountOut:r,feePct:0,errors:a}}else{let r=this.calculateOutGivenIn(t,e),o=this.calculateTradeFee(r,i),l=Yt.toPct(this.repayFeeApply?i.repayFee:i.exchangeFee),c=r-o,p=t.balanceOut/this.maxOutRatio;return c>p&&a.push("MaxOutRatioExceeded"),{amountIn:e,calculatedOut:r,amountOut:c,feePct:l,errors:a}}}calculateInGivenOut(t,e){let i=T.calculateInGivenOut(t.balanceIn.toString(),t.balanceOut.toString(),t.weightIn.toString(),t.weightOut.toString(),e.toString()),s=BigInt(i);return s<0n?0n:s}calculateOutGivenIn(t,e){let i=T.calculateOutGivenIn(t.balanceIn.toString(),t.balanceOut.toString(),t.weightIn.toString(),t.weightOut.toString(),e.toString()),s=BigInt(i);return s<0n?0n:s}spotPriceInGivenOut(t){let e=T.getSpotPrice(t.balanceOut.toString(),t.balanceIn.toString(),t.weightOut.toString(),t.weightIn.toString(),$t.toBigInt(1,Ut).toString());return BigInt(e)}spotPriceOutGivenIn(t){let e=T.getSpotPrice(t.balanceIn.toString(),t.balanceOut.toString(),t.weightIn.toString(),t.weightOut.toString(),$t.toBigInt(1,Ut).toString());return BigInt(e)}calculateTradeFee(t,e){let i=T.calculatePoolTradeFee(t.toString(),this.repayFeeApply?e.repayFee[0]:e.exchangeFee[0],this.repayFeeApply?e.repayFee[1]:e.exchangeFee[1]);return BigInt(i)}};import{CompatibilityLevel as Ei}from"polkadot-api";import{Subscription as Ci,distinctUntilChanged as Li,filter as Mi,map as Di}from"rxjs";import{memoize1 as yi}from"@thi.ng/memoize";import{TLRUCache as fi}from"@thi.ng/cache";import{ReplaySubject as te,Subscription as ee,combineLatest as Si,defer as vi,from as xi,interval as Ii,merge as _t,of as Oi,EMPTY as et}from"rxjs";import{bufferCount as wi,bufferTime as Ti,catchError as it,filter as xt,finalize as kt,map as W,pairwise as Rt,repeat as Et,skip as Ai,share as Bi,startWith as Fi,switchMap as ie,tap as G,throttleTime as _i}from"rxjs/operators";import{hydration as ni,hydrationNext as ri}from"@galacticcouncil/descriptors";import{log as ti}from"@galacticcouncil/common";import{map as ei,shareReplay as ii,tap as si}from"rxjs";import{defer as $e,from as Ue,of as Xt,timer as Ye}from"rxjs";import{catchError as Xe,distinctUntilChanged as ze,expand as Ke,map as Ft,shareReplay as je,skip as Qe,switchMap as Je,timeout as Ze}from"rxjs/operators";function zt(u,{intervalMs:t=5e3,rpcTimeoutMs:e=1e4}={}){let i=()=>$e(()=>Ue(u._request("system_health",[]))).pipe(Ze({first:e}),Ft(()=>"online"),Xe(()=>Xt("offline")));return Xt({state:"offline",delayMs:0}).pipe(Ke(a=>Ye(a.delayMs).pipe(Je(i),Ft(n=>({state:n,delayMs:t})))),Qe(1),Ft(a=>a.state),ze(),je({bufferSize:1,refCount:!0}))}var{logger:ai}=ti,yt=class u{static instance=null;bestBlock$;finalizedBlock$;connection$;constructor(t){this.bestBlock$=this.watched("watcher(bestBlock)",t.getUnsafeApi().query.System.Number.watchValue({at:"best"}).pipe(ei(({value:e})=>e))),this.finalizedBlock$=this.watched("watcher(finalizedBlock)",t.finalizedBlock$),this.connection$=this.watched("watcher(connection)",zt(t))}static getInstance(t){return this.instance||(this.instance=new u(t)),this.instance}watched(t,e){return e.pipe(si({error:i=>ai.error(t,i)}),ii({bufferSize:1,refCount:!0}))}};var B=class{client;api;apiNext;watcher;constructor(t){this.client=t,this.api=this.client.getTypedApi(ni),this.apiNext=this.client.getTypedApi(ri),this.watcher=yt.getInstance(this.client)}};import{getWsProvider as xn}from"polkadot-api/ws";import{withLogsRecorder as On}from"polkadot-api/logs-provider";import{Binary as Gn}from"polkadot-api";import{log as oi}from"@galacticcouncil/common";import{combineLatest as li,concat as ci,defer as J,from as Kt}from"rxjs";import{bufferCount as jt,distinctUntilChanged as Qt,debounceTime as ui,map as N,retry as pi,startWith as Jt,switchMap as Zt,tap as Z,take as mi,skip as di,connect as gi}from"rxjs/operators";var{logger:V}=oi,tt=class extends B{erc20Ids=null;constructor(t){super(t)}async getBalance(t,e){return e===0?this.getSystemBalance(t):this.getBalanceData(t,e)}async getSystemBalance(t){let e=this.api.query.System.Account,{data:i}=await e.getValue(t,{at:"best"});return this.getBreakdown(i)}async getTokenBalance(t,e){let s=await this.api.query.Tokens.Accounts.getValue(t,e,{at:"best"});return this.getBreakdown(s)}async getErc20Balance(t,e){return this.getBalanceData(t,e)}watchBalance(t){return J(()=>{let e=this.watchSystemBalance(t),i=this.watchTokensBalance(t),s=this.watchErc20Balance(t);return li([e,i,s]).pipe(gi(a=>ci(a.pipe(mi(1)),a.pipe(di(1),ui(250)))))}).pipe(N(e=>e.flat()),Jt([]),jt(2,1),N(([e,i],s)=>s===0?i:this.getDeltas(e,i))).pipe(Z({subscribe:()=>V.debug("balance: subscribe",t),error:e=>V.error("balance",e)}),pi({delay:1e3}))}watchSystemBalance(t){let e=this.api.query.System.Account;return J(()=>e.watchValue(t,{at:"best"})).pipe(N(({value:i})=>({id:0,balance:this.getBreakdown(i.data)})),Z({error:i=>V.error("balance(system)",i)}))}watchTokenBalance(t,e){let i=this.api.query.Tokens.Accounts;return J(()=>i.watchValue(t,e,{at:"best"})).pipe(N(({value:s})=>({id:e,balance:this.getBreakdown(s)})),Z({error:s=>V.error("balance(token)",s)}))}watchTokensBalance(t){let e=this.api.query.Tokens.Accounts;return J(()=>e.watchEntries(t,{at:"best"})).pipe(Qt((i,s)=>!s.deltas),N(({deltas:i})=>{let s=[];return i?.deleted.forEach(a=>{let[n,r]=a.args;s.push({id:r,balance:this.getBreakdown({free:0n,reserved:0n,frozen:0n})})}),i?.upserted.forEach(a=>{let[n,r]=a.args;s.push({id:r,balance:this.getBreakdown(a.value)})}),s}),Z({error:i=>V.error("balance(tokens)",i)}))}watchErc20Balance(t,e){let i=async()=>{if(this.erc20Ids)return this.erc20Ids;let a=await this.api.query.AssetRegistry.Assets.getEntries({at:"best"});return this.erc20Ids=a.filter(({value:n})=>n.asset_type.type==="Erc20").map(({keyArgs:n})=>{let[r]=n;return r}),this.erc20Ids},s=async a=>(await Promise.all(a.map(async r=>[r,await this.getBalanceData(t,r)]))).map(([r,o])=>({id:r,balance:o}));return J(()=>Kt(e?Promise.resolve(e):i()).pipe(Zt(a=>this.watcher.bestBlock$.pipe(Zt(()=>Kt(s(a))))),Jt([]),jt(2,1),N(([a,n],r)=>r===0?n.filter(o=>o.balance.total>0n):this.getDeltas(a,n)),Qt((a,n)=>n.length===0),Z({error:a=>V.error("balance(erc20)",a)})))}async getBalanceData(t,e){let i=await this.api.apis.CurrenciesApi.account(e,t,{at:"best"});return this.getBreakdown(i)}getBreakdown(t){let e=t.free>=t.frozen?t.free-t.frozen:0n,i=t.free+t.reserved;return{free:t.free,reserved:t.reserved,frozen:t.frozen,total:i,transferable:e}}getDeltas(t,e){let i=(a,n)=>a!==void 0&&n!==void 0&&a.transferable===n.transferable&&a.total===n.total,s=t.reduce((a,n)=>(a.set(n.id,n.balance),a),new Map);return e.filter(a=>!i(a.balance,s.get(a.id)))}};import{BehaviorSubject as bi}from"rxjs";var ft=class{store$=new bi([]);updateQueue=Promise.resolve();changeset=new Set;get pools(){return this.store$.value}asObservable(){return this.store$.asObservable()}applyChangeset(t){return this.changeset.size===0?[]:t.filter(e=>this.changeset.has(e.address))}set(t){this.changeset=new Set(t.map(e=>e.address)),this.store$.next(t)}update(t){this.updateQueue=this.updateQueue.then(async()=>{let e=this.store$.value,i=new Map(e.map((r,o)=>[r.address,o])),s=await t(e),a=e.slice(),n=new Set;for(let r of s){let o=i.get(r.address);o===void 0?(i.set(r.address,a.length),a.push(r)):a[o]=r,n.add(r.address)}this.changeset=n,this.store$.next(a)}).catch(console.error)}destroy(){this.store$.complete()}};import{log as hi}from"@galacticcouncil/common";var Pi={Aave:"AAVE",LBP:"LBP",Omnipool:"OMNI",Stableswap:"STBL",XYK:"XYK",HSM:"HSM"},{logger:St}=hi,vt=class{type;constructor(t){this.type=t}prefix(){return this.pad(`pool(${Pi[this.type]})`,10)}trace(t,...e){St.trace(`${this.prefix()} ${t} :`,...e)}debug(t,...e){St.debug(`${this.prefix()} ${t} :`,...e)}info(t,...e){St.info(`${this.prefix()} ${t} :`,...e)}error(t,...e){St.error(`${this.prefix()} ${t} :`,...e)}pad(t,e){return t.length>=e?t:t+" ".repeat(e-t.length)}};var{withTimeout:ki}=bt,Ri=3e3,v=class extends B{evm;balance;store=new ft;log;shared$;resync$=new te(1);resyncAt=0;resyncPending=!1;mem=0;memPoolsCache=new fi(null,{ttl:6*1e3});memPools=yi(t=>(this.log.info("pool_sync",{mem:t}),this.loadPools()),this.memPoolsCache);constructor(t,e){super(t),this.evm=e,this.balance=new tt(t),this.log=new vt(this.getPoolType())}async getMemPools(){return this.memPools(this.mem)}async getPools(){return(await this.getMemPools()).filter(e=>this.hasValidAssets(e))}getSubscriber(){return this.shared$||(this.shared$=this.subscribeStore()),this.shared$.pipe(Fi([]),wi(2,1),W(([t,e])=>t.length===0?e:this.store.applyChangeset(e)),xt(t=>t.length>0),_i(1e3,void 0,{leading:!0,trailing:!0}))}subscribeStore(){return vi(()=>{let t=new ee;return t.add(this.startWatchdog()),this.resync$.next(),this.resync$.pipe(ie(()=>{let e=new ee;return xi(ki(this.getMemPools(),6e4,"getMemPools stalled")).pipe(G(()=>this.log.info("pool_synced",{mem:this.mem})),W(s=>s.filter(a=>this.hasValidAssets(a))),G(s=>this.store.set(s)),it(()=>(this.log.error("pool_seed_error",{mem:this.mem}),this.requestResync(),et))).pipe(G(()=>{e.add(this.subscribeBalances()),e.add(this.subscribeUpdates())}),ie(s=>_t(Oi(s),this.store.asObservable().pipe(Ai(1)))),kt(()=>{e.unsubscribe()}))}),kt(()=>t.unsubscribe()))}).pipe(Bi({connector:()=>new te(1),resetOnRefCountZero:!0}))}subscribeBalances(){let t=this.store.pools.map(e=>{let{address:i}=e,s=[this.balance.watchTokensBalance(i)];if(this.hasSystemAsset(e)){let a=this.balance.watchSystemBalance(i);s.push(a)}if(this.hasErc20Asset(e)){let a=e.tokens.filter(r=>r.type==="Erc20").map(r=>r.id),n=this.balance.watchErc20Balance(i,a);s.push(n)}return Si(s).pipe(W(a=>a.flat()),Rt(),W(([a,n])=>this.balance.getDeltas(a,n)),xt(a=>a.length>0),W(a=>[i,a]))});return _t(...t).pipe(Ti(250),xt(e=>e.length>0),W(e=>new Map(e)),this.watchGuard("balances")).subscribe(e=>{this.store.update(i=>this.updateBalances(i,e))})}hasSystemAsset(t){return t.tokens.some(e=>e.id===0)}hasErc20Asset(t){return t.tokens.some(e=>e.type==="Erc20")}hasValidAssets(t){return t.tokens.every(({decimals:e,balance:i})=>t.type==="XYK"?i>0n&&!!e:!!e)}updateBalances=(t,e)=>{let i=[],s=new Map(t.map(a=>[a.address,a]));for(let[a,n]of e){let r=s.get(a);if(r){let o=r.tokens.map(l=>{let c=n.find(p=>p.id===l.id);return c&&l.id!==r.id?{...l,balance:c.balance.transferable}:l});i.push({...r,tokens:o})}}return i};resync(t=!1){let e=Date.now();!t&&e-this.resyncAt<Ri||(this.resyncAt=e,this.mem++,this.resync$.next())}requestResync(t=!1){this.resyncPending||(this.resyncPending=!0,setTimeout(()=>{this.resyncPending=!1,this.resync(t)},0))}startWatchdog(){let s=this.watcher.connection$.pipe(Rt(),xt(([r,o])=>r==="offline"&&o==="online"),G(()=>{this.log.debug("watchdog_recover_online",{mem:this.mem}),this.requestResync()}),it(r=>(this.log.error("watchdog_recovery_error",r),et)),Et({delay:1e3})),a=this.watcher.finalizedBlock$.pipe(Rt(),G(([r,o])=>{let l=Number(r.number),c=Number(o.number),p=c-l;p>=3&&(this.log.debug("watchdog_gap",{from:l,to:c,gap:p}),this.requestResync())}),it(r=>(this.log.error("watchdog_gap_error",r),et)),Et({delay:1e3})),n=Ii(36e5).pipe(G(()=>{this.log.debug("watchdog_periodic",{mem:this.mem}),this.requestResync()}),it(r=>(this.log.error("watchdog_periodic_error",r),et)),Et({delay:1e3}));return _t(s,a,n).subscribe()}watchGuard(t){return e=>e.pipe(G({error:i=>{this.log.error(t,i),this.requestResync(!0)}}),kt(()=>{this.log.debug(t,"unsub")}),it(()=>et))}};var st=class extends v{MAX_FINAL_WEIGHT=100000000n;poolsData=new Map([]);getPoolType(){return"LBP"}async getPoolLimits(){let[t,e,i]=await Promise.all([this.api.constants.LBP.MaxInRatio(),this.api.constants.LBP.MaxOutRatio(),this.api.constants.LBP.MinTradingLimit()]);return{maxInRatio:t,maxOutRatio:e,minTradingLimit:i}}getPoolWeights(t,e){let{start:i,end:s,initial_weight:a,final_weight:n}=t,r=T.calculateLinearWeights(i?i.toString():"0",s?s.toString():"0",a.toString(),n.toString(),e.toString()),o=BigInt(r),l=this.MAX_FINAL_WEIGHT-BigInt(o);return[o,l]}async isSupported(){return(await this.api.getStaticApis()).compat.query.LBP.PoolData.isCompatible(Ei.BackwardsCompatible)}async loadPools(){let[t,e,i]=await Promise.all([this.api.query.LBP.PoolData.getEntries({at:"best"}),this.api.query.ParachainSystem.ValidationData.getValue({at:"best"}),this.getPoolLimits()]),s=e?.relay_parent_number||0,a=t.filter(({value:n})=>e&&this.isActivePool(n,s)).map(async({keyArgs:n,value:r})=>{let[o]=n,l=o.toString(),c=await this.getPoolDelta(l,r,s);return{address:l,type:"LBP",fee:r.fee,...c,...i}});return Promise.all(a)}async getPoolDelta(t,e,i){let{assets:s,repay_target:a,fee_collector:n}=e,[r,o]=this.getPoolWeights(e,i),[l,c]=s,[p,m,g,d,S]=await Promise.all([this.isRepayFeeApplied(l,a,n.toString()),this.balance.getBalance(t,l),this.api.query.AssetRegistry.Assets.getValue(l),this.balance.getBalance(t,c),this.api.query.AssetRegistry.Assets.getValue(c)]);return{repayFeeApply:p,tokens:[{id:l,decimals:g?.decimals,existentialDeposit:g?.existential_deposit,balance:m.transferable,weight:r,type:g?.asset_type.type},{id:c,decimals:S?.decimals,existentialDeposit:S?.existential_deposit,balance:d.transferable,weight:o,type:S?.asset_type.type}]}}isActivePool(t,e){let{start:i,end:s}=t;return i&&s?e>=i&&e<s:!1}async isRepayFeeApplied(t,e,i){if(e===0n)return!1;try{return(await this.balance.getBalance(i,t)).transferable<e}catch{return!0}}async getRepayFee(){return await this.api.constants.LBP.repay_fee()}async getPoolFees(t,e){let i=this.store.pools.find(a=>a.address===e);return{repayFee:await this.getRepayFee(),exchangeFee:i.fee}}subscribeValidationData(){return this.api.query.ParachainSystem.ValidationData.watchValue({at:"best"}).pipe(Di(({value:t})=>t),Mi(t=>t!==void 0),Li((t,e)=>t.relay_parent_number===e.relay_parent_number),this.watchGuard("parachainSystem.ValidationData")).subscribe(({relay_parent_number:t})=>{this.store.update(async e=>{let i=[];for(let s of e){let a=this.poolsData.get(s.address);if(a){let{assets:n,repay_target:r,fee_collector:o}=a,[l]=n,[c,p]=this.getPoolWeights(a,t),[m,g]=s.tokens,d=[{...m,weight:c},{...g,weight:p}],S=await this.isRepayFeeApplied(l,r,o.toString());i.push({...s,tokens:d,repayFeeApply:S})}}return i})})}subscribeUpdates(){let t=new Ci;return t.add(this.subscribeValidationData()),t}};var le={};A(le,{OmniMath:()=>b,OmniPool:()=>at,OmniPoolClient:()=>nt});import{calculate_in_given_out as Hi,calculate_lrna_in_given_out as Gi,calculate_out_given_in as qi,calculate_out_given_lrna_in as Ni,calculate_spot_price as Vi,calculate_lrna_spot_price as Wi,calculate_shares as $i,calculate_liquidity_out as Ui,calculate_liquidity_lrna_out as Yi,verify_asset_cap as Xi,calculate_liquidity_hub_in as zi,is_sell_allowed as Ki,is_buy_allowed as ji,is_add_liquidity_allowed as Qi,is_remove_liquidity_allowed as Ji,recalculate_asset_fee as Zi,recalculate_protocol_fee as ts}from"@galacticcouncil/math-omnipool";import $ from"big.js";var b=class{static calculateSpotPrice(t,e,i,s){return Vi(t,e,i,s)}static calculateLrnaSpotPrice(t,e){return Wi(t,e)}static calculateInGivenOut(t,e,i,s,a,n,r,o,l,c){return Hi(t,e,i,s,a,n,r,o,l,c)}static calculateLrnaInGivenOut(t,e,i,s,a,n){return Gi(t,e,i,s,a,n)}static calculateOutGivenIn(t,e,i,s,a,n,r,o,l,c){return qi(t,e,i,s,a,n,r,o,l,c)}static calculateOutGivenLrnaIn(t,e,i,s,a,n){return Ni(t,e,i,s,a,n)}static calculateShares(t,e,i,s){return $i(t,e,i,s)}static calculateLiquidityOut(t,e,i,s,a,n,r,o){return Ui(t,e,i,s,a,n,r,o)}static calculateLiquidityLRNAOut(t,e,i,s,a,n,r,o){return Yi(t,e,i,s,a,n,r,o)}static calculateCapDifference(t,e,i,s){let a=$(e),n=$(t),r=$(s),o=$(i),l=$(10).pow(18),c=o.div(l);if(a.div(r).lt(c)){let m=c.times(r).minus(a).times(n),g=a.times($(1).minus(c));return m.div(g).toFixed(0)}else return"0"}static calculateLimitHubIn(t,e,i,s){return zi(t,e,i,s)}static isSellAllowed(t){return Ki(t)}static isBuyAllowed(t){return ji(t)}static isAddLiquidityAllowed(t){return Qi(t)}static isRemoveLiquidityAllowed(t){return Ji(t)}static recalculateAssetFee(t,e,i,s,a,n,r,o,l,c,p){return Zi(t,e,i,s,a,n,r,o,l,c,p)}static recalculateProtocolFee(t,e,i,s,a,n,r,o,l,c,p){return ts(t,e,i,s,a,n,r,o,l,c,p)}static verifyAssetCap(t,e,i,s){return Xi(t,e,i,s)}};import{big as es}from"@galacticcouncil/common";var{FeeUtils:F}=P,at=class u{type;address;tokens;maxInRatio;maxOutRatio;minTradingLimit;hubAssetId;static fromPool(t){return new u(t)}constructor(t){this.type="Omnipool",this.address=t.address,this.tokens=t.tokens,this.maxInRatio=t.maxInRatio,this.maxOutRatio=t.maxOutRatio,this.minTradingLimit=t.minTradingLimit,this.hubAssetId=t.hubAssetId}validatePair(t,e){return this.hubAssetId!=e}parsePair(t,e){let i=new Map(this.tokens.map(n=>[n.id,n])),s=i.get(t),a=i.get(e);if(s==null)throw new Error("Pool does not contain tokenIn");if(a==null)throw new Error("Pool does not contain tokenOut");return{assetIn:t,assetOut:e,hubReservesIn:s.hubReserves,hubReservesOut:a.hubReserves,sharesIn:s.shares,sharesOut:a.shares,decimalsIn:s.decimals,decimalsOut:a.decimals,balanceIn:s.balance,balanceOut:a.balance,tradeableIn:s.tradeable,tradeableOut:a.tradeable,assetInEd:s.existentialDeposit,assetOutEd:a.existentialDeposit}}validateAndBuy(t,e,i){let s=this.calculateInGivenOut(t,e),a=this.calculateInGivenOut(t,e,i),n=s===0n?0:D.calculateBuyFee(s,a),r=[],o=b.isSellAllowed(t.tradeableIn),l=b.isBuyAllowed(t.tradeableOut);(!o||!l)&&r.push("TradeNotAllowed"),(e<this.minTradingLimit||s<t.assetInEd)&&r.push("InsufficientTradingAmount");let c=t.balanceOut/this.maxOutRatio;e>c&&r.push("MaxOutRatioExceeded");let p=t.balanceIn/this.maxInRatio;return a>p&&r.push("MaxInRatioExceeded"),{amountIn:a,calculatedIn:s,amountOut:e,feePct:n,errors:r}}validateAndSell(t,e,i){let s=this.calculateOutGivenIn(t,e),a=this.calculateOutGivenIn(t,e,i),n=D.calculateSellFee(s,a),r=[],o=b.isSellAllowed(t.tradeableIn),l=b.isBuyAllowed(t.tradeableOut);(!o||!l)&&r.push("TradeNotAllowed"),(e<this.minTradingLimit||s<t.assetOutEd)&&r.push("InsufficientTradingAmount");let c=t.balanceIn/this.maxInRatio;e>c&&r.push("MaxInRatioExceeded");let p=t.balanceOut/this.maxOutRatio;return a>p&&r.push("MaxOutRatioExceeded"),{amountIn:e,calculatedOut:s,amountOut:a,feePct:n,errors:r}}calculateInGivenOut(t,e,i){if(t.assetIn==this.hubAssetId)return this.calculateLrnaInGivenOut(t,e,i);let s=b.calculateInGivenOut(t.balanceIn.toString(),t.hubReservesIn.toString(),t.sharesIn.toString(),t.balanceOut.toString(),t.hubReservesOut.toString(),t.sharesOut.toString(),e.toString(),i?F.toRaw(i.assetFee).toString():"0",i?F.toRaw(i.protocolFee).toString():"0",i?F.toRaw(i.maxSlipFee).toString():"0"),a=BigInt(s);return a<0n?0n:a}calculateLrnaInGivenOut(t,e,i){let s=b.calculateLrnaInGivenOut(t.balanceOut.toString(),t.hubReservesOut.toString(),t.sharesOut.toString(),e.toString(),i?F.toRaw(i.assetFee).toString():"0",i?F.toRaw(i.maxSlipFee).toString():"0"),a=BigInt(s);return a<0n?0n:a}calculateOutGivenIn(t,e,i){if(t.assetIn==this.hubAssetId)return this.calculateOutGivenLrnaIn(t,e,i);let s=b.calculateOutGivenIn(t.balanceIn.toString(),t.hubReservesIn.toString(),t.sharesIn.toString(),t.balanceOut.toString(),t.hubReservesOut.toString(),t.sharesOut.toString(),e.toString(),i?F.toRaw(i.assetFee).toString():"0",i?F.toRaw(i.protocolFee).toString():"0",i?F.toRaw(i.maxSlipFee).toString():"0"),a=BigInt(s);return a<0n?0n:a}calculateOutGivenLrnaIn(t,e,i){let s=b.calculateOutGivenLrnaIn(t.balanceOut.toString(),t.hubReservesOut.toString(),t.sharesOut.toString(),e.toString(),i?F.toRaw(i.assetFee).toString():"0",i?F.toRaw(i.maxSlipFee).toString():"0"),a=BigInt(s);return a<0n?0n:a}spotPriceInGivenOut(t){if(t.assetIn==this.hubAssetId)return this.spotPriceLrnaInGivenOut(t);let e=b.calculateSpotPrice(t.balanceOut.toString(),t.hubReservesOut.toString(),t.balanceIn.toString(),t.hubReservesIn.toString());return this.normalizeSpot(BigInt(e),t.decimalsOut,t.decimalsIn)}spotPriceLrnaInGivenOut(t){let e=b.calculateLrnaSpotPrice(t.hubReservesOut.toString(),t.balanceOut.toString());return this.normalizeSpot(BigInt(e),t.decimalsOut,t.decimalsIn)}spotPriceOutGivenIn(t){if(t.assetIn==this.hubAssetId)return this.spotPriceOutGivenLrnaIn(t);let e=b.calculateSpotPrice(t.balanceIn.toString(),t.hubReservesIn.toString(),t.balanceOut.toString(),t.hubReservesOut.toString());return this.normalizeSpot(BigInt(e),t.decimalsIn,t.decimalsOut)}spotPriceOutGivenLrnaIn(t){let e=b.calculateLrnaSpotPrice(t.balanceOut.toString(),t.hubReservesOut.toString());return this.normalizeSpot(BigInt(e),t.decimalsIn,t.decimalsOut)}normalizeSpot(t,e,i){let s=e-i;if(s===0)return t;let a=es.pow10(Math.abs(s));return s>0?t*a:t/a}};import{AccountId as is,Binary as ae,CompatibilityLevel as ne,Enum as ss}from"polkadot-api";import{toHex as as}from"@polkadot-api/utils";import{Subscription as ns,distinctUntilChanged as Lt,filter as rs,finalize as Mt,map as U,merge as os,tap as It}from"rxjs";import{HYDRATION_SS58_PREFIX as ls}from"@galacticcouncil/common";var{FeeUtils:h}=P,re=ae.toHex(ae.fromText("omnipool")),oe=ss("Short"),nt=class extends v{queryBus=new Pt;block=0;dynamicFeesConfig=this.queryBus.scope("DynamicFees.AssetFeeConfiguration",t=>this.api.query.DynamicFees.AssetFeeConfiguration.getValue(t,{at:"best"}),t=>String(t));dynamicFees=this.queryBus.scope("DynamicFees.AssetFee",t=>this.api.query.DynamicFees.AssetFee.getValue(t,{at:"best"}),t=>String(t),6*1e3);maxSlipFee=this.queryBus.scope("Omnipool.SlipFee",()=>this.apiNext.query.Omnipool.SlipFee.getValue({at:"best"}),()=>"slipFee");emaOracles=this.queryBus.scope("EmaOracle.Oracles.Short",t=>this.api.query.EmaOracle.Oracles.getValue(re,t,oe,{at:"best"}),t=>t.join(":"),6*1e3);getPoolType(){return"Omnipool"}getPoolAddress(){let t="modlomnipool".padEnd(32,"\0"),e=new TextEncoder().encode(t),i=as(e);return is(ls).dec(i)}getOraclePair(t){return t===0?[0,1]:[1,t]}async getPoolLimits(){let[t,e,i]=await Promise.all([this.api.constants.Omnipool.MaxInRatio(),this.api.constants.Omnipool.MaxOutRatio(),this.api.constants.Omnipool.MinimumTradingLimit()]);return{maxInRatio:t,maxOutRatio:e,minTradingLimit:i}}async isSupported(){return(await this.api.getStaticApis()).compat.query.Omnipool.Assets.isCompatible(ne.BackwardsCompatible)}async isSlipFeeSupported(){return(await this.apiNext.getStaticApis()).compat.query.Omnipool.SlipFee.isCompatible(ne.Partial)}async loadPools(){let t=await this.api.constants.Omnipool.HubAssetId(),e=this.getPoolAddress(),[i,s,a,n,r]=await Promise.all([this.api.query.Omnipool.Assets.getEntries({at:"best"}),this.api.query.Omnipool.HubAssetTradability.getValue(),this.api.query.AssetRegistry.Assets.getValue(t),this.balance.getBalance(e,t),this.getPoolLimits()]),o=i.map(async({keyArgs:c,value:p})=>{let[m]=c,{hub_reserve:g,shares:d,tradable:S,cap:_,protocol_shares:k}=p,[x,w]=await Promise.all([this.api.query.AssetRegistry.Assets.getValue(m),this.balance.getBalance(e,m)]);return{id:m,decimals:x?.decimals,existentialDeposit:x?.existential_deposit,balance:w.transferable,cap:_,hubReserves:g,protocolShares:k,shares:d,tradeable:S,type:x?.asset_type.type}}),l=await Promise.all(o);return l.push({id:t,decimals:a?.decimals,existentialDeposit:a?.existential_deposit,balance:n.transferable,tradeable:s,type:a?.asset_type.type}),[{address:e,type:"Omnipool",hubAssetId:t,tokens:l,...r}]}async getPoolFees(t){let e=t.assetOut,i=t.assetIn,s=0;await this.isSlipFeeSupported()&&(s=await this.maxSlipFee.get()??0);let n=await this.dynamicFeesConfig.get(e);if(n?.type==="Fixed"){let{asset_fee:I,protocol_fee:R}=n.value;return{assetFee:h.fromPermill(I),protocolFee:h.fromPermill(R),maxSlipFee:h.fromPermill(s)}}let r=this.getOraclePair(e),o=this.getOraclePair(i),[l,c,p]=await Promise.all([this.dynamicFees.get(e),this.emaOracles.get(r),this.emaOracles.get(o)]),[m,g,d]=await this.getAssetFee(t,this.block,l,c,n?.value.asset_fee_params),[S,_,k]=i===1?[0,0,0]:await this.getProtocolFee(t,this.block,l,p,n?.value.protocol_fee_params),x=m+S,w=d+k;return{assetFee:h.fromPermill(g),protocolFee:h.fromPermill(_),maxSlipFee:h.fromPermill(s),min:h.fromPermill(x),max:h.fromPermill(w)}}async getAssetFee(t,e,i,s,a){let{assetOut:n,balanceOut:r}=t,{min_fee:o,max_fee:l,decay:c,amplification:p}=a||await this.api.constants.DynamicFees.AssetFeeParameters();if(!i||!s)return[o,o,l];let m=h.fromPermill(o),g=h.fromPermill(l),[d]=s,{asset_fee:S,timestamp:_}=i,k=Math.max(1,e-_),x=d.volume.b_in.toString(),w=d.volume.b_out.toString(),I=d.liquidity.b.toString();n===0&&(x=d.volume.a_in.toString(),w=d.volume.a_out.toString(),I=d.liquidity.a.toString());let R=h.fromPermill(S),K=b.recalculateAssetFee(x,w,I,"9",r.toString(),h.toRaw(R).toString(),k.toString(),h.toRaw(m).toString(),h.toRaw(g).toString(),c.toString(),p.toString());return[o,Number(K)*1e6,l]}async getProtocolFee(t,e,i,s,a){let{assetIn:n,balanceIn:r}=t,{min_fee:o,max_fee:l,decay:c,amplification:p}=a||await this.api.constants.DynamicFees.ProtocolFeeParameters();if(!i||!s)return[o,o,l];let m=h.fromPermill(o),g=h.fromPermill(l),[d]=s,{protocol_fee:S,timestamp:_}=i,k=Math.max(1,e-_),x=d.volume.b_in.toString(),w=d.volume.b_out.toString(),I=d.liquidity.b.toString();n===0&&(x=d.volume.a_in.toString(),w=d.volume.a_out.toString(),I=d.liquidity.a.toString());let R=h.fromPermill(S),K=b.recalculateProtocolFee(x,w,I,"9",r.toString(),h.toRaw(R).toString(),k.toString(),h.toRaw(m).toString(),h.toRaw(g).toString(),c.toString(),p.toString());return[o,Number(K)*1e6,l]}subscribeEmaOracles(){let[t]=this.store.pools,i=t.tokens.map(s=>s.id).map(s=>this.getOraclePair(s)).map(s=>this.api.query.EmaOracle.Oracles.watchValue(re,s,oe,{at:"best"}).pipe(U(({value:a})=>a),rs(a=>a!==void 0),U((a,n)=>({value:a,index:n})),It(({index:a})=>{a>0&&this.log.trace("emaOracle.Oracles",s.join(":"))}),U(({value:a})=>({pair:s,value:a}))));return os(...i).pipe(Mt(()=>this.emaOracles.clear()),this.watchGuard("emaOracle.Oracles")).subscribe(s=>{let{pair:a,value:n}=s;this.emaOracles.set(n,a)})}subscribeDynamicFees(){return this.api.query.DynamicFees.AssetFee.watchEntries({at:"best"}).pipe(Lt((t,e)=>!e.deltas),U((t,e)=>({value:t,index:e})),It(({value:t,index:e})=>{e>0&&this.log.trace("dynamicFees.AssetFee",t.deltas?.upserted)}),Mt(()=>this.dynamicFees.clear()),this.watchGuard("dynamicFees.AssetFee")).subscribe(({value:{deltas:t}})=>{t?.upserted.forEach(e=>{let[i]=e.args;this.dynamicFees.set(e.value,i)})})}subscribeDynamicFeesConfig(){return this.api.query.DynamicFees.AssetFeeConfiguration.watchEntries({at:"best"}).pipe(Lt((t,e)=>!e.deltas),U((t,e)=>({value:t,index:e})),It(({value:t,index:e})=>{e>0&&this.log.trace("dynamicFees.AssetFeeConfiguration",t.deltas?.upserted)}),Mt(()=>this.dynamicFeesConfig.clear()),this.watchGuard("dynamicFees.AssetFeeConfiguration")).subscribe(({value:{deltas:t}})=>{t?.upserted.forEach(e=>{let[i]=e.args;this.dynamicFeesConfig.set(e.value,i)})})}subscribeBlock(){return this.watcher.bestBlock$.pipe(this.watchGuard("watcher.bestBlock")).subscribe(t=>{this.block=t})}subscribeAssets(){return this.api.query.Omnipool.Assets.watchEntries({at:"best"}).pipe(Lt((t,e)=>!e.deltas),U((t,e)=>({value:t,index:e})),It(({value:t,index:e})=>{e>0&&this.log.trace("omnipool.Assets",t.deltas?.upserted)}),this.watchGuard("omnipool.Assets")).subscribe(({value:{deltas:t}})=>{this.store.update(([e])=>{let i=t?.upserted.reduce((a,n)=>{let[r]=n.args;return a.set(r,n.value),a},new Map),s=e.tokens.map(a=>{let n=i?.get(a.id);return n?this.updateTokenState(a,n):a});return[{...e,tokens:s}]})})}subscribeUpdates(){let t=new ns;return t.add(this.subscribeAssets()),t.add(this.subscribeDynamicFees()),t.add(this.subscribeDynamicFeesConfig()),t.add(this.subscribeEmaOracles()),t.add(this.subscribeBlock()),t}updateTokenState(t,e){let{hub_reserve:i,shares:s,tradable:a,cap:n,protocol_shares:r}=e;return{...t,cap:n,hubReserves:i,protocolShares:r,shares:s,tradeable:a}}};var pe={};A(pe,{StableMath:()=>f,StableSwap:()=>q,StableSwapClient:()=>rt});import{calculate_in_given_out as cs,calculate_out_given_in as us,calculate_amplification as ps,calculate_add_one_asset as ms,calculate_liquidity_out_one_asset as ds,calculate_shares as gs,calculate_shares_for_amount as bs,calculate_spot_price_with_fee as hs,pool_account_name as Ps,recalculate_peg as ys}from"@galacticcouncil/math-stableswap";var f=class{static getPoolAddress(t){return Ps(t)}static defaultPegs(t){let e=[];for(let i=0;i<t;i++)e.push(["1","1"]);return e}static calculateAmplification(t,e,i,s,a){return ps(t,e,i,s,a)}static calculateInGivenOut(t,e,i,s,a,n,r){return cs(t,e,i,s,a,n,r)}static calculateAddOneAsset(t,e,i,s,a,n,r){return ms(t,e,i,s,a,n,r)}static calculateSharesForAmount(t,e,i,s,a,n,r){return bs(t,e,i,s,a,n,r)}static calculateOutGivenIn(t,e,i,s,a,n,r){return us(t,e,i,s,a,n,r)}static calculateLiquidityOutOneAsset(t,e,i,s,a,n,r){return ds(t,e,i,s,a,n,r)}static calculateShares(t,e,i,s,a,n){return gs(t,e,i,s,a,n)}static calculateSpotPriceWithFee(t,e,i,s,a,n,r,o){return hs(t,e,i,s,a,n,r,o)}static recalculatePegs(t,e,i,s,a,n){let r=ys(t,e,i,s,a,n);return JSON.parse(r)}};import{RUNTIME_DECIMALS as fs,big as ce}from"@galacticcouncil/common";var{FeeUtils:Y}=P,q=class u{type;address;tokens;maxInRatio;maxOutRatio;minTradingLimit;amplification;isRampPeriod;id;fee;totalIssuance;pegs;static fromPool(t){return new u(t)}constructor(t){this.type="Stableswap",this.address=t.address,this.tokens=t.tokens,this.maxInRatio=t.maxInRatio,this.maxOutRatio=t.maxOutRatio,this.minTradingLimit=t.minTradingLimit,this.amplification=t.amplification,this.isRampPeriod=t.isRampPeriod,this.id=t.id,this.fee=t.fee,this.totalIssuance=t.totalIssuance,this.pegs=t.pegs}validatePair(t,e){return!0}parsePair(t,e){let i=new Map(this.tokens.map(n=>[n.id,n])),s=i.get(t),a=i.get(e);if(s==null)throw new Error("Pool does not contain tokenIn");if(a==null)throw new Error("Pool does not contain tokenOut");return{assetIn:t,assetOut:e,balanceIn:s.balance,balanceOut:a.balance,decimalsIn:s.decimals,decimalsOut:a.decimals,tradeableIn:this.id===t?15:s.tradeable,tradeableOut:this.id===e?15:a.tradeable,assetInEd:s.existentialDeposit,assetOutEd:a.existentialDeposit}}validateAndBuy(t,e,i){let s=this.calculateInGivenOut(t,e),a=this.calculateInGivenOut(t,e,i),n=s===0n?0:D.calculateBuyFee(s,a),r=[],o=b.isSellAllowed(t.tradeableIn),l=b.isBuyAllowed(t.tradeableOut);return(!o||!l)&&r.push("TradeNotAllowed"),(e<this.minTradingLimit||s<t.assetInEd)&&r.push("InsufficientTradingAmount"),{amountIn:a,calculatedIn:s,amountOut:e,feePct:n,errors:r}}validateAndSell(t,e,i){let s=this.calculateOutGivenIn(t,e),a=this.calculateOutGivenIn(t,e,i),n=D.calculateSellFee(s,a),r=[],o=b.isSellAllowed(t.tradeableIn),l=b.isBuyAllowed(t.tradeableOut);return(!o||!l)&&r.push("TradeNotAllowed"),(e<this.minTradingLimit||s<t.assetOutEd)&&r.push("InsufficientTradingAmount"),{amountIn:e,calculatedOut:s,amountOut:a,feePct:n,errors:r}}calculateIn(t,e,i){let s=f.calculateInGivenOut(this.getReserves(),Number(t.assetIn),Number(t.assetOut),e.toString(),this.amplification.toString(),i?Y.toRaw(i.fee).toString():"0",this.getPegs()),a=BigInt(s);return a<0n?0n:a}calculateAddOneAsset(t,e,i){let s=f.calculateAddOneAsset(this.getReserves(),e.toString(),Number(t.assetIn),this.amplification.toString(),this.totalIssuance.toString(),i?Y.toRaw(i.fee).toString():"0",this.getPegs()),a=BigInt(s);return a<0n?0n:a}calculateSharesForAmount(t,e,i){let s=f.calculateSharesForAmount(this.getReserves(),Number(t.assetOut),e.toString(),this.amplification.toString(),this.totalIssuance.toString(),i?Y.toRaw(i.fee).toString():"0",this.getPegs()),a=BigInt(s);return a<0n?0n:a}calculateInGivenOut(t,e,i){return t.assetOut==this.id?this.calculateAddOneAsset(t,e,i):t.assetIn==this.id?this.calculateSharesForAmount(t,e,i):this.calculateIn(t,e,i)}spotPriceInGivenOut(t){let e=f.calculateSpotPriceWithFee(this.id.toString(),this.getReserves(),this.amplification.toString(),t.assetOut.toString(),t.assetIn.toString(),this.totalIssuance.toString(),"0",this.getPegs());return this.normalizeSpot(BigInt(e),t.assetOut===this.id,t.assetIn===this.id,t.decimalsOut,t.decimalsIn)}calculateOut(t,e,i){let s=f.calculateOutGivenIn(this.getReserves(),Number(t.assetIn),Number(t.assetOut),e.toString(),this.amplification.toString(),i?Y.toRaw(i.fee).toString():"0",this.getPegs()),a=BigInt(s);return a<0n?0n:a}calculateWithdrawOneAsset(t,e,i){let s=f.calculateLiquidityOutOneAsset(this.getReserves(),e.toString(),Number(t.assetOut),this.amplification.toString(),this.totalIssuance.toString(),i?Y.toRaw(i.fee).toString():"0",this.getPegs()),a=BigInt(s);return a<0n?0n:a}calculateShares(t,e,i){let s=f.calculateShares(this.getReserves(),this.getAssets(t.assetIn,e),this.amplification.toString(),this.totalIssuance.toString(),i?Y.toRaw(i.fee).toString():"0",this.getPegs()),a=BigInt(s);return a<0n?0n:a}calculateOutGivenIn(t,e,i){return t.assetIn==this.id?this.calculateWithdrawOneAsset(t,e,i):t.assetOut==this.id?this.calculateShares(t,e,i):this.calculateOut(t,e,i)}spotPriceOutGivenIn(t){let e=f.calculateSpotPriceWithFee(this.id.toString(),this.getReserves(),this.amplification.toString(),t.assetIn.toString(),t.assetOut.toString(),this.totalIssuance.toString(),"0",this.getPegs());return this.normalizeSpot(BigInt(e),t.assetIn===this.id,t.assetOut===this.id,t.decimalsIn,t.decimalsOut)}getPegs(){return JSON.stringify(this.pegs)}getReserves(){let t=this.tokens.filter(e=>e.id!=this.id).map(({id:e,balance:i,decimals:s})=>({asset_id:e,amount:i,decimals:s}));return JSON.stringify(t,j.jsonFormatter)}getAssets(t,e){let i={asset_id:Number(t),amount:e.toString()};return JSON.stringify([i],j.jsonFormatter)}normalizeSpot(t,e,i,s,a){return e?t*ce.pow10(fs-a):i?t/ce.pow10(a-s):t}};import{AccountId as Ss,CompatibilityLevel as vs}from"polkadot-api";import{toHex as xs}from"@polkadot-api/utils";import{blake2b as Is}from"@noble/hashes/blake2b";import{Subscription as Os,distinctUntilChanged as ws,map as wt,merge as Ts,tap as ue}from"rxjs";import{HYDRATION_SS58_PREFIX as As,RUNTIME_DECIMALS as Bs}from"@galacticcouncil/common";var{FeeUtils:Fs}=P,rt=class extends v{poolsData=new Map([]);getPoolType(){return"Stableswap"}getPoolAddress(t){let e=f.getPoolAddress(t),i=Is(e,{dkLen:32}),s=xs(i);return Ss(As).dec(s)}async getPoolLimits(){return{maxInRatio:0n,maxOutRatio:0n,minTradingLimit:await this.api.constants.Stableswap.MinTradingLimit()}}getPoolAmplification(t,e){let{initial_amplification:i,final_amplification:s,initial_block:a,final_block:n}=t,r=f.calculateAmplification(i.toString(),s.toString(),a.toString(),n.toString(),e.toString()),o=Number(r)<s;return{amplification:BigInt(r),isRampPeriod:o}}async getPoolTokens(t,e){let i=this.getPoolAddress(t),s=e.assets.map(async a=>{let[n,r,o]=await Promise.all([this.api.query.Stableswap.AssetTradability.getValue(t,a),this.api.query.AssetRegistry.Assets.getValue(a),this.balance.getBalance(i,a)]);return{id:a,decimals:r?.decimals,existentialDeposit:r?.existential_deposit,balance:o.transferable,tradeable:n,type:r?.asset_type.type}});return Promise.all(s)}async isSupported(){return(await this.api.getStaticApis()).compat.query.Stableswap.Pools.isCompatible(vs.BackwardsCompatible)}async loadPools(){let[t,e,i]=await Promise.all([this.api.query.Stableswap.Pools.getEntries({at:"best"}),this.api.query.System.Number.getValue({at:"best"}),this.getPoolLimits()]),s=t.map(async({keyArgs:a,value:n})=>{let[r]=a,o=this.getPoolAddress(r),[l,c,p]=await Promise.all([this.getPoolTokens(r,n),this.api.query.Stableswap.PoolPegs.getValue(r,{at:"best"}),this.api.query.Tokens.TotalIssuance.getValue(r,{at:"best"})]),m=this.getPoolAmplification(n,e),g=c?this.getRecentPegs(c):this.getDefaultPegs(n);return l.push({id:r,tradeable:15,balance:p,decimals:Bs}),this.poolsData.set(r,n),{address:o,id:r,type:"Stableswap",fee:Fs.fromPermill(n.fee),tokens:l,totalIssuance:p,pegs:g,...i,...m}});return Promise.all(s)}async getPoolFees(t,e){return{fee:this.store.pools.find(s=>s.address===e).fee}}getDefaultPegs(t){return f.defaultPegs(t.assets.length)}getRecentPegs(t){let{current:e}=t;return Array.from(e.entries()).map(([i,s])=>s.map(a=>a.toString()))}subscribeIssuance(){let e=this.store.pools.map(i=>i.id).map(i=>this.api.query.Tokens.TotalIssuance.watchValue(i,{at:"best"}).pipe(wt(({value:s})=>s),wt((s,a)=>({value:s,index:a})),ue(({index:s,value:a})=>{s>0&&this.log.trace("tokens.TotalIssuance",i,a)}),wt(({value:s})=>({id:i,value:s}))));return Ts(...e).pipe(this.watchGuard("tokens.TotalIssuance")).subscribe(i=>{let{id:s,value:a}=i;this.store.update(n=>{let r=[];return n.filter(o=>o.id===s).forEach(o=>{let l=o.tokens.map(c=>c.id===s?{...c,balance:a}:c);r.push({...o,tokens:l,totalIssuance:a})}),r})})}subscribePoolPegs(){return this.api.query.Stableswap.PoolPegs.watchEntries({at:"best"}).pipe(ws((t,e)=>!e.deltas),wt((t,e)=>({value:t,index:e})),ue(({value:t,index:e})=>{e>0&&this.log.trace("stableswap.PoolPegs",t.deltas?.upserted)}),this.watchGuard("stableswap.PoolPegs")).subscribe({error:t=>this.log.error("stableswap.PoolPegs",t),next:({value:{deltas:t}})=>{this.store.update(e=>{let i=[],s=new Map(e.map(a=>[a.id,a]));return t?.upserted.forEach(({args:a,value:n})=>{let[r]=a,o=s.get(r);if(o){let l=this.getRecentPegs(n);i.push({...o,pegs:l})}}),i})}})}subscribeBlock(){return this.watcher.bestBlock$.pipe(this.watchGuard("watcher.bestBlock")).subscribe(t=>{this.store.update(e=>{let i=[];return e.filter(s=>s.isRampPeriod).forEach(s=>{let a=this.poolsData.get(s.id);if(a){let n=this.getPoolAmplification(a,t);i.push({...s,...n})}}),i})})}subscribeUpdates(){let t=new Os;return t.add(this.subscribePoolPegs()),t.add(this.subscribeIssuance()),this.hasOnRamps()&&t.add(this.subscribeBlock()),t}hasOnRamps(){return this.store.pools.filter(t=>t.isRampPeriod).length>0}};var de={};A(de,{XykMath:()=>L,XykPool:()=>ot,XykPoolClient:()=>lt});import{calculate_in_given_out as _s,calculate_out_given_in as ks,calculate_pool_trade_fee as Rs,get_spot_price as Es,calculate_liquidity_in as Cs,calculate_shares as Ls,calculate_spot_price as Ms,calculate_spot_price_with_fee as Ds,calculate_liquidity_out_asset_a as Hs,calculate_liquidity_out_asset_b as Gs}from"@galacticcouncil/math-xyk";var L=class{static getSpotPrice(t,e,i){return Es(t,e,i)}static calculateInGivenOut(t,e,i){return _s(t,e,i)}static calculateOutGivenIn(t,e,i){return ks(t,e,i)}static calculatePoolTradeFee(t,e,i){return Rs(t,e,i)}static calculateLiquidityIn(t,e,i){return Cs(t,e,i)}static calculateSpotPrice(t,e){return Ms(t,e)}static calculateSpotPriceWithFee(t,e,i,s){return Ds(t,e,i,s)}static calculateShares(t,e,i){return Ls(t,e,i)}static calculateLiquidityOutAssetA(t,e,i,s){return Hs(t,e,i,s)}static calculateLiquidityOutAssetB(t,e,i,s){return Gs(t,e,i,s)}};import{big as qs}from"@galacticcouncil/common";var{FeeUtils:me}=P,ot=class u{type;address;tokens;maxInRatio;maxOutRatio;minTradingLimit;static fromPool(t){return new u(t)}constructor(t){this.type="XYK",this.address=t.address,this.tokens=t.tokens,this.maxInRatio=t.maxInRatio,this.maxOutRatio=t.maxOutRatio,this.minTradingLimit=t.minTradingLimit}validatePair(t,e){return!0}parsePair(t,e){let i=new Map(this.tokens.map(n=>[n.id,n])),s=i.get(t),a=i.get(e);if(s==null)throw new Error("Pool does not contain tokenIn");if(a==null)throw new Error("Pool does not contain tokenOut");return{assetIn:t,assetOut:e,decimalsIn:s.decimals,decimalsOut:a.decimals,balanceIn:s.balance,balanceOut:a.balance,assetInEd:s.existentialDeposit,assetOutEd:a.existentialDeposit}}validateAndBuy(t,e,i){let s=this.calculateInGivenOut(t,e),a=this.calculateTradeFee(s,i),n=me.toPct(i.exchangeFee),r=s+a,o=[];(e<this.minTradingLimit||s<t.assetInEd)&&o.push("InsufficientTradingAmount");let l=t.balanceOut/this.maxOutRatio;e>l&&o.push("MaxOutRatioExceeded");let c=t.balanceIn/this.maxInRatio;return r>c&&o.push("MaxInRatioExceeded"),{amountIn:r,calculatedIn:s,amountOut:e,feePct:n,errors:o}}validateAndSell(t,e,i){let s=this.calculateOutGivenIn(t,e),a=this.calculateTradeFee(s,i),n=me.toPct(i.exchangeFee),r=s-a,o=[];(e<this.minTradingLimit||s<t.assetOutEd)&&o.push("InsufficientTradingAmount");let l=t.balanceIn/this.maxInRatio;e>l&&o.push("MaxInRatioExceeded");let c=t.balanceOut/this.maxOutRatio;return r>c&&o.push("MaxOutRatioExceeded"),{amountIn:e,calculatedOut:s,amountOut:r,feePct:n,errors:o}}calculateInGivenOut(t,e){let i=L.calculateInGivenOut(t.balanceIn.toString(),t.balanceOut.toString(),e.toString()),s=BigInt(i);return s<0n?0n:s}calculateOutGivenIn(t,e){let i=L.calculateOutGivenIn(t.balanceIn.toString(),t.balanceOut.toString(),e.toString()),s=BigInt(i);return s<0n?0n:s}spotPriceInGivenOut(t){let e=L.calculateSpotPrice(t.balanceOut.toString(),t.balanceIn.toString());return this.normalizeSpot(BigInt(e),t.decimalsOut,t.decimalsIn)}spotPriceOutGivenIn(t){let e=L.calculateSpotPrice(t.balanceIn.toString(),t.balanceOut.toString());return this.normalizeSpot(BigInt(e),t.decimalsIn,t.decimalsOut)}calculateTradeFee(t,e){let i=L.calculatePoolTradeFee(t.toString(),e.exchangeFee[0],e.exchangeFee[1]);return BigInt(i)}normalizeSpot(t,e,i){let s=e-i;if(s===0)return t;let a=qs.pow10(Math.abs(s));return s>0?t*a:t/a}};import{CompatibilityLevel as Ns}from"polkadot-api";import{Subscription as Vs}from"rxjs";var lt=class extends v{decimals=new Map([]);getPoolType(){return"XYK"}async withOverride(t){this.decimals=t?new Map(t.map(e=>[e.id,e.decimals])):new Map}async getPoolLimits(){let[t,e,i]=await Promise.all([this.api.constants.XYK.MaxInRatio(),this.api.constants.XYK.MaxOutRatio(),this.api.constants.XYK.MinTradingLimit()]);return{maxInRatio:t,maxOutRatio:e,minTradingLimit:i}}async isSupported(){return(await this.api.getStaticApis()).compat.query.XYK.PoolAssets.isCompatible(Ns.BackwardsCompatible)}async loadPools(){let[t,e]=await Promise.all([this.api.query.XYK.PoolAssets.getEntries(),this.getPoolLimits()]),i=t.map(async({keyArgs:s,value:a})=>{let[n]=s,[r,o]=a,[l,c,p,m]=await Promise.all([this.balance.getBalance(n,r),this.api.query.AssetRegistry.Assets.getValue(r),this.balance.getBalance(n,o),this.api.query.AssetRegistry.Assets.getValue(o)]);return{address:n,type:"XYK",tokens:[{id:r,decimals:c?.decimals||this.decimals.get(r),existentialDeposit:c?.existential_deposit,balance:l.transferable,type:c?.asset_type.type},{id:o,decimals:m?.decimals||this.decimals.get(o),existentialDeposit:m?.existential_deposit,balance:p.transferable,type:m?.asset_type.type}],...e}});return Promise.all(i)}async getPoolFees(){return{exchangeFee:await this.getExchangeFee()}}async getExchangeFee(){return await this.api.constants.XYK.GetExchangeFee()}subscribeUpdates(){return Vs.EMPTY}};var Se={};A(Se,{AavePool:()=>ct,AavePoolClient:()=>ut});import{big as ge,RUNTIME_DECIMALS as be}from"@galacticcouncil/common";var ct=class u{type;address;tokens;maxInRatio;maxOutRatio;minTradingLimit;static fromPool(t){return new u(t)}constructor(t){this.type="Aave",this.address=t.address,this.tokens=t.tokens,this.maxInRatio=t.maxInRatio,this.maxOutRatio=t.maxOutRatio,this.minTradingLimit=t.minTradingLimit}validatePair(t,e){return!0}parsePair(t,e){let i=new Map(this.tokens.map(n=>[n.id,n])),s=i.get(t),a=i.get(e);if(s==null)throw new Error("Pool does not contain tokenIn");if(a==null)throw new Error("Pool does not contain tokenOut");return{assetIn:t,assetOut:e,balanceIn:s.balance,balanceOut:a.balance,decimalsIn:s.decimals,decimalsOut:a.decimals,assetInEd:0n,assetOutEd:0n}}validateAndBuy(t,e,i){let s=this.calculateInGivenOut(t,e),a=[];return e>t.balanceOut&&a.push("TradeNotAllowed"),{amountIn:s,calculatedIn:s,amountOut:e,feePct:0,errors:a}}validateAndSell(t,e,i){let s=this.calculateOutGivenIn(t,e),a=[];return s>t.balanceOut&&a.push("TradeNotAllowed"),{amountIn:e,calculatedOut:s,amountOut:s,feePct:0,errors:a}}calculateInGivenOut(t,e){return e}calculateOutGivenIn(t,e){return e}spotPriceInGivenOut(t){return ge.toBigInt(1,be)}spotPriceOutGivenIn(t){return ge.toBigInt(1,be)}calculateTradeFee(t,e){return 0n}};import{AccountId as Ws,Binary as $s}from"polkadot-api";import{toHex as Us}from"@polkadot-api/utils";import{Subscription as Pe,filter as Dt,map as ye,mergeMap as fe}from"rxjs";import{decodeEventLog as Ys}from"viem";import{erc20 as Xs,HYDRATION_SS58_PREFIX as zs}from"@galacticcouncil/common";var he=[{anonymous:!1,inputs:[{indexed:!0,internalType:"address",name:"reserve",type:"address"},{indexed:!1,internalType:"address",name:"user",type:"address"},{indexed:!0,internalType:"address",name:"onBehalfOf",type:"address"},{indexed:!1,internalType:"uint256",name:"amount",type:"uint256"},{indexed:!0,internalType:"uint16",name:"referralCode",type:"uint16"}],name:"Supply",type:"event"},{anonymous:!1,inputs:[{indexed:!0,internalType:"address",name:"reserve",type:"address"},{indexed:!0,internalType:"address",name:"user",type:"address"},{indexed:!0,internalType:"address",name:"to",type:"address"},{indexed:!1,internalType:"uint256",name:"amount",type:"uint256"}],name:"Withdraw",type:"event"},{anonymous:!1,inputs:[{indexed:!0,internalType:"address",name:"reserve",type:"address"},{indexed:!1,internalType:"address",name:"user",type:"address"},{indexed:!0,internalType:"address",name:"onBehalfOf",type:"address"},{indexed:!1,internalType:"uint256",name:"amount",type:"uint256"},{indexed:!1,internalType:"enum DataTypes.InterestRateMode",name:"interestRateMode",type:"uint8"},{indexed:!1,internalType:"uint256",name:"borrowRate",type:"uint256"},{indexed:!0,internalType:"uint16",name:"referralCode",type:"uint16"}],name:"Borrow",type:"event"},{anonymous:!1,inputs:[{indexed:!0,internalType:"address",name:"reserve",type:"address"},{indexed:!0,internalType:"address",name:"user",type:"address"},{indexed:!0,internalType:"address",name:"repayer",type:"address"},{indexed:!1,internalType:"uint256",name:"amount",type:"uint256"},{indexed:!1,internalType:"bool",name:"useATokens",type:"bool"}],name:"Repay",type:"event"}];var{ERC20:Ks}=Xs,js=["Supply","Withdraw","Repay","Borrow"],ut=class extends v{getPoolType(){return"Aave"}async isSupported(){return!0}getPoolId(t,e){let i=t+"/"+e,s=new TextEncoder().encode(i.padEnd(32,"\0")),a=Us(s);return Ws(zs).dec(a)}getPoolLimits(){return{maxInRatio:0n,maxOutRatio:0n,minTradingLimit:0n}}async loadPools(){let e=(await this.api.apis.AaveTradeExecutor.pools({at:"best"})).map(async({reserve:i,atoken:s,liqudity_in:a,liqudity_out:n})=>{let[r,o,l,c]=await Promise.all([this.api.query.AssetRegistry.Assets.getValue(i),this.api.query.AssetRegistry.AssetLocations.getValue(i),this.api.query.AssetRegistry.Assets.getValue(s),this.api.query.AssetRegistry.AssetLocations.getValue(s)]);return{address:this.getPoolId(i,s),type:"Aave",tokens:[{id:i,decimals:r?.decimals,existentialDeposit:r?.existential_deposit,balance:a,location:o,type:r?.asset_type.type},{id:s,decimals:l?.decimals,existentialDeposit:l?.existential_deposit,balance:n,location:c,type:l?.asset_type.type}],...this.getPoolLimits()}});return Promise.all(e)}async getPoolDelta(t){let[e,i]=t.tokens,{liqudity_in:s,liqudity_out:a}=await this.api.apis.AaveTradeExecutor.pool(e.id,i.id,{at:"best"});return t.tokens.map(n=>{let r=n.id===e.id?s:a;return{...n,balance:r}})}async getPoolFees(){return{}}getReserveH160Id(t){if(t.type==="Erc20"&&t.location){let e=t.location.interior;if(e.type==="X1"&&e.value.type==="AccountKey20"){let{value:i}=e.value;return i.key}throw new Error("Invalid aave reserve multilocation")}return Ks.fromAssetId(t.id)}parseRouterLog(t){let{asset_in:e,asset_out:i}=t;return{assetIn:e,assetOut:i,key:`${e}:${i}`}}parseEvmLog(t){let{topics:e,data:i}=t.log,s=e,a=$s.toHex(i);try{let{eventName:n,args:r}=Ys({abi:he,topics:s,data:a}),o=r.reserve.toLowerCase();return{eventName:n,reserve:o,key:`${n}:${o}`}}catch{return}}subscribeRouterExecuted(){let e=this.store.pools.map(i=>i.tokens).map(([i,s])=>s).map(i=>i.id);return this.api.event.Router.Executed.watch().pipe(fe(({events:i})=>i),ye(({payload:i})=>this.parseRouterLog(i)),Dt(({assetIn:i,assetOut:s})=>e.includes(i)||e.includes(s)),this.watchGuard("router.Execute")).subscribe(({assetIn:i,assetOut:s,key:a})=>{this.log.trace("router.Executed",a),this.store.update(async n=>{let r=[];for(let o of n){let[l,c]=o.tokens;if(c.id===i||c.id===s){let m=await this.getPoolDelta(o);r.push({...o,tokens:m})}}return r})})}subscribeEvmLog(){return this.api.event.EVM.Log.watch().pipe(fe(({events:t})=>t),ye(({payload:t})=>this.parseEvmLog(t)),Dt(t=>t!==void 0),Dt(({eventName:t})=>js.includes(t)),this.watchGuard("evm.Log")).subscribe(({reserve:t,eventName:e})=>{this.log.trace(`evm.Log.${e}`,t),this.store.update(async i=>{let s=[];for(let a of i){let[n]=a.tokens;if(this.getReserveH160Id(n).toLowerCase()===t){let o=await this.getPoolDelta(a);s.push({...a,tokens:o})}}return s})})}subscribeBalances(){return Pe.EMPTY}subscribeUpdates(){let t=new Pe;return t.add(this.subscribeRouterExecuted()),t.add(this.subscribeEvmLog()),t}};var Ie={};A(Ie,{HsmMath:()=>O,HsmPool:()=>pt,HsmPoolClient:()=>gt});import{calculate_collateral_in_given_hollar_out as Qs,calculate_collateral_out_given_hollar_in as Js,calculate_hollar_in_given_collateral_out as Zs,calculate_hollar_out_given_collateral_in as ta,calculate_imbalance as ea,calculate_max_price as ia,calculate_buyback_limit as sa,calculate_buyback_price_with_fee as aa}from"@galacticcouncil/math-hsm";var O=class{static calculateCollateralInGivenHollarOut(t,e,i){return Qs(t,e,i)}static calculateCollateralOutGivenHollarIn(t,e,i){return Js(t,e,i)}static calculateHollarOutGivenCollateralIn(t,e,i){return ta(t,e,i)}static calculateHollarInGivenCollateralOut(t,e,i){return Zs(t,e,i)}static calculateImbalance(t,e,i){return ea(t,e,i)}static calculateBuybackLimit(t,e){return sa(t,e)}static calculateBuybackPriceWithFee(t,e,i){return aa(t,e,i)}static calculateMaxPrice(t,e){return ia(t,e)}};import{big as M,RUNTIME_DECIMALS as Tt}from"@galacticcouncil/common";var{FeeUtils:X}=P,pt=class u extends q{hsmAddress;hsmMintCapacity;hollarId;hollarH160;collateralId;collateralBalance;maxBuyPriceCoefficient;maxInHolding;purchaseFee;buyBackFee;buyBackRate;static fromPool(t){return new u(t)}constructor(t){super(t),this.type="HSM",this.hsmAddress=t.hsmAddress,this.hsmMintCapacity=t.hsmMintCapacity,this.hollarId=t.hollarId,this.hollarH160=t.hollarH160,this.collateralId=t.collateralId,this.collateralBalance=t.collateralBalance,this.maxBuyPriceCoefficient=t.maxBuyPriceCoefficient,this.maxInHolding=t.maxInHolding,this.purchaseFee=t.purchaseFee,this.buyBackFee=t.buyBackFee,this.buyBackRate=t.buyBackRate}validatePair(t,e){return!0}parsePair(t,e){return super.parsePair(t,e)}validateTradeHollarIn(t,e,i){let s=this.parsePair(t.assetOut,t.assetIn),a=super.calculateInGivenOut(s,e,{fee:this.fee}),n=this.calculateBuybackLimit(t);e>n&&i.push("MaxBuyBackExceeded");let r=this.calculateMaxPrice(t);return this.calculateBuyPrice(t,e,a)>r&&i.push("MaxBuyPriceExceeded"),a>this.collateralBalance&&i.push("InsufficientCollateral"),i}validateTradeHollarOut(t,e,i){return this.collateralBalance+t>this.maxInHolding&&i.push("MaxHoldingExceeded"),e>this.hsmMintCapacity&&i.push("FacilitatorCapacityExceeded"),i}validateTradeConstraints(t,e,i){let s=[];return t.assetIn===this.hollarId?this.validateTradeHollarIn(t,e,s):this.validateTradeHollarOut(e,i,s)}validateAndBuy(t,e){let i=this.calculateInGivenOut(t,e),s=this.validateTradeConstraints(t,i,e);return{amountIn:i,calculatedIn:i,amountOut:e,feePct:0,errors:s}}validateAndSell(t,e){let i=this.calculateOutGivenIn(t,e),s=this.validateTradeConstraints(t,e,i);return{amountIn:e,calculatedOut:i,amountOut:i,feePct:0,errors:s}}calculateHollarInGivenCollateralOut(t,e){let i=super.calculateInGivenOut(t,e,{fee:this.fee}),s=O.calculateHollarInGivenCollateralOut(e.toString(),i.toString(),X.toRaw(this.buyBackFee).toString());return BigInt(s)}calculateCollateralInGivenHollarOut(t){let e=this.getCollateralPeg(),i=O.calculateCollateralInGivenHollarOut(t.toString(),JSON.stringify(e),X.toRaw(this.purchaseFee).toString());return BigInt(i)}calculateInGivenOut(t,e){return t.assetOut==this.hollarId?this.calculateCollateralInGivenHollarOut(e):this.calculateHollarInGivenCollateralOut(t,e)}calculateCollateralOutGivenHollarIn(t,e){let i=super.calculateOutGivenIn(t,e,{fee:this.fee}),s=O.calculateCollateralOutGivenHollarIn(e.toString(),i.toString(),X.toRaw(this.buyBackFee).toString());return BigInt(s)}calculateHollarOutGivenCollateralIn(t){let e=this.getCollateralPeg(),i=O.calculateHollarOutGivenCollateralIn(t.toString(),JSON.stringify(e),X.toRaw(this.purchaseFee).toString());return BigInt(i)}calculateOutGivenIn(t,e){return t.assetIn==this.hollarId?this.calculateCollateralOutGivenHollarIn(t,e):this.calculateHollarOutGivenCollateralIn(e)}calculateImbalance(t){let e=this.getCollateralPeg(),i=O.calculateImbalance(t.balanceIn.toString(),JSON.stringify(e),t.balanceOut.toString());return BigInt(i)}calculateBuybackLimit(t){let e=this.calculateImbalance(t),i=O.calculateBuybackLimit(e.toString(),X.toRaw(this.buyBackRate).toString());return BigInt(i)}calculateBuyPrice(t,e,i){let s=O.calculateBuybackPriceWithFee(i.toString(),e.toString(),X.toRaw(this.buyBackFee).toString()),[a,n]=JSON.parse(s),r=M.pow10(t.decimalsIn+Tt-t.decimalsOut);return BigInt(a)*r/BigInt(n)}calculateMaxPrice(t){let e=this.getCollateralPeg(),i=O.calculateMaxPrice(JSON.stringify(e),this.maxBuyPriceCoefficient.toString()),[s,a]=JSON.parse(i),n=M.pow10(Tt-t.decimalsOut);return BigInt(s)*n/BigInt(a)}spotPriceInGivenOut(t){let e=M.toBigInt(1,t.decimalsOut),s=this.calculateInGivenOut(t,e)*M.pow10(Tt-t.decimalsOut);return this.normalizeSpotPrice(s,t.decimalsOut,t.decimalsIn)}spotPriceOutGivenIn(t){let e=M.toBigInt(1,t.decimalsIn),s=this.calculateOutGivenIn(t,e)*M.pow10(Tt-t.decimalsIn);return this.normalizeSpotPrice(s,t.decimalsIn,t.decimalsOut)}getCollateralPeg(){let t=this.tokens.findIndex(s=>s.id!==this.hollarId),e=this.pegs[t],i=this.tokens[t].decimals;return this.isDefaultPeg(e)?[M.toBigInt(1,18).toString(),M.toBigInt(1,i).toString()]:e}isDefaultPeg(t){let[e,i]=t;return Array.isArray(t)&&t.length===2&&e==="1"&&i==="1"}normalizeSpotPrice(t,e,i){let s=e-i;if(s===0)return t;let a=M.pow10(Math.abs(s));return s>0?t*a:t/a}};import{AccountId as na,Binary as ra,CompatibilityLevel as oa}from"polkadot-api";import{toHex as la}from"@polkadot-api/utils";import{Subscription as Ht,combineLatest as ca,filter as ve,map as Gt,mergeMap as ua,pairwise as pa}from"rxjs";import{decodeEventLog as ma}from"viem";import{h160 as da,HYDRATION_SS58_PREFIX as ga}from"@galacticcouncil/common";var mt=[{inputs:[{internalType:"address",name:"facilitator",type:"address"}],name:"getFacilitator",outputs:[{type:"tuple",components:[{name:"addr",type:"address"},{name:"label",type:"bytes32"},{name:"bucketCapacity",type:"uint128"},{name:"bucketLevel",type:"uint128"}]}],stateMutability:"view",type:"function"},{inputs:[{internalType:"address",name:"facilitator",type:"address"}],name:"getFacilitatorBucket",outputs:[{internalType:"uint256",name:"",type:"uint256"},{internalType:"uint256",name:"",type:"uint256"}],stateMutability:"view",type:"function"},{inputs:[],name:"getFacilitatorsList",outputs:[{internalType:"address[]",name:"",type:"address[]"}],stateMutability:"view",type:"function"},{anonymous:!1,inputs:[{indexed:!0,internalType:"address",name:"facilitatorAddress",type:"address"},{indexed:!0,internalType:"bytes32",name:"label",type:"bytes32"},{indexed:!1,internalType:"uint256",name:"bucketCapacity",type:"uint256"}],name:"FacilitatorAdded",type:"event"},{anonymous:!1,inputs:[{indexed:!0,internalType:"address",name:"facilitatorAddress",type:"address"},{indexed:!1,internalType:"uint256",name:"oldCapacity",type:"uint256"},{indexed:!1,internalType:"uint256",name:"newCapacity",type:"uint256"}],name:"FacilitatorBucketCapacityUpdated",type:"event"},{anonymous:!1,inputs:[{indexed:!0,internalType:"address",name:"facilitatorAddress",type:"address"},{indexed:!1,internalType:"uint256",name:"oldLevel",type:"uint256"},{indexed:!1,internalType:"uint256",name:"newLevel",type:"uint256"}],name:"FacilitatorBucketLevelUpdated",type:"event"},{anonymous:!1,inputs:[{indexed:!0,internalType:"address",name:"facilitatorAddress",type:"address"}],name:"FacilitatorRemoved",type:"event"}];var dt=class{client;constructor(t){this.client=t.getWsProvider()}async getFacilitatorCapacity(t,e){let[i,s]=await this.client.readContract({abi:mt,address:t,functionName:"getFacilitatorBucket",args:[e]});return i-s}};var{FeeUtils:qt}=P,{H160:xe}=da,ba=["FacilitatorBucketCapacityUpdated","FacilitatorBucketLevelUpdated"],gt=class extends v{ghoClient;stableClient;constructor(t,e,i){super(t,e),this.stableClient=i,this.ghoClient=new dt(e)}getPoolType(){return"HSM"}getPoolId(t){return this.getPoolAddress("hsm:"+t)}getFacilitatorAddress(){return this.getPoolAddress("modlpy/hsmod")}getHollarAddress(t){if(t){let e=t.interior;if(e.type==="X1"&&e.value.type==="AccountKey20"){let{value:i}=e.value;return i.key}}throw Error("Invalid hollar multilocation")}getPoolAddress(t){let e=t.padEnd(32,"\0"),i=new TextEncoder().encode(e),s=la(i);return na(ga).dec(s)}async isSupported(){return(await this.api.getStaticApis()).compat.query.HSM.Collaterals.isCompatible(oa.BackwardsCompatible)}async loadPools(){let t=await this.api.constants.HSM.HollarId(),[e,i,s]=await Promise.all([this.api.query.AssetRegistry.AssetLocations.getValue(t),this.api.query.HSM.Collaterals.getEntries({at:"best"}),this.stableClient.getPools()]);if(i.length===0)return[];let a=this.getFacilitatorAddress(),n=xe.fromAny(a),r=this.getHollarAddress(e),o=await this.ghoClient.getFacilitatorCapacity(r,n),l=i.map(async({keyArgs:p,value:m})=>{let[g]=p,{pool_id:d,max_buy_price_coefficient:S,max_in_holding:_,purchase_fee:k,buy_back_fee:x,buyback_rate:w}=m,I=s.find(R=>R.id===d);if(I){let R=this.getPoolId(d),K=await this.balance.getBalance(a,g);return{...I,address:R,type:"HSM",tokens:I.tokens.filter(Oe=>Oe.id!==d),hsmAddress:a,hsmMintCapacity:o,hollarId:t,hollarH160:r,collateralId:g,collateralBalance:K.transferable,maxBuyPriceCoefficient:S,maxInHolding:_,purchaseFee:qt.fromPermill(k),buyBackFee:qt.fromPermill(x),buyBackRate:qt.fromPerbill(w)}}});return(await Promise.all(l)).filter(p=>p!==null)}async getPoolFees(){return{}}parseEvmLog(t){let{topics:e,data:i}=t.log,s=e,a=ra.toHex(i);try{let{eventName:n,args:r}=ma({abi:mt,topics:s,data:a}),o=r.facilitatorAddress.toLowerCase();return{eventName:n,facilitator:o,key:`${n}:${o}`}}catch{return}}subscribeEvmLog(){return this.api.event.EVM.Log.watch().pipe(ua(({events:t})=>t),Gt(({payload:t})=>this.parseEvmLog(t)),ve(t=>t!==void 0),ve(({eventName:t})=>ba.includes(t)),this.watchGuard("evm.Log")).subscribe(({eventName:t,facilitator:e})=>{this.log.trace(`evm.Log.${t}`,e),this.store.update(async i=>{let s=[],[{hsmAddress:a,hollarH160:n}]=i,r=xe.fromAny(a);if(r.toLowerCase()===e){let l=await this.ghoClient.getFacilitatorCapacity(n,r);for(let c of i)s.push({...c,hsmMintCapacity:l})}return s})})}subscribeCollateralBalance(){let t=[],e=[];this.store.pools.forEach(a=>{let{tokens:n,collateralId:r}=a;n.find(l=>l.id===r).type==="Erc20"?e.push(r):t.push(r)});let[{hsmAddress:i}]=this.store.pools,s=[];if(t.length>0){let a=this.balance.watchTokensBalance(i);s.push(a)}if(e.length>0){let a=this.balance.watchErc20Balance(i,e);s.push(a)}return s.length>0?ca(s).pipe(Gt(a=>a.flat()),pa(),Gt(([a,n])=>this.balance.getDeltas(a,n)),this.watchGuard("balances")).subscribe(a=>{this.store.update(n=>{let r=[],o=new Map(n.map(l=>[l.collateralId,l]));return a.forEach(({id:l,balance:c})=>{let p=o.get(l);p&&(this.log.trace("balances",{id:l,balance:c}),r.push({...p,collateralBalance:c.transferable}))}),r})}):Ht.EMPTY}subscribeStableswapUpdates(){return this.stableClient.getSubscriber().pipe(this.watchGuard("stableswap.updates")).subscribe(t=>{let e=new Map(t.map(i=>[i.id,i]));this.store.update(i=>{let s=[];for(let a of i){let n=e.get(a.id);n&&s.push({...a,fee:n.fee,tokens:n.tokens.filter(r=>r.id!==a.id),totalIssuance:n.totalIssuance,pegs:n.pegs,amplification:n.amplification,isRampPeriod:n.isRampPeriod})}return s})})}subscribeBalances(){return Ht.EMPTY}subscribeUpdates(){let t=new Ht;return t.add(this.subscribeCollateralBalance()),t.add(this.subscribeStableswapUpdates()),t.add(this.subscribeEvmLog()),t}};var Nt=class{static get(t){switch(t.type){case"Aave":return ct.fromPool(t);case"XYK":return ot.fromPool(t);case"Omnipool":return at.fromPool(t);case"LBP":return Q.fromPool(t);case"Stableswap":return q.fromPool(t);case"HSM":return pt.fromPool(t);default:throw new Error("Pool type "+t.type+" is not supported yet")}}};import{log as ha}from"@galacticcouncil/common";import{Subject as Pa,Subscription as z,takeUntil as ya}from"rxjs";var At=class extends Error{constructor(t){super(),this.message=`${t} pool invalid`,this.name="PoolNotFound"}};var{logger:fa}=ha,Vt=class extends B{evm;aave;omnipool;stableswap;hsm;xyk;lbp;active=new Set([]);pools=new Map([]);clients=[];aaveSub=z.EMPTY;omniSub=z.EMPTY;stableSub=z.EMPTY;hsmSub=z.EMPTY;xykSub=z.EMPTY;lbpSub=z.EMPTY;isReady=!1;isDestroyed=new Pa;constructor(t,e){super(t),this.evm=e,this.aave=new ut(t,e),this.omnipool=new nt(t,e),this.stableswap=new rt(t,e),this.hsm=new gt(t,e,this.stableswap),this.xyk=new lt(t,e),this.lbp=new st(t,e),this.clients=[this.aave,this.omnipool,this.stableswap,this.hsm,this.xyk,this.lbp]}subscribe(t){return t.getSubscriber().pipe(ya(this.isDestroyed)).subscribe(e=>{e.forEach(i=>{this.pools.set(i.address,i)})})}withAave(){return this.aaveSub.unsubscribe(),this.aaveSub=this.subscribe(this.aave),this.active.add("Aave"),this}withOmnipool(){return this.omniSub.unsubscribe(),this.omniSub=this.subscribe(this.omnipool),this.active.add("Omnipool"),this}withStableswap(){return this.stableSub.unsubscribe(),this.stableSub=this.subscribe(this.stableswap),this.active.add("Stableswap"),this}withHsm(){return this.active.has("Stableswap")||(fa.info("[PoolContextProvider] auto-activating stableswap"),this.withStableswap()),this.hsmSub.unsubscribe(),this.hsmSub=this.subscribe(this.hsm),this.active.add("HSM"),this}withXyk(t){return this.xyk.withOverride(t),this.xykSub.unsubscribe(),this.xykSub=this.subscribe(this.xyk),this.active.add("XYK"),this}withLbp(){return this.lbpSub.unsubscribe(),this.lbpSub=this.subscribe(this.lbp),this.active.add("LBP"),this}destroy(){this.isDestroyed.next(!0),this.isDestroyed.complete(),this.active.clear(),this.pools.clear(),this.isReady=!1}async getPools(){if(this.isReady){let e=this.pools.values();return Array.from(e)}let t=await Promise.all(this.clients.filter(e=>this.active.has(e.getPoolType())).map(e=>e.getPools()));return this.isReady=!0,t.flat()}async getPoolFees(t,e){let i=this.clients.find(s=>s.getPoolType()===e.type);if(i)return i.getPoolFees(t,e.address);throw new At(e.type)}};export{Vt as PoolContextProvider,H as PoolError,Nt as PoolFactory,y as PoolType,Se as aave,Ie as hsm,se as lbp,le as omni,pe as stable,de as xyk};
@@ -1 +1 @@
1
- "use strict";var Ie=Object.create;var yt=Object.defineProperty;var we=Object.getOwnPropertyDescriptor;var Oe=Object.getOwnPropertyNames;var ve=Object.getPrototypeOf,Te=Object.prototype.hasOwnProperty;var J=(c,t)=>{for(var e in t)yt(c,e,{get:t[e],enumerable:!0})},jt=(c,t,e,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let a of Oe(t))!Te.call(c,a)&&a!==e&&yt(c,a,{get:()=>t[a],enumerable:!(s=we(t,a))||s.enumerable});return c};var Et=(c,t,e)=>(e=c!=null?Ie(ve(c)):{},jt(t||!c||!c.__esModule?yt(e,"default",{value:c,enumerable:!0}):e,c)),xe=c=>jt(yt({},"__esModule",{value:!0}),c);var ps={};J(ps,{DCA_TIME_RESERVE:()=>he,DEFAULT_BLOCK_TIME:()=>ge,DEFAULT_MIN_BUDGET:()=>$t,ORDER_MIN_BLOCK_PERIOD:()=>be,Router:()=>rt,TWAP_EXECUTION_INTERVAL:()=>Pt,TWAP_MAX_DURATION:()=>Yt,TWAP_MAX_PRICE_IMPACT:()=>Xt,TWAP_TX_MULTIPLIER:()=>ol,TradeOrderError:()=>Ut,TradeOrderType:()=>Wt,TradeRouteBuilder:()=>W,TradeRouter:()=>ot,TradeScheduler:()=>Rt,TradeType:()=>Vt});module.exports=xe(ps);var lt=class{constructor(t=1/0){this.capacity=t}storage=[];enqueue(t){if(this.size()===this.capacity)throw Error("Queue has reached max capacity, you cannot add more items");this.storage.push(t)}dequeue(){return this.storage.shift()}size(){return this.storage.length}};var Be=10,ct=class{isNotVisited(t,e){let s=!0;return e.forEach(a=>{(a[0]===t[0]||a[1]===t[1])&&(s=!1)}),s}findPaths(t,e,s){let a=[],i=new lt,n=[];for(n.push([e,""]),i.enqueue(n);i.size()>0;){let r=i.dequeue();if(!r||r.length>Be)continue;let o=r[r.length-1];(s===null||o[0]===s)&&a.push(r),t.get(o[0])?.forEach(u=>{if(this.isNotVisited(u,r)){let m=[...r];m.push(u),i.enqueue(m)}})}return a}findShortestPaths(t,e,s){let a=[],i=new lt,n=[];n.push([e,""]),i.enqueue(n);let r=1/0;for(;i.size()>0;){let o=i.dequeue();if(!o)continue;let l=o[o.length-1];if(l[0]===s){o.length<r?(r=o.length,a.length=0,a.push(o)):o.length===r&&a.push(o);continue}let u=t.get(l[0]);for(let m of u??[])this.isNotVisited(m,o)&&i.enqueue([...o,m])}return a}buildAndPopulateGraph(t,e){let s=new Map;for(let a of t)s.set(parseInt(a),[]);for(let[a,i,n]of e)s.get(i)?.push([n,a]);return s}};function kt(c){let t={};for(let e of c){let s=e.tokens.length;for(let a=0;a<s;a++){t[e.tokens[a].id]||(t[e.tokens[a].id]=[]);for(let i=0;i<s;i++){if(a==i)continue;let n=[e.address,e.tokens[a].id,e.tokens[i].id];t[e.tokens[a].id].push(n)}}}return t}var H=require("@galacticcouncil/math-lbp"),G=class{static getSpotPrice(t,e,s,a,i){return(0,H.get_spot_price)(t,e,s,a,i)}static calculateInGivenOut(t,e,s,a,i){return(0,H.calculate_in_given_out)(t,e,s,a,i)}static calculateOutGivenIn(t,e,s,a,i){return(0,H.calculate_out_given_in)(t,e,s,a,i)}static calculateLinearWeights(t,e,s,a,i){return(0,H.calculate_linear_weights)(t,e,s,a,i)}static calculatePoolTradeFee(t,e,s){return(0,H.calculate_pool_trade_fee)(t,e,s)}};var Z=require("@galacticcouncil/common");var ft={};J(ft,{withTimeout:()=>Ae});function Ae(c,t,e="timeout"){return new Promise((s,a)=>{let i=setTimeout(()=>a(new Error(e)),t);c.then(n=>{clearTimeout(i),s(n)},n=>{clearTimeout(i),a(n)})})}var C={};J(C,{divSpot:()=>_e,getFraction:()=>Re,mulScaled:()=>Qt,mulSpot:()=>Fe});var Ct=require("@galacticcouncil/common");function Qt(c,t,e,s,a){let i=e+s-a,n=c*t;return i>0?n/BigInt(10)**BigInt(i):i<0?n*BigInt(10)**BigInt(-i):n}function Fe(c,t,e,s){return Qt(c,t,e,Ct.RUNTIME_DECIMALS,s)}function _e(c,t,e,s){if(t===0n)return 0n;let a=BigInt(10)**BigInt(Ct.RUNTIME_DECIMALS+s-e);return c*a/t}function Re(c,t,e=2){if(t<.01||t>100)throw new Error("Supported range is from 0.01% - 100%");let s=BigInt(10)**BigInt(e),a=BigInt(Math.round(t*Number(s)));return c*a/(BigInt(100)*s)}var w={};J(w,{FeeUtils:()=>Mt,shiftNeg:()=>ke});var Zt=Et(require("big.js"));var Mt=class c{static toPct(t){let[e,s]=t;return c.safeDivide(e*100,s)}static toRaw(t){let[e,s]=t;return c.safeDivide(e,s)}static fromPermill(t){return[t,1e6]}static fromPerbill(t){return[t,1e9]}static fromRate(t,e){return[t,e]}static safeDivide(t,e,s=12){let a=10**s;return Math.round(t*a/e)/a}static safeRound(t){return parseFloat(t.toPrecision(15))}};function ke(c,t){let e=(0,Zt.default)(typeof c=="bigint"?c.toString():c);return t===0?e.toString():e.div(Math.pow(10,t)).toString()}var ut={};J(ut,{findNestedKey:()=>Ce,findNestedObj:()=>Me,jsonFormatter:()=>Le});var Ce=(c,t)=>{let e=[];return JSON.stringify(c,(s,a)=>(a&&a[t]&&e.push(a),a)),e[0]},Me=(c,t,e)=>{let s;return JSON.stringify(c,(a,i)=>(i&&i[t]===e&&(s=i),i)),s},Le=(c,t)=>typeof t=="bigint"?t.toString():t;var A={};J(A,{calculateBuyFee:()=>qe,calculateDiffToAvg:()=>De,calculateDiffToRef:()=>He,calculateSellFee:()=>Ne});var N=Et(require("big.js"));function De(c,t){let e=(0,N.default)(c.toString()),s=(0,N.default)(t.toString());return e.minus(s).abs().div(e.plus(s).div(2)).mul(100).round(2).toNumber()}function He(c,t){if(t===0n)return 0;let e=(0,N.default)(c.toString()),s=(0,N.default)(t.toString());return e.minus(s).div(s).mul(100).round(2).toNumber()}function Ne(c,t){if(c===0n)return 0;let e=(0,N.default)(c.toString()),s=(0,N.default)(t.toString());return(0,N.default)(1).minus(s.div(e)).mul(100).round(2).toNumber()}function qe(c,t){if(c===0n)return 0;let e=(0,N.default)(c.toString());return(0,N.default)(t.toString()).div(e).minus(1).mul(100).round(2).toNumber()}var{FeeUtils:te}=w,St=class c{type;address;tokens;maxInRatio;maxOutRatio;minTradingLimit;fee;repayFeeApply;static fromPool(t){return new c(t)}constructor(t){this.type="LBP",this.address=t.address,this.tokens=t.tokens,this.maxInRatio=t.maxInRatio,this.maxOutRatio=t.maxOutRatio,this.minTradingLimit=t.minTradingLimit,this.fee=t.fee,this.repayFeeApply=t.repayFeeApply}validatePair(t,e){return!0}parsePair(t,e){let s=new Map(this.tokens.map(n=>[n.id,n])),a=s.get(t),i=s.get(e);if(a==null)throw new Error("Pool does not contain tokenIn");if(i==null)throw new Error("Pool does not contain tokenOut");return{assetIn:t,assetOut:e,balanceIn:a.balance,balanceOut:i.balance,decimalsIn:a.decimals,decimalsOut:i.decimals,weightIn:a.weight,weightOut:i.weight}}validateAndBuy(t,e,s){let a=this.tokens[0].id,i=[];e<this.minTradingLimit&&i.push("InsufficientTradingAmount");let n=t.balanceOut/this.maxOutRatio;if(e>n&&i.push("MaxOutRatioExceeded"),a===t.assetOut){let r=this.calculateTradeFee(e,s),o=te.toPct(this.repayFeeApply?s.repayFee:s.exchangeFee),l=e+r,u=this.calculateInGivenOut(t,l),m=t.balanceIn/this.maxInRatio;return u>m&&i.push("MaxInRatioExceeded"),{amountIn:u,calculatedIn:u,amountOut:e,feePct:o,errors:i}}else{let r=this.calculateInGivenOut(t,e),o=t.balanceIn/this.maxInRatio;return r>o&&i.push("MaxInRatioExceeded"),{amountIn:r,calculatedIn:r,amountOut:e,feePct:0,errors:i}}}validateAndSell(t,e,s){let a=this.tokens[0].id,i=[];e<this.minTradingLimit&&i.push("InsufficientTradingAmount");let n=t.balanceIn/this.maxInRatio;if(e>n&&i.push("MaxInRatioExceeded"),a===t.assetIn){let r=this.calculateOutGivenIn(t,e),o=t.balanceOut/this.maxOutRatio;return r>o&&i.push("MaxOutRatioExceeded"),{amountIn:e,calculatedOut:r,amountOut:r,feePct:0,errors:i}}else{let r=this.calculateOutGivenIn(t,e),o=this.calculateTradeFee(r,s),l=te.toPct(this.repayFeeApply?s.repayFee:s.exchangeFee),u=r-o,m=t.balanceOut/this.maxOutRatio;return u>m&&i.push("MaxOutRatioExceeded"),{amountIn:e,calculatedOut:r,amountOut:u,feePct:l,errors:i}}}calculateInGivenOut(t,e){let s=G.calculateInGivenOut(t.balanceIn.toString(),t.balanceOut.toString(),t.weightIn.toString(),t.weightOut.toString(),e.toString()),a=BigInt(s);return a<0n?0n:a}calculateOutGivenIn(t,e){let s=G.calculateOutGivenIn(t.balanceIn.toString(),t.balanceOut.toString(),t.weightIn.toString(),t.weightOut.toString(),e.toString()),a=BigInt(s);return a<0n?0n:a}spotPriceInGivenOut(t){let e=G.getSpotPrice(t.balanceOut.toString(),t.balanceIn.toString(),t.weightOut.toString(),t.weightIn.toString(),Z.big.toBigInt(1,Z.RUNTIME_DECIMALS).toString());return BigInt(e)}spotPriceOutGivenIn(t){let e=G.getSpotPrice(t.balanceIn.toString(),t.balanceOut.toString(),t.weightIn.toString(),t.weightOut.toString(),Z.big.toBigInt(1,Z.RUNTIME_DECIMALS).toString());return BigInt(e)}calculateTradeFee(t,e){let s=G.calculatePoolTradeFee(t.toString(),this.repayFeeApply?e.repayFee[0]:e.exchangeFee[0],this.repayFeeApply?e.repayFee[1]:e.exchangeFee[1]);return BigInt(s)}};var Ye=require("polkadot-api"),vt=require("rxjs");var V=require("rxjs"),R=require("rxjs/operators");var se=require("@galacticcouncil/descriptors");var ee=require("@galacticcouncil/common"),Lt=require("rxjs");var It=require("rxjs"),$=require("rxjs/operators");var{logger:Gs}=ee.log;var Ge=require("polkadot-api/ws"),Ve=require("polkadot-api/logs-provider");var We=require("polkadot-api/sm-provider");var Ue=require("polkadot-api");var ae=require("@galacticcouncil/common"),Ot=require("rxjs"),M=require("rxjs/operators");var{logger:ra}=ae.log;var Xe=require("rxjs");var ie=require("@galacticcouncil/common");var fa={Aave:"AAVE",LBP:"LBP",Omnipool:"OMNI",Stableswap:"STBL",XYK:"XYK",HSM:"HSM"},{logger:Sa}=ie.log;var{withTimeout:La}=ft;var h=require("@galacticcouncil/math-omnipool"),z=Et(require("big.js")),I=class{static calculateSpotPrice(t,e,s,a){return(0,h.calculate_spot_price)(t,e,s,a)}static calculateLrnaSpotPrice(t,e){return(0,h.calculate_lrna_spot_price)(t,e)}static calculateInGivenOut(t,e,s,a,i,n,r,o,l,u){return(0,h.calculate_in_given_out)(t,e,s,a,i,n,r,o,l,u)}static calculateLrnaInGivenOut(t,e,s,a,i,n){return(0,h.calculate_lrna_in_given_out)(t,e,s,a,i,n)}static calculateOutGivenIn(t,e,s,a,i,n,r,o,l,u){return(0,h.calculate_out_given_in)(t,e,s,a,i,n,r,o,l,u)}static calculateOutGivenLrnaIn(t,e,s,a,i,n){return(0,h.calculate_out_given_lrna_in)(t,e,s,a,i,n)}static calculateShares(t,e,s,a){return(0,h.calculate_shares)(t,e,s,a)}static calculateLiquidityOut(t,e,s,a,i,n,r,o){return(0,h.calculate_liquidity_out)(t,e,s,a,i,n,r,o)}static calculateLiquidityLRNAOut(t,e,s,a,i,n,r,o){return(0,h.calculate_liquidity_lrna_out)(t,e,s,a,i,n,r,o)}static calculateCapDifference(t,e,s,a){let i=(0,z.default)(e),n=(0,z.default)(t),r=(0,z.default)(a),o=(0,z.default)(s),l=(0,z.default)(10).pow(18),u=o.div(l);if(i.div(r).lt(u)){let b=u.times(r).minus(i).times(n),d=i.times((0,z.default)(1).minus(u));return b.div(d).toFixed(0)}else return"0"}static calculateLimitHubIn(t,e,s,a){return(0,h.calculate_liquidity_hub_in)(t,e,s,a)}static isSellAllowed(t){return(0,h.is_sell_allowed)(t)}static isBuyAllowed(t){return(0,h.is_buy_allowed)(t)}static isAddLiquidityAllowed(t){return(0,h.is_add_liquidity_allowed)(t)}static isRemoveLiquidityAllowed(t){return(0,h.is_remove_liquidity_allowed)(t)}static recalculateAssetFee(t,e,s,a,i,n,r,o,l,u,m){return(0,h.recalculate_asset_fee)(t,e,s,a,i,n,r,o,l,u,m)}static recalculateProtocolFee(t,e,s,a,i,n,r,o,l,u,m){return(0,h.recalculate_protocol_fee)(t,e,s,a,i,n,r,o,l,u,m)}static verifyAssetCap(t,e,s,a){return(0,h.verify_asset_cap)(t,e,s,a)}};var ne=require("@galacticcouncil/common");var{FeeUtils:q}=w,Tt=class c{type;address;tokens;maxInRatio;maxOutRatio;minTradingLimit;hubAssetId;static fromPool(t){return new c(t)}constructor(t){this.type="Omnipool",this.address=t.address,this.tokens=t.tokens,this.maxInRatio=t.maxInRatio,this.maxOutRatio=t.maxOutRatio,this.minTradingLimit=t.minTradingLimit,this.hubAssetId=t.hubAssetId}validatePair(t,e){return this.hubAssetId!=e}parsePair(t,e){let s=new Map(this.tokens.map(n=>[n.id,n])),a=s.get(t),i=s.get(e);if(a==null)throw new Error("Pool does not contain tokenIn");if(i==null)throw new Error("Pool does not contain tokenOut");return{assetIn:t,assetOut:e,hubReservesIn:a.hubReserves,hubReservesOut:i.hubReserves,sharesIn:a.shares,sharesOut:i.shares,decimalsIn:a.decimals,decimalsOut:i.decimals,balanceIn:a.balance,balanceOut:i.balance,tradeableIn:a.tradeable,tradeableOut:i.tradeable,assetInEd:a.existentialDeposit,assetOutEd:i.existentialDeposit}}validateAndBuy(t,e,s){let a=this.calculateInGivenOut(t,e),i=this.calculateInGivenOut(t,e,s),n=a===0n?0:A.calculateBuyFee(a,i),r=[],o=I.isSellAllowed(t.tradeableIn),l=I.isBuyAllowed(t.tradeableOut);(!o||!l)&&r.push("TradeNotAllowed"),(e<this.minTradingLimit||a<t.assetInEd)&&r.push("InsufficientTradingAmount");let u=t.balanceOut/this.maxOutRatio;e>u&&r.push("MaxOutRatioExceeded");let m=t.balanceIn/this.maxInRatio;return i>m&&r.push("MaxInRatioExceeded"),{amountIn:i,calculatedIn:a,amountOut:e,feePct:n,errors:r}}validateAndSell(t,e,s){let a=this.calculateOutGivenIn(t,e),i=this.calculateOutGivenIn(t,e,s),n=A.calculateSellFee(a,i),r=[],o=I.isSellAllowed(t.tradeableIn),l=I.isBuyAllowed(t.tradeableOut);(!o||!l)&&r.push("TradeNotAllowed"),(e<this.minTradingLimit||a<t.assetOutEd)&&r.push("InsufficientTradingAmount");let u=t.balanceIn/this.maxInRatio;e>u&&r.push("MaxInRatioExceeded");let m=t.balanceOut/this.maxOutRatio;return i>m&&r.push("MaxOutRatioExceeded"),{amountIn:e,calculatedOut:a,amountOut:i,feePct:n,errors:r}}calculateInGivenOut(t,e,s){if(t.assetIn==this.hubAssetId)return this.calculateLrnaInGivenOut(t,e,s);let a=I.calculateInGivenOut(t.balanceIn.toString(),t.hubReservesIn.toString(),t.sharesIn.toString(),t.balanceOut.toString(),t.hubReservesOut.toString(),t.sharesOut.toString(),e.toString(),s?q.toRaw(s.assetFee).toString():"0",s?q.toRaw(s.protocolFee).toString():"0",s?q.toRaw(s.maxSlipFee).toString():"0"),i=BigInt(a);return i<0n?0n:i}calculateLrnaInGivenOut(t,e,s){let a=I.calculateLrnaInGivenOut(t.balanceOut.toString(),t.hubReservesOut.toString(),t.sharesOut.toString(),e.toString(),s?q.toRaw(s.assetFee).toString():"0",s?q.toRaw(s.maxSlipFee).toString():"0"),i=BigInt(a);return i<0n?0n:i}calculateOutGivenIn(t,e,s){if(t.assetIn==this.hubAssetId)return this.calculateOutGivenLrnaIn(t,e,s);let a=I.calculateOutGivenIn(t.balanceIn.toString(),t.hubReservesIn.toString(),t.sharesIn.toString(),t.balanceOut.toString(),t.hubReservesOut.toString(),t.sharesOut.toString(),e.toString(),s?q.toRaw(s.assetFee).toString():"0",s?q.toRaw(s.protocolFee).toString():"0",s?q.toRaw(s.maxSlipFee).toString():"0"),i=BigInt(a);return i<0n?0n:i}calculateOutGivenLrnaIn(t,e,s){let a=I.calculateOutGivenLrnaIn(t.balanceOut.toString(),t.hubReservesOut.toString(),t.sharesOut.toString(),e.toString(),s?q.toRaw(s.assetFee).toString():"0",s?q.toRaw(s.maxSlipFee).toString():"0"),i=BigInt(a);return i<0n?0n:i}spotPriceInGivenOut(t){if(t.assetIn==this.hubAssetId)return this.spotPriceLrnaInGivenOut(t);let e=I.calculateSpotPrice(t.balanceOut.toString(),t.hubReservesOut.toString(),t.balanceIn.toString(),t.hubReservesIn.toString());return this.normalizeSpot(BigInt(e),t.decimalsOut,t.decimalsIn)}spotPriceLrnaInGivenOut(t){let e=I.calculateLrnaSpotPrice(t.hubReservesOut.toString(),t.balanceOut.toString());return this.normalizeSpot(BigInt(e),t.decimalsOut,t.decimalsIn)}spotPriceOutGivenIn(t){if(t.assetIn==this.hubAssetId)return this.spotPriceOutGivenLrnaIn(t);let e=I.calculateSpotPrice(t.balanceIn.toString(),t.hubReservesIn.toString(),t.balanceOut.toString(),t.hubReservesOut.toString());return this.normalizeSpot(BigInt(e),t.decimalsIn,t.decimalsOut)}spotPriceOutGivenLrnaIn(t){let e=I.calculateLrnaSpotPrice(t.balanceOut.toString(),t.hubReservesOut.toString());return this.normalizeSpot(BigInt(e),t.decimalsIn,t.decimalsOut)}normalizeSpot(t,e,s){let a=e-s;if(a===0)return t;let i=ne.big.pow10(Math.abs(a));return a>0?t*i:t/i}};var K=require("polkadot-api"),Ke=require("@polkadot-api/utils"),j=require("rxjs"),je=require("@galacticcouncil/common");var{FeeUtils:fi}=w,Si=K.Binary.toHex(K.Binary.fromText("omnipool")),Ii=(0,K.Enum)("Short");var O=require("@galacticcouncil/math-stableswap"),k=class{static getPoolAddress(t){return(0,O.pool_account_name)(t)}static defaultPegs(t){let e=[];for(let s=0;s<t;s++)e.push(["1","1"]);return e}static calculateAmplification(t,e,s,a,i){return(0,O.calculate_amplification)(t,e,s,a,i)}static calculateInGivenOut(t,e,s,a,i,n,r){return(0,O.calculate_in_given_out)(t,e,s,a,i,n,r)}static calculateAddOneAsset(t,e,s,a,i,n,r){return(0,O.calculate_add_one_asset)(t,e,s,a,i,n,r)}static calculateSharesForAmount(t,e,s,a,i,n,r){return(0,O.calculate_shares_for_amount)(t,e,s,a,i,n,r)}static calculateOutGivenIn(t,e,s,a,i,n,r){return(0,O.calculate_out_given_in)(t,e,s,a,i,n,r)}static calculateLiquidityOutOneAsset(t,e,s,a,i,n,r){return(0,O.calculate_liquidity_out_one_asset)(t,e,s,a,i,n,r)}static calculateShares(t,e,s,a,i,n){return(0,O.calculate_shares)(t,e,s,a,i,n)}static calculateSpotPriceWithFee(t,e,s,a,i,n,r,o){return(0,O.calculate_spot_price_with_fee)(t,e,s,a,i,n,r,o)}static recalculatePegs(t,e,s,a,i,n){let r=(0,O.recalculate_peg)(t,e,s,a,i,n);return JSON.parse(r)}};var dt=require("@galacticcouncil/common");var{FeeUtils:et}=w,st=class c{type;address;tokens;maxInRatio;maxOutRatio;minTradingLimit;amplification;isRampPeriod;id;fee;totalIssuance;pegs;static fromPool(t){return new c(t)}constructor(t){this.type="Stableswap",this.address=t.address,this.tokens=t.tokens,this.maxInRatio=t.maxInRatio,this.maxOutRatio=t.maxOutRatio,this.minTradingLimit=t.minTradingLimit,this.amplification=t.amplification,this.isRampPeriod=t.isRampPeriod,this.id=t.id,this.fee=t.fee,this.totalIssuance=t.totalIssuance,this.pegs=t.pegs}validatePair(t,e){return!0}parsePair(t,e){let s=new Map(this.tokens.map(n=>[n.id,n])),a=s.get(t),i=s.get(e);if(a==null)throw new Error("Pool does not contain tokenIn");if(i==null)throw new Error("Pool does not contain tokenOut");return{assetIn:t,assetOut:e,balanceIn:a.balance,balanceOut:i.balance,decimalsIn:a.decimals,decimalsOut:i.decimals,tradeableIn:this.id===t?15:a.tradeable,tradeableOut:this.id===e?15:i.tradeable,assetInEd:a.existentialDeposit,assetOutEd:i.existentialDeposit}}validateAndBuy(t,e,s){let a=this.calculateInGivenOut(t,e),i=this.calculateInGivenOut(t,e,s),n=a===0n?0:A.calculateBuyFee(a,i),r=[],o=I.isSellAllowed(t.tradeableIn),l=I.isBuyAllowed(t.tradeableOut);return(!o||!l)&&r.push("TradeNotAllowed"),(e<this.minTradingLimit||a<t.assetInEd)&&r.push("InsufficientTradingAmount"),{amountIn:i,calculatedIn:a,amountOut:e,feePct:n,errors:r}}validateAndSell(t,e,s){let a=this.calculateOutGivenIn(t,e),i=this.calculateOutGivenIn(t,e,s),n=A.calculateSellFee(a,i),r=[],o=I.isSellAllowed(t.tradeableIn),l=I.isBuyAllowed(t.tradeableOut);return(!o||!l)&&r.push("TradeNotAllowed"),(e<this.minTradingLimit||a<t.assetOutEd)&&r.push("InsufficientTradingAmount"),{amountIn:e,calculatedOut:a,amountOut:i,feePct:n,errors:r}}calculateIn(t,e,s){let a=k.calculateInGivenOut(this.getReserves(),Number(t.assetIn),Number(t.assetOut),e.toString(),this.amplification.toString(),s?et.toRaw(s.fee).toString():"0",this.getPegs()),i=BigInt(a);return i<0n?0n:i}calculateAddOneAsset(t,e,s){let a=k.calculateAddOneAsset(this.getReserves(),e.toString(),Number(t.assetIn),this.amplification.toString(),this.totalIssuance.toString(),s?et.toRaw(s.fee).toString():"0",this.getPegs()),i=BigInt(a);return i<0n?0n:i}calculateSharesForAmount(t,e,s){let a=k.calculateSharesForAmount(this.getReserves(),Number(t.assetOut),e.toString(),this.amplification.toString(),this.totalIssuance.toString(),s?et.toRaw(s.fee).toString():"0",this.getPegs()),i=BigInt(a);return i<0n?0n:i}calculateInGivenOut(t,e,s){return t.assetOut==this.id?this.calculateAddOneAsset(t,e,s):t.assetIn==this.id?this.calculateSharesForAmount(t,e,s):this.calculateIn(t,e,s)}spotPriceInGivenOut(t){let e=k.calculateSpotPriceWithFee(this.id.toString(),this.getReserves(),this.amplification.toString(),t.assetOut.toString(),t.assetIn.toString(),this.totalIssuance.toString(),"0",this.getPegs());return this.normalizeSpot(BigInt(e),t.assetOut===this.id,t.assetIn===this.id,t.decimalsOut,t.decimalsIn)}calculateOut(t,e,s){let a=k.calculateOutGivenIn(this.getReserves(),Number(t.assetIn),Number(t.assetOut),e.toString(),this.amplification.toString(),s?et.toRaw(s.fee).toString():"0",this.getPegs()),i=BigInt(a);return i<0n?0n:i}calculateWithdrawOneAsset(t,e,s){let a=k.calculateLiquidityOutOneAsset(this.getReserves(),e.toString(),Number(t.assetOut),this.amplification.toString(),this.totalIssuance.toString(),s?et.toRaw(s.fee).toString():"0",this.getPegs()),i=BigInt(a);return i<0n?0n:i}calculateShares(t,e,s){let a=k.calculateShares(this.getReserves(),this.getAssets(t.assetIn,e),this.amplification.toString(),this.totalIssuance.toString(),s?et.toRaw(s.fee).toString():"0",this.getPegs()),i=BigInt(a);return i<0n?0n:i}calculateOutGivenIn(t,e,s){return t.assetIn==this.id?this.calculateWithdrawOneAsset(t,e,s):t.assetOut==this.id?this.calculateShares(t,e,s):this.calculateOut(t,e,s)}spotPriceOutGivenIn(t){let e=k.calculateSpotPriceWithFee(this.id.toString(),this.getReserves(),this.amplification.toString(),t.assetIn.toString(),t.assetOut.toString(),this.totalIssuance.toString(),"0",this.getPegs());return this.normalizeSpot(BigInt(e),t.assetIn===this.id,t.assetOut===this.id,t.decimalsIn,t.decimalsOut)}getPegs(){return JSON.stringify(this.pegs)}getReserves(){let t=this.tokens.filter(e=>e.id!=this.id).map(({id:e,balance:s,decimals:a})=>({asset_id:e,amount:s,decimals:a}));return JSON.stringify(t,ut.jsonFormatter)}getAssets(t,e){let s={asset_id:Number(t),amount:e.toString()};return JSON.stringify([s],ut.jsonFormatter)}normalizeSpot(t,e,s,a,i){return e?t*dt.big.pow10(dt.RUNTIME_DECIMALS-i):s?t/dt.big.pow10(i-a):t}};var re=require("polkadot-api"),Je=require("@polkadot-api/utils"),Ze=require("@noble/hashes/blake2b"),gt=require("rxjs"),oe=require("@galacticcouncil/common");var{FeeUtils:Ji}=w;var v=require("@galacticcouncil/math-xyk"),X=class{static getSpotPrice(t,e,s){return(0,v.get_spot_price)(t,e,s)}static calculateInGivenOut(t,e,s){return(0,v.calculate_in_given_out)(t,e,s)}static calculateOutGivenIn(t,e,s){return(0,v.calculate_out_given_in)(t,e,s)}static calculatePoolTradeFee(t,e,s){return(0,v.calculate_pool_trade_fee)(t,e,s)}static calculateLiquidityIn(t,e,s){return(0,v.calculate_liquidity_in)(t,e,s)}static calculateSpotPrice(t,e){return(0,v.calculate_spot_price)(t,e)}static calculateSpotPriceWithFee(t,e,s,a){return(0,v.calculate_spot_price_with_fee)(t,e,s,a)}static calculateShares(t,e,s){return(0,v.calculate_shares)(t,e,s)}static calculateLiquidityOutAssetA(t,e,s,a){return(0,v.calculate_liquidity_out_asset_a)(t,e,s,a)}static calculateLiquidityOutAssetB(t,e,s,a){return(0,v.calculate_liquidity_out_asset_b)(t,e,s,a)}};var ce=require("@galacticcouncil/common");var{FeeUtils:le}=w,xt=class c{type;address;tokens;maxInRatio;maxOutRatio;minTradingLimit;static fromPool(t){return new c(t)}constructor(t){this.type="XYK",this.address=t.address,this.tokens=t.tokens,this.maxInRatio=t.maxInRatio,this.maxOutRatio=t.maxOutRatio,this.minTradingLimit=t.minTradingLimit}validatePair(t,e){return!0}parsePair(t,e){let s=new Map(this.tokens.map(n=>[n.id,n])),a=s.get(t),i=s.get(e);if(a==null)throw new Error("Pool does not contain tokenIn");if(i==null)throw new Error("Pool does not contain tokenOut");return{assetIn:t,assetOut:e,decimalsIn:a.decimals,decimalsOut:i.decimals,balanceIn:a.balance,balanceOut:i.balance,assetInEd:a.existentialDeposit,assetOutEd:i.existentialDeposit}}validateAndBuy(t,e,s){let a=this.calculateInGivenOut(t,e),i=this.calculateTradeFee(a,s),n=le.toPct(s.exchangeFee),r=a+i,o=[];(e<this.minTradingLimit||a<t.assetInEd)&&o.push("InsufficientTradingAmount");let l=t.balanceOut/this.maxOutRatio;e>l&&o.push("MaxOutRatioExceeded");let u=t.balanceIn/this.maxInRatio;return r>u&&o.push("MaxInRatioExceeded"),{amountIn:r,calculatedIn:a,amountOut:e,feePct:n,errors:o}}validateAndSell(t,e,s){let a=this.calculateOutGivenIn(t,e),i=this.calculateTradeFee(a,s),n=le.toPct(s.exchangeFee),r=a-i,o=[];(e<this.minTradingLimit||a<t.assetOutEd)&&o.push("InsufficientTradingAmount");let l=t.balanceIn/this.maxInRatio;e>l&&o.push("MaxInRatioExceeded");let u=t.balanceOut/this.maxOutRatio;return r>u&&o.push("MaxOutRatioExceeded"),{amountIn:e,calculatedOut:a,amountOut:r,feePct:n,errors:o}}calculateInGivenOut(t,e){let s=X.calculateInGivenOut(t.balanceIn.toString(),t.balanceOut.toString(),e.toString()),a=BigInt(s);return a<0n?0n:a}calculateOutGivenIn(t,e){let s=X.calculateOutGivenIn(t.balanceIn.toString(),t.balanceOut.toString(),e.toString()),a=BigInt(s);return a<0n?0n:a}spotPriceInGivenOut(t){let e=X.calculateSpotPrice(t.balanceOut.toString(),t.balanceIn.toString());return this.normalizeSpot(BigInt(e),t.decimalsOut,t.decimalsIn)}spotPriceOutGivenIn(t){let e=X.calculateSpotPrice(t.balanceIn.toString(),t.balanceOut.toString());return this.normalizeSpot(BigInt(e),t.decimalsIn,t.decimalsOut)}calculateTradeFee(t,e){let s=X.calculatePoolTradeFee(t.toString(),e.exchangeFee[0],e.exchangeFee[1]);return BigInt(s)}normalizeSpot(t,e,s){let a=e-s;if(a===0)return t;let i=ce.big.pow10(Math.abs(a));return a>0?t*i:t/i}};var es=require("polkadot-api"),ss=require("rxjs");var at=require("@galacticcouncil/common");var Bt=class c{type;address;tokens;maxInRatio;maxOutRatio;minTradingLimit;static fromPool(t){return new c(t)}constructor(t){this.type="Aave",this.address=t.address,this.tokens=t.tokens,this.maxInRatio=t.maxInRatio,this.maxOutRatio=t.maxOutRatio,this.minTradingLimit=t.minTradingLimit}validatePair(t,e){return!0}parsePair(t,e){let s=new Map(this.tokens.map(n=>[n.id,n])),a=s.get(t),i=s.get(e);if(a==null)throw new Error("Pool does not contain tokenIn");if(i==null)throw new Error("Pool does not contain tokenOut");return{assetIn:t,assetOut:e,balanceIn:a.balance,balanceOut:i.balance,decimalsIn:a.decimals,decimalsOut:i.decimals,assetInEd:0n,assetOutEd:0n}}validateAndBuy(t,e,s){let a=this.calculateInGivenOut(t,e),i=[];return e>t.balanceOut&&i.push("TradeNotAllowed"),{amountIn:a,calculatedIn:a,amountOut:e,feePct:0,errors:i}}validateAndSell(t,e,s){let a=this.calculateOutGivenIn(t,e),i=[];return a>t.balanceOut&&i.push("TradeNotAllowed"),{amountIn:e,calculatedOut:a,amountOut:a,feePct:0,errors:i}}calculateInGivenOut(t,e){return e}calculateOutGivenIn(t,e){return e}spotPriceInGivenOut(t){return at.big.toBigInt(1,at.RUNTIME_DECIMALS)}spotPriceOutGivenIn(t){return at.big.toBigInt(1,at.RUNTIME_DECIMALS)}calculateTradeFee(t,e){return 0n}};var ue=require("polkadot-api"),is=require("@polkadot-api/utils"),At=require("rxjs"),ns=require("viem"),Ht=require("@galacticcouncil/common");var{ERC20:Yn}=Ht.erc20;var B=require("@galacticcouncil/math-hsm"),L=class{static calculateCollateralInGivenHollarOut(t,e,s){return(0,B.calculate_collateral_in_given_hollar_out)(t,e,s)}static calculateCollateralOutGivenHollarIn(t,e,s){return(0,B.calculate_collateral_out_given_hollar_in)(t,e,s)}static calculateHollarOutGivenCollateralIn(t,e,s){return(0,B.calculate_hollar_out_given_collateral_in)(t,e,s)}static calculateHollarInGivenCollateralOut(t,e,s){return(0,B.calculate_hollar_in_given_collateral_out)(t,e,s)}static calculateImbalance(t,e,s){return(0,B.calculate_imbalance)(t,e,s)}static calculateBuybackLimit(t,e){return(0,B.calculate_buyback_limit)(t,e)}static calculateBuybackPriceWithFee(t,e,s){return(0,B.calculate_buyback_price_with_fee)(t,e,s)}static calculateMaxPrice(t,e){return(0,B.calculate_max_price)(t,e)}};var F=require("@galacticcouncil/common");var{FeeUtils:it}=w,Ft=class c extends st{hsmAddress;hsmMintCapacity;hollarId;hollarH160;collateralId;collateralBalance;maxBuyPriceCoefficient;maxInHolding;purchaseFee;buyBackFee;buyBackRate;static fromPool(t){return new c(t)}constructor(t){super(t),this.type="HSM",this.hsmAddress=t.hsmAddress,this.hsmMintCapacity=t.hsmMintCapacity,this.hollarId=t.hollarId,this.hollarH160=t.hollarH160,this.collateralId=t.collateralId,this.collateralBalance=t.collateralBalance,this.maxBuyPriceCoefficient=t.maxBuyPriceCoefficient,this.maxInHolding=t.maxInHolding,this.purchaseFee=t.purchaseFee,this.buyBackFee=t.buyBackFee,this.buyBackRate=t.buyBackRate}validatePair(t,e){return!0}parsePair(t,e){return super.parsePair(t,e)}validateTradeHollarIn(t,e,s){let a=this.parsePair(t.assetOut,t.assetIn),i=super.calculateInGivenOut(a,e,{fee:this.fee}),n=this.calculateBuybackLimit(t);e>n&&s.push("MaxBuyBackExceeded");let r=this.calculateMaxPrice(t);return this.calculateBuyPrice(t,e,i)>r&&s.push("MaxBuyPriceExceeded"),i>this.collateralBalance&&s.push("InsufficientCollateral"),s}validateTradeHollarOut(t,e,s){return this.collateralBalance+t>this.maxInHolding&&s.push("MaxHoldingExceeded"),e>this.hsmMintCapacity&&s.push("FacilitatorCapacityExceeded"),s}validateTradeConstraints(t,e,s){let a=[];return t.assetIn===this.hollarId?this.validateTradeHollarIn(t,e,a):this.validateTradeHollarOut(e,s,a)}validateAndBuy(t,e){let s=this.calculateInGivenOut(t,e),a=this.validateTradeConstraints(t,s,e);return{amountIn:s,calculatedIn:s,amountOut:e,feePct:0,errors:a}}validateAndSell(t,e){let s=this.calculateOutGivenIn(t,e),a=this.validateTradeConstraints(t,e,s);return{amountIn:e,calculatedOut:s,amountOut:s,feePct:0,errors:a}}calculateHollarInGivenCollateralOut(t,e){let s=super.calculateInGivenOut(t,e,{fee:this.fee}),a=L.calculateHollarInGivenCollateralOut(e.toString(),s.toString(),it.toRaw(this.buyBackFee).toString());return BigInt(a)}calculateCollateralInGivenHollarOut(t){let e=this.getCollateralPeg(),s=L.calculateCollateralInGivenHollarOut(t.toString(),JSON.stringify(e),it.toRaw(this.purchaseFee).toString());return BigInt(s)}calculateInGivenOut(t,e){return t.assetOut==this.hollarId?this.calculateCollateralInGivenHollarOut(e):this.calculateHollarInGivenCollateralOut(t,e)}calculateCollateralOutGivenHollarIn(t,e){let s=super.calculateOutGivenIn(t,e,{fee:this.fee}),a=L.calculateCollateralOutGivenHollarIn(e.toString(),s.toString(),it.toRaw(this.buyBackFee).toString());return BigInt(a)}calculateHollarOutGivenCollateralIn(t){let e=this.getCollateralPeg(),s=L.calculateHollarOutGivenCollateralIn(t.toString(),JSON.stringify(e),it.toRaw(this.purchaseFee).toString());return BigInt(s)}calculateOutGivenIn(t,e){return t.assetIn==this.hollarId?this.calculateCollateralOutGivenHollarIn(t,e):this.calculateHollarOutGivenCollateralIn(e)}calculateImbalance(t){let e=this.getCollateralPeg(),s=L.calculateImbalance(t.balanceIn.toString(),JSON.stringify(e),t.balanceOut.toString());return BigInt(s)}calculateBuybackLimit(t){let e=this.calculateImbalance(t),s=L.calculateBuybackLimit(e.toString(),it.toRaw(this.buyBackRate).toString());return BigInt(s)}calculateBuyPrice(t,e,s){let a=L.calculateBuybackPriceWithFee(s.toString(),e.toString(),it.toRaw(this.buyBackFee).toString()),[i,n]=JSON.parse(a),r=F.big.pow10(t.decimalsIn+F.RUNTIME_DECIMALS-t.decimalsOut);return BigInt(i)*r/BigInt(n)}calculateMaxPrice(t){let e=this.getCollateralPeg(),s=L.calculateMaxPrice(JSON.stringify(e),this.maxBuyPriceCoefficient.toString()),[a,i]=JSON.parse(s),n=F.big.pow10(F.RUNTIME_DECIMALS-t.decimalsOut);return BigInt(a)*n/BigInt(i)}spotPriceInGivenOut(t){let e=F.big.toBigInt(1,t.decimalsOut),a=this.calculateInGivenOut(t,e)*F.big.pow10(F.RUNTIME_DECIMALS-t.decimalsOut);return this.normalizeSpotPrice(a,t.decimalsOut,t.decimalsIn)}spotPriceOutGivenIn(t){let e=F.big.toBigInt(1,t.decimalsIn),a=this.calculateOutGivenIn(t,e)*F.big.pow10(F.RUNTIME_DECIMALS-t.decimalsIn);return this.normalizeSpotPrice(a,t.decimalsIn,t.decimalsOut)}getCollateralPeg(){let t=this.tokens.findIndex(a=>a.id!==this.hollarId),e=this.pegs[t],s=this.tokens[t].decimals;return this.isDefaultPeg(e)?[F.big.toBigInt(1,18).toString(),F.big.toBigInt(1,s).toString()]:e}isDefaultPeg(t){let[e,s]=t;return Array.isArray(t)&&t.length===2&&e==="1"&&s==="1"}normalizeSpotPrice(t,e,s){let a=e-s;if(a===0)return t;let i=F.big.pow10(Math.abs(a));return a>0?t*i:t/i}};var Nt=require("polkadot-api"),ls=require("@polkadot-api/utils"),nt=require("rxjs"),cs=require("viem"),qt=require("@galacticcouncil/common");var{FeeUtils:Or}=w,{H160:vr}=qt.h160;var ht=class{static get(t){switch(t.type){case"Aave":return Bt.fromPool(t);case"XYK":return xt.fromPool(t);case"Omnipool":return Tt.fromPool(t);case"LBP":return St.fromPool(t);case"Stableswap":return st.fromPool(t);case"HSM":return Ft.fromPool(t);default:throw new Error("Pool type "+t.type+" is not supported yet")}}};var me=require("@galacticcouncil/common"),Gt=require("rxjs");var _t=class extends Error{constructor(t,e){super(),this.message=`Route from ${t} to ${e} not found in current configuration`,this.name="RouteNotFound"}};var{logger:mo}=me.log;var bt=class{getProposals(t,e,s){let a=s.filter(p=>p.type==="XYK"),i=s.filter(p=>p.type!=="XYK"),n=new Set(i.map(p=>p.tokens).flat().map(p=>p.id)),r=n.has(t),o=n.has(e),l=new ct,u=p=>{let y=kt(p),f=Object.keys(y),D=f.flatMap(E=>y[E]);return l.buildAndPopulateGraph(f,D)};if(!r&&!o){let p=a.filter(D=>D.tokens.find(E=>E.id===t)||D.tokens.find(E=>E.id===e)),y=u(p),f=l.findPaths(y,t,e);return this.parsePaths(f)}if(r&&o){let p=u(i),y=l.findPaths(p,t,e);return this.parsePaths(y)}let m=r?e:t,b=a.filter(p=>p.tokens.some(y=>y.id===m));if(b.length===0)return[];let d=[...i,...b],S=u(d),g=l.findPaths(S,t,e);return this.parsePaths(g)}parsePaths(t){let e=[];for(let s of t){let a=[];for(let i=0;i<s.length;i++){let n=s[i],r=s[i+1];if(r==null)break;a.push(this.toEdge(n,r))}e.push(a)}return e}toEdge(t,e){return[e[1],t[0],e[0]]}};var rt=class{routeSuggester;routeProposals;ctx;filter={};constructor(t){this.ctx=t,this.routeSuggester=new bt,this.routeProposals=new Map}async withFilter(t){this.filter=t||{},this.routeProposals.clear(),this.onFilterChanged()}onFilterChanged(){}buildRouteKey(t,e,s){return`${t}->${e}::${s.length}`}applyPoolFilter(t){let{useOnly:e=[],exclude:s=[]}=this.filter,a=new Set(e),i=new Set(s);return t.filter(n=>i.has(n.type)?!1:a.size>0?a.has(n.type):!0)}async getPools(){let t=await this.ctx.getPools();return this.applyPoolFilter(t)}async getRoutes(t,e){let s=await this.getPools();return this.validateInput(t,e,s),this.getPaths(t,e,s)}async getTradeableAssets(){let t=await this.getPools(),e=this.getAssets(t);return Array.from(e)}async getRouteableAssets(t){let e=await this.getTradeableAssets();return(await Promise.all(e.filter(a=>a!==t).map(a=>this.getRoutes(a,t)))).filter(a=>a.length>0).map(([a])=>a[0].assetIn).sort()}validateInput(t,e,s){if(s.length===0)throw new Error("No pools configured");if(t===e)throw new Error("Trading pair can't be identical");let a=this.getAssets(s);if(!a.has(t))throw new Error(t+" is not supported asset");if(!a.has(e))throw new Error(e+" is not supported asset");return this.toPoolsMap(s)}getAssets(t){let e=t.map(s=>s.tokens.map(a=>a.id)).flat().sort((s,a)=>s>a?1:-1);return new Set(e)}getPaths(t,e,s){let a=this.toPoolsMap(s);return this.getProposals(t,e,s).filter(n=>this.validPath(n,a)).map(n=>this.toHops(n,a))}getProposals(t,e,s){let a=this.buildRouteKey(t,e,s);if(this.routeProposals.has(a))return this.routeProposals.get(a);let i=this.routeSuggester.getProposals(t,e,s);return this.routeProposals.set(a,i),i}validPath(t,e){return t.length>0&&t.map(s=>this.validEdge(s,e)).reduce((s,a)=>s&&a)}validEdge([t,e,s],a){return a.get(t)?.validatePair(e,s)||!1}toPoolsMap(t){return new Map(t.map(e=>[e.address,ht.get(e)]))}toHops(t,e){return t.map(([s,a,i])=>{let n=e.get(s);return{poolAddress:s,poolId:n?.id,pool:n?.type,assetIn:a,assetOut:i}})}};var P=require("@galacticcouncil/common");var Vt=(e=>(e.Buy="Buy",e.Sell="Sell",e))(Vt||{}),Wt=(s=>(s.Dca="Dca",s.TwapSell="TwapSell",s.TwapBuy="TwapBuy",s))(Wt||{}),Ut=(s=>(s.OrderTooSmall="OrderTooSmall",s.OrderTooBig="OrderTooBig",s.OrderImpactTooBig="OrderImpactTooBig",s))(Ut||{});var{FeeUtils:de}=w,ot=class extends rt{mlr;constructor(t){super(t),this.mlr=new Map}onFilterChanged(){this.mlr.clear()}buildCtxSync(t,e,s){let a=super.validateInput(t,e,s),i=super.getPaths(t,e,s);if(!i.length)throw new _t(t,e);return{paths:i,pools:s,poolsMap:a}}async withCtx(t,e,s){let a=await super.getPools(),i=this.buildCtxSync(t,e,a);return s(i)}isDirectTrade(t){return t.length==1}findBestSellRoute(t){let e=t.sort((s,a)=>{let i=s[s.length-1].amountOut,n=a[a.length-1].amountOut;return i>n?-1:1});return e.find(s=>s.every(a=>a.errors.length==0))||e[0]}getRouteFeeRange(t){if(t.filter(s=>s.tradeFeeRange).length>0){let s=t.map(i=>i.tradeFeeRange?.[0]??i.tradeFeePct).reduce((i,n)=>i+n),a=t.map(i=>i.tradeFeeRange?.[1]??i.tradeFeePct).reduce((i,n)=>i+n);return[s,a]}}getPoolFeeRange(t,e){let s=t.min?de.toPct(t.min):void 0,a=t.max?de.toPct(t.max):void 0;if(s&&a)return[s,Math.max(a,e)]}async getBestSell(t,e,s){return this.getSell(t,e,s)}getSellSpot(t){let e=t[t.length-1];return t.length===1?e.spotPrice:this.calculateSpot(t)}async getSell(t,e,s,a){return this.withCtx(t,e,async({paths:i,poolsMap:n})=>{let r;if(a)r=await this.toSellSwaps(s,a,n);else{let o=i.map(u=>this.toSellSwaps(s,u,n)),l=await Promise.all(o);r=this.findBestSellRoute(l)}return this.buildSell(n,r)})}async getSells(t,e,s){return this.withCtx(t,e,async({paths:a,poolsMap:i})=>{let n=a.map(o=>this.toSellSwaps(s,o,i));return(await Promise.all(n)).filter(o=>o.every(l=>l.errors.length==0)).map(o=>this.buildSell(i,o)).sort((o,l)=>o.amountOut>l.amountOut?-1:1)})}buildSell(t,e){let s=e[0],a=e[e.length-1],i=this.isDirectTrade(e),n=this.getSellSpot(e),r=a.amountOut,o=i?a.calculatedOut:this.calculateDelta0Y(s.amountIn,e,t),l=o-r,u=this.getRouteFeeRange(e),m=i?a.tradeFeePct:A.calculateSellFee(o,r),b=C.mulSpot(s.amountIn,n,s.assetInDecimals,a.assetOutDecimals),d=A.calculateDiffToRef(o,b);return{type:"Sell",amountIn:s.amountIn,amountOut:a.amountOut,spotPrice:n,tradeFee:l,tradeFeePct:m,tradeFeeRange:u,priceImpactPct:d,swaps:e,toHuman(){return{type:"Sell",amountIn:P.big.toDecimal(s.amountIn,s.assetInDecimals),amountOut:P.big.toDecimal(a.amountOut,a.assetOutDecimals),spotPrice:P.big.toDecimal(n,P.RUNTIME_DECIMALS),tradeFee:P.big.toDecimal(l,a.assetOutDecimals),tradeFeePct:m,tradeFeeRange:u,priceImpactPct:d,swaps:e.map(S=>S.toHuman())}}}}calculateSpot(t){return t.map(e=>e.spotPrice).reduce((e,s)=>e*s/10n**BigInt(P.RUNTIME_DECIMALS))}calculateDelta0Y(t,e,s){let a=[];for(let i=0;i<e.length;i++){let n=e[i],r=s.get(n.poolAddress);if(r==null)throw new Error("Pool does not exit");let o=r.parsePair(n.assetIn,n.assetOut),l;i>0?l=a[i-1]:l=t;let u=r.calculateOutGivenIn(o,l);a.push(u)}return a[a.length-1]}async calculateMostLiquidRoute(t,e,s){let{paths:a,pools:i,poolsMap:n}=s,l=i.filter(g=>g.tokens.some(p=>p.id===t)).map(g=>g.type==="Aave"?g.tokens:g.tokens.filter(p=>p.id===t)).map(g=>g.map(p=>p.balance).reduce((p,y)=>p+y)).sort((g,p)=>p<g?-1:1)[0],u=C.getFraction(l,.1),m=await Promise.all(a.map(g=>this.toSellSwaps(u,g,n))),d=this.findBestSellRoute(m).map(g=>({poolAddress:g.poolAddress,poolId:g?.poolId,pool:g.pool,assetIn:g.assetIn,assetOut:g.assetOut})),S=this.buildRouteKey(t,e,i);return this.mlr.set(S,d),d}async toSellSwaps(t,e,s){let a=[];for(let i=0;i<e.length;i++){let n=e[i],r=s.get(n.poolAddress);if(r==null)throw new Error("Pool does not exit");let o=r.parsePair(n.assetIn,n.assetOut),l;i>0?l=a[i-1].amountOut:l=typeof t=="string"?P.big.toBigInt(t,o.decimalsIn):t;let u=await this.ctx.getPoolFees(o,r),{amountOut:m,calculatedOut:b,feePct:d,errors:S}=r.validateAndSell(o,l,u),g=this.getPoolFeeRange(u,d),p=r.spotPriceOutGivenIn(o),y=C.mulSpot(l,p,o.decimalsIn,o.decimalsOut),f=A.calculateDiffToRef(b,y);a.push({...n,assetInDecimals:o.decimalsIn,assetOutDecimals:o.decimalsOut,amountIn:l,amountOut:m,calculatedOut:b,spotPrice:p,tradeFeePct:d,tradeFeeRange:g,priceImpactPct:f,errors:S,isSupply(){return r.type==="Aave"&&r.tokens[0].id===n.assetIn},isWithdraw(){return r.type==="Aave"&&r.tokens[1].id===n.assetIn},toHuman(){return{...n,amountIn:P.big.toDecimal(l,o.decimalsIn),amountOut:P.big.toDecimal(m,o.decimalsOut),calculatedOut:P.big.toDecimal(b,o.decimalsOut),spotPrice:P.big.toDecimal(p,P.RUNTIME_DECIMALS),tradeFeePct:d,tradeFeeRange:g,priceImpactPct:f,errors:S}}})}return a}async getMostLiquidRoute(t,e){return this.withCtx(t,e,async s=>{let a=this.buildRouteKey(t,e,s.pools),i=this.mlr.get(a);return i||this.calculateMostLiquidRoute(t,e,s)})}async getSpotPrice(t,e){return this.withCtx(t,e,async s=>{let{pools:a,poolsMap:i}=s,n=this.buildRouteKey(t,e,a),r=this.mlr.get(n);r||(r=await this.calculateMostLiquidRoute(t,e,s));let o=await this.toSellSwaps("1",r,i);return{amount:this.getSellSpot(o),decimals:P.RUNTIME_DECIMALS}}).catch(()=>{})}findBestBuyRoute(t){let e=t.sort((s,a)=>{let i=s[0].amountIn,n=a[0].amountIn;return i>n?1:-1});return e.find(s=>s.every(a=>a.errors.length==0))||e[0]}async getBestBuy(t,e,s){return this.getBuy(t,e,s)}getBuySpot(t){let e=t[0];return t.length===1?e.spotPrice:this.calculateSpot(t)}async getBuy(t,e,s,a){return this.withCtx(t,e,async({paths:i,poolsMap:n})=>{let r;if(a)r=await this.toBuySwaps(s,a,n);else{let o=i.map(u=>this.toBuySwaps(s,u,n)),l=await Promise.all(o);r=this.findBestBuyRoute(l)}return this.buildBuy(n,r)})}async getBuys(t,e,s){return this.withCtx(t,e,async({paths:a,poolsMap:i})=>{let n=a.map(o=>this.toBuySwaps(s,o,i));return(await Promise.all(n)).filter(o=>o.every(l=>l.errors.length==0)).map(o=>this.buildBuy(i,o)).sort((o,l)=>o.amountIn>l.amountIn?1:-1)})}buildBuy(t,e){let s=e[e.length-1],a=e[0],i=this.isDirectTrade(e),n=this.getBuySpot(e),r=a.amountIn,o=i?a.calculatedIn:this.calculateDelta0X(s.amountOut,e,t),l=r-o,u=this.getRouteFeeRange(e),m=i?a.tradeFeePct:A.calculateBuyFee(o,r),b=C.mulSpot(s.amountOut,n,s.assetOutDecimals,a.assetInDecimals),d;return o===0n?d=-100:d=A.calculateDiffToRef(b,o),{type:"Buy",amountOut:s.amountOut,amountIn:a.amountIn,spotPrice:n,tradeFee:l,tradeFeePct:m,tradeFeeRange:u,priceImpactPct:d,swaps:e,toHuman(){return{type:"Buy",amountOut:P.big.toDecimal(s.amountOut,s.assetOutDecimals),amountIn:P.big.toDecimal(a.amountIn,a.assetInDecimals),spotPrice:P.big.toDecimal(n,P.RUNTIME_DECIMALS),tradeFee:P.big.toDecimal(l,a.assetInDecimals),tradeFeePct:m,tradeFeeRange:u,priceImpactPct:d,swaps:e.map(S=>S.toHuman())}}}}calculateDelta0X(t,e,s){let a=[];for(let i=e.length-1;i>=0;i--){let n=e[i],r=s.get(n.poolAddress);if(r==null)throw new Error("Pool does not exit");let o=r.parsePair(n.assetIn,n.assetOut),l;i==e.length-1?l=t:l=a[0];let u=r.calculateInGivenOut(o,l);a.unshift(u)}return a[0]}async toBuySwaps(t,e,s){let a=[];for(let i=e.length-1;i>=0;i--){let n=e[i],r=s.get(n.poolAddress);if(r==null)throw new Error("Pool does not exit");let o=r.parsePair(n.assetIn,n.assetOut),l;i==e.length-1?l=typeof t=="string"?P.big.toBigInt(t,o.decimalsOut):t:l=a[0].amountIn;let u=await this.ctx.getPoolFees(o,r),{amountIn:m,calculatedIn:b,feePct:d,errors:S}=r.validateAndBuy(o,l,u),g=this.getPoolFeeRange(u,d),p=r.spotPriceInGivenOut(o),y=C.mulSpot(l,p,o.decimalsOut,o.decimalsIn),f;b===0n?f=-100:f=A.calculateDiffToRef(y,b),a.unshift({...n,assetInDecimals:o.decimalsIn,assetOutDecimals:o.decimalsOut,amountOut:l,amountIn:m,calculatedIn:b,spotPrice:p,tradeFeePct:d,tradeFeeRange:g,priceImpactPct:f,errors:S,isSupply(){return r.type==="Aave"&&r.tokens[0].id===n.assetIn},isWithdraw(){return r.type==="Aave"&&r.tokens[1].id===n.assetIn},toHuman(){return{...n,amountOut:P.big.toDecimal(l,o.decimalsOut),amountIn:P.big.toDecimal(m,o.decimalsIn),calculatedIn:P.big.toDecimal(b,o.decimalsIn),spotPrice:P.big.toDecimal(p,P.RUNTIME_DECIMALS),tradeFeePct:d,tradeFeeRange:g,priceImpactPct:f,errors:S}}})}return a}};var x=require("@galacticcouncil/common");var ge=6e3,$t=1000000000000000n,Pt=6,Xt=-5,Yt=216e5,ol=3,he=.1,be=6;var zt=require("polkadot-api");var W=class{static build(t){return t.map(({assetIn:e,assetOut:s,pool:a,poolId:i})=>a==="Stableswap"?{pool:(0,zt.Enum)("Stableswap",i),asset_in:e,asset_out:s}:{pool:(0,zt.Enum)(a),asset_in:e,asset_out:s})}};var Rt=class{schedulerOptions;router;constructor(t,e={}){this.router=new ot(t),this.router.withFilter({exclude:["HSM"]}),this.schedulerOptions=Object.freeze({blockTime:e.blockTime??6e3,minBudgetInNative:e.minBudgetInNative??$t})}get blockTime(){return this.schedulerOptions.blockTime}get minOrderBudget(){return this.schedulerOptions.minBudgetInNative}async getDcaOrder(t,e,s,a,i){let n=await this.router.getBestSell(t,e,s),{amountIn:r,swaps:o,priceImpactPct:l}=n,u=o[0],m=o[o.length-1],{assetInDecimals:b}=u,{assetOutDecimals:d}=m,S=Math.abs(l),g=await this.getMinimumOrderBudget(t,b),p=this.getOptimalTradeCount(S),y=this.getMaximumTradeCount(r,g,a),f=i||Math.min(p,y),D=Math.round(a/f),E=r/BigInt(f),_=await this.router.getBestSell(t,e,E),Y=r<g,Q=[];Y&&Q.push("OrderTooSmall");let U=_.amountOut*BigInt(f),ye=this.toBlockPeriod(D),fe=_.tradeFee*BigInt(f),Se=W.build(o),Kt={assetIn:t,assetOut:e,errors:Q,maxTradeCount:y,tradeCount:f,tradeFee:fe,tradeImpactPct:_.priceImpactPct,tradePeriod:ye,tradeRoute:Se,type:"Dca"};return{...Kt,amountIn:r,amountOut:U,tradeAmountIn:_.amountIn,tradeAmountOut:_.amountOut,toHuman(){return{...Kt,amountIn:x.big.toDecimal(r,b),amountOut:x.big.toDecimal(U,d),tradeAmountIn:x.big.toDecimal(_.amountIn,b),tradeAmountOut:x.big.toDecimal(_.amountOut,d)}}}}async getMinimumOrderBudget(t,e){if(0===t)return this.minOrderBudget;let s=await this.router.getSpotPrice(0,t);if(s)return C.mulSpot(this.minOrderBudget,s.amount,12,e);let a=await this.router.getSpotPrice(t,0);if(a)return C.divSpot(this.minOrderBudget,a.amount,12,e);throw new Error("Unable to calculate order budget")}getMaximumTradeCount(t,e,s){let a=e*2n/10n;if(a===0n)return 0;let i=Number(t/a),n=Math.floor(s/this.blockTime),r=Math.max(0,Math.floor(n*(1-.1)));return Math.min(i,r)}getOptimalTradeCount(t){let e=Math.round(t*10)||1;return Math.max(e,3)}async getOpenBudgetDcaOrder(t,e,s,a){let i=await this.router.getBestSell(t,e,s),{swaps:n}=i,r=n[0],o=n[n.length-1],{assetInDecimals:l}=r,{assetOutDecimals:u}=o,m=await this.getMinimumOrderBudget(t,l),b=i.amountIn<m,d=[];b&&d.push("OrderTooSmall");let S=this.toBlockPeriod(a),g=W.build(n),p={assetIn:t,assetOut:e,errors:d,maxTradeCount:0,tradeCount:0,tradeFee:i.tradeFee,tradeImpactPct:i.priceImpactPct,tradePeriod:S,tradeRoute:g,type:"Dca"};return{...p,amountIn:0n,amountOut:0n,tradeAmountIn:i.amountIn,tradeAmountOut:i.amountOut,toHuman(){return{...p,amountIn:"0",amountOut:"0",tradeAmountIn:x.big.toDecimal(i.amountIn,l),tradeAmountOut:x.big.toDecimal(i.amountOut,u)}}}}async getTwapSellOrder(t,e,s){let a=await this.router.getBestSell(t,e,s),{amountIn:i,swaps:n,priceImpactPct:r}=a,o=n[0],l=n[n.length-1],{assetInDecimals:u}=o,{assetOutDecimals:m}=l,b=Math.abs(r),d=this.getTwapTradeCount(b),S=i/BigInt(d),[g,p]=await Promise.all([this.getMinimumOrderBudget(t,u),this.router.getBestSell(o.assetIn,l.assetOut,S)]),y=d===1,f=i<g,D=p.priceImpactPct<-5,E=[];f||y?E.push("OrderTooSmall"):D&&E.push("OrderImpactTooBig");let _=p.amountOut*BigInt(d),Y=p.tradeFee*BigInt(d),Q=W.build(n),U={assetIn:t,assetOut:e,errors:E,tradeCount:d,tradeImpactPct:p.priceImpactPct,tradePeriod:6,tradeRoute:Q,type:"TwapSell"};return{...U,amountIn:i,amountOut:_,tradeAmountIn:p.amountIn,tradeAmountOut:p.amountOut,tradeFee:Y,toHuman(){return{...U,amountIn:x.big.toDecimal(i,u),amountOut:x.big.toDecimal(_,m),tradeAmountIn:x.big.toDecimal(p.amountIn,u),tradeAmountOut:x.big.toDecimal(p.amountOut,m),tradeFee:x.big.toDecimal(Y,m)}}}}async getTwapBuyOrder(t,e,s){let a=await this.router.getBestBuy(t,e,s),{amountOut:i,swaps:n,priceImpactPct:r}=a,o=n[0],l=n[n.length-1],{assetInDecimals:u}=o,{assetOutDecimals:m}=l,b=Math.abs(r),d=this.getTwapTradeCount(b),S=i/BigInt(d),[g,p]=await Promise.all([this.getMinimumOrderBudget(t,u),this.router.getBestBuy(o.assetIn,l.assetOut,S)]),y=p.amountIn*BigInt(d),f=d===1,D=y<g,E=p.priceImpactPct<-5,_=[];D||f?_.push("OrderTooSmall"):E&&_.push("OrderImpactTooBig");let Y=p.tradeFee*BigInt(d),Q=W.build(n),U={assetIn:t,assetOut:e,errors:_,tradeCount:d,tradeImpactPct:p.priceImpactPct,tradePeriod:6,tradeRoute:Q,type:"TwapBuy"};return{...U,amountIn:y,amountOut:i,tradeAmountIn:p.amountIn,tradeAmountOut:p.amountOut,tradeFee:Y,toHuman(){return{...U,amountIn:x.big.toDecimal(y,u),amountOut:x.big.toDecimal(i,m),tradeAmountIn:x.big.toDecimal(p.amountIn,u),tradeAmountOut:x.big.toDecimal(p.amountOut,m),tradeFee:x.big.toDecimal(Y,u)}}}}getTwapTradeCount(t){let e=this.getOptimalTradeCount(t);if(this.getTwapExecutionTime(e)>216e5){let a=216e5/(this.blockTime*6);return Math.round(a)}return e}getTwapExecutionTime(t){return t*6*this.blockTime}toBlockPeriod(t){let e=t/this.blockTime,s=Math.round(e);return Math.max(s,6)}};0&&(module.exports={DCA_TIME_RESERVE,DEFAULT_BLOCK_TIME,DEFAULT_MIN_BUDGET,ORDER_MIN_BLOCK_PERIOD,Router,TWAP_EXECUTION_INTERVAL,TWAP_MAX_DURATION,TWAP_MAX_PRICE_IMPACT,TWAP_TX_MULTIPLIER,TradeOrderError,TradeOrderType,TradeRouteBuilder,TradeRouter,TradeScheduler,TradeType});
1
+ "use strict";var Ie=Object.create;var yt=Object.defineProperty;var we=Object.getOwnPropertyDescriptor;var Oe=Object.getOwnPropertyNames;var ve=Object.getPrototypeOf,Te=Object.prototype.hasOwnProperty;var J=(c,t)=>{for(var e in t)yt(c,e,{get:t[e],enumerable:!0})},jt=(c,t,e,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let a of Oe(t))!Te.call(c,a)&&a!==e&&yt(c,a,{get:()=>t[a],enumerable:!(s=we(t,a))||s.enumerable});return c};var Et=(c,t,e)=>(e=c!=null?Ie(ve(c)):{},jt(t||!c||!c.__esModule?yt(e,"default",{value:c,enumerable:!0}):e,c)),xe=c=>jt(yt({},"__esModule",{value:!0}),c);var us={};J(us,{DCA_TIME_RESERVE:()=>he,DEFAULT_BLOCK_TIME:()=>ge,DEFAULT_MIN_BUDGET:()=>$t,ORDER_MIN_BLOCK_PERIOD:()=>be,Router:()=>rt,TWAP_EXECUTION_INTERVAL:()=>Pt,TWAP_MAX_DURATION:()=>Yt,TWAP_MAX_PRICE_IMPACT:()=>Xt,TWAP_TX_MULTIPLIER:()=>rl,TradeOrderError:()=>Ut,TradeOrderType:()=>Wt,TradeRouteBuilder:()=>W,TradeRouter:()=>ot,TradeScheduler:()=>Rt,TradeType:()=>Vt});module.exports=xe(us);var lt=class{constructor(t=1/0){this.capacity=t}storage=[];enqueue(t){if(this.size()===this.capacity)throw Error("Queue has reached max capacity, you cannot add more items");this.storage.push(t)}dequeue(){return this.storage.shift()}size(){return this.storage.length}};var Be=10,ct=class{isNotVisited(t,e){let s=!0;return e.forEach(a=>{(a[0]===t[0]||a[1]===t[1])&&(s=!1)}),s}findPaths(t,e,s){let a=[],i=new lt,n=[];for(n.push([e,""]),i.enqueue(n);i.size()>0;){let r=i.dequeue();if(!r||r.length>Be)continue;let o=r[r.length-1];(s===null||o[0]===s)&&a.push(r),t.get(o[0])?.forEach(u=>{if(this.isNotVisited(u,r)){let m=[...r];m.push(u),i.enqueue(m)}})}return a}findShortestPaths(t,e,s){let a=[],i=new lt,n=[];n.push([e,""]),i.enqueue(n);let r=1/0;for(;i.size()>0;){let o=i.dequeue();if(!o)continue;let l=o[o.length-1];if(l[0]===s){o.length<r?(r=o.length,a.length=0,a.push(o)):o.length===r&&a.push(o);continue}let u=t.get(l[0]);for(let m of u??[])this.isNotVisited(m,o)&&i.enqueue([...o,m])}return a}buildAndPopulateGraph(t,e){let s=new Map;for(let a of t)s.set(parseInt(a),[]);for(let[a,i,n]of e)s.get(i)?.push([n,a]);return s}};function kt(c){let t={};for(let e of c){let s=e.tokens.length;for(let a=0;a<s;a++){t[e.tokens[a].id]||(t[e.tokens[a].id]=[]);for(let i=0;i<s;i++){if(a==i)continue;let n=[e.address,e.tokens[a].id,e.tokens[i].id];t[e.tokens[a].id].push(n)}}}return t}var H=require("@galacticcouncil/math-lbp"),G=class{static getSpotPrice(t,e,s,a,i){return(0,H.get_spot_price)(t,e,s,a,i)}static calculateInGivenOut(t,e,s,a,i){return(0,H.calculate_in_given_out)(t,e,s,a,i)}static calculateOutGivenIn(t,e,s,a,i){return(0,H.calculate_out_given_in)(t,e,s,a,i)}static calculateLinearWeights(t,e,s,a,i){return(0,H.calculate_linear_weights)(t,e,s,a,i)}static calculatePoolTradeFee(t,e,s){return(0,H.calculate_pool_trade_fee)(t,e,s)}};var Z=require("@galacticcouncil/common");var ft={};J(ft,{withTimeout:()=>Ae});function Ae(c,t,e="timeout"){return new Promise((s,a)=>{let i=setTimeout(()=>a(new Error(e)),t);c.then(n=>{clearTimeout(i),s(n)},n=>{clearTimeout(i),a(n)})})}var C={};J(C,{divSpot:()=>_e,getFraction:()=>Re,mulScaled:()=>Qt,mulSpot:()=>Fe});var Ct=require("@galacticcouncil/common");function Qt(c,t,e,s,a){let i=e+s-a,n=c*t;return i>0?n/BigInt(10)**BigInt(i):i<0?n*BigInt(10)**BigInt(-i):n}function Fe(c,t,e,s){return Qt(c,t,e,Ct.RUNTIME_DECIMALS,s)}function _e(c,t,e,s){if(t===0n)return 0n;let a=BigInt(10)**BigInt(Ct.RUNTIME_DECIMALS+s-e);return c*a/t}function Re(c,t,e=2){if(t<.01||t>100)throw new Error("Supported range is from 0.01% - 100%");let s=BigInt(10)**BigInt(e),a=BigInt(Math.round(t*Number(s)));return c*a/(BigInt(100)*s)}var w={};J(w,{FeeUtils:()=>Mt,shiftNeg:()=>ke});var Zt=Et(require("big.js"));var Mt=class c{static toPct(t){let[e,s]=t;return c.safeDivide(e*100,s)}static toRaw(t){let[e,s]=t;return c.safeDivide(e,s)}static fromPermill(t){return[t,1e6]}static fromPerbill(t){return[t,1e9]}static fromRate(t,e){return[t,e]}static safeDivide(t,e,s=12){let a=10**s;return Math.round(t*a/e)/a}static safeRound(t){return parseFloat(t.toPrecision(15))}};function ke(c,t){let e=(0,Zt.default)(typeof c=="bigint"?c.toString():c);return t===0?e.toString():e.div(Math.pow(10,t)).toString()}var ut={};J(ut,{findNestedKey:()=>Ce,findNestedObj:()=>Me,jsonFormatter:()=>Le});var Ce=(c,t)=>{let e=[];return JSON.stringify(c,(s,a)=>(a&&a[t]&&e.push(a),a)),e[0]},Me=(c,t,e)=>{let s;return JSON.stringify(c,(a,i)=>(i&&i[t]===e&&(s=i),i)),s},Le=(c,t)=>typeof t=="bigint"?t.toString():t;var A={};J(A,{calculateBuyFee:()=>qe,calculateDiffToAvg:()=>De,calculateDiffToRef:()=>He,calculateSellFee:()=>Ne});var N=Et(require("big.js"));function De(c,t){let e=(0,N.default)(c.toString()),s=(0,N.default)(t.toString());return e.minus(s).abs().div(e.plus(s).div(2)).mul(100).round(2).toNumber()}function He(c,t){if(t===0n)return 0;let e=(0,N.default)(c.toString()),s=(0,N.default)(t.toString());return e.minus(s).div(s).mul(100).round(2).toNumber()}function Ne(c,t){if(c===0n)return 0;let e=(0,N.default)(c.toString()),s=(0,N.default)(t.toString());return(0,N.default)(1).minus(s.div(e)).mul(100).round(2).toNumber()}function qe(c,t){if(c===0n)return 0;let e=(0,N.default)(c.toString());return(0,N.default)(t.toString()).div(e).minus(1).mul(100).round(2).toNumber()}var{FeeUtils:te}=w,St=class c{type;address;tokens;maxInRatio;maxOutRatio;minTradingLimit;fee;repayFeeApply;static fromPool(t){return new c(t)}constructor(t){this.type="LBP",this.address=t.address,this.tokens=t.tokens,this.maxInRatio=t.maxInRatio,this.maxOutRatio=t.maxOutRatio,this.minTradingLimit=t.minTradingLimit,this.fee=t.fee,this.repayFeeApply=t.repayFeeApply}validatePair(t,e){return!0}parsePair(t,e){let s=new Map(this.tokens.map(n=>[n.id,n])),a=s.get(t),i=s.get(e);if(a==null)throw new Error("Pool does not contain tokenIn");if(i==null)throw new Error("Pool does not contain tokenOut");return{assetIn:t,assetOut:e,balanceIn:a.balance,balanceOut:i.balance,decimalsIn:a.decimals,decimalsOut:i.decimals,weightIn:a.weight,weightOut:i.weight}}validateAndBuy(t,e,s){let a=this.tokens[0].id,i=[];e<this.minTradingLimit&&i.push("InsufficientTradingAmount");let n=t.balanceOut/this.maxOutRatio;if(e>n&&i.push("MaxOutRatioExceeded"),a===t.assetOut){let r=this.calculateTradeFee(e,s),o=te.toPct(this.repayFeeApply?s.repayFee:s.exchangeFee),l=e+r,u=this.calculateInGivenOut(t,l),m=t.balanceIn/this.maxInRatio;return u>m&&i.push("MaxInRatioExceeded"),{amountIn:u,calculatedIn:u,amountOut:e,feePct:o,errors:i}}else{let r=this.calculateInGivenOut(t,e),o=t.balanceIn/this.maxInRatio;return r>o&&i.push("MaxInRatioExceeded"),{amountIn:r,calculatedIn:r,amountOut:e,feePct:0,errors:i}}}validateAndSell(t,e,s){let a=this.tokens[0].id,i=[];e<this.minTradingLimit&&i.push("InsufficientTradingAmount");let n=t.balanceIn/this.maxInRatio;if(e>n&&i.push("MaxInRatioExceeded"),a===t.assetIn){let r=this.calculateOutGivenIn(t,e),o=t.balanceOut/this.maxOutRatio;return r>o&&i.push("MaxOutRatioExceeded"),{amountIn:e,calculatedOut:r,amountOut:r,feePct:0,errors:i}}else{let r=this.calculateOutGivenIn(t,e),o=this.calculateTradeFee(r,s),l=te.toPct(this.repayFeeApply?s.repayFee:s.exchangeFee),u=r-o,m=t.balanceOut/this.maxOutRatio;return u>m&&i.push("MaxOutRatioExceeded"),{amountIn:e,calculatedOut:r,amountOut:u,feePct:l,errors:i}}}calculateInGivenOut(t,e){let s=G.calculateInGivenOut(t.balanceIn.toString(),t.balanceOut.toString(),t.weightIn.toString(),t.weightOut.toString(),e.toString()),a=BigInt(s);return a<0n?0n:a}calculateOutGivenIn(t,e){let s=G.calculateOutGivenIn(t.balanceIn.toString(),t.balanceOut.toString(),t.weightIn.toString(),t.weightOut.toString(),e.toString()),a=BigInt(s);return a<0n?0n:a}spotPriceInGivenOut(t){let e=G.getSpotPrice(t.balanceOut.toString(),t.balanceIn.toString(),t.weightOut.toString(),t.weightIn.toString(),Z.big.toBigInt(1,Z.RUNTIME_DECIMALS).toString());return BigInt(e)}spotPriceOutGivenIn(t){let e=G.getSpotPrice(t.balanceIn.toString(),t.balanceOut.toString(),t.weightIn.toString(),t.weightOut.toString(),Z.big.toBigInt(1,Z.RUNTIME_DECIMALS).toString());return BigInt(e)}calculateTradeFee(t,e){let s=G.calculatePoolTradeFee(t.toString(),this.repayFeeApply?e.repayFee[0]:e.exchangeFee[0],this.repayFeeApply?e.repayFee[1]:e.exchangeFee[1]);return BigInt(s)}};var Xe=require("polkadot-api"),vt=require("rxjs");var V=require("rxjs"),R=require("rxjs/operators");var se=require("@galacticcouncil/descriptors");var ee=require("@galacticcouncil/common"),Lt=require("rxjs");var It=require("rxjs"),$=require("rxjs/operators");var{logger:qs}=ee.log;var Ge=require("polkadot-api/ws"),Ve=require("polkadot-api/logs-provider");var We=require("polkadot-api");var ae=require("@galacticcouncil/common"),Ot=require("rxjs"),M=require("rxjs/operators");var{logger:na}=ae.log;var $e=require("rxjs");var ie=require("@galacticcouncil/common");var ya={Aave:"AAVE",LBP:"LBP",Omnipool:"OMNI",Stableswap:"STBL",XYK:"XYK",HSM:"HSM"},{logger:fa}=ie.log;var{withTimeout:Ma}=ft;var h=require("@galacticcouncil/math-omnipool"),z=Et(require("big.js")),I=class{static calculateSpotPrice(t,e,s,a){return(0,h.calculate_spot_price)(t,e,s,a)}static calculateLrnaSpotPrice(t,e){return(0,h.calculate_lrna_spot_price)(t,e)}static calculateInGivenOut(t,e,s,a,i,n,r,o,l,u){return(0,h.calculate_in_given_out)(t,e,s,a,i,n,r,o,l,u)}static calculateLrnaInGivenOut(t,e,s,a,i,n){return(0,h.calculate_lrna_in_given_out)(t,e,s,a,i,n)}static calculateOutGivenIn(t,e,s,a,i,n,r,o,l,u){return(0,h.calculate_out_given_in)(t,e,s,a,i,n,r,o,l,u)}static calculateOutGivenLrnaIn(t,e,s,a,i,n){return(0,h.calculate_out_given_lrna_in)(t,e,s,a,i,n)}static calculateShares(t,e,s,a){return(0,h.calculate_shares)(t,e,s,a)}static calculateLiquidityOut(t,e,s,a,i,n,r,o){return(0,h.calculate_liquidity_out)(t,e,s,a,i,n,r,o)}static calculateLiquidityLRNAOut(t,e,s,a,i,n,r,o){return(0,h.calculate_liquidity_lrna_out)(t,e,s,a,i,n,r,o)}static calculateCapDifference(t,e,s,a){let i=(0,z.default)(e),n=(0,z.default)(t),r=(0,z.default)(a),o=(0,z.default)(s),l=(0,z.default)(10).pow(18),u=o.div(l);if(i.div(r).lt(u)){let b=u.times(r).minus(i).times(n),d=i.times((0,z.default)(1).minus(u));return b.div(d).toFixed(0)}else return"0"}static calculateLimitHubIn(t,e,s,a){return(0,h.calculate_liquidity_hub_in)(t,e,s,a)}static isSellAllowed(t){return(0,h.is_sell_allowed)(t)}static isBuyAllowed(t){return(0,h.is_buy_allowed)(t)}static isAddLiquidityAllowed(t){return(0,h.is_add_liquidity_allowed)(t)}static isRemoveLiquidityAllowed(t){return(0,h.is_remove_liquidity_allowed)(t)}static recalculateAssetFee(t,e,s,a,i,n,r,o,l,u,m){return(0,h.recalculate_asset_fee)(t,e,s,a,i,n,r,o,l,u,m)}static recalculateProtocolFee(t,e,s,a,i,n,r,o,l,u,m){return(0,h.recalculate_protocol_fee)(t,e,s,a,i,n,r,o,l,u,m)}static verifyAssetCap(t,e,s,a){return(0,h.verify_asset_cap)(t,e,s,a)}};var ne=require("@galacticcouncil/common");var{FeeUtils:q}=w,Tt=class c{type;address;tokens;maxInRatio;maxOutRatio;minTradingLimit;hubAssetId;static fromPool(t){return new c(t)}constructor(t){this.type="Omnipool",this.address=t.address,this.tokens=t.tokens,this.maxInRatio=t.maxInRatio,this.maxOutRatio=t.maxOutRatio,this.minTradingLimit=t.minTradingLimit,this.hubAssetId=t.hubAssetId}validatePair(t,e){return this.hubAssetId!=e}parsePair(t,e){let s=new Map(this.tokens.map(n=>[n.id,n])),a=s.get(t),i=s.get(e);if(a==null)throw new Error("Pool does not contain tokenIn");if(i==null)throw new Error("Pool does not contain tokenOut");return{assetIn:t,assetOut:e,hubReservesIn:a.hubReserves,hubReservesOut:i.hubReserves,sharesIn:a.shares,sharesOut:i.shares,decimalsIn:a.decimals,decimalsOut:i.decimals,balanceIn:a.balance,balanceOut:i.balance,tradeableIn:a.tradeable,tradeableOut:i.tradeable,assetInEd:a.existentialDeposit,assetOutEd:i.existentialDeposit}}validateAndBuy(t,e,s){let a=this.calculateInGivenOut(t,e),i=this.calculateInGivenOut(t,e,s),n=a===0n?0:A.calculateBuyFee(a,i),r=[],o=I.isSellAllowed(t.tradeableIn),l=I.isBuyAllowed(t.tradeableOut);(!o||!l)&&r.push("TradeNotAllowed"),(e<this.minTradingLimit||a<t.assetInEd)&&r.push("InsufficientTradingAmount");let u=t.balanceOut/this.maxOutRatio;e>u&&r.push("MaxOutRatioExceeded");let m=t.balanceIn/this.maxInRatio;return i>m&&r.push("MaxInRatioExceeded"),{amountIn:i,calculatedIn:a,amountOut:e,feePct:n,errors:r}}validateAndSell(t,e,s){let a=this.calculateOutGivenIn(t,e),i=this.calculateOutGivenIn(t,e,s),n=A.calculateSellFee(a,i),r=[],o=I.isSellAllowed(t.tradeableIn),l=I.isBuyAllowed(t.tradeableOut);(!o||!l)&&r.push("TradeNotAllowed"),(e<this.minTradingLimit||a<t.assetOutEd)&&r.push("InsufficientTradingAmount");let u=t.balanceIn/this.maxInRatio;e>u&&r.push("MaxInRatioExceeded");let m=t.balanceOut/this.maxOutRatio;return i>m&&r.push("MaxOutRatioExceeded"),{amountIn:e,calculatedOut:a,amountOut:i,feePct:n,errors:r}}calculateInGivenOut(t,e,s){if(t.assetIn==this.hubAssetId)return this.calculateLrnaInGivenOut(t,e,s);let a=I.calculateInGivenOut(t.balanceIn.toString(),t.hubReservesIn.toString(),t.sharesIn.toString(),t.balanceOut.toString(),t.hubReservesOut.toString(),t.sharesOut.toString(),e.toString(),s?q.toRaw(s.assetFee).toString():"0",s?q.toRaw(s.protocolFee).toString():"0",s?q.toRaw(s.maxSlipFee).toString():"0"),i=BigInt(a);return i<0n?0n:i}calculateLrnaInGivenOut(t,e,s){let a=I.calculateLrnaInGivenOut(t.balanceOut.toString(),t.hubReservesOut.toString(),t.sharesOut.toString(),e.toString(),s?q.toRaw(s.assetFee).toString():"0",s?q.toRaw(s.maxSlipFee).toString():"0"),i=BigInt(a);return i<0n?0n:i}calculateOutGivenIn(t,e,s){if(t.assetIn==this.hubAssetId)return this.calculateOutGivenLrnaIn(t,e,s);let a=I.calculateOutGivenIn(t.balanceIn.toString(),t.hubReservesIn.toString(),t.sharesIn.toString(),t.balanceOut.toString(),t.hubReservesOut.toString(),t.sharesOut.toString(),e.toString(),s?q.toRaw(s.assetFee).toString():"0",s?q.toRaw(s.protocolFee).toString():"0",s?q.toRaw(s.maxSlipFee).toString():"0"),i=BigInt(a);return i<0n?0n:i}calculateOutGivenLrnaIn(t,e,s){let a=I.calculateOutGivenLrnaIn(t.balanceOut.toString(),t.hubReservesOut.toString(),t.sharesOut.toString(),e.toString(),s?q.toRaw(s.assetFee).toString():"0",s?q.toRaw(s.maxSlipFee).toString():"0"),i=BigInt(a);return i<0n?0n:i}spotPriceInGivenOut(t){if(t.assetIn==this.hubAssetId)return this.spotPriceLrnaInGivenOut(t);let e=I.calculateSpotPrice(t.balanceOut.toString(),t.hubReservesOut.toString(),t.balanceIn.toString(),t.hubReservesIn.toString());return this.normalizeSpot(BigInt(e),t.decimalsOut,t.decimalsIn)}spotPriceLrnaInGivenOut(t){let e=I.calculateLrnaSpotPrice(t.hubReservesOut.toString(),t.balanceOut.toString());return this.normalizeSpot(BigInt(e),t.decimalsOut,t.decimalsIn)}spotPriceOutGivenIn(t){if(t.assetIn==this.hubAssetId)return this.spotPriceOutGivenLrnaIn(t);let e=I.calculateSpotPrice(t.balanceIn.toString(),t.hubReservesIn.toString(),t.balanceOut.toString(),t.hubReservesOut.toString());return this.normalizeSpot(BigInt(e),t.decimalsIn,t.decimalsOut)}spotPriceOutGivenLrnaIn(t){let e=I.calculateLrnaSpotPrice(t.balanceOut.toString(),t.hubReservesOut.toString());return this.normalizeSpot(BigInt(e),t.decimalsIn,t.decimalsOut)}normalizeSpot(t,e,s){let a=e-s;if(a===0)return t;let i=ne.big.pow10(Math.abs(a));return a>0?t*i:t/i}};var K=require("polkadot-api"),ze=require("@polkadot-api/utils"),j=require("rxjs"),Ke=require("@galacticcouncil/common");var{FeeUtils:yi}=w,fi=K.Binary.toHex(K.Binary.fromText("omnipool")),Si=(0,K.Enum)("Short");var O=require("@galacticcouncil/math-stableswap"),k=class{static getPoolAddress(t){return(0,O.pool_account_name)(t)}static defaultPegs(t){let e=[];for(let s=0;s<t;s++)e.push(["1","1"]);return e}static calculateAmplification(t,e,s,a,i){return(0,O.calculate_amplification)(t,e,s,a,i)}static calculateInGivenOut(t,e,s,a,i,n,r){return(0,O.calculate_in_given_out)(t,e,s,a,i,n,r)}static calculateAddOneAsset(t,e,s,a,i,n,r){return(0,O.calculate_add_one_asset)(t,e,s,a,i,n,r)}static calculateSharesForAmount(t,e,s,a,i,n,r){return(0,O.calculate_shares_for_amount)(t,e,s,a,i,n,r)}static calculateOutGivenIn(t,e,s,a,i,n,r){return(0,O.calculate_out_given_in)(t,e,s,a,i,n,r)}static calculateLiquidityOutOneAsset(t,e,s,a,i,n,r){return(0,O.calculate_liquidity_out_one_asset)(t,e,s,a,i,n,r)}static calculateShares(t,e,s,a,i,n){return(0,O.calculate_shares)(t,e,s,a,i,n)}static calculateSpotPriceWithFee(t,e,s,a,i,n,r,o){return(0,O.calculate_spot_price_with_fee)(t,e,s,a,i,n,r,o)}static recalculatePegs(t,e,s,a,i,n){let r=(0,O.recalculate_peg)(t,e,s,a,i,n);return JSON.parse(r)}};var dt=require("@galacticcouncil/common");var{FeeUtils:et}=w,st=class c{type;address;tokens;maxInRatio;maxOutRatio;minTradingLimit;amplification;isRampPeriod;id;fee;totalIssuance;pegs;static fromPool(t){return new c(t)}constructor(t){this.type="Stableswap",this.address=t.address,this.tokens=t.tokens,this.maxInRatio=t.maxInRatio,this.maxOutRatio=t.maxOutRatio,this.minTradingLimit=t.minTradingLimit,this.amplification=t.amplification,this.isRampPeriod=t.isRampPeriod,this.id=t.id,this.fee=t.fee,this.totalIssuance=t.totalIssuance,this.pegs=t.pegs}validatePair(t,e){return!0}parsePair(t,e){let s=new Map(this.tokens.map(n=>[n.id,n])),a=s.get(t),i=s.get(e);if(a==null)throw new Error("Pool does not contain tokenIn");if(i==null)throw new Error("Pool does not contain tokenOut");return{assetIn:t,assetOut:e,balanceIn:a.balance,balanceOut:i.balance,decimalsIn:a.decimals,decimalsOut:i.decimals,tradeableIn:this.id===t?15:a.tradeable,tradeableOut:this.id===e?15:i.tradeable,assetInEd:a.existentialDeposit,assetOutEd:i.existentialDeposit}}validateAndBuy(t,e,s){let a=this.calculateInGivenOut(t,e),i=this.calculateInGivenOut(t,e,s),n=a===0n?0:A.calculateBuyFee(a,i),r=[],o=I.isSellAllowed(t.tradeableIn),l=I.isBuyAllowed(t.tradeableOut);return(!o||!l)&&r.push("TradeNotAllowed"),(e<this.minTradingLimit||a<t.assetInEd)&&r.push("InsufficientTradingAmount"),{amountIn:i,calculatedIn:a,amountOut:e,feePct:n,errors:r}}validateAndSell(t,e,s){let a=this.calculateOutGivenIn(t,e),i=this.calculateOutGivenIn(t,e,s),n=A.calculateSellFee(a,i),r=[],o=I.isSellAllowed(t.tradeableIn),l=I.isBuyAllowed(t.tradeableOut);return(!o||!l)&&r.push("TradeNotAllowed"),(e<this.minTradingLimit||a<t.assetOutEd)&&r.push("InsufficientTradingAmount"),{amountIn:e,calculatedOut:a,amountOut:i,feePct:n,errors:r}}calculateIn(t,e,s){let a=k.calculateInGivenOut(this.getReserves(),Number(t.assetIn),Number(t.assetOut),e.toString(),this.amplification.toString(),s?et.toRaw(s.fee).toString():"0",this.getPegs()),i=BigInt(a);return i<0n?0n:i}calculateAddOneAsset(t,e,s){let a=k.calculateAddOneAsset(this.getReserves(),e.toString(),Number(t.assetIn),this.amplification.toString(),this.totalIssuance.toString(),s?et.toRaw(s.fee).toString():"0",this.getPegs()),i=BigInt(a);return i<0n?0n:i}calculateSharesForAmount(t,e,s){let a=k.calculateSharesForAmount(this.getReserves(),Number(t.assetOut),e.toString(),this.amplification.toString(),this.totalIssuance.toString(),s?et.toRaw(s.fee).toString():"0",this.getPegs()),i=BigInt(a);return i<0n?0n:i}calculateInGivenOut(t,e,s){return t.assetOut==this.id?this.calculateAddOneAsset(t,e,s):t.assetIn==this.id?this.calculateSharesForAmount(t,e,s):this.calculateIn(t,e,s)}spotPriceInGivenOut(t){let e=k.calculateSpotPriceWithFee(this.id.toString(),this.getReserves(),this.amplification.toString(),t.assetOut.toString(),t.assetIn.toString(),this.totalIssuance.toString(),"0",this.getPegs());return this.normalizeSpot(BigInt(e),t.assetOut===this.id,t.assetIn===this.id,t.decimalsOut,t.decimalsIn)}calculateOut(t,e,s){let a=k.calculateOutGivenIn(this.getReserves(),Number(t.assetIn),Number(t.assetOut),e.toString(),this.amplification.toString(),s?et.toRaw(s.fee).toString():"0",this.getPegs()),i=BigInt(a);return i<0n?0n:i}calculateWithdrawOneAsset(t,e,s){let a=k.calculateLiquidityOutOneAsset(this.getReserves(),e.toString(),Number(t.assetOut),this.amplification.toString(),this.totalIssuance.toString(),s?et.toRaw(s.fee).toString():"0",this.getPegs()),i=BigInt(a);return i<0n?0n:i}calculateShares(t,e,s){let a=k.calculateShares(this.getReserves(),this.getAssets(t.assetIn,e),this.amplification.toString(),this.totalIssuance.toString(),s?et.toRaw(s.fee).toString():"0",this.getPegs()),i=BigInt(a);return i<0n?0n:i}calculateOutGivenIn(t,e,s){return t.assetIn==this.id?this.calculateWithdrawOneAsset(t,e,s):t.assetOut==this.id?this.calculateShares(t,e,s):this.calculateOut(t,e,s)}spotPriceOutGivenIn(t){let e=k.calculateSpotPriceWithFee(this.id.toString(),this.getReserves(),this.amplification.toString(),t.assetIn.toString(),t.assetOut.toString(),this.totalIssuance.toString(),"0",this.getPegs());return this.normalizeSpot(BigInt(e),t.assetIn===this.id,t.assetOut===this.id,t.decimalsIn,t.decimalsOut)}getPegs(){return JSON.stringify(this.pegs)}getReserves(){let t=this.tokens.filter(e=>e.id!=this.id).map(({id:e,balance:s,decimals:a})=>({asset_id:e,amount:s,decimals:a}));return JSON.stringify(t,ut.jsonFormatter)}getAssets(t,e){let s={asset_id:Number(t),amount:e.toString()};return JSON.stringify([s],ut.jsonFormatter)}normalizeSpot(t,e,s,a,i){return e?t*dt.big.pow10(dt.RUNTIME_DECIMALS-i):s?t/dt.big.pow10(i-a):t}};var re=require("polkadot-api"),Qe=require("@polkadot-api/utils"),Je=require("@noble/hashes/blake2b"),gt=require("rxjs"),oe=require("@galacticcouncil/common");var{FeeUtils:Qi}=w;var v=require("@galacticcouncil/math-xyk"),X=class{static getSpotPrice(t,e,s){return(0,v.get_spot_price)(t,e,s)}static calculateInGivenOut(t,e,s){return(0,v.calculate_in_given_out)(t,e,s)}static calculateOutGivenIn(t,e,s){return(0,v.calculate_out_given_in)(t,e,s)}static calculatePoolTradeFee(t,e,s){return(0,v.calculate_pool_trade_fee)(t,e,s)}static calculateLiquidityIn(t,e,s){return(0,v.calculate_liquidity_in)(t,e,s)}static calculateSpotPrice(t,e){return(0,v.calculate_spot_price)(t,e)}static calculateSpotPriceWithFee(t,e,s,a){return(0,v.calculate_spot_price_with_fee)(t,e,s,a)}static calculateShares(t,e,s){return(0,v.calculate_shares)(t,e,s)}static calculateLiquidityOutAssetA(t,e,s,a){return(0,v.calculate_liquidity_out_asset_a)(t,e,s,a)}static calculateLiquidityOutAssetB(t,e,s,a){return(0,v.calculate_liquidity_out_asset_b)(t,e,s,a)}};var ce=require("@galacticcouncil/common");var{FeeUtils:le}=w,xt=class c{type;address;tokens;maxInRatio;maxOutRatio;minTradingLimit;static fromPool(t){return new c(t)}constructor(t){this.type="XYK",this.address=t.address,this.tokens=t.tokens,this.maxInRatio=t.maxInRatio,this.maxOutRatio=t.maxOutRatio,this.minTradingLimit=t.minTradingLimit}validatePair(t,e){return!0}parsePair(t,e){let s=new Map(this.tokens.map(n=>[n.id,n])),a=s.get(t),i=s.get(e);if(a==null)throw new Error("Pool does not contain tokenIn");if(i==null)throw new Error("Pool does not contain tokenOut");return{assetIn:t,assetOut:e,decimalsIn:a.decimals,decimalsOut:i.decimals,balanceIn:a.balance,balanceOut:i.balance,assetInEd:a.existentialDeposit,assetOutEd:i.existentialDeposit}}validateAndBuy(t,e,s){let a=this.calculateInGivenOut(t,e),i=this.calculateTradeFee(a,s),n=le.toPct(s.exchangeFee),r=a+i,o=[];(e<this.minTradingLimit||a<t.assetInEd)&&o.push("InsufficientTradingAmount");let l=t.balanceOut/this.maxOutRatio;e>l&&o.push("MaxOutRatioExceeded");let u=t.balanceIn/this.maxInRatio;return r>u&&o.push("MaxInRatioExceeded"),{amountIn:r,calculatedIn:a,amountOut:e,feePct:n,errors:o}}validateAndSell(t,e,s){let a=this.calculateOutGivenIn(t,e),i=this.calculateTradeFee(a,s),n=le.toPct(s.exchangeFee),r=a-i,o=[];(e<this.minTradingLimit||a<t.assetOutEd)&&o.push("InsufficientTradingAmount");let l=t.balanceIn/this.maxInRatio;e>l&&o.push("MaxInRatioExceeded");let u=t.balanceOut/this.maxOutRatio;return r>u&&o.push("MaxOutRatioExceeded"),{amountIn:e,calculatedOut:a,amountOut:r,feePct:n,errors:o}}calculateInGivenOut(t,e){let s=X.calculateInGivenOut(t.balanceIn.toString(),t.balanceOut.toString(),e.toString()),a=BigInt(s);return a<0n?0n:a}calculateOutGivenIn(t,e){let s=X.calculateOutGivenIn(t.balanceIn.toString(),t.balanceOut.toString(),e.toString()),a=BigInt(s);return a<0n?0n:a}spotPriceInGivenOut(t){let e=X.calculateSpotPrice(t.balanceOut.toString(),t.balanceIn.toString());return this.normalizeSpot(BigInt(e),t.decimalsOut,t.decimalsIn)}spotPriceOutGivenIn(t){let e=X.calculateSpotPrice(t.balanceIn.toString(),t.balanceOut.toString());return this.normalizeSpot(BigInt(e),t.decimalsIn,t.decimalsOut)}calculateTradeFee(t,e){let s=X.calculatePoolTradeFee(t.toString(),e.exchangeFee[0],e.exchangeFee[1]);return BigInt(s)}normalizeSpot(t,e,s){let a=e-s;if(a===0)return t;let i=ce.big.pow10(Math.abs(a));return a>0?t*i:t/i}};var ts=require("polkadot-api"),es=require("rxjs");var at=require("@galacticcouncil/common");var Bt=class c{type;address;tokens;maxInRatio;maxOutRatio;minTradingLimit;static fromPool(t){return new c(t)}constructor(t){this.type="Aave",this.address=t.address,this.tokens=t.tokens,this.maxInRatio=t.maxInRatio,this.maxOutRatio=t.maxOutRatio,this.minTradingLimit=t.minTradingLimit}validatePair(t,e){return!0}parsePair(t,e){let s=new Map(this.tokens.map(n=>[n.id,n])),a=s.get(t),i=s.get(e);if(a==null)throw new Error("Pool does not contain tokenIn");if(i==null)throw new Error("Pool does not contain tokenOut");return{assetIn:t,assetOut:e,balanceIn:a.balance,balanceOut:i.balance,decimalsIn:a.decimals,decimalsOut:i.decimals,assetInEd:0n,assetOutEd:0n}}validateAndBuy(t,e,s){let a=this.calculateInGivenOut(t,e),i=[];return e>t.balanceOut&&i.push("TradeNotAllowed"),{amountIn:a,calculatedIn:a,amountOut:e,feePct:0,errors:i}}validateAndSell(t,e,s){let a=this.calculateOutGivenIn(t,e),i=[];return a>t.balanceOut&&i.push("TradeNotAllowed"),{amountIn:e,calculatedOut:a,amountOut:a,feePct:0,errors:i}}calculateInGivenOut(t,e){return e}calculateOutGivenIn(t,e){return e}spotPriceInGivenOut(t){return at.big.toBigInt(1,at.RUNTIME_DECIMALS)}spotPriceOutGivenIn(t){return at.big.toBigInt(1,at.RUNTIME_DECIMALS)}calculateTradeFee(t,e){return 0n}};var ue=require("polkadot-api"),as=require("@polkadot-api/utils"),At=require("rxjs"),is=require("viem"),Ht=require("@galacticcouncil/common");var{ERC20:Xn}=Ht.erc20;var B=require("@galacticcouncil/math-hsm"),L=class{static calculateCollateralInGivenHollarOut(t,e,s){return(0,B.calculate_collateral_in_given_hollar_out)(t,e,s)}static calculateCollateralOutGivenHollarIn(t,e,s){return(0,B.calculate_collateral_out_given_hollar_in)(t,e,s)}static calculateHollarOutGivenCollateralIn(t,e,s){return(0,B.calculate_hollar_out_given_collateral_in)(t,e,s)}static calculateHollarInGivenCollateralOut(t,e,s){return(0,B.calculate_hollar_in_given_collateral_out)(t,e,s)}static calculateImbalance(t,e,s){return(0,B.calculate_imbalance)(t,e,s)}static calculateBuybackLimit(t,e){return(0,B.calculate_buyback_limit)(t,e)}static calculateBuybackPriceWithFee(t,e,s){return(0,B.calculate_buyback_price_with_fee)(t,e,s)}static calculateMaxPrice(t,e){return(0,B.calculate_max_price)(t,e)}};var F=require("@galacticcouncil/common");var{FeeUtils:it}=w,Ft=class c extends st{hsmAddress;hsmMintCapacity;hollarId;hollarH160;collateralId;collateralBalance;maxBuyPriceCoefficient;maxInHolding;purchaseFee;buyBackFee;buyBackRate;static fromPool(t){return new c(t)}constructor(t){super(t),this.type="HSM",this.hsmAddress=t.hsmAddress,this.hsmMintCapacity=t.hsmMintCapacity,this.hollarId=t.hollarId,this.hollarH160=t.hollarH160,this.collateralId=t.collateralId,this.collateralBalance=t.collateralBalance,this.maxBuyPriceCoefficient=t.maxBuyPriceCoefficient,this.maxInHolding=t.maxInHolding,this.purchaseFee=t.purchaseFee,this.buyBackFee=t.buyBackFee,this.buyBackRate=t.buyBackRate}validatePair(t,e){return!0}parsePair(t,e){return super.parsePair(t,e)}validateTradeHollarIn(t,e,s){let a=this.parsePair(t.assetOut,t.assetIn),i=super.calculateInGivenOut(a,e,{fee:this.fee}),n=this.calculateBuybackLimit(t);e>n&&s.push("MaxBuyBackExceeded");let r=this.calculateMaxPrice(t);return this.calculateBuyPrice(t,e,i)>r&&s.push("MaxBuyPriceExceeded"),i>this.collateralBalance&&s.push("InsufficientCollateral"),s}validateTradeHollarOut(t,e,s){return this.collateralBalance+t>this.maxInHolding&&s.push("MaxHoldingExceeded"),e>this.hsmMintCapacity&&s.push("FacilitatorCapacityExceeded"),s}validateTradeConstraints(t,e,s){let a=[];return t.assetIn===this.hollarId?this.validateTradeHollarIn(t,e,a):this.validateTradeHollarOut(e,s,a)}validateAndBuy(t,e){let s=this.calculateInGivenOut(t,e),a=this.validateTradeConstraints(t,s,e);return{amountIn:s,calculatedIn:s,amountOut:e,feePct:0,errors:a}}validateAndSell(t,e){let s=this.calculateOutGivenIn(t,e),a=this.validateTradeConstraints(t,e,s);return{amountIn:e,calculatedOut:s,amountOut:s,feePct:0,errors:a}}calculateHollarInGivenCollateralOut(t,e){let s=super.calculateInGivenOut(t,e,{fee:this.fee}),a=L.calculateHollarInGivenCollateralOut(e.toString(),s.toString(),it.toRaw(this.buyBackFee).toString());return BigInt(a)}calculateCollateralInGivenHollarOut(t){let e=this.getCollateralPeg(),s=L.calculateCollateralInGivenHollarOut(t.toString(),JSON.stringify(e),it.toRaw(this.purchaseFee).toString());return BigInt(s)}calculateInGivenOut(t,e){return t.assetOut==this.hollarId?this.calculateCollateralInGivenHollarOut(e):this.calculateHollarInGivenCollateralOut(t,e)}calculateCollateralOutGivenHollarIn(t,e){let s=super.calculateOutGivenIn(t,e,{fee:this.fee}),a=L.calculateCollateralOutGivenHollarIn(e.toString(),s.toString(),it.toRaw(this.buyBackFee).toString());return BigInt(a)}calculateHollarOutGivenCollateralIn(t){let e=this.getCollateralPeg(),s=L.calculateHollarOutGivenCollateralIn(t.toString(),JSON.stringify(e),it.toRaw(this.purchaseFee).toString());return BigInt(s)}calculateOutGivenIn(t,e){return t.assetIn==this.hollarId?this.calculateCollateralOutGivenHollarIn(t,e):this.calculateHollarOutGivenCollateralIn(e)}calculateImbalance(t){let e=this.getCollateralPeg(),s=L.calculateImbalance(t.balanceIn.toString(),JSON.stringify(e),t.balanceOut.toString());return BigInt(s)}calculateBuybackLimit(t){let e=this.calculateImbalance(t),s=L.calculateBuybackLimit(e.toString(),it.toRaw(this.buyBackRate).toString());return BigInt(s)}calculateBuyPrice(t,e,s){let a=L.calculateBuybackPriceWithFee(s.toString(),e.toString(),it.toRaw(this.buyBackFee).toString()),[i,n]=JSON.parse(a),r=F.big.pow10(t.decimalsIn+F.RUNTIME_DECIMALS-t.decimalsOut);return BigInt(i)*r/BigInt(n)}calculateMaxPrice(t){let e=this.getCollateralPeg(),s=L.calculateMaxPrice(JSON.stringify(e),this.maxBuyPriceCoefficient.toString()),[a,i]=JSON.parse(s),n=F.big.pow10(F.RUNTIME_DECIMALS-t.decimalsOut);return BigInt(a)*n/BigInt(i)}spotPriceInGivenOut(t){let e=F.big.toBigInt(1,t.decimalsOut),a=this.calculateInGivenOut(t,e)*F.big.pow10(F.RUNTIME_DECIMALS-t.decimalsOut);return this.normalizeSpotPrice(a,t.decimalsOut,t.decimalsIn)}spotPriceOutGivenIn(t){let e=F.big.toBigInt(1,t.decimalsIn),a=this.calculateOutGivenIn(t,e)*F.big.pow10(F.RUNTIME_DECIMALS-t.decimalsIn);return this.normalizeSpotPrice(a,t.decimalsIn,t.decimalsOut)}getCollateralPeg(){let t=this.tokens.findIndex(a=>a.id!==this.hollarId),e=this.pegs[t],s=this.tokens[t].decimals;return this.isDefaultPeg(e)?[F.big.toBigInt(1,18).toString(),F.big.toBigInt(1,s).toString()]:e}isDefaultPeg(t){let[e,s]=t;return Array.isArray(t)&&t.length===2&&e==="1"&&s==="1"}normalizeSpotPrice(t,e,s){let a=e-s;if(a===0)return t;let i=F.big.pow10(Math.abs(a));return a>0?t*i:t/i}};var Nt=require("polkadot-api"),os=require("@polkadot-api/utils"),nt=require("rxjs"),ls=require("viem"),qt=require("@galacticcouncil/common");var{FeeUtils:wr}=w,{H160:Or}=qt.h160;var ht=class{static get(t){switch(t.type){case"Aave":return Bt.fromPool(t);case"XYK":return xt.fromPool(t);case"Omnipool":return Tt.fromPool(t);case"LBP":return St.fromPool(t);case"Stableswap":return st.fromPool(t);case"HSM":return Ft.fromPool(t);default:throw new Error("Pool type "+t.type+" is not supported yet")}}};var me=require("@galacticcouncil/common"),Gt=require("rxjs");var _t=class extends Error{constructor(t,e){super(),this.message=`Route from ${t} to ${e} not found in current configuration`,this.name="RouteNotFound"}};var{logger:po}=me.log;var bt=class{getProposals(t,e,s){let a=s.filter(p=>p.type==="XYK"),i=s.filter(p=>p.type!=="XYK"),n=new Set(i.map(p=>p.tokens).flat().map(p=>p.id)),r=n.has(t),o=n.has(e),l=new ct,u=p=>{let y=kt(p),f=Object.keys(y),D=f.flatMap(E=>y[E]);return l.buildAndPopulateGraph(f,D)};if(!r&&!o){let p=a.filter(D=>D.tokens.find(E=>E.id===t)||D.tokens.find(E=>E.id===e)),y=u(p),f=l.findPaths(y,t,e);return this.parsePaths(f)}if(r&&o){let p=u(i),y=l.findPaths(p,t,e);return this.parsePaths(y)}let m=r?e:t,b=a.filter(p=>p.tokens.some(y=>y.id===m));if(b.length===0)return[];let d=[...i,...b],S=u(d),g=l.findPaths(S,t,e);return this.parsePaths(g)}parsePaths(t){let e=[];for(let s of t){let a=[];for(let i=0;i<s.length;i++){let n=s[i],r=s[i+1];if(r==null)break;a.push(this.toEdge(n,r))}e.push(a)}return e}toEdge(t,e){return[e[1],t[0],e[0]]}};var rt=class{routeSuggester;routeProposals;ctx;filter={};constructor(t){this.ctx=t,this.routeSuggester=new bt,this.routeProposals=new Map}async withFilter(t){this.filter=t||{},this.routeProposals.clear(),this.onFilterChanged()}onFilterChanged(){}buildRouteKey(t,e,s){return`${t}->${e}::${s.length}`}applyPoolFilter(t){let{useOnly:e=[],exclude:s=[]}=this.filter,a=new Set(e),i=new Set(s);return t.filter(n=>i.has(n.type)?!1:a.size>0?a.has(n.type):!0)}async getPools(){let t=await this.ctx.getPools();return this.applyPoolFilter(t)}async getRoutes(t,e){let s=await this.getPools();return this.validateInput(t,e,s),this.getPaths(t,e,s)}async getTradeableAssets(){let t=await this.getPools(),e=this.getAssets(t);return Array.from(e)}async getRouteableAssets(t){let e=await this.getTradeableAssets();return(await Promise.all(e.filter(a=>a!==t).map(a=>this.getRoutes(a,t)))).filter(a=>a.length>0).map(([a])=>a[0].assetIn).sort()}validateInput(t,e,s){if(s.length===0)throw new Error("No pools configured");if(t===e)throw new Error("Trading pair can't be identical");let a=this.getAssets(s);if(!a.has(t))throw new Error(t+" is not supported asset");if(!a.has(e))throw new Error(e+" is not supported asset");return this.toPoolsMap(s)}getAssets(t){let e=t.map(s=>s.tokens.map(a=>a.id)).flat().sort((s,a)=>s>a?1:-1);return new Set(e)}getPaths(t,e,s){let a=this.toPoolsMap(s);return this.getProposals(t,e,s).filter(n=>this.validPath(n,a)).map(n=>this.toHops(n,a))}getProposals(t,e,s){let a=this.buildRouteKey(t,e,s);if(this.routeProposals.has(a))return this.routeProposals.get(a);let i=this.routeSuggester.getProposals(t,e,s);return this.routeProposals.set(a,i),i}validPath(t,e){return t.length>0&&t.map(s=>this.validEdge(s,e)).reduce((s,a)=>s&&a)}validEdge([t,e,s],a){return a.get(t)?.validatePair(e,s)||!1}toPoolsMap(t){return new Map(t.map(e=>[e.address,ht.get(e)]))}toHops(t,e){return t.map(([s,a,i])=>{let n=e.get(s);return{poolAddress:s,poolId:n?.id,pool:n?.type,assetIn:a,assetOut:i}})}};var P=require("@galacticcouncil/common");var Vt=(e=>(e.Buy="Buy",e.Sell="Sell",e))(Vt||{}),Wt=(s=>(s.Dca="Dca",s.TwapSell="TwapSell",s.TwapBuy="TwapBuy",s))(Wt||{}),Ut=(s=>(s.OrderTooSmall="OrderTooSmall",s.OrderTooBig="OrderTooBig",s.OrderImpactTooBig="OrderImpactTooBig",s))(Ut||{});var{FeeUtils:de}=w,ot=class extends rt{mlr;constructor(t){super(t),this.mlr=new Map}onFilterChanged(){this.mlr.clear()}buildCtxSync(t,e,s){let a=super.validateInput(t,e,s),i=super.getPaths(t,e,s);if(!i.length)throw new _t(t,e);return{paths:i,pools:s,poolsMap:a}}async withCtx(t,e,s){let a=await super.getPools(),i=this.buildCtxSync(t,e,a);return s(i)}isDirectTrade(t){return t.length==1}findBestSellRoute(t){let e=t.sort((s,a)=>{let i=s[s.length-1].amountOut,n=a[a.length-1].amountOut;return i>n?-1:1});return e.find(s=>s.every(a=>a.errors.length==0))||e[0]}getRouteFeeRange(t){if(t.filter(s=>s.tradeFeeRange).length>0){let s=t.map(i=>i.tradeFeeRange?.[0]??i.tradeFeePct).reduce((i,n)=>i+n),a=t.map(i=>i.tradeFeeRange?.[1]??i.tradeFeePct).reduce((i,n)=>i+n);return[s,a]}}getPoolFeeRange(t,e){let s=t.min?de.toPct(t.min):void 0,a=t.max?de.toPct(t.max):void 0;if(s&&a)return[s,Math.max(a,e)]}async getBestSell(t,e,s){return this.getSell(t,e,s)}getSellSpot(t){let e=t[t.length-1];return t.length===1?e.spotPrice:this.calculateSpot(t)}async getSell(t,e,s,a){return this.withCtx(t,e,async({paths:i,poolsMap:n})=>{let r;if(a)r=await this.toSellSwaps(s,a,n);else{let o=i.map(u=>this.toSellSwaps(s,u,n)),l=await Promise.all(o);r=this.findBestSellRoute(l)}return this.buildSell(n,r)})}async getSells(t,e,s){return this.withCtx(t,e,async({paths:a,poolsMap:i})=>{let n=a.map(o=>this.toSellSwaps(s,o,i));return(await Promise.all(n)).filter(o=>o.every(l=>l.errors.length==0)).map(o=>this.buildSell(i,o)).sort((o,l)=>o.amountOut>l.amountOut?-1:1)})}buildSell(t,e){let s=e[0],a=e[e.length-1],i=this.isDirectTrade(e),n=this.getSellSpot(e),r=a.amountOut,o=i?a.calculatedOut:this.calculateDelta0Y(s.amountIn,e,t),l=o-r,u=this.getRouteFeeRange(e),m=i?a.tradeFeePct:A.calculateSellFee(o,r),b=C.mulSpot(s.amountIn,n,s.assetInDecimals,a.assetOutDecimals),d=A.calculateDiffToRef(o,b);return{type:"Sell",amountIn:s.amountIn,amountOut:a.amountOut,spotPrice:n,tradeFee:l,tradeFeePct:m,tradeFeeRange:u,priceImpactPct:d,swaps:e,toHuman(){return{type:"Sell",amountIn:P.big.toDecimal(s.amountIn,s.assetInDecimals),amountOut:P.big.toDecimal(a.amountOut,a.assetOutDecimals),spotPrice:P.big.toDecimal(n,P.RUNTIME_DECIMALS),tradeFee:P.big.toDecimal(l,a.assetOutDecimals),tradeFeePct:m,tradeFeeRange:u,priceImpactPct:d,swaps:e.map(S=>S.toHuman())}}}}calculateSpot(t){return t.map(e=>e.spotPrice).reduce((e,s)=>e*s/10n**BigInt(P.RUNTIME_DECIMALS))}calculateDelta0Y(t,e,s){let a=[];for(let i=0;i<e.length;i++){let n=e[i],r=s.get(n.poolAddress);if(r==null)throw new Error("Pool does not exit");let o=r.parsePair(n.assetIn,n.assetOut),l;i>0?l=a[i-1]:l=t;let u=r.calculateOutGivenIn(o,l);a.push(u)}return a[a.length-1]}async calculateMostLiquidRoute(t,e,s){let{paths:a,pools:i,poolsMap:n}=s,l=i.filter(g=>g.tokens.some(p=>p.id===t)).map(g=>g.type==="Aave"?g.tokens:g.tokens.filter(p=>p.id===t)).map(g=>g.map(p=>p.balance).reduce((p,y)=>p+y)).sort((g,p)=>p<g?-1:1)[0],u=C.getFraction(l,.1),m=await Promise.all(a.map(g=>this.toSellSwaps(u,g,n))),d=this.findBestSellRoute(m).map(g=>({poolAddress:g.poolAddress,poolId:g?.poolId,pool:g.pool,assetIn:g.assetIn,assetOut:g.assetOut})),S=this.buildRouteKey(t,e,i);return this.mlr.set(S,d),d}async toSellSwaps(t,e,s){let a=[];for(let i=0;i<e.length;i++){let n=e[i],r=s.get(n.poolAddress);if(r==null)throw new Error("Pool does not exit");let o=r.parsePair(n.assetIn,n.assetOut),l;i>0?l=a[i-1].amountOut:l=typeof t=="string"?P.big.toBigInt(t,o.decimalsIn):t;let u=await this.ctx.getPoolFees(o,r),{amountOut:m,calculatedOut:b,feePct:d,errors:S}=r.validateAndSell(o,l,u),g=this.getPoolFeeRange(u,d),p=r.spotPriceOutGivenIn(o),y=C.mulSpot(l,p,o.decimalsIn,o.decimalsOut),f=A.calculateDiffToRef(b,y);a.push({...n,assetInDecimals:o.decimalsIn,assetOutDecimals:o.decimalsOut,amountIn:l,amountOut:m,calculatedOut:b,spotPrice:p,tradeFeePct:d,tradeFeeRange:g,priceImpactPct:f,errors:S,isSupply(){return r.type==="Aave"&&r.tokens[0].id===n.assetIn},isWithdraw(){return r.type==="Aave"&&r.tokens[1].id===n.assetIn},toHuman(){return{...n,amountIn:P.big.toDecimal(l,o.decimalsIn),amountOut:P.big.toDecimal(m,o.decimalsOut),calculatedOut:P.big.toDecimal(b,o.decimalsOut),spotPrice:P.big.toDecimal(p,P.RUNTIME_DECIMALS),tradeFeePct:d,tradeFeeRange:g,priceImpactPct:f,errors:S}}})}return a}async getMostLiquidRoute(t,e){return this.withCtx(t,e,async s=>{let a=this.buildRouteKey(t,e,s.pools),i=this.mlr.get(a);return i||this.calculateMostLiquidRoute(t,e,s)})}async getSpotPrice(t,e){return this.withCtx(t,e,async s=>{let{pools:a,poolsMap:i}=s,n=this.buildRouteKey(t,e,a),r=this.mlr.get(n);r||(r=await this.calculateMostLiquidRoute(t,e,s));let o=await this.toSellSwaps("1",r,i);return{amount:this.getSellSpot(o),decimals:P.RUNTIME_DECIMALS}}).catch(()=>{})}findBestBuyRoute(t){let e=t.sort((s,a)=>{let i=s[0].amountIn,n=a[0].amountIn;return i>n?1:-1});return e.find(s=>s.every(a=>a.errors.length==0))||e[0]}async getBestBuy(t,e,s){return this.getBuy(t,e,s)}getBuySpot(t){let e=t[0];return t.length===1?e.spotPrice:this.calculateSpot(t)}async getBuy(t,e,s,a){return this.withCtx(t,e,async({paths:i,poolsMap:n})=>{let r;if(a)r=await this.toBuySwaps(s,a,n);else{let o=i.map(u=>this.toBuySwaps(s,u,n)),l=await Promise.all(o);r=this.findBestBuyRoute(l)}return this.buildBuy(n,r)})}async getBuys(t,e,s){return this.withCtx(t,e,async({paths:a,poolsMap:i})=>{let n=a.map(o=>this.toBuySwaps(s,o,i));return(await Promise.all(n)).filter(o=>o.every(l=>l.errors.length==0)).map(o=>this.buildBuy(i,o)).sort((o,l)=>o.amountIn>l.amountIn?1:-1)})}buildBuy(t,e){let s=e[e.length-1],a=e[0],i=this.isDirectTrade(e),n=this.getBuySpot(e),r=a.amountIn,o=i?a.calculatedIn:this.calculateDelta0X(s.amountOut,e,t),l=r-o,u=this.getRouteFeeRange(e),m=i?a.tradeFeePct:A.calculateBuyFee(o,r),b=C.mulSpot(s.amountOut,n,s.assetOutDecimals,a.assetInDecimals),d;return o===0n?d=-100:d=A.calculateDiffToRef(b,o),{type:"Buy",amountOut:s.amountOut,amountIn:a.amountIn,spotPrice:n,tradeFee:l,tradeFeePct:m,tradeFeeRange:u,priceImpactPct:d,swaps:e,toHuman(){return{type:"Buy",amountOut:P.big.toDecimal(s.amountOut,s.assetOutDecimals),amountIn:P.big.toDecimal(a.amountIn,a.assetInDecimals),spotPrice:P.big.toDecimal(n,P.RUNTIME_DECIMALS),tradeFee:P.big.toDecimal(l,a.assetInDecimals),tradeFeePct:m,tradeFeeRange:u,priceImpactPct:d,swaps:e.map(S=>S.toHuman())}}}}calculateDelta0X(t,e,s){let a=[];for(let i=e.length-1;i>=0;i--){let n=e[i],r=s.get(n.poolAddress);if(r==null)throw new Error("Pool does not exit");let o=r.parsePair(n.assetIn,n.assetOut),l;i==e.length-1?l=t:l=a[0];let u=r.calculateInGivenOut(o,l);a.unshift(u)}return a[0]}async toBuySwaps(t,e,s){let a=[];for(let i=e.length-1;i>=0;i--){let n=e[i],r=s.get(n.poolAddress);if(r==null)throw new Error("Pool does not exit");let o=r.parsePair(n.assetIn,n.assetOut),l;i==e.length-1?l=typeof t=="string"?P.big.toBigInt(t,o.decimalsOut):t:l=a[0].amountIn;let u=await this.ctx.getPoolFees(o,r),{amountIn:m,calculatedIn:b,feePct:d,errors:S}=r.validateAndBuy(o,l,u),g=this.getPoolFeeRange(u,d),p=r.spotPriceInGivenOut(o),y=C.mulSpot(l,p,o.decimalsOut,o.decimalsIn),f;b===0n?f=-100:f=A.calculateDiffToRef(y,b),a.unshift({...n,assetInDecimals:o.decimalsIn,assetOutDecimals:o.decimalsOut,amountOut:l,amountIn:m,calculatedIn:b,spotPrice:p,tradeFeePct:d,tradeFeeRange:g,priceImpactPct:f,errors:S,isSupply(){return r.type==="Aave"&&r.tokens[0].id===n.assetIn},isWithdraw(){return r.type==="Aave"&&r.tokens[1].id===n.assetIn},toHuman(){return{...n,amountOut:P.big.toDecimal(l,o.decimalsOut),amountIn:P.big.toDecimal(m,o.decimalsIn),calculatedIn:P.big.toDecimal(b,o.decimalsIn),spotPrice:P.big.toDecimal(p,P.RUNTIME_DECIMALS),tradeFeePct:d,tradeFeeRange:g,priceImpactPct:f,errors:S}}})}return a}};var x=require("@galacticcouncil/common");var ge=6e3,$t=1000000000000000n,Pt=6,Xt=-5,Yt=216e5,rl=3,he=.1,be=6;var zt=require("polkadot-api");var W=class{static build(t){return t.map(({assetIn:e,assetOut:s,pool:a,poolId:i})=>a==="Stableswap"?{pool:(0,zt.Enum)("Stableswap",i),asset_in:e,asset_out:s}:{pool:(0,zt.Enum)(a),asset_in:e,asset_out:s})}};var Rt=class{schedulerOptions;router;constructor(t,e={}){this.router=new ot(t),this.router.withFilter({exclude:["HSM"]}),this.schedulerOptions=Object.freeze({blockTime:e.blockTime??6e3,minBudgetInNative:e.minBudgetInNative??$t})}get blockTime(){return this.schedulerOptions.blockTime}get minOrderBudget(){return this.schedulerOptions.minBudgetInNative}async getDcaOrder(t,e,s,a,i){let n=await this.router.getBestSell(t,e,s),{amountIn:r,swaps:o,priceImpactPct:l}=n,u=o[0],m=o[o.length-1],{assetInDecimals:b}=u,{assetOutDecimals:d}=m,S=Math.abs(l),g=await this.getMinimumOrderBudget(t,b),p=this.getOptimalTradeCount(S),y=this.getMaximumTradeCount(r,g,a),f=i||Math.min(p,y),D=Math.round(a/f),E=r/BigInt(f),_=await this.router.getBestSell(t,e,E),Y=r<g,Q=[];Y&&Q.push("OrderTooSmall");let U=_.amountOut*BigInt(f),ye=this.toBlockPeriod(D),fe=_.tradeFee*BigInt(f),Se=W.build(o),Kt={assetIn:t,assetOut:e,errors:Q,maxTradeCount:y,tradeCount:f,tradeFee:fe,tradeImpactPct:_.priceImpactPct,tradePeriod:ye,tradeRoute:Se,type:"Dca"};return{...Kt,amountIn:r,amountOut:U,tradeAmountIn:_.amountIn,tradeAmountOut:_.amountOut,toHuman(){return{...Kt,amountIn:x.big.toDecimal(r,b),amountOut:x.big.toDecimal(U,d),tradeAmountIn:x.big.toDecimal(_.amountIn,b),tradeAmountOut:x.big.toDecimal(_.amountOut,d)}}}}async getMinimumOrderBudget(t,e){if(0===t)return this.minOrderBudget;let s=await this.router.getSpotPrice(0,t);if(s)return C.mulSpot(this.minOrderBudget,s.amount,12,e);let a=await this.router.getSpotPrice(t,0);if(a)return C.divSpot(this.minOrderBudget,a.amount,12,e);throw new Error("Unable to calculate order budget")}getMaximumTradeCount(t,e,s){let a=e*2n/10n;if(a===0n)return 0;let i=Number(t/a),n=Math.floor(s/this.blockTime),r=Math.max(0,Math.floor(n*(1-.1)));return Math.min(i,r)}getOptimalTradeCount(t){let e=Math.round(t*10)||1;return Math.max(e,3)}async getOpenBudgetDcaOrder(t,e,s,a){let i=await this.router.getBestSell(t,e,s),{swaps:n}=i,r=n[0],o=n[n.length-1],{assetInDecimals:l}=r,{assetOutDecimals:u}=o,m=await this.getMinimumOrderBudget(t,l),b=i.amountIn<m,d=[];b&&d.push("OrderTooSmall");let S=this.toBlockPeriod(a),g=W.build(n),p={assetIn:t,assetOut:e,errors:d,maxTradeCount:0,tradeCount:0,tradeFee:i.tradeFee,tradeImpactPct:i.priceImpactPct,tradePeriod:S,tradeRoute:g,type:"Dca"};return{...p,amountIn:0n,amountOut:0n,tradeAmountIn:i.amountIn,tradeAmountOut:i.amountOut,toHuman(){return{...p,amountIn:"0",amountOut:"0",tradeAmountIn:x.big.toDecimal(i.amountIn,l),tradeAmountOut:x.big.toDecimal(i.amountOut,u)}}}}async getTwapSellOrder(t,e,s){let a=await this.router.getBestSell(t,e,s),{amountIn:i,swaps:n,priceImpactPct:r}=a,o=n[0],l=n[n.length-1],{assetInDecimals:u}=o,{assetOutDecimals:m}=l,b=Math.abs(r),d=this.getTwapTradeCount(b),S=i/BigInt(d),[g,p]=await Promise.all([this.getMinimumOrderBudget(t,u),this.router.getBestSell(o.assetIn,l.assetOut,S)]),y=d===1,f=i<g,D=p.priceImpactPct<-5,E=[];f||y?E.push("OrderTooSmall"):D&&E.push("OrderImpactTooBig");let _=p.amountOut*BigInt(d),Y=p.tradeFee*BigInt(d),Q=W.build(n),U={assetIn:t,assetOut:e,errors:E,tradeCount:d,tradeImpactPct:p.priceImpactPct,tradePeriod:6,tradeRoute:Q,type:"TwapSell"};return{...U,amountIn:i,amountOut:_,tradeAmountIn:p.amountIn,tradeAmountOut:p.amountOut,tradeFee:Y,toHuman(){return{...U,amountIn:x.big.toDecimal(i,u),amountOut:x.big.toDecimal(_,m),tradeAmountIn:x.big.toDecimal(p.amountIn,u),tradeAmountOut:x.big.toDecimal(p.amountOut,m),tradeFee:x.big.toDecimal(Y,m)}}}}async getTwapBuyOrder(t,e,s){let a=await this.router.getBestBuy(t,e,s),{amountOut:i,swaps:n,priceImpactPct:r}=a,o=n[0],l=n[n.length-1],{assetInDecimals:u}=o,{assetOutDecimals:m}=l,b=Math.abs(r),d=this.getTwapTradeCount(b),S=i/BigInt(d),[g,p]=await Promise.all([this.getMinimumOrderBudget(t,u),this.router.getBestBuy(o.assetIn,l.assetOut,S)]),y=p.amountIn*BigInt(d),f=d===1,D=y<g,E=p.priceImpactPct<-5,_=[];D||f?_.push("OrderTooSmall"):E&&_.push("OrderImpactTooBig");let Y=p.tradeFee*BigInt(d),Q=W.build(n),U={assetIn:t,assetOut:e,errors:_,tradeCount:d,tradeImpactPct:p.priceImpactPct,tradePeriod:6,tradeRoute:Q,type:"TwapBuy"};return{...U,amountIn:y,amountOut:i,tradeAmountIn:p.amountIn,tradeAmountOut:p.amountOut,tradeFee:Y,toHuman(){return{...U,amountIn:x.big.toDecimal(y,u),amountOut:x.big.toDecimal(i,m),tradeAmountIn:x.big.toDecimal(p.amountIn,u),tradeAmountOut:x.big.toDecimal(p.amountOut,m),tradeFee:x.big.toDecimal(Y,u)}}}}getTwapTradeCount(t){let e=this.getOptimalTradeCount(t);if(this.getTwapExecutionTime(e)>216e5){let a=216e5/(this.blockTime*6);return Math.round(a)}return e}getTwapExecutionTime(t){return t*6*this.blockTime}toBlockPeriod(t){let e=t/this.blockTime,s=Math.round(e);return Math.max(s,6)}};0&&(module.exports={DCA_TIME_RESERVE,DEFAULT_BLOCK_TIME,DEFAULT_MIN_BUDGET,ORDER_MIN_BLOCK_PERIOD,Router,TWAP_EXECUTION_INTERVAL,TWAP_MAX_DURATION,TWAP_MAX_PRICE_IMPACT,TWAP_TX_MULTIPLIER,TradeOrderError,TradeOrderType,TradeRouteBuilder,TradeRouter,TradeScheduler,TradeType});