@galacticcouncil/sdk-next 1.3.0 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- var $t=Object.defineProperty;var F=(u,e)=>{for(var t in e)$t(u,t,{get:e[t],enumerable:!0})};import Wt from"buffer";typeof window<"u"&&(window.Buffer=Wt.Buffer);var yt={};F(yt,{LbpMath:()=>O,LbpPool:()=>se,LbpPoolClient:()=>ue});import{calculate_in_given_out as Yt,calculate_out_given_in as Xt,calculate_linear_weights as Kt,calculate_pool_trade_fee as zt,get_spot_price as jt}from"@galacticcouncil/math-lbp";var O=class{static getSpotPrice(e,t,a,i,s){return jt(e,t,a,i,s)}static calculateInGivenOut(e,t,a,i,s){return Yt(e,t,a,i,s)}static calculateOutGivenIn(e,t,a,i,s){return Xt(e,t,a,i,s)}static calculateLinearWeights(e,t,a,i,s){return Kt(e,t,a,i,s)}static calculatePoolTradeFee(e,t,a){return zt(e,t,a)}};import{big as st,RUNTIME_DECIMALS as nt}from"@galacticcouncil/common";var f=(n=>(n.Aave="Aave",n.LBP="LBP",n.Omni="Omnipool",n.Stable="Stableswap",n.XYK="XYK",n.HSM="HSM",n))(f||{}),H=(l=>(l.UnknownError="UnknownError",l.FacilitatorCapacityExceeded="FacilitatorCapacityExceeded",l.InsufficientTradingAmount="InsufficientTradingAmount",l.InsufficientCollateral="InsufficientCollateral",l.MaxHoldingExceeded="MaxHoldingExceeded",l.MaxInRatioExceeded="MaxInRatioExceeded",l.MaxOutRatioExceeded="MaxOutRatioExceeded",l.TradeNotAllowed="TradeNotAllowed",l.MaxBuyBackExceeded="MaxBuyBackExceeded",l.MaxBuyPriceExceeded="MaxBuyPriceExceeded",l))(H||{});var xe={};F(xe,{withTimeout:()=>Qt});function Qt(u,e,t="timeout"){return new Promise((a,i)=>{let s=setTimeout(()=>i(new Error(t)),e);u.then(n=>{clearTimeout(s),a(n)},n=>{clearTimeout(s),i(n)})})}import{RUNTIME_DECIMALS as en}from"@galacticcouncil/common";var y={};F(y,{FeeUtils:()=>He,shiftNeg:()=>ta});import ea from"big.js";var He=class u{static toPct(e){let[t,a]=e;return u.safeDivide(t*100,a)}static toRaw(e){let[t,a]=e;return u.safeDivide(t,a)}static fromPermill(e){return[e,1e6]}static fromPerbill(e){return[e,1e9]}static fromRate(e,t){return[e,t]}static safeDivide(e,t,a=12){let i=10**a;return Math.round(e*i/t)/i}static safeRound(e){return parseFloat(e.toPrecision(15))}};function ta(u,e){let t=ea(typeof u=="bigint"?u.toString():u);return e===0?t.toString():t.div(Math.pow(10,e)).toString()}var ie={};F(ie,{findNestedKey:()=>aa,findNestedObj:()=>ia,jsonFormatter:()=>sa});var aa=(u,e)=>{let t=[];return JSON.stringify(u,(a,i)=>(i&&i[e]&&t.push(i),i)),t[0]},ia=(u,e,t)=>{let a;return JSON.stringify(u,(i,s)=>(s&&s[e]===t&&(a=s),s)),a},sa=(u,e)=>typeof e=="bigint"?e.toString():e;var L={};F(L,{calculateBuyFee:()=>la,calculateDiffToAvg:()=>na,calculateDiffToRef:()=>ra,calculateSellFee:()=>oa});import k from"big.js";function na(u,e){let t=k(u.toString()),a=k(e.toString());return t.minus(a).abs().div(t.plus(a).div(2)).mul(100).round(2).toNumber()}function ra(u,e){if(e===0n)return 0;let t=k(u.toString()),a=k(e.toString());return t.minus(a).div(a).mul(100).round(2).toNumber()}function oa(u,e){if(u===0n)return 0;let t=k(u.toString()),a=k(e.toString());return k(1).minus(a.div(t)).mul(100).round(2).toNumber()}function la(u,e){if(u===0n)return 0;let t=k(u.toString());return k(e.toString()).div(t).minus(1).mul(100).round(2).toNumber()}import{TLRUCache as it}from"@thi.ng/cache";var $=class{debug;constructor(e){this.debug=e||!1}log(e,t,a){this.debug&&console.log(e,t,a)}scope(e,t,a,i){let s=new Map,n=i!==void 0?new it(null,{ttl:i}):new it;return{get:(...l)=>{let p=a(...l);if(s.has(p)){this.log("[live]",e,p);let d=s.get(p);return Promise.resolve(d)}if(n.has(p))return this.log("[memo]",e,p),n.get(p);this.log("[fetch]",e,p);let m=t(...l).catch(d=>{throw n.delete(p),d});return n.set(p,m),m},set:(l,...p)=>{let m=a(...p);this.log("[set-live]",e,m),s.set(m,l)},clear:()=>{this.log("[clear]",e),s.clear(),n.release()}}}};var{FeeUtils:rt}=y,se=class u{type;address;tokens;maxInRatio;maxOutRatio;minTradingLimit;fee;repayFeeApply;static fromPool(e){return new u(e)}constructor(e){this.type="LBP",this.address=e.address,this.tokens=e.tokens,this.maxInRatio=e.maxInRatio,this.maxOutRatio=e.maxOutRatio,this.minTradingLimit=e.minTradingLimit,this.fee=e.fee,this.repayFeeApply=e.repayFeeApply}validatePair(e,t){return!0}parsePair(e,t){let a=new Map(this.tokens.map(n=>[n.id,n])),i=a.get(e),s=a.get(t);if(i==null)throw new Error("Pool does not contain tokenIn");if(s==null)throw new Error("Pool does not contain tokenOut");return{assetIn:e,assetOut:t,balanceIn:i.balance,balanceOut:s.balance,decimalsIn:i.decimals,decimalsOut:s.decimals,weightIn:i.weight,weightOut:s.weight}}validateAndBuy(e,t,a){let i=this.tokens[0].id,s=[];t<this.minTradingLimit&&s.push("InsufficientTradingAmount");let n=e.balanceOut/this.maxOutRatio;if(t>n&&s.push("MaxOutRatioExceeded"),i===e.assetOut){let r=this.calculateTradeFee(t,a),o=rt.toPct(this.repayFeeApply?a.repayFee:a.exchangeFee),c=t+r,l=this.calculateInGivenOut(e,c),p=e.balanceIn/this.maxInRatio;return l>p&&s.push("MaxInRatioExceeded"),{amountIn:l,calculatedIn:l,amountOut:t,feePct:o,errors:s}}else{let r=this.calculateInGivenOut(e,t),o=e.balanceIn/this.maxInRatio;return r>o&&s.push("MaxInRatioExceeded"),{amountIn:r,calculatedIn:r,amountOut:t,feePct:0,errors:s}}}validateAndSell(e,t,a){let i=this.tokens[0].id,s=[];t<this.minTradingLimit&&s.push("InsufficientTradingAmount");let n=e.balanceIn/this.maxInRatio;if(t>n&&s.push("MaxInRatioExceeded"),i===e.assetIn){let r=this.calculateOutGivenIn(e,t),o=e.balanceOut/this.maxOutRatio;return r>o&&s.push("MaxOutRatioExceeded"),{amountIn:t,calculatedOut:r,amountOut:r,feePct:0,errors:s}}else{let r=this.calculateOutGivenIn(e,t),o=this.calculateTradeFee(r,a),c=rt.toPct(this.repayFeeApply?a.repayFee:a.exchangeFee),l=r-o,p=e.balanceOut/this.maxOutRatio;return l>p&&s.push("MaxOutRatioExceeded"),{amountIn:t,calculatedOut:r,amountOut:l,feePct:c,errors:s}}}calculateInGivenOut(e,t){let a=O.calculateInGivenOut(e.balanceIn.toString(),e.balanceOut.toString(),e.weightIn.toString(),e.weightOut.toString(),t.toString()),i=BigInt(a);return i<0n?0n:i}calculateOutGivenIn(e,t){let a=O.calculateOutGivenIn(e.balanceIn.toString(),e.balanceOut.toString(),e.weightIn.toString(),e.weightOut.toString(),t.toString()),i=BigInt(a);return i<0n?0n:i}spotPriceInGivenOut(e){let t=O.getSpotPrice(e.balanceOut.toString(),e.balanceIn.toString(),e.weightOut.toString(),e.weightIn.toString(),st.toBigInt(1,nt).toString());return BigInt(t)}spotPriceOutGivenIn(e){let t=O.getSpotPrice(e.balanceIn.toString(),e.balanceOut.toString(),e.weightIn.toString(),e.weightOut.toString(),st.toBigInt(1,nt).toString());return BigInt(t)}calculateTradeFee(e,t){let a=O.calculatePoolTradeFee(e.toString(),this.repayFeeApply?t.repayFee[0]:t.exchangeFee[0],this.repayFeeApply?t.repayFee[1]:t.exchangeFee[1]);return BigInt(a)}};import{CompatibilityLevel as Za}from"polkadot-api";import{Subscription as ei,distinctUntilChanged as ti,filter as ai,map as ii}from"rxjs";import{memoize1 as Ha}from"@thi.ng/memoize";import{TLRUCache as Na}from"@thi.ng/cache";import{ReplaySubject as gt,Subscription as bt,combineLatest as qa,defer as Ga,from as Va,interval as Ua,merge as qe,of as $a,EMPTY as le}from"rxjs";import{bufferCount as Wa,bufferTime as Ya,catchError as ce,filter as Be,finalize as Ge,map as X,pairwise as Ve,repeat as Ue,skip as Xa,share as Ka,startWith as za,switchMap as ht,tap as N,throttleTime as ja}from"rxjs/operators";import{hydration as Aa,hydrationNext as Ia,hydrationIce as wa}from"@galacticcouncil/descriptors";import{log as Pa}from"@galacticcouncil/common";import{map as va,shareReplay as Sa,tap as Ta}from"rxjs";import{defer as ca,from as ua,of as ot,timer as pa}from"rxjs";import{catchError as ma,distinctUntilChanged as da,expand as ga,map as Ne,shareReplay as ba,skip as ha,switchMap as ya,timeout as fa}from"rxjs/operators";function lt(u,{intervalMs:e=5e3,rpcTimeoutMs:t=1e4}={}){let a=()=>ca(()=>ua(u._request("system_health",[]))).pipe(fa({first:t}),Ne(()=>"online"),ma(()=>ot("offline")));return ot({state:"offline",delayMs:0}).pipe(ga(s=>pa(s.delayMs).pipe(ya(a),Ne(n=>({state:n,delayMs:e})))),ha(1),Ne(s=>s.state),da(),ba({bufferSize:1,refCount:!0}))}var{logger:xa}=Pa,Ae=class u{static instance=null;bestBlock$;finalizedBlock$;connection$;constructor(e){this.bestBlock$=this.watched("watcher(bestBlock)",e.getUnsafeApi().query.System.Number.watchValue({at:"best"}).pipe(va(({value:t})=>t))),this.finalizedBlock$=this.watched("watcher(finalizedBlock)",e.finalizedBlock$),this.connection$=this.watched("watcher(connection)",lt(e))}static getInstance(e){return this.instance||(this.instance=new u(e)),this.instance}watched(e,t){return t.pipe(Ta({error:a=>xa.error(e,a)}),Sa({bufferSize:1,refCount:!0}))}};var _=class{client;api;apiNext;apiIce;watcher;at;constructor(e,t){this.client=e,this.api=this.client.getTypedApi(Aa),this.apiNext=this.client.getTypedApi(Ia),this.apiIce=this.client.getTypedApi(wa),this.watcher=Ae.getInstance(this.client),this.at=t??"best"}};import{getWsProvider as Xn}from"polkadot-api/ws";import{withLogsRecorder as zn}from"polkadot-api/logs-provider";import{Binary as ur}from"polkadot-api";import{log as Oa}from"@galacticcouncil/common";import{combineLatest as Ba,concat as Fa,defer as ne,from as ct}from"rxjs";import{bufferCount as ut,distinctUntilChanged as pt,debounceTime as _a,map as W,retry as Ea,startWith as mt,switchMap as dt,tap as re,take as Ra,skip as ka,connect as Ca}from"rxjs/operators";var{logger:Y}=Oa,oe=class extends _{erc20Ids=null;constructor(e,t){super(e,t)}async getBalance(e,t){return t===0?this.getSystemBalance(e):this.getBalanceData(e,t)}async getSystemBalance(e){let t=this.api.query.System.Account,{data:a}=await t.getValue(e,{at:this.at});return this.getBreakdown(a)}async getTokenBalance(e,t){let i=await this.api.query.Tokens.Accounts.getValue(e,t,{at:this.at});return this.getBreakdown(i)}async getErc20Balance(e,t){return this.getBalanceData(e,t)}watchBalance(e){return ne(()=>{let t=this.watchSystemBalance(e),a=this.watchTokensBalance(e),i=this.watchErc20Balance(e);return Ba([t,a,i]).pipe(Ca(s=>Fa(s.pipe(Ra(1)),s.pipe(ka(1),_a(250)))))}).pipe(W(t=>t.flat()),mt([]),ut(2,1),W(([t,a],i)=>i===0?a:this.getDeltas(t,a))).pipe(re({subscribe:()=>Y.debug("balance: subscribe",e),error:t=>Y.error("balance",t)}),Ea({delay:1e3}))}watchSystemBalance(e){let t=this.api.query.System.Account;return ne(()=>t.watchValue(e,{at:"best"})).pipe(W(({value:a})=>({id:0,balance:this.getBreakdown(a.data)})),re({error:a=>Y.error("balance(system)",a)}))}watchTokenBalance(e,t){let a=this.api.query.Tokens.Accounts;return ne(()=>a.watchValue(e,t,{at:"best"})).pipe(W(({value:i})=>({id:t,balance:this.getBreakdown(i)})),re({error:i=>Y.error("balance(token)",i)}))}watchTokensBalance(e){let t=this.api.query.Tokens.Accounts;return ne(()=>t.watchEntries(e,{at:"best"})).pipe(pt((a,i)=>!i.deltas),W(({deltas:a})=>{let i=[];return a?.deleted.forEach(s=>{let[n,r]=s.args;i.push({id:r,balance:this.getBreakdown({free:0n,reserved:0n,frozen:0n})})}),a?.upserted.forEach(s=>{let[n,r]=s.args;i.push({id:r,balance:this.getBreakdown(s.value)})}),i}),re({error:a=>Y.error("balance(tokens)",a)}))}watchErc20Balance(e,t){let a=async()=>{if(this.erc20Ids)return this.erc20Ids;let s=await this.api.query.AssetRegistry.Assets.getEntries({at:"best"});return this.erc20Ids=s.filter(({value:n})=>n.asset_type.type==="Erc20").map(({keyArgs:n})=>{let[r]=n;return r}),this.erc20Ids},i=async s=>(await Promise.all(s.map(async r=>[r,await this.getBalanceData(e,r)]))).map(([r,o])=>({id:r,balance:o}));return ne(()=>ct(t?Promise.resolve(t):a()).pipe(dt(s=>this.watcher.bestBlock$.pipe(dt(()=>ct(i(s))))),mt([]),ut(2,1),W(([s,n],r)=>r===0?n.filter(o=>o.balance.total>0n):this.getDeltas(s,n)),pt((s,n)=>n.length===0),re({error:s=>Y.error("balance(erc20)",s)})))}async getBalanceData(e,t){let a=await this.api.apis.CurrenciesApi.account(t,e,{at:this.at});return this.getBreakdown(a)}getBreakdown(e){let t=e.free>=e.frozen?e.free-e.frozen:0n,a=e.free+e.reserved;return{free:e.free,reserved:e.reserved,frozen:e.frozen,total:a,transferable:t}}getDeltas(e,t){let a=(s,n)=>s!==void 0&&n!==void 0&&s.transferable===n.transferable&&s.total===n.total,i=e.reduce((s,n)=>(s.set(n.id,n.balance),s),new Map);return t.filter(s=>!a(s.balance,i.get(s.id)))}};import{BehaviorSubject as Ma}from"rxjs";var Ie=class{store$=new Ma([]);updateQueue=Promise.resolve();changeset=new Set;get pools(){return this.store$.value}asObservable(){return this.store$.asObservable()}applyChangeset(e){return this.changeset.size===0?[]:e.filter(t=>this.changeset.has(t.address))}set(e){this.changeset=new Set(e.map(t=>t.address)),this.store$.next(e)}update(e){this.updateQueue=this.updateQueue.then(async()=>{let t=this.store$.value,a=new Map(t.map((r,o)=>[r.address,o])),i=await e(t),s=t.slice(),n=new Set;for(let r of i){let o=a.get(r.address);o===void 0?(a.set(r.address,s.length),s.push(r)):s[o]=r,n.add(r.address)}this.changeset=n,this.store$.next(s)}).catch(console.error)}destroy(){this.store$.complete()}};import{log as La}from"@galacticcouncil/common";var Da={Aave:"AAVE",LBP:"LBP",Omnipool:"OMNI",Stableswap:"STBL",XYK:"XYK",HSM:"HSM"},{logger:we}=La,Oe=class{type;constructor(e){this.type=e}prefix(){return this.pad(`pool(${Da[this.type]})`,10)}trace(e,...t){we.trace(`${this.prefix()} ${e} :`,...t)}debug(e,...t){we.debug(`${this.prefix()} ${e} :`,...t)}info(e,...t){we.info(`${this.prefix()} ${e} :`,...t)}error(e,...t){we.error(`${this.prefix()} ${e} :`,...t)}pad(e,t){return e.length>=t?e:e+" ".repeat(t-e.length)}};var{withTimeout:Qa}=xe,Ja=3e3,S=class extends _{evm;balance;store=new Ie;log;shared$;resync$=new gt(1);resyncAt=0;resyncPending=!1;mem=0;memPoolsCache=new Na(null,{ttl:6*1e3});memPools=Ha(e=>(this.log.info("pool_sync",{mem:e}),this.loadPools()),this.memPoolsCache);constructor(e,t,a){super(e,a),this.evm=t,this.balance=new oe(e,a),this.log=new Oe(this.getPoolType())}async getMemPools(){return this.memPools(this.mem)}async getPools(){let t=(await this.getMemPools()).filter(a=>this.hasValidAssets(a));return this.store.set(t),t}getSubscriber(){return this.shared$||(this.shared$=this.subscribeStore()),this.shared$.pipe(za([]),Wa(2,1),X(([e,t])=>e.length===0?t:this.store.applyChangeset(t)),Be(e=>e.length>0),ja(1e3,void 0,{leading:!0,trailing:!0}))}subscribeStore(){return Ga(()=>{let e=new bt;return e.add(this.startWatchdog()),this.resync$.next(),this.resync$.pipe(ht(()=>{let t=new bt;return Va(Qa(this.getMemPools(),6e4,"getMemPools stalled")).pipe(N(()=>this.log.info("pool_synced",{mem:this.mem})),X(i=>i.filter(s=>this.hasValidAssets(s))),N(i=>this.store.set(i)),ce(()=>(this.log.error("pool_seed_error",{mem:this.mem}),this.requestResync(),le))).pipe(N(()=>{t.add(this.subscribeBalances()),t.add(this.subscribeUpdates())}),ht(i=>qe($a(i),this.store.asObservable().pipe(Xa(1)))),Ge(()=>{t.unsubscribe()}))}),Ge(()=>e.unsubscribe()))}).pipe(Ka({connector:()=>new gt(1),resetOnRefCountZero:!0}))}subscribeBalances(){let e=this.store.pools.map(t=>{let{address:a}=t,i=[this.balance.watchTokensBalance(a)];if(this.hasSystemAsset(t)){let s=this.balance.watchSystemBalance(a);i.push(s)}if(this.hasErc20Asset(t)){let s=t.tokens.filter(r=>r.type==="Erc20").map(r=>r.id),n=this.balance.watchErc20Balance(a,s);i.push(n)}return qa(i).pipe(X(s=>s.flat()),Ve(),X(([s,n])=>this.balance.getDeltas(s,n)),Be(s=>s.length>0),X(s=>[a,s]))});return qe(...e).pipe(Ya(250),Be(t=>t.length>0),X(t=>new Map(t)),this.watchGuard("balances")).subscribe(t=>{this.store.update(a=>this.updateBalances(a,t))})}hasSystemAsset(e){return e.tokens.some(t=>t.id===0)}hasErc20Asset(e){return e.tokens.some(t=>t.type==="Erc20")}hasValidAssets(e){return e.tokens.every(({decimals:t,balance:a})=>e.type==="XYK"?a>0n&&!!t:!!t)}updateBalances=(e,t)=>{let a=[],i=new Map(e.map(s=>[s.address,s]));for(let[s,n]of t){let r=i.get(s);if(r){let o=r.tokens.map(c=>{let l=n.find(p=>p.id===c.id);return l&&c.id!==r.id?{...c,balance:l.balance.transferable}:c});a.push({...r,tokens:o})}}return a};resync(e=!1){let t=Date.now();!e&&t-this.resyncAt<Ja||(this.resyncAt=t,this.mem++,this.resync$.next())}requestResync(e=!1){this.resyncPending||(this.resyncPending=!0,setTimeout(()=>{this.resyncPending=!1,this.resync(e)},0))}startWatchdog(){let i=this.watcher.connection$.pipe(Ve(),Be(([r,o])=>r==="offline"&&o==="online"),N(()=>{this.log.debug("watchdog_recover_online",{mem:this.mem}),this.requestResync()}),ce(r=>(this.log.error("watchdog_recovery_error",r),le)),Ue({delay:1e3})),s=this.watcher.finalizedBlock$.pipe(Ve(),N(([r,o])=>{let c=Number(r.number),l=Number(o.number),p=l-c;p>=3&&(this.log.debug("watchdog_gap",{from:c,to:l,gap:p}),this.requestResync())}),ce(r=>(this.log.error("watchdog_gap_error",r),le)),Ue({delay:1e3})),n=Ua(36e5).pipe(N(()=>{this.log.debug("watchdog_periodic",{mem:this.mem}),this.requestResync()}),ce(r=>(this.log.error("watchdog_periodic_error",r),le)),Ue({delay:1e3}));return qe(i,s,n).subscribe()}watchGuard(e){return t=>t.pipe(N({error:a=>{this.log.error(e,a),this.requestResync(!0)}}),Ge(()=>{this.log.debug(e,"unsub")}),ce(()=>le))}};var ue=class extends S{MAX_FINAL_WEIGHT=100000000n;poolsData=new Map([]);getPoolType(){return"LBP"}async getPoolLimits(){let[e,t,a]=await Promise.all([this.api.constants.LBP.MaxInRatio(),this.api.constants.LBP.MaxOutRatio(),this.api.constants.LBP.MinTradingLimit()]);return{maxInRatio:e,maxOutRatio:t,minTradingLimit:a}}getPoolWeights(e,t){let{start:a,end:i,initial_weight:s,final_weight:n}=e,r=O.calculateLinearWeights(a?a.toString():"0",i?i.toString():"0",s.toString(),n.toString(),t.toString()),o=BigInt(r),c=this.MAX_FINAL_WEIGHT-BigInt(o);return[o,c]}async isSupported(){return(await this.api.getStaticApis()).compat.query.LBP.PoolData.isCompatible(Za.BackwardsCompatible)}async loadPools(){let[e,t,a]=await Promise.all([this.api.query.LBP.PoolData.getEntries({at:this.at}),this.api.query.ParachainSystem.ValidationData.getValue({at:this.at}),this.getPoolLimits()]),i=t?.relay_parent_number||0,s=e.filter(({value:n})=>t&&this.isActivePool(n,i)).map(async({keyArgs:n,value:r})=>{let[o]=n,c=o.toString(),l=await this.getPoolDelta(c,r,i);return{address:c,type:"LBP",fee:r.fee,...l,...a}});return Promise.all(s)}async getPoolDelta(e,t,a){let{assets:i,repay_target:s,fee_collector:n}=t,[r,o]=this.getPoolWeights(t,a),[c,l]=i,[p,m,d,g,b]=await Promise.all([this.isRepayFeeApplied(c,s,n.toString()),this.balance.getBalance(e,c),this.api.query.AssetRegistry.Assets.getValue(c,{at:this.at}),this.balance.getBalance(e,l),this.api.query.AssetRegistry.Assets.getValue(l,{at:this.at})]);return{repayFeeApply:p,tokens:[{id:c,decimals:d?.decimals,existentialDeposit:d?.existential_deposit,balance:m.transferable,weight:r,type:d?.asset_type.type},{id:l,decimals:b?.decimals,existentialDeposit:b?.existential_deposit,balance:g.transferable,weight:o,type:b?.asset_type.type}]}}isActivePool(e,t){let{start:a,end:i}=e;return a&&i?t>=a&&t<i:!1}async isRepayFeeApplied(e,t,a){if(t===0n)return!1;try{return(await this.balance.getBalance(a,e)).transferable<t}catch{return!0}}async getRepayFee(){return await this.api.constants.LBP.repay_fee()}async getPoolFees(e,t){let a=this.store.pools.find(s=>s.address===t);return{repayFee:await this.getRepayFee(),exchangeFee:a.fee}}subscribeValidationData(){return this.api.query.ParachainSystem.ValidationData.watchValue({at:"best"}).pipe(ii(({value:e})=>e),ai(e=>e!==void 0),ti((e,t)=>e.relay_parent_number===t.relay_parent_number),this.watchGuard("parachainSystem.ValidationData")).subscribe(({relay_parent_number:e})=>{this.store.update(async t=>{let a=[];for(let i of t){let s=this.poolsData.get(i.address);if(s){let{assets:n,repay_target:r,fee_collector:o}=s,[c]=n,[l,p]=this.getPoolWeights(s,e),[m,d]=i.tokens,g=[{...m,weight:l},{...d,weight:p}],b=await this.isRepayFeeApplied(c,r,o.toString());a.push({...i,tokens:g,repayFeeApply:b})}}return a})})}subscribeUpdates(){let e=new ei;return e.add(this.subscribeValidationData()),e}};var St={};F(St,{OmniMath:()=>h,OmniPool:()=>pe,OmniPoolClient:()=>me,OmniPoolFee:()=>q,getEmaKey:()=>_e,getEmaPair:()=>z});import{calculate_in_given_out as si,calculate_lrna_in_given_out as ni,calculate_out_given_in as ri,calculate_out_given_lrna_in as oi,calculate_spot_price as li,calculate_lrna_spot_price as ci,calculate_shares as ui,calculate_liquidity_out as pi,calculate_liquidity_lrna_out as mi,verify_asset_cap as di,calculate_liquidity_hub_in as gi,is_sell_allowed as bi,is_buy_allowed as hi,is_add_liquidity_allowed as yi,is_remove_liquidity_allowed as fi,recalculate_asset_fee as Pi,recalculate_protocol_fee as vi}from"@galacticcouncil/math-omnipool";import K from"big.js";var h=class{static calculateSpotPrice(e,t,a,i){return li(e,t,a,i)}static calculateLrnaSpotPrice(e,t){return ci(e,t)}static calculateInGivenOut(e,t,a,i,s,n,r,o,c,l){return si(e,t,a,i,s,n,r,o,c,l)}static calculateLrnaInGivenOut(e,t,a,i,s,n){return ni(e,t,a,i,s,n)}static calculateOutGivenIn(e,t,a,i,s,n,r,o,c,l){return ri(e,t,a,i,s,n,r,o,c,l)}static calculateOutGivenLrnaIn(e,t,a,i,s,n){return oi(e,t,a,i,s,n)}static calculateShares(e,t,a,i){return ui(e,t,a,i)}static calculateLiquidityOut(e,t,a,i,s,n,r,o){return pi(e,t,a,i,s,n,r,o)}static calculateLiquidityLRNAOut(e,t,a,i,s,n,r,o){return mi(e,t,a,i,s,n,r,o)}static calculateCapDifference(e,t,a,i){let s=K(t),n=K(e),r=K(i),o=K(a),c=K(10).pow(18),l=o.div(c);if(s.div(r).lt(l)){let m=l.times(r).minus(s).times(n),d=s.times(K(1).minus(l));return m.div(d).toFixed(0)}else return"0"}static calculateLimitHubIn(e,t,a,i){return gi(e,t,a,i)}static isSellAllowed(e){return bi(e)}static isBuyAllowed(e){return hi(e)}static isAddLiquidityAllowed(e){return yi(e)}static isRemoveLiquidityAllowed(e){return fi(e)}static recalculateAssetFee(e,t,a,i,s,n,r,o,c,l,p){return Pi(e,t,a,i,s,n,r,o,c,l,p)}static recalculateProtocolFee(e,t,a,i,s,n,r,o,c,l,p){return vi(e,t,a,i,s,n,r,o,c,l,p)}static verifyAssetCap(e,t,a,i){return di(e,t,a,i)}};import{big as Si}from"@galacticcouncil/common";var{FeeUtils:R}=y,pe=class u{type;address;tokens;maxInRatio;maxOutRatio;minTradingLimit;hubAssetId;static fromPool(e){return new u(e)}constructor(e){this.type="Omnipool",this.address=e.address,this.tokens=e.tokens,this.maxInRatio=e.maxInRatio,this.maxOutRatio=e.maxOutRatio,this.minTradingLimit=e.minTradingLimit,this.hubAssetId=e.hubAssetId}validatePair(e,t){return this.hubAssetId!=t}parsePair(e,t){let a=new Map(this.tokens.map(n=>[n.id,n])),i=a.get(e),s=a.get(t);if(i==null)throw new Error("Pool does not contain tokenIn");if(s==null)throw new Error("Pool does not contain tokenOut");return{assetIn:e,assetOut:t,hubReservesIn:i.hubReserves,hubReservesOut:s.hubReserves,sharesIn:i.shares,sharesOut:s.shares,decimalsIn:i.decimals,decimalsOut:s.decimals,balanceIn:i.balance,balanceOut:s.balance,tradeableIn:i.tradeable,tradeableOut:s.tradeable,assetInEd:i.existentialDeposit,assetOutEd:s.existentialDeposit}}validateAndBuy(e,t,a){let i=this.calculateInGivenOut(e,t),s=this.calculateInGivenOut(e,t,a),n=i===0n?0:L.calculateBuyFee(i,s),r=[],o=h.isSellAllowed(e.tradeableIn),c=h.isBuyAllowed(e.tradeableOut);(!o||!c)&&r.push("TradeNotAllowed"),(t<this.minTradingLimit||i<e.assetInEd)&&r.push("InsufficientTradingAmount");let l=e.balanceOut/this.maxOutRatio;t>l&&r.push("MaxOutRatioExceeded");let p=e.balanceIn/this.maxInRatio;return s>p&&r.push("MaxInRatioExceeded"),{amountIn:s,calculatedIn:i,amountOut:t,feePct:n,errors:r}}validateAndSell(e,t,a){let i=this.calculateOutGivenIn(e,t),s=this.calculateOutGivenIn(e,t,a),n=L.calculateSellFee(i,s),r=[],o=h.isSellAllowed(e.tradeableIn),c=h.isBuyAllowed(e.tradeableOut);(!o||!c)&&r.push("TradeNotAllowed"),(t<this.minTradingLimit||i<e.assetOutEd)&&r.push("InsufficientTradingAmount");let l=e.balanceIn/this.maxInRatio;t>l&&r.push("MaxInRatioExceeded");let p=e.balanceOut/this.maxOutRatio;return s>p&&r.push("MaxOutRatioExceeded"),{amountIn:t,calculatedOut:i,amountOut:s,feePct:n,errors:r}}calculateInGivenOut(e,t,a){if(e.assetIn==this.hubAssetId)return this.calculateLrnaInGivenOut(e,t,a);let i=h.calculateInGivenOut(e.balanceIn.toString(),e.hubReservesIn.toString(),e.sharesIn.toString(),e.balanceOut.toString(),e.hubReservesOut.toString(),e.sharesOut.toString(),t.toString(),a?R.toRaw(a.assetFee).toString():"0",a?R.toRaw(a.protocolFee).toString():"0",a?R.toRaw(a.maxSlipFee).toString():"0"),s=BigInt(i);return s<0n?0n:s}calculateLrnaInGivenOut(e,t,a){let i=h.calculateLrnaInGivenOut(e.balanceOut.toString(),e.hubReservesOut.toString(),e.sharesOut.toString(),t.toString(),a?R.toRaw(a.assetFee).toString():"0",a?R.toRaw(a.maxSlipFee).toString():"0"),s=BigInt(i);return s<0n?0n:s}calculateOutGivenIn(e,t,a){if(e.assetIn==this.hubAssetId)return this.calculateOutGivenLrnaIn(e,t,a);let i=h.calculateOutGivenIn(e.balanceIn.toString(),e.hubReservesIn.toString(),e.sharesIn.toString(),e.balanceOut.toString(),e.hubReservesOut.toString(),e.sharesOut.toString(),t.toString(),a?R.toRaw(a.assetFee).toString():"0",a?R.toRaw(a.protocolFee).toString():"0",a?R.toRaw(a.maxSlipFee).toString():"0"),s=BigInt(i);return s<0n?0n:s}calculateOutGivenLrnaIn(e,t,a){let i=h.calculateOutGivenLrnaIn(e.balanceOut.toString(),e.hubReservesOut.toString(),e.sharesOut.toString(),t.toString(),a?R.toRaw(a.assetFee).toString():"0",a?R.toRaw(a.maxSlipFee).toString():"0"),s=BigInt(i);return s<0n?0n:s}spotPriceInGivenOut(e){if(e.assetIn==this.hubAssetId)return this.spotPriceLrnaInGivenOut(e);let t=h.calculateSpotPrice(e.balanceOut.toString(),e.hubReservesOut.toString(),e.balanceIn.toString(),e.hubReservesIn.toString());return this.normalizeSpot(BigInt(t),e.decimalsOut,e.decimalsIn)}spotPriceLrnaInGivenOut(e){let t=h.calculateLrnaSpotPrice(e.hubReservesOut.toString(),e.balanceOut.toString());return this.normalizeSpot(BigInt(t),e.decimalsOut,e.decimalsIn)}spotPriceOutGivenIn(e){if(e.assetIn==this.hubAssetId)return this.spotPriceOutGivenLrnaIn(e);let t=h.calculateSpotPrice(e.balanceIn.toString(),e.hubReservesIn.toString(),e.balanceOut.toString(),e.hubReservesOut.toString());return this.normalizeSpot(BigInt(t),e.decimalsIn,e.decimalsOut)}spotPriceOutGivenLrnaIn(e){let t=h.calculateLrnaSpotPrice(e.balanceOut.toString(),e.hubReservesOut.toString());return this.normalizeSpot(BigInt(t),e.decimalsIn,e.decimalsOut)}normalizeSpot(e,t,a){let i=t-a;if(i===0)return e;let s=Si.pow10(Math.abs(i));return i>0?e*s:e/s}};import{AccountId as Ti,Binary as ft,CompatibilityLevel as xi,Enum as Ai}from"polkadot-api";import{toHex as Ii}from"@polkadot-api/utils";import{Subscription as wi,distinctUntilChanged as $e,filter as Oi,finalize as We,map as j,merge as Bi,tap as Ee}from"rxjs";import{HYDRATION_SS58_PREFIX as Fi}from"@galacticcouncil/common";var{FeeUtils:v}=y,q=class u{static compute(e,t,a,i,s,n,r,o){let c=e.assetIn,[l,p,m]=u.getAssetFee(e,t,a,i,n),d=0,g=0,b=0;c!==1&&([d,g,b]=u.getProtocolFee(e,t,a,s,r));let B=l+d,x=m+b;return{assetFee:v.fromPermill(p),protocolFee:v.fromPermill(g),maxSlipFee:v.fromPermill(o),min:v.fromPermill(B),max:v.fromPermill(x)}}static getAssetFee(e,t,a,i,s){let{assetOut:n,balanceOut:r}=e,{min_fee:o,max_fee:c,decay:l,amplification:p}=s;if(!a||!i)return[o,o,c];let m=v.fromPermill(o),d=v.fromPermill(c),[g]=i,{asset_fee:b,timestamp:B}=a,x=Math.max(1,t-B),A=g.volume.b_in.toString(),I=g.volume.b_out.toString(),w=g.liquidity.b.toString();n===0&&(A=g.volume.a_in.toString(),I=g.volume.a_out.toString(),w=g.liquidity.a.toString());let D=v.fromPermill(b),ae=h.recalculateAssetFee(A,I,w,"9",r.toString(),v.toRaw(D).toString(),x.toString(),v.toRaw(m).toString(),v.toRaw(d).toString(),l.toString(),p.toString());return[o,Number(ae)*1e6,c]}static getProtocolFee(e,t,a,i,s){let{assetIn:n,balanceIn:r}=e,{min_fee:o,max_fee:c,decay:l,amplification:p}=s;if(!a||!i)return[o,o,c];let m=v.fromPermill(o),d=v.fromPermill(c),[g]=i,{protocol_fee:b,timestamp:B}=a,x=Math.max(1,t-B),A=g.volume.b_in.toString(),I=g.volume.b_out.toString(),w=g.liquidity.b.toString();n===0&&(A=g.volume.a_in.toString(),I=g.volume.a_out.toString(),w=g.liquidity.a.toString());let D=v.fromPermill(b),ae=h.recalculateProtocolFee(A,I,w,"9",r.toString(),v.toRaw(D).toString(),x.toString(),v.toRaw(m).toString(),v.toRaw(d).toString(),l.toString(),p.toString());return[o,Number(ae)*1e6,c]}};var z=u=>u===0?[0,1]:[1,u],_e=u=>z(u).join(":");var{FeeUtils:Ye}=y,Pt=ft.toHex(ft.fromText("omnipool")),vt=Ai("Short"),me=class extends S{queryBus=new $;block=0;dynamicFeesConfig=this.queryBus.scope("DynamicFees.AssetFeeConfiguration",e=>this.api.query.DynamicFees.AssetFeeConfiguration.getValue(e,{at:this.at}),e=>String(e));dynamicFees=this.queryBus.scope("DynamicFees.AssetFee",e=>this.api.query.DynamicFees.AssetFee.getValue(e,{at:this.at}),e=>String(e),6*1e3);maxSlipFee=this.queryBus.scope("Omnipool.SlipFee",()=>this.apiNext.query.Omnipool.SlipFee.getValue({at:this.at}),()=>"slipFee");emaOracles=this.queryBus.scope("EmaOracle.Oracles.Short",e=>this.api.query.EmaOracle.Oracles.getValue(Pt,e,vt,{at:this.at}),e=>e.join(":"),6*1e3);getPoolType(){return"Omnipool"}getPoolAddress(){let e="modlomnipool".padEnd(32,"\0"),t=new TextEncoder().encode(e),a=Ii(t);return Ti(Fi).dec(a)}async getPoolLimits(){let[e,t,a]=await Promise.all([this.api.constants.Omnipool.MaxInRatio(),this.api.constants.Omnipool.MaxOutRatio(),this.api.constants.Omnipool.MinimumTradingLimit()]);return{maxInRatio:e,maxOutRatio:t,minTradingLimit:a}}async isSupported(){return(await this.api.getStaticApis()).compat.query.Omnipool.Assets.isCompatible(xi.BackwardsCompatible)}async loadPools(){let e=await this.api.constants.Omnipool.HubAssetId(),t=this.getPoolAddress(),[a,i,s,n,r,o]=await Promise.all([this.api.query.Omnipool.Assets.getEntries({at:this.at}),this.api.query.Omnipool.HubAssetTradability.getValue({at:this.at}),this.api.query.AssetRegistry.Assets.getValue(e,{at:this.at}),this.balance.getBalance(t,e),this.getPoolLimits(),this.api.query.System.Number.getValue({at:this.at})]);this.block=o;let c=a.map(async({keyArgs:p,value:m})=>{let[d]=p,{hub_reserve:g,shares:b,tradable:B,cap:x,protocol_shares:A}=m,[I,w]=await Promise.all([this.api.query.AssetRegistry.Assets.getValue(d,{at:this.at}),this.balance.getBalance(t,d)]);return{id:d,decimals:I?.decimals,existentialDeposit:I?.existential_deposit,balance:w.transferable,cap:x,hubReserves:g,protocolShares:A,shares:b,tradeable:B,type:I?.asset_type.type}}),l=await Promise.all(c);return l.push({id:e,decimals:s?.decimals,existentialDeposit:s?.existential_deposit,balance:n.transferable,tradeable:i,type:s?.asset_type.type}),[{address:t,type:"Omnipool",hubAssetId:e,tokens:l,...r}]}async getPoolFees(e){let t=e.assetOut,a=e.assetIn,s=await this.maxSlipFee.get()??0,n=await this.dynamicFeesConfig.get(t);if(n?.type==="Fixed"){let{asset_fee:m,protocol_fee:d}=n.value;return{assetFee:Ye.fromPermill(m),protocolFee:Ye.fromPermill(d),maxSlipFee:Ye.fromPermill(s)}}let[r,o,c,l,p]=await Promise.all([this.dynamicFees.get(t),this.emaOracles.get(z(t)),this.emaOracles.get(z(a)),n?n.value.asset_fee_params:this.api.constants.DynamicFees.AssetFeeParameters(),n?n.value.protocol_fee_params:this.api.constants.DynamicFees.ProtocolFeeParameters()]);return q.compute(e,this.block,r,o,c,l,p,s)}subscribeEmaOracles(){let[e]=this.store.pools,a=e.tokens.map(i=>i.id).map(i=>z(i)).map(i=>this.api.query.EmaOracle.Oracles.watchValue(Pt,i,vt,{at:"best"}).pipe(j(({value:s})=>s),Oi(s=>s!==void 0),j((s,n)=>({value:s,index:n})),Ee(({index:s})=>{s>0&&this.log.trace("emaOracle.Oracles",i.join(":"))}),j(({value:s})=>({pair:i,value:s}))));return Bi(...a).pipe(We(()=>this.emaOracles.clear()),this.watchGuard("emaOracle.Oracles")).subscribe(i=>{let{pair:s,value:n}=i;this.emaOracles.set(n,s)})}subscribeDynamicFees(){return this.api.query.DynamicFees.AssetFee.watchEntries({at:"best"}).pipe($e((e,t)=>!t.deltas),j((e,t)=>({value:e,index:t})),Ee(({value:e,index:t})=>{t>0&&this.log.trace("dynamicFees.AssetFee",e.deltas?.upserted)}),We(()=>this.dynamicFees.clear()),this.watchGuard("dynamicFees.AssetFee")).subscribe(({value:{deltas:e}})=>{e?.upserted.forEach(t=>{let[a]=t.args;this.dynamicFees.set(t.value,a)})})}subscribeDynamicFeesConfig(){return this.api.query.DynamicFees.AssetFeeConfiguration.watchEntries({at:"best"}).pipe($e((e,t)=>!t.deltas),j((e,t)=>({value:e,index:t})),Ee(({value:e,index:t})=>{t>0&&this.log.trace("dynamicFees.AssetFeeConfiguration",e.deltas?.upserted)}),We(()=>this.dynamicFeesConfig.clear()),this.watchGuard("dynamicFees.AssetFeeConfiguration")).subscribe(({value:{deltas:e}})=>{e?.upserted.forEach(t=>{let[a]=t.args;this.dynamicFeesConfig.set(t.value,a)})})}subscribeBlock(){return this.watcher.bestBlock$.pipe(this.watchGuard("watcher.bestBlock")).subscribe(e=>{this.block=e})}subscribeAssets(){return this.api.query.Omnipool.Assets.watchEntries({at:"best"}).pipe($e((e,t)=>!t.deltas),j((e,t)=>({value:e,index:t})),Ee(({value:e,index:t})=>{t>0&&this.log.trace("omnipool.Assets",e.deltas?.upserted)}),this.watchGuard("omnipool.Assets")).subscribe(({value:{deltas:e}})=>{this.store.update(([t])=>{let a=e?.upserted.reduce((s,n)=>{let[r]=n.args;return s.set(r,n.value),s},new Map),i=t.tokens.map(s=>{let n=a?.get(s.id);return n?this.updateTokenState(s,n):s});return[{...t,tokens:i}]})})}subscribeUpdates(){let e=new wi;return e.add(this.subscribeAssets()),e.add(this.subscribeDynamicFees()),e.add(this.subscribeDynamicFeesConfig()),e.add(this.subscribeEmaOracles()),e.add(this.subscribeBlock()),e}updateTokenState(e,t){let{hub_reserve:a,shares:i,tradable:s,cap:n,protocol_shares:r}=t;return{...e,cap:n,hubReserves:a,protocolShares:r,shares:i,tradeable:s}}};var Et={};F(Et,{StableMath:()=>P,StableSwap:()=>G,StableSwapClient:()=>he});import{calculate_in_given_out as _i,calculate_out_given_in as Ei,calculate_amplification as Ri,calculate_add_one_asset as ki,calculate_liquidity_out_one_asset as Ci,calculate_shares as Mi,calculate_shares_for_amount as Li,calculate_spot_price_with_fee as Di,pool_account_name as Hi,recalculate_peg as Ni}from"@galacticcouncil/math-stableswap";var P=class{static getPoolAddress(e){return Hi(e)}static defaultPegs(e){let t=[];for(let a=0;a<e;a++)t.push(["1","1"]);return t}static calculateAmplification(e,t,a,i,s){return Ri(e,t,a,i,s)}static calculateInGivenOut(e,t,a,i,s,n,r){return _i(e,t,a,i,s,n,r)}static calculateAddOneAsset(e,t,a,i,s,n,r){return ki(e,t,a,i,s,n,r)}static calculateSharesForAmount(e,t,a,i,s,n,r){return Li(e,t,a,i,s,n,r)}static calculateOutGivenIn(e,t,a,i,s,n,r){return Ei(e,t,a,i,s,n,r)}static calculateLiquidityOutOneAsset(e,t,a,i,s,n,r){return Ci(e,t,a,i,s,n,r)}static calculateShares(e,t,a,i,s,n){return Mi(e,t,a,i,s,n)}static calculateSpotPriceWithFee(e,t,a,i,s,n,r,o){return Di(e,t,a,i,s,n,r,o)}static recalculatePegs(e,t,a,i,s,n){let r=Ni(e,t,a,i,s,n);return JSON.parse(r)}};import{RUNTIME_DECIMALS as qi,big as Tt}from"@galacticcouncil/common";var{FeeUtils:Q}=y,G=class u{type;address;tokens;maxInRatio;maxOutRatio;minTradingLimit;amplification;isRampPeriod;id;fee;totalIssuance;pegs;static fromPool(e){return new u(e)}constructor(e){this.type="Stableswap",this.address=e.address,this.tokens=e.tokens,this.maxInRatio=e.maxInRatio,this.maxOutRatio=e.maxOutRatio,this.minTradingLimit=e.minTradingLimit,this.amplification=e.amplification,this.isRampPeriod=e.isRampPeriod,this.id=e.id,this.fee=e.fee,this.totalIssuance=e.totalIssuance,this.pegs=e.pegs}validatePair(e,t){return!0}parsePair(e,t){let a=new Map(this.tokens.map(n=>[n.id,n])),i=a.get(e),s=a.get(t);if(i==null)throw new Error("Pool does not contain tokenIn");if(s==null)throw new Error("Pool does not contain tokenOut");return{assetIn:e,assetOut:t,balanceIn:i.balance,balanceOut:s.balance,decimalsIn:i.decimals,decimalsOut:s.decimals,tradeableIn:this.id===e?15:i.tradeable,tradeableOut:this.id===t?15:s.tradeable,assetInEd:i.existentialDeposit,assetOutEd:s.existentialDeposit}}validateAndBuy(e,t,a){let i=this.calculateInGivenOut(e,t),s=this.calculateInGivenOut(e,t,a),n=i===0n?0:L.calculateBuyFee(i,s),r=[],o=h.isSellAllowed(e.tradeableIn),c=h.isBuyAllowed(e.tradeableOut);return(!o||!c)&&r.push("TradeNotAllowed"),(t<this.minTradingLimit||i<e.assetInEd)&&r.push("InsufficientTradingAmount"),{amountIn:s,calculatedIn:i,amountOut:t,feePct:n,errors:r}}validateAndSell(e,t,a){let i=this.calculateOutGivenIn(e,t),s=this.calculateOutGivenIn(e,t,a),n=L.calculateSellFee(i,s),r=[],o=h.isSellAllowed(e.tradeableIn),c=h.isBuyAllowed(e.tradeableOut);return(!o||!c)&&r.push("TradeNotAllowed"),(t<this.minTradingLimit||i<e.assetOutEd)&&r.push("InsufficientTradingAmount"),{amountIn:t,calculatedOut:i,amountOut:s,feePct:n,errors:r}}calculateIn(e,t,a){let i=P.calculateInGivenOut(this.getReserves(),Number(e.assetIn),Number(e.assetOut),t.toString(),this.amplification.toString(),a?Q.toRaw(a.fee).toString():"0",this.getPegs()),s=BigInt(i);return s<0n?0n:s}calculateAddOneAsset(e,t,a){let i=P.calculateAddOneAsset(this.getReserves(),t.toString(),Number(e.assetIn),this.amplification.toString(),this.totalIssuance.toString(),a?Q.toRaw(a.fee).toString():"0",this.getPegs()),s=BigInt(i);return s<0n?0n:s}calculateSharesForAmount(e,t,a){let i=P.calculateSharesForAmount(this.getReserves(),Number(e.assetOut),t.toString(),this.amplification.toString(),this.totalIssuance.toString(),a?Q.toRaw(a.fee).toString():"0",this.getPegs()),s=BigInt(i);return s<0n?0n:s}calculateInGivenOut(e,t,a){return e.assetOut==this.id?this.calculateAddOneAsset(e,t,a):e.assetIn==this.id?this.calculateSharesForAmount(e,t,a):this.calculateIn(e,t,a)}spotPriceInGivenOut(e){let t=P.calculateSpotPriceWithFee(this.id.toString(),this.getReserves(),this.amplification.toString(),e.assetOut.toString(),e.assetIn.toString(),this.totalIssuance.toString(),"0",this.getPegs());return this.normalizeSpot(BigInt(t),e.assetOut===this.id,e.assetIn===this.id,e.decimalsOut,e.decimalsIn)}calculateOut(e,t,a){let i=P.calculateOutGivenIn(this.getReserves(),Number(e.assetIn),Number(e.assetOut),t.toString(),this.amplification.toString(),a?Q.toRaw(a.fee).toString():"0",this.getPegs()),s=BigInt(i);return s<0n?0n:s}calculateWithdrawOneAsset(e,t,a){let i=P.calculateLiquidityOutOneAsset(this.getReserves(),t.toString(),Number(e.assetOut),this.amplification.toString(),this.totalIssuance.toString(),a?Q.toRaw(a.fee).toString():"0",this.getPegs()),s=BigInt(i);return s<0n?0n:s}calculateShares(e,t,a){let i=P.calculateShares(this.getReserves(),this.getAssets(e.assetIn,t),this.amplification.toString(),this.totalIssuance.toString(),a?Q.toRaw(a.fee).toString():"0",this.getPegs()),s=BigInt(i);return s<0n?0n:s}calculateOutGivenIn(e,t,a){return e.assetIn==this.id?this.calculateWithdrawOneAsset(e,t,a):e.assetOut==this.id?this.calculateShares(e,t,a):this.calculateOut(e,t,a)}spotPriceOutGivenIn(e){let t=P.calculateSpotPriceWithFee(this.id.toString(),this.getReserves(),this.amplification.toString(),e.assetIn.toString(),e.assetOut.toString(),this.totalIssuance.toString(),"0",this.getPegs());return this.normalizeSpot(BigInt(t),e.assetIn===this.id,e.assetOut===this.id,e.decimalsIn,e.decimalsOut)}getPegs(){return JSON.stringify(this.pegs)}getReserves(){let e=this.tokens.filter(t=>t.id!=this.id).map(({id:t,balance:a,decimals:i})=>({asset_id:t,amount:a,decimals:i}));return JSON.stringify(e,ie.jsonFormatter)}getAssets(e,t){let a={asset_id:Number(e),amount:t.toString()};return JSON.stringify([a],ie.jsonFormatter)}normalizeSpot(e,t,a,i,s){return t?e*Tt.pow10(qi-s):a?e/Tt.pow10(s-i):e}};import{AccountId as Vi,CompatibilityLevel as Ui}from"polkadot-api";import{toHex as $i}from"@polkadot-api/utils";import{blake2b as Wi}from"@noble/hashes/blake2b";import{Subscription as Yi,distinctUntilChanged as _t,filter as Xi,map as Z,merge as Ki,tap as Ke}from"rxjs";import{HYDRATION_SS58_PREFIX as zi,RUNTIME_DECIMALS as ji}from"@galacticcouncil/common";import{Binary as Gi}from"polkadot-api";import{decodeEventLog as It}from"viem";var Xe=[{inputs:[],name:"decimals",outputs:[{internalType:"uint8",name:"",type:"uint8"}],stateMutability:"view",type:"function"},{inputs:[],name:"description",outputs:[{internalType:"string",name:"",type:"string"}],stateMutability:"view",type:"function"},{inputs:[],name:"version",outputs:[{internalType:"uint256",name:"",type:"uint256"}],stateMutability:"view",type:"function"},{inputs:[{internalType:"uint80",name:"_roundId",type:"uint80"}],name:"getRoundData",outputs:[{internalType:"uint80",name:"roundId",type:"uint80"},{internalType:"int256",name:"answer",type:"int256"},{internalType:"uint256",name:"startedAt",type:"uint256"},{internalType:"uint256",name:"updatedAt",type:"uint256"},{internalType:"uint80",name:"answeredInRound",type:"uint80"}],stateMutability:"view",type:"function"},{inputs:[],name:"latestRoundData",outputs:[{internalType:"uint80",name:"roundId",type:"uint80"},{internalType:"int256",name:"answer",type:"int256"},{internalType:"uint256",name:"startedAt",type:"uint256"},{internalType:"uint256",name:"updatedAt",type:"uint256"},{internalType:"uint80",name:"answeredInRound",type:"uint80"}],stateMutability:"view",type:"function"}],xt=[{anonymous:!1,inputs:[{indexed:!1,name:"key",type:"string"},{indexed:!1,name:"value",type:"uint128"},{indexed:!1,name:"timestamp",type:"uint128"}],name:"OracleUpdate",type:"event"}],At=[{anonymous:!1,inputs:[{indexed:!0,name:"roundId",type:"uint80"},{indexed:!1,name:"answer",type:"int256"},{indexed:!1,name:"timestamp",type:"uint256"}],name:"PriceUpdated",type:"event"}];var de=class{static parse(e){let{address:t,topics:a,data:i}=e.log,s=t.toLowerCase(),n=Gi.toHex(i);try{let{eventName:r,args:o}=It({abi:At,topics:a,data:n});return{eventName:`ManagedOracle.${r}`,emitter:s,value:o.answer,timestamp:o.timestamp}}catch{}try{let{eventName:r,args:o}=It({abi:xt,topics:a,data:n});return{eventName:`DIA.${r}`,emitter:s,key:o.key,value:o.value,timestamp:o.timestamp}}catch{}}};var ge=class{adapter;constructor(e){this.adapter=e.getRPCAdapter()}async getData(e,t=6){let[a,i,s]=await Promise.all([this.adapter.readContract({abi:Xe,address:e,functionName:"latestRoundData"}),this.adapter.readContract({abi:Xe,address:e,functionName:"decimals"}),this.adapter.getBlock()]),[n,r,o,c]=a,l=s.number-(s.timestamp-c)/BigInt(t),p=Number(l);return{price:r,decimals:i,updatedAt:p<0?0:p}}};var wt={"EUR/USD":"0xaa47a5662269270d3df33ae08f806e383611575c","sUSDs/USD":"0x4b32bffc6acd751446e79e8687ef3815fd7924fd","sUSDe/USD":"0x22cdea305cee63d082e79f8c5db939eecd0265d0"},Ot={"0xcfab6a4031c70da0f0cf6f31a252c16119db3611":"0xaafd758688cefd0a7b7770a825f1aad551e16185"},Bt={"bifrosto:5:15:LastBlock":"0xaafd758688cefd0a7b7770a825f1aad551e16185"};function Ft(u,e,t){let a=Buffer.from(u.replace(/^0x/,""),"hex").toString("ascii").replace(/\0+$/,""),[i,s]=[e[0],e[1]].sort((n,r)=>n-r);return`${a}:${i}:${s}:${t}`}var{FeeUtils:J}=y,be=class u{static compute(e,t,a,i){let s=u.getRecent(t),n=J.fromPermill(e.fee),r=J.fromPerbill(t.max_peg_update),o=a.map(({pair:g,updatedAt:b})=>[g,b]),c=a.find(g=>g.source),l=t.updated_at?t.updated_at.toString():c?.updatedAt;if(!l)throw new Error("Current peg unknown!");let[p,m]=P.recalculatePegs(JSON.stringify(s),l,JSON.stringify(o),i.toString(),J.toRaw(r).toString(),J.toRaw(n).toString()),d=Number(p)*1e6;return{pegsFee:J.fromPermill(d),pegs:m}}static getDefault(e){return{pegsFee:J.fromPermill(e.fee),pegs:P.defaultPegs(e.assets.length)}}static getRecent(e){let{current:t}=e;return Array.from(t.entries()).map(([a,i])=>i.map(s=>s.toString()))}};var{FeeUtils:Qi}=y,Ji=["ManagedOracle.PriceUpdated","DIA.OracleUpdate"],he=class extends S{poolsData=new Map([]);mmOracle=new ge(this.evm);mmAddresses=new Set;mmRouting={byEmitter:new Map,byDiaKey:new Map,byEma:new Map};queryBus=new $;emaOracles=this.queryBus.scope("EmaOracle.Oracles",(e,t,a)=>this.api.query.EmaOracle.Oracles.getValue(e,t,a,{at:this.at}),(e,t,a)=>`${e.toString()}:${t.join(":")}:${a.type}`,6*1e3);mmOracles=this.queryBus.scope("MmOracle",e=>this.mmOracle.getData(e),e=>e.toLowerCase(),600*1e3);pegs=this.queryBus.scope("Stableswap.PoolPegs",e=>this.api.query.Stableswap.PoolPegs.getValue(e,{at:this.at}),e=>String(e),6*1e3);getPoolType(){return"Stableswap"}getPoolAddress(e){let t=P.getPoolAddress(e),a=Wi(t,{dkLen:32}),i=$i(a);return Vi(zi).dec(i)}async getPoolLimits(){return{maxInRatio:0n,maxOutRatio:0n,minTradingLimit:await this.api.constants.Stableswap.MinTradingLimit()}}getPoolAmplification(e,t){let{initial_amplification:a,final_amplification:i,initial_block:s,final_block:n}=e,r=P.calculateAmplification(a.toString(),i.toString(),s.toString(),n.toString(),t.toString()),o=Number(r)<i;return{amplification:BigInt(r),isRampPeriod:o}}async getPoolTokens(e,t){let a=this.getPoolAddress(e),i=t.assets.map(async s=>{let[n,r,o]=await Promise.all([this.api.query.Stableswap.AssetTradability.getValue(e,s,{at:this.at}),this.api.query.AssetRegistry.Assets.getValue(s,{at:this.at}),this.balance.getBalance(a,s)]);return{id:s,decimals:r?.decimals,existentialDeposit:r?.existential_deposit,balance:o.transferable,tradeable:n,type:r?.asset_type.type}});return Promise.all(i)}buildRouting(){this.mmRouting.byEmitter.clear(),this.mmRouting.byDiaKey.clear(),this.mmRouting.byEma.clear();for(let e of this.mmAddresses)this.mmRouting.byEmitter.set(e,e);for(let[e,t]of Object.entries(Ot)){let a=e.toLowerCase(),i=t.toLowerCase();this.mmAddresses.has(i)&&this.mmRouting.byEmitter.set(a,i)}for(let[e,t]of Object.entries(wt)){let a=t.toLowerCase();this.mmAddresses.has(a)&&this.mmRouting.byDiaKey.set(e,a)}for(let[e,t]of Object.entries(Bt)){let a=t.toLowerCase();this.mmAddresses.has(a)&&this.mmRouting.byEma.set(e,a)}}async isSupported(){return(await this.api.getStaticApis()).compat.query.Stableswap.Pools.isCompatible(Ui.BackwardsCompatible)}async loadPools(){let[e,t,a,i]=await Promise.all([this.api.query.Stableswap.Pools.getEntries({at:this.at}),this.api.query.Stableswap.PoolPegs.getEntries({at:this.at}),this.api.query.System.Number.getValue({at:this.at}),this.getPoolLimits()]);for(let{keyArgs:n,value:r}of t){let[o]=n;this.pegs.set(r,o);for(let c of r.source)c.type==="MMOracle"&&this.mmAddresses.add(c.value.toString().toLowerCase())}this.buildRouting();let s=e.map(async({keyArgs:n,value:r})=>{let[o]=n,c=this.getPoolAddress(o),[l,p,m,d]=await Promise.all([this.getPoolTokens(o,r),this.getPoolAmplification(r,a),this.getPoolPegs(o,r,a),this.api.query.Tokens.TotalIssuance.getValue(o,{at:this.at})]);return l.push({id:o,tradeable:15,balance:d,decimals:ji}),this.poolsData.set(o,r),{address:c,id:o,type:"Stableswap",fee:Qi.fromPermill(r.fee),tokens:l,totalIssuance:d,...m,...i,...p}});return Promise.all(s)}async getPoolFees(e,t){return{fee:this.store.pools.find(i=>i.address===t).fee}}async getPoolPegs(e,t,a){let i=await this.pegs.get(e);if(!i)return be.getDefault(t);let s=await this.getLatestPegs(t,i,a);return be.compute(t,i,s,a)}async getLatestPegs(e,t,a){let{source:i}=t,s=e.assets,n=i.map(async(r,o)=>{if(r.type==="Oracle"){let[c,l,p]=r.value,m=[p,s[o]].sort((x,A)=>x-A),d=await this.emaOracles.get(c,m,l);if(!d)throw new Error("EmaOracle missing for "+c+" / "+m);let[{price:g,updated_at:b}]=d;return{pair:p===m[0]?[g.n.toString(),g.d.toString()]:[g.d.toString(),g.n.toString()],updatedAt:b.toString(),source:r.type}}if(r.type==="MMOracle"){let c=r.value.toString(),{price:l,decimals:p,updatedAt:m}=await this.mmOracles.get(c),d=(10n**BigInt(p)).toString();return{pair:[l.toString(),d],updatedAt:m.toString(),source:r.type}}if(r.type==="Value")return{pair:r.value.map(l=>l.toString()),updatedAt:a.toString()};throw new Error(r+" source not supported")});return Promise.all(n)}subscribeIssuance(){let t=this.store.pools.map(a=>a.id).map(a=>this.api.query.Tokens.TotalIssuance.watchValue(a,{at:"best"}).pipe(Z(({value:i})=>i),Z((i,s)=>({value:i,index:s})),Ke(({index:i,value:s})=>{i>0&&this.log.trace("tokens.TotalIssuance",a,s)}),Z(({value:i})=>({id:a,value:i}))));return Ki(...t).pipe(this.watchGuard("tokens.TotalIssuance")).subscribe(a=>{let{id:i,value:s}=a;this.store.update(n=>{let r=[];return n.filter(o=>o.id===i).forEach(o=>{let c=o.tokens.map(l=>l.id===i?{...l,balance:s}:l);r.push({...o,tokens:c,totalIssuance:s})}),r})})}subscribePoolPegs(){return this.api.query.Stableswap.PoolPegs.watchEntries({at:"best"}).pipe(_t((e,t)=>!t.deltas),Z((e,t)=>({value:e,index:t})),Ke(({value:e,index:t})=>{t>0&&this.log.trace("stableswap.PoolPegs",e.deltas?.upserted)}),this.watchGuard("stableswap.PoolPegs")).subscribe({error:e=>this.log.error("stableswap.PoolPegs",e),next:({value:{deltas:e}})=>{for(let{args:t,value:a}of e?.upserted??[]){let[i]=t;this.pegs.set(a,i)}}})}subscribeEmaOracles(){return this.api.query.EmaOracle.Oracles.watchEntries({at:"best"}).pipe(_t((e,t)=>!t.deltas),Z((e,t)=>({value:e,index:t})),Ke(({value:e,index:t})=>{t>0&&this.log.trace("emaOracle.Oracles",e.deltas?.upserted)}),this.watchGuard("emaOracle.Oracles")).subscribe(async({value:{deltas:e}})=>{let t=new Set;for(let{args:a,value:i}of e?.upserted??[]){let[s,n,r]=a;this.emaOracles.set(i,s,n,r);let o=Ft(s,n,r.type),c=this.mmRouting.byEma.get(o);c&&t.add(c)}for(let a of t){let i=await this.mmOracle.getData(a);this.log.trace("mmOracle.Hybrid",{h160:a,fresh:i}),this.mmOracles.set(i,a)}})}subscribeMMOracles(){return this.api.event.EVM.Log.watch().pipe(Z(({events:e})=>e.map(t=>de.parse(t.payload)).filter(t=>!!t).filter(({eventName:t})=>Ji.includes(t))),Xi(e=>e.length>0),this.watchGuard("evm.Log")).subscribe(async e=>{let t=new Set;for(let a of e){if(console.log(a),a.eventName==="ManagedOracle.PriceUpdated"){let i=this.mmRouting.byEmitter.get(a.emitter);i&&t.add(i)}if(a.eventName==="DIA.OracleUpdate"&&a.key){let i=this.mmRouting.byDiaKey.get(a.key);i&&t.add(i)}}for(let a of t){let i=await this.mmOracle.getData(a);this.log.trace("mmOracle",{h160:a,fresh:i}),this.mmOracles.set(i,a)}})}subscribeBlock(){return this.watcher.bestBlock$.pipe(this.watchGuard("watcher.bestBlock")).subscribe(e=>{this.store.update(async t=>{let a=[];for(let i of t){let s=this.poolsData.get(i.id);if(s){let n=await this.getPoolPegs(i.id,s,e),r=this.getPoolAmplification(s,e);a.push({...i,...n,...r})}}return a})})}subscribeUpdates(){let e=new Yi;return e.add(this.subscribePoolPegs()),e.add(this.subscribeEmaOracles()),e.add(this.subscribeMMOracles()),e.add(this.subscribeIssuance()),e.add(this.subscribeBlock()),e}};var kt={};F(kt,{XykMath:()=>C,XykPool:()=>ye,XykPoolClient:()=>fe});import{calculate_in_given_out as Zi,calculate_out_given_in as es,calculate_pool_trade_fee as ts,get_spot_price as as,calculate_liquidity_in as is,calculate_shares as ss,calculate_spot_price as ns,calculate_spot_price_with_fee as rs,calculate_liquidity_out_asset_a as os,calculate_liquidity_out_asset_b as ls}from"@galacticcouncil/math-xyk";var C=class{static getSpotPrice(e,t,a){return as(e,t,a)}static calculateInGivenOut(e,t,a){return Zi(e,t,a)}static calculateOutGivenIn(e,t,a){return es(e,t,a)}static calculatePoolTradeFee(e,t,a){return ts(e,t,a)}static calculateLiquidityIn(e,t,a){return is(e,t,a)}static calculateSpotPrice(e,t){return ns(e,t)}static calculateSpotPriceWithFee(e,t,a,i){return rs(e,t,a,i)}static calculateShares(e,t,a){return ss(e,t,a)}static calculateLiquidityOutAssetA(e,t,a,i){return os(e,t,a,i)}static calculateLiquidityOutAssetB(e,t,a,i){return ls(e,t,a,i)}};import{big as cs}from"@galacticcouncil/common";var{FeeUtils:Rt}=y,ye=class u{type;address;tokens;maxInRatio;maxOutRatio;minTradingLimit;static fromPool(e){return new u(e)}constructor(e){this.type="XYK",this.address=e.address,this.tokens=e.tokens,this.maxInRatio=e.maxInRatio,this.maxOutRatio=e.maxOutRatio,this.minTradingLimit=e.minTradingLimit}validatePair(e,t){return!0}parsePair(e,t){let a=new Map(this.tokens.map(n=>[n.id,n])),i=a.get(e),s=a.get(t);if(i==null)throw new Error("Pool does not contain tokenIn");if(s==null)throw new Error("Pool does not contain tokenOut");return{assetIn:e,assetOut:t,decimalsIn:i.decimals,decimalsOut:s.decimals,balanceIn:i.balance,balanceOut:s.balance,assetInEd:i.existentialDeposit,assetOutEd:s.existentialDeposit}}validateAndBuy(e,t,a){let i=this.calculateInGivenOut(e,t),s=this.calculateTradeFee(i,a),n=Rt.toPct(a.exchangeFee),r=i+s,o=[];(t<this.minTradingLimit||i<e.assetInEd)&&o.push("InsufficientTradingAmount");let c=e.balanceOut/this.maxOutRatio;t>c&&o.push("MaxOutRatioExceeded");let l=e.balanceIn/this.maxInRatio;return r>l&&o.push("MaxInRatioExceeded"),{amountIn:r,calculatedIn:i,amountOut:t,feePct:n,errors:o}}validateAndSell(e,t,a){let i=this.calculateOutGivenIn(e,t),s=this.calculateTradeFee(i,a),n=Rt.toPct(a.exchangeFee),r=i-s,o=[];(t<this.minTradingLimit||i<e.assetOutEd)&&o.push("InsufficientTradingAmount");let c=e.balanceIn/this.maxInRatio;t>c&&o.push("MaxInRatioExceeded");let l=e.balanceOut/this.maxOutRatio;return r>l&&o.push("MaxOutRatioExceeded"),{amountIn:t,calculatedOut:i,amountOut:r,feePct:n,errors:o}}calculateInGivenOut(e,t){let a=C.calculateInGivenOut(e.balanceIn.toString(),e.balanceOut.toString(),t.toString()),i=BigInt(a);return i<0n?0n:i}calculateOutGivenIn(e,t){let a=C.calculateOutGivenIn(e.balanceIn.toString(),e.balanceOut.toString(),t.toString()),i=BigInt(a);return i<0n?0n:i}spotPriceInGivenOut(e){let t=C.calculateSpotPrice(e.balanceOut.toString(),e.balanceIn.toString());return this.normalizeSpot(BigInt(t),e.decimalsOut,e.decimalsIn)}spotPriceOutGivenIn(e){let t=C.calculateSpotPrice(e.balanceIn.toString(),e.balanceOut.toString());return this.normalizeSpot(BigInt(t),e.decimalsIn,e.decimalsOut)}calculateTradeFee(e,t){let a=C.calculatePoolTradeFee(e.toString(),t.exchangeFee[0],t.exchangeFee[1]);return BigInt(a)}normalizeSpot(e,t,a){let i=t-a;if(i===0)return e;let s=cs.pow10(Math.abs(i));return i>0?e*s:e/s}};import{CompatibilityLevel as us}from"polkadot-api";import{Subscription as ps}from"rxjs";var fe=class extends S{decimals=new Map([]);getPoolType(){return"XYK"}async withOverride(e){this.decimals=e?new Map(e.map(t=>[t.id,t.decimals])):new Map}async getPoolLimits(){let[e,t,a]=await Promise.all([this.api.constants.XYK.MaxInRatio(),this.api.constants.XYK.MaxOutRatio(),this.api.constants.XYK.MinTradingLimit()]);return{maxInRatio:e,maxOutRatio:t,minTradingLimit:a}}async isSupported(){return(await this.api.getStaticApis()).compat.query.XYK.PoolAssets.isCompatible(us.BackwardsCompatible)}async loadPools(){let[e,t]=await Promise.all([this.api.query.XYK.PoolAssets.getEntries({at:this.at}),this.getPoolLimits()]),a=e.map(async({keyArgs:i,value:s})=>{let[n]=i,[r,o]=s,[c,l,p,m]=await Promise.all([this.balance.getBalance(n,r),this.api.query.AssetRegistry.Assets.getValue(r,{at:this.at}),this.balance.getBalance(n,o),this.api.query.AssetRegistry.Assets.getValue(o,{at:this.at})]);return{address:n,type:"XYK",tokens:[{id:r,decimals:l?.decimals||this.decimals.get(r),existentialDeposit:l?.existential_deposit,balance:c.transferable,type:l?.asset_type.type},{id:o,decimals:m?.decimals||this.decimals.get(o),existentialDeposit:m?.existential_deposit,balance:p.transferable,type:m?.asset_type.type}],...t}});return Promise.all(a)}async getPoolFees(){return{exchangeFee:await this.getExchangeFee()}}async getExchangeFee(){return await this.api.constants.XYK.GetExchangeFee()}subscribeUpdates(){return ps.EMPTY}};var Nt={};F(Nt,{AavePool:()=>Pe,AavePoolClient:()=>ve});import{big as Ct,RUNTIME_DECIMALS as Mt}from"@galacticcouncil/common";var Pe=class u{type;address;tokens;maxInRatio;maxOutRatio;minTradingLimit;static fromPool(e){return new u(e)}constructor(e){this.type="Aave",this.address=e.address,this.tokens=e.tokens,this.maxInRatio=e.maxInRatio,this.maxOutRatio=e.maxOutRatio,this.minTradingLimit=e.minTradingLimit}validatePair(e,t){return!0}parsePair(e,t){let a=new Map(this.tokens.map(n=>[n.id,n])),i=a.get(e),s=a.get(t);if(i==null)throw new Error("Pool does not contain tokenIn");if(s==null)throw new Error("Pool does not contain tokenOut");return{assetIn:e,assetOut:t,balanceIn:i.balance,balanceOut:s.balance,decimalsIn:i.decimals,decimalsOut:s.decimals,assetInEd:0n,assetOutEd:0n}}validateAndBuy(e,t,a){let i=this.calculateInGivenOut(e,t),s=[];return t>e.balanceOut&&s.push("TradeNotAllowed"),{amountIn:i,calculatedIn:i,amountOut:t,feePct:0,errors:s}}validateAndSell(e,t,a){let i=this.calculateOutGivenIn(e,t),s=[];return i>e.balanceOut&&s.push("TradeNotAllowed"),{amountIn:t,calculatedOut:i,amountOut:i,feePct:0,errors:s}}calculateInGivenOut(e,t){return t}calculateOutGivenIn(e,t){return t}spotPriceInGivenOut(e){return Ct.toBigInt(1,Mt)}spotPriceOutGivenIn(e){return Ct.toBigInt(1,Mt)}calculateTradeFee(e,t){return 0n}};import{AccountId as hs}from"polkadot-api";import{toHex as ys}from"@polkadot-api/utils";import{Subscription as Lt,filter as je,map as Dt,mergeMap as Ht}from"rxjs";import{erc20 as fs,HYDRATION_SS58_PREFIX as Ps}from"@galacticcouncil/common";var ze=[{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"},{inputs:[{internalType:"address",name:"asset",type:"address"},{internalType:"uint256",name:"amount",type:"uint256"},{internalType:"address",name:"to",type:"address"}],name:"withdraw",outputs:[{internalType:"uint256",name:"",type:"uint256"}],stateMutability:"nonpayable",type:"function"},{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"},{inputs:[{internalType:"address",name:"asset",type:"address"},{internalType:"uint256",name:"amount",type:"uint256"},{internalType:"uint256",name:"interestRateMode",type:"uint256"},{internalType:"uint16",name:"referralCode",type:"uint16"},{internalType:"address",name:"onBehalfOf",type:"address"}],name:"borrow",outputs:[],stateMutability:"nonpayable",type:"function"},{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"},{inputs:[{internalType:"address",name:"user",type:"address"}],name:"getUserAccountData",outputs:[{internalType:"uint256",name:"totalCollateralBase",type:"uint256"},{internalType:"uint256",name:"totalDebtBase",type:"uint256"},{internalType:"uint256",name:"availableBorrowsBase",type:"uint256"},{internalType:"uint256",name:"currentLiquidationThreshold",type:"uint256"},{internalType:"uint256",name:"ltv",type:"uint256"},{internalType:"uint256",name:"healthFactor",type:"uint256"}],stateMutability:"view",type:"function"}];var Lu=BigInt("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");import{Binary as ms}from"polkadot-api";import{decodeEventLog as ds}from"viem";var ke=class{static parse(e){let{topics:t,data:a}=e.log,i=ms.toHex(a);try{let{eventName:s,args:n}=ds({abi:ze,topics:t,data:i}),r=n.reserve.toLowerCase();return{eventName:s,reserve:r,key:`${s}:${r}`}}catch{return}}};import ep from"big.js";import{big as ap,erc20 as gs,h160 as bs}from"@galacticcouncil/common";var{ERC20:sp}=gs,{H160:np}=bs;var rp=10n**27n;var{ERC20:vs}=fs,Ss=["Supply","Withdraw","Repay","Borrow"],ve=class extends S{getPoolType(){return"Aave"}async isSupported(){return!0}getPoolId(e,t){let a=e+"/"+t,i=new TextEncoder().encode(a.padEnd(32,"\0")),s=ys(i);return hs(Ps).dec(s)}getPoolLimits(){return{maxInRatio:0n,maxOutRatio:0n,minTradingLimit:0n}}async loadPools(){let t=(await this.api.apis.AaveTradeExecutor.pools({at:this.at})).map(async({reserve:a,atoken:i,liqudity_in:s,liqudity_out:n})=>{let[r,o,c,l]=await Promise.all([this.api.query.AssetRegistry.Assets.getValue(a,{at:this.at}),this.api.query.AssetRegistry.AssetLocations.getValue(a,{at:this.at}),this.api.query.AssetRegistry.Assets.getValue(i,{at:this.at}),this.api.query.AssetRegistry.AssetLocations.getValue(i,{at:this.at})]);return{address:this.getPoolId(a,i),type:"Aave",tokens:[{id:a,decimals:r?.decimals,existentialDeposit:r?.existential_deposit,balance:s,location:o,type:r?.asset_type.type},{id:i,decimals:c?.decimals,existentialDeposit:c?.existential_deposit,balance:n,location:l,type:c?.asset_type.type}],...this.getPoolLimits()}});return Promise.all(t)}async getPoolDelta(e){let[t,a]=e.tokens,{liqudity_in:i,liqudity_out:s}=await this.api.apis.AaveTradeExecutor.pool(t.id,a.id,{at:this.at});return e.tokens.map(n=>{let r=n.id===t.id?i:s;return{...n,balance:r}})}async getPoolFees(){return{}}getReserveH160Id(e){if(e.type==="Erc20"&&e.location){let t=e.location.interior;if(t.type==="X1"&&t.value.type==="AccountKey20"){let{value:a}=t.value;return a.key}throw new Error("Invalid aave reserve multilocation")}return vs.fromAssetId(e.id)}parseRouterLog(e){let{asset_in:t,asset_out:a}=e;return{assetIn:t,assetOut:a,key:`${t}:${a}`}}subscribeRouterExecuted(){let t=this.store.pools.map(a=>a.tokens).map(([a,i])=>i).map(a=>a.id);return this.api.event.Router.Executed.watch().pipe(Ht(({events:a})=>a),Dt(({payload:a})=>this.parseRouterLog(a)),je(({assetIn:a,assetOut:i})=>t.includes(a)||t.includes(i)),this.watchGuard("router.Execute")).subscribe(({assetIn:a,assetOut:i,key:s})=>{this.log.trace("router.Executed",s),this.store.update(async n=>{let r=[];for(let o of n){let[c,l]=o.tokens;if(l.id===a||l.id===i){let m=await this.getPoolDelta(o);r.push({...o,tokens:m})}}return r})})}subscribeEvmLog(){return this.api.event.EVM.Log.watch().pipe(Ht(({events:e})=>e),Dt(({payload:e})=>ke.parse(e)),je(e=>e!==void 0),je(({eventName:e})=>Ss.includes(e)),this.watchGuard("evm.Log")).subscribe(({reserve:e,eventName:t})=>{this.log.trace(`evm.Log.${t}`,e),this.store.update(async a=>{let i=[];for(let s of a){let[n]=s.tokens;if(this.getReserveH160Id(n).toLowerCase()===e){let o=await this.getPoolDelta(s);i.push({...s,tokens:o})}}return i})})}subscribeBalances(){return Lt.EMPTY}subscribeUpdates(){let e=new Lt;return e.add(this.subscribeRouterExecuted()),e.add(this.subscribeEvmLog()),e}};var Vt={};F(Vt,{HsmMath:()=>T,HsmPool:()=>Se,HsmPoolClient:()=>Te});import{calculate_collateral_in_given_hollar_out as Ts,calculate_collateral_out_given_hollar_in as xs,calculate_hollar_in_given_collateral_out as As,calculate_hollar_out_given_collateral_in as Is,calculate_imbalance as ws,calculate_max_price as Os,calculate_buyback_limit as Bs,calculate_buyback_price_with_fee as Fs}from"@galacticcouncil/math-hsm";var T=class{static calculateCollateralInGivenHollarOut(e,t,a){return Ts(e,t,a)}static calculateCollateralOutGivenHollarIn(e,t,a){return xs(e,t,a)}static calculateHollarOutGivenCollateralIn(e,t,a){return Is(e,t,a)}static calculateHollarInGivenCollateralOut(e,t,a){return As(e,t,a)}static calculateImbalance(e,t,a){return ws(e,t,a)}static calculateBuybackLimit(e,t){return Bs(e,t)}static calculateBuybackPriceWithFee(e,t,a){return Fs(e,t,a)}static calculateMaxPrice(e,t){return Os(e,t)}};import{big as M,RUNTIME_DECIMALS as Ce}from"@galacticcouncil/common";var{FeeUtils:ee}=y,Se=class u extends G{hsmAddress;hsmMintCapacity;hollarId;hollarH160;collateralId;collateralBalance;maxBuyPriceCoefficient;maxInHolding;purchaseFee;buyBackFee;buyBackRate;static fromPool(e){return new u(e)}constructor(e){super(e),this.type="HSM",this.hsmAddress=e.hsmAddress,this.hsmMintCapacity=e.hsmMintCapacity,this.hollarId=e.hollarId,this.hollarH160=e.hollarH160,this.collateralId=e.collateralId,this.collateralBalance=e.collateralBalance,this.maxBuyPriceCoefficient=e.maxBuyPriceCoefficient,this.maxInHolding=e.maxInHolding,this.purchaseFee=e.purchaseFee,this.buyBackFee=e.buyBackFee,this.buyBackRate=e.buyBackRate}validatePair(e,t){return!0}parsePair(e,t){return super.parsePair(e,t)}validateTradeHollarIn(e,t,a){let i=this.parsePair(e.assetOut,e.assetIn),s=super.calculateInGivenOut(i,t,{fee:this.fee}),n=this.calculateBuybackLimit(e);t>n&&a.push("MaxBuyBackExceeded");let r=this.calculateMaxPrice(e);return this.calculateBuyPrice(e,t,s)>r&&a.push("MaxBuyPriceExceeded"),s>this.collateralBalance&&a.push("InsufficientCollateral"),a}validateTradeHollarOut(e,t,a){return this.collateralBalance+e>this.maxInHolding&&a.push("MaxHoldingExceeded"),t>this.hsmMintCapacity&&a.push("FacilitatorCapacityExceeded"),a}validateTradeConstraints(e,t,a){let i=[];return e.assetIn===this.hollarId?this.validateTradeHollarIn(e,t,i):this.validateTradeHollarOut(t,a,i)}validateAndBuy(e,t){let a=this.calculateInGivenOut(e,t),i=this.validateTradeConstraints(e,a,t);return{amountIn:a,calculatedIn:a,amountOut:t,feePct:0,errors:i}}validateAndSell(e,t){let a=this.calculateOutGivenIn(e,t),i=this.validateTradeConstraints(e,t,a);return{amountIn:t,calculatedOut:a,amountOut:a,feePct:0,errors:i}}calculateHollarInGivenCollateralOut(e,t){let a=super.calculateInGivenOut(e,t,{fee:this.fee}),i=T.calculateHollarInGivenCollateralOut(t.toString(),a.toString(),ee.toRaw(this.buyBackFee).toString());return BigInt(i)}calculateCollateralInGivenHollarOut(e){let t=this.getCollateralPeg(),a=T.calculateCollateralInGivenHollarOut(e.toString(),JSON.stringify(t),ee.toRaw(this.purchaseFee).toString());return BigInt(a)}calculateInGivenOut(e,t){return e.assetOut==this.hollarId?this.calculateCollateralInGivenHollarOut(t):this.calculateHollarInGivenCollateralOut(e,t)}calculateCollateralOutGivenHollarIn(e,t){let a=super.calculateOutGivenIn(e,t,{fee:this.fee}),i=T.calculateCollateralOutGivenHollarIn(t.toString(),a.toString(),ee.toRaw(this.buyBackFee).toString());return BigInt(i)}calculateHollarOutGivenCollateralIn(e){let t=this.getCollateralPeg(),a=T.calculateHollarOutGivenCollateralIn(e.toString(),JSON.stringify(t),ee.toRaw(this.purchaseFee).toString());return BigInt(a)}calculateOutGivenIn(e,t){return e.assetIn==this.hollarId?this.calculateCollateralOutGivenHollarIn(e,t):this.calculateHollarOutGivenCollateralIn(t)}calculateImbalance(e){let t=this.getCollateralPeg(),a=T.calculateImbalance(e.balanceIn.toString(),JSON.stringify(t),e.balanceOut.toString());return BigInt(a)}calculateBuybackLimit(e){let t=this.calculateImbalance(e),a=T.calculateBuybackLimit(t.toString(),ee.toRaw(this.buyBackRate).toString());return BigInt(a)}calculateBuyPrice(e,t,a){let i=T.calculateBuybackPriceWithFee(a.toString(),t.toString(),ee.toRaw(this.buyBackFee).toString()),[s,n]=JSON.parse(i),r=M.pow10(e.decimalsIn+Ce-e.decimalsOut);return BigInt(s)*r/BigInt(n)}calculateMaxPrice(e){let t=this.getCollateralPeg(),a=T.calculateMaxPrice(JSON.stringify(t),this.maxBuyPriceCoefficient.toString()),[i,s]=JSON.parse(a),n=M.pow10(Ce-e.decimalsOut);return BigInt(i)*n/BigInt(s)}spotPriceInGivenOut(e){let t=M.toBigInt(1,e.decimalsOut),i=this.calculateInGivenOut(e,t)*M.pow10(Ce-e.decimalsOut);return this.normalizeSpotPrice(i,e.decimalsOut,e.decimalsIn)}spotPriceOutGivenIn(e){let t=M.toBigInt(1,e.decimalsIn),i=this.calculateOutGivenIn(e,t)*M.pow10(Ce-e.decimalsIn);return this.normalizeSpotPrice(i,e.decimalsIn,e.decimalsOut)}getCollateralPeg(){let e=this.tokens.findIndex(i=>i.id!==this.hollarId),t=this.pegs[e],a=this.tokens[e].decimals;return this.isDefaultPeg(t)?[M.toBigInt(1,18).toString(),M.toBigInt(1,a).toString()]:t}isDefaultPeg(e){let[t,a]=e;return Array.isArray(e)&&e.length===2&&t==="1"&&a==="1"}normalizeSpotPrice(e,t,a){let i=t-a;if(i===0)return e;let s=M.pow10(Math.abs(i));return i>0?e*s:e/s}};import{AccountId as Rs,CompatibilityLevel as ks}from"polkadot-api";import{toHex as Cs}from"@polkadot-api/utils";import{Subscription as Qe,combineLatest as Ms,filter as qt,map as Je,mergeMap as Ls,pairwise as Ds}from"rxjs";import{h160 as Hs,HYDRATION_SS58_PREFIX as Ns}from"@galacticcouncil/common";import{Binary as _s}from"polkadot-api";import{decodeEventLog as Es}from"viem";var Me=[{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 Le=class{static parse(e){let{topics:t,data:a}=e.log,i=_s.toHex(a);try{let{eventName:s,args:n}=Es({abi:Me,topics:t,data:i}),r=n.facilitatorAddress.toLowerCase();return{eventName:s,facilitator:r,key:`${s}:${r}`}}catch{return}}};var De=class{client;constructor(e){this.client=e.getWsProvider()}async getFacilitatorCapacity(e,t){let[a,i]=await this.client.readContract({abi:Me,address:e,functionName:"getFacilitatorBucket",args:[t]});return a-i}};var{FeeUtils:Ze}=y,{H160:Gt}=Hs,qs=["FacilitatorBucketCapacityUpdated","FacilitatorBucketLevelUpdated"],Te=class extends S{ghoClient;stableClient;constructor(e,t,a,i){super(e,t,i),this.stableClient=a,this.ghoClient=new De(t)}getPoolType(){return"HSM"}getPoolId(e){return this.getPoolAddress("hsm:"+e)}getFacilitatorAddress(){return this.getPoolAddress("modlpy/hsmod")}getHollarAddress(e){if(e){let t=e.interior;if(t.type==="X1"&&t.value.type==="AccountKey20"){let{value:a}=t.value;return a.key}}throw Error("Invalid hollar multilocation")}getPoolAddress(e){let t=e.padEnd(32,"\0"),a=new TextEncoder().encode(t),i=Cs(a);return Rs(Ns).dec(i)}async isSupported(){return(await this.api.getStaticApis()).compat.query.HSM.Collaterals.isCompatible(ks.BackwardsCompatible)}async loadPools(){let e=await this.api.constants.HSM.HollarId(),[t,a,i]=await Promise.all([this.api.query.AssetRegistry.AssetLocations.getValue(e,{at:this.at}),this.api.query.HSM.Collaterals.getEntries({at:this.at}),this.stableClient.getPools()]);if(a.length===0)return[];let s=this.getFacilitatorAddress(),n=Gt.fromAny(s),r=this.getHollarAddress(t),o=await this.ghoClient.getFacilitatorCapacity(r,n),c=a.map(async({keyArgs:p,value:m})=>{let[d]=p,{pool_id:g,max_buy_price_coefficient:b,max_in_holding:B,purchase_fee:x,buy_back_fee:A,buyback_rate:I}=m,w=i.find(D=>D.id===g);if(w){let D=this.getPoolId(g),ae=await this.balance.getBalance(s,d);return{...w,address:D,type:"HSM",tokens:w.tokens.filter(Ut=>Ut.id!==g),hsmAddress:s,hsmMintCapacity:o,hollarId:e,hollarH160:r,collateralId:d,collateralBalance:ae.transferable,maxBuyPriceCoefficient:b,maxInHolding:B,purchaseFee:Ze.fromPermill(x),buyBackFee:Ze.fromPermill(A),buyBackRate:Ze.fromPerbill(I)}}});return(await Promise.all(c)).filter(p=>p!==null)}async getPoolFees(){return{}}subscribeEvmLog(){return this.api.event.EVM.Log.watch().pipe(Ls(({events:e})=>e),Je(({payload:e})=>Le.parse(e)),qt(e=>e!==void 0),qt(({eventName:e})=>qs.includes(e)),this.watchGuard("evm.Log")).subscribe(({eventName:e,facilitator:t})=>{this.log.trace(`evm.Log.${e}`,t),this.store.update(async a=>{let i=[],[{hsmAddress:s,hollarH160:n}]=a,r=Gt.fromAny(s);if(r.toLowerCase()===t){let c=await this.ghoClient.getFacilitatorCapacity(n,r);for(let l of a)i.push({...l,hsmMintCapacity:c})}return i})})}subscribeCollateralBalance(){let e=[],t=[];this.store.pools.forEach(s=>{let{tokens:n,collateralId:r}=s;n.find(c=>c.id===r).type==="Erc20"?t.push(r):e.push(r)});let[{hsmAddress:a}]=this.store.pools,i=[];if(e.length>0){let s=this.balance.watchTokensBalance(a);i.push(s)}if(t.length>0){let s=this.balance.watchErc20Balance(a,t);i.push(s)}return i.length>0?Ms(i).pipe(Je(s=>s.flat()),Ds(),Je(([s,n])=>this.balance.getDeltas(s,n)),this.watchGuard("balances")).subscribe(s=>{this.store.update(n=>{let r=[],o=new Map(n.map(c=>[c.collateralId,c]));return s.forEach(({id:c,balance:l})=>{let p=o.get(c);p&&(this.log.trace("balances",{id:c,balance:l}),r.push({...p,collateralBalance:l.transferable}))}),r})}):Qe.EMPTY}subscribeStableswapUpdates(){return this.stableClient.getSubscriber().pipe(this.watchGuard("stableswap.updates")).subscribe(e=>{let t=new Map(e.map(a=>[a.id,a]));this.store.update(a=>{let i=[];for(let s of a){let n=t.get(s.id);n&&i.push({...s,fee:n.fee,tokens:n.tokens.filter(r=>r.id!==s.id),totalIssuance:n.totalIssuance,pegs:n.pegs,amplification:n.amplification,isRampPeriod:n.isRampPeriod})}return i})})}subscribeBalances(){return Qe.EMPTY}subscribeUpdates(){let e=new Qe;return e.add(this.subscribeCollateralBalance()),e.add(this.subscribeStableswapUpdates()),e.add(this.subscribeEvmLog()),e}};var et=class{static get(e){switch(e.type){case"Aave":return Pe.fromPool(e);case"XYK":return ye.fromPool(e);case"Omnipool":return pe.fromPool(e);case"LBP":return se.fromPool(e);case"Stableswap":return G.fromPool(e);case"HSM":return Se.fromPool(e);default:throw new Error("Pool type "+e.type+" is not supported yet")}}};import{log as Gs}from"@galacticcouncil/common";import{Subject as Vs,Subscription as V,takeUntil as Us}from"rxjs";var te=class extends Error{constructor(e){super(),this.message=`${e} pool invalid`,this.name="PoolNotFound"}};var{logger:$s}=Gs,tt=class extends _{evm;aave;omnipool;stableswap;hsm;xyk;lbp;active=new Set([]);pools=new Map([]);clients=[];aaveSub=V.EMPTY;omniSub=V.EMPTY;stableSub=V.EMPTY;hsmSub=V.EMPTY;xykSub=V.EMPTY;lbpSub=V.EMPTY;isReady=!1;isDestroyed=new Vs;constructor(e,t,a){super(e,a),this.evm=t,this.aave=new ve(e,t,a),this.omnipool=new me(e,t,a),this.stableswap=new he(e,t,a),this.hsm=new Te(e,t,this.stableswap,a),this.xyk=new fe(e,t,a),this.lbp=new ue(e,t,a),this.clients=[this.aave,this.omnipool,this.stableswap,this.hsm,this.xyk,this.lbp]}get isHistorical(){return this.at!=="best"&&this.at!=="finalized"}subscribe(e){return this.isHistorical?V.EMPTY:e.getSubscriber().pipe(Us(this.isDestroyed)).subscribe(t=>{t.forEach(a=>{this.pools.set(a.address,a)})})}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")||($s.info("[PoolContextProvider] auto-activating stableswap"),this.withStableswap()),this.hsmSub.unsubscribe(),this.hsmSub=this.subscribe(this.hsm),this.active.add("HSM"),this}withXyk(e){return this.xyk.withOverride(e),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 t=this.pools.values();return Array.from(t)}let e=await Promise.all(this.clients.filter(t=>this.active.has(t.getPoolType())).map(t=>t.getPools()));return this.isReady=!0,e.flat()}async getPoolFees(e,t){let a=this.clients.find(i=>i.getPoolType()===t.type);if(a)return a.getPoolFees(e,t.address);throw new te(t.type)}};var at=class{constructor(e){this.snapshot=e;let{aave:t,xyk:a,lbp:i,stable:s,omni:n}=e.pools;this.flat=[...t,...a,...i,...s,...n]}flat;async getPools(){return this.flat}async getPoolFees(e,t){let{block:a,states:i}=this.snapshot;switch(t.type){case"Aave":return{};case"XYK":{let{exchangeFee:s}=i.xyk;return{exchangeFee:s}}case"LBP":{let{repayFee:s}=i.lbp;return{exchangeFee:t.fee,repayFee:s}}case"Stableswap":return{fee:t.fee};case"Omnipool":{let s=e.assetOut,n=e.assetIn,{dynamicFees:r,emaOracles:o,assetFeeParams:c,protocolFeeParams:l,maxSlipFee:p}=i.omni,m=r.find(({asset:b})=>b===s)?.fee,d=o.find(({pair:b})=>b.join(":")===_e(s))?.oracle,g=o.find(({pair:b})=>b.join(":")===_e(n))?.oracle;return q.compute(e,a,m,d,g,c,l,p)}default:throw new te(t.type)}}};export{tt as PoolContextProvider,H as PoolError,et as PoolFactory,f as PoolType,at as SnapshotPoolCtxProvider,Nt as aave,Vt as hsm,yt as lbp,St as omni,Et as stable,kt as xyk};
1
+ var di=Object.defineProperty;var F=(u,t)=>{for(var e in t)di(u,e,{get:t[e],enumerable:!0})};import gi from"buffer";typeof window<"u"&&(window.Buffer=gi.Buffer);var Fe={};F(Fe,{LbpMath:()=>E,LbpPool:()=>ct,LbpPoolClient:()=>bt});import{calculate_in_given_out as bi,calculate_out_given_in as hi,calculate_linear_weights as yi,calculate_pool_trade_fee as fi,get_spot_price as Pi}from"@galacticcouncil/math-lbp";var E=class{static getSpotPrice(t,e,i,a,s){return Pi(t,e,i,a,s)}static calculateInGivenOut(t,e,i,a,s){return bi(t,e,i,a,s)}static calculateOutGivenIn(t,e,i,a,s){return hi(t,e,i,a,s)}static calculateLinearWeights(t,e,i,a,s){return yi(t,e,i,a,s)}static calculatePoolTradeFee(t,e,i){return fi(t,e,i)}};import{big as fe,RUNTIME_DECIMALS as Pe}from"@galacticcouncil/common";var P=(n=>(n.Aave="Aave",n.LBP="LBP",n.Omni="Omnipool",n.Stable="Stableswap",n.XYK="XYK",n.HSM="HSM",n.V3="UniswapV3",n))(P||{}),V=(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))(V||{});var Ft={};F(Ft,{withTimeout:()=>Si});function Si(u,t,e="timeout"){return new Promise((i,a)=>{let s=setTimeout(()=>a(new Error(e)),t);u.then(r=>{clearTimeout(s),i(r)},r=>{clearTimeout(s),a(r)})})}import{RUNTIME_DECIMALS as Dn}from"@galacticcouncil/common";var f={};F(f,{FeeUtils:()=>Yt,shiftNeg:()=>Ii});import xi from"big.js";var Yt=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 a=10**i;return Math.round(t*a/e)/a}static safeRound(t){return parseFloat(t.toPrecision(15))}};function Ii(u,t){let e=xi(typeof u=="bigint"?u.toString():u);return t===0?e.toString():e.div(Math.pow(10,t)).toString()}var lt={};F(lt,{findNestedKey:()=>wi,findNestedObj:()=>Ai,jsonFormatter:()=>Oi});var wi=(u,t)=>{let e=[];return JSON.stringify(u,(i,a)=>(a&&a[t]&&e.push(a),a)),e[0]},Ai=(u,t,e)=>{let i;return JSON.stringify(u,(a,s)=>(s&&s[t]===e&&(i=s),s)),i},Oi=(u,t)=>typeof t=="bigint"?t.toString():t;var R={};F(R,{calculateBuyFee:()=>Fi,calculateDiffToAvg:()=>Bi,calculateDiffToRef:()=>_i,calculateSellFee:()=>ki});import D from"big.js";function Bi(u,t){let e=D(u.toString()),i=D(t.toString());return e.minus(i).abs().div(e.plus(i).div(2)).mul(100).round(2).toNumber()}function _i(u,t){if(t===0n)return 0;let e=D(u.toString()),i=D(t.toString());return e.minus(i).div(i).mul(100).round(2).toNumber()}function ki(u,t){if(u===0n)return 0;let e=D(u.toString()),i=D(t.toString());return D(1).minus(i.div(e)).mul(100).round(2).toNumber()}function Fi(u,t){if(u===0n)return 0;let e=D(u.toString());return D(t.toString()).div(e).minus(1).mul(100).round(2).toNumber()}import{TLRUCache as ye}from"@thi.ng/cache";var z=class{debug;constructor(t){this.debug=t||!1}log(t,e,i){this.debug&&console.log(t,e,i)}scope(t,e,i,a){let s=new Map,r=a!==void 0?new ye(null,{ttl:a}):new ye;return{get:(...c)=>{let m=i(...c);if(s.has(m)){this.log("[live]",t,m);let p=s.get(m);return Promise.resolve(p)}if(r.has(m))return this.log("[memo]",t,m),r.get(m);this.log("[fetch]",t,m);let g=e(...c).catch(p=>{throw r.delete(m),p});return r.set(m,g),g},set:(c,...m)=>{let g=i(...m);this.log("[set-live]",t,g),s.set(g,c)},clear:()=>{this.log("[clear]",t),s.clear(),r.release()}}}};var{FeeUtils:Se}=f,ct=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(r=>[r.id,r])),a=i.get(t),s=i.get(e);if(a==null)throw new Error("Pool does not contain tokenIn");if(s==null)throw new Error("Pool does not contain tokenOut");return{assetIn:t,assetOut:e,balanceIn:a.balance,balanceOut:s.balance,decimalsIn:a.decimals,decimalsOut:s.decimals,weightIn:a.weight,weightOut:s.weight}}validateAndBuy(t,e,i){let a=this.tokens[0].id,s=[];e<this.minTradingLimit&&s.push("InsufficientTradingAmount");let r=t.balanceOut/this.maxOutRatio;if(e>r&&s.push("MaxOutRatioExceeded"),a===t.assetOut){let n=this.calculateTradeFee(e,i),o=Se.toPct(this.repayFeeApply?i.repayFee:i.exchangeFee),l=e+n,c=this.calculateInGivenOut(t,l),m=t.balanceIn/this.maxInRatio;return c>m&&s.push("MaxInRatioExceeded"),{amountIn:c,calculatedIn:c,amountOut:e,feePct:o,errors:s}}else{let n=this.calculateInGivenOut(t,e),o=t.balanceIn/this.maxInRatio;return n>o&&s.push("MaxInRatioExceeded"),{amountIn:n,calculatedIn:n,amountOut:e,feePct:0,errors:s}}}validateAndSell(t,e,i){let a=this.tokens[0].id,s=[];e<this.minTradingLimit&&s.push("InsufficientTradingAmount");let r=t.balanceIn/this.maxInRatio;if(e>r&&s.push("MaxInRatioExceeded"),a===t.assetIn){let n=this.calculateOutGivenIn(t,e),o=t.balanceOut/this.maxOutRatio;return n>o&&s.push("MaxOutRatioExceeded"),{amountIn:e,calculatedOut:n,amountOut:n,feePct:0,errors:s}}else{let n=this.calculateOutGivenIn(t,e),o=this.calculateTradeFee(n,i),l=Se.toPct(this.repayFeeApply?i.repayFee:i.exchangeFee),c=n-o,m=t.balanceOut/this.maxOutRatio;return c>m&&s.push("MaxOutRatioExceeded"),{amountIn:e,calculatedOut:n,amountOut:c,feePct:l,errors:s}}}calculateInGivenOut(t,e){let i=E.calculateInGivenOut(t.balanceIn.toString(),t.balanceOut.toString(),t.weightIn.toString(),t.weightOut.toString(),e.toString()),a=BigInt(i);return a<0n?0n:a}calculateOutGivenIn(t,e){let i=E.calculateOutGivenIn(t.balanceIn.toString(),t.balanceOut.toString(),t.weightIn.toString(),t.weightOut.toString(),e.toString()),a=BigInt(i);return a<0n?0n:a}spotPriceInGivenOut(t){let e=E.getSpotPrice(t.balanceOut.toString(),t.balanceIn.toString(),t.weightOut.toString(),t.weightIn.toString(),fe.toBigInt(1,Pe).toString());return BigInt(e)}spotPriceOutGivenIn(t){let e=E.getSpotPrice(t.balanceIn.toString(),t.balanceOut.toString(),t.weightIn.toString(),t.weightOut.toString(),fe.toBigInt(1,Pe).toString());return BigInt(e)}calculateTradeFee(t,e){let i=E.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 Ta}from"polkadot-api";import{Subscription as xa,distinctUntilChanged as Ia,filter as wa,map as Aa}from"rxjs";import{memoize1 as oa}from"@thi.ng/memoize";import{TLRUCache as la}from"@thi.ng/cache";import{ReplaySubject as Be,Subscription as _e,combineLatest as ca,defer as ua,from as ma,interval as pa,merge as zt,of as da,EMPTY as dt}from"rxjs";import{bufferCount as ga,bufferTime as ba,catchError as gt,filter as Lt,finalize as jt,map as J,pairwise as Qt,repeat as Jt,skip as ha,share as ya,startWith as fa,switchMap as ke,tap as $,throttleTime as Pa}from"rxjs/operators";import{hydration as Yi,hydrationNext as Ki,hydrationIce as zi}from"@galacticcouncil/descriptors";import{log as Hi}from"@galacticcouncil/common";import{map as Ui,shareReplay as $i,tap as Wi}from"rxjs";import{defer as Ei,from as Ri,of as ve,timer as Ci}from"rxjs";import{catchError as Mi,distinctUntilChanged as Li,expand as Di,map as Kt,shareReplay as qi,skip as Ni,switchMap as Vi,timeout as Gi}from"rxjs/operators";function Te(u,{intervalMs:t=5e3,rpcTimeoutMs:e=1e4}={}){let i=()=>Ei(()=>Ri(u._request("system_health",[]))).pipe(Gi({first:e}),Kt(()=>"online"),Mi(()=>ve("offline")));return ve({state:"offline",delayMs:0}).pipe(Di(s=>Ci(s.delayMs).pipe(Vi(i),Kt(r=>({state:r,delayMs:t})))),Ni(1),Kt(s=>s.state),Li(),qi({bufferSize:1,refCount:!0}))}var{logger:Xi}=Hi,Et=class u{static instance=null;bestBlock$;finalizedBlock$;connection$;constructor(t){this.bestBlock$=this.watched("watcher(bestBlock)",t.getUnsafeApi().query.System.Number.watchValue({at:"best"}).pipe(Ui(({value:e})=>e))),this.finalizedBlock$=this.watched("watcher(finalizedBlock)",t.finalizedBlock$),this.connection$=this.watched("watcher(connection)",Te(t))}static getInstance(t){return this.instance||(this.instance=new u(t)),this.instance}watched(t,e){return e.pipe(Wi({error:i=>Xi.error(t,i)}),$i({bufferSize:1,refCount:!0}))}};var C=class{client;api;apiNext;apiIce;watcher;at;constructor(t,e){this.client=t,this.api=this.client.getTypedApi(Yi),this.apiNext=this.client.getTypedApi(Ki),this.apiIce=this.client.getTypedApi(zi),this.watcher=Et.getInstance(this.client),this.at=e??"best"}};import{getWsProvider as _r}from"polkadot-api/ws";import{withLogsRecorder as Fr}from"polkadot-api/logs-provider";import{Binary as Xr}from"polkadot-api";import{log as ji}from"@galacticcouncil/common";import{combineLatest as Qi,concat as Ji,defer as ut,from as xe}from"rxjs";import{bufferCount as Ie,distinctUntilChanged as we,debounceTime as Zi,map as j,retry as ta,startWith as Ae,switchMap as Oe,tap as mt,take as ea,skip as ia,connect as aa}from"rxjs/operators";var{logger:Q}=ji,pt=class extends C{erc20Ids=null;constructor(t,e){super(t,e)}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:this.at});return this.getBreakdown(i)}async getTokenBalance(t,e){let a=await this.api.query.Tokens.Accounts.getValue(t,e,{at:this.at});return this.getBreakdown(a)}async getErc20Balance(t,e){return this.getBalanceData(t,e)}watchBalance(t){return ut(()=>{let e=this.watchSystemBalance(t),i=this.watchTokensBalance(t),a=this.watchErc20Balance(t);return Qi([e,i,a]).pipe(aa(s=>Ji(s.pipe(ea(1)),s.pipe(ia(1),Zi(250)))))}).pipe(j(e=>e.flat()),Ae([]),Ie(2,1),j(([e,i],a)=>a===0?i:this.getDeltas(e,i))).pipe(mt({subscribe:()=>Q.debug("balance: subscribe",t),error:e=>Q.error("balance",e)}),ta({delay:1e3}))}watchSystemBalance(t){let e=this.api.query.System.Account;return ut(()=>e.watchValue(t,{at:"best"})).pipe(j(({value:i})=>({id:0,balance:this.getBreakdown(i.data)})),mt({error:i=>Q.error("balance(system)",i)}))}watchTokenBalance(t,e){let i=this.api.query.Tokens.Accounts;return ut(()=>i.watchValue(t,e,{at:"best"})).pipe(j(({value:a})=>({id:e,balance:this.getBreakdown(a)})),mt({error:a=>Q.error("balance(token)",a)}))}watchTokensBalance(t){let e=this.api.query.Tokens.Accounts;return ut(()=>e.watchEntries(t,{at:"best"})).pipe(we((i,a)=>!a.deltas),j(({deltas:i})=>{let a=[];return i?.deleted.forEach(s=>{let[r,n]=s.args;a.push({id:n,balance:this.getBreakdown({free:0n,reserved:0n,frozen:0n})})}),i?.upserted.forEach(s=>{let[r,n]=s.args;a.push({id:n,balance:this.getBreakdown(s.value)})}),a}),mt({error:i=>Q.error("balance(tokens)",i)}))}watchErc20Balance(t,e){let i=async()=>{if(this.erc20Ids)return this.erc20Ids;let s=await this.api.query.AssetRegistry.Assets.getEntries({at:"best"});return this.erc20Ids=s.filter(({value:r})=>r.asset_type.type==="Erc20").map(({keyArgs:r})=>{let[n]=r;return n}),this.erc20Ids},a=async s=>(await Promise.all(s.map(async n=>[n,await this.getBalanceData(t,n)]))).map(([n,o])=>({id:n,balance:o}));return ut(()=>xe(e?Promise.resolve(e):i()).pipe(Oe(s=>this.watcher.bestBlock$.pipe(Oe(()=>xe(a(s))))),Ae([]),Ie(2,1),j(([s,r],n)=>n===0?r.filter(o=>o.balance.total>0n):this.getDeltas(s,r)),we((s,r)=>r.length===0),mt({error:s=>Q.error("balance(erc20)",s)})))}async getBalanceData(t,e){let i=await this.api.apis.CurrenciesApi.account(e,t,{at:this.at});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=(s,r)=>s!==void 0&&r!==void 0&&s.transferable===r.transferable&&s.total===r.total,a=t.reduce((s,r)=>(s.set(r.id,r.balance),s),new Map);return e.filter(s=>!i(s.balance,a.get(s.id)))}};import{BehaviorSubject as sa}from"rxjs";var Rt=class{store$=new sa([]);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((n,o)=>[n.address,o])),a=await t(e),s=e.slice(),r=new Set;for(let n of a){let o=i.get(n.address);o===void 0?(i.set(n.address,s.length),s.push(n)):s[o]=n,r.add(n.address)}this.changeset=r,this.store$.next(s)}).catch(console.error)}destroy(){this.store$.complete()}};import{log as na}from"@galacticcouncil/common";var ra={Aave:"AAVE",LBP:"LBP",Omnipool:"OMNI",Stableswap:"STBL",XYK:"XYK",HSM:"HSM",UniswapV3:"UNIV3"},{logger:Ct}=na,Mt=class{type;constructor(t){this.type=t}prefix(){return this.pad(`pool(${ra[this.type]})`,10)}trace(t,...e){Ct.trace(`${this.prefix()} ${t} :`,...e)}debug(t,...e){Ct.debug(`${this.prefix()} ${t} :`,...e)}info(t,...e){Ct.info(`${this.prefix()} ${t} :`,...e)}error(t,...e){Ct.error(`${this.prefix()} ${t} :`,...e)}pad(t,e){return t.length>=e?t:t+" ".repeat(e-t.length)}};var{withTimeout:Sa}=Ft,va=3e3,w=class extends C{evm;balance;store=new Rt;log;shared$;resync$=new Be(1);resyncAt=0;resyncPending=!1;mem=0;memPoolsCache=new la(null,{ttl:6*1e3});memPools=oa(t=>(this.log.info("pool_sync",{mem:t}),this.loadPools()),this.memPoolsCache);constructor(t,e,i){super(t,i),this.evm=e,this.balance=new pt(t,i),this.log=new Mt(this.getPoolType())}async getMemPools(){return this.memPools(this.mem)}async getPools(){let e=(await this.getMemPools()).filter(i=>this.hasValidAssets(i));return this.store.set(e),e}getSubscriber(){return this.shared$||(this.shared$=this.subscribeStore()),this.shared$.pipe(fa([]),ga(2,1),J(([t,e])=>t.length===0?e:this.store.applyChangeset(e)),Lt(t=>t.length>0),Pa(1e3,void 0,{leading:!0,trailing:!0}))}subscribeStore(){return ua(()=>{let t=new _e;return t.add(this.startWatchdog()),this.resync$.next(),this.resync$.pipe(ke(()=>{let e=new _e;return ma(Sa(this.getMemPools(),6e4,"getMemPools stalled")).pipe($(()=>this.log.info("pool_synced",{mem:this.mem})),J(a=>a.filter(s=>this.hasValidAssets(s))),$(a=>this.store.set(a)),gt(()=>(this.log.error("pool_seed_error",{mem:this.mem}),this.requestResync(),dt))).pipe($(()=>{e.add(this.subscribeBalances()),e.add(this.subscribeUpdates())}),ke(a=>zt(da(a),this.store.asObservable().pipe(ha(1)))),jt(()=>{e.unsubscribe()}))}),jt(()=>t.unsubscribe()))}).pipe(ya({connector:()=>new Be(1),resetOnRefCountZero:!0}))}subscribeBalances(){let t=this.store.pools.map(e=>{let{address:i}=e,a=[this.balance.watchTokensBalance(i)];if(this.hasSystemAsset(e)){let s=this.balance.watchSystemBalance(i);a.push(s)}if(this.hasErc20Asset(e)){let s=e.tokens.filter(n=>n.type==="Erc20").map(n=>n.id),r=this.balance.watchErc20Balance(i,s);a.push(r)}return ca(a).pipe(J(s=>s.flat()),Qt(),J(([s,r])=>this.balance.getDeltas(s,r)),Lt(s=>s.length>0),J(s=>[i,s]))});return zt(...t).pipe(ba(250),Lt(e=>e.length>0),J(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=[],a=new Map(t.map(s=>[s.address,s]));for(let[s,r]of e){let n=a.get(s);if(n){let o=n.tokens.map(l=>{let c=r.find(m=>m.id===l.id);return c&&l.id!==n.id?{...l,balance:c.balance.transferable}:l});i.push({...n,tokens:o})}}return i};resync(t=!1){let e=Date.now();!t&&e-this.resyncAt<va||(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 a=this.watcher.connection$.pipe(Qt(),Lt(([n,o])=>n==="offline"&&o==="online"),$(()=>{this.log.debug("watchdog_recover_online",{mem:this.mem}),this.requestResync()}),gt(n=>(this.log.error("watchdog_recovery_error",n),dt)),Jt({delay:1e3})),s=this.watcher.finalizedBlock$.pipe(Qt(),$(([n,o])=>{let l=Number(n.number),c=Number(o.number),m=c-l;m>=3&&(this.log.debug("watchdog_gap",{from:l,to:c,gap:m}),this.requestResync())}),gt(n=>(this.log.error("watchdog_gap_error",n),dt)),Jt({delay:1e3})),r=pa(36e5).pipe($(()=>{this.log.debug("watchdog_periodic",{mem:this.mem}),this.requestResync()}),gt(n=>(this.log.error("watchdog_periodic_error",n),dt)),Jt({delay:1e3}));return zt(a,s,r).subscribe()}watchGuard(t){return e=>e.pipe($({error:i=>{this.log.error(t,i),this.requestResync(!0)}}),jt(()=>{this.log.debug(t,"unsub")}),gt(()=>dt))}};var bt=class extends w{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:a,initial_weight:s,final_weight:r}=t,n=E.calculateLinearWeights(i?i.toString():"0",a?a.toString():"0",s.toString(),r.toString(),e.toString()),o=BigInt(n),l=this.MAX_FINAL_WEIGHT-BigInt(o);return[o,l]}async isSupported(){return(await this.api.getStaticApis()).compat.query.LBP.PoolData.isCompatible(Ta.BackwardsCompatible)}async loadPools(){let[t,e,i]=await Promise.all([this.api.query.LBP.PoolData.getEntries({at:this.at}),this.api.query.ParachainSystem.ValidationData.getValue({at:this.at}),this.getPoolLimits()]),a=e?.relay_parent_number||0,s=t.filter(({value:r})=>e&&this.isActivePool(r,a)).map(async({keyArgs:r,value:n})=>{let[o]=r,l=o.toString(),c=await this.getPoolDelta(l,n,a);return{address:l,type:"LBP",fee:n.fee,...c,...i}});return Promise.all(s)}async getPoolDelta(t,e,i){let{assets:a,repay_target:s,fee_collector:r}=e,[n,o]=this.getPoolWeights(e,i),[l,c]=a,[m,g,p,d,b]=await Promise.all([this.isRepayFeeApplied(l,s,r.toString()),this.balance.getBalance(t,l),this.api.query.AssetRegistry.Assets.getValue(l,{at:this.at}),this.balance.getBalance(t,c),this.api.query.AssetRegistry.Assets.getValue(c,{at:this.at})]);return{repayFeeApply:m,tokens:[{id:l,decimals:p?.decimals,existentialDeposit:p?.existential_deposit,balance:g.transferable,weight:n,type:p?.asset_type.type},{id:c,decimals:b?.decimals,existentialDeposit:b?.existential_deposit,balance:d.transferable,weight:o,type:b?.asset_type.type}]}}isActivePool(t,e){let{start:i,end:a}=t;return i&&a?e>=i&&e<a:!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(s=>s.address===e);return{repayFee:await this.getRepayFee(),exchangeFee:i.fee}}subscribeValidationData(){return this.api.query.ParachainSystem.ValidationData.watchValue({at:"best"}).pipe(Aa(({value:t})=>t),wa(t=>t!==void 0),Ia((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 a of e){let s=this.poolsData.get(a.address);if(s){let{assets:r,repay_target:n,fee_collector:o}=s,[l]=r,[c,m]=this.getPoolWeights(s,t),[g,p]=a.tokens,d=[{...g,weight:c},{...p,weight:m}],b=await this.isRepayFeeApplied(l,n,o.toString());i.push({...a,tokens:d,repayFeeApply:b})}}return i})})}subscribeUpdates(){let t=new xa;return t.add(this.subscribeValidationData()),t}};var Me={};F(Me,{OmniMath:()=>y,OmniPool:()=>ht,OmniPoolClient:()=>yt,OmniPoolFee:()=>W,getEmaKey:()=>qt,getEmaPair:()=>tt});import{calculate_in_given_out as Oa,calculate_lrna_in_given_out as Ba,calculate_out_given_in as _a,calculate_out_given_lrna_in as ka,calculate_spot_price as Fa,calculate_lrna_spot_price as Ea,calculate_shares as Ra,calculate_liquidity_out as Ca,calculate_liquidity_lrna_out as Ma,verify_asset_cap as La,calculate_liquidity_hub_in as Da,is_sell_allowed as qa,is_buy_allowed as Na,is_add_liquidity_allowed as Va,is_remove_liquidity_allowed as Ga,recalculate_asset_fee as Ha,recalculate_protocol_fee as Ua}from"@galacticcouncil/math-omnipool";import Z from"big.js";var y=class{static calculateSpotPrice(t,e,i,a){return Fa(t,e,i,a)}static calculateLrnaSpotPrice(t,e){return Ea(t,e)}static calculateInGivenOut(t,e,i,a,s,r,n,o,l,c){return Oa(t,e,i,a,s,r,n,o,l,c)}static calculateLrnaInGivenOut(t,e,i,a,s,r){return Ba(t,e,i,a,s,r)}static calculateOutGivenIn(t,e,i,a,s,r,n,o,l,c){return _a(t,e,i,a,s,r,n,o,l,c)}static calculateOutGivenLrnaIn(t,e,i,a,s,r){return ka(t,e,i,a,s,r)}static calculateShares(t,e,i,a){return Ra(t,e,i,a)}static calculateLiquidityOut(t,e,i,a,s,r,n,o){return Ca(t,e,i,a,s,r,n,o)}static calculateLiquidityLRNAOut(t,e,i,a,s,r,n,o){return Ma(t,e,i,a,s,r,n,o)}static calculateCapDifference(t,e,i,a){let s=Z(e),r=Z(t),n=Z(a),o=Z(i),l=Z(10).pow(18),c=o.div(l);if(s.div(n).lt(c)){let g=c.times(n).minus(s).times(r),p=s.times(Z(1).minus(c));return g.div(p).toFixed(0)}else return"0"}static calculateLimitHubIn(t,e,i,a){return Da(t,e,i,a)}static isSellAllowed(t){return qa(t)}static isBuyAllowed(t){return Na(t)}static isAddLiquidityAllowed(t){return Va(t)}static isRemoveLiquidityAllowed(t){return Ga(t)}static recalculateAssetFee(t,e,i,a,s,r,n,o,l,c,m){return Ha(t,e,i,a,s,r,n,o,l,c,m)}static recalculateProtocolFee(t,e,i,a,s,r,n,o,l,c,m){return Ua(t,e,i,a,s,r,n,o,l,c,m)}static verifyAssetCap(t,e,i,a){return La(t,e,i,a)}};import{big as $a}from"@galacticcouncil/common";var{FeeUtils:L}=f,ht=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(r=>[r.id,r])),a=i.get(t),s=i.get(e);if(a==null)throw new Error("Pool does not contain tokenIn");if(s==null)throw new Error("Pool does not contain tokenOut");return{assetIn:t,assetOut:e,hubReservesIn:a.hubReserves,hubReservesOut:s.hubReserves,sharesIn:a.shares,sharesOut:s.shares,decimalsIn:a.decimals,decimalsOut:s.decimals,balanceIn:a.balance,balanceOut:s.balance,tradeableIn:a.tradeable,tradeableOut:s.tradeable,assetInEd:a.existentialDeposit,assetOutEd:s.existentialDeposit}}validateAndBuy(t,e,i){let a=this.calculateInGivenOut(t,e),s=this.calculateInGivenOut(t,e,i),r=a===0n?0:R.calculateBuyFee(a,s),n=[],o=y.isSellAllowed(t.tradeableIn),l=y.isBuyAllowed(t.tradeableOut);(!o||!l)&&n.push("TradeNotAllowed"),(e<this.minTradingLimit||a<t.assetInEd)&&n.push("InsufficientTradingAmount");let c=t.balanceOut/this.maxOutRatio;e>c&&n.push("MaxOutRatioExceeded");let m=t.balanceIn/this.maxInRatio;return s>m&&n.push("MaxInRatioExceeded"),{amountIn:s,calculatedIn:a,amountOut:e,feePct:r,errors:n}}validateAndSell(t,e,i){let a=this.calculateOutGivenIn(t,e),s=this.calculateOutGivenIn(t,e,i),r=R.calculateSellFee(a,s),n=[],o=y.isSellAllowed(t.tradeableIn),l=y.isBuyAllowed(t.tradeableOut);(!o||!l)&&n.push("TradeNotAllowed"),(e<this.minTradingLimit||a<t.assetOutEd)&&n.push("InsufficientTradingAmount");let c=t.balanceIn/this.maxInRatio;e>c&&n.push("MaxInRatioExceeded");let m=t.balanceOut/this.maxOutRatio;return s>m&&n.push("MaxOutRatioExceeded"),{amountIn:e,calculatedOut:a,amountOut:s,feePct:r,errors:n}}calculateInGivenOut(t,e,i){if(t.assetIn==this.hubAssetId)return this.calculateLrnaInGivenOut(t,e,i);let a=y.calculateInGivenOut(t.balanceIn.toString(),t.hubReservesIn.toString(),t.sharesIn.toString(),t.balanceOut.toString(),t.hubReservesOut.toString(),t.sharesOut.toString(),e.toString(),i?L.toRaw(i.assetFee).toString():"0",i?L.toRaw(i.protocolFee).toString():"0",i?L.toRaw(i.maxSlipFee).toString():"0"),s=BigInt(a);return s<0n?0n:s}calculateLrnaInGivenOut(t,e,i){let a=y.calculateLrnaInGivenOut(t.balanceOut.toString(),t.hubReservesOut.toString(),t.sharesOut.toString(),e.toString(),i?L.toRaw(i.assetFee).toString():"0",i?L.toRaw(i.maxSlipFee).toString():"0"),s=BigInt(a);return s<0n?0n:s}calculateOutGivenIn(t,e,i){if(t.assetIn==this.hubAssetId)return this.calculateOutGivenLrnaIn(t,e,i);let a=y.calculateOutGivenIn(t.balanceIn.toString(),t.hubReservesIn.toString(),t.sharesIn.toString(),t.balanceOut.toString(),t.hubReservesOut.toString(),t.sharesOut.toString(),e.toString(),i?L.toRaw(i.assetFee).toString():"0",i?L.toRaw(i.protocolFee).toString():"0",i?L.toRaw(i.maxSlipFee).toString():"0"),s=BigInt(a);return s<0n?0n:s}calculateOutGivenLrnaIn(t,e,i){let a=y.calculateOutGivenLrnaIn(t.balanceOut.toString(),t.hubReservesOut.toString(),t.sharesOut.toString(),e.toString(),i?L.toRaw(i.assetFee).toString():"0",i?L.toRaw(i.maxSlipFee).toString():"0"),s=BigInt(a);return s<0n?0n:s}spotPriceInGivenOut(t){if(t.assetIn==this.hubAssetId)return this.spotPriceLrnaInGivenOut(t);let e=y.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=y.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=y.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=y.calculateLrnaSpotPrice(t.balanceOut.toString(),t.hubReservesOut.toString());return this.normalizeSpot(BigInt(e),t.decimalsIn,t.decimalsOut)}normalizeSpot(t,e,i){let a=e-i;if(a===0)return t;let s=$a.pow10(Math.abs(a));return a>0?t*s:t/s}};import{AccountId as Wa,Binary as Ee,CompatibilityLevel as Xa,Enum as Ya}from"polkadot-api";import{toHex as Ka}from"@polkadot-api/utils";import{Subscription as za,distinctUntilChanged as Zt,filter as ja,finalize as te,map as et,merge as Qa,tap as Nt}from"rxjs";import{HYDRATION_SS58_PREFIX as Ja}from"@galacticcouncil/common";var{FeeUtils:I}=f,W=class u{static compute(t,e,i,a,s,r,n,o){let l=t.assetIn,[c,m,g]=u.getAssetFee(t,e,i,a,r),p=0,d=0,b=0;l!==1&&([p,d,b]=u.getProtocolFee(t,e,i,s,n));let O=c+p,S=g+b;return{assetFee:I.fromPermill(m),protocolFee:I.fromPermill(d),maxSlipFee:I.fromPermill(o),min:I.fromPermill(O),max:I.fromPermill(S)}}static getAssetFee(t,e,i,a,s){let{assetOut:r,balanceOut:n}=t,{min_fee:o,max_fee:l,decay:c,amplification:m}=s;if(!i||!a)return[o,o,l];let g=I.fromPermill(o),p=I.fromPermill(l),[d]=a,{asset_fee:b,timestamp:O}=i,S=Math.max(1,e-O),A=d.volume.b_in.toString(),x=d.volume.b_out.toString(),v=d.liquidity.b.toString();r===0&&(A=d.volume.a_in.toString(),x=d.volume.a_out.toString(),v=d.liquidity.a.toString());let B=I.fromPermill(b),k=y.recalculateAssetFee(A,x,v,"9",n.toString(),I.toRaw(B).toString(),S.toString(),I.toRaw(g).toString(),I.toRaw(p).toString(),c.toString(),m.toString());return[o,Number(k)*1e6,l]}static getProtocolFee(t,e,i,a,s){let{assetIn:r,balanceIn:n}=t,{min_fee:o,max_fee:l,decay:c,amplification:m}=s;if(!i||!a)return[o,o,l];let g=I.fromPermill(o),p=I.fromPermill(l),[d]=a,{protocol_fee:b,timestamp:O}=i,S=Math.max(1,e-O),A=d.volume.b_in.toString(),x=d.volume.b_out.toString(),v=d.liquidity.b.toString();r===0&&(A=d.volume.a_in.toString(),x=d.volume.a_out.toString(),v=d.liquidity.a.toString());let B=I.fromPermill(b),k=y.recalculateProtocolFee(A,x,v,"9",n.toString(),I.toRaw(B).toString(),S.toString(),I.toRaw(g).toString(),I.toRaw(p).toString(),c.toString(),m.toString());return[o,Number(k)*1e6,l]}};var tt=u=>u===0?[0,1]:[1,u],qt=u=>tt(u).join(":");var{FeeUtils:ee}=f,Re=Ee.toHex(Ee.fromText("omnipool")),Ce=Ya("Short"),yt=class extends w{queryBus=new z;block=0;dynamicFeesConfig=this.queryBus.scope("DynamicFees.AssetFeeConfiguration",t=>this.api.query.DynamicFees.AssetFeeConfiguration.getValue(t,{at:this.at}),t=>String(t));dynamicFees=this.queryBus.scope("DynamicFees.AssetFee",t=>this.api.query.DynamicFees.AssetFee.getValue(t,{at:this.at}),t=>String(t),6*1e3);maxSlipFee=this.queryBus.scope("Omnipool.SlipFee",()=>this.apiNext.query.Omnipool.SlipFee.getValue({at:this.at}),()=>"slipFee");emaOracles=this.queryBus.scope("EmaOracle.Oracles.Short",t=>this.api.query.EmaOracle.Oracles.getValue(Re,t,Ce,{at:this.at}),t=>t.join(":"),6*1e3);getPoolType(){return"Omnipool"}getPoolAddress(){let t="modlomnipool".padEnd(32,"\0"),e=new TextEncoder().encode(t),i=Ka(e);return Wa(Ja).dec(i)}async getPoolLimits(){let[t,e,i]=await Promise.all([this.api.constants.Omnipool.MaxInRatio(),this.api.constants.Omnipool.MaxOutRatio(),this.api.constants.Omnipool.MinimumTradingLimit()]);return{maxInRatio:t,maxOutRatio:e,minTradingLimit:i}}async isSupported(){return(await this.api.getStaticApis()).compat.query.Omnipool.Assets.isCompatible(Xa.BackwardsCompatible)}async loadPools(){let t=await this.api.constants.Omnipool.HubAssetId(),e=this.getPoolAddress(),[i,a,s,r,n,o]=await Promise.all([this.api.query.Omnipool.Assets.getEntries({at:this.at}),this.api.query.Omnipool.HubAssetTradability.getValue({at:this.at}),this.api.query.AssetRegistry.Assets.getValue(t,{at:this.at}),this.balance.getBalance(e,t),this.getPoolLimits(),this.api.query.System.Number.getValue({at:this.at})]);this.block=o;let l=i.map(async({keyArgs:m,value:g})=>{let[p]=m,{hub_reserve:d,shares:b,tradable:O,cap:S,protocol_shares:A}=g,[x,v]=await Promise.all([this.api.query.AssetRegistry.Assets.getValue(p,{at:this.at}),this.balance.getBalance(e,p)]);return{id:p,decimals:x?.decimals,existentialDeposit:x?.existential_deposit,balance:v.transferable,cap:S,hubReserves:d,protocolShares:A,shares:b,tradeable:O,type:x?.asset_type.type}}),c=await Promise.all(l);return c.push({id:t,decimals:s?.decimals,existentialDeposit:s?.existential_deposit,balance:r.transferable,tradeable:a,type:s?.asset_type.type}),[{address:e,type:"Omnipool",hubAssetId:t,tokens:c,...n}]}async getPoolFees(t){let e=t.assetOut,i=t.assetIn,s=await this.maxSlipFee.get()??0,r=await this.dynamicFeesConfig.get(e);if(r?.type==="Fixed"){let{asset_fee:g,protocol_fee:p}=r.value;return{assetFee:ee.fromPermill(g),protocolFee:ee.fromPermill(p),maxSlipFee:ee.fromPermill(s)}}let[n,o,l,c,m]=await Promise.all([this.dynamicFees.get(e),this.emaOracles.get(tt(e)),this.emaOracles.get(tt(i)),r?r.value.asset_fee_params:this.api.constants.DynamicFees.AssetFeeParameters(),r?r.value.protocol_fee_params:this.api.constants.DynamicFees.ProtocolFeeParameters()]);return W.compute(t,this.block,n,o,l,c,m,s)}subscribeEmaOracles(){let[t]=this.store.pools,i=t.tokens.map(a=>a.id).map(a=>tt(a)).map(a=>this.api.query.EmaOracle.Oracles.watchValue(Re,a,Ce,{at:"best"}).pipe(et(({value:s})=>s),ja(s=>s!==void 0),et((s,r)=>({value:s,index:r})),Nt(({index:s})=>{s>0&&this.log.trace("emaOracle.Oracles",a.join(":"))}),et(({value:s})=>({pair:a,value:s}))));return Qa(...i).pipe(te(()=>this.emaOracles.clear()),this.watchGuard("emaOracle.Oracles")).subscribe(a=>{let{pair:s,value:r}=a;this.emaOracles.set(r,s)})}subscribeDynamicFees(){return this.api.query.DynamicFees.AssetFee.watchEntries({at:"best"}).pipe(Zt((t,e)=>!e.deltas),et((t,e)=>({value:t,index:e})),Nt(({value:t,index:e})=>{e>0&&this.log.trace("dynamicFees.AssetFee",t.deltas?.upserted)}),te(()=>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(Zt((t,e)=>!e.deltas),et((t,e)=>({value:t,index:e})),Nt(({value:t,index:e})=>{e>0&&this.log.trace("dynamicFees.AssetFeeConfiguration",t.deltas?.upserted)}),te(()=>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(Zt((t,e)=>!e.deltas),et((t,e)=>({value:t,index:e})),Nt(({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((s,r)=>{let[n]=r.args;return s.set(n,r.value),s},new Map),a=e.tokens.map(s=>{let r=i?.get(s.id);return r?this.updateTokenState(s,r):s});return[{...e,tokens:a}]})})}subscribeUpdates(){let t=new za;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:a,tradable:s,cap:r,protocol_shares:n}=e;return{...t,cap:r,hubReserves:i,protocolShares:n,shares:a,tradeable:s}}};var We={};F(We,{StableMath:()=>T,StableSwap:()=>X,StableSwapClient:()=>vt});import{calculate_in_given_out as Za,calculate_out_given_in as ts,calculate_amplification as es,calculate_add_one_asset as is,calculate_liquidity_out_one_asset as as,calculate_shares as ss,calculate_shares_for_amount as ns,calculate_spot_price_with_fee as rs,pool_account_name as os,recalculate_peg as ls}from"@galacticcouncil/math-stableswap";var T=class{static getPoolAddress(t){return os(t)}static defaultPegs(t){let e=[];for(let i=0;i<t;i++)e.push(["1","1"]);return e}static calculateAmplification(t,e,i,a,s){return es(t,e,i,a,s)}static calculateInGivenOut(t,e,i,a,s,r,n){return Za(t,e,i,a,s,r,n)}static calculateAddOneAsset(t,e,i,a,s,r,n){return is(t,e,i,a,s,r,n)}static calculateSharesForAmount(t,e,i,a,s,r,n){return ns(t,e,i,a,s,r,n)}static calculateOutGivenIn(t,e,i,a,s,r,n){return ts(t,e,i,a,s,r,n)}static calculateLiquidityOutOneAsset(t,e,i,a,s,r,n){return as(t,e,i,a,s,r,n)}static calculateShares(t,e,i,a,s,r){return ss(t,e,i,a,s,r)}static calculateSpotPriceWithFee(t,e,i,a,s,r,n,o){return rs(t,e,i,a,s,r,n,o)}static recalculatePegs(t,e,i,a,s,r){let n=ls(t,e,i,a,s,r);return JSON.parse(n)}};import{RUNTIME_DECIMALS as cs,big as Le}from"@galacticcouncil/common";var{FeeUtils:it}=f,X=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(r=>[r.id,r])),a=i.get(t),s=i.get(e);if(a==null)throw new Error("Pool does not contain tokenIn");if(s==null)throw new Error("Pool does not contain tokenOut");return{assetIn:t,assetOut:e,balanceIn:a.balance,balanceOut:s.balance,decimalsIn:a.decimals,decimalsOut:s.decimals,tradeableIn:this.id===t?15:a.tradeable,tradeableOut:this.id===e?15:s.tradeable,assetInEd:a.existentialDeposit,assetOutEd:s.existentialDeposit}}validateAndBuy(t,e,i){let a=this.calculateInGivenOut(t,e),s=this.calculateInGivenOut(t,e,i),r=a===0n?0:R.calculateBuyFee(a,s),n=[],o=y.isSellAllowed(t.tradeableIn),l=y.isBuyAllowed(t.tradeableOut);return(!o||!l)&&n.push("TradeNotAllowed"),(e<this.minTradingLimit||a<t.assetInEd)&&n.push("InsufficientTradingAmount"),{amountIn:s,calculatedIn:a,amountOut:e,feePct:r,errors:n}}validateAndSell(t,e,i){let a=this.calculateOutGivenIn(t,e),s=this.calculateOutGivenIn(t,e,i),r=R.calculateSellFee(a,s),n=[],o=y.isSellAllowed(t.tradeableIn),l=y.isBuyAllowed(t.tradeableOut);return(!o||!l)&&n.push("TradeNotAllowed"),(e<this.minTradingLimit||a<t.assetOutEd)&&n.push("InsufficientTradingAmount"),{amountIn:e,calculatedOut:a,amountOut:s,feePct:r,errors:n}}calculateIn(t,e,i){let a=T.calculateInGivenOut(this.getReserves(),Number(t.assetIn),Number(t.assetOut),e.toString(),this.amplification.toString(),i?it.toRaw(i.fee).toString():"0",this.getPegs()),s=BigInt(a);return s<0n?0n:s}calculateAddOneAsset(t,e,i){let a=T.calculateAddOneAsset(this.getReserves(),e.toString(),Number(t.assetIn),this.amplification.toString(),this.totalIssuance.toString(),i?it.toRaw(i.fee).toString():"0",this.getPegs()),s=BigInt(a);return s<0n?0n:s}calculateSharesForAmount(t,e,i){let a=T.calculateSharesForAmount(this.getReserves(),Number(t.assetOut),e.toString(),this.amplification.toString(),this.totalIssuance.toString(),i?it.toRaw(i.fee).toString():"0",this.getPegs()),s=BigInt(a);return s<0n?0n:s}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=T.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 a=T.calculateOutGivenIn(this.getReserves(),Number(t.assetIn),Number(t.assetOut),e.toString(),this.amplification.toString(),i?it.toRaw(i.fee).toString():"0",this.getPegs()),s=BigInt(a);return s<0n?0n:s}calculateWithdrawOneAsset(t,e,i){let a=T.calculateLiquidityOutOneAsset(this.getReserves(),e.toString(),Number(t.assetOut),this.amplification.toString(),this.totalIssuance.toString(),i?it.toRaw(i.fee).toString():"0",this.getPegs()),s=BigInt(a);return s<0n?0n:s}calculateShares(t,e,i){let a=T.calculateShares(this.getReserves(),this.getAssets(t.assetIn,e),this.amplification.toString(),this.totalIssuance.toString(),i?it.toRaw(i.fee).toString():"0",this.getPegs()),s=BigInt(a);return s<0n?0n:s}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=T.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:a})=>({asset_id:e,amount:i,decimals:a}));return JSON.stringify(t,lt.jsonFormatter)}getAssets(t,e){let i={asset_id:Number(t),amount:e.toString()};return JSON.stringify([i],lt.jsonFormatter)}normalizeSpot(t,e,i,a,s){return e?t*Le.pow10(cs-s):i?t/Le.pow10(s-a):t}};import{AccountId as ms,CompatibilityLevel as ps}from"polkadot-api";import{toHex as ds}from"@polkadot-api/utils";import{blake2b as gs}from"@noble/hashes/blake2b";import{Subscription as bs,distinctUntilChanged as $e,filter as hs,map as st,merge as ys,tap as ae}from"rxjs";import{HYDRATION_SS58_PREFIX as fs,RUNTIME_DECIMALS as Ps}from"@galacticcouncil/common";import{Binary as us}from"polkadot-api";import{decodeEventLog as Ne}from"viem";var ie=[{inputs:[],name:"decimals",outputs:[{internalType:"uint8",name:"",type:"uint8"}],stateMutability:"view",type:"function"},{inputs:[],name:"description",outputs:[{internalType:"string",name:"",type:"string"}],stateMutability:"view",type:"function"},{inputs:[],name:"version",outputs:[{internalType:"uint256",name:"",type:"uint256"}],stateMutability:"view",type:"function"},{inputs:[{internalType:"uint80",name:"_roundId",type:"uint80"}],name:"getRoundData",outputs:[{internalType:"uint80",name:"roundId",type:"uint80"},{internalType:"int256",name:"answer",type:"int256"},{internalType:"uint256",name:"startedAt",type:"uint256"},{internalType:"uint256",name:"updatedAt",type:"uint256"},{internalType:"uint80",name:"answeredInRound",type:"uint80"}],stateMutability:"view",type:"function"},{inputs:[],name:"latestRoundData",outputs:[{internalType:"uint80",name:"roundId",type:"uint80"},{internalType:"int256",name:"answer",type:"int256"},{internalType:"uint256",name:"startedAt",type:"uint256"},{internalType:"uint256",name:"updatedAt",type:"uint256"},{internalType:"uint80",name:"answeredInRound",type:"uint80"}],stateMutability:"view",type:"function"}],De=[{anonymous:!1,inputs:[{indexed:!1,name:"key",type:"string"},{indexed:!1,name:"value",type:"uint128"},{indexed:!1,name:"timestamp",type:"uint128"}],name:"OracleUpdate",type:"event"}],qe=[{anonymous:!1,inputs:[{indexed:!0,name:"roundId",type:"uint80"},{indexed:!1,name:"answer",type:"int256"},{indexed:!1,name:"timestamp",type:"uint256"}],name:"PriceUpdated",type:"event"}];var ft=class{static parse(t){let{address:e,topics:i,data:a}=t.log,s=e.toLowerCase(),r=us.toHex(a);try{let{eventName:n,args:o}=Ne({abi:qe,topics:i,data:r});return{eventName:`ManagedOracle.${n}`,emitter:s,value:o.answer,timestamp:o.timestamp}}catch{}try{let{eventName:n,args:o}=Ne({abi:De,topics:i,data:r});return{eventName:`DIA.${n}`,emitter:s,key:o.key,value:o.value,timestamp:o.timestamp}}catch{}}};var Pt=class{adapter;constructor(t){this.adapter=t.getRPCAdapter()}async getData(t,e=6){let[i,a,s]=await Promise.all([this.adapter.readContract({abi:ie,address:t,functionName:"latestRoundData"}),this.adapter.readContract({abi:ie,address:t,functionName:"decimals"}),this.adapter.getBlock()]),[r,n,o,l]=i,c=s.number-(s.timestamp-l)/BigInt(e),m=Number(c);return{price:n,decimals:a,updatedAt:m<0?0:m}}};var Ve={"EUR/USD":"0xaa47a5662269270d3df33ae08f806e383611575c","sUSDs/USD":"0x4b32bffc6acd751446e79e8687ef3815fd7924fd","sUSDe/USD":"0x22cdea305cee63d082e79f8c5db939eecd0265d0"},Ge={"0xcfab6a4031c70da0f0cf6f31a252c16119db3611":"0xaafd758688cefd0a7b7770a825f1aad551e16185"},He={"bifrosto:5:15:LastBlock":"0xaafd758688cefd0a7b7770a825f1aad551e16185"};function Ue(u,t,e){let i=Buffer.from(u.replace(/^0x/,""),"hex").toString("ascii").replace(/\0+$/,""),[a,s]=[t[0],t[1]].sort((r,n)=>r-n);return`${i}:${a}:${s}:${e}`}var{FeeUtils:at}=f,St=class u{static compute(t,e,i,a){let s=u.getRecent(e),r=at.fromPermill(t.fee),n=at.fromPerbill(e.max_peg_update),o=i.map(({pair:d,updatedAt:b})=>[d,b]),l=i.find(d=>d.source),c=e.updated_at?e.updated_at.toString():l?.updatedAt;if(!c)throw new Error("Current peg unknown!");let[m,g]=T.recalculatePegs(JSON.stringify(s),c,JSON.stringify(o),a.toString(),at.toRaw(n).toString(),at.toRaw(r).toString()),p=Number(m)*1e6;return{pegsFee:at.fromPermill(p),pegs:g}}static getDefault(t){return{pegsFee:at.fromPermill(t.fee),pegs:T.defaultPegs(t.assets.length)}}static getRecent(t){let{current:e}=t;return Array.from(e.entries()).map(([i,a])=>a.map(s=>s.toString()))}};var{FeeUtils:Ss}=f,vs=["ManagedOracle.PriceUpdated","DIA.OracleUpdate"],vt=class extends w{poolsData=new Map([]);mmOracle=new Pt(this.evm);mmAddresses=new Set;mmRouting={byEmitter:new Map,byDiaKey:new Map,byEma:new Map};queryBus=new z;emaOracles=this.queryBus.scope("EmaOracle.Oracles",(t,e,i)=>this.api.query.EmaOracle.Oracles.getValue(t,e,i,{at:this.at}),(t,e,i)=>`${t.toString()}:${e.join(":")}:${i.type}`,6*1e3);mmOracles=this.queryBus.scope("MmOracle",t=>this.mmOracle.getData(t),t=>t.toLowerCase(),600*1e3);pegs=this.queryBus.scope("Stableswap.PoolPegs",t=>this.api.query.Stableswap.PoolPegs.getValue(t,{at:this.at}),t=>String(t),6*1e3);getPoolType(){return"Stableswap"}getPoolAddress(t){let e=T.getPoolAddress(t),i=gs(e,{dkLen:32}),a=ds(i);return ms(fs).dec(a)}async getPoolLimits(){return{maxInRatio:0n,maxOutRatio:0n,minTradingLimit:await this.api.constants.Stableswap.MinTradingLimit()}}getPoolAmplification(t,e){let{initial_amplification:i,final_amplification:a,initial_block:s,final_block:r}=t,n=T.calculateAmplification(i.toString(),a.toString(),s.toString(),r.toString(),e.toString()),o=Number(n)<a;return{amplification:BigInt(n),isRampPeriod:o}}async getPoolTokens(t,e){let i=this.getPoolAddress(t),a=e.assets.map(async s=>{let[r,n,o]=await Promise.all([this.api.query.Stableswap.AssetTradability.getValue(t,s,{at:this.at}),this.api.query.AssetRegistry.Assets.getValue(s,{at:this.at}),this.balance.getBalance(i,s)]);return{id:s,decimals:n?.decimals,existentialDeposit:n?.existential_deposit,balance:o.transferable,tradeable:r,type:n?.asset_type.type}});return Promise.all(a)}buildRouting(){this.mmRouting.byEmitter.clear(),this.mmRouting.byDiaKey.clear(),this.mmRouting.byEma.clear();for(let t of this.mmAddresses)this.mmRouting.byEmitter.set(t,t);for(let[t,e]of Object.entries(Ge)){let i=t.toLowerCase(),a=e.toLowerCase();this.mmAddresses.has(a)&&this.mmRouting.byEmitter.set(i,a)}for(let[t,e]of Object.entries(Ve)){let i=e.toLowerCase();this.mmAddresses.has(i)&&this.mmRouting.byDiaKey.set(t,i)}for(let[t,e]of Object.entries(He)){let i=e.toLowerCase();this.mmAddresses.has(i)&&this.mmRouting.byEma.set(t,i)}}async isSupported(){return(await this.api.getStaticApis()).compat.query.Stableswap.Pools.isCompatible(ps.BackwardsCompatible)}async loadPools(){let[t,e,i,a]=await Promise.all([this.api.query.Stableswap.Pools.getEntries({at:this.at}),this.api.query.Stableswap.PoolPegs.getEntries({at:this.at}),this.api.query.System.Number.getValue({at:this.at}),this.getPoolLimits()]);for(let{keyArgs:r,value:n}of e){let[o]=r;this.pegs.set(n,o);for(let l of n.source)l.type==="MMOracle"&&this.mmAddresses.add(l.value.toString().toLowerCase())}this.buildRouting();let s=t.map(async({keyArgs:r,value:n})=>{let[o]=r,l=this.getPoolAddress(o),[c,m,g,p]=await Promise.all([this.getPoolTokens(o,n),this.getPoolAmplification(n,i),this.getPoolPegs(o,n,i),this.api.query.Tokens.TotalIssuance.getValue(o,{at:this.at})]);return c.push({id:o,tradeable:15,balance:p,decimals:Ps}),this.poolsData.set(o,n),{address:l,id:o,type:"Stableswap",fee:Ss.fromPermill(n.fee),tokens:c,totalIssuance:p,...g,...a,...m}});return Promise.all(s)}async getPoolFees(t,e){return{fee:this.store.pools.find(a=>a.address===e).fee}}async getPoolPegs(t,e,i){let a=await this.pegs.get(t);if(!a)return St.getDefault(e);let s=await this.getLatestPegs(e,a,i);return St.compute(e,a,s,i)}async getLatestPegs(t,e,i){let{source:a}=e,s=t.assets,r=a.map(async(n,o)=>{if(n.type==="Oracle"){let[l,c,m]=n.value,g=[m,s[o]].sort((S,A)=>S-A),p=await this.emaOracles.get(l,g,c);if(!p)throw new Error("EmaOracle missing for "+l+" / "+g);let[{price:d,updated_at:b}]=p;return{pair:m===g[0]?[d.n.toString(),d.d.toString()]:[d.d.toString(),d.n.toString()],updatedAt:b.toString(),source:n.type}}if(n.type==="MMOracle"){let l=n.value.toString(),{price:c,decimals:m,updatedAt:g}=await this.mmOracles.get(l),p=(10n**BigInt(m)).toString();return{pair:[c.toString(),p],updatedAt:g.toString(),source:n.type}}if(n.type==="Value")return{pair:n.value.map(c=>c.toString()),updatedAt:i.toString()};throw new Error(n+" source not supported")});return Promise.all(r)}subscribeIssuance(){let e=this.store.pools.map(i=>i.id).map(i=>this.api.query.Tokens.TotalIssuance.watchValue(i,{at:"best"}).pipe(st(({value:a})=>a),st((a,s)=>({value:a,index:s})),ae(({index:a,value:s})=>{a>0&&this.log.trace("tokens.TotalIssuance",i,s)}),st(({value:a})=>({id:i,value:a}))));return ys(...e).pipe(this.watchGuard("tokens.TotalIssuance")).subscribe(i=>{let{id:a,value:s}=i;this.store.update(r=>{let n=[];return r.filter(o=>o.id===a).forEach(o=>{let l=o.tokens.map(c=>c.id===a?{...c,balance:s}:c);n.push({...o,tokens:l,totalIssuance:s})}),n})})}subscribePoolPegs(){return this.api.query.Stableswap.PoolPegs.watchEntries({at:"best"}).pipe($e((t,e)=>!e.deltas),st((t,e)=>({value:t,index:e})),ae(({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}})=>{for(let{args:e,value:i}of t?.upserted??[]){let[a]=e;this.pegs.set(i,a)}}})}subscribeEmaOracles(){return this.api.query.EmaOracle.Oracles.watchEntries({at:"best"}).pipe($e((t,e)=>!e.deltas),st((t,e)=>({value:t,index:e})),ae(({value:t,index:e})=>{e>0&&this.log.trace("emaOracle.Oracles",t.deltas?.upserted)}),this.watchGuard("emaOracle.Oracles")).subscribe(async({value:{deltas:t}})=>{let e=new Set;for(let{args:i,value:a}of t?.upserted??[]){let[s,r,n]=i;this.emaOracles.set(a,s,r,n);let o=Ue(s,r,n.type),l=this.mmRouting.byEma.get(o);l&&e.add(l)}for(let i of e){let a=await this.mmOracle.getData(i);this.log.trace("mmOracle.Hybrid",{h160:i,fresh:a}),this.mmOracles.set(a,i)}})}subscribeMMOracles(){return this.api.event.EVM.Log.watch().pipe(st(({events:t})=>t.map(e=>ft.parse(e.payload)).filter(e=>!!e).filter(({eventName:e})=>vs.includes(e))),hs(t=>t.length>0),this.watchGuard("evm.Log")).subscribe(async t=>{let e=new Set;for(let i of t){if(console.log(i),i.eventName==="ManagedOracle.PriceUpdated"){let a=this.mmRouting.byEmitter.get(i.emitter);a&&e.add(a)}if(i.eventName==="DIA.OracleUpdate"&&i.key){let a=this.mmRouting.byDiaKey.get(i.key);a&&e.add(a)}}for(let i of e){let a=await this.mmOracle.getData(i);this.log.trace("mmOracle",{h160:i,fresh:a}),this.mmOracles.set(a,i)}})}subscribeBlock(){return this.watcher.bestBlock$.pipe(this.watchGuard("watcher.bestBlock")).subscribe(t=>{this.store.update(async e=>{let i=[];for(let a of e){let s=this.poolsData.get(a.id);if(s){let r=await this.getPoolPegs(a.id,s,t),n=this.getPoolAmplification(s,t);i.push({...a,...r,...n})}}return i})})}subscribeUpdates(){let t=new bs;return t.add(this.subscribePoolPegs()),t.add(this.subscribeEmaOracles()),t.add(this.subscribeMMOracles()),t.add(this.subscribeIssuance()),t.add(this.subscribeBlock()),t}};var Ye={};F(Ye,{XykMath:()=>q,XykPool:()=>Tt,XykPoolClient:()=>xt});import{calculate_in_given_out as Ts,calculate_out_given_in as xs,calculate_pool_trade_fee as Is,get_spot_price as ws,calculate_liquidity_in as As,calculate_shares as Os,calculate_spot_price as Bs,calculate_spot_price_with_fee as _s,calculate_liquidity_out_asset_a as ks,calculate_liquidity_out_asset_b as Fs}from"@galacticcouncil/math-xyk";var q=class{static getSpotPrice(t,e,i){return ws(t,e,i)}static calculateInGivenOut(t,e,i){return Ts(t,e,i)}static calculateOutGivenIn(t,e,i){return xs(t,e,i)}static calculatePoolTradeFee(t,e,i){return Is(t,e,i)}static calculateLiquidityIn(t,e,i){return As(t,e,i)}static calculateSpotPrice(t,e){return Bs(t,e)}static calculateSpotPriceWithFee(t,e,i,a){return _s(t,e,i,a)}static calculateShares(t,e,i){return Os(t,e,i)}static calculateLiquidityOutAssetA(t,e,i,a){return ks(t,e,i,a)}static calculateLiquidityOutAssetB(t,e,i,a){return Fs(t,e,i,a)}};import{big as Es}from"@galacticcouncil/common";var{FeeUtils:Xe}=f,Tt=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(r=>[r.id,r])),a=i.get(t),s=i.get(e);if(a==null)throw new Error("Pool does not contain tokenIn");if(s==null)throw new Error("Pool does not contain tokenOut");return{assetIn:t,assetOut:e,decimalsIn:a.decimals,decimalsOut:s.decimals,balanceIn:a.balance,balanceOut:s.balance,assetInEd:a.existentialDeposit,assetOutEd:s.existentialDeposit}}validateAndBuy(t,e,i){let a=this.calculateInGivenOut(t,e),s=this.calculateTradeFee(a,i),r=Xe.toPct(i.exchangeFee),n=a+s,o=[];(e<this.minTradingLimit||a<t.assetInEd)&&o.push("InsufficientTradingAmount");let l=t.balanceOut/this.maxOutRatio;e>l&&o.push("MaxOutRatioExceeded");let c=t.balanceIn/this.maxInRatio;return n>c&&o.push("MaxInRatioExceeded"),{amountIn:n,calculatedIn:a,amountOut:e,feePct:r,errors:o}}validateAndSell(t,e,i){let a=this.calculateOutGivenIn(t,e),s=this.calculateTradeFee(a,i),r=Xe.toPct(i.exchangeFee),n=a-s,o=[];(e<this.minTradingLimit||a<t.assetOutEd)&&o.push("InsufficientTradingAmount");let l=t.balanceIn/this.maxInRatio;e>l&&o.push("MaxInRatioExceeded");let c=t.balanceOut/this.maxOutRatio;return n>c&&o.push("MaxOutRatioExceeded"),{amountIn:e,calculatedOut:a,amountOut:n,feePct:r,errors:o}}calculateInGivenOut(t,e){let i=q.calculateInGivenOut(t.balanceIn.toString(),t.balanceOut.toString(),e.toString()),a=BigInt(i);return a<0n?0n:a}calculateOutGivenIn(t,e){let i=q.calculateOutGivenIn(t.balanceIn.toString(),t.balanceOut.toString(),e.toString()),a=BigInt(i);return a<0n?0n:a}spotPriceInGivenOut(t){let e=q.calculateSpotPrice(t.balanceOut.toString(),t.balanceIn.toString());return this.normalizeSpot(BigInt(e),t.decimalsOut,t.decimalsIn)}spotPriceOutGivenIn(t){let e=q.calculateSpotPrice(t.balanceIn.toString(),t.balanceOut.toString());return this.normalizeSpot(BigInt(e),t.decimalsIn,t.decimalsOut)}calculateTradeFee(t,e){let i=q.calculatePoolTradeFee(t.toString(),e.exchangeFee[0],e.exchangeFee[1]);return BigInt(i)}normalizeSpot(t,e,i){let a=e-i;if(a===0)return t;let s=Es.pow10(Math.abs(a));return a>0?t*s:t/s}};import{CompatibilityLevel as Rs}from"polkadot-api";import{Subscription as Cs}from"rxjs";var xt=class extends w{decimals=new Map([]);getPoolType(){return"XYK"}async withOverride(t){this.decimals=t?new Map(t.map(e=>[e.id,e.decimals])):new Map}async getPoolLimits(){let[t,e,i]=await Promise.all([this.api.constants.XYK.MaxInRatio(),this.api.constants.XYK.MaxOutRatio(),this.api.constants.XYK.MinTradingLimit()]);return{maxInRatio:t,maxOutRatio:e,minTradingLimit:i}}async isSupported(){return(await this.api.getStaticApis()).compat.query.XYK.PoolAssets.isCompatible(Rs.BackwardsCompatible)}async loadPools(){let[t,e]=await Promise.all([this.api.query.XYK.PoolAssets.getEntries({at:this.at}),this.getPoolLimits()]),i=t.map(async({keyArgs:a,value:s})=>{let[r]=a,[n,o]=s,[l,c,m,g]=await Promise.all([this.balance.getBalance(r,n),this.api.query.AssetRegistry.Assets.getValue(n,{at:this.at}),this.balance.getBalance(r,o),this.api.query.AssetRegistry.Assets.getValue(o,{at:this.at})]);return{address:r,type:"XYK",tokens:[{id:n,decimals:c?.decimals||this.decimals.get(n),existentialDeposit:c?.existential_deposit,balance:l.transferable,type:c?.asset_type.type},{id:o,decimals:g?.decimals||this.decimals.get(o),existentialDeposit:g?.existential_deposit,balance:m.transferable,type:g?.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 Cs.EMPTY}};var Ze={};F(Ze,{AavePool:()=>It,AavePoolClient:()=>wt});import{big as Ke,RUNTIME_DECIMALS as ze}from"@galacticcouncil/common";var It=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(r=>[r.id,r])),a=i.get(t),s=i.get(e);if(a==null)throw new Error("Pool does not contain tokenIn");if(s==null)throw new Error("Pool does not contain tokenOut");return{assetIn:t,assetOut:e,balanceIn:a.balance,balanceOut:s.balance,decimalsIn:a.decimals,decimalsOut:s.decimals,assetInEd:0n,assetOutEd:0n}}validateAndBuy(t,e,i){let a=this.calculateInGivenOut(t,e),s=[];return e>t.balanceOut&&s.push("TradeNotAllowed"),{amountIn:a,calculatedIn:a,amountOut:e,feePct:0,errors:s}}validateAndSell(t,e,i){let a=this.calculateOutGivenIn(t,e),s=[];return a>t.balanceOut&&s.push("TradeNotAllowed"),{amountIn:e,calculatedOut:a,amountOut:a,feePct:0,errors:s}}calculateInGivenOut(t,e){return e}calculateOutGivenIn(t,e){return e}spotPriceInGivenOut(t){return Ke.toBigInt(1,ze)}spotPriceOutGivenIn(t){return Ke.toBigInt(1,ze)}calculateTradeFee(t,e){return 0n}};import{AccountId as Ns}from"polkadot-api";import{toHex as Vs}from"@polkadot-api/utils";import{Subscription as je,filter as ne,map as Qe,mergeMap as Je}from"rxjs";import{erc20 as Gs,HYDRATION_SS58_PREFIX as Hs}from"@galacticcouncil/common";var se=[{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"},{inputs:[{internalType:"address",name:"asset",type:"address"},{internalType:"uint256",name:"amount",type:"uint256"},{internalType:"address",name:"to",type:"address"}],name:"withdraw",outputs:[{internalType:"uint256",name:"",type:"uint256"}],stateMutability:"nonpayable",type:"function"},{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"},{inputs:[{internalType:"address",name:"asset",type:"address"},{internalType:"uint256",name:"amount",type:"uint256"},{internalType:"uint256",name:"interestRateMode",type:"uint256"},{internalType:"uint16",name:"referralCode",type:"uint16"},{internalType:"address",name:"onBehalfOf",type:"address"}],name:"borrow",outputs:[],stateMutability:"nonpayable",type:"function"},{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"},{inputs:[{internalType:"address",name:"user",type:"address"}],name:"getUserAccountData",outputs:[{internalType:"uint256",name:"totalCollateralBase",type:"uint256"},{internalType:"uint256",name:"totalDebtBase",type:"uint256"},{internalType:"uint256",name:"availableBorrowsBase",type:"uint256"},{internalType:"uint256",name:"currentLiquidationThreshold",type:"uint256"},{internalType:"uint256",name:"ltv",type:"uint256"},{internalType:"uint256",name:"healthFactor",type:"uint256"}],stateMutability:"view",type:"function"}];var fm=BigInt("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");import{Binary as Ms}from"polkadot-api";import{decodeEventLog as Ls}from"viem";var Gt=class{static parse(t){let{topics:e,data:i}=t.log,a=Ms.toHex(i);try{let{eventName:s,args:r}=Ls({abi:se,topics:e,data:a}),n=r.reserve.toLowerCase();return{eventName:s,reserve:n,key:`${s}:${n}`}}catch{return}}};import Lm from"big.js";import{big as qm,erc20 as Ds,h160 as qs}from"@galacticcouncil/common";var{ERC20:Vm}=Ds,{H160:Gm}=qs;var Hm=10n**27n;var{ERC20:Us}=Gs,$s=["Supply","Withdraw","Repay","Borrow"],wt=class extends w{getPoolType(){return"Aave"}async isSupported(){return!0}getPoolId(t,e){let i=t+"/"+e,a=new TextEncoder().encode(i.padEnd(32,"\0")),s=Vs(a);return Ns(Hs).dec(s)}getPoolLimits(){return{maxInRatio:0n,maxOutRatio:0n,minTradingLimit:0n}}async loadPools(){let e=(await this.api.apis.AaveTradeExecutor.pools({at:this.at})).map(async({reserve:i,atoken:a,liqudity_in:s,liqudity_out:r})=>{let[n,o,l,c]=await Promise.all([this.api.query.AssetRegistry.Assets.getValue(i,{at:this.at}),this.api.query.AssetRegistry.AssetLocations.getValue(i,{at:this.at}),this.api.query.AssetRegistry.Assets.getValue(a,{at:this.at}),this.api.query.AssetRegistry.AssetLocations.getValue(a,{at:this.at})]);return{address:this.getPoolId(i,a),type:"Aave",tokens:[{id:i,decimals:n?.decimals,existentialDeposit:n?.existential_deposit,balance:s,location:o,type:n?.asset_type.type},{id:a,decimals:l?.decimals,existentialDeposit:l?.existential_deposit,balance:r,location:c,type:l?.asset_type.type}],...this.getPoolLimits()}});return Promise.all(e)}async getPoolDelta(t){let[e,i]=t.tokens,{liqudity_in:a,liqudity_out:s}=await this.api.apis.AaveTradeExecutor.pool(e.id,i.id,{at:this.at});return t.tokens.map(r=>{let n=r.id===e.id?a:s;return{...r,balance:n}})}async getPoolFees(){return{}}getReserveH160Id(t){if(t.type==="Erc20"&&t.location){let e=t.location.interior;if(e.type==="X1"&&e.value.type==="AccountKey20"){let{value:i}=e.value;return i.key}throw new Error("Invalid aave reserve multilocation")}return Us.fromAssetId(t.id)}parseRouterLog(t){let{asset_in:e,asset_out:i}=t;return{assetIn:e,assetOut:i,key:`${e}:${i}`}}subscribeRouterExecuted(){let e=this.store.pools.map(i=>i.tokens).map(([i,a])=>a).map(i=>i.id);return this.api.event.Router.Executed.watch().pipe(Je(({events:i})=>i),Qe(({payload:i})=>this.parseRouterLog(i)),ne(({assetIn:i,assetOut:a})=>e.includes(i)||e.includes(a)),this.watchGuard("router.Execute")).subscribe(({assetIn:i,assetOut:a,key:s})=>{this.log.trace("router.Executed",s),this.store.update(async r=>{let n=[];for(let o of r){let[l,c]=o.tokens;if(c.id===i||c.id===a){let g=await this.getPoolDelta(o);n.push({...o,tokens:g})}}return n})})}subscribeEvmLog(){return this.api.event.EVM.Log.watch().pipe(Je(({events:t})=>t),Qe(({payload:t})=>Gt.parse(t)),ne(t=>t!==void 0),ne(({eventName:t})=>$s.includes(t)),this.watchGuard("evm.Log")).subscribe(({reserve:t,eventName:e})=>{this.log.trace(`evm.Log.${e}`,t),this.store.update(async i=>{let a=[];for(let s of i){let[r]=s.tokens;if(this.getReserveH160Id(r).toLowerCase()===t){let o=await this.getPoolDelta(s);a.push({...s,tokens:o})}}return a})})}subscribeBalances(){return je.EMPTY}subscribeUpdates(){let t=new je;return t.add(this.subscribeRouterExecuted()),t.add(this.subscribeEvmLog()),t}};var ii={};F(ii,{HsmMath:()=>_,HsmPool:()=>At,HsmPoolClient:()=>Ot});import{calculate_collateral_in_given_hollar_out as Ws,calculate_collateral_out_given_hollar_in as Xs,calculate_hollar_in_given_collateral_out as Ys,calculate_hollar_out_given_collateral_in as Ks,calculate_imbalance as zs,calculate_max_price as js,calculate_buyback_limit as Qs,calculate_buyback_price_with_fee as Js}from"@galacticcouncil/math-hsm";var _=class{static calculateCollateralInGivenHollarOut(t,e,i){return Ws(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 Ys(t,e,i)}static calculateImbalance(t,e,i){return zs(t,e,i)}static calculateBuybackLimit(t,e){return Qs(t,e)}static calculateBuybackPriceWithFee(t,e,i){return Js(t,e,i)}static calculateMaxPrice(t,e){return js(t,e)}};import{big as N,RUNTIME_DECIMALS as Ht}from"@galacticcouncil/common";var{FeeUtils:nt}=f,At=class u extends X{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 a=this.parsePair(t.assetOut,t.assetIn),s=super.calculateInGivenOut(a,e,{fee:this.fee}),r=this.calculateBuybackLimit(t);e>r&&i.push("MaxBuyBackExceeded");let n=this.calculateMaxPrice(t);return this.calculateBuyPrice(t,e,s)>n&&i.push("MaxBuyPriceExceeded"),s>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 a=[];return t.assetIn===this.hollarId?this.validateTradeHollarIn(t,e,a):this.validateTradeHollarOut(e,i,a)}validateAndBuy(t,e){let i=this.calculateInGivenOut(t,e),a=this.validateTradeConstraints(t,i,e);return{amountIn:i,calculatedIn:i,amountOut:e,feePct:0,errors:a}}validateAndSell(t,e){let i=this.calculateOutGivenIn(t,e),a=this.validateTradeConstraints(t,e,i);return{amountIn:e,calculatedOut:i,amountOut:i,feePct:0,errors:a}}calculateHollarInGivenCollateralOut(t,e){let i=super.calculateInGivenOut(t,e,{fee:this.fee}),a=_.calculateHollarInGivenCollateralOut(e.toString(),i.toString(),nt.toRaw(this.buyBackFee).toString());return BigInt(a)}calculateCollateralInGivenHollarOut(t){let e=this.getCollateralPeg(),i=_.calculateCollateralInGivenHollarOut(t.toString(),JSON.stringify(e),nt.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}),a=_.calculateCollateralOutGivenHollarIn(e.toString(),i.toString(),nt.toRaw(this.buyBackFee).toString());return BigInt(a)}calculateHollarOutGivenCollateralIn(t){let e=this.getCollateralPeg(),i=_.calculateHollarOutGivenCollateralIn(t.toString(),JSON.stringify(e),nt.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=_.calculateImbalance(t.balanceIn.toString(),JSON.stringify(e),t.balanceOut.toString());return BigInt(i)}calculateBuybackLimit(t){let e=this.calculateImbalance(t),i=_.calculateBuybackLimit(e.toString(),nt.toRaw(this.buyBackRate).toString());return BigInt(i)}calculateBuyPrice(t,e,i){let a=_.calculateBuybackPriceWithFee(i.toString(),e.toString(),nt.toRaw(this.buyBackFee).toString()),[s,r]=JSON.parse(a),n=N.pow10(t.decimalsIn+Ht-t.decimalsOut);return BigInt(s)*n/BigInt(r)}calculateMaxPrice(t){let e=this.getCollateralPeg(),i=_.calculateMaxPrice(JSON.stringify(e),this.maxBuyPriceCoefficient.toString()),[a,s]=JSON.parse(i),r=N.pow10(Ht-t.decimalsOut);return BigInt(a)*r/BigInt(s)}spotPriceInGivenOut(t){let e=N.toBigInt(1,t.decimalsOut),a=this.calculateInGivenOut(t,e)*N.pow10(Ht-t.decimalsOut);return this.normalizeSpotPrice(a,t.decimalsOut,t.decimalsIn)}spotPriceOutGivenIn(t){let e=N.toBigInt(1,t.decimalsIn),a=this.calculateOutGivenIn(t,e)*N.pow10(Ht-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],i=this.tokens[t].decimals;return this.isDefaultPeg(e)?[N.toBigInt(1,18).toString(),N.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 a=e-i;if(a===0)return t;let s=N.pow10(Math.abs(a));return a>0?t*s:t/s}};import{AccountId as en,CompatibilityLevel as an}from"polkadot-api";import{toHex as sn}from"@polkadot-api/utils";import{Subscription as re,combineLatest as nn,filter as ti,map as oe,mergeMap as rn,pairwise as on}from"rxjs";import{h160 as ln,HYDRATION_SS58_PREFIX as cn}from"@galacticcouncil/common";import{Binary as Zs}from"polkadot-api";import{decodeEventLog as tn}from"viem";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 $t=class{static parse(t){let{topics:e,data:i}=t.log,a=Zs.toHex(i);try{let{eventName:s,args:r}=tn({abi:Ut,topics:e,data:a}),n=r.facilitatorAddress.toLowerCase();return{eventName:s,facilitator:n,key:`${s}:${n}`}}catch{return}}};var Wt=class{client;constructor(t){this.client=t.getWsProvider()}async getFacilitatorCapacity(t,e){let[i,a]=await this.client.readContract({abi:Ut,address:t,functionName:"getFacilitatorBucket",args:[e]});return i-a}};var{FeeUtils:le}=f,{H160:ei}=ln,un=["FacilitatorBucketCapacityUpdated","FacilitatorBucketLevelUpdated"],Ot=class extends w{ghoClient;stableClient;constructor(t,e,i,a){super(t,e,a),this.stableClient=i,this.ghoClient=new Wt(e)}getPoolType(){return"HSM"}getPoolId(t){return this.getPoolAddress("hsm:"+t)}getFacilitatorAddress(){return this.getPoolAddress("modlpy/hsmod")}getHollarAddress(t){if(t){let e=t.interior;if(e.type==="X1"&&e.value.type==="AccountKey20"){let{value:i}=e.value;return i.key}}throw Error("Invalid hollar multilocation")}getPoolAddress(t){let e=t.padEnd(32,"\0"),i=new TextEncoder().encode(e),a=sn(i);return en(cn).dec(a)}async isSupported(){return(await this.api.getStaticApis()).compat.query.HSM.Collaterals.isCompatible(an.BackwardsCompatible)}async loadPools(){let t=await this.api.constants.HSM.HollarId(),[e,i,a]=await Promise.all([this.api.query.AssetRegistry.AssetLocations.getValue(t,{at:this.at}),this.api.query.HSM.Collaterals.getEntries({at:this.at}),this.stableClient.getPools()]);if(i.length===0)return[];let s=this.getFacilitatorAddress(),r=ei.fromAny(s),n=this.getHollarAddress(e),o=await this.ghoClient.getFacilitatorCapacity(n,r),l=i.map(async({keyArgs:m,value:g})=>{let[p]=m,{pool_id:d,max_buy_price_coefficient:b,max_in_holding:O,purchase_fee:S,buy_back_fee:A,buyback_rate:x}=g,v=a.find(B=>B.id===d);if(v){let B=this.getPoolId(d),k=await this.balance.getBalance(s,p);return{...v,address:B,type:"HSM",tokens:v.tokens.filter(U=>U.id!==d),hsmAddress:s,hsmMintCapacity:o,hollarId:t,hollarH160:n,collateralId:p,collateralBalance:k.transferable,maxBuyPriceCoefficient:b,maxInHolding:O,purchaseFee:le.fromPermill(S),buyBackFee:le.fromPermill(A),buyBackRate:le.fromPerbill(x)}}});return(await Promise.all(l)).filter(m=>m!==null)}async getPoolFees(){return{}}subscribeEvmLog(){return this.api.event.EVM.Log.watch().pipe(rn(({events:t})=>t),oe(({payload:t})=>$t.parse(t)),ti(t=>t!==void 0),ti(({eventName:t})=>un.includes(t)),this.watchGuard("evm.Log")).subscribe(({eventName:t,facilitator:e})=>{this.log.trace(`evm.Log.${t}`,e),this.store.update(async i=>{let a=[],[{hsmAddress:s,hollarH160:r}]=i,n=ei.fromAny(s);if(n.toLowerCase()===e){let l=await this.ghoClient.getFacilitatorCapacity(r,n);for(let c of i)a.push({...c,hsmMintCapacity:l})}return a})})}subscribeCollateralBalance(){let t=[],e=[];this.store.pools.forEach(s=>{let{tokens:r,collateralId:n}=s;r.find(l=>l.id===n).type==="Erc20"?e.push(n):t.push(n)});let[{hsmAddress:i}]=this.store.pools,a=[];if(t.length>0){let s=this.balance.watchTokensBalance(i);a.push(s)}if(e.length>0){let s=this.balance.watchErc20Balance(i,e);a.push(s)}return a.length>0?nn(a).pipe(oe(s=>s.flat()),on(),oe(([s,r])=>this.balance.getDeltas(s,r)),this.watchGuard("balances")).subscribe(s=>{this.store.update(r=>{let n=[],o=new Map(r.map(l=>[l.collateralId,l]));return s.forEach(({id:l,balance:c})=>{let m=o.get(l);m&&(this.log.trace("balances",{id:l,balance:c}),n.push({...m,collateralBalance:c.transferable}))}),n})}):re.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 a=[];for(let s of i){let r=e.get(s.id);r&&a.push({...s,fee:r.fee,tokens:r.tokens.filter(n=>n.id!==s.id),totalIssuance:r.totalIssuance,pegs:r.pegs,amplification:r.amplification,isRampPeriod:r.isRampPeriod})}return a})})}subscribeBalances(){return re.EMPTY}subscribeUpdates(){let t=new re;return t.add(this.subscribeCollateralBalance()),t.add(this.subscribeStableswapUpdates()),t.add(this.subscribeEvmLog()),t}};var pi={};F(pi,{UNISWAP_V3_FACTORY:()=>ce,UniswapV3Math:()=>rt,UniswapV3Pool:()=>Bt,UniswapV3PoolClient:()=>kt,V3_POOLS:()=>ue,ticksInWord:()=>mi});var ce="0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0",ue=[{assetA:16,assetB:9,fee:3e3},{assetA:16,assetB:9,fee:500}];import h from"jsbi";import{LiquidityMath as mn,SwapMath as pn,Tick as dn,TickList as ai,TickMath as G}from"@uniswap/v3-sdk";var me=h.BigInt(0),si=h.BigInt(1),pe=h.BigInt(-1),rt=class u{static calculateOutGivenIn(t,e,i){if(i<=0n||t.liquidity<=0n)return 0n;let a=u.computeSwap(t,e,h.BigInt(i.toString())),s=h.multiply(a.amountCalculated,pe);return BigInt(s.toString())}static calculateInGivenOut(t,e,i){if(i<=0n||t.liquidity<=0n)return 0n;let a=u.computeSwap(t,e,h.multiply(h.BigInt(i.toString()),pe));return BigInt(a.amountCalculated.toString())}static computeSwap(t,e,i){let a=u.buildTicks(t.ticks),s=t.tickSpacing,r=t.fee,n=e?h.add(G.MIN_SQRT_RATIO,si):h.subtract(G.MAX_SQRT_RATIO,si),o=h.greaterThanOrEqual(i,me),l=i,c=me,m=h.BigInt(t.sqrtPriceX96.toString()),g=t.tick,p=h.BigInt(t.liquidity.toString());for(;h.notEqual(l,me)&&h.notEqual(m,n);){let d=m,[b,O]=ai.nextInitializedTickWithinOneWord(a,g,e,s);b<G.MIN_TICK?b=G.MIN_TICK:b>G.MAX_TICK&&(b=G.MAX_TICK);let S=G.getSqrtRatioAtTick(b),A=(e?h.lessThan(S,n):h.greaterThan(S,n))?n:S,[x,v,B,k]=pn.computeSwapStep(m,A,p,l,r);if(m=x,o?(l=h.subtract(l,h.add(v,k)),c=h.subtract(c,B)):(l=h.add(l,B),c=h.add(c,h.add(v,k))),h.equal(m,S)){if(O){let U=ai.getTick(a,b).liquidityNet;e&&(U=h.multiply(U,pe)),p=mn.addDelta(p,U)}g=e?b-1:b}else h.notEqual(m,d)&&(g=G.getTickAtSqrtRatio(m))}return{amountCalculated:c,sqrtPriceX96:m,liquidity:p,tick:g}}static buildTicks(t){return t.map(e=>new dn({index:e.index,liquidityGross:e.liquidityGross.toString(),liquidityNet:e.liquidityNet.toString()})).sort((e,i)=>e.index-i.index)}};import{RUNTIME_DECIMALS as gn}from"@galacticcouncil/common";var bn=1e6,ni=10n**BigInt(gn),ri=192n,Bt=class u{type;address;id;tokens;maxInRatio;maxOutRatio;minTradingLimit;fee;token0;token1;sqrtPriceX96;tick;liquidity;tickSpacing;ticks;static fromPool(t){return new u(t)}constructor(t){this.type="UniswapV3",this.address=t.address,this.id=t.id,this.tokens=t.tokens,this.maxInRatio=t.maxInRatio,this.maxOutRatio=t.maxOutRatio,this.minTradingLimit=t.minTradingLimit,this.fee=t.fee,this.token0=t.token0,this.token1=t.token1,this.sqrtPriceX96=t.sqrtPriceX96,this.tick=t.tick,this.liquidity=t.liquidity,this.tickSpacing=t.tickSpacing,this.ticks=t.ticks}validatePair(t,e){let i=a=>a===this.token0||a===this.token1;return i(t)&&i(e)&&t!==e}parsePair(t,e){let i=new Map(this.tokens.map(r=>[r.id,r])),a=i.get(t),s=i.get(e);if(a==null)throw new Error("Pool does not contain tokenIn");if(s==null)throw new Error("Pool does not contain tokenOut");return{assetIn:t,assetOut:e,decimalsIn:a.decimals,decimalsOut:s.decimals,balanceIn:a.balance,balanceOut:s.balance,assetInEd:a.existentialDeposit,assetOutEd:s.existentialDeposit}}calculateInGivenOut(t,e,i){return rt.calculateInGivenOut(this.toState(i!=null),this.isZeroForOne(t.assetIn),e)}calculateOutGivenIn(t,e,i){return rt.calculateOutGivenIn(this.toState(i!=null),this.isZeroForOne(t.assetIn),e)}spotPriceOutGivenIn(t){let e=this.spotOutPerIn(this.isZeroForOne(t.assetIn));return this.normalizeSpot(e,t.decimalsIn,t.decimalsOut)}spotPriceInGivenOut(t){let e=this.spotOutPerIn(!this.isZeroForOne(t.assetIn));return this.normalizeSpot(e,t.decimalsOut,t.decimalsIn)}validateAndSell(t,e,i){let a=this.calculateOutGivenIn(t,e),s=this.calculateOutGivenIn(t,e,this.fees()),r=R.calculateSellFee(a,s),n=[];(e<this.minTradingLimit||a<t.assetOutEd)&&n.push("InsufficientTradingAmount");let o=t.balanceIn/this.maxInRatio;e>o&&n.push("MaxInRatioExceeded");let l=t.balanceOut/this.maxOutRatio;return s>l&&n.push("MaxOutRatioExceeded"),{amountIn:e,calculatedOut:a,amountOut:s,feePct:r,errors:n}}validateAndBuy(t,e,i){let a=this.calculateInGivenOut(t,e),s=this.calculateInGivenOut(t,e,this.fees()),r=R.calculateBuyFee(a,s),n=[];(e<this.minTradingLimit||a<t.assetInEd)&&n.push("InsufficientTradingAmount");let o=t.balanceOut/this.maxOutRatio;e>o&&n.push("MaxOutRatioExceeded");let l=t.balanceIn/this.maxInRatio;return s>l&&n.push("MaxInRatioExceeded"),{amountIn:s,calculatedIn:a,amountOut:e,feePct:r,errors:n}}fees(){return{fee:[this.fee,bn]}}isZeroForOne(t){return t===this.token0}toState(t){return{fee:t?this.fee:0,sqrtPriceX96:this.sqrtPriceX96,tick:this.tick,liquidity:this.liquidity,tickSpacing:this.tickSpacing,ticks:this.ticks}}spotOutPerIn(t){let e=this.sqrtPriceX96*this.sqrtPriceX96;if(e===0n)return 0n;let i=e*ni>>ri;return t?i:(ni<<ri)/e}normalizeSpot(t,e,i){let a=e-i;if(a===0)return t;let s=10n**BigInt(Math.abs(a));return a>0?t*s:t/s}};import{Subscription as hn,filter as yn,map as fn,mergeMap as Pn}from"rxjs";import{erc20 as Sn}from"@galacticcouncil/common";import{TICK_SPACINGS as vn,TickMath as li,nearestUsableTick as ci}from"@uniswap/v3-sdk";import{parseAbi as de}from"viem";var oi=de(["function getPool(address tokenA, address tokenB, uint24 fee) view returns (address pool)"]),Y=de(["function slot0() view returns (uint160 sqrtPriceX96, int24 tick, uint16 observationIndex, uint16 observationCardinality, uint16 observationCardinalityNext, uint8 feeProtocol, bool unlocked)","function liquidity() view returns (uint128)","function tickBitmap(int16 wordPosition) view returns (uint256)","function ticks(int24 tick) view returns (uint128 liquidityGross, int128 liquidityNet, uint256 feeGrowthOutside0X128, uint256 feeGrowthOutside1X128, int56 tickCumulativeOutside, uint160 secondsPerLiquidityOutsideX128, uint32 secondsOutside, bool initialized)"]),_t=de(["function balanceOf(address account) view returns (uint256)"]);var{ERC20:Xt}=Sn,Tn="0x0000000000000000000000000000000000000000",xn=1e6,ui=5;function mi(u,t,e){let i=[];for(let a=0;a<256;a++)u>>BigInt(a)&1n&&i.push((t*256+a)*e);return i}var kt=class extends w{getPoolType(){return"UniswapV3"}async isSupported(){return!0}async getPoolFees(t,e){let i=this.store.pools.find(s=>s.address===e);return{fee:[i?i.fee:0,xn]}}async loadPools(){let t=this.evm.getWsProvider();return(await Promise.all(ue.map(i=>this.loadPool(t,i)))).filter(i=>i!==void 0)}async loadPool(t,e){try{let{assetA:i,assetB:a,fee:s}=e,r=vn[s];if(r===void 0)return;let n=Xt.fromAssetId(i).toLowerCase(),o=Xt.fromAssetId(a).toLowerCase(),l=n<o,c=l?i:a,m=l?a:i,g=l?n:o,p=l?o:n,d=await t.readContract({abi:oi,address:ce,functionName:"getPool",args:[g,p,s]});if(d.toLowerCase()===Tn)return;let[b,O,S,A,x,v]=await Promise.all([t.readContract({abi:Y,address:d,functionName:"slot0"}),t.readContract({abi:Y,address:d,functionName:"liquidity"}),t.readContract({abi:_t,address:g,functionName:"balanceOf",args:[d]}),t.readContract({abi:_t,address:p,functionName:"balanceOf",args:[d]}),this.api.query.AssetRegistry.Assets.getValue(c,{at:this.at}),this.api.query.AssetRegistry.Assets.getValue(m,{at:this.at})]),B=b[0],k=b[1],U=await this.loadTicks(t,d,k,r);return{address:d,type:"UniswapV3",token0:c,token1:m,fee:s,sqrtPriceX96:B,tick:k,liquidity:O,tickSpacing:r,ticks:U,tokens:[{id:c,decimals:x?.decimals,existentialDeposit:x?.existential_deposit??0n,balance:S,type:x?.asset_type.type},{id:m,decimals:v?.decimals,existentialDeposit:v?.existential_deposit??0n,balance:A,type:v?.asset_type.type}],maxInRatio:3n,maxOutRatio:3n,minTradingLimit:0n}}catch(i){this.log.error("v3_load_pool",e,i);return}}async loadTicks(t,e,i,a){let s=Math.floor(i/a)>>8,r=[];for(let p=s-ui;p<=s+ui;p++)r.push(p);let n=await Promise.all(r.map(p=>t.readContract({abi:Y,address:e,functionName:"tickBitmap",args:[p]}))),o=r.flatMap((p,d)=>mi(n[d],p,a)),l=await Promise.all(o.map(p=>t.readContract({abi:Y,address:e,functionName:"ticks",args:[p]}))),c=o.map((p,d)=>({index:p,liquidityGross:l[d][0],liquidityNet:l[d][1]})),m=ci(li.MIN_TICK,a),g=ci(li.MAX_TICK,a);return c.some(p=>p.index===m)||c.push({index:m,liquidityNet:0n,liquidityGross:0n}),c.some(p=>p.index===g)||c.push({index:g,liquidityNet:0n,liquidityGross:0n}),c.sort((p,d)=>p.index-d.index),c}async refreshPool(t,e){let i=e.address,a=Xt.fromAssetId(e.token0).toLowerCase(),s=Xt.fromAssetId(e.token1).toLowerCase(),[r,n,o,l]=await Promise.all([t.readContract({abi:Y,address:i,functionName:"slot0"}),t.readContract({abi:Y,address:i,functionName:"liquidity"}),t.readContract({abi:_t,address:a,functionName:"balanceOf",args:[i]}),t.readContract({abi:_t,address:s,functionName:"balanceOf",args:[i]})]),c=r[1],m=await this.loadTicks(t,i,c,e.tickSpacing),g=e.tokens.map(p=>p.id===e.token0?{...p,balance:o}:{...p,balance:l});return{...e,sqrtPriceX96:r[0],tick:c,liquidity:n,ticks:m,tokens:g}}subscribeBalances(){return hn.EMPTY}subscribeUpdates(){let t=new Set(this.store.pools.map(e=>e.address.toLowerCase()));return this.api.event.EVM.Log.watch().pipe(Pn(({events:e})=>e),fn(({payload:e})=>e.log.address.toLowerCase()),yn(e=>t.has(e)),this.watchGuard("evm.Log")).subscribe(e=>{this.log.trace("evm.Log",e),this.store.update(async i=>{let a=this.evm.getWsProvider(),s=[];for(let r of i)r.address.toLowerCase()===e&&s.push(await this.refreshPool(a,r));return s})})}};var ge=class{static get(t){switch(t.type){case"Aave":return It.fromPool(t);case"XYK":return Tt.fromPool(t);case"Omnipool":return ht.fromPool(t);case"LBP":return ct.fromPool(t);case"Stableswap":return X.fromPool(t);case"HSM":return At.fromPool(t);case"UniswapV3":return Bt.fromPool(t);default:throw new Error("Pool type "+t.type+" is not supported yet")}}};import{log as In}from"@galacticcouncil/common";import{Subject as wn,Subscription as H,takeUntil as An}from"rxjs";var ot=class extends Error{constructor(t){super(),this.message=`${t} pool invalid`,this.name="PoolNotFound"}};var{logger:On}=In,be=class extends C{evm;aave;omnipool;stableswap;hsm;xyk;lbp;uniswapv3;active=new Set([]);pools=new Map([]);clients=[];aaveSub=H.EMPTY;omniSub=H.EMPTY;stableSub=H.EMPTY;hsmSub=H.EMPTY;xykSub=H.EMPTY;lbpSub=H.EMPTY;v3Sub=H.EMPTY;isReady=!1;isDestroyed=new wn;constructor(t,e,i){super(t,i),this.evm=e,this.aave=new wt(t,e,i),this.omnipool=new yt(t,e,i),this.stableswap=new vt(t,e,i),this.hsm=new Ot(t,e,this.stableswap,i),this.xyk=new xt(t,e,i),this.lbp=new bt(t,e,i),this.uniswapv3=new kt(t,e,i),this.clients=[this.aave,this.omnipool,this.stableswap,this.hsm,this.xyk,this.lbp,this.uniswapv3]}get isHistorical(){return this.at!=="best"&&this.at!=="finalized"}subscribe(t){return this.isHistorical?H.EMPTY:t.getSubscriber().pipe(An(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")||(On.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}withV3(){return this.v3Sub.unsubscribe(),this.v3Sub=this.subscribe(this.uniswapv3),this.active.add("UniswapV3"),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(a=>a.getPoolType()===e.type);if(i)return i.getPoolFees(t,e.address);throw new ot(e.type)}};var he=class{constructor(t){this.snapshot=t;let{aave:e,xyk:i,lbp:a,stable:s,omni:r}=t.pools;this.flat=[...e,...i,...a,...s,...r]}flat;async getPools(){return this.flat}async getPoolFees(t,e){let{block:i,states:a}=this.snapshot;switch(e.type){case"Aave":return{};case"XYK":{let{exchangeFee:s}=a.xyk;return{exchangeFee:s}}case"LBP":{let{repayFee:s}=a.lbp;return{exchangeFee:e.fee,repayFee:s}}case"Stableswap":return{fee:e.fee};case"Omnipool":{let s=t.assetOut,r=t.assetIn,{dynamicFees:n,emaOracles:o,assetFeeParams:l,protocolFeeParams:c,maxSlipFee:m}=a.omni,g=n.find(({asset:b})=>b===s)?.fee,p=o.find(({pair:b})=>b.join(":")===qt(s))?.oracle,d=o.find(({pair:b})=>b.join(":")===qt(r))?.oracle;return W.compute(t,i,g,p,d,l,c,m)}default:throw new ot(e.type)}}};export{be as PoolContextProvider,V as PoolError,ge as PoolFactory,P as PoolType,he as SnapshotPoolCtxProvider,Ze as aave,ii as hsm,Fe as lbp,Me as omni,We as stable,pi as uniswapv3,Ye as xyk};
@@ -9,7 +9,8 @@ export declare enum PoolType {
9
9
  Omni = "Omnipool",
10
10
  Stable = "Stableswap",
11
11
  XYK = "XYK",
12
- HSM = "HSM"
12
+ HSM = "HSM",
13
+ V3 = "UniswapV3"
13
14
  }
14
15
  export declare enum PoolError {
15
16
  UnknownError = "UnknownError",
@@ -90,6 +91,7 @@ export type Hop = {
90
91
  pool: PoolType;
91
92
  poolAddress: string;
92
93
  poolId?: number;
94
+ fee?: number;
93
95
  assetIn: number;
94
96
  assetOut: number;
95
97
  };
@@ -0,0 +1,7 @@
1
+ import { V3PoolState } from './types';
2
+ export declare class UniswapV3Math {
3
+ static calculateOutGivenIn(state: V3PoolState, zeroForOne: boolean, amountIn: bigint): bigint;
4
+ static calculateInGivenOut(state: V3PoolState, zeroForOne: boolean, amountOut: bigint): bigint;
5
+ private static computeSwap;
6
+ private static buildTicks;
7
+ }
@@ -0,0 +1,46 @@
1
+ import { BuyCtx, Pool, PoolFees, PoolPair, PoolToken, PoolType, SellCtx } from '../types';
2
+ import { UniswapV3PoolBase, UniswapV3PoolFees, V3Tick } from './types';
3
+ /**
4
+ * Concrete Uniswap v3 pool. Implements the synchronous router `Pool` interface
5
+ * by delegating swap math to `UniswapV3Math` (a tick-walk over the pool's
6
+ * loaded concentrated liquidity) and deriving the spot price from `sqrtPriceX96`.
7
+ *
8
+ * The v3 fee is taken inside the swap, so — mirroring `OmniPool`/`StableSwap` —
9
+ * `calculate*` returns the gross (fee-less) amount when called without `fees`
10
+ * and the net amount when called with them; `validateAndSell/Buy` use the two
11
+ * to report the effective fee.
12
+ */
13
+ export declare class UniswapV3Pool implements Pool {
14
+ type: PoolType;
15
+ address: string;
16
+ id?: number;
17
+ tokens: PoolToken[];
18
+ maxInRatio: bigint;
19
+ maxOutRatio: bigint;
20
+ minTradingLimit: bigint;
21
+ fee: number;
22
+ token0: number;
23
+ token1: number;
24
+ sqrtPriceX96: bigint;
25
+ tick: number;
26
+ liquidity: bigint;
27
+ tickSpacing: number;
28
+ ticks: V3Tick[];
29
+ static fromPool(pool: UniswapV3PoolBase): UniswapV3Pool;
30
+ constructor(pool: UniswapV3PoolBase);
31
+ validatePair(tokenIn: number, tokenOut: number): boolean;
32
+ parsePair(tokenIn: number, tokenOut: number): PoolPair;
33
+ /** Input required for `amountOut`; gross (fee-less) unless `fees` is given. */
34
+ calculateInGivenOut(poolPair: PoolPair, amountOut: bigint, fees?: UniswapV3PoolFees): bigint;
35
+ /** Output for `amountIn`; gross (fee-less) unless `fees` is given. */
36
+ calculateOutGivenIn(poolPair: PoolPair, amountIn: bigint, fees?: UniswapV3PoolFees): bigint;
37
+ spotPriceOutGivenIn(poolPair: PoolPair): bigint;
38
+ spotPriceInGivenOut(poolPair: PoolPair): bigint;
39
+ validateAndSell(poolPair: PoolPair, amountIn: bigint, _dynamicFees: PoolFees | null): SellCtx;
40
+ validateAndBuy(poolPair: PoolPair, amountOut: bigint, _dynamicFees: PoolFees | null): BuyCtx;
41
+ private fees;
42
+ private isZeroForOne;
43
+ private toState;
44
+ private spotOutPerIn;
45
+ private normalizeSpot;
46
+ }
@@ -0,0 +1,45 @@
1
+ import { Subscription } from 'rxjs';
2
+ import { PoolFees, PoolPair, PoolType } from '../types';
3
+ import { PoolClient } from '../PoolClient';
4
+ import { UniswapV3PoolBase } from './types';
5
+ /**
6
+ * Decode one tick-bitmap word into the absolute tick indices it marks
7
+ * initialized. Bit `i` of the word at `wordPos` is compressed tick
8
+ * `wordPos * 256 + i`, i.e. absolute tick `(wordPos * 256 + i) * tickSpacing`.
9
+ */
10
+ export declare function ticksInWord(bitmap: bigint, wordPos: number, tickSpacing: number): number[];
11
+ /**
12
+ * Router venue for Uniswap v3 pools on Hydration's EVM.
13
+ *
14
+ * Pools come from a curated per-chain config (`V3_POOLS`) and are resolved via
15
+ * the v3 factory — mirroring the on-chain design where v3 routes are
16
+ * governance-gated rather than permissionless. Concentrated-liquidity state
17
+ * (`slot0`, `liquidity`, and initialized ticks via the tick bitmap) is read
18
+ * directly over the EVM; quoting itself is client-side in
19
+ * `UniswapV3Pool`/`UniswapV3Math`.
20
+ */
21
+ export declare class UniswapV3PoolClient extends PoolClient<UniswapV3PoolBase> {
22
+ getPoolType(): PoolType;
23
+ isSupported(): Promise<boolean>;
24
+ /** Fixed per-pool fee tier as a `[numerator, denominator]` fraction. */
25
+ getPoolFees(_pair: PoolPair, address: string): Promise<PoolFees>;
26
+ /** Resolve and load every configured pool; pools that fail to load are skipped. */
27
+ loadPools(): Promise<UniswapV3PoolBase[]>;
28
+ private loadPool;
29
+ /**
30
+ * Read the initialized ticks in a bounded window around the current tick via
31
+ * the pool's tick bitmap, plus the usable min/max ticks as zero-liquidity
32
+ * sentinels so the swap walk is always bounded (a full-range pool with no
33
+ * ticks in range simply yields the two sentinels).
34
+ */
35
+ private loadTicks;
36
+ private refreshPool;
37
+ /**
38
+ * The base balance watcher targets substrate accounts, but a v3 pool is an
39
+ * EVM contract — its reserves, price and ticks are refreshed via EVM reads in
40
+ * `subscribeUpdates`/`loadPools` instead (mirrors `AavePoolClient`).
41
+ */
42
+ protected subscribeBalances(): Subscription;
43
+ /** Re-sync a pool's state whenever it emits an EVM log (swap/mint/burn). */
44
+ protected subscribeUpdates(): Subscription;
45
+ }