@galacticcouncil/sdk-next 0.41.0 → 0.41.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.
- package/build/farm/index.cjs +1 -1
- package/build/farm/index.mjs +1 -1
- package/build/index.cjs +1 -1
- package/build/index.mjs +1 -1
- package/build/pool/index.cjs +1 -1
- package/build/pool/index.mjs +1 -1
- package/build/sor/index.cjs +1 -1
- package/build/sor/index.mjs +1 -1
- package/build/tx/index.cjs +1 -1
- package/build/tx/index.mjs +1 -1
- package/package.json +1 -1
package/build/pool/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var Oe=Object.defineProperty;var B=(u,t)=>{for(var e in t)Oe(u,e,{get:t[e],enumerable:!0})};import Ie from"buffer";typeof window<"u"&&(window.Buffer=Ie.Buffer);var se={};B(se,{LbpMath:()=>T,LbpPool:()=>j,LbpPoolClient:()=>tt});import{calculate_in_given_out as we,calculate_out_given_in as Te,calculate_linear_weights as Be,calculate_pool_trade_fee as Ae,get_spot_price as Fe}from"@galacticcouncil/math-lbp";var T=class{static getSpotPrice(t,e,i,s,a){return Fe(t,e,i,s,a)}static calculateInGivenOut(t,e,i,s,a){return we(t,e,i,s,a)}static calculateOutGivenIn(t,e,i,s,a){return Te(t,e,i,s,a)}static calculateLinearWeights(t,e,i,s,a){return Be(t,e,i,s,a)}static calculatePoolTradeFee(t,e,i){return Ae(t,e,i)}};import{big as Wt,RUNTIME_DECIMALS as $t}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 dt={};B(dt,{withTimeout:()=>_e});function _e(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 xa}from"@galacticcouncil/common";var P={};B(P,{FeeUtils:()=>Bt,shiftNeg:()=>Ce});import Ee 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 Ce(u,t){let e=Ee(typeof u=="bigint"?u.toString():u);return t===0?e.toString():e.div(Math.pow(10,t)).toString()}var K={};B(K,{findNestedKey:()=>Le,findNestedObj:()=>Me,jsonFormatter:()=>De});var Le=(u,t)=>{let e=[];return JSON.stringify(u,(i,s)=>(s&&s[t]&&e.push(s),s)),e[0]},Me=(u,t,e)=>{let i;return JSON.stringify(u,(s,a)=>(a&&a[t]===e&&(i=a),a)),i},De=(u,t)=>typeof t=="bigint"?t.toString():t;var D={};B(D,{calculateBuyFee:()=>Ne,calculateDiffToAvg:()=>He,calculateDiffToRef:()=>Ge,calculateSellFee:()=>qe});import E from"big.js";function He(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 Ge(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 qe(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 Ne(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 Vt}from"@thi.ng/cache";var bt=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 Vt(null,{ttl:s}):new Vt;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:Ut}=P,j=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=Ut.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=Ut.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(),Wt.toBigInt(1,$t).toString());return BigInt(e)}spotPriceOutGivenIn(t){let e=T.getSpotPrice(t.balanceIn.toString(),t.balanceOut.toString(),t.weightIn.toString(),t.weightOut.toString(),Wt.toBigInt(1,$t).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 Fi}from"polkadot-api";import{Subscription as _i,distinctUntilChanged as ki,filter as Ri}from"rxjs";import{memoize1 as bi}from"@thi.ng/memoize";import{TLRUCache as hi}from"@thi.ng/cache";import{ReplaySubject as Zt,Subscription as te,combineLatest as Pi,defer as yi,from as fi,merge as Ft,of as Si,EMPTY as St}from"rxjs";import{bufferCount as vi,bufferTime as xi,catchError as vt,filter as xt,finalize as _t,map as V,pairwise as kt,repeat as ee,skip as Oi,share as Ii,startWith as wi,switchMap as ie,tap as W,throttleTime as Ti}from"rxjs/operators";import{hydration as ii,hydrationNext as si}from"@galacticcouncil/descriptors";import{log as Je}from"@galacticcouncil/common";import{shareReplay as Ze,tap as ti}from"rxjs";import{defer as Ve,from as We,of as Yt,timer as $e}from"rxjs";import{catchError as Ue,distinctUntilChanged as Ye,expand as Xe,map as At,shareReplay as ze,skip as Ke,switchMap as je,timeout as Qe}from"rxjs/operators";function Xt(u,{intervalMs:t=5e3,rpcTimeoutMs:e=1e4}={}){let i=()=>Ve(()=>We(u._request("system_health",[]))).pipe(Qe({first:e}),At(()=>"online"),Ue(()=>Yt("offline")));return Yt({state:"offline",delayMs:0}).pipe(Xe(a=>$e(a.delayMs).pipe(je(i),At(n=>({state:n,delayMs:t})))),Ke(1),At(a=>a.state),Ye(),ze({bufferSize:1,refCount:!0}))}var{logger:ei}=Je,ht=class u{static instance=null;bestBlock$;finalizedBlock$;connection$;constructor(t){this.bestBlock$=this.watched("watcher(bestBlock)",t.getUnsafeApi().query.System.Number.watchValue("best")),this.finalizedBlock$=this.watched("watcher(finalizedBlock)",t.finalizedBlock$),this.connection$=this.watched("watcher(connection)",Xt(t))}static getInstance(t){return this.instance||(this.instance=new u(t)),this.instance}watched(t,e){return e.pipe(ti({error:i=>ei.error(t,i)}),Ze({bufferSize:1,refCount:!0}))}};var A=class{client;api;apiNext;watcher;constructor(t){this.client=t,this.api=this.client.getTypedApi(ii),this.apiNext=this.client.getTypedApi(si),this.watcher=ht.getInstance(this.client)}};import{getWsProvider as bn}from"polkadot-api/ws-provider";import{withLogsRecorder as Pn}from"polkadot-api/logs-provider";import{withLegacy as fn}from"@polkadot-api/legacy-provider";import{getSmProvider as On}from"polkadot-api/sm-provider";import{log as ai}from"@galacticcouncil/common";import{combineLatest as ni,concat as ri,defer as Q,from as zt}from"rxjs";import{bufferCount as Kt,distinctUntilChanged as jt,debounceTime as oi,map as q,retry as li,startWith as Qt,switchMap as Jt,tap as J,take as ci,skip as ui,connect as pi}from"rxjs/operators";var{logger:N}=ai,Z=class extends A{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 Q(()=>{let e=this.watchSystemBalance(t),i=this.watchTokensBalance(t),s=this.watchErc20Balance(t);return ni([e,i,s]).pipe(pi(a=>ri(a.pipe(ci(1)),a.pipe(ui(1),oi(250)))))}).pipe(q(e=>e.flat()),Qt([]),Kt(2,1),q(([e,i],s)=>s===0?i:this.getDeltas(e,i))).pipe(J({subscribe:()=>N.debug("balance: subscribe",t),error:e=>N.error("balance",e)}),li({delay:1e3}))}watchSystemBalance(t){let e=this.api.query.System.Account;return Q(()=>e.watchValue(t,"best")).pipe(q(i=>({id:0,balance:this.getBreakdown(i.data)})),J({error:i=>N.error("balance(system)",i)}))}watchTokenBalance(t,e){let i=this.api.query.Tokens.Accounts;return Q(()=>i.watchValue(t,e,"best")).pipe(q(s=>({id:e,balance:this.getBreakdown(s)})),J({error:s=>N.error("balance(token)",s)}))}watchTokensBalance(t){let e=this.api.query.Tokens.Accounts;return Q(()=>e.watchEntries(t,{at:"best"})).pipe(jt((i,s)=>!s.deltas),q(({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}),J({error:i=>N.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 Q(()=>zt(e?Promise.resolve(e):i()).pipe(Jt(a=>this.watcher.bestBlock$.pipe(Jt(()=>zt(s(a))))),Qt([]),Kt(2,1),q(([a,n],r)=>r===0?n.filter(o=>o.balance.total>0n):this.getDeltas(a,n)),jt((a,n)=>n.length===0),J({error:a=>N.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 mi}from"rxjs";var Pt=class{store$=new mi([]);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 di}from"@galacticcouncil/common";var gi={Aave:"AAVE",LBP:"LBP",Omnipool:"OMNI",Stableswap:"STBL",XYK:"XYK",HSM:"HSM"},{logger:yt}=di,ft=class{type;constructor(t){this.type=t}prefix(){return this.pad(`pool(${gi[this.type]})`,10)}trace(t,...e){yt.trace(`${this.prefix()} ${t} :`,...e)}debug(t,...e){yt.debug(`${this.prefix()} ${t} :`,...e)}info(t,...e){yt.info(`${this.prefix()} ${t} :`,...e)}error(t,...e){yt.error(`${this.prefix()} ${t} :`,...e)}pad(t,e){return t.length>=e?t:t+" ".repeat(e-t.length)}};var{withTimeout:Bi}=dt,Ai=3e3,v=class extends A{evm;balance;store=new Pt;log;shared$;resync$=new Zt(1);resyncAt=0;resyncPending=!1;mem=0;memPoolsCache=new hi(null,{ttl:6*1e3});memPools=bi(t=>(this.log.info("pool_sync",{mem:t}),this.loadPools()),this.memPoolsCache);constructor(t,e){super(t),this.evm=e,this.balance=new Z(t),this.log=new ft(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(wi([]),vi(2,1),V(([t,e])=>t.length===0?e:this.store.applyChangeset(e)),xt(t=>t.length>0),Ti(1e3,void 0,{leading:!0,trailing:!0}))}subscribeStore(){return yi(()=>{let t=new te;return t.add(this.startWatchdog()),this.resync$.next(),this.resync$.pipe(ie(()=>{let e=new te;return fi(Bi(this.getMemPools(),6e4,"getMemPools stalled")).pipe(W(()=>this.log.info("pool_synced",{mem:this.mem})),V(s=>s.filter(a=>this.hasValidAssets(a))),W(s=>this.store.set(s)),vt(()=>(this.log.error("pool_seed_error",{mem:this.mem}),this.requestResync(),St))).pipe(W(()=>{e.add(this.subscribeBalances()),e.add(this.subscribeUpdates())}),ie(s=>Ft(Si(s),this.store.asObservable().pipe(Oi(1)))),_t(()=>{e.unsubscribe()}))}),_t(()=>t.unsubscribe()))}).pipe(Ii({connector:()=>new Zt(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 Pi(s).pipe(V(a=>a.flat()),kt(),V(([a,n])=>this.balance.getDeltas(a,n)),xt(a=>a.length>0),V(a=>[i,a]))});return Ft(...t).pipe(xi(250),xt(e=>e.length>0),V(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<Ai||(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 i=this.watcher.connection$.pipe(kt(),xt(([a,n])=>a==="offline"&&n==="online"),W(()=>{this.log.debug("watchdog_recover_online",{mem:this.mem}),this.requestResync()}),vt(a=>(this.log.error("watchdog_recovery_error",a),St)),ee({delay:1e3})),s=this.watcher.finalizedBlock$.pipe(kt(),W(([a,n])=>{let r=Number(a.number),o=Number(n.number),l=o-r;l>=3&&(this.log.debug("watchdog_gap",{from:r,to:o,gap:l}),this.requestResync())}),vt(a=>(this.log.error("watchdog_gap_error",a),St)),ee({delay:1e3}));return Ft(i,s).subscribe()}watchGuard(t){return e=>e.pipe(W({error:i=>{this.log.error(t,i),this.requestResync(!0)}}),_t(()=>{this.log.debug(t,"unsub")}),vt(()=>St))}};var tt=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(){let t=this.api.query.LBP.PoolData,e=await this.api.compatibilityToken;return t.isCompatible(Fi.BackwardsCompatible,e)}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("best").pipe(Ri(t=>t!==void 0),ki((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 _i;return t.add(this.subscribeValidationData()),t}};var oe={};B(oe,{OmniMath:()=>b,OmniPool:()=>et,OmniPoolClient:()=>st});import{calculate_in_given_out as Ei,calculate_lrna_in_given_out as Ci,calculate_out_given_in as Li,calculate_out_given_lrna_in as Mi,calculate_spot_price as Di,calculate_lrna_spot_price as Hi,calculate_shares as Gi,calculate_liquidity_out as qi,calculate_liquidity_lrna_out as Ni,verify_asset_cap as Vi,calculate_liquidity_hub_in as Wi,is_sell_allowed as $i,is_buy_allowed as Ui,is_add_liquidity_allowed as Yi,is_remove_liquidity_allowed as Xi,recalculate_asset_fee as zi,recalculate_protocol_fee as Ki}from"@galacticcouncil/math-omnipool";import $ from"big.js";var b=class{static calculateSpotPrice(t,e,i,s){return Di(t,e,i,s)}static calculateLrnaSpotPrice(t,e){return Hi(t,e)}static calculateInGivenOut(t,e,i,s,a,n,r,o,l,c){return Ei(t,e,i,s,a,n,r,o,l,c)}static calculateLrnaInGivenOut(t,e,i,s,a,n){return Ci(t,e,i,s,a,n)}static calculateOutGivenIn(t,e,i,s,a,n,r,o,l,c){return Li(t,e,i,s,a,n,r,o,l,c)}static calculateOutGivenLrnaIn(t,e,i,s,a,n){return Mi(t,e,i,s,a,n)}static calculateShares(t,e,i,s){return Gi(t,e,i,s)}static calculateLiquidityOut(t,e,i,s,a,n,r,o){return qi(t,e,i,s,a,n,r,o)}static calculateLiquidityLRNAOut(t,e,i,s,a,n,r,o){return Ni(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 Wi(t,e,i,s)}static isSellAllowed(t){return $i(t)}static isBuyAllowed(t){return Ui(t)}static isAddLiquidityAllowed(t){return Yi(t)}static isRemoveLiquidityAllowed(t){return Xi(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 Ki(t,e,i,s,a,n,r,o,l,c,p)}static verifyAssetCap(t,e,i,s){return Vi(t,e,i,s)}};import{big as ji}from"@galacticcouncil/common";var{FeeUtils:F}=P,et=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=ji.pow10(Math.abs(s));return s>0?t*a:t/a}};import{AccountId as Qi,Binary as Ji,CompatibilityLevel as ae,Enum as Zi}from"polkadot-api";import{toHex as ts}from"@polkadot-api/utils";import{Subscription as es,distinctUntilChanged as Et,filter as is,finalize as Ct,map as it,merge as ss,tap as Ot}from"rxjs";import{HYDRATION_SS58_PREFIX as as}from"@galacticcouncil/common";var{FeeUtils:h}=P,ne=Ji.fromText("omnipool"),re=Zi("Short"),st=class extends v{queryBus=new bt;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(ne,t,re,{at:"best"}),t=>t.join(":"),6*1e3);getPoolType(){return"Omnipool"}getPoolAddress(){let t="modlomnipool".padEnd(32,"\0"),e=new TextEncoder().encode(t),i=ts(e);return Qi(as).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(){let t=this.api.query.Omnipool.Assets,e=await this.api.compatibilityToken;return t.isCompatible(ae.BackwardsCompatible,e)}async isSlipFeeSupported(){return this.apiNext.query.Omnipool.SlipFee.isCompatible(ae.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:O,protocol_fee:R}=n.value;return{assetFee:h.fromPermill(O),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(),O=d.liquidity.b.toString();n===0&&(x=d.volume.a_in.toString(),w=d.volume.a_out.toString(),O=d.liquidity.a.toString());let R=h.fromPermill(S),z=b.recalculateAssetFee(x,w,O,"9",r.toString(),h.toRaw(R).toString(),k.toString(),h.toRaw(m).toString(),h.toRaw(g).toString(),c.toString(),p.toString());return[o,Number(z)*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(),O=d.liquidity.b.toString();n===0&&(x=d.volume.a_in.toString(),w=d.volume.a_out.toString(),O=d.liquidity.a.toString());let R=h.fromPermill(S),z=b.recalculateProtocolFee(x,w,O,"9",r.toString(),h.toRaw(R).toString(),k.toString(),h.toRaw(m).toString(),h.toRaw(g).toString(),c.toString(),p.toString());return[o,Number(z)*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(ne,s,re,"best").pipe(is(a=>a!==void 0),it((a,n)=>({value:a,index:n})),Ot(({index:a})=>{a>0&&this.log.trace("emaOracle.Oracles",s.join(":"))}),it(({value:a})=>({pair:s,value:a}))));return ss(...i).pipe(Ct(()=>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(Et((t,e)=>!e.deltas),it((t,e)=>({value:t,index:e})),Ot(({value:t,index:e})=>{e>0&&this.log.trace("dynamicFees.AssetFee",t.deltas?.upserted)}),Ct(()=>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(Et((t,e)=>!e.deltas),it((t,e)=>({value:t,index:e})),Ot(({value:t,index:e})=>{e>0&&this.log.trace("dynamicFees.AssetFeeConfiguration",t.deltas?.upserted)}),Ct(()=>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(Et((t,e)=>!e.deltas),it((t,e)=>({value:t,index:e})),Ot(({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 es;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 ue={};B(ue,{StableMath:()=>f,StableSwap:()=>G,StableSwapClient:()=>at});import{calculate_in_given_out as ns,calculate_out_given_in as rs,calculate_amplification as os,calculate_add_one_asset as ls,calculate_liquidity_out_one_asset as cs,calculate_shares as us,calculate_shares_for_amount as ps,calculate_spot_price_with_fee as ms,pool_account_name as ds,recalculate_peg as gs}from"@galacticcouncil/math-stableswap";var f=class{static getPoolAddress(t){return ds(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 os(t,e,i,s,a)}static calculateInGivenOut(t,e,i,s,a,n,r){return ns(t,e,i,s,a,n,r)}static calculateAddOneAsset(t,e,i,s,a,n,r){return ls(t,e,i,s,a,n,r)}static calculateSharesForAmount(t,e,i,s,a,n,r){return ps(t,e,i,s,a,n,r)}static calculateOutGivenIn(t,e,i,s,a,n,r){return rs(t,e,i,s,a,n,r)}static calculateLiquidityOutOneAsset(t,e,i,s,a,n,r){return cs(t,e,i,s,a,n,r)}static calculateShares(t,e,i,s,a,n){return us(t,e,i,s,a,n)}static calculateSpotPriceWithFee(t,e,i,s,a,n,r,o){return ms(t,e,i,s,a,n,r,o)}static recalculatePegs(t,e,i,s,a,n){let r=gs(t,e,i,s,a,n);return JSON.parse(r)}};import{RUNTIME_DECIMALS as bs,big as le}from"@galacticcouncil/common";var{FeeUtils:U}=P,G=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?U.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?U.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?U.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?U.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?U.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?U.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,K.jsonFormatter)}getAssets(t,e){let i={asset_id:Number(t),amount:e.toString()};return JSON.stringify([i],K.jsonFormatter)}normalizeSpot(t,e,i,s,a){return e?t*le.pow10(bs-a):i?t/le.pow10(a-s):t}};import{AccountId as hs,CompatibilityLevel as Ps}from"polkadot-api";import{toHex as ys}from"@polkadot-api/utils";import{blake2b as fs}from"@noble/hashes/blake2b";import{Subscription as Ss,distinctUntilChanged as vs,map as Lt,merge as xs,tap as ce}from"rxjs";import{HYDRATION_SS58_PREFIX as Os,RUNTIME_DECIMALS as Is}from"@galacticcouncil/common";var{FeeUtils:ws}=P,at=class extends v{poolsData=new Map([]);getPoolType(){return"Stableswap"}getPoolAddress(t){let e=f.getPoolAddress(t),i=fs(e,{dkLen:32}),s=ys(i);return hs(Os).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(){let t=this.api.query.Stableswap.Pools,e=await this.api.compatibilityToken;return t.isCompatible(Ps.BackwardsCompatible,e)}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:Is}),this.poolsData.set(r,n),{address:o,id:r,type:"Stableswap",fee:ws.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,"best").pipe(Lt((s,a)=>({value:s,index:a})),ce(({index:s,value:a})=>{s>0&&this.log.trace("tokens.TotalIssuance",i,a)}),Lt(({value:s})=>({id:i,value:s}))));return xs(...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(vs((t,e)=>!e.deltas),Lt((t,e)=>({value:t,index:e})),ce(({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 Ss;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 me={};B(me,{XykMath:()=>L,XykPool:()=>nt,XykPoolClient:()=>rt});import{calculate_in_given_out as Ts,calculate_out_given_in as Bs,calculate_pool_trade_fee as As,get_spot_price as Fs,calculate_liquidity_in as _s,calculate_shares as ks,calculate_spot_price as Rs,calculate_spot_price_with_fee as Es,calculate_liquidity_out_asset_a as Cs,calculate_liquidity_out_asset_b as Ls}from"@galacticcouncil/math-xyk";var L=class{static getSpotPrice(t,e,i){return Fs(t,e,i)}static calculateInGivenOut(t,e,i){return Ts(t,e,i)}static calculateOutGivenIn(t,e,i){return Bs(t,e,i)}static calculatePoolTradeFee(t,e,i){return As(t,e,i)}static calculateLiquidityIn(t,e,i){return _s(t,e,i)}static calculateSpotPrice(t,e){return Rs(t,e)}static calculateSpotPriceWithFee(t,e,i,s){return Es(t,e,i,s)}static calculateShares(t,e,i){return ks(t,e,i)}static calculateLiquidityOutAssetA(t,e,i,s){return Cs(t,e,i,s)}static calculateLiquidityOutAssetB(t,e,i,s){return Ls(t,e,i,s)}};import{big as Ms}from"@galacticcouncil/common";var{FeeUtils:pe}=P,nt=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=pe.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=pe.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=Ms.pow10(Math.abs(s));return s>0?t*a:t/a}};import{CompatibilityLevel as Ds}from"polkadot-api";import{Subscription as Hs}from"rxjs";var rt=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(){let t=this.api.query.XYK.PoolAssets,e=await this.api.compatibilityToken;return t.isCompatible(Ds.BackwardsCompatible,e)}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 Hs.EMPTY}};var ye={};B(ye,{AavePool:()=>ot,AavePoolClient:()=>lt});import{big as de,RUNTIME_DECIMALS as ge}from"@galacticcouncil/common";var ot=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 de.toBigInt(1,ge)}spotPriceOutGivenIn(t){return de.toBigInt(1,ge)}calculateTradeFee(t,e){return 0n}};import{AccountId as Gs}from"polkadot-api";import{toHex as qs}from"@polkadot-api/utils";import{Subscription as he,filter as Mt,map as Pe}from"rxjs";import{decodeEventLog as Ns}from"viem";import{erc20 as Vs,HYDRATION_SS58_PREFIX as Ws}from"@galacticcouncil/common";var be=[{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:$s}=Vs,Us=["Supply","Withdraw","Repay","Borrow"],lt=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=qs(s);return Gs(Ws).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.asHex()}throw new Error("Invalid aave reserve multilocation")}return $s.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.map(n=>n.asHex()),a=i.asHex();try{let{eventName:n,args:r}=Ns({abi:be,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(Pe(({payload:i})=>this.parseRouterLog(i)),Mt(({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(Pe(({payload:t})=>this.parseEvmLog(t)),Mt(t=>t!==void 0),Mt(({eventName:t})=>Us.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 he.EMPTY}subscribeUpdates(){let t=new he;return t.add(this.subscribeRouterExecuted()),t.add(this.subscribeEvmLog()),t}};var ve={};B(ve,{HsmMath:()=>I,HsmPool:()=>ct,HsmPoolClient:()=>mt});import{calculate_collateral_in_given_hollar_out as Ys,calculate_collateral_out_given_hollar_in as Xs,calculate_hollar_in_given_collateral_out as zs,calculate_hollar_out_given_collateral_in as Ks,calculate_imbalance as js,calculate_max_price as Qs,calculate_buyback_limit as Js,calculate_buyback_price_with_fee as Zs}from"@galacticcouncil/math-hsm";var I=class{static calculateCollateralInGivenHollarOut(t,e,i){return Ys(t,e,i)}static calculateCollateralOutGivenHollarIn(t,e,i){return Xs(t,e,i)}static calculateHollarOutGivenCollateralIn(t,e,i){return Ks(t,e,i)}static calculateHollarInGivenCollateralOut(t,e,i){return zs(t,e,i)}static calculateImbalance(t,e,i){return js(t,e,i)}static calculateBuybackLimit(t,e){return Js(t,e)}static calculateBuybackPriceWithFee(t,e,i){return Zs(t,e,i)}static calculateMaxPrice(t,e){return Qs(t,e)}};import{big as M,RUNTIME_DECIMALS as wt}from"@galacticcouncil/common";var{FeeUtils:Y}=P,ct=class u extends G{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=I.calculateHollarInGivenCollateralOut(e.toString(),i.toString(),Y.toRaw(this.buyBackFee).toString());return BigInt(s)}calculateCollateralInGivenHollarOut(t){let e=this.getCollateralPeg(),i=I.calculateCollateralInGivenHollarOut(t.toString(),JSON.stringify(e),Y.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=I.calculateCollateralOutGivenHollarIn(e.toString(),i.toString(),Y.toRaw(this.buyBackFee).toString());return BigInt(s)}calculateHollarOutGivenCollateralIn(t){let e=this.getCollateralPeg(),i=I.calculateHollarOutGivenCollateralIn(t.toString(),JSON.stringify(e),Y.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=I.calculateImbalance(t.balanceIn.toString(),JSON.stringify(e),t.balanceOut.toString());return BigInt(i)}calculateBuybackLimit(t){let e=this.calculateImbalance(t),i=I.calculateBuybackLimit(e.toString(),Y.toRaw(this.buyBackRate).toString());return BigInt(i)}calculateBuyPrice(t,e,i){let s=I.calculateBuybackPriceWithFee(i.toString(),e.toString(),Y.toRaw(this.buyBackFee).toString()),[a,n]=JSON.parse(s),r=M.pow10(t.decimalsIn+wt-t.decimalsOut);return BigInt(a)*r/BigInt(n)}calculateMaxPrice(t){let e=this.getCollateralPeg(),i=I.calculateMaxPrice(JSON.stringify(e),this.maxBuyPriceCoefficient.toString()),[s,a]=JSON.parse(i),n=M.pow10(wt-t.decimalsOut);return BigInt(s)*n/BigInt(a)}spotPriceInGivenOut(t){let e=M.toBigInt(1,t.decimalsOut),s=this.calculateInGivenOut(t,e)*M.pow10(wt-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(wt-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 ta,CompatibilityLevel as ea}from"polkadot-api";import{toHex as ia}from"@polkadot-api/utils";import{Subscription as Dt,combineLatest as sa,filter as fe,map as Ht,pairwise as aa}from"rxjs";import{decodeEventLog as na}from"viem";import{h160 as ra,HYDRATION_SS58_PREFIX as oa}from"@galacticcouncil/common";var ut=[{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 pt=class{client;constructor(t){this.client=t.getWsProvider()}async getFacilitatorCapacity(t,e){let[i,s]=await this.client.readContract({abi:ut,address:t,functionName:"getFacilitatorBucket",args:[e]});return i-s}};var{FeeUtils:Gt}=P,{H160:Se}=ra,la=["FacilitatorBucketCapacityUpdated","FacilitatorBucketLevelUpdated"],mt=class extends v{ghoClient;stableClient;constructor(t,e,i){super(t,e),this.stableClient=i,this.ghoClient=new pt(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.asHex()}}throw Error("Invalid hollar multilocation")}getPoolAddress(t){let e=t.padEnd(32,"\0"),i=new TextEncoder().encode(e),s=ia(i);return ta(oa).dec(s)}async isSupported(){let t=this.api.query.HSM.Collaterals,e=await this.api.compatibilityToken;return t.isCompatible(ea.BackwardsCompatible,e)}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=Se.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,O=s.find(R=>R.id===d);if(O){let R=this.getPoolId(d),z=await this.balance.getBalance(a,g);return{...O,address:R,type:"HSM",tokens:O.tokens.filter(xe=>xe.id!==d),hsmAddress:a,hsmMintCapacity:o,hollarId:t,hollarH160:r,collateralId:g,collateralBalance:z.transferable,maxBuyPriceCoefficient:S,maxInHolding:_,purchaseFee:Gt.fromPermill(k),buyBackFee:Gt.fromPermill(x),buyBackRate:Gt.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.map(n=>n.asHex()),a=i.asHex();try{let{eventName:n,args:r}=na({abi:ut,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(Ht(({payload:t})=>this.parseEvmLog(t)),fe(t=>t!==void 0),fe(({eventName:t})=>la.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=Se.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?sa(s).pipe(Ht(a=>a.flat()),aa(),Ht(([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})}):Dt.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 Dt.EMPTY}subscribeUpdates(){let t=new Dt;return t.add(this.subscribeCollateralBalance()),t.add(this.subscribeStableswapUpdates()),t.add(this.subscribeEvmLog()),t}};var qt=class{static get(t){switch(t.type){case"Aave":return ot.fromPool(t);case"XYK":return nt.fromPool(t);case"Omnipool":return et.fromPool(t);case"LBP":return j.fromPool(t);case"Stableswap":return G.fromPool(t);case"HSM":return ct.fromPool(t);default:throw new Error("Pool type "+t.type+" is not supported yet")}}};import{log as ca}from"@galacticcouncil/common";import{Subject as ua,Subscription as X,takeUntil as pa}from"rxjs";var Tt=class extends Error{constructor(t){super(),this.message=`${t} pool invalid`,this.name="PoolNotFound"}};var{logger:ma}=ca,Nt=class extends A{evm;aave;omnipool;stableswap;hsm;xyk;lbp;active=new Set([]);pools=new Map([]);clients=[];aaveSub=X.EMPTY;omniSub=X.EMPTY;stableSub=X.EMPTY;hsmSub=X.EMPTY;xykSub=X.EMPTY;lbpSub=X.EMPTY;isReady=!1;isDestroyed=new ua;constructor(t,e){super(t),this.evm=e,this.aave=new lt(t,e),this.omnipool=new st(t,e),this.stableswap=new at(t,e),this.hsm=new mt(t,e,this.stableswap),this.xyk=new rt(t,e),this.lbp=new tt(t,e),this.clients=[this.aave,this.omnipool,this.stableswap,this.hsm,this.xyk,this.lbp]}subscribe(t){return t.getSubscriber().pipe(pa(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")||(ma.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 Tt(e.type)}};export{Nt as PoolContextProvider,H as PoolError,qt as PoolFactory,y as PoolType,ye as aave,ve as hsm,se as lbp,oe as omni,ue as stable,me as xyk};
|
|
1
|
+
var Ie=Object.defineProperty;var B=(u,t)=>{for(var e in t)Ie(u,e,{get:t[e],enumerable:!0})};import Oe from"buffer";typeof window<"u"&&(window.Buffer=Oe.Buffer);var se={};B(se,{LbpMath:()=>T,LbpPool:()=>j,LbpPoolClient:()=>it});import{calculate_in_given_out as we,calculate_out_given_in as Te,calculate_linear_weights as Be,calculate_pool_trade_fee as Ae,get_spot_price as Fe}from"@galacticcouncil/math-lbp";var T=class{static getSpotPrice(t,e,i,s,a){return Fe(t,e,i,s,a)}static calculateInGivenOut(t,e,i,s,a){return we(t,e,i,s,a)}static calculateOutGivenIn(t,e,i,s,a){return Te(t,e,i,s,a)}static calculateLinearWeights(t,e,i,s,a){return Be(t,e,i,s,a)}static calculatePoolTradeFee(t,e,i){return Ae(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={};B(bt,{withTimeout:()=>_e});function _e(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 Ia}from"@galacticcouncil/common";var P={};B(P,{FeeUtils:()=>Bt,shiftNeg:()=>Ce});import Ee 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 Ce(u,t){let e=Ee(typeof u=="bigint"?u.toString():u);return t===0?e.toString():e.div(Math.pow(10,t)).toString()}var K={};B(K,{findNestedKey:()=>Le,findNestedObj:()=>Me,jsonFormatter:()=>De});var Le=(u,t)=>{let e=[];return JSON.stringify(u,(i,s)=>(s&&s[t]&&e.push(s),s)),e[0]},Me=(u,t,e)=>{let i;return JSON.stringify(u,(s,a)=>(a&&a[t]===e&&(i=a),a)),i},De=(u,t)=>typeof t=="bigint"?t.toString():t;var D={};B(D,{calculateBuyFee:()=>Ne,calculateDiffToAvg:()=>He,calculateDiffToRef:()=>Ge,calculateSellFee:()=>qe});import E from"big.js";function He(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 Ge(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 qe(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 Ne(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,j=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 _i}from"polkadot-api";import{Subscription as ki,distinctUntilChanged as Ri,filter as Ei}from"rxjs";import{memoize1 as bi}from"@thi.ng/memoize";import{TLRUCache as hi}from"@thi.ng/cache";import{ReplaySubject as te,Subscription as ee,combineLatest as Pi,defer as yi,from as fi,interval as Si,merge as Ft,of as vi,EMPTY as tt}from"rxjs";import{bufferCount as xi,bufferTime as Ii,catchError as et,filter as xt,finalize as _t,map as W,pairwise as kt,repeat as Rt,skip as Oi,share as wi,startWith as Ti,switchMap as ie,tap as G,throttleTime as Bi}from"rxjs/operators";import{hydration as ii,hydrationNext as si}from"@galacticcouncil/descriptors";import{log as Je}from"@galacticcouncil/common";import{shareReplay as Ze,tap as ti}from"rxjs";import{defer as Ve,from as We,of as Xt,timer as $e}from"rxjs";import{catchError as Ue,distinctUntilChanged as Ye,expand as Xe,map as At,shareReplay as ze,skip as Ke,switchMap as je,timeout as Qe}from"rxjs/operators";function zt(u,{intervalMs:t=5e3,rpcTimeoutMs:e=1e4}={}){let i=()=>Ve(()=>We(u._request("system_health",[]))).pipe(Qe({first:e}),At(()=>"online"),Ue(()=>Xt("offline")));return Xt({state:"offline",delayMs:0}).pipe(Xe(a=>$e(a.delayMs).pipe(je(i),At(n=>({state:n,delayMs:t})))),Ke(1),At(a=>a.state),Ye(),ze({bufferSize:1,refCount:!0}))}var{logger:ei}=Je,yt=class u{static instance=null;bestBlock$;finalizedBlock$;connection$;constructor(t){this.bestBlock$=this.watched("watcher(bestBlock)",t.getUnsafeApi().query.System.Number.watchValue("best")),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(ti({error:i=>ei.error(t,i)}),Ze({bufferSize:1,refCount:!0}))}};var A=class{client;api;apiNext;watcher;constructor(t){this.client=t,this.api=this.client.getTypedApi(ii),this.apiNext=this.client.getTypedApi(si),this.watcher=yt.getInstance(this.client)}};import{getWsProvider as hn}from"polkadot-api/ws-provider";import{withLogsRecorder as yn}from"polkadot-api/logs-provider";import{withLegacy as Sn}from"@polkadot-api/legacy-provider";import{getSmProvider as On}from"polkadot-api/sm-provider";import{log as ai}from"@galacticcouncil/common";import{combineLatest as ni,concat as ri,defer as Q,from as Kt}from"rxjs";import{bufferCount as jt,distinctUntilChanged as Qt,debounceTime as oi,map as N,retry as li,startWith as Jt,switchMap as Zt,tap as J,take as ci,skip as ui,connect as pi}from"rxjs/operators";var{logger:V}=ai,Z=class extends A{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 Q(()=>{let e=this.watchSystemBalance(t),i=this.watchTokensBalance(t),s=this.watchErc20Balance(t);return ni([e,i,s]).pipe(pi(a=>ri(a.pipe(ci(1)),a.pipe(ui(1),oi(250)))))}).pipe(N(e=>e.flat()),Jt([]),jt(2,1),N(([e,i],s)=>s===0?i:this.getDeltas(e,i))).pipe(J({subscribe:()=>V.debug("balance: subscribe",t),error:e=>V.error("balance",e)}),li({delay:1e3}))}watchSystemBalance(t){let e=this.api.query.System.Account;return Q(()=>e.watchValue(t,"best")).pipe(N(i=>({id:0,balance:this.getBreakdown(i.data)})),J({error:i=>V.error("balance(system)",i)}))}watchTokenBalance(t,e){let i=this.api.query.Tokens.Accounts;return Q(()=>i.watchValue(t,e,"best")).pipe(N(s=>({id:e,balance:this.getBreakdown(s)})),J({error:s=>V.error("balance(token)",s)}))}watchTokensBalance(t){let e=this.api.query.Tokens.Accounts;return Q(()=>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}),J({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 Q(()=>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),J({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 mi}from"rxjs";var ft=class{store$=new mi([]);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 di}from"@galacticcouncil/common";var gi={Aave:"AAVE",LBP:"LBP",Omnipool:"OMNI",Stableswap:"STBL",XYK:"XYK",HSM:"HSM"},{logger:St}=di,vt=class{type;constructor(t){this.type=t}prefix(){return this.pad(`pool(${gi[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:Ai}=bt,Fi=3e3,v=class extends A{evm;balance;store=new ft;log;shared$;resync$=new te(1);resyncAt=0;resyncPending=!1;mem=0;memPoolsCache=new hi(null,{ttl:6*1e3});memPools=bi(t=>(this.log.info("pool_sync",{mem:t}),this.loadPools()),this.memPoolsCache);constructor(t,e){super(t),this.evm=e,this.balance=new Z(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(Ti([]),xi(2,1),W(([t,e])=>t.length===0?e:this.store.applyChangeset(e)),xt(t=>t.length>0),Bi(1e3,void 0,{leading:!0,trailing:!0}))}subscribeStore(){return yi(()=>{let t=new ee;return t.add(this.startWatchdog()),this.resync$.next(),this.resync$.pipe(ie(()=>{let e=new ee;return fi(Ai(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)),et(()=>(this.log.error("pool_seed_error",{mem:this.mem}),this.requestResync(),tt))).pipe(G(()=>{e.add(this.subscribeBalances()),e.add(this.subscribeUpdates())}),ie(s=>Ft(vi(s),this.store.asObservable().pipe(Oi(1)))),_t(()=>{e.unsubscribe()}))}),_t(()=>t.unsubscribe()))}).pipe(wi({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 Pi(s).pipe(W(a=>a.flat()),kt(),W(([a,n])=>this.balance.getDeltas(a,n)),xt(a=>a.length>0),W(a=>[i,a]))});return Ft(...t).pipe(Ii(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<Fi||(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(kt(),xt(([r,o])=>r==="offline"&&o==="online"),G(()=>{this.log.debug("watchdog_recover_online",{mem:this.mem}),this.requestResync()}),et(r=>(this.log.error("watchdog_recovery_error",r),tt)),Rt({delay:1e3})),a=this.watcher.finalizedBlock$.pipe(kt(),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())}),et(r=>(this.log.error("watchdog_gap_error",r),tt)),Rt({delay:1e3})),n=Si(36e5).pipe(G(()=>{this.log.debug("watchdog_periodic",{mem:this.mem}),this.requestResync()}),et(r=>(this.log.error("watchdog_periodic_error",r),tt)),Rt({delay:1e3}));return Ft(s,a,n).subscribe()}watchGuard(t){return e=>e.pipe(G({error:i=>{this.log.error(t,i),this.requestResync(!0)}}),_t(()=>{this.log.debug(t,"unsub")}),et(()=>tt))}};var it=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(){let t=this.api.query.LBP.PoolData,e=await this.api.compatibilityToken;return t.isCompatible(_i.BackwardsCompatible,e)}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("best").pipe(Ei(t=>t!==void 0),Ri((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 ki;return t.add(this.subscribeValidationData()),t}};var oe={};B(oe,{OmniMath:()=>b,OmniPool:()=>st,OmniPoolClient:()=>nt});import{calculate_in_given_out as Ci,calculate_lrna_in_given_out as Li,calculate_out_given_in as Mi,calculate_out_given_lrna_in as Di,calculate_spot_price as Hi,calculate_lrna_spot_price as Gi,calculate_shares as qi,calculate_liquidity_out as Ni,calculate_liquidity_lrna_out as Vi,verify_asset_cap as Wi,calculate_liquidity_hub_in as $i,is_sell_allowed as Ui,is_buy_allowed as Yi,is_add_liquidity_allowed as Xi,is_remove_liquidity_allowed as zi,recalculate_asset_fee as Ki,recalculate_protocol_fee as ji}from"@galacticcouncil/math-omnipool";import $ from"big.js";var b=class{static calculateSpotPrice(t,e,i,s){return Hi(t,e,i,s)}static calculateLrnaSpotPrice(t,e){return Gi(t,e)}static calculateInGivenOut(t,e,i,s,a,n,r,o,l,c){return Ci(t,e,i,s,a,n,r,o,l,c)}static calculateLrnaInGivenOut(t,e,i,s,a,n){return Li(t,e,i,s,a,n)}static calculateOutGivenIn(t,e,i,s,a,n,r,o,l,c){return Mi(t,e,i,s,a,n,r,o,l,c)}static calculateOutGivenLrnaIn(t,e,i,s,a,n){return Di(t,e,i,s,a,n)}static calculateShares(t,e,i,s){return qi(t,e,i,s)}static calculateLiquidityOut(t,e,i,s,a,n,r,o){return Ni(t,e,i,s,a,n,r,o)}static calculateLiquidityLRNAOut(t,e,i,s,a,n,r,o){return Vi(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 $i(t,e,i,s)}static isSellAllowed(t){return Ui(t)}static isBuyAllowed(t){return Yi(t)}static isAddLiquidityAllowed(t){return Xi(t)}static isRemoveLiquidityAllowed(t){return zi(t)}static recalculateAssetFee(t,e,i,s,a,n,r,o,l,c,p){return Ki(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 ji(t,e,i,s,a,n,r,o,l,c,p)}static verifyAssetCap(t,e,i,s){return Wi(t,e,i,s)}};import{big as Qi}from"@galacticcouncil/common";var{FeeUtils:F}=P,st=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=Qi.pow10(Math.abs(s));return s>0?t*a:t/a}};import{AccountId as Ji,Binary as Zi,CompatibilityLevel as ae,Enum as ts}from"polkadot-api";import{toHex as es}from"@polkadot-api/utils";import{Subscription as is,distinctUntilChanged as Ct,filter as ss,finalize as Lt,map as at,merge as as,tap as It}from"rxjs";import{HYDRATION_SS58_PREFIX as ns}from"@galacticcouncil/common";var{FeeUtils:h}=P,ne=Zi.fromText("omnipool"),re=ts("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(ne,t,re,{at:"best"}),t=>t.join(":"),6*1e3);getPoolType(){return"Omnipool"}getPoolAddress(){let t="modlomnipool".padEnd(32,"\0"),e=new TextEncoder().encode(t),i=es(e);return Ji(ns).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(){let t=this.api.query.Omnipool.Assets,e=await this.api.compatibilityToken;return t.isCompatible(ae.BackwardsCompatible,e)}async isSlipFeeSupported(){return this.apiNext.query.Omnipool.SlipFee.isCompatible(ae.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),z=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(z)*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),z=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(z)*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(ne,s,re,"best").pipe(ss(a=>a!==void 0),at((a,n)=>({value:a,index:n})),It(({index:a})=>{a>0&&this.log.trace("emaOracle.Oracles",s.join(":"))}),at(({value:a})=>({pair:s,value:a}))));return as(...i).pipe(Lt(()=>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(Ct((t,e)=>!e.deltas),at((t,e)=>({value:t,index:e})),It(({value:t,index:e})=>{e>0&&this.log.trace("dynamicFees.AssetFee",t.deltas?.upserted)}),Lt(()=>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(Ct((t,e)=>!e.deltas),at((t,e)=>({value:t,index:e})),It(({value:t,index:e})=>{e>0&&this.log.trace("dynamicFees.AssetFeeConfiguration",t.deltas?.upserted)}),Lt(()=>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(Ct((t,e)=>!e.deltas),at((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 is;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 ue={};B(ue,{StableMath:()=>f,StableSwap:()=>q,StableSwapClient:()=>rt});import{calculate_in_given_out as rs,calculate_out_given_in as os,calculate_amplification as ls,calculate_add_one_asset as cs,calculate_liquidity_out_one_asset as us,calculate_shares as ps,calculate_shares_for_amount as ms,calculate_spot_price_with_fee as ds,pool_account_name as gs,recalculate_peg as bs}from"@galacticcouncil/math-stableswap";var f=class{static getPoolAddress(t){return gs(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 ls(t,e,i,s,a)}static calculateInGivenOut(t,e,i,s,a,n,r){return rs(t,e,i,s,a,n,r)}static calculateAddOneAsset(t,e,i,s,a,n,r){return cs(t,e,i,s,a,n,r)}static calculateSharesForAmount(t,e,i,s,a,n,r){return ms(t,e,i,s,a,n,r)}static calculateOutGivenIn(t,e,i,s,a,n,r){return os(t,e,i,s,a,n,r)}static calculateLiquidityOutOneAsset(t,e,i,s,a,n,r){return us(t,e,i,s,a,n,r)}static calculateShares(t,e,i,s,a,n){return ps(t,e,i,s,a,n)}static calculateSpotPriceWithFee(t,e,i,s,a,n,r,o){return ds(t,e,i,s,a,n,r,o)}static recalculatePegs(t,e,i,s,a,n){let r=bs(t,e,i,s,a,n);return JSON.parse(r)}};import{RUNTIME_DECIMALS as hs,big as le}from"@galacticcouncil/common";var{FeeUtils:U}=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?U.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?U.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?U.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?U.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?U.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?U.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,K.jsonFormatter)}getAssets(t,e){let i={asset_id:Number(t),amount:e.toString()};return JSON.stringify([i],K.jsonFormatter)}normalizeSpot(t,e,i,s,a){return e?t*le.pow10(hs-a):i?t/le.pow10(a-s):t}};import{AccountId as Ps,CompatibilityLevel as ys}from"polkadot-api";import{toHex as fs}from"@polkadot-api/utils";import{blake2b as Ss}from"@noble/hashes/blake2b";import{Subscription as vs,distinctUntilChanged as xs,map as Mt,merge as Is,tap as ce}from"rxjs";import{HYDRATION_SS58_PREFIX as Os,RUNTIME_DECIMALS as ws}from"@galacticcouncil/common";var{FeeUtils:Ts}=P,rt=class extends v{poolsData=new Map([]);getPoolType(){return"Stableswap"}getPoolAddress(t){let e=f.getPoolAddress(t),i=Ss(e,{dkLen:32}),s=fs(i);return Ps(Os).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(){let t=this.api.query.Stableswap.Pools,e=await this.api.compatibilityToken;return t.isCompatible(ys.BackwardsCompatible,e)}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:ws}),this.poolsData.set(r,n),{address:o,id:r,type:"Stableswap",fee:Ts.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,"best").pipe(Mt((s,a)=>({value:s,index:a})),ce(({index:s,value:a})=>{s>0&&this.log.trace("tokens.TotalIssuance",i,a)}),Mt(({value:s})=>({id:i,value:s}))));return Is(...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(xs((t,e)=>!e.deltas),Mt((t,e)=>({value:t,index:e})),ce(({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 vs;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 me={};B(me,{XykMath:()=>L,XykPool:()=>ot,XykPoolClient:()=>lt});import{calculate_in_given_out as Bs,calculate_out_given_in as As,calculate_pool_trade_fee as Fs,get_spot_price as _s,calculate_liquidity_in as ks,calculate_shares as Rs,calculate_spot_price as Es,calculate_spot_price_with_fee as Cs,calculate_liquidity_out_asset_a as Ls,calculate_liquidity_out_asset_b as Ms}from"@galacticcouncil/math-xyk";var L=class{static getSpotPrice(t,e,i){return _s(t,e,i)}static calculateInGivenOut(t,e,i){return Bs(t,e,i)}static calculateOutGivenIn(t,e,i){return As(t,e,i)}static calculatePoolTradeFee(t,e,i){return Fs(t,e,i)}static calculateLiquidityIn(t,e,i){return ks(t,e,i)}static calculateSpotPrice(t,e){return Es(t,e)}static calculateSpotPriceWithFee(t,e,i,s){return Cs(t,e,i,s)}static calculateShares(t,e,i){return Rs(t,e,i)}static calculateLiquidityOutAssetA(t,e,i,s){return Ls(t,e,i,s)}static calculateLiquidityOutAssetB(t,e,i,s){return Ms(t,e,i,s)}};import{big as Ds}from"@galacticcouncil/common";var{FeeUtils:pe}=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=pe.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=pe.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=Ds.pow10(Math.abs(s));return s>0?t*a:t/a}};import{CompatibilityLevel as Hs}from"polkadot-api";import{Subscription as Gs}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(){let t=this.api.query.XYK.PoolAssets,e=await this.api.compatibilityToken;return t.isCompatible(Hs.BackwardsCompatible,e)}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 Gs.EMPTY}};var ye={};B(ye,{AavePool:()=>ct,AavePoolClient:()=>ut});import{big as de,RUNTIME_DECIMALS as ge}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 de.toBigInt(1,ge)}spotPriceOutGivenIn(t){return de.toBigInt(1,ge)}calculateTradeFee(t,e){return 0n}};import{AccountId as qs}from"polkadot-api";import{toHex as Ns}from"@polkadot-api/utils";import{Subscription as he,filter as Dt,map as Pe}from"rxjs";import{decodeEventLog as Vs}from"viem";import{erc20 as Ws,HYDRATION_SS58_PREFIX as $s}from"@galacticcouncil/common";var be=[{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:Us}=Ws,Ys=["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=Ns(s);return qs($s).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.asHex()}throw new Error("Invalid aave reserve multilocation")}return Us.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.map(n=>n.asHex()),a=i.asHex();try{let{eventName:n,args:r}=Vs({abi:be,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(Pe(({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(Pe(({payload:t})=>this.parseEvmLog(t)),Dt(t=>t!==void 0),Dt(({eventName:t})=>Ys.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 he.EMPTY}subscribeUpdates(){let t=new he;return t.add(this.subscribeRouterExecuted()),t.add(this.subscribeEvmLog()),t}};var ve={};B(ve,{HsmMath:()=>O,HsmPool:()=>pt,HsmPoolClient:()=>gt});import{calculate_collateral_in_given_hollar_out as Xs,calculate_collateral_out_given_hollar_in as zs,calculate_hollar_in_given_collateral_out as Ks,calculate_hollar_out_given_collateral_in as js,calculate_imbalance as Qs,calculate_max_price as Js,calculate_buyback_limit as Zs,calculate_buyback_price_with_fee as ta}from"@galacticcouncil/math-hsm";var O=class{static calculateCollateralInGivenHollarOut(t,e,i){return Xs(t,e,i)}static calculateCollateralOutGivenHollarIn(t,e,i){return zs(t,e,i)}static calculateHollarOutGivenCollateralIn(t,e,i){return js(t,e,i)}static calculateHollarInGivenCollateralOut(t,e,i){return Ks(t,e,i)}static calculateImbalance(t,e,i){return Qs(t,e,i)}static calculateBuybackLimit(t,e){return Zs(t,e)}static calculateBuybackPriceWithFee(t,e,i){return ta(t,e,i)}static calculateMaxPrice(t,e){return Js(t,e)}};import{big as M,RUNTIME_DECIMALS as wt}from"@galacticcouncil/common";var{FeeUtils:Y}=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(),Y.toRaw(this.buyBackFee).toString());return BigInt(s)}calculateCollateralInGivenHollarOut(t){let e=this.getCollateralPeg(),i=O.calculateCollateralInGivenHollarOut(t.toString(),JSON.stringify(e),Y.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(),Y.toRaw(this.buyBackFee).toString());return BigInt(s)}calculateHollarOutGivenCollateralIn(t){let e=this.getCollateralPeg(),i=O.calculateHollarOutGivenCollateralIn(t.toString(),JSON.stringify(e),Y.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(),Y.toRaw(this.buyBackRate).toString());return BigInt(i)}calculateBuyPrice(t,e,i){let s=O.calculateBuybackPriceWithFee(i.toString(),e.toString(),Y.toRaw(this.buyBackFee).toString()),[a,n]=JSON.parse(s),r=M.pow10(t.decimalsIn+wt-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(wt-t.decimalsOut);return BigInt(s)*n/BigInt(a)}spotPriceInGivenOut(t){let e=M.toBigInt(1,t.decimalsOut),s=this.calculateInGivenOut(t,e)*M.pow10(wt-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(wt-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 ea,CompatibilityLevel as ia}from"polkadot-api";import{toHex as sa}from"@polkadot-api/utils";import{Subscription as Ht,combineLatest as aa,filter as fe,map as Gt,pairwise as na}from"rxjs";import{decodeEventLog as ra}from"viem";import{h160 as oa,HYDRATION_SS58_PREFIX as la}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:Se}=oa,ca=["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.asHex()}}throw Error("Invalid hollar multilocation")}getPoolAddress(t){let e=t.padEnd(32,"\0"),i=new TextEncoder().encode(e),s=sa(i);return ea(la).dec(s)}async isSupported(){let t=this.api.query.HSM.Collaterals,e=await this.api.compatibilityToken;return t.isCompatible(ia.BackwardsCompatible,e)}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=Se.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),z=await this.balance.getBalance(a,g);return{...I,address:R,type:"HSM",tokens:I.tokens.filter(xe=>xe.id!==d),hsmAddress:a,hsmMintCapacity:o,hollarId:t,hollarH160:r,collateralId:g,collateralBalance:z.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.map(n=>n.asHex()),a=i.asHex();try{let{eventName:n,args:r}=ra({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(Gt(({payload:t})=>this.parseEvmLog(t)),fe(t=>t!==void 0),fe(({eventName:t})=>ca.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=Se.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?aa(s).pipe(Gt(a=>a.flat()),na(),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 st.fromPool(t);case"LBP":return j.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 ua}from"@galacticcouncil/common";import{Subject as pa,Subscription as X,takeUntil as ma}from"rxjs";var Tt=class extends Error{constructor(t){super(),this.message=`${t} pool invalid`,this.name="PoolNotFound"}};var{logger:da}=ua,Vt=class extends A{evm;aave;omnipool;stableswap;hsm;xyk;lbp;active=new Set([]);pools=new Map([]);clients=[];aaveSub=X.EMPTY;omniSub=X.EMPTY;stableSub=X.EMPTY;hsmSub=X.EMPTY;xykSub=X.EMPTY;lbpSub=X.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 it(t,e),this.clients=[this.aave,this.omnipool,this.stableswap,this.hsm,this.xyk,this.lbp]}subscribe(t){return t.getSubscriber().pipe(ma(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")||(da.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 Tt(e.type)}};export{Vt as PoolContextProvider,H as PoolError,Nt as PoolFactory,y as PoolType,ye as aave,ve as hsm,se as lbp,oe as omni,ue as stable,me as xyk};
|
package/build/sor/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var Se=Object.create;var yt=Object.defineProperty;var Ie=Object.getOwnPropertyDescriptor;var we=Object.getOwnPropertyNames;var Oe=Object.getPrototypeOf,Te=Object.prototype.hasOwnProperty;var Q=(c,t)=>{for(var e in t)yt(c,e,{get:t[e],enumerable:!0})},zt=(c,t,e,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let a of we(t))!Te.call(c,a)&&a!==e&&yt(c,a,{get:()=>t[a],enumerable:!(s=Ie(t,a))||s.enumerable});return c};var _t=(c,t,e)=>(e=c!=null?Se(Oe(c)):{},zt(t||!c||!c.__esModule?yt(e,"default",{value:c,enumerable:!0}):e,c)),ve=c=>zt(yt({},"__esModule",{value:!0}),c);var ps={};Q(ps,{DCA_TIME_RESERVE:()=>ge,DEFAULT_BLOCK_TIME:()=>de,DEFAULT_MIN_BUDGET:()=>Wt,ORDER_MIN_BLOCK_PERIOD:()=>be,Router:()=>nt,TWAP_EXECUTION_INTERVAL:()=>Pt,TWAP_MAX_DURATION:()=>$t,TWAP_MAX_PRICE_IMPACT:()=>Ut,TWAP_TX_MULTIPLIER:()=>nl,TradeOrderError:()=>Vt,TradeOrderType:()=>Gt,TradeRouteBuilder:()=>V,TradeRouter:()=>rt,TradeScheduler:()=>Ft,TradeType:()=>Nt});module.exports=ve(ps);var ot=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 xe=10,lt=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 ot,n=[];for(n.push([e,""]),i.enqueue(n);i.size()>0;){let r=i.dequeue();if(!r||r.length>xe)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 ot,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 Rt(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 J=require("@galacticcouncil/common");var ft={};Q(ft,{withTimeout:()=>Be});function Be(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={};Q(C,{divSpot:()=>Fe,getFraction:()=>_e,mulScaled:()=>Kt,mulSpot:()=>Ae});var Et=require("@galacticcouncil/common");function Kt(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 Ae(c,t,e,s){return Kt(c,t,e,Et.RUNTIME_DECIMALS,s)}function Fe(c,t,e,s){if(t===0n)return 0n;let a=BigInt(10)**BigInt(Et.RUNTIME_DECIMALS+s-e);return c*a/t}function _e(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={};Q(w,{FeeUtils:()=>kt,shiftNeg:()=>Ee});var Qt=_t(require("big.js"));var kt=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 Ee(c,t){let e=(0,Qt.default)(typeof c=="bigint"?c.toString():c);return t===0?e.toString():e.div(Math.pow(10,t)).toString()}var ct={};Q(ct,{findNestedKey:()=>ke,findNestedObj:()=>Ce,jsonFormatter:()=>Me});var ke=(c,t)=>{let e=[];return JSON.stringify(c,(s,a)=>(a&&a[t]&&e.push(a),a)),e[0]},Ce=(c,t,e)=>{let s;return JSON.stringify(c,(a,i)=>(i&&i[t]===e&&(s=i),i)),s},Me=(c,t)=>typeof t=="bigint"?t.toString():t;var A={};Q(A,{calculateBuyFee:()=>qe,calculateDiffToAvg:()=>Le,calculateDiffToRef:()=>De,calculateSellFee:()=>He});var q=_t(require("big.js"));function Le(c,t){let e=(0,q.default)(c.toString()),s=(0,q.default)(t.toString());return e.minus(s).abs().div(e.plus(s).div(2)).mul(100).round(2).toNumber()}function De(c,t){if(t===0n)return 0;let e=(0,q.default)(c.toString()),s=(0,q.default)(t.toString());return e.minus(s).div(s).mul(100).round(2).toNumber()}function He(c,t){if(c===0n)return 0;let e=(0,q.default)(c.toString()),s=(0,q.default)(t.toString());return(0,q.default)(1).minus(s.div(e)).mul(100).round(2).toNumber()}function qe(c,t){if(c===0n)return 0;let e=(0,q.default)(c.toString());return(0,q.default)(t.toString()).div(e).minus(1).mul(100).round(2).toNumber()}var{FeeUtils:Jt}=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=Jt.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=Jt.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(),J.big.toBigInt(1,J.RUNTIME_DECIMALS).toString());return BigInt(e)}spotPriceOutGivenIn(t){let e=G.getSpotPrice(t.balanceIn.toString(),t.balanceOut.toString(),t.weightIn.toString(),t.weightOut.toString(),J.big.toBigInt(1,J.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"),Ct=require("rxjs");var $=require("rxjs"),R=require("rxjs/operators");var ee=require("@galacticcouncil/descriptors");var Zt=require("@galacticcouncil/common"),te=require("rxjs");var It=require("rxjs"),U=require("rxjs/operators");var{logger:Gs}=Zt.log;var Ne=require("polkadot-api/ws-provider"),Ge=require("polkadot-api/logs-provider"),Ve=require("@polkadot-api/legacy-provider");var We=require("polkadot-api/sm-provider");var se=require("@galacticcouncil/common"),Ot=require("rxjs"),M=require("rxjs/operators");var{logger:na}=se.log;var $e=require("rxjs");var ae=require("@galacticcouncil/common");var ya={Aave:"AAVE",LBP:"LBP",Omnipool:"OMNI",Stableswap:"STBL",XYK:"XYK",HSM:"HSM"},{logger:fa}=ae.log;var{withTimeout:Ma}=ft;var b=require("@galacticcouncil/math-omnipool"),z=_t(require("big.js")),I=class{static calculateSpotPrice(t,e,s,a){return(0,b.calculate_spot_price)(t,e,s,a)}static calculateLrnaSpotPrice(t,e){return(0,b.calculate_lrna_spot_price)(t,e)}static calculateInGivenOut(t,e,s,a,i,n,r,o,l,u){return(0,b.calculate_in_given_out)(t,e,s,a,i,n,r,o,l,u)}static calculateLrnaInGivenOut(t,e,s,a,i,n){return(0,b.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,b.calculate_out_given_in)(t,e,s,a,i,n,r,o,l,u)}static calculateOutGivenLrnaIn(t,e,s,a,i,n){return(0,b.calculate_out_given_lrna_in)(t,e,s,a,i,n)}static calculateShares(t,e,s,a){return(0,b.calculate_shares)(t,e,s,a)}static calculateLiquidityOut(t,e,s,a,i,n,r,o){return(0,b.calculate_liquidity_out)(t,e,s,a,i,n,r,o)}static calculateLiquidityLRNAOut(t,e,s,a,i,n,r,o){return(0,b.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 h=u.times(r).minus(i).times(n),d=i.times((0,z.default)(1).minus(u));return h.div(d).toFixed(0)}else return"0"}static calculateLimitHubIn(t,e,s,a){return(0,b.calculate_liquidity_hub_in)(t,e,s,a)}static isSellAllowed(t){return(0,b.is_sell_allowed)(t)}static isBuyAllowed(t){return(0,b.is_buy_allowed)(t)}static isAddLiquidityAllowed(t){return(0,b.is_add_liquidity_allowed)(t)}static isRemoveLiquidityAllowed(t){return(0,b.is_remove_liquidity_allowed)(t)}static recalculateAssetFee(t,e,s,a,i,n,r,o,l,u,m){return(0,b.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,b.recalculate_protocol_fee)(t,e,s,a,i,n,r,o,l,u,m)}static verifyAssetCap(t,e,s,a){return(0,b.verify_asset_cap)(t,e,s,a)}};var ie=require("@galacticcouncil/common");var{FeeUtils:N}=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?N.toRaw(s.assetFee).toString():"0",s?N.toRaw(s.protocolFee).toString():"0",s?N.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?N.toRaw(s.assetFee).toString():"0",s?N.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?N.toRaw(s.assetFee).toString():"0",s?N.toRaw(s.protocolFee).toString():"0",s?N.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?N.toRaw(s.assetFee).toString():"0",s?N.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=ie.big.pow10(Math.abs(a));return a>0?t*i:t/i}};var tt=require("polkadot-api"),ze=require("@polkadot-api/utils"),K=require("rxjs"),Ke=require("@galacticcouncil/common");var{FeeUtils:Pi}=w,yi=tt.Binary.fromText("omnipool"),fi=(0,tt.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 mt=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,ct.jsonFormatter)}getAssets(t,e){let s={asset_id:Number(t),amount:e.toString()};return JSON.stringify([s],ct.jsonFormatter)}normalizeSpot(t,e,s,a,i){return e?t*mt.big.pow10(mt.RUNTIME_DECIMALS-i):s?t/mt.big.pow10(i-a):t}};var ne=require("polkadot-api"),Qe=require("@polkadot-api/utils"),Je=require("@noble/hashes/blake2b"),dt=require("rxjs"),re=require("@galacticcouncil/common");var{FeeUtils:ji}=w;var T=require("@galacticcouncil/math-xyk"),X=class{static getSpotPrice(t,e,s){return(0,T.get_spot_price)(t,e,s)}static calculateInGivenOut(t,e,s){return(0,T.calculate_in_given_out)(t,e,s)}static calculateOutGivenIn(t,e,s){return(0,T.calculate_out_given_in)(t,e,s)}static calculatePoolTradeFee(t,e,s){return(0,T.calculate_pool_trade_fee)(t,e,s)}static calculateLiquidityIn(t,e,s){return(0,T.calculate_liquidity_in)(t,e,s)}static calculateSpotPrice(t,e){return(0,T.calculate_spot_price)(t,e)}static calculateSpotPriceWithFee(t,e,s,a){return(0,T.calculate_spot_price_with_fee)(t,e,s,a)}static calculateShares(t,e,s){return(0,T.calculate_shares)(t,e,s)}static calculateLiquidityOutAssetA(t,e,s,a){return(0,T.calculate_liquidity_out_asset_a)(t,e,s,a)}static calculateLiquidityOutAssetB(t,e,s,a){return(0,T.calculate_liquidity_out_asset_b)(t,e,s,a)}};var le=require("@galacticcouncil/common");var{FeeUtils:oe}=w,vt=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=oe.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=oe.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=le.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 xt=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 as=require("polkadot-api"),is=require("@polkadot-api/utils"),Lt=require("rxjs"),ns=require("viem"),Dt=require("@galacticcouncil/common");var{ERC20:$n}=Dt.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,Bt=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 ue=require("polkadot-api"),ls=require("@polkadot-api/utils"),gt=require("rxjs"),cs=require("viem"),Ht=require("@galacticcouncil/common");var{FeeUtils:Ir}=w,{H160:wr}=Ht.h160;var bt=class{static get(t){switch(t.type){case"Aave":return xt.fromPool(t);case"XYK":return vt.fromPool(t);case"Omnipool":return Tt.fromPool(t);case"LBP":return St.fromPool(t);case"Stableswap":return st.fromPool(t);case"HSM":return Bt.fromPool(t);default:throw new Error("Pool type "+t.type+" is not supported yet")}}};var pe=require("@galacticcouncil/common"),qt=require("rxjs");var At=class extends Error{constructor(t,e){super(),this.message=`Route from ${t} to ${e} not found in current configuration`,this.name="RouteNotFound"}};var{logger:uo}=pe.log;var ht=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 lt,u=p=>{let y=Rt(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,h=a.filter(p=>p.tokens.some(y=>y.id===m));if(h.length===0)return[];let d=[...i,...h],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 nt=class{routeSuggester;routeProposals;ctx;filter={};constructor(t){this.ctx=t,this.routeSuggester=new ht,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,bt.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 Nt=(e=>(e.Buy="Buy",e.Sell="Sell",e))(Nt||{}),Gt=(s=>(s.Dca="Dca",s.TwapSell="TwapSell",s.TwapBuy="TwapBuy",s))(Gt||{}),Vt=(s=>(s.OrderTooSmall="OrderTooSmall",s.OrderTooBig="OrderTooBig",s.OrderImpactTooBig="OrderImpactTooBig",s))(Vt||{});var{FeeUtils:me}=w,rt=class extends nt{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 At(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?me.toPct(t.min):void 0,a=t.max?me.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),h=C.mulSpot(s.amountIn,n,s.assetInDecimals,a.assetOutDecimals),d=A.calculateDiffToRef(o,h);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:h,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(h,y);a.push({...n,assetInDecimals:o.decimalsIn,assetOutDecimals:o.decimalsOut,amountIn:l,amountOut:m,calculatedOut:h,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(h,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),h=C.mulSpot(s.amountOut,n,s.assetOutDecimals,a.assetInDecimals),d;return o===0n?d=-100:d=A.calculateDiffToRef(h,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:h,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;h===0n?f=-100:f=A.calculateDiffToRef(y,h),a.unshift({...n,assetInDecimals:o.decimalsIn,assetOutDecimals:o.decimalsOut,amountOut:l,amountIn:m,calculatedIn:h,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(h,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 de=6e3,Wt=1000000000000000n,Pt=6,Ut=-5,$t=216e5,nl=3,ge=.1,be=6;var Xt=require("polkadot-api");var V=class{static build(t){return t.map(({assetIn:e,assetOut:s,pool:a,poolId:i})=>a==="Stableswap"?{pool:(0,Xt.Enum)("Stableswap",i),asset_in:e,asset_out:s}:{pool:(0,Xt.Enum)(a),asset_in:e,asset_out:s})}};var Ft=class{schedulerOptions;router;constructor(t,e={}){this.router=new rt(t),this.router.withFilter({exclude:["HSM"]}),this.schedulerOptions=Object.freeze({blockTime:e.blockTime??6e3,minBudgetInNative:e.minBudgetInNative??Wt})}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:h}=u,{assetOutDecimals:d}=m,S=Math.abs(l),g=await this.getMinimumOrderBudget(t,h),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,j=[];Y&&j.push("OrderTooSmall");let W=_.amountOut*BigInt(f),Pe=this.toBlockPeriod(D),ye=_.tradeFee*BigInt(f),fe=V.build(o),Yt={assetIn:t,assetOut:e,errors:j,maxTradeCount:y,tradeCount:f,tradeFee:ye,tradeImpactPct:_.priceImpactPct,tradePeriod:Pe,tradeRoute:fe,type:"Dca"};return{...Yt,amountIn:r,amountOut:W,tradeAmountIn:_.amountIn,tradeAmountOut:_.amountOut,toHuman(){return{...Yt,amountIn:x.big.toDecimal(r,h),amountOut:x.big.toDecimal(W,d),tradeAmountIn:x.big.toDecimal(_.amountIn,h),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),h=i.amountIn<m,d=[];h&&d.push("OrderTooSmall");let S=this.toBlockPeriod(a),g=V.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,h=Math.abs(r),d=this.getTwapTradeCount(h),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),j=V.build(n),W={assetIn:t,assetOut:e,errors:E,tradeCount:d,tradeImpactPct:p.priceImpactPct,tradePeriod:6,tradeRoute:j,type:"TwapSell"};return{...W,amountIn:i,amountOut:_,tradeAmountIn:p.amountIn,tradeAmountOut:p.amountOut,tradeFee:Y,toHuman(){return{...W,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,h=Math.abs(r),d=this.getTwapTradeCount(h),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),j=V.build(n),W={assetIn:t,assetOut:e,errors:_,tradeCount:d,tradeImpactPct:p.priceImpactPct,tradePeriod:6,tradeRoute:j,type:"TwapBuy"};return{...W,amountIn:y,amountOut:i,tradeAmountIn:p.amountIn,tradeAmountOut:p.amountOut,tradeFee:Y,toHuman(){return{...W,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 Se=Object.create;var yt=Object.defineProperty;var Ie=Object.getOwnPropertyDescriptor;var we=Object.getOwnPropertyNames;var Oe=Object.getPrototypeOf,Te=Object.prototype.hasOwnProperty;var Q=(c,t)=>{for(var e in t)yt(c,e,{get:t[e],enumerable:!0})},zt=(c,t,e,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let a of we(t))!Te.call(c,a)&&a!==e&&yt(c,a,{get:()=>t[a],enumerable:!(s=Ie(t,a))||s.enumerable});return c};var _t=(c,t,e)=>(e=c!=null?Se(Oe(c)):{},zt(t||!c||!c.__esModule?yt(e,"default",{value:c,enumerable:!0}):e,c)),ve=c=>zt(yt({},"__esModule",{value:!0}),c);var ps={};Q(ps,{DCA_TIME_RESERVE:()=>ge,DEFAULT_BLOCK_TIME:()=>de,DEFAULT_MIN_BUDGET:()=>Wt,ORDER_MIN_BLOCK_PERIOD:()=>he,Router:()=>nt,TWAP_EXECUTION_INTERVAL:()=>Pt,TWAP_MAX_DURATION:()=>$t,TWAP_MAX_PRICE_IMPACT:()=>Ut,TWAP_TX_MULTIPLIER:()=>nl,TradeOrderError:()=>Vt,TradeOrderType:()=>Gt,TradeRouteBuilder:()=>W,TradeRouter:()=>rt,TradeScheduler:()=>Ft,TradeType:()=>Nt});module.exports=ve(ps);var ot=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 xe=10,lt=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 ot,n=[];for(n.push([e,""]),i.enqueue(n);i.size()>0;){let r=i.dequeue();if(!r||r.length>xe)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 ot,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 Rt(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 J=require("@galacticcouncil/common");var ft={};Q(ft,{withTimeout:()=>Be});function Be(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={};Q(C,{divSpot:()=>Fe,getFraction:()=>_e,mulScaled:()=>Kt,mulSpot:()=>Ae});var Et=require("@galacticcouncil/common");function Kt(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 Ae(c,t,e,s){return Kt(c,t,e,Et.RUNTIME_DECIMALS,s)}function Fe(c,t,e,s){if(t===0n)return 0n;let a=BigInt(10)**BigInt(Et.RUNTIME_DECIMALS+s-e);return c*a/t}function _e(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={};Q(w,{FeeUtils:()=>kt,shiftNeg:()=>Ee});var Qt=_t(require("big.js"));var kt=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 Ee(c,t){let e=(0,Qt.default)(typeof c=="bigint"?c.toString():c);return t===0?e.toString():e.div(Math.pow(10,t)).toString()}var ct={};Q(ct,{findNestedKey:()=>ke,findNestedObj:()=>Ce,jsonFormatter:()=>Me});var ke=(c,t)=>{let e=[];return JSON.stringify(c,(s,a)=>(a&&a[t]&&e.push(a),a)),e[0]},Ce=(c,t,e)=>{let s;return JSON.stringify(c,(a,i)=>(i&&i[t]===e&&(s=i),i)),s},Me=(c,t)=>typeof t=="bigint"?t.toString():t;var A={};Q(A,{calculateBuyFee:()=>qe,calculateDiffToAvg:()=>Le,calculateDiffToRef:()=>De,calculateSellFee:()=>He});var q=_t(require("big.js"));function Le(c,t){let e=(0,q.default)(c.toString()),s=(0,q.default)(t.toString());return e.minus(s).abs().div(e.plus(s).div(2)).mul(100).round(2).toNumber()}function De(c,t){if(t===0n)return 0;let e=(0,q.default)(c.toString()),s=(0,q.default)(t.toString());return e.minus(s).div(s).mul(100).round(2).toNumber()}function He(c,t){if(c===0n)return 0;let e=(0,q.default)(c.toString()),s=(0,q.default)(t.toString());return(0,q.default)(1).minus(s.div(e)).mul(100).round(2).toNumber()}function qe(c,t){if(c===0n)return 0;let e=(0,q.default)(c.toString());return(0,q.default)(t.toString()).div(e).minus(1).mul(100).round(2).toNumber()}var{FeeUtils:Jt}=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=Jt.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=Jt.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(),J.big.toBigInt(1,J.RUNTIME_DECIMALS).toString());return BigInt(e)}spotPriceOutGivenIn(t){let e=G.getSpotPrice(t.balanceIn.toString(),t.balanceOut.toString(),t.weightIn.toString(),t.weightOut.toString(),J.big.toBigInt(1,J.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"),Ct=require("rxjs");var V=require("rxjs"),R=require("rxjs/operators");var ee=require("@galacticcouncil/descriptors");var Zt=require("@galacticcouncil/common"),te=require("rxjs");var It=require("rxjs"),$=require("rxjs/operators");var{logger:Gs}=Zt.log;var Ne=require("polkadot-api/ws-provider"),Ge=require("polkadot-api/logs-provider"),Ve=require("@polkadot-api/legacy-provider");var We=require("polkadot-api/sm-provider");var se=require("@galacticcouncil/common"),Ot=require("rxjs"),M=require("rxjs/operators");var{logger:na}=se.log;var $e=require("rxjs");var ae=require("@galacticcouncil/common");var ya={Aave:"AAVE",LBP:"LBP",Omnipool:"OMNI",Stableswap:"STBL",XYK:"XYK",HSM:"HSM"},{logger:fa}=ae.log;var{withTimeout:Ma}=ft;var h=require("@galacticcouncil/math-omnipool"),z=_t(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 ie=require("@galacticcouncil/common");var{FeeUtils:N}=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?N.toRaw(s.assetFee).toString():"0",s?N.toRaw(s.protocolFee).toString():"0",s?N.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?N.toRaw(s.assetFee).toString():"0",s?N.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?N.toRaw(s.assetFee).toString():"0",s?N.toRaw(s.protocolFee).toString():"0",s?N.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?N.toRaw(s.assetFee).toString():"0",s?N.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=ie.big.pow10(Math.abs(a));return a>0?t*i:t/i}};var tt=require("polkadot-api"),ze=require("@polkadot-api/utils"),K=require("rxjs"),Ke=require("@galacticcouncil/common");var{FeeUtils:Pi}=w,yi=tt.Binary.fromText("omnipool"),fi=(0,tt.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 mt=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,ct.jsonFormatter)}getAssets(t,e){let s={asset_id:Number(t),amount:e.toString()};return JSON.stringify([s],ct.jsonFormatter)}normalizeSpot(t,e,s,a,i){return e?t*mt.big.pow10(mt.RUNTIME_DECIMALS-i):s?t/mt.big.pow10(i-a):t}};var ne=require("polkadot-api"),Qe=require("@polkadot-api/utils"),Je=require("@noble/hashes/blake2b"),dt=require("rxjs"),re=require("@galacticcouncil/common");var{FeeUtils:ji}=w;var T=require("@galacticcouncil/math-xyk"),X=class{static getSpotPrice(t,e,s){return(0,T.get_spot_price)(t,e,s)}static calculateInGivenOut(t,e,s){return(0,T.calculate_in_given_out)(t,e,s)}static calculateOutGivenIn(t,e,s){return(0,T.calculate_out_given_in)(t,e,s)}static calculatePoolTradeFee(t,e,s){return(0,T.calculate_pool_trade_fee)(t,e,s)}static calculateLiquidityIn(t,e,s){return(0,T.calculate_liquidity_in)(t,e,s)}static calculateSpotPrice(t,e){return(0,T.calculate_spot_price)(t,e)}static calculateSpotPriceWithFee(t,e,s,a){return(0,T.calculate_spot_price_with_fee)(t,e,s,a)}static calculateShares(t,e,s){return(0,T.calculate_shares)(t,e,s)}static calculateLiquidityOutAssetA(t,e,s,a){return(0,T.calculate_liquidity_out_asset_a)(t,e,s,a)}static calculateLiquidityOutAssetB(t,e,s,a){return(0,T.calculate_liquidity_out_asset_b)(t,e,s,a)}};var le=require("@galacticcouncil/common");var{FeeUtils:oe}=w,vt=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=oe.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=oe.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=le.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 xt=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 as=require("polkadot-api"),is=require("@polkadot-api/utils"),Lt=require("rxjs"),ns=require("viem"),Dt=require("@galacticcouncil/common");var{ERC20:$n}=Dt.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,Bt=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 ue=require("polkadot-api"),ls=require("@polkadot-api/utils"),gt=require("rxjs"),cs=require("viem"),Ht=require("@galacticcouncil/common");var{FeeUtils:Ir}=w,{H160:wr}=Ht.h160;var ht=class{static get(t){switch(t.type){case"Aave":return xt.fromPool(t);case"XYK":return vt.fromPool(t);case"Omnipool":return Tt.fromPool(t);case"LBP":return St.fromPool(t);case"Stableswap":return st.fromPool(t);case"HSM":return Bt.fromPool(t);default:throw new Error("Pool type "+t.type+" is not supported yet")}}};var pe=require("@galacticcouncil/common"),qt=require("rxjs");var At=class extends Error{constructor(t,e){super(),this.message=`Route from ${t} to ${e} not found in current configuration`,this.name="RouteNotFound"}};var{logger:uo}=pe.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 lt,u=p=>{let y=Rt(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 nt=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 Nt=(e=>(e.Buy="Buy",e.Sell="Sell",e))(Nt||{}),Gt=(s=>(s.Dca="Dca",s.TwapSell="TwapSell",s.TwapBuy="TwapBuy",s))(Gt||{}),Vt=(s=>(s.OrderTooSmall="OrderTooSmall",s.OrderTooBig="OrderTooBig",s.OrderImpactTooBig="OrderImpactTooBig",s))(Vt||{});var{FeeUtils:me}=w,rt=class extends nt{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 At(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?me.toPct(t.min):void 0,a=t.max?me.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 de=6e3,Wt=1000000000000000n,Pt=6,Ut=-5,$t=216e5,nl=3,ge=.1,he=6;var Xt=require("polkadot-api");var W=class{static build(t){return t.map(({assetIn:e,assetOut:s,pool:a,poolId:i})=>a==="Stableswap"?{pool:(0,Xt.Enum)("Stableswap",i),asset_in:e,asset_out:s}:{pool:(0,Xt.Enum)(a),asset_in:e,asset_out:s})}};var Ft=class{schedulerOptions;router;constructor(t,e={}){this.router=new rt(t),this.router.withFilter({exclude:["HSM"]}),this.schedulerOptions=Object.freeze({blockTime:e.blockTime??6e3,minBudgetInNative:e.minBudgetInNative??Wt})}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,j=[];Y&&j.push("OrderTooSmall");let U=_.amountOut*BigInt(f),Pe=this.toBlockPeriod(D),ye=_.tradeFee*BigInt(f),fe=W.build(o),Yt={assetIn:t,assetOut:e,errors:j,maxTradeCount:y,tradeCount:f,tradeFee:ye,tradeImpactPct:_.priceImpactPct,tradePeriod:Pe,tradeRoute:fe,type:"Dca"};return{...Yt,amountIn:r,amountOut:U,tradeAmountIn:_.amountIn,tradeAmountOut:_.amountOut,toHuman(){return{...Yt,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),j=W.build(n),U={assetIn:t,assetOut:e,errors:E,tradeCount:d,tradeImpactPct:p.priceImpactPct,tradePeriod:6,tradeRoute:j,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),j=W.build(n),U={assetIn:t,assetOut:e,errors:_,tradeCount:d,tradeImpactPct:p.priceImpactPct,tradePeriod:6,tradeRoute:j,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});
|