@galacticcouncil/sdk-next 0.37.0 → 0.38.1-pr305-7b64458
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/build/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var _r=Object.defineProperty;var I=(m,t)=>{for(var e in t)_r(m,e,{get:t[e],enumerable:!0})};import Fr from"buffer";typeof window<"u"&&(window.Buffer=Fr.Buffer);var Pn={};I(Pn,{Papi:()=>_,Watcher:()=>At,getSm:()=>Jr,getWs:()=>jr});import{hydration as Yr,hydrationNext as $r}from"@galacticcouncil/descriptors";import{log as Gr}from"@galacticcouncil/common";import{shareReplay as Vr,tap as Ur}from"rxjs";import{defer as Rr,from as Cr,of as yn,timer as Er}from"rxjs";import{catchError as kr,distinctUntilChanged as Mr,expand as Dr,map as Me,shareReplay as Lr,skip as qr,switchMap as Nr,timeout as Hr}from"rxjs/operators";function fn(m,{intervalMs:t=5e3,rpcTimeoutMs:e=1e4}={}){let n=()=>Rr(()=>Cr(m._request("system_health",[]))).pipe(Hr({first:e}),Me(()=>"online"),kr(()=>yn("offline")));return yn({state:"offline",delayMs:0}).pipe(Dr(i=>Er(i.delayMs).pipe(Nr(n),Me(a=>({state:a,delayMs:t})))),qr(1),Me(i=>i.state),Mr(),Lr({bufferSize:1,refCount:!0}))}var{logger:Wr}=Gr,At=class m{static instance=null;bestBlock$;finalizedBlock$;connection$;constructor(t){this.bestBlock$=this.watched("watcher(bestBlock)",t.getUnsafeApi().query.System.Number.watchValue("best")),this.finalizedBlock$=this.watched("watcher(finalizedBlock)",t.finalizedBlock$),this.connection$=this.watched("watcher(connection)",fn(t))}static getInstance(t){return this.instance||(this.instance=new m(t)),this.instance}watched(t,e){return e.pipe(Ur({error:n=>Wr.error(t,n)}),Vr({bufferSize:1,refCount:!0}))}};var _=class{client;api;apiNext;watcher;constructor(t){this.client=t,this.api=this.client.getTypedApi(Yr),this.apiNext=this.client.getTypedApi($r),this.watcher=At.getInstance(this.client)}};import{getWsProvider as Xr}from"polkadot-api/ws-provider";import{withLogsRecorder as zr}from"polkadot-api/logs-provider";import{withLegacy as Kr}from"@polkadot-api/legacy-provider";var jr=(m,t={})=>{let e=typeof m=="string"?m.split(","):m,n=Xr(e,{innerEnhancer:Kr(),...t});return zr(r=>console.log(r),n),n};import{getSmProvider as Qr}from"polkadot-api/sm-provider";async function Jr(m){let{start:t}=await import("polkadot-api/smoldot"),{chainSpec:e}=await import("polkadot-api/chains/polkadot"),n=t(),r=await n.addChain({chainSpec:e}),i=await n.addChain({chainSpec:m,potentialRelayChains:[r]});return Qr(i)}var wn={};I(wn,{AAVE_GAS_LIMIT:()=>qe,AAVE_LENDING_POOL_ADDRESS:()=>me,AAVE_POOL_ABI:()=>De,AAVE_POOL_DATA_PROVIDER:()=>ue,AAVE_POOL_DATA_PROVIDER_ABI:()=>ce,AAVE_POOL_PROXY:()=>Le,AAVE_ROUNDING_THRESHOLD:()=>Ko,AAVE_UINT_256_MAX:()=>Zr,AaveClient:()=>Bt,AaveUtils:()=>nt});var De=[{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 ce=[{inputs:[{internalType:"contract IEACAggregatorProxy",name:"_networkBaseTokenPriceInUsdProxyAggregator",type:"address"},{internalType:"contract IEACAggregatorProxy",name:"_marketReferenceCurrencyPriceInUsdProxyAggregator",type:"address"}],stateMutability:"nonpayable",type:"constructor"},{inputs:[],name:"ETH_CURRENCY_UNIT",outputs:[{internalType:"uint256",name:"",type:"uint256"}],stateMutability:"view",type:"function"},{inputs:[],name:"MKR_ADDRESS",outputs:[{internalType:"address",name:"",type:"address"}],stateMutability:"view",type:"function"},{inputs:[{internalType:"bytes32",name:"_bytes32",type:"bytes32"}],name:"bytes32ToString",outputs:[{internalType:"string",name:"",type:"string"}],stateMutability:"pure",type:"function"},{inputs:[{internalType:"contract IPoolAddressesProvider",name:"provider",type:"address"}],name:"getReservesData",outputs:[{components:[{internalType:"address",name:"underlyingAsset",type:"address"},{internalType:"string",name:"name",type:"string"},{internalType:"string",name:"symbol",type:"string"},{internalType:"uint256",name:"decimals",type:"uint256"},{internalType:"uint256",name:"baseLTVasCollateral",type:"uint256"},{internalType:"uint256",name:"reserveLiquidationThreshold",type:"uint256"},{internalType:"uint256",name:"reserveLiquidationBonus",type:"uint256"},{internalType:"uint256",name:"reserveFactor",type:"uint256"},{internalType:"bool",name:"usageAsCollateralEnabled",type:"bool"},{internalType:"bool",name:"borrowingEnabled",type:"bool"},{internalType:"bool",name:"stableBorrowRateEnabled",type:"bool"},{internalType:"bool",name:"isActive",type:"bool"},{internalType:"bool",name:"isFrozen",type:"bool"},{internalType:"uint128",name:"liquidityIndex",type:"uint128"},{internalType:"uint128",name:"variableBorrowIndex",type:"uint128"},{internalType:"uint128",name:"liquidityRate",type:"uint128"},{internalType:"uint128",name:"variableBorrowRate",type:"uint128"},{internalType:"uint128",name:"stableBorrowRate",type:"uint128"},{internalType:"uint40",name:"lastUpdateTimestamp",type:"uint40"},{internalType:"address",name:"aTokenAddress",type:"address"},{internalType:"address",name:"stableDebtTokenAddress",type:"address"},{internalType:"address",name:"variableDebtTokenAddress",type:"address"},{internalType:"address",name:"interestRateStrategyAddress",type:"address"},{internalType:"uint256",name:"availableLiquidity",type:"uint256"},{internalType:"uint256",name:"totalPrincipalStableDebt",type:"uint256"},{internalType:"uint256",name:"averageStableRate",type:"uint256"},{internalType:"uint256",name:"stableDebtLastUpdateTimestamp",type:"uint256"},{internalType:"uint256",name:"totalScaledVariableDebt",type:"uint256"},{internalType:"uint256",name:"priceInMarketReferenceCurrency",type:"uint256"},{internalType:"address",name:"priceOracle",type:"address"},{internalType:"uint256",name:"variableRateSlope1",type:"uint256"},{internalType:"uint256",name:"variableRateSlope2",type:"uint256"},{internalType:"uint256",name:"stableRateSlope1",type:"uint256"},{internalType:"uint256",name:"stableRateSlope2",type:"uint256"},{internalType:"uint256",name:"baseStableBorrowRate",type:"uint256"},{internalType:"uint256",name:"baseVariableBorrowRate",type:"uint256"},{internalType:"uint256",name:"optimalUsageRatio",type:"uint256"},{internalType:"bool",name:"isPaused",type:"bool"},{internalType:"bool",name:"isSiloedBorrowing",type:"bool"},{internalType:"uint128",name:"accruedToTreasury",type:"uint128"},{internalType:"uint128",name:"unbacked",type:"uint128"},{internalType:"uint128",name:"isolationModeTotalDebt",type:"uint128"},{internalType:"bool",name:"flashLoanEnabled",type:"bool"},{internalType:"uint256",name:"debtCeiling",type:"uint256"},{internalType:"uint256",name:"debtCeilingDecimals",type:"uint256"},{internalType:"uint8",name:"eModeCategoryId",type:"uint8"},{internalType:"uint256",name:"borrowCap",type:"uint256"},{internalType:"uint256",name:"supplyCap",type:"uint256"},{internalType:"uint16",name:"eModeLtv",type:"uint16"},{internalType:"uint16",name:"eModeLiquidationThreshold",type:"uint16"},{internalType:"uint16",name:"eModeLiquidationBonus",type:"uint16"},{internalType:"address",name:"eModePriceSource",type:"address"},{internalType:"string",name:"eModeLabel",type:"string"},{internalType:"bool",name:"borrowableInIsolation",type:"bool"}],internalType:"struct IUiPoolDataProviderV3.AggregatedReserveData[]",name:"",type:"tuple[]"},{components:[{internalType:"uint256",name:"marketReferenceCurrencyUnit",type:"uint256"},{internalType:"int256",name:"marketReferenceCurrencyPriceInUsd",type:"int256"},{internalType:"int256",name:"networkBaseTokenPriceInUsd",type:"int256"},{internalType:"uint8",name:"networkBaseTokenPriceDecimals",type:"uint8"}],internalType:"struct IUiPoolDataProviderV3.BaseCurrencyInfo",name:"",type:"tuple"}],stateMutability:"view",type:"function"},{inputs:[{internalType:"contract IPoolAddressesProvider",name:"provider",type:"address"}],name:"getReservesList",outputs:[{internalType:"address[]",name:"",type:"address[]"}],stateMutability:"view",type:"function"},{inputs:[{internalType:"contract IPoolAddressesProvider",name:"provider",type:"address"},{internalType:"address",name:"user",type:"address"}],name:"getUserReservesData",outputs:[{components:[{internalType:"address",name:"underlyingAsset",type:"address"},{internalType:"uint256",name:"scaledATokenBalance",type:"uint256"},{internalType:"bool",name:"usageAsCollateralEnabledOnUser",type:"bool"},{internalType:"uint256",name:"stableBorrowRate",type:"uint256"},{internalType:"uint256",name:"scaledVariableDebt",type:"uint256"},{internalType:"uint256",name:"principalStableDebt",type:"uint256"},{internalType:"uint256",name:"stableBorrowLastUpdateTimestamp",type:"uint256"}],internalType:"struct IUiPoolDataProviderV3.UserReserveData[]",name:"",type:"tuple[]"},{internalType:"uint8",name:"",type:"uint8"}],stateMutability:"view",type:"function"},{inputs:[],name:"marketReferenceCurrencyPriceInUsdProxyAggregator",outputs:[{internalType:"contract IEACAggregatorProxy",name:"",type:"address"}],stateMutability:"view",type:"function"},{inputs:[],name:"networkBaseTokenPriceInUsdProxyAggregator",outputs:[{internalType:"contract IEACAggregatorProxy",name:"",type:"address"}],stateMutability:"view",type:"function"}];var Le="0x1b02E051683b5cfaC5929C25E84adb26ECf87B38",ue="0x112b087b60C1a166130d59266363C45F8aa99db0",me="0xf3Ba4D1b50f78301BDD7EAEa9B67822A15FCA691",qe=1000000n,Ko=5,Zr=BigInt("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");var Bt=class{client;constructor(t){this.client=t.getWsProvider()}async getBlockTimestamp(){let t=await this.client.getBlock();return Number(t.timestamp)}async getReservesData(){return await this.client.readContract({abi:ce,address:ue,args:[me],functionName:"getReservesData"})}async getUserReservesData(t){return await this.client.readContract({abi:ce,address:ue,args:[me,t],functionName:"getUserReservesData"})}async getUserAccountData(t){return await this.client.readContract({abi:De,address:Le,args:[t],functionName:"getUserAccountData"})}};import E from"big.js";import{big as et,erc20 as ti,h160 as ei}from"@galacticcouncil/common";var{ERC20:at}=ti,{H160:Ne}=ei,ni=1.01,ri=31536000n,Sn=4,pe=-1,de=10n**27n,nt=class{client;constructor(t){this.client=new Bt(t)}async getSummary(t){let e=Ne.fromAny(t),[n,r,i,a]=await Promise.all([this.client.getReservesData(),this.client.getUserReservesData(e),this.client.getUserAccountData(e),this.client.getBlockTimestamp()]),[s]=n,[o,l]=r,[c,u,d,p,h,b]=i,g=et.toDecimal(b,18),f=[];for(let y of o){let S=y.underlyingAsset.toLowerCase(),P=s.find(({underlyingAsset:ke})=>ke.toLowerCase()===S);if(!P)throw new Error("Missing pool reserve for "+S);let w=y.scaledATokenBalance,T=P.liquidityIndex,F=P.liquidityRate,k=P.availableLiquidity,$=P.priceInMarketReferenceCurrency,K=a+6,H=this.calculateLinearInterest(F,P.lastUpdateTimestamp,K),V=T*H/de,Ot=w*V/de,se=Number(l!==0&&l===P.eModeCategoryId?P.eModeLiquidationThreshold:P.reserveLiquidationThreshold)/1e4,oe=P.usageAsCollateralEnabled&&y.usageAsCollateralEnabledOnUser&&y.scaledATokenBalance>0n,le=at.toAssetId(S);f.push({aTokenBalance:Ot,availableLiquidity:k,decimals:Number(P.decimals),isCollateral:oe,priceInRef:$,reserveId:le,reserveAsset:S,reserveLiquidationThreshold:se})}return{healthFactor:Number(g),currentLiquidationThreshold:Number(et.toDecimal(p,Sn)),totalCollateral:c,totalDebt:u,reserves:f}}async hasBorrowPositions(t){let e=Ne.fromAny(t),n=await this.client.getUserAccountData(e),[r,i]=n;return i>0n}async getHealthFactor(t){let e=Ne.fromAny(t),n=await this.client.getUserAccountData(e),[r,i,a,s,o,l]=n;return this.calculateHealthFactorFromBalances(i,r,s)}async getHealthFactorAfterWithdraw(t,e,n){let{totalCollateral:r,totalDebt:i,reserves:a,currentLiquidationThreshold:s}=await this.getSummary(t);if(i===0n)return pe;let o=at.fromAssetId(e),l=a.find(S=>S.reserveAsset===o);if(!l)throw new Error("Missing reserve ctx for "+o);let{decimals:c,isCollateral:u,priceInRef:d,reserveLiquidationThreshold:p}=l,h=et.toBigInt(n,c),b=u?h*d/10n**BigInt(c):0n,g=r-b;if(g<=0n)return 0;let f=E(r.toString()).mul(s).minus(E(b.toString()).mul(p)).div(g.toString()),y=E(g.toString()).mul(f).div(i.toString()).toFixed(6,E.roundDown);return Number(y)}async getHealthFactorAfterSupply(t,e,n){let{totalCollateral:r,totalDebt:i,reserves:a,currentLiquidationThreshold:s}=await this.getSummary(t);if(i===0n)return pe;let o=at.fromAssetId(e),l=a.find(y=>y.reserveAsset===o);if(!l)throw new Error("Missing reserve ctx for "+o);let{decimals:c,priceInRef:u,reserveLiquidationThreshold:d}=l,h=et.toBigInt(n,c)*u/10n**BigInt(c),b=r+h;if(b<=0n)return 0;let g=E(r.toString()).mul(s).plus(E(h.toString()).mul(d)).div(b.toString()),f=E(b.toString()).mul(g).div(i.toString()).toFixed(6,E.roundDown);return Number(f)}async getHealthFactorAfterSwap(t,e,n,r,i){let{totalDebt:a,reserves:s,healthFactor:o}=await this.getSummary(t);if(a===0n)return pe;let l=at.fromAssetId(n),c=at.fromAssetId(i),u=s.find(T=>T.reserveAsset===l),d=s.find(T=>T.reserveAsset===c);if(!u)throw new Error(`Missing reserve ctx for ${l}`);if(!d)throw new Error(`Missing reserve ctx for ${d}`);let p=et.toBigInt(e,u.decimals),h=et.toBigInt(r,d.decimals),b=p*u.priceInRef/10n**BigInt(u.decimals),g=h*d.priceInRef/10n**BigInt(d.decimals),f=u.isCollateral?E(b.toString()).mul(u.reserveLiquidationThreshold):E(0),P=E(g.toString()).mul(d.reserveLiquidationThreshold).minus(f).div(a.toString()),w=E(o).plus(P).toFixed(6,E.roundDown);return Number(w)}async getMaxWithdraw(t,e){let{totalDebt:n,reserves:r,healthFactor:i}=await this.getSummary(t),a=at.fromAssetId(e),s=r.find(o=>o.reserveAsset===a);if(!s)throw new Error("Missing reserve ctx for "+a);return this.calculateWithdrawMax(s,n,i)}async getMaxWithdrawAll(t){let{totalDebt:e,reserves:n,healthFactor:r}=await this.getSummary(t),i={};for(let a of n){let s=this.calculateWithdrawMax(a,e,r);a.reserveId&&(i[a.reserveId]=s)}return i}calculateWithdrawMax(t,e,n){let{aTokenBalance:r,availableLiquidity:i,decimals:a,priceInRef:s,reserveLiquidationThreshold:o,isCollateral:l}=t,c=r;if(l&&e>0n){let d=n-ni;if(d>0){let p=E(d).mul(e.toString()).div(o).toFixed(0,E.roundDown),h=E(p).div(s.toString()).mul(10**a).toFixed(0,E.roundDown);c=r<BigInt(h)?r:BigInt(h)}else c=0n}return{amount:c<i?c:i,decimals:a}}calculateLinearInterest(t,e,n){let r=n-e;if(r<=0)return de;let i=t*BigInt(r)/ri;return de+i}calculateHealthFactorFromBalances(t,e,n){if(t===0n)return pe;let r=e*n/t,i=et.toDecimal(r,Sn);return Number(i)}};var An={};I(An,{AssetClient:()=>st,BalanceClient:()=>X,ChainParams:()=>mt});var st=class extends _{SUPPORTED_TYPES=["StableSwap","Bond","Token","External","Erc20"];constructor(t){super(t)}async queryShares(){let e=await this.api.query.Stableswap.Pools.getEntries();return new Map(e.map(({keyArgs:n,value:r})=>{let[i]=n;return[i,r]}))}async queryBonds(){let e=await this.api.query.Bonds.Bonds.getEntries();return new Map(e.map(({keyArgs:n,value:r})=>{let[i]=n;return[i,r]}))}async queryAssets(){let e=await this.api.query.AssetRegistry.Assets.getEntries();return new Map(e.filter(({value:n})=>{let{asset_type:r}=n;return this.SUPPORTED_TYPES.includes(r.type)}).map(({keyArgs:n,value:r})=>{let[i]=n;return[i,r]}))}async queryAssetLocations(){let e=await this.api.query.AssetRegistry.AssetLocations.getEntries();return new Map(e.map(({keyArgs:n,value:r})=>{let[i]=n;return[i,r]}))}async mapToken(t,e,n,r){let{name:i,asset_type:a,is_sufficient:s,existential_deposit:o}=e,{symbol:l,decimals:c}=n.get(t)??{};return{id:t,name:i?.asText(),symbol:l,decimals:c,icon:l,type:a.type,isSufficient:s,location:r,existentialDeposit:o}}async mapBond(t,e,n,r){let[i,a]=r,{asset_type:s,is_sufficient:o,existential_deposit:l}=e,{symbol:c,decimals:u}=await this.mapToken(i,e,n),d=Number(a),p=new Intl.DateTimeFormat("en-GB"),h=[c,"Bond",p.format(d)].join(" ");return{id:t,name:h,symbol:c+"b",decimals:u,icon:c,type:s.type,isSufficient:o,existentialDeposit:l,underlyingAssetId:i,maturity:d}}async mapShares(t,e,n,r){let{assets:i}=r,{name:a,symbol:s,asset_type:o,is_sufficient:l,existential_deposit:c}=e,u=await Promise.all(i.map(async h=>{let{symbol:b}=await this.mapToken(h,e,n);return[h,b]})),d=Object.fromEntries(u),p=Object.values(d);return{id:t,name:p.join(", "),symbol:s?.asText()||a?.asText(),decimals:18,icon:p.join("/"),type:o.type,isSufficient:l,existentialDeposit:c,meta:d}}async mapExternal(t,e,n,r){let i=await this.mapToken(t,e,new Map,r),a=n?.find(s=>s.internalId===i.id);return a?{...i,decimals:a.decimals,name:a.name,symbol:a.symbol,icon:a.symbol,isWhiteListed:a.isWhiteListed}:i}parseMetadata(t){return new Map(Array.from(t,([e,n])=>[e,{symbol:n.symbol?.asText(),decimals:n.decimals}]))}async getSupported(t,e){let[n,r,i,a]=await Promise.all([this.queryAssets(),this.queryAssetLocations(),this.queryShares(),this.queryBonds()]),s=this.parseMetadata(n),o=[];for(let[l,c]of Array.from(n)){let u=r.get(l),{asset_type:d}=c,p;switch(d.type){case"Bond":let h=a.get(l);p=await this.mapBond(l,c,s,h);break;case"StableSwap":let b=i.get(l);p=await this.mapShares(l,c,s,b);break;case"External":p=await this.mapExternal(l,c,e,u);break;default:p=await this.mapToken(l,c,s,u)}o.push(p)}return t?o:o.filter(l=>this.isValidAsset(l))}isValidAsset(t){let e=Math.sign(t.decimals);return!!t.symbol&&(e===0||e===1)}};import{log as si}from"@galacticcouncil/common";import{combineLatest as oi,concat as li,defer as Ft,from as vn}from"rxjs";import{bufferCount as ci,distinctUntilChanged as xn,debounceTime as ui,map as ct,pairwise as mi,retry as pi,startWith as In,switchMap as On,tap as Rt,take as di,skip as gi,connect as hi}from"rxjs/operators";var Tn={};I(Tn,{HUB_ASSET_ID:()=>_t,HYDRATION_OMNIPOOL_ADDRESS:()=>ai,HYDRATION_PARACHAIN_ID:()=>ii,PERBILL_DENOMINATOR:()=>He,PERMILL_DENOMINATOR:()=>ot,SYSTEM_ASSET_DECIMALS:()=>ge,SYSTEM_ASSET_ID:()=>A,TRADEABLE_DEFAULT:()=>lt});var ot=1e6,He=1e9,A=0,ge=12,ii=2034,ai="7L53bUTBbfuj14UpdCNPwmgzzHSsrsTWBHX5pys32mVWM3C1",_t=1,lt=15;var{logger:ut}=si,X=class extends _{constructor(t){super(t)}async getBalance(t,e){return e===0?this.getSystemBalance(t):this.getBalanceData(t,e)}async getSystemBalance(t){let e=this.api.query.System.Account,{data:n}=await e.getValue(t,{at:"best"});return this.getBreakdown(n)}async getTokenBalance(t,e){let r=await this.api.query.Tokens.Accounts.getValue(t,e,{at:"best"});return this.getBreakdown(r)}async getErc20Balance(t,e){return this.getBalanceData(t,e)}watchBalance(t){return Ft(()=>{let e=this.watchSystemBalance(t),n=this.watchTokensBalance(t),r=this.watchErc20Balance(t);return oi([e,n,r]).pipe(hi(i=>li(i.pipe(di(1)),i.pipe(gi(1),ui(250)))))}).pipe(ct(e=>e.flat()),In([]),ci(2,1),ct(([e,n],r)=>r===0?n:this.getDeltas(e,n))).pipe(Rt({subscribe:()=>ut.debug("balance: subscribe",t),error:e=>ut.error("balance",e)}),pi({delay:1e3}))}watchSystemBalance(t){let e=this.api.query.System.Account;return Ft(()=>e.watchValue(t,"best")).pipe(ct(n=>({id:0,balance:this.getBreakdown(n.data)})),Rt({error:n=>ut.error("balance(system)",n)}))}watchTokenBalance(t,e){let n=this.api.query.Tokens.Accounts;return Ft(()=>n.watchValue(t,e,"best")).pipe(ct(r=>({id:e,balance:this.getBreakdown(r)})),Rt({error:r=>ut.error("balance(token)",r)}))}watchTokensBalance(t){let e=this.api.query.Tokens.Accounts;return Ft(()=>e.watchEntries(t,{at:"best"})).pipe(xn((n,r)=>!r.deltas),ct(({deltas:n})=>{let r=[];return n?.deleted.forEach(i=>{let[a,s]=i.args;r.push({id:s,balance:this.getBreakdown({free:0n,reserved:0n,frozen:0n})})}),n?.upserted.forEach(i=>{let[a,s]=i.args;r.push({id:s,balance:this.getBreakdown(i.value)})}),r}),Rt({error:n=>ut.error("balance(tokens)",n)}))}watchErc20Balance(t,e){let n=async()=>(await this.api.query.AssetRegistry.Assets.getEntries({at:"best"})).filter(({value:a})=>a.asset_type.type==="Erc20").map(({keyArgs:a})=>{let[s]=a;return s}),r=async i=>(await Promise.all(i.map(async s=>[s,await this.getBalanceData(t,s)]))).map(([s,o])=>({id:s,balance:o}));return Ft(()=>vn(e?Promise.resolve(e):n()).pipe(On(i=>this.watcher.bestBlock$.pipe(In(null),On(()=>vn(r(i))))),mi(),ct(([i,a],s)=>s===0?a.filter(o=>o.balance.total>0n):this.getDeltas(i,a)),xn((i,a)=>a.length===0),Rt({error:i=>ut.error("balance(erc20)",i)})))}async getBalanceData(t,e){let n=await this.api.apis.CurrenciesApi.account(e,t,{at:"best"});return this.getBreakdown(n)}getBreakdown(t){let e=t.free>=t.frozen?t.free-t.frozen:0n,n=t.free+t.reserved;return{free:t.free,reserved:t.reserved,frozen:t.frozen,total:n,transferable:e}}getDeltas(t,e){let n=(i,a)=>i!==void 0&&a!==void 0&&i.transferable===a.transferable&&i.total===a.total,r=t.reduce((i,a)=>(i.set(a.id,a.balance),i),new Map);return e.filter(i=>!n(i.balance,r.get(i.id)))}};var mt=class extends _{_minOrderBudget;_blockTime;constructor(t){super(t)}async getBlockTime(){if(this._blockTime===void 0){let t=await this.api.constants.Aura.SlotDuration();this._blockTime=Number(t)}return this._blockTime}async getMinOrderBudget(){return this._minOrderBudget===void 0&&(this._minOrderBudget=await this.api.constants.DCA.MinBudgetInNativeCurrency()),this._minOrderBudget}};var Bn={};I(Bn,{AssetNotFound:()=>Ge,PoolNotFound:()=>Ct,RouteNotFound:()=>Et});var Ge=class extends Error{constructor(t){super(),this.message=`${t} not found`,this.name="AssetNotFound"}},Ct=class extends Error{constructor(t){super(),this.message=`${t} pool invalid`,this.name="PoolNotFound"}},Et=class extends Error{constructor(t,e){super(),this.message=`Route from ${t} to ${e} not found in current configuration`,this.name="RouteNotFound"}};var Cn={};I(Cn,{EvmClient:()=>Mt,EvmRpcAdapter:()=>kt,createChain:()=>Ve});import{Binary as bi,FixedSizeBinary as _n}from"polkadot-api";import{hydration as yi}from"@galacticcouncil/descriptors";import{encodeFunctionData as fi,decodeFunctionResult as Pi}from"viem";var Si=10000000n,kt=class{api;constructor(t){this.api=t.getTypedApi(yi)}async getBlock(){let t=await this.api.query.Ethereum.CurrentBlock.getValue({at:"best"}),{header:e}=t,n=e.timestamp/1000n,[r]=e.number;return{timestamp:n,number:r}}readContract=(async t=>{let{abi:e,address:n,functionName:r,args:i}=t,a=fi({abi:e,functionName:r,args:i}),s=await this.api.apis.EthereumRuntimeRPCApi.call(_n.fromText(""),_n.fromHex(n),bi.fromHex(a),[0n,0n,0n,0n],[Si,0n,0n,0n],void 0,void 0,void 0,!1,[],[]);if(!s.success)throw console.error(r,s.value.type),new Error("Contract read failure");let{exit_reason:o,value:l,used_gas:c}=s.value;if(console.log(c),o.type==="Succeed")return Pi({abi:e,functionName:r,data:l.asHex()});throw console.log(r,o.type,o.value.type),new Error("Contract read error")})};import{defineChain as wi}from"viem";var Ti=["https://hydration-rpc.n.dwellir.com","https://hydration.dotters.network","https://rpc.helikon.io/hydradx","https://hydration.ibp.network","https://rpc.cay.hydration.cloud","https://rpc.parm.hydration.cloud","https://rpc.roach.hydration.cloud","https://rpc.zipp.hydration.cloud","https://rpc.sin.hydration.cloud","https://rpc.coke.hydration.cloud"],Ve=()=>wi({id:222222,name:"Hydration",network:"hydration",nativeCurrency:{decimals:18,name:"WETH",symbol:"WETH"},rpcUrls:{default:{http:Ti}},blockExplorers:{default:{name:"Hydration Explorer",url:"https://hydration.subscan.io"}},testnet:!1});import{createPublicClient as Fn,createWalletClient as vi,custom as Rn,http as xi}from"viem";var Mt=class{client;chain;constructor(t){this.client=t,this.chain=Ve()}get chainId(){return this.chain.id}get chainCurrency(){return this.chain.nativeCurrency.symbol}get chainDecimals(){return this.chain.nativeCurrency.decimals}getProvider(){return Fn({chain:this.chain,transport:xi()})}getWsProvider(){return Fn({transport:Rn({request:({method:t,params:e})=>this.client._request(t,e||[])})})}getSigner(t){return vi({account:t,chain:this.chain,transport:Rn(window.ethereum)})}getRPCAdapter(){return new kt(this.client)}};var Gn={};I(Gn,{LiquidityMiningApi:()=>Lt,LiquidityMiningClient:()=>qt});import{AccountId as Ui}from"polkadot-api";import q from"big.js";import{HYDRATION_SS58_PREFIX as Wi,RUNTIME_DECIMALS as pt}from"@galacticcouncil/common";import{fixed_from_rational as Hn}from"@galacticcouncil/math-liquidity-mining";var he={};I(he,{withTimeout:()=>Ii});function Ii(m,t,e="timeout"){return new Promise((n,r)=>{let i=setTimeout(()=>r(new Error(e)),t);m.then(a=>{clearTimeout(i),n(a)},a=>{clearTimeout(i),r(a)})})}var R={};I(R,{divSpot:()=>Ai,getFraction:()=>Bi,mulScaled:()=>kn,mulSpot:()=>Oi});import{RUNTIME_DECIMALS as En}from"@galacticcouncil/common";function kn(m,t,e,n,r){let i=e+n-r,a=m*t;return i>0?a/BigInt(10)**BigInt(i):i<0?a*BigInt(10)**BigInt(-i):a}function Oi(m,t,e,n){return kn(m,t,e,En,n)}function Ai(m,t,e,n){if(t===0n)return 0n;let r=BigInt(10)**BigInt(En+n-e);return m*r/t}function Bi(m,t,e=2){if(t<.01||t>100)throw new Error("Supported range is from 0.01% - 100%");let n=BigInt(10)**BigInt(e),r=BigInt(Math.round(t*Number(n)));return m*r/(BigInt(100)*n)}var v={};I(v,{FeeUtils:()=>Ue,shiftNeg:()=>Fi});import _i from"big.js";var Ue=class m{static toPct(t){let[e,n]=t;return m.safeDivide(e*100,n)}static toRaw(t){let[e,n]=t;return m.safeDivide(e,n)}static fromPermill(t){return[t,1e6]}static fromPerbill(t){return[t,1e9]}static fromRate(t,e){return[t,e]}static safeDivide(t,e,n=12){let r=10**n;return Math.round(t*r/e)/r}static safeRound(t){return parseFloat(t.toPrecision(15))}};function Fi(m,t){let e=_i(typeof m=="bigint"?m.toString():m);return t===0?e.toString():e.div(Math.pow(10,t)).toString()}var Dt={};I(Dt,{findNestedKey:()=>Ri,findNestedObj:()=>Ci,jsonFormatter:()=>Ei});var Ri=(m,t)=>{let e=[];return JSON.stringify(m,(n,r)=>(r&&r[t]&&e.push(r),r)),e[0]},Ci=(m,t,e)=>{let n;return JSON.stringify(m,(r,i)=>(i&&i[t]===e&&(n=i),i)),n},Ei=(m,t)=>typeof t=="bigint"?t.toString():t;var L={};I(L,{calculateBuyFee:()=>Li,calculateDiffToAvg:()=>ki,calculateDiffToRef:()=>Mi,calculateSellFee:()=>Di});import j from"big.js";function ki(m,t){let e=j(m.toString()),n=j(t.toString());return e.minus(n).abs().div(e.plus(n).div(2)).mul(100).round(2).toNumber()}function Mi(m,t){if(t===0n)return 0;let e=j(m.toString()),n=j(t.toString());return e.minus(n).div(n).mul(100).round(2).toNumber()}function Di(m,t){if(m===0n)return 0;let e=j(m.toString()),n=j(t.toString());return j(1).minus(n.div(e)).mul(100).round(2).toNumber()}function Li(m,t){if(m===0n)return 0;let e=j(m.toString());return j(t.toString()).div(e).minus(1).mul(100).round(2).toNumber()}import{TLRUCache as Mn}from"@thi.ng/cache";var be=class{debug;constructor(t){this.debug=t||!1}log(t,e,n){this.debug&&console.log(t,e,n)}scope(t,e,n,r){let i=new Map,a=r!==void 0?new Mn(null,{ttl:r}):new Mn;return{get:(...c)=>{let u=n(...c);if(i.has(u)){this.log("[live]",t,u);let p=i.get(u);return Promise.resolve(p)}if(a.has(u))return this.log("[memo]",t,u),a.get(u);this.log("[fetch]",t,u);let d=e(...c).catch(p=>{throw a.delete(u),p});return a.set(u,d),d},set:(c,...u)=>{let d=n(...u);this.log("[set-live]",t,d),i.set(d,c)},clear:()=>{this.log("[clear]",t),i.clear(),a.release()}}}};var ye=class{result=new Map;getKey(t,e){return[e,t.toString()].join(",")}constructor(t,e){for(let n=0;n<t.length;++n){let[r,i]=t[n];this.result.set(this.getKey(i,r),e[n].free)}}freeBalance(t,e){return this.result.get(this.getKey(t,e))??0n}transfer(t,e,n,r){let i=this.getKey(t,e),a=this.getKey(t,n),s=this.result.get(i)??0n,o=this.result.get(a)??0n;if(s<r)throw new Error("Attempting to transfer more than is present");this.result.set(i,s+r),this.result.set(a,o+r)}};import rt from"big.js";import{calculate_accumulated_rps as qi,calculate_global_farm_rewards as Ni,calculate_loyalty_multiplier as Hi,calculate_user_reward as Nn,calculate_yield_farm_delta_rpvs as Gi}from"@galacticcouncil/math-liquidity-mining";import Dn from"big.js";var We=Dn(10).pow(18),Ln=BigInt(Dn(1).pow(18).toString()),qn=6e3;var Vi="1000000000000000000",fe=class{constructor(t,e,n){this.getAccount=t;this.getAsset=e;this.multiCurrency=n}async syncGlobalFarm(t,e,n){if(t.state.type!=="Active"||t.updated_at===e)return null;if(t.total_shares_z===0n)return t;let r=await this.getAsset(t.reward_currency),i=e-t.updated_at,a=this.getAccount(t.id),s=r?.existential_deposit;if(!s)throw new Error("Missing reward currency asset list");let o=this.multiCurrency.freeBalance(t.reward_currency,a),l=rt(s.toString()),c=rt(o.toString()).minus(l.lt(o.toString())?s.toString():o.toString()),u=rt(Ni(t.total_shares_z.toString(),n.toString(),rt(t.yield_per_period.toString()).mul(We).round(0,rt.roundDown).toFixed(),t.max_reward_per_period.toString(),i.toFixed()));if(c.lt(u)&&(u=c),u.eq(0))return t;let d=this.getAccount(0);return this.multiCurrency.transfer(t.reward_currency,a,d,BigInt(u.toFixed())),{...t,accumulated_rpz:BigInt(qi(t.accumulated_rpz.toString(),t.total_shares_z.toString(),u.toFixed()))}}syncYieldFarm(t,e,n){if(t.state.type!=="Active"||t.updated_at===n)return null;if(t.total_valued_shares===0n)return{...t,updated_at:n};let r=Gi(t.accumulated_rpz.toString(),e.accumulated_rpz.toString(),t.multiplier.toString(),t.total_valued_shares.toString());return{...t,accumulated_rpvs:t.accumulated_rpvs+BigInt(r),updated_at:n}}getLoyaltyMultiplier(t,e){let n=rt(1).mul(We).round(0,rt.roundDown).toString();if(!e)return n;let{initial_reward_percentage:r,scale_coef:i}=e;return Hi(t.toFixed(),r.toString(),i.toFixed())}async claimRewards(t,e,n,r,i){if(e.state.type==="Terminated")return null;let a=Math.floor(r/t.blocks_per_period);if(n.updated_at===a)return null;let s=await this.syncGlobalFarm(t,a,i);if(!s)return null;let o=this.syncYieldFarm(e,s,a);if(!o)return null;let l=o.total_stopped-n.stopped_at_creation,c=o.updated_at-n.entered_at-l,u=this.getLoyaltyMultiplier(c,o.loyalty_curve),d=BigInt(Nn(n.accumulated_rpvs.toString(),n.valued_shares.toString(),n.accumulated_claimed_rewards.toString(),o.accumulated_rpvs.toString(),u)),p=BigInt(Nn(n.accumulated_rpvs.toString(),n.valued_shares.toString(),n.accumulated_claimed_rewards.toString(),o.accumulated_rpvs.toString(),Vi));return{reward:d,maxReward:p,assetId:s.reward_currency,yieldFarmId:o.id,isActiveFarm:o.state.type==="Active"}}};var Yi=q(365.2425).times(24).times(60).times(60),Lt=class{balance;client;options;constructor(t,e,n={}){this.client=t,this.balance=e,this.options=Object.freeze({blockTime:n.blockTime??qn})}get blockTime(){return this.options.blockTime}async getOraclePrice(t,e){let n=[t,e].sort((i,a)=>i-a);if(t===e)return Ln;let r=await this.client.getOraclePrice(n);if(r){let{n:i,d:a}=r[0].price,s;return t<e?s=Hn(i.toString(),a.toString()):s=Hn(a.toString(),i.toString()),BigInt(s)}}getFarmAddress=(t,e)=>{let n=Buffer.from("modl","utf-8"),r=Buffer.from(e?"78796b4c4d704944":"4f6d6e6957684c4d","hex"),i=Buffer.from([t]),a=Buffer.concat([n,r,i]),o="0x"+Buffer.concat([a,Buffer.alloc(32-a.length)]).toString("hex");return Ui(Wi).dec(o)};getGlobalRewardPerPeriod(t,e,n,r){let i=q(r).times(t.toString()).times(e.toString()).div(Math.pow(10,pt));return i.gte(n.toString())?n.toString():i.toString()}getPoolYieldPerPeriod(t,e,n,r){let i=q(t.toString()).times(e),a=q(n.toString()).times(r);return i.div(a.toString()).toString()}farmData(t,e,n){let{yieldFarm:r,globalFarm:i,priceAdjustment:a,balance:s,id:o}=t,{multiplier:l,loyalty_curve:c}=r,{blocks_per_period:u,yield_per_period:d,total_shares_z:p,max_reward_per_period:h,pending_rewards:b,accumulated_paid_rewards:g,planned_yielding_periods:f,updated_at:y,incentivized_asset:S,reward_currency:P,price_adjustment:w,min_deposit:T}=i,F=v.shiftNeg(a??w,pt),k=v.shiftNeg(l,pt),$=v.shiftNeg(c?.initial_reward_percentage??0,pt),K=Yi.div(q(this.blockTime).div(1e3).times(u)).toString(),H;if(p<=0)H=q(k).times(d.toString()).times(K).div(Math.pow(10,pt)).toString();else{let Ar=this.getGlobalRewardPerPeriod(p,d,h,F),Br=this.getPoolYieldPerPeriod(Ar,k,p,F);H=q(Br).times(K).toString()}let V=b+g,Ot=h*BigInt(f),ae=s.transferable+V,hn=ae-V,se=q(hn.toString()).div(h.toString()),oe=q(e).div(u.toString()).toString(),le=(p>=0?se.plus(y):se.plus(oe)).toString(),ke=q(le).times(u).toString(),Ir=q(p.toString()).div(q(h.toString()).div(d.toString())).div(Math.pow(10,pt)).times(100).times(F).toFixed(2),bn=q(V.toString()).div(ae.toString()).gte(.999);H=bn?"0":q(H).div(n?2:1).times(100).toString();let Or=$?q(H).times($).toString():void 0;return{apr:H,minApr:Or,isDistributed:bn,estimatedEndPeriod:le,estimatedEndBlock:ke,maxRewards:Ot,incentivizedAsset:S,rewardCurrency:P,loyaltyCurve:c,currentPeriod:oe,potMaxRewards:ae,fullness:Ir,yieldFarmId:r.id,globalFarmId:i.id,poolId:o,distributedRewards:V,plannedYieldingPeriods:f,minDeposit:T,blocksPerPeriod:u}}async getAllOmnipoolFarms(){let e=(await this.client.getAllOmnipooFarms()).reduce((r,i)=>r.includes(i.keyArgs[0].toString())?r:[...r,i.keyArgs[0].toString()],[]),n=await Promise.all(e.map(async r=>{let i=await this.getOmnipoolFarms(r);if(i)return[r,i]}));return Object.fromEntries(n.filter(r=>!!r))}async getOmnipoolFarms(t){let e=await this.client.getOmnipooFarms(Number(t)),n=await this.client.getRelayBlockNumber(),r=await Promise.all(e.map(async({keyArgs:i,value:a})=>{let[,s]=i,o=a,l=await this.client.getOmnipoolGlobalFarm(s),c=await this.client.getOmnipoolYieldFarm(Number(t),s,o);if(!l||!c)return;let u=l.reward_currency,d=l.incentivized_asset,p=this.getFarmAddress(s),h=await this.getOraclePrice(u,d),b=await this.balance.getBalance(p,u);return{id:t,globalFarm:l,yieldFarm:c,priceAdjustment:h,balance:b}}));return n?r.map(i=>i?this.farmData(i,n):void 0):[]}async getAllIsolatedFarms(){let e=(await this.client.getAllIsolatedFarms()).reduce((r,i)=>r.includes(i.keyArgs[0].toString())?r:[...r,i.keyArgs[0].toString()],[]),n=await Promise.all(e.map(async r=>{let i=await this.getIsolatedFarms(r);if(i)return[r,i]}));return Object.fromEntries(n.filter(r=>!!r))}async getIsolatedFarms(t){let e=await this.client.getIsolatedFarms(t),n=await this.client.getRelayBlockNumber(),r=await Promise.all(e.map(async({keyArgs:i,value:a})=>{let[,s]=i,o=a,l=await this.client.getIsolatedGlobalFarm(s),c=await this.client.getIsolatedYieldFarm(t,s,o);if(!l||!c)return;let u=l.reward_currency,d=l.incentivized_asset,p=this.getFarmAddress(s,!0),h=await this.getOraclePrice(u,d),b=await this.balance.getBalance(p,u);return{id:t,globalFarm:l,yieldFarm:c,priceAdjustment:h,balance:b,farmAddress:p}}));return n?r.map(i=>i?this.farmData(i,n,!0):void 0):[]}async getDepositReward(t,e,n,r){let i=e.global_farm_id,a=e.yield_farm_id,s=n?await this.client.getIsolatedYieldFarm(t,i,a):await this.client.getOmnipoolYieldFarm(Number(t),i,a),o=n?await this.client.getIsolatedGlobalFarm(i):await this.client.getOmnipoolGlobalFarm(i);if(!o||!s)return;let l=o.reward_currency,c=o.incentivized_asset,u=[[this.getFarmAddress(0,n),o.reward_currency],[this.getFarmAddress(o.id,n),o.reward_currency]],d=await this.getAccountAssetBalances(u),p=await this.getOraclePrice(l,c),h=new ye(u,d),g=await new fe(y=>this.getFarmAddress(y),y=>this.client.getAsset(y),h).claimRewards(o,s,e,r,p??o.price_adjustment);if(!g)return;let f=await this.client.getAsset(g.assetId);if(f&&!(g.reward<=f.existential_deposit))return g}async getAccountAssetBalances(t){let[e,n]=await Promise.all([Promise.all(t.filter(([i,a])=>a!==0).map(([i,a])=>this.balance.getTokenBalance(i,a))),Promise.all(t.filter(([i,a])=>a===0).map(([i])=>this.balance.getSystemBalance(i)))]),r=[];for(let i=0,a=0;i+a<t.length;){let s=i+a,[,o]=t[s];o===0?(r.push(n[a]),a+=1):(r.push(e[i]),i+=1)}return r}};import{Binary as $i,Enum as Xi}from"polkadot-api";var qt=class extends _{omnipoolAssetIds=[];async getOraclePrice(t){return await this.api.query.EmaOracle.Oracles.getValue($i.fromText("omnipool"),t,Xi("TenMinutes"))}async getRelayBlockNumber(){return(await this.api.query.ParachainSystem.ValidationData.getValue())?.relay_parent_number}async getAllOmnipooFarms(){return this.api.query.OmnipoolWarehouseLM.ActiveYieldFarm.getEntries()}async getOmnipooFarms(t){return this.api.query.OmnipoolWarehouseLM.ActiveYieldFarm.getEntries(t)}async getOmnipoolGlobalFarm(t){return this.api.query.OmnipoolWarehouseLM.GlobalFarm.getValue(t,{at:"best"})}async getOmnipoolYieldFarm(t,e,n){return this.api.query.OmnipoolWarehouseLM.YieldFarm.getValue(t,e,n,{at:"best"})}async getAllIsolatedFarms(){return this.api.query.XYKWarehouseLM.ActiveYieldFarm.getEntries()}async getIsolatedFarms(t){return this.api.query.XYKWarehouseLM.ActiveYieldFarm.getEntries(t)}async getIsolatedGlobalFarm(t){return this.api.query.XYKWarehouseLM.GlobalFarm.getValue(t,{at:"best"})}async getIsolatedYieldFarm(t,e,n){return this.api.query.XYKWarehouseLM.YieldFarm.getValue(t,e,n,{at:"best"})}async getAsset(t){return this.api.query.AssetRegistry.Assets.getValue(t)}};var lr={};I(lr,{PoolContextProvider:()=>St,PoolError:()=>Z,PoolFactory:()=>ft,PoolType:()=>O,aave:()=>nn,hsm:()=>on,lbp:()=>ze,omni:()=>Qe,stable:()=>Ze,xyk:()=>tn});var ze={};I(ze,{LbpMath:()=>Y,LbpPool:()=>Nt,LbpPoolClient:()=>Ht});import{calculate_in_given_out as zi,calculate_out_given_in as Ki,calculate_linear_weights as ji,calculate_pool_trade_fee as Qi,get_spot_price as Ji}from"@galacticcouncil/math-lbp";var Y=class{static getSpotPrice(t,e,n,r,i){return Ji(t,e,n,r,i)}static calculateInGivenOut(t,e,n,r,i){return zi(t,e,n,r,i)}static calculateOutGivenIn(t,e,n,r,i){return Ki(t,e,n,r,i)}static calculateLinearWeights(t,e,n,r,i){return ji(t,e,n,r,i)}static calculatePoolTradeFee(t,e,n){return Qi(t,e,n)}};import{big as Vn,RUNTIME_DECIMALS as Un}from"@galacticcouncil/common";var O=(a=>(a.Aave="Aave",a.LBP="LBP",a.Omni="Omnipool",a.Stable="Stableswap",a.XYK="XYK",a.HSM="HSM",a))(O||{}),Z=(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))(Z||{});var{FeeUtils:Wn}=v,Nt=class m{type;address;tokens;maxInRatio;maxOutRatio;minTradingLimit;fee;repayFeeApply;static fromPool(t){return new m(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 n=new Map(this.tokens.map(a=>[a.id,a])),r=n.get(t),i=n.get(e);if(r==null)throw new Error("Pool does not contain tokenIn");if(i==null)throw new Error("Pool does not contain tokenOut");return{assetIn:t,assetOut:e,balanceIn:r.balance,balanceOut:i.balance,decimalsIn:r.decimals,decimalsOut:i.decimals,weightIn:r.weight,weightOut:i.weight}}validateAndBuy(t,e,n){let r=this.tokens[0].id,i=[];e<this.minTradingLimit&&i.push("InsufficientTradingAmount");let a=t.balanceOut/this.maxOutRatio;if(e>a&&i.push("MaxOutRatioExceeded"),r===t.assetOut){let s=this.calculateTradeFee(e,n),o=Wn.toPct(this.repayFeeApply?n.repayFee:n.exchangeFee),l=e+s,c=this.calculateInGivenOut(t,l),u=t.balanceIn/this.maxInRatio;return c>u&&i.push("MaxInRatioExceeded"),{amountIn:c,calculatedIn:c,amountOut:e,feePct:o,errors:i}}else{let s=this.calculateInGivenOut(t,e),o=t.balanceIn/this.maxInRatio;return s>o&&i.push("MaxInRatioExceeded"),{amountIn:s,calculatedIn:s,amountOut:e,feePct:0,errors:i}}}validateAndSell(t,e,n){let r=this.tokens[0].id,i=[];e<this.minTradingLimit&&i.push("InsufficientTradingAmount");let a=t.balanceIn/this.maxInRatio;if(e>a&&i.push("MaxInRatioExceeded"),r===t.assetIn){let s=this.calculateOutGivenIn(t,e),o=t.balanceOut/this.maxOutRatio;return s>o&&i.push("MaxOutRatioExceeded"),{amountIn:e,calculatedOut:s,amountOut:s,feePct:0,errors:i}}else{let s=this.calculateOutGivenIn(t,e),o=this.calculateTradeFee(s,n),l=Wn.toPct(this.repayFeeApply?n.repayFee:n.exchangeFee),c=s-o,u=t.balanceOut/this.maxOutRatio;return c>u&&i.push("MaxOutRatioExceeded"),{amountIn:e,calculatedOut:s,amountOut:c,feePct:l,errors:i}}}calculateInGivenOut(t,e){let n=Y.calculateInGivenOut(t.balanceIn.toString(),t.balanceOut.toString(),t.weightIn.toString(),t.weightOut.toString(),e.toString()),r=BigInt(n);return r<0n?0n:r}calculateOutGivenIn(t,e){let n=Y.calculateOutGivenIn(t.balanceIn.toString(),t.balanceOut.toString(),t.weightIn.toString(),t.weightOut.toString(),e.toString()),r=BigInt(n);return r<0n?0n:r}spotPriceInGivenOut(t){let e=Y.getSpotPrice(t.balanceOut.toString(),t.balanceIn.toString(),t.weightOut.toString(),t.weightIn.toString(),Vn.toBigInt(1,Un).toString());return BigInt(e)}spotPriceOutGivenIn(t){let e=Y.getSpotPrice(t.balanceIn.toString(),t.balanceOut.toString(),t.weightIn.toString(),t.weightOut.toString(),Vn.toBigInt(1,Un).toString());return BigInt(e)}calculateTradeFee(t,e){let n=Y.calculatePoolTradeFee(t.toString(),this.repayFeeApply?e.repayFee[0]:e.exchangeFee[0],this.repayFeeApply?e.repayFee[1]:e.exchangeFee[1]);return BigInt(n)}};import{CompatibilityLevel as ba}from"polkadot-api";import{Subscription as ya,distinctUntilChanged as fa,filter as Pa}from"rxjs";import{memoize1 as na}from"@thi.ng/memoize";import{TLRUCache as ra}from"@thi.ng/cache";import{ReplaySubject as Yn,Subscription as $n,combineLatest as ia,defer as aa,from as sa,merge as Ye,of as oa,EMPTY as Te}from"rxjs";import{bufferCount as la,bufferTime as ca,catchError as ve,filter as xe,finalize as $e,map as dt,pairwise as Xe,repeat as Xn,skip as ua,share as ma,startWith as pa,switchMap as zn,tap as gt,throttleTime as da}from"rxjs/operators";import{BehaviorSubject as Zi}from"rxjs";var Pe=class{store$=new Zi([]);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,n=new Map(e.map((s,o)=>[s.address,o])),r=await t(e),i=e.slice(),a=new Set;for(let s of r){let o=n.get(s.address);o===void 0?(n.set(s.address,i.length),i.push(s)):i[o]=s,a.add(s.address)}this.changeset=a,this.store$.next(i)}).catch(console.error)}destroy(){this.store$.complete()}};import{log as ta}from"@galacticcouncil/common";var ea={Aave:"AAVE",LBP:"LBP",Omnipool:"OMNI",Stableswap:"STBL",XYK:"XYK",HSM:"HSM"},{logger:Se}=ta,we=class{type;constructor(t){this.type=t}prefix(){return this.pad(`pool(${ea[this.type]})`,10)}trace(t,...e){Se.trace(`${this.prefix()} ${t} :`,...e)}debug(t,...e){Se.debug(`${this.prefix()} ${t} :`,...e)}info(t,...e){Se.info(`${this.prefix()} ${t} :`,...e)}error(t,...e){Se.error(`${this.prefix()} ${t} :`,...e)}pad(t,e){return t.length>=e?t:t+" ".repeat(e-t.length)}};var{withTimeout:ga}=he,ha=3e3,N=class extends _{evm;balance;store=new Pe;log;shared$;resync$=new Yn(1);resyncAt=0;resyncPending=!1;mem=0;memPoolsCache=new ra(null,{ttl:6*1e3});memPools=na(t=>(this.log.info("pool_sync",{mem:t}),this.loadPools()),this.memPoolsCache);constructor(t,e){super(t),this.evm=e,this.balance=new X(t),this.log=new we(this.getPoolType())}async getMemPools(){return this.memPools(this.mem)}async getPools(){return(await this.getMemPools()).filter(e=>this.hasValidAssets(e))}getSubscriber(){return this.shared$||(this.shared$=this.subscribeStore()),this.shared$.pipe(pa([]),la(2,1),dt(([t,e])=>t.length===0?e:this.store.applyChangeset(e)),xe(t=>t.length>0),da(1e3,void 0,{leading:!0,trailing:!0}))}subscribeStore(){return aa(()=>{let t=new $n;return t.add(this.startWatchdog()),this.resync$.next(),this.resync$.pipe(zn(()=>{let e=new $n;return sa(ga(this.getMemPools(),6e4,"getMemPools stalled")).pipe(gt(()=>this.log.info("pool_synced",{mem:this.mem})),dt(r=>r.filter(i=>this.hasValidAssets(i))),gt(r=>this.store.set(r)),ve(()=>(this.log.error("pool_seed_error",{mem:this.mem}),this.requestResync(),Te))).pipe(gt(()=>{e.add(this.subscribeBalances()),e.add(this.subscribeUpdates())}),zn(r=>Ye(oa(r),this.store.asObservable().pipe(ua(1)))),$e(()=>{e.unsubscribe()}))}),$e(()=>t.unsubscribe()))}).pipe(ma({connector:()=>new Yn(1),resetOnRefCountZero:!0}))}subscribeBalances(){let t=this.store.pools.map(e=>{let{address:n}=e,r=[this.balance.watchTokensBalance(n)];if(this.hasSystemAsset(e)){let i=this.balance.watchSystemBalance(n);r.push(i)}if(this.hasErc20Asset(e)){let i=e.tokens.filter(s=>s.type==="Erc20").map(s=>s.id),a=this.balance.watchErc20Balance(n,i);r.push(a)}return ia(r).pipe(dt(i=>i.flat()),Xe(),dt(([i,a])=>this.balance.getDeltas(i,a)),xe(i=>i.length>0),dt(i=>[n,i]))});return Ye(...t).pipe(ca(250),xe(e=>e.length>0),dt(e=>new Map(e)),this.watchGuard("balances")).subscribe(e=>{this.store.update(n=>this.updateBalances(n,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:n})=>n>0n&&!!e)}updateBalances=(t,e)=>{let n=[],r=new Map(t.map(i=>[i.address,i]));for(let[i,a]of e){let s=r.get(i);if(s){let o=s.tokens.map(l=>{let c=a.find(u=>u.id===l.id);return c&&l.id!==s.id?{...l,balance:c.balance.transferable}:l});n.push({...s,tokens:o})}}return n};resync(t=!1){let e=Date.now();!t&&e-this.resyncAt<ha||(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 n=this.watcher.connection$.pipe(Xe(),xe(([i,a])=>i==="offline"&&a==="online"),gt(()=>{this.log.debug("watchdog_recover_online",{mem:this.mem}),this.requestResync()}),ve(i=>(this.log.error("watchdog_recovery_error",i),Te)),Xn({delay:1e3})),r=this.watcher.finalizedBlock$.pipe(Xe(),gt(([i,a])=>{let s=Number(i.number),o=Number(a.number),l=o-s;l>=3&&(this.log.debug("watchdog_gap",{from:s,to:o,gap:l}),this.requestResync())}),ve(i=>(this.log.error("watchdog_gap_error",i),Te)),Xn({delay:1e3}));return Ye(n,r).subscribe()}watchGuard(t){return e=>e.pipe(gt({error:n=>{this.log.error(t,n),this.requestResync(!0)}}),$e(()=>{this.log.debug(t,"unsub")}),ve(()=>Te))}};var Ht=class extends N{MAX_FINAL_WEIGHT=100000000n;poolsData=new Map([]);getPoolType(){return"LBP"}async getPoolLimits(){let[t,e,n]=await Promise.all([this.api.constants.LBP.MaxInRatio(),this.api.constants.LBP.MaxOutRatio(),this.api.constants.LBP.MinTradingLimit()]);return{maxInRatio:t,maxOutRatio:e,minTradingLimit:n}}getPoolWeights(t,e){let{start:n,end:r,initial_weight:i,final_weight:a}=t,s=Y.calculateLinearWeights(n?n.toString():"0",r?r.toString():"0",i.toString(),a.toString(),e.toString()),o=BigInt(s),l=this.MAX_FINAL_WEIGHT-BigInt(o);return[o,l]}async isSupported(){let t=this.api.query.LBP.PoolData,e=await this.api.compatibilityToken;return t.isCompatible(ba.BackwardsCompatible,e)}async loadPools(){let[t,e,n]=await Promise.all([this.api.query.LBP.PoolData.getEntries({at:"best"}),this.api.query.ParachainSystem.ValidationData.getValue({at:"best"}),this.getPoolLimits()]),r=e?.relay_parent_number||0,i=t.filter(({value:a})=>e&&this.isActivePool(a,r)).map(async({keyArgs:a,value:s})=>{let[o]=a,l=o.toString(),c=await this.getPoolDelta(l,s,r);return{address:l,type:"LBP",fee:s.fee,...c,...n}});return Promise.all(i)}async getPoolDelta(t,e,n){let{assets:r,repay_target:i,fee_collector:a}=e,[s,o]=this.getPoolWeights(e,n),[l,c]=r,[u,d,p,h,b]=await Promise.all([this.isRepayFeeApplied(l,i,a.toString()),this.balance.getBalance(t,l),this.api.query.AssetRegistry.Assets.getValue(l),this.balance.getBalance(t,c),this.api.query.AssetRegistry.Assets.getValue(c)]);return{repayFeeApply:u,tokens:[{id:l,decimals:p?.decimals,existentialDeposit:p?.existential_deposit,balance:d.transferable,weight:s,type:p?.asset_type.type},{id:c,decimals:b?.decimals,existentialDeposit:b?.existential_deposit,balance:h.transferable,weight:o,type:b?.asset_type.type}]}}isActivePool(t,e){let{start:n,end:r}=t;return n&&r?e>=n&&e<r:!1}async isRepayFeeApplied(t,e,n){if(e===0n)return!1;try{return(await this.balance.getBalance(n,t)).transferable<e}catch{return!0}}async getRepayFee(){return await this.api.constants.LBP.repay_fee()}async getPoolFees(t,e){let n=this.store.pools.find(i=>i.address===e);return{repayFee:await this.getRepayFee(),exchangeFee:n.fee}}subscribeValidationData(){return this.api.query.ParachainSystem.ValidationData.watchValue("best").pipe(Pa(t=>t!==void 0),fa((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 n=[];for(let r of e){let i=this.poolsData.get(r.address);if(i){let{assets:a,repay_target:s,fee_collector:o}=i,[l]=a,[c,u]=this.getPoolWeights(i,t),[d,p]=r.tokens,h=[{...d,weight:c},{...p,weight:u}],b=await this.isRepayFeeApplied(l,s,o.toString());n.push({...r,tokens:h,repayFeeApply:b})}}return n})})}subscribeUpdates(){let t=new ya;return t.add(this.subscribeValidationData()),t}};var Qe={};I(Qe,{OmniMath:()=>x,OmniPool:()=>Gt,OmniPoolClient:()=>Ut});import{calculate_in_given_out as Sa,calculate_lrna_in_given_out as wa,calculate_out_given_in as Ta,calculate_out_given_lrna_in as va,calculate_spot_price as xa,calculate_lrna_spot_price as Ia,calculate_shares as Oa,calculate_liquidity_out as Aa,calculate_liquidity_lrna_out as Ba,verify_asset_cap as _a,calculate_liquidity_hub_in as Fa,is_sell_allowed as Ra,is_buy_allowed as Ca,is_add_liquidity_allowed as Ea,is_remove_liquidity_allowed as ka,recalculate_asset_fee as Ma,recalculate_protocol_fee as Da}from"@galacticcouncil/math-omnipool";import ht from"big.js";var x=class{static calculateSpotPrice(t,e,n,r){return xa(t,e,n,r)}static calculateLrnaSpotPrice(t,e){return Ia(t,e)}static calculateInGivenOut(t,e,n,r,i,a,s,o,l,c){return Sa(t,e,n,r,i,a,s,o,l,c)}static calculateLrnaInGivenOut(t,e,n,r,i,a){return wa(t,e,n,r,i,a)}static calculateOutGivenIn(t,e,n,r,i,a,s,o,l,c){return Ta(t,e,n,r,i,a,s,o,l,c)}static calculateOutGivenLrnaIn(t,e,n,r,i,a){return va(t,e,n,r,i,a)}static calculateShares(t,e,n,r){return Oa(t,e,n,r)}static calculateLiquidityOut(t,e,n,r,i,a,s,o){return Aa(t,e,n,r,i,a,s,o)}static calculateLiquidityLRNAOut(t,e,n,r,i,a,s,o){return Ba(t,e,n,r,i,a,s,o)}static calculateCapDifference(t,e,n,r){let i=ht(e),a=ht(t),s=ht(r),o=ht(n),l=ht(10).pow(18),c=o.div(l);if(i.div(s).lt(c)){let d=c.times(s).minus(i).times(a),p=i.times(ht(1).minus(c));return d.div(p).toFixed(0)}else return"0"}static calculateLimitHubIn(t,e,n,r){return Fa(t,e,n,r)}static isSellAllowed(t){return Ra(t)}static isBuyAllowed(t){return Ca(t)}static isAddLiquidityAllowed(t){return Ea(t)}static isRemoveLiquidityAllowed(t){return ka(t)}static recalculateAssetFee(t,e,n,r,i,a,s,o,l,c,u){return Ma(t,e,n,r,i,a,s,o,l,c,u)}static recalculateProtocolFee(t,e,n,r,i,a,s,o,l,c,u){return Da(t,e,n,r,i,a,s,o,l,c,u)}static verifyAssetCap(t,e,n,r){return _a(t,e,n,r)}};import{big as La}from"@galacticcouncil/common";var{FeeUtils:z}=v,Gt=class m{type;address;tokens;maxInRatio;maxOutRatio;minTradingLimit;hubAssetId;static fromPool(t){return new m(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 n=new Map(this.tokens.map(a=>[a.id,a])),r=n.get(t),i=n.get(e);if(r==null)throw new Error("Pool does not contain tokenIn");if(i==null)throw new Error("Pool does not contain tokenOut");return{assetIn:t,assetOut:e,hubReservesIn:r.hubReserves,hubReservesOut:i.hubReserves,sharesIn:r.shares,sharesOut:i.shares,decimalsIn:r.decimals,decimalsOut:i.decimals,balanceIn:r.balance,balanceOut:i.balance,tradeableIn:r.tradeable,tradeableOut:i.tradeable,assetInEd:r.existentialDeposit,assetOutEd:i.existentialDeposit}}validateAndBuy(t,e,n){let r=this.calculateInGivenOut(t,e),i=this.calculateInGivenOut(t,e,n),a=r===0n?0:L.calculateBuyFee(r,i),s=[],o=x.isSellAllowed(t.tradeableIn),l=x.isBuyAllowed(t.tradeableOut);(!o||!l)&&s.push("TradeNotAllowed"),(e<this.minTradingLimit||r<t.assetInEd)&&s.push("InsufficientTradingAmount");let c=t.balanceOut/this.maxOutRatio;e>c&&s.push("MaxOutRatioExceeded");let u=t.balanceIn/this.maxInRatio;return i>u&&s.push("MaxInRatioExceeded"),{amountIn:i,calculatedIn:r,amountOut:e,feePct:a,errors:s}}validateAndSell(t,e,n){let r=this.calculateOutGivenIn(t,e),i=this.calculateOutGivenIn(t,e,n),a=L.calculateSellFee(r,i),s=[],o=x.isSellAllowed(t.tradeableIn),l=x.isBuyAllowed(t.tradeableOut);(!o||!l)&&s.push("TradeNotAllowed"),(e<this.minTradingLimit||r<t.assetOutEd)&&s.push("InsufficientTradingAmount");let c=t.balanceIn/this.maxInRatio;e>c&&s.push("MaxInRatioExceeded");let u=t.balanceOut/this.maxOutRatio;return i>u&&s.push("MaxOutRatioExceeded"),{amountIn:e,calculatedOut:r,amountOut:i,feePct:a,errors:s}}calculateInGivenOut(t,e,n){if(t.assetIn==this.hubAssetId)return this.calculateLrnaInGivenOut(t,e,n);let r=x.calculateInGivenOut(t.balanceIn.toString(),t.hubReservesIn.toString(),t.sharesIn.toString(),t.balanceOut.toString(),t.hubReservesOut.toString(),t.sharesOut.toString(),e.toString(),n?z.toRaw(n.assetFee).toString():"0",n?z.toRaw(n.protocolFee).toString():"0",n?z.toRaw(n.maxSlipFee).toString():"0"),i=BigInt(r);return i<0n?0n:i}calculateLrnaInGivenOut(t,e,n){let r=x.calculateLrnaInGivenOut(t.balanceOut.toString(),t.hubReservesOut.toString(),t.sharesOut.toString(),e.toString(),n?z.toRaw(n.assetFee).toString():"0",n?z.toRaw(n.maxSlipFee).toString():"0"),i=BigInt(r);return i<0n?0n:i}calculateOutGivenIn(t,e,n){if(t.assetIn==this.hubAssetId)return this.calculateOutGivenLrnaIn(t,e,n);let r=x.calculateOutGivenIn(t.balanceIn.toString(),t.hubReservesIn.toString(),t.sharesIn.toString(),t.balanceOut.toString(),t.hubReservesOut.toString(),t.sharesOut.toString(),e.toString(),n?z.toRaw(n.assetFee).toString():"0",n?z.toRaw(n.protocolFee).toString():"0",n?z.toRaw(n.maxSlipFee).toString():"0"),i=BigInt(r);return i<0n?0n:i}calculateOutGivenLrnaIn(t,e,n){let r=x.calculateOutGivenLrnaIn(t.balanceOut.toString(),t.hubReservesOut.toString(),t.sharesOut.toString(),e.toString(),n?z.toRaw(n.assetFee).toString():"0",n?z.toRaw(n.maxSlipFee).toString():"0"),i=BigInt(r);return i<0n?0n:i}spotPriceInGivenOut(t){if(t.assetIn==this.hubAssetId)return this.spotPriceLrnaInGivenOut(t);let e=x.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=x.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=x.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=x.calculateLrnaSpotPrice(t.balanceOut.toString(),t.hubReservesOut.toString());return this.normalizeSpot(BigInt(e),t.decimalsIn,t.decimalsOut)}normalizeSpot(t,e,n){let r=e-n;if(r===0)return t;let i=La.pow10(Math.abs(r));return r>0?t*i:t/i}};import{AccountId as qa,Binary as Na,CompatibilityLevel as Kn,Enum as Ha}from"polkadot-api";import{toHex as Ga}from"@polkadot-api/utils";import{Subscription as Va,distinctUntilChanged as Ke,filter as Ua,finalize as je,map as Vt,merge as Wa,tap as Ie}from"rxjs";import{HYDRATION_SS58_PREFIX as Ya}from"@galacticcouncil/common";var{FeeUtils:B}=v,jn=Na.fromText("omnipool"),Qn=Ha("Short"),Ut=class extends N{queryBus=new be;block=0;dynamicFeesConfig=this.queryBus.scope("DynamicFees.AssetFeeConfiguration",t=>this.api.query.DynamicFees.AssetFeeConfiguration.getValue(t,{at:"best"}),t=>String(t));dynamicFees=this.queryBus.scope("DynamicFees.AssetFee",t=>this.api.query.DynamicFees.AssetFee.getValue(t,{at:"best"}),t=>String(t),6*1e3);maxSlipFee=this.queryBus.scope("Omnipool.SlipFee",()=>this.apiNext.query.Omnipool.SlipFee.getValue({at:"best"}),()=>"slipFee");emaOracles=this.queryBus.scope("EmaOracle.Oracles.Short",t=>this.api.query.EmaOracle.Oracles.getValue(jn,t,Qn,{at:"best"}),t=>t.join(":"),6*1e3);getPoolType(){return"Omnipool"}getPoolAddress(){let t="modlomnipool".padEnd(32,"\0"),e=new TextEncoder().encode(t),n=Ga(e);return qa(Ya).dec(n)}getOraclePair(t){return t===0?[0,1]:[1,t]}async getPoolLimits(){let[t,e,n]=await Promise.all([this.api.constants.Omnipool.MaxInRatio(),this.api.constants.Omnipool.MaxOutRatio(),this.api.constants.Omnipool.MinimumTradingLimit()]);return{maxInRatio:t,maxOutRatio:e,minTradingLimit:n}}async isSupported(){let t=this.api.query.Omnipool.Assets,e=await this.api.compatibilityToken;return t.isCompatible(Kn.BackwardsCompatible,e)}async isSlipFeeSupported(){return this.apiNext.query.Omnipool.SlipFee.isCompatible(Kn.Partial)}async loadPools(){let t=await this.api.constants.Omnipool.HubAssetId(),e=this.getPoolAddress(),[n,r,i,a,s]=await Promise.all([this.api.query.Omnipool.Assets.getEntries({at:"best"}),this.api.query.Omnipool.HubAssetTradability.getValue(),this.api.query.AssetRegistry.Assets.getValue(t),this.balance.getBalance(e,t),this.getPoolLimits()]),o=n.map(async({keyArgs:c,value:u})=>{let[d]=c,{hub_reserve:p,shares:h,tradable:b,cap:g,protocol_shares:f}=u,[y,S]=await Promise.all([this.api.query.AssetRegistry.Assets.getValue(d),this.balance.getBalance(e,d)]);return{id:d,decimals:y?.decimals,existentialDeposit:y?.existential_deposit,balance:S.transferable,cap:g,hubReserves:p,protocolShares:f,shares:h,tradeable:b,type:y?.asset_type.type}}),l=await Promise.all(o);return l.push({id:t,decimals:i?.decimals,existentialDeposit:i?.existential_deposit,balance:a.transferable,tradeable:r,type:i?.asset_type.type}),[{address:e,type:"Omnipool",hubAssetId:t,tokens:l,...s}]}async getPoolFees(t){let e=t.assetOut,n=t.assetIn,r=0;await this.isSlipFeeSupported()&&(r=await this.maxSlipFee.get()??0);let a=await this.dynamicFeesConfig.get(e);if(a?.type==="Fixed"){let{asset_fee:P,protocol_fee:w}=a.value;return{assetFee:B.fromPermill(P),protocolFee:B.fromPermill(w),maxSlipFee:B.fromPermill(r)}}let s=this.getOraclePair(e),o=this.getOraclePair(n),[l,c,u]=await Promise.all([this.dynamicFees.get(e),this.emaOracles.get(s),this.emaOracles.get(o)]),[d,p,h]=await this.getAssetFee(t,this.block,l,c,a?.value.asset_fee_params),[b,g,f]=n===1?[0,0,0]:await this.getProtocolFee(t,this.block,l,u,a?.value.protocol_fee_params),y=d+b,S=h+f;return{assetFee:B.fromPermill(p),protocolFee:B.fromPermill(g),maxSlipFee:B.fromPermill(r),min:B.fromPermill(y),max:B.fromPermill(S)}}async getAssetFee(t,e,n,r,i){let{assetOut:a,balanceOut:s}=t,{min_fee:o,max_fee:l,decay:c,amplification:u}=i||await this.api.constants.DynamicFees.AssetFeeParameters();if(!n||!r)return[o,o,l];let d=B.fromPermill(o),p=B.fromPermill(l),[h]=r,{asset_fee:b,timestamp:g}=n,f=Math.max(1,e-g),y=h.volume.b_in.toString(),S=h.volume.b_out.toString(),P=h.liquidity.b.toString();a===0&&(y=h.volume.a_in.toString(),S=h.volume.a_out.toString(),P=h.liquidity.a.toString());let w=B.fromPermill(b),T=x.recalculateAssetFee(y,S,P,"9",s.toString(),B.toRaw(w).toString(),f.toString(),B.toRaw(d).toString(),B.toRaw(p).toString(),c.toString(),u.toString());return[o,Number(T)*1e6,l]}async getProtocolFee(t,e,n,r,i){let{assetIn:a,balanceIn:s}=t,{min_fee:o,max_fee:l,decay:c,amplification:u}=i||await this.api.constants.DynamicFees.ProtocolFeeParameters();if(!n||!r)return[o,o,l];let d=B.fromPermill(o),p=B.fromPermill(l),[h]=r,{protocol_fee:b,timestamp:g}=n,f=Math.max(1,e-g),y=h.volume.b_in.toString(),S=h.volume.b_out.toString(),P=h.liquidity.b.toString();a===0&&(y=h.volume.a_in.toString(),S=h.volume.a_out.toString(),P=h.liquidity.a.toString());let w=B.fromPermill(b),T=x.recalculateProtocolFee(y,S,P,"9",s.toString(),B.toRaw(w).toString(),f.toString(),B.toRaw(d).toString(),B.toRaw(p).toString(),c.toString(),u.toString());return[o,Number(T)*1e6,l]}subscribeEmaOracles(){let[t]=this.store.pools,n=t.tokens.map(r=>r.id).map(r=>this.getOraclePair(r)).map(r=>this.api.query.EmaOracle.Oracles.watchValue(jn,r,Qn,"best").pipe(Ua(i=>i!==void 0),Vt((i,a)=>({value:i,index:a})),Ie(({index:i})=>{i>0&&this.log.trace("emaOracle.Oracles",r.join(":"))}),Vt(({value:i})=>({pair:r,value:i}))));return Wa(...n).pipe(je(()=>this.emaOracles.clear()),this.watchGuard("emaOracle.Oracles")).subscribe(r=>{let{pair:i,value:a}=r;this.emaOracles.set(a,i)})}subscribeDynamicFees(){return this.api.query.DynamicFees.AssetFee.watchEntries({at:"best"}).pipe(Ke((t,e)=>!e.deltas),Vt((t,e)=>({value:t,index:e})),Ie(({value:t,index:e})=>{e>0&&this.log.trace("dynamicFees.AssetFee",t.deltas?.upserted)}),je(()=>this.dynamicFees.clear()),this.watchGuard("dynamicFees.AssetFee")).subscribe(({value:{deltas:t}})=>{t?.upserted.forEach(e=>{let[n]=e.args;this.dynamicFees.set(e.value,n)})})}subscribeDynamicFeesConfig(){return this.api.query.DynamicFees.AssetFeeConfiguration.watchEntries({at:"best"}).pipe(Ke((t,e)=>!e.deltas),Vt((t,e)=>({value:t,index:e})),Ie(({value:t,index:e})=>{e>0&&this.log.trace("dynamicFees.AssetFeeConfiguration",t.deltas?.upserted)}),je(()=>this.dynamicFeesConfig.clear()),this.watchGuard("dynamicFees.AssetFeeConfiguration")).subscribe(({value:{deltas:t}})=>{t?.upserted.forEach(e=>{let[n]=e.args;this.dynamicFeesConfig.set(e.value,n)})})}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(Ke((t,e)=>!e.deltas),Vt((t,e)=>({value:t,index:e})),Ie(({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 n=t?.upserted.reduce((i,a)=>{let[s]=a.args;return i.set(s,a.value),i},new Map),r=e.tokens.map(i=>{let a=n?.get(i.id);return a?this.updateTokenState(i,a):i});return[{...e,tokens:r}]})})}subscribeUpdates(){let t=new Va;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:n,shares:r,tradable:i,cap:a,protocol_shares:s}=e;return{...t,cap:a,hubReserves:n,protocolShares:s,shares:r,tradeable:i}}};var Ze={};I(Ze,{StableMath:()=>M,StableSwap:()=>it,StableSwapClient:()=>Wt});import{calculate_in_given_out as $a,calculate_out_given_in as Xa,calculate_amplification as za,calculate_add_one_asset as Ka,calculate_liquidity_out_one_asset as ja,calculate_shares as Qa,calculate_shares_for_amount as Ja,calculate_spot_price_with_fee as Za,pool_account_name as ts,recalculate_peg as es}from"@galacticcouncil/math-stableswap";var M=class{static getPoolAddress(t){return ts(t)}static defaultPegs(t){let e=[];for(let n=0;n<t;n++)e.push(["1","1"]);return e}static calculateAmplification(t,e,n,r,i){return za(t,e,n,r,i)}static calculateInGivenOut(t,e,n,r,i,a,s){return $a(t,e,n,r,i,a,s)}static calculateAddOneAsset(t,e,n,r,i,a,s){return Ka(t,e,n,r,i,a,s)}static calculateSharesForAmount(t,e,n,r,i,a,s){return Ja(t,e,n,r,i,a,s)}static calculateOutGivenIn(t,e,n,r,i,a,s){return Xa(t,e,n,r,i,a,s)}static calculateLiquidityOutOneAsset(t,e,n,r,i,a,s){return ja(t,e,n,r,i,a,s)}static calculateShares(t,e,n,r,i,a){return Qa(t,e,n,r,i,a)}static calculateSpotPriceWithFee(t,e,n,r,i,a,s,o){return Za(t,e,n,r,i,a,s,o)}static recalculatePegs(t,e,n,r,i,a){let s=es(t,e,n,r,i,a);return JSON.parse(s)}};import{RUNTIME_DECIMALS as ns,big as Jn}from"@galacticcouncil/common";var{FeeUtils:bt}=v,it=class m{type;address;tokens;maxInRatio;maxOutRatio;minTradingLimit;amplification;isRampPeriod;id;fee;totalIssuance;pegs;static fromPool(t){return new m(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 n=new Map(this.tokens.map(a=>[a.id,a])),r=n.get(t),i=n.get(e);if(r==null)throw new Error("Pool does not contain tokenIn");if(i==null)throw new Error("Pool does not contain tokenOut");return{assetIn:t,assetOut:e,balanceIn:r.balance,balanceOut:i.balance,decimalsIn:r.decimals,decimalsOut:i.decimals,tradeableIn:this.id===t?15:r.tradeable,tradeableOut:this.id===e?15:i.tradeable,assetInEd:r.existentialDeposit,assetOutEd:i.existentialDeposit}}validateAndBuy(t,e,n){let r=this.calculateInGivenOut(t,e),i=this.calculateInGivenOut(t,e,n),a=r===0n?0:L.calculateBuyFee(r,i),s=[],o=x.isSellAllowed(t.tradeableIn),l=x.isBuyAllowed(t.tradeableOut);return(!o||!l)&&s.push("TradeNotAllowed"),(e<this.minTradingLimit||r<t.assetInEd)&&s.push("InsufficientTradingAmount"),{amountIn:i,calculatedIn:r,amountOut:e,feePct:a,errors:s}}validateAndSell(t,e,n){let r=this.calculateOutGivenIn(t,e),i=this.calculateOutGivenIn(t,e,n),a=L.calculateSellFee(r,i),s=[],o=x.isSellAllowed(t.tradeableIn),l=x.isBuyAllowed(t.tradeableOut);return(!o||!l)&&s.push("TradeNotAllowed"),(e<this.minTradingLimit||r<t.assetOutEd)&&s.push("InsufficientTradingAmount"),{amountIn:e,calculatedOut:r,amountOut:i,feePct:a,errors:s}}calculateIn(t,e,n){let r=M.calculateInGivenOut(this.getReserves(),Number(t.assetIn),Number(t.assetOut),e.toString(),this.amplification.toString(),n?bt.toRaw(n.fee).toString():"0",this.getPegs()),i=BigInt(r);return i<0n?0n:i}calculateAddOneAsset(t,e,n){let r=M.calculateAddOneAsset(this.getReserves(),e.toString(),Number(t.assetIn),this.amplification.toString(),this.totalIssuance.toString(),n?bt.toRaw(n.fee).toString():"0",this.getPegs()),i=BigInt(r);return i<0n?0n:i}calculateSharesForAmount(t,e,n){let r=M.calculateSharesForAmount(this.getReserves(),Number(t.assetOut),e.toString(),this.amplification.toString(),this.totalIssuance.toString(),n?bt.toRaw(n.fee).toString():"0",this.getPegs()),i=BigInt(r);return i<0n?0n:i}calculateInGivenOut(t,e,n){return t.assetOut==this.id?this.calculateAddOneAsset(t,e,n):t.assetIn==this.id?this.calculateSharesForAmount(t,e,n):this.calculateIn(t,e,n)}spotPriceInGivenOut(t){let e=M.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,n){let r=M.calculateOutGivenIn(this.getReserves(),Number(t.assetIn),Number(t.assetOut),e.toString(),this.amplification.toString(),n?bt.toRaw(n.fee).toString():"0",this.getPegs()),i=BigInt(r);return i<0n?0n:i}calculateWithdrawOneAsset(t,e,n){let r=M.calculateLiquidityOutOneAsset(this.getReserves(),e.toString(),Number(t.assetOut),this.amplification.toString(),this.totalIssuance.toString(),n?bt.toRaw(n.fee).toString():"0",this.getPegs()),i=BigInt(r);return i<0n?0n:i}calculateShares(t,e,n){let r=M.calculateShares(this.getReserves(),this.getAssets(t.assetIn,e),this.amplification.toString(),this.totalIssuance.toString(),n?bt.toRaw(n.fee).toString():"0",this.getPegs()),i=BigInt(r);return i<0n?0n:i}calculateOutGivenIn(t,e,n){return t.assetIn==this.id?this.calculateWithdrawOneAsset(t,e,n):t.assetOut==this.id?this.calculateShares(t,e,n):this.calculateOut(t,e,n)}spotPriceOutGivenIn(t){let e=M.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:n,decimals:r})=>({asset_id:e,amount:n,decimals:r}));return JSON.stringify(t,Dt.jsonFormatter)}getAssets(t,e){let n={asset_id:Number(t),amount:e.toString()};return JSON.stringify([n],Dt.jsonFormatter)}normalizeSpot(t,e,n,r,i){return e?t*Jn.pow10(ns-i):n?t/Jn.pow10(i-r):t}};import{AccountId as rs,CompatibilityLevel as is}from"polkadot-api";import{toHex as as}from"@polkadot-api/utils";import{blake2b as ss}from"@noble/hashes/blake2b";import{Subscription as os,distinctUntilChanged as ls,map as Je,merge as cs,tap as Zn}from"rxjs";import{HYDRATION_SS58_PREFIX as us,RUNTIME_DECIMALS as ms}from"@galacticcouncil/common";var{FeeUtils:ps}=v,Wt=class extends N{poolsData=new Map([]);getPoolType(){return"Stableswap"}getPoolAddress(t){let e=M.getPoolAddress(t),n=ss(e,{dkLen:32}),r=as(n);return rs(us).dec(r)}async getPoolLimits(){return{maxInRatio:0n,maxOutRatio:0n,minTradingLimit:await this.api.constants.Stableswap.MinTradingLimit()}}getPoolAmplification(t,e){let{initial_amplification:n,final_amplification:r,initial_block:i,final_block:a}=t,s=M.calculateAmplification(n.toString(),r.toString(),i.toString(),a.toString(),e.toString()),o=Number(s)<r;return{amplification:BigInt(s),isRampPeriod:o}}async getPoolTokens(t,e){let n=this.getPoolAddress(t),r=e.assets.map(async i=>{let[a,s,o]=await Promise.all([this.api.query.Stableswap.AssetTradability.getValue(t,i),this.api.query.AssetRegistry.Assets.getValue(i),this.balance.getBalance(n,i)]);return{id:i,decimals:s?.decimals,existentialDeposit:s?.existential_deposit,balance:o.transferable,tradeable:a,type:s?.asset_type.type}});return Promise.all(r)}async isSupported(){let t=this.api.query.Stableswap.Pools,e=await this.api.compatibilityToken;return t.isCompatible(is.BackwardsCompatible,e)}async loadPools(){let[t,e,n]=await Promise.all([this.api.query.Stableswap.Pools.getEntries({at:"best"}),this.api.query.System.Number.getValue({at:"best"}),this.getPoolLimits()]),r=t.map(async({keyArgs:i,value:a})=>{let[s]=i,o=this.getPoolAddress(s),[l,c,u]=await Promise.all([this.getPoolTokens(s,a),this.api.query.Stableswap.PoolPegs.getValue(s,{at:"best"}),this.api.query.Tokens.TotalIssuance.getValue(s,{at:"best"})]),d=this.getPoolAmplification(a,e),p=c?this.getRecentPegs(c):this.getDefaultPegs(a);return l.push({id:s,tradeable:15,balance:u,decimals:ms}),this.poolsData.set(s,a),{address:o,id:s,type:"Stableswap",fee:ps.fromPermill(a.fee),tokens:l,totalIssuance:u,pegs:p,...n,...d}});return Promise.all(r)}async getPoolFees(t,e){return{fee:this.store.pools.find(r=>r.address===e).fee}}getDefaultPegs(t){return M.defaultPegs(t.assets.length)}getRecentPegs(t){let{current:e}=t;return Array.from(e.entries()).map(([n,r])=>r.map(i=>i.toString()))}subscribeIssuance(){let e=this.store.pools.map(n=>n.id).map(n=>this.api.query.Tokens.TotalIssuance.watchValue(n,"best").pipe(Je((r,i)=>({value:r,index:i})),Zn(({index:r,value:i})=>{r>0&&this.log.trace("tokens.TotalIssuance",n,i)}),Je(({value:r})=>({id:n,value:r}))));return cs(...e).pipe(this.watchGuard("tokens.TotalIssuance")).subscribe(n=>{let{id:r,value:i}=n;this.store.update(a=>{let s=[];return a.filter(o=>o.id===r).forEach(o=>{let l=o.tokens.map(c=>c.id===r?{...c,balance:i}:c);s.push({...o,tokens:l,totalIssuance:i})}),s})})}subscribePoolPegs(){return this.api.query.Stableswap.PoolPegs.watchEntries({at:"best"}).pipe(ls((t,e)=>!e.deltas),Je((t,e)=>({value:t,index:e})),Zn(({value:t,index:e})=>{e>0&&this.log.trace("stableswap.PoolPegs",t.deltas?.upserted)}),this.watchGuard("stableswap.PoolPegs")).subscribe({error:t=>this.log.error("stableswap.PoolPegs",t),next:({value:{deltas:t}})=>{this.store.update(e=>{let n=[],r=new Map(e.map(i=>[i.id,i]));return t?.upserted.forEach(({args:i,value:a})=>{let[s]=i,o=r.get(s);if(o){let l=this.getRecentPegs(a);n.push({...o,pegs:l})}}),n})}})}subscribeBlock(){return this.watcher.bestBlock$.pipe(this.watchGuard("watcher.bestBlock")).subscribe(t=>{this.store.update(e=>{let n=[];return e.filter(r=>r.isRampPeriod).forEach(r=>{let i=this.poolsData.get(r.id);if(i){let a=this.getPoolAmplification(i,t);n.push({...r,...a})}}),n})})}subscribeUpdates(){let t=new os;return t.add(this.subscribePoolPegs()),t.add(this.subscribeIssuance()),this.hasOnRamps()&&t.add(this.subscribeBlock()),t}hasOnRamps(){return this.store.pools.filter(t=>t.isRampPeriod).length>0}};var tn={};I(tn,{XykMath:()=>Q,XykPool:()=>Yt,XykPoolClient:()=>$t});import{calculate_in_given_out as ds,calculate_out_given_in as gs,calculate_pool_trade_fee as hs,get_spot_price as bs,calculate_liquidity_in as ys,calculate_shares as fs,calculate_spot_price as Ps,calculate_spot_price_with_fee as Ss,calculate_liquidity_out_asset_a as ws,calculate_liquidity_out_asset_b as Ts}from"@galacticcouncil/math-xyk";var Q=class{static getSpotPrice(t,e,n){return bs(t,e,n)}static calculateInGivenOut(t,e,n){return ds(t,e,n)}static calculateOutGivenIn(t,e,n){return gs(t,e,n)}static calculatePoolTradeFee(t,e,n){return hs(t,e,n)}static calculateLiquidityIn(t,e,n){return ys(t,e,n)}static calculateSpotPrice(t,e){return Ps(t,e)}static calculateSpotPriceWithFee(t,e,n,r){return Ss(t,e,n,r)}static calculateShares(t,e,n){return fs(t,e,n)}static calculateLiquidityOutAssetA(t,e,n,r){return ws(t,e,n,r)}static calculateLiquidityOutAssetB(t,e,n,r){return Ts(t,e,n,r)}};import{big as vs}from"@galacticcouncil/common";var{FeeUtils:tr}=v,Yt=class m{type;address;tokens;maxInRatio;maxOutRatio;minTradingLimit;static fromPool(t){return new m(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 n=new Map(this.tokens.map(a=>[a.id,a])),r=n.get(t),i=n.get(e);if(r==null)throw new Error("Pool does not contain tokenIn");if(i==null)throw new Error("Pool does not contain tokenOut");return{assetIn:t,assetOut:e,decimalsIn:r.decimals,decimalsOut:i.decimals,balanceIn:r.balance,balanceOut:i.balance,assetInEd:r.existentialDeposit,assetOutEd:i.existentialDeposit}}validateAndBuy(t,e,n){let r=this.calculateInGivenOut(t,e),i=this.calculateTradeFee(r,n),a=tr.toPct(n.exchangeFee),s=r+i,o=[];(e<this.minTradingLimit||r<t.assetInEd)&&o.push("InsufficientTradingAmount");let l=t.balanceOut/this.maxOutRatio;e>l&&o.push("MaxOutRatioExceeded");let c=t.balanceIn/this.maxInRatio;return s>c&&o.push("MaxInRatioExceeded"),{amountIn:s,calculatedIn:r,amountOut:e,feePct:a,errors:o}}validateAndSell(t,e,n){let r=this.calculateOutGivenIn(t,e),i=this.calculateTradeFee(r,n),a=tr.toPct(n.exchangeFee),s=r-i,o=[];(e<this.minTradingLimit||r<t.assetOutEd)&&o.push("InsufficientTradingAmount");let l=t.balanceIn/this.maxInRatio;e>l&&o.push("MaxInRatioExceeded");let c=t.balanceOut/this.maxOutRatio;return s>c&&o.push("MaxOutRatioExceeded"),{amountIn:e,calculatedOut:r,amountOut:s,feePct:a,errors:o}}calculateInGivenOut(t,e){let n=Q.calculateInGivenOut(t.balanceIn.toString(),t.balanceOut.toString(),e.toString()),r=BigInt(n);return r<0n?0n:r}calculateOutGivenIn(t,e){let n=Q.calculateOutGivenIn(t.balanceIn.toString(),t.balanceOut.toString(),e.toString()),r=BigInt(n);return r<0n?0n:r}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 n=Q.calculatePoolTradeFee(t.toString(),e.exchangeFee[0],e.exchangeFee[1]);return BigInt(n)}normalizeSpot(t,e,n){let r=e-n;if(r===0)return t;let i=vs.pow10(Math.abs(r));return r>0?t*i:t/i}};import{CompatibilityLevel as xs}from"polkadot-api";import{Subscription as Is}from"rxjs";var $t=class extends N{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,n]=await Promise.all([this.api.constants.XYK.MaxInRatio(),this.api.constants.XYK.MaxOutRatio(),this.api.constants.XYK.MinTradingLimit()]);return{maxInRatio:t,maxOutRatio:e,minTradingLimit:n}}async isSupported(){let t=this.api.query.XYK.PoolAssets,e=await this.api.compatibilityToken;return t.isCompatible(xs.BackwardsCompatible,e)}async loadPools(){let[t,e]=await Promise.all([this.api.query.XYK.PoolAssets.getEntries(),this.getPoolLimits()]),n=t.map(async({keyArgs:r,value:i})=>{let[a]=r,[s,o]=i,[l,c,u,d]=await Promise.all([this.balance.getBalance(a,s),this.api.query.AssetRegistry.Assets.getValue(s),this.balance.getBalance(a,o),this.api.query.AssetRegistry.Assets.getValue(o)]);return{address:a,type:"XYK",tokens:[{id:s,decimals:c?.decimals||this.decimals.get(s),existentialDeposit:c?.existential_deposit,balance:l.transferable,type:c?.asset_type.type},{id:o,decimals:d?.decimals||this.decimals.get(o),existentialDeposit:d?.existential_deposit,balance:u.transferable,type:d?.asset_type.type}],...e}});return Promise.all(n)}async getPoolFees(){return{exchangeFee:await this.getExchangeFee()}}async getExchangeFee(){return await this.api.constants.XYK.GetExchangeFee()}subscribeUpdates(){return Is.EMPTY}};var nn={};I(nn,{AavePool:()=>Xt,AavePoolClient:()=>zt});import{big as er,RUNTIME_DECIMALS as nr}from"@galacticcouncil/common";var Xt=class m{type;address;tokens;maxInRatio;maxOutRatio;minTradingLimit;static fromPool(t){return new m(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 n=new Map(this.tokens.map(a=>[a.id,a])),r=n.get(t),i=n.get(e);if(r==null)throw new Error("Pool does not contain tokenIn");if(i==null)throw new Error("Pool does not contain tokenOut");return{assetIn:t,assetOut:e,balanceIn:r.balance,balanceOut:i.balance,decimalsIn:r.decimals,decimalsOut:i.decimals,assetInEd:0n,assetOutEd:0n}}validateAndBuy(t,e,n){let r=this.calculateInGivenOut(t,e),i=[];return e>t.balanceOut&&i.push("TradeNotAllowed"),{amountIn:r,calculatedIn:r,amountOut:e,feePct:0,errors:i}}validateAndSell(t,e,n){let r=this.calculateOutGivenIn(t,e),i=[];return r>t.balanceOut&&i.push("TradeNotAllowed"),{amountIn:e,calculatedOut:r,amountOut:r,feePct:0,errors:i}}calculateInGivenOut(t,e){return e}calculateOutGivenIn(t,e){return e}spotPriceInGivenOut(t){return er.toBigInt(1,nr)}spotPriceOutGivenIn(t){return er.toBigInt(1,nr)}calculateTradeFee(t,e){return 0n}};import{AccountId as Os}from"polkadot-api";import{toHex as As}from"@polkadot-api/utils";import{Subscription as ir,filter as en,map as ar}from"rxjs";import{decodeEventLog as Bs}from"viem";import{erc20 as _s,HYDRATION_SS58_PREFIX as Fs}from"@galacticcouncil/common";var rr=[{anonymous:!1,inputs:[{indexed:!0,internalType:"address",name:"reserve",type:"address"},{indexed:!1,internalType:"address",name:"user",type:"address"},{indexed:!0,internalType:"address",name:"onBehalfOf",type:"address"},{indexed:!1,internalType:"uint256",name:"amount",type:"uint256"},{indexed:!0,internalType:"uint16",name:"referralCode",type:"uint16"}],name:"Supply",type:"event"},{anonymous:!1,inputs:[{indexed:!0,internalType:"address",name:"reserve",type:"address"},{indexed:!0,internalType:"address",name:"user",type:"address"},{indexed:!0,internalType:"address",name:"to",type:"address"},{indexed:!1,internalType:"uint256",name:"amount",type:"uint256"}],name:"Withdraw",type:"event"},{anonymous:!1,inputs:[{indexed:!0,internalType:"address",name:"reserve",type:"address"},{indexed:!1,internalType:"address",name:"user",type:"address"},{indexed:!0,internalType:"address",name:"onBehalfOf",type:"address"},{indexed:!1,internalType:"uint256",name:"amount",type:"uint256"},{indexed:!1,internalType:"enum DataTypes.InterestRateMode",name:"interestRateMode",type:"uint8"},{indexed:!1,internalType:"uint256",name:"borrowRate",type:"uint256"},{indexed:!0,internalType:"uint16",name:"referralCode",type:"uint16"}],name:"Borrow",type:"event"},{anonymous:!1,inputs:[{indexed:!0,internalType:"address",name:"reserve",type:"address"},{indexed:!0,internalType:"address",name:"user",type:"address"},{indexed:!0,internalType:"address",name:"repayer",type:"address"},{indexed:!1,internalType:"uint256",name:"amount",type:"uint256"},{indexed:!1,internalType:"bool",name:"useATokens",type:"bool"}],name:"Repay",type:"event"}];var{ERC20:Rs}=_s,Cs=["Supply","Withdraw","Repay","Borrow"],zt=class extends N{getPoolType(){return"Aave"}async isSupported(){return!0}getPoolId(t,e){let n=t+"/"+e,r=new TextEncoder().encode(n.padEnd(32,"\0")),i=As(r);return Os(Fs).dec(i)}getPoolLimits(){return{maxInRatio:0n,maxOutRatio:0n,minTradingLimit:0n}}async loadPools(){let e=(await this.api.apis.AaveTradeExecutor.pools({at:"best"})).map(async({reserve:n,atoken:r,liqudity_in:i,liqudity_out:a})=>{let[s,o,l,c]=await Promise.all([this.api.query.AssetRegistry.Assets.getValue(n),this.api.query.AssetRegistry.AssetLocations.getValue(n),this.api.query.AssetRegistry.Assets.getValue(r),this.api.query.AssetRegistry.AssetLocations.getValue(r)]);return{address:this.getPoolId(n,r),type:"Aave",tokens:[{id:n,decimals:s?.decimals,existentialDeposit:s?.existential_deposit,balance:i,location:o,type:s?.asset_type.type},{id:r,decimals:l?.decimals,existentialDeposit:l?.existential_deposit,balance:a,location:c,type:l?.asset_type.type}],...this.getPoolLimits()}});return Promise.all(e)}async getPoolDelta(t){let[e,n]=t.tokens,{liqudity_in:r,liqudity_out:i}=await this.api.apis.AaveTradeExecutor.pool(e.id,n.id,{at:"best"});return t.tokens.map(a=>{let s=a.id===e.id?r:i;return{...a,balance:s}})}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:n}=e.value;return n.key.asHex()}throw new Error("Invalid aave reserve multilocation")}return Rs.fromAssetId(t.id)}parseRouterLog(t){let{asset_in:e,asset_out:n}=t;return{assetIn:e,assetOut:n,key:`${e}:${n}`}}parseEvmLog(t){let{topics:e,data:n}=t.log,r=e.map(a=>a.asHex()),i=n.asHex();try{let{eventName:a,args:s}=Bs({abi:rr,topics:r,data:i}),o=s.reserve.toLowerCase();return{eventName:a,reserve:o,key:`${a}:${o}`}}catch{return}}subscribeRouterExecuted(){let e=this.store.pools.map(n=>n.tokens).map(([n,r])=>r).map(n=>n.id);return this.api.event.Router.Executed.watch().pipe(ar(({payload:n})=>this.parseRouterLog(n)),en(({assetIn:n,assetOut:r})=>e.includes(n)||e.includes(r)),this.watchGuard("router.Execute")).subscribe(({assetIn:n,assetOut:r,key:i})=>{this.log.trace("router.Executed",i),this.store.update(async a=>{let s=[];for(let o of a){let[l,c]=o.tokens;if(c.id===n||c.id===r){let d=await this.getPoolDelta(o);s.push({...o,tokens:d})}}return s})})}subscribeEvmLog(){return this.api.event.EVM.Log.watch().pipe(ar(({payload:t})=>this.parseEvmLog(t)),en(t=>t!==void 0),en(({eventName:t})=>Cs.includes(t)),this.watchGuard("evm.Log")).subscribe(({reserve:t,eventName:e})=>{this.log.trace(`evm.Log.${e}`,t),this.store.update(async n=>{let r=[];for(let i of n){let[a]=i.tokens;if(this.getReserveH160Id(a).toLowerCase()===t){let o=await this.getPoolDelta(i);r.push({...i,tokens:o})}}return r})})}subscribeBalances(){return ir.EMPTY}subscribeUpdates(){let t=new ir;return t.add(this.subscribeRouterExecuted()),t.add(this.subscribeEvmLog()),t}};var on={};I(on,{HsmMath:()=>U,HsmPool:()=>Kt,HsmPoolClient:()=>Jt});import{calculate_collateral_in_given_hollar_out as Es,calculate_collateral_out_given_hollar_in as ks,calculate_hollar_in_given_collateral_out as Ms,calculate_hollar_out_given_collateral_in as Ds,calculate_imbalance as Ls,calculate_max_price as qs,calculate_buyback_limit as Ns,calculate_buyback_price_with_fee as Hs}from"@galacticcouncil/math-hsm";var U=class{static calculateCollateralInGivenHollarOut(t,e,n){return Es(t,e,n)}static calculateCollateralOutGivenHollarIn(t,e,n){return ks(t,e,n)}static calculateHollarOutGivenCollateralIn(t,e,n){return Ds(t,e,n)}static calculateHollarInGivenCollateralOut(t,e,n){return Ms(t,e,n)}static calculateImbalance(t,e,n){return Ls(t,e,n)}static calculateBuybackLimit(t,e){return Ns(t,e)}static calculateBuybackPriceWithFee(t,e,n){return Hs(t,e,n)}static calculateMaxPrice(t,e){return qs(t,e)}};import{big as J,RUNTIME_DECIMALS as Oe}from"@galacticcouncil/common";var{FeeUtils:yt}=v,Kt=class m extends it{hsmAddress;hsmMintCapacity;hollarId;hollarH160;collateralId;collateralBalance;maxBuyPriceCoefficient;maxInHolding;purchaseFee;buyBackFee;buyBackRate;static fromPool(t){return new m(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,n){let r=this.parsePair(t.assetOut,t.assetIn),i=super.calculateInGivenOut(r,e,{fee:this.fee}),a=this.calculateBuybackLimit(t);e>a&&n.push("MaxBuyBackExceeded");let s=this.calculateMaxPrice(t);return this.calculateBuyPrice(t,e,i)>s&&n.push("MaxBuyPriceExceeded"),i>this.collateralBalance&&n.push("InsufficientCollateral"),n}validateTradeHollarOut(t,e,n){return this.collateralBalance+t>this.maxInHolding&&n.push("MaxHoldingExceeded"),e>this.hsmMintCapacity&&n.push("FacilitatorCapacityExceeded"),n}validateTradeConstraints(t,e,n){let r=[];return t.assetIn===this.hollarId?this.validateTradeHollarIn(t,e,r):this.validateTradeHollarOut(e,n,r)}validateAndBuy(t,e){let n=this.calculateInGivenOut(t,e),r=this.validateTradeConstraints(t,n,e);return{amountIn:n,calculatedIn:n,amountOut:e,feePct:0,errors:r}}validateAndSell(t,e){let n=this.calculateOutGivenIn(t,e),r=this.validateTradeConstraints(t,e,n);return{amountIn:e,calculatedOut:n,amountOut:n,feePct:0,errors:r}}calculateHollarInGivenCollateralOut(t,e){let n=super.calculateInGivenOut(t,e,{fee:this.fee}),r=U.calculateHollarInGivenCollateralOut(e.toString(),n.toString(),yt.toRaw(this.buyBackFee).toString());return BigInt(r)}calculateCollateralInGivenHollarOut(t){let e=this.getCollateralPeg(),n=U.calculateCollateralInGivenHollarOut(t.toString(),JSON.stringify(e),yt.toRaw(this.purchaseFee).toString());return BigInt(n)}calculateInGivenOut(t,e){return t.assetOut==this.hollarId?this.calculateCollateralInGivenHollarOut(e):this.calculateHollarInGivenCollateralOut(t,e)}calculateCollateralOutGivenHollarIn(t,e){let n=super.calculateOutGivenIn(t,e,{fee:this.fee}),r=U.calculateCollateralOutGivenHollarIn(e.toString(),n.toString(),yt.toRaw(this.buyBackFee).toString());return BigInt(r)}calculateHollarOutGivenCollateralIn(t){let e=this.getCollateralPeg(),n=U.calculateHollarOutGivenCollateralIn(t.toString(),JSON.stringify(e),yt.toRaw(this.purchaseFee).toString());return BigInt(n)}calculateOutGivenIn(t,e){return t.assetIn==this.hollarId?this.calculateCollateralOutGivenHollarIn(t,e):this.calculateHollarOutGivenCollateralIn(e)}calculateImbalance(t){let e=this.getCollateralPeg(),n=U.calculateImbalance(t.balanceIn.toString(),JSON.stringify(e),t.balanceOut.toString());return BigInt(n)}calculateBuybackLimit(t){let e=this.calculateImbalance(t),n=U.calculateBuybackLimit(e.toString(),yt.toRaw(this.buyBackRate).toString());return BigInt(n)}calculateBuyPrice(t,e,n){let r=U.calculateBuybackPriceWithFee(n.toString(),e.toString(),yt.toRaw(this.buyBackFee).toString()),[i,a]=JSON.parse(r),s=J.pow10(t.decimalsIn+Oe-t.decimalsOut);return BigInt(i)*s/BigInt(a)}calculateMaxPrice(t){let e=this.getCollateralPeg(),n=U.calculateMaxPrice(JSON.stringify(e),this.maxBuyPriceCoefficient.toString()),[r,i]=JSON.parse(n),a=J.pow10(Oe-t.decimalsOut);return BigInt(r)*a/BigInt(i)}spotPriceInGivenOut(t){let e=J.toBigInt(1,t.decimalsOut),r=this.calculateInGivenOut(t,e)*J.pow10(Oe-t.decimalsOut);return this.normalizeSpotPrice(r,t.decimalsOut,t.decimalsIn)}spotPriceOutGivenIn(t){let e=J.toBigInt(1,t.decimalsIn),r=this.calculateOutGivenIn(t,e)*J.pow10(Oe-t.decimalsIn);return this.normalizeSpotPrice(r,t.decimalsIn,t.decimalsOut)}getCollateralPeg(){let t=this.tokens.findIndex(r=>r.id!==this.hollarId),e=this.pegs[t],n=this.tokens[t].decimals;return this.isDefaultPeg(e)?[J.toBigInt(1,18).toString(),J.toBigInt(1,n).toString()]:e}isDefaultPeg(t){let[e,n]=t;return Array.isArray(t)&&t.length===2&&e==="1"&&n==="1"}normalizeSpotPrice(t,e,n){let r=e-n;if(r===0)return t;let i=J.pow10(Math.abs(r));return r>0?t*i:t/i}};import{AccountId as Gs,CompatibilityLevel as Vs}from"polkadot-api";import{toHex as Us}from"@polkadot-api/utils";import{Subscription as rn,combineLatest as Ws,filter as sr,map as an,pairwise as Ys}from"rxjs";import{decodeEventLog as $s}from"viem";import{h160 as Xs,HYDRATION_SS58_PREFIX as zs}from"@galacticcouncil/common";var jt=[{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 Qt=class{client;constructor(t){this.client=t.getWsProvider()}async getFacilitatorCapacity(t,e){let[n,r]=await this.client.readContract({abi:jt,address:t,functionName:"getFacilitatorBucket",args:[e]});return n-r}};var{FeeUtils:sn}=v,{H160:or}=Xs,Ks=["FacilitatorBucketCapacityUpdated","FacilitatorBucketLevelUpdated"],Jt=class extends N{ghoClient;stableClient;constructor(t,e,n){super(t,e),this.stableClient=n,this.ghoClient=new Qt(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:n}=e.value;return n.key.asHex()}}throw Error("Invalid hollar multilocation")}getPoolAddress(t){let e=t.padEnd(32,"\0"),n=new TextEncoder().encode(e),r=Us(n);return Gs(zs).dec(r)}async isSupported(){let t=this.api.query.HSM.Collaterals,e=await this.api.compatibilityToken;return t.isCompatible(Vs.BackwardsCompatible,e)}async loadPools(){let t=await this.api.constants.HSM.HollarId(),[e,n,r]=await Promise.all([this.api.query.AssetRegistry.AssetLocations.getValue(t),this.api.query.HSM.Collaterals.getEntries({at:"best"}),this.stableClient.getPools()]);if(n.length===0)return[];let i=this.getFacilitatorAddress(),a=or.fromAny(i),s=this.getHollarAddress(e),o=await this.ghoClient.getFacilitatorCapacity(s,a),l=n.map(async({keyArgs:u,value:d})=>{let[p]=u,{pool_id:h,max_buy_price_coefficient:b,max_in_holding:g,purchase_fee:f,buy_back_fee:y,buyback_rate:S}=d,P=r.find(w=>w.id===h);if(P){let w=this.getPoolId(h),T=await this.balance.getBalance(i,p);return{...P,address:w,type:"HSM",tokens:P.tokens.filter(F=>F.id!==h),hsmAddress:i,hsmMintCapacity:o,hollarId:t,hollarH160:s,collateralId:p,collateralBalance:T.transferable,maxBuyPriceCoefficient:b,maxInHolding:g,purchaseFee:sn.fromPermill(f),buyBackFee:sn.fromPermill(y),buyBackRate:sn.fromPerbill(S)}}});return(await Promise.all(l)).filter(u=>u!==null)}async getPoolFees(){return{}}parseEvmLog(t){let{topics:e,data:n}=t.log,r=e.map(a=>a.asHex()),i=n.asHex();try{let{eventName:a,args:s}=$s({abi:jt,topics:r,data:i}),o=s.facilitatorAddress.toLowerCase();return{eventName:a,facilitator:o,key:`${a}:${o}`}}catch{return}}subscribeEvmLog(){return this.api.event.EVM.Log.watch().pipe(an(({payload:t})=>this.parseEvmLog(t)),sr(t=>t!==void 0),sr(({eventName:t})=>Ks.includes(t)),this.watchGuard("evm.Log")).subscribe(({eventName:t,facilitator:e})=>{this.log.trace(`evm.Log.${t}`,e),this.store.update(async n=>{let r=[],[{hsmAddress:i,hollarH160:a}]=n,s=or.fromAny(i);if(s.toLowerCase()===e){let l=await this.ghoClient.getFacilitatorCapacity(a,s);for(let c of n)r.push({...c,hsmMintCapacity:l})}return r})})}subscribeCollateralBalance(){let t=[],e=[];this.store.pools.forEach(i=>{let{tokens:a,collateralId:s}=i;a.find(l=>l.id===s).type==="Erc20"?e.push(s):t.push(s)});let[{hsmAddress:n}]=this.store.pools,r=[];if(t.length>0){let i=this.balance.watchTokensBalance(n);r.push(i)}if(e.length>0){let i=this.balance.watchErc20Balance(n,e);r.push(i)}return r.length>0?Ws(r).pipe(an(i=>i.flat()),Ys(),an(([i,a])=>this.balance.getDeltas(i,a)),this.watchGuard("balances")).subscribe(i=>{this.store.update(a=>{let s=[],o=new Map(a.map(l=>[l.collateralId,l]));return i.forEach(({id:l,balance:c})=>{let u=o.get(l);u&&(this.log.trace("balances",{id:l,balance:c}),s.push({...u,collateralBalance:c.transferable}))}),s})}):rn.EMPTY}subscribeStableswapUpdates(){return this.stableClient.getSubscriber().pipe(this.watchGuard("stableswap.updates")).subscribe(t=>{let e=new Map(t.map(n=>[n.id,n]));this.store.update(n=>{let r=[];for(let i of n){let a=e.get(i.id);a&&r.push({...i,fee:a.fee,tokens:a.tokens.filter(s=>s.id!==i.id),totalIssuance:a.totalIssuance,pegs:a.pegs,amplification:a.amplification,isRampPeriod:a.isRampPeriod})}return r})})}subscribeBalances(){return rn.EMPTY}subscribeUpdates(){let t=new rn;return t.add(this.subscribeCollateralBalance()),t.add(this.subscribeStableswapUpdates()),t.add(this.subscribeEvmLog()),t}};var ft=class{static get(t){switch(t.type){case"Aave":return Xt.fromPool(t);case"XYK":return Yt.fromPool(t);case"Omnipool":return Gt.fromPool(t);case"LBP":return Nt.fromPool(t);case"Stableswap":return it.fromPool(t);case"HSM":return Kt.fromPool(t);default:throw new Error("Pool type "+t.type+" is not supported yet")}}};import{log as js}from"@galacticcouncil/common";import{Subject as Qs,Subscription as Pt,takeUntil as Js}from"rxjs";var{logger:Zs}=js,St=class extends _{evm;aave;omnipool;stableswap;hsm;xyk;lbp;active=new Set([]);pools=new Map([]);clients=[];aaveSub=Pt.EMPTY;omniSub=Pt.EMPTY;stableSub=Pt.EMPTY;hsmSub=Pt.EMPTY;xykSub=Pt.EMPTY;lbpSub=Pt.EMPTY;isReady=!1;isDestroyed=new Qs;constructor(t,e){super(t),this.evm=e,this.aave=new zt(t,e),this.omnipool=new Ut(t,e),this.stableswap=new Wt(t,e),this.hsm=new Jt(t,e,this.stableswap),this.xyk=new $t(t,e),this.lbp=new Ht(t,e),this.clients=[this.aave,this.omnipool,this.stableswap,this.hsm,this.xyk,this.lbp]}subscribe(t){return t.getSubscriber().pipe(Js(this.isDestroyed)).subscribe(e=>{e.forEach(n=>{this.pools.set(n.address,n)})})}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")||(Zs.info("[PoolContextProvider] auto-activating stableswap"),this.withStableswap()),this.hsmSub.unsubscribe(),this.hsmSub=this.subscribe(this.hsm),this.active.add("HSM"),this}withXyk(t){return this.xyk.withOverride(t),this.xykSub.unsubscribe(),this.xykSub=this.subscribe(this.xyk),this.active.add("XYK"),this}withLbp(){return this.lbpSub.unsubscribe(),this.lbpSub=this.subscribe(this.lbp),this.active.add("LBP"),this}destroy(){this.isDestroyed.next(!0),this.isDestroyed.complete(),this.active.clear(),this.pools.clear(),this.isReady=!1}async getPools(){if(this.isReady){let e=this.pools.values();return Array.from(e)}let t=await Promise.all(this.clients.filter(e=>this.active.has(e.getPoolType())).map(e=>e.getPools()));return this.isReady=!0,t.flat()}async getPoolFees(t,e){let n=this.clients.find(r=>r.getPoolType()===e.type);if(n)return n.getPoolFees(t,e.address);throw new Ct(e.type)}};var gr={};I(gr,{DCA_TIME_RESERVE:()=>mr,DEFAULT_BLOCK_TIME:()=>ur,DEFAULT_MIN_BUDGET:()=>un,ORDER_MIN_BLOCK_PERIOD:()=>pr,Router:()=>wt,TWAP_EXECUTION_INTERVAL:()=>ne,TWAP_MAX_DURATION:()=>pn,TWAP_MAX_PRICE_IMPACT:()=>mn,TWAP_TX_MULTIPLIER:()=>nb,TradeOrderError:()=>cn,TradeOrderType:()=>Be,TradeRouteBuilder:()=>G,TradeRouter:()=>tt,TradeScheduler:()=>vt,TradeType:()=>Ae});var Zt=class{constructor(t=1/0){this.capacity=t}storage=[];enqueue(t){if(this.size()===this.capacity)throw Error("Queue has reached max capacity, you cannot add more items");this.storage.push(t)}dequeue(){return this.storage.shift()}size(){return this.storage.length}};var to=10,te=class{isNotVisited(t,e){let n=!0;return e.forEach(r=>{(r[0]===t[0]||r[1]===t[1])&&(n=!1)}),n}findPaths(t,e,n){let r=[],i=new Zt,a=[];for(a.push([e,""]),i.enqueue(a);i.size()>0;){let s=i.dequeue();if(!s||s.length>to)continue;let o=s[s.length-1];(n===null||o[0]===n)&&r.push(s),t.get(o[0])?.forEach(c=>{if(this.isNotVisited(c,s)){let u=[...s];u.push(c),i.enqueue(u)}})}return r}findShortestPaths(t,e,n){let r=[],i=new Zt,a=[];a.push([e,""]),i.enqueue(a);let s=1/0;for(;i.size()>0;){let o=i.dequeue();if(!o)continue;let l=o[o.length-1];if(l[0]===n){o.length<s?(s=o.length,r.length=0,r.push(o)):o.length===s&&r.push(o);continue}let c=t.get(l[0]);for(let u of c??[])this.isNotVisited(u,o)&&i.enqueue([...o,u])}return r}buildAndPopulateGraph(t,e){let n=new Map;for(let r of t)n.set(parseInt(r),[]);for(let[r,i,a]of e)n.get(i)?.push([a,r]);return n}};function ln(m){let t={};for(let e of m){let n=e.tokens.length;for(let r=0;r<n;r++){t[e.tokens[r].id]||(t[e.tokens[r].id]=[]);for(let i=0;i<n;i++){if(r==i)continue;let a=[e.address,e.tokens[r].id,e.tokens[i].id];t[e.tokens[r].id].push(a)}}}return t}var ee=class{getProposals(t,e,n){let r=n.filter(g=>g.type==="XYK"),i=n.filter(g=>g.type!=="XYK"),a=new Set(i.map(g=>g.tokens).flat().map(g=>g.id)),s=a.has(t),o=a.has(e),l=new te,c=g=>{let f=ln(g),y=Object.keys(f),S=y.flatMap(P=>f[P]);return l.buildAndPopulateGraph(y,S)};if(!s&&!o){let g=r.filter(S=>S.tokens.find(P=>P.id===t)||S.tokens.find(P=>P.id===e)),f=c(g),y=l.findPaths(f,t,e);return this.parsePaths(y)}if(s&&o){let g=c(i),f=l.findPaths(g,t,e);return this.parsePaths(f)}let u=s?e:t,d=r.filter(g=>g.tokens.some(f=>f.id===u));if(d.length===0)return[];let p=[...i,...d],h=c(p),b=l.findPaths(h,t,e);return this.parsePaths(b)}parsePaths(t){let e=[];for(let n of t){let r=[];for(let i=0;i<n.length;i++){let a=n[i],s=n[i+1];if(s==null)break;r.push(this.toEdge(a,s))}e.push(r)}return e}toEdge(t,e){return[e[1],t[0],e[0]]}};var wt=class{routeSuggester;routeProposals;ctx;filter={};constructor(t){this.ctx=t,this.routeSuggester=new ee,this.routeProposals=new Map}async withFilter(t){this.filter=t||{},this.routeProposals.clear(),this.onFilterChanged()}onFilterChanged(){}buildRouteKey(t,e,n){return`${t}->${e}::${n.length}`}applyPoolFilter(t){let{useOnly:e=[],exclude:n=[]}=this.filter,r=new Set(e),i=new Set(n);return t.filter(a=>i.has(a.type)?!1:r.size>0?r.has(a.type):!0)}async getPools(){let t=await this.ctx.getPools();return this.applyPoolFilter(t)}async getRoutes(t,e){let n=await this.getPools();return this.validateInput(t,e,n),this.getPaths(t,e,n)}async getTradeableAssets(){let t=await this.getPools(),e=this.getAssets(t);return Array.from(e)}async getRouteableAssets(t){let e=await this.getTradeableAssets();return(await Promise.all(e.filter(r=>r!==t).map(r=>this.getRoutes(r,t)))).filter(r=>r.length>0).map(([r])=>r[0].assetIn).sort()}validateInput(t,e,n){if(n.length===0)throw new Error("No pools configured");if(t===e)throw new Error("Trading pair can't be identical");let r=this.getAssets(n);if(!r.has(t))throw new Error(t+" is not supported asset");if(!r.has(e))throw new Error(e+" is not supported asset");return this.toPoolsMap(n)}getAssets(t){let e=t.map(n=>n.tokens.map(r=>r.id)).flat().sort((n,r)=>n>r?1:-1);return new Set(e)}getPaths(t,e,n){let r=this.toPoolsMap(n);return this.getProposals(t,e,n).filter(a=>this.validPath(a,r)).map(a=>this.toHops(a,r))}getProposals(t,e,n){let r=this.buildRouteKey(t,e,n);if(this.routeProposals.has(r))return this.routeProposals.get(r);let i=this.routeSuggester.getProposals(t,e,n);return this.routeProposals.set(r,i),i}validPath(t,e){return t.length>0&&t.map(n=>this.validEdge(n,e)).reduce((n,r)=>n&&r)}validEdge([t,e,n],r){return r.get(t)?.validatePair(e,n)||!1}toPoolsMap(t){return new Map(t.map(e=>[e.address,ft.get(e)]))}toHops(t,e){return t.map(([n,r,i])=>{let a=e.get(n);return{poolAddress:n,poolId:a?.id,pool:a?.type,assetIn:r,assetOut:i}})}};import{big as C,RUNTIME_DECIMALS as Tt}from"@galacticcouncil/common";var Ae=(e=>(e.Buy="Buy",e.Sell="Sell",e))(Ae||{}),Be=(n=>(n.Dca="Dca",n.TwapSell="TwapSell",n.TwapBuy="TwapBuy",n))(Be||{}),cn=(n=>(n.OrderTooSmall="OrderTooSmall",n.OrderTooBig="OrderTooBig",n.OrderImpactTooBig="OrderImpactTooBig",n))(cn||{});var{FeeUtils:cr}=v,tt=class extends wt{mlr;constructor(t){super(t),this.mlr=new Map}onFilterChanged(){this.mlr.clear()}buildCtxSync(t,e,n){let r=super.validateInput(t,e,n),i=super.getPaths(t,e,n);if(!i.length)throw new Et(t,e);return{paths:i,pools:n,poolsMap:r}}async withCtx(t,e,n){let r=await super.getPools(),i=this.buildCtxSync(t,e,r);return n(i)}isDirectTrade(t){return t.length==1}findBestSellRoute(t){let e=t.sort((n,r)=>{let i=n[n.length-1].amountOut,a=r[r.length-1].amountOut;return i>a?-1:1});return e.find(n=>n.every(r=>r.errors.length==0))||e[0]}getRouteFeeRange(t){if(t.filter(n=>n.tradeFeeRange).length>0){let n=t.map(i=>i.tradeFeeRange?.[0]??i.tradeFeePct).reduce((i,a)=>i+a),r=t.map(i=>i.tradeFeeRange?.[1]??i.tradeFeePct).reduce((i,a)=>i+a);return[n,r]}}getPoolFeeRange(t,e){let n=t.min?cr.toPct(t.min):void 0,r=t.max?cr.toPct(t.max):void 0;if(n&&r)return[n,Math.max(r,e)]}async getBestSell(t,e,n){return this.getSell(t,e,n)}getSellSpot(t){let e=t[t.length-1];return t.length===1?e.spotPrice:this.calculateSpot(t)}async getSell(t,e,n,r){return this.withCtx(t,e,async({paths:i,poolsMap:a})=>{let s;if(r)s=await this.toSellSwaps(n,r,a);else{let o=i.map(c=>this.toSellSwaps(n,c,a)),l=await Promise.all(o);s=this.findBestSellRoute(l)}return this.buildSell(a,s)})}async getSells(t,e,n){return this.withCtx(t,e,async({paths:r,poolsMap:i})=>{let a=r.map(o=>this.toSellSwaps(n,o,i));return(await Promise.all(a)).filter(o=>o.every(l=>l.errors.length==0)).map(o=>this.buildSell(i,o)).sort((o,l)=>o.amountOut>l.amountOut?-1:1)})}buildSell(t,e){let n=e[0],r=e[e.length-1],i=this.isDirectTrade(e),a=this.getSellSpot(e),s=r.amountOut,o=i?r.calculatedOut:this.calculateDelta0Y(n.amountIn,e,t),l=o-s,c=this.getRouteFeeRange(e),u=i?r.tradeFeePct:L.calculateSellFee(o,s),d=R.mulSpot(n.amountIn,a,n.assetInDecimals,r.assetOutDecimals),p=L.calculateDiffToRef(o,d);return{type:"Sell",amountIn:n.amountIn,amountOut:r.amountOut,spotPrice:a,tradeFee:l,tradeFeePct:u,tradeFeeRange:c,priceImpactPct:p,swaps:e,toHuman(){return{type:"Sell",amountIn:C.toDecimal(n.amountIn,n.assetInDecimals),amountOut:C.toDecimal(r.amountOut,r.assetOutDecimals),spotPrice:C.toDecimal(a,Tt),tradeFee:C.toDecimal(l,r.assetOutDecimals),tradeFeePct:u,tradeFeeRange:c,priceImpactPct:p,swaps:e.map(h=>h.toHuman())}}}}calculateSpot(t){return t.map(e=>e.spotPrice).reduce((e,n)=>e*n/10n**BigInt(Tt))}calculateDelta0Y(t,e,n){let r=[];for(let i=0;i<e.length;i++){let a=e[i],s=n.get(a.poolAddress);if(s==null)throw new Error("Pool does not exit");let o=s.parsePair(a.assetIn,a.assetOut),l;i>0?l=r[i-1]:l=t;let c=s.calculateOutGivenIn(o,l);r.push(c)}return r[r.length-1]}async calculateMostLiquidRoute(t,e,n){let{paths:r,pools:i,poolsMap:a}=n,l=i.filter(b=>b.tokens.some(g=>g.id===t)).map(b=>b.type==="Aave"?b.tokens:b.tokens.filter(g=>g.id===t)).map(b=>b.map(g=>g.balance).reduce((g,f)=>g+f)).sort((b,g)=>g<b?-1:1)[0],c=R.getFraction(l,.1),u=await Promise.all(r.map(b=>this.toSellSwaps(c,b,a))),p=this.findBestSellRoute(u).map(b=>({poolAddress:b.poolAddress,poolId:b?.poolId,pool:b.pool,assetIn:b.assetIn,assetOut:b.assetOut})),h=this.buildRouteKey(t,e,i);return this.mlr.set(h,p),p}async toSellSwaps(t,e,n){let r=[];for(let i=0;i<e.length;i++){let a=e[i],s=n.get(a.poolAddress);if(s==null)throw new Error("Pool does not exit");let o=s.parsePair(a.assetIn,a.assetOut),l;i>0?l=r[i-1].amountOut:l=typeof t=="string"?C.toBigInt(t,o.decimalsIn):t;let c=await this.ctx.getPoolFees(o,s),{amountOut:u,calculatedOut:d,feePct:p,errors:h}=s.validateAndSell(o,l,c),b=this.getPoolFeeRange(c,p),g=s.spotPriceOutGivenIn(o),f=R.mulSpot(l,g,o.decimalsIn,o.decimalsOut),y=L.calculateDiffToRef(d,f);r.push({...a,assetInDecimals:o.decimalsIn,assetOutDecimals:o.decimalsOut,amountIn:l,amountOut:u,calculatedOut:d,spotPrice:g,tradeFeePct:p,tradeFeeRange:b,priceImpactPct:y,errors:h,isSupply(){return s.type==="Aave"&&s.tokens[0].id===a.assetIn},isWithdraw(){return s.type==="Aave"&&s.tokens[1].id===a.assetIn},toHuman(){return{...a,amountIn:C.toDecimal(l,o.decimalsIn),amountOut:C.toDecimal(u,o.decimalsOut),calculatedOut:C.toDecimal(d,o.decimalsOut),spotPrice:C.toDecimal(g,Tt),tradeFeePct:p,tradeFeeRange:b,priceImpactPct:y,errors:h}}})}return r}async getMostLiquidRoute(t,e){return this.withCtx(t,e,async n=>{let r=this.buildRouteKey(t,e,n.pools),i=this.mlr.get(r);return i||this.calculateMostLiquidRoute(t,e,n)})}async getSpotPrice(t,e){return this.withCtx(t,e,async n=>{let{pools:r,poolsMap:i}=n,a=this.buildRouteKey(t,e,r),s=this.mlr.get(a);s||(s=await this.calculateMostLiquidRoute(t,e,n));let o=await this.toSellSwaps("1",s,i);return{amount:this.getSellSpot(o),decimals:Tt}}).catch(()=>{})}findBestBuyRoute(t){let e=t.sort((n,r)=>{let i=n[0].amountIn,a=r[0].amountIn;return i>a?1:-1});return e.find(n=>n.every(r=>r.errors.length==0))||e[0]}async getBestBuy(t,e,n){return this.getBuy(t,e,n)}getBuySpot(t){let e=t[0];return t.length===1?e.spotPrice:this.calculateSpot(t)}async getBuy(t,e,n,r){return this.withCtx(t,e,async({paths:i,poolsMap:a})=>{let s;if(r)s=await this.toBuySwaps(n,r,a);else{let o=i.map(c=>this.toBuySwaps(n,c,a)),l=await Promise.all(o);s=this.findBestBuyRoute(l)}return this.buildBuy(a,s)})}async getBuys(t,e,n){return this.withCtx(t,e,async({paths:r,poolsMap:i})=>{let a=r.map(o=>this.toBuySwaps(n,o,i));return(await Promise.all(a)).filter(o=>o.every(l=>l.errors.length==0)).map(o=>this.buildBuy(i,o)).sort((o,l)=>o.amountIn>l.amountIn?1:-1)})}buildBuy(t,e){let n=e[e.length-1],r=e[0],i=this.isDirectTrade(e),a=this.getBuySpot(e),s=r.amountIn,o=i?r.calculatedIn:this.calculateDelta0X(n.amountOut,e,t),l=s-o,c=this.getRouteFeeRange(e),u=i?r.tradeFeePct:L.calculateBuyFee(o,s),d=R.mulSpot(n.amountOut,a,n.assetOutDecimals,r.assetInDecimals),p;return o===0n?p=-100:p=L.calculateDiffToRef(d,o),{type:"Buy",amountOut:n.amountOut,amountIn:r.amountIn,spotPrice:a,tradeFee:l,tradeFeePct:u,tradeFeeRange:c,priceImpactPct:p,swaps:e,toHuman(){return{type:"Buy",amountOut:C.toDecimal(n.amountOut,n.assetOutDecimals),amountIn:C.toDecimal(r.amountIn,r.assetInDecimals),spotPrice:C.toDecimal(a,Tt),tradeFee:C.toDecimal(l,r.assetInDecimals),tradeFeePct:u,tradeFeeRange:c,priceImpactPct:p,swaps:e.map(h=>h.toHuman())}}}}calculateDelta0X(t,e,n){let r=[];for(let i=e.length-1;i>=0;i--){let a=e[i],s=n.get(a.poolAddress);if(s==null)throw new Error("Pool does not exit");let o=s.parsePair(a.assetIn,a.assetOut),l;i==e.length-1?l=t:l=r[0];let c=s.calculateInGivenOut(o,l);r.unshift(c)}return r[0]}async toBuySwaps(t,e,n){let r=[];for(let i=e.length-1;i>=0;i--){let a=e[i],s=n.get(a.poolAddress);if(s==null)throw new Error("Pool does not exit");let o=s.parsePair(a.assetIn,a.assetOut),l;i==e.length-1?l=typeof t=="string"?C.toBigInt(t,o.decimalsOut):t:l=r[0].amountIn;let c=await this.ctx.getPoolFees(o,s),{amountIn:u,calculatedIn:d,feePct:p,errors:h}=s.validateAndBuy(o,l,c),b=this.getPoolFeeRange(c,p),g=s.spotPriceInGivenOut(o),f=R.mulSpot(l,g,o.decimalsOut,o.decimalsIn),y;d===0n?y=-100:y=L.calculateDiffToRef(f,d),r.unshift({...a,assetInDecimals:o.decimalsIn,assetOutDecimals:o.decimalsOut,amountOut:l,amountIn:u,calculatedIn:d,spotPrice:g,tradeFeePct:p,tradeFeeRange:b,priceImpactPct:y,errors:h,isSupply(){return s.type==="Aave"&&s.tokens[0].id===a.assetIn},isWithdraw(){return s.type==="Aave"&&s.tokens[1].id===a.assetIn},toHuman(){return{...a,amountOut:C.toDecimal(l,o.decimalsOut),amountIn:C.toDecimal(u,o.decimalsIn),calculatedIn:C.toDecimal(d,o.decimalsIn),spotPrice:C.toDecimal(g,Tt),tradeFeePct:p,tradeFeeRange:b,priceImpactPct:y,errors:h}}})}return r}};import{big as D}from"@galacticcouncil/common";var ur=6e3,un=1000000000000000n,ne=6,mn=-5,pn=216e5,nb=3,mr=.1,pr=6;import{Enum as dr}from"polkadot-api";var G=class{static build(t){return t.map(({assetIn:e,assetOut:n,pool:r,poolId:i})=>r==="Stableswap"?{pool:dr("Stableswap",i),asset_in:e,asset_out:n}:{pool:dr(r),asset_in:e,asset_out:n})}};var vt=class{schedulerOptions;router;constructor(t,e={}){this.router=new tt(t),this.router.withFilter({exclude:["HSM"]}),this.schedulerOptions=Object.freeze({blockTime:e.blockTime??6e3,minBudgetInNative:e.minBudgetInNative??un})}get blockTime(){return this.schedulerOptions.blockTime}get minOrderBudget(){return this.schedulerOptions.minBudgetInNative}async getDcaOrder(t,e,n,r,i){let a=await this.router.getBestSell(t,e,n),{amountIn:s,swaps:o,priceImpactPct:l}=a,c=o[0],u=o[o.length-1],{assetInDecimals:d}=c,{assetOutDecimals:p}=u,h=Math.abs(l),b=await this.getMinimumOrderBudget(t,d),g=this.getOptimalTradeCount(h),f=this.getMaximumTradeCount(s,b,r),y=i||Math.min(g,f),S=Math.round(r/y),P=s/BigInt(y),w=await this.router.getBestSell(t,e,P),T=s<b,F=[];T&&F.push("OrderTooSmall");let k=w.amountOut*BigInt(y),$=this.toBlockPeriod(S),K=w.tradeFee*BigInt(y),H=G.build(o),V={assetIn:t,assetOut:e,errors:F,maxTradeCount:f,tradeCount:y,tradeFee:K,tradeImpactPct:w.priceImpactPct,tradePeriod:$,tradeRoute:H,type:"Dca"};return{...V,amountIn:s,amountOut:k,tradeAmountIn:w.amountIn,tradeAmountOut:w.amountOut,toHuman(){return{...V,amountIn:D.toDecimal(s,d),amountOut:D.toDecimal(k,p),tradeAmountIn:D.toDecimal(w.amountIn,d),tradeAmountOut:D.toDecimal(w.amountOut,p)}}}}async getMinimumOrderBudget(t,e){if(0===t)return this.minOrderBudget;let n=await this.router.getSpotPrice(0,t);if(n)return R.mulSpot(this.minOrderBudget,n.amount,12,e);let r=await this.router.getSpotPrice(t,0);if(r)return R.divSpot(this.minOrderBudget,r.amount,12,e);throw new Error("Unable to calculate order budget")}getMaximumTradeCount(t,e,n){let r=e*2n/10n;if(r===0n)return 0;let i=Number(t/r),a=Math.floor(n/this.blockTime),s=Math.max(0,Math.floor(a*(1-.1)));return Math.min(i,s)}getOptimalTradeCount(t){let e=Math.round(t*10)||1;return Math.max(e,3)}async getOpenBudgetDcaOrder(t,e,n,r){let i=await this.router.getBestSell(t,e,n),{swaps:a}=i,s=a[0],o=a[a.length-1],{assetInDecimals:l}=s,{assetOutDecimals:c}=o,u=await this.getMinimumOrderBudget(t,l),d=i.amountIn<u,p=[];d&&p.push("OrderTooSmall");let h=this.toBlockPeriod(r),b=G.build(a),g={assetIn:t,assetOut:e,errors:p,maxTradeCount:0,tradeCount:0,tradeFee:i.tradeFee,tradeImpactPct:i.priceImpactPct,tradePeriod:h,tradeRoute:b,type:"Dca"};return{...g,amountIn:0n,amountOut:0n,tradeAmountIn:i.amountIn,tradeAmountOut:i.amountOut,toHuman(){return{...g,amountIn:"0",amountOut:"0",tradeAmountIn:D.toDecimal(i.amountIn,l),tradeAmountOut:D.toDecimal(i.amountOut,c)}}}}async getTwapSellOrder(t,e,n){let r=await this.router.getBestSell(t,e,n),{amountIn:i,swaps:a,priceImpactPct:s}=r,o=a[0],l=a[a.length-1],{assetInDecimals:c}=o,{assetOutDecimals:u}=l,d=Math.abs(s),p=this.getTwapTradeCount(d),h=i/BigInt(p),[b,g]=await Promise.all([this.getMinimumOrderBudget(t,c),this.router.getBestSell(o.assetIn,l.assetOut,h)]),f=p===1,y=i<b,S=g.priceImpactPct<-5,P=[];y||f?P.push("OrderTooSmall"):S&&P.push("OrderImpactTooBig");let w=g.amountOut*BigInt(p),T=g.tradeFee*BigInt(p),F=G.build(a),k={assetIn:t,assetOut:e,errors:P,tradeCount:p,tradeImpactPct:g.priceImpactPct,tradePeriod:6,tradeRoute:F,type:"TwapSell"};return{...k,amountIn:i,amountOut:w,tradeAmountIn:g.amountIn,tradeAmountOut:g.amountOut,tradeFee:T,toHuman(){return{...k,amountIn:D.toDecimal(i,c),amountOut:D.toDecimal(w,u),tradeAmountIn:D.toDecimal(g.amountIn,c),tradeAmountOut:D.toDecimal(g.amountOut,u),tradeFee:D.toDecimal(T,u)}}}}async getTwapBuyOrder(t,e,n){let r=await this.router.getBestBuy(t,e,n),{amountOut:i,swaps:a,priceImpactPct:s}=r,o=a[0],l=a[a.length-1],{assetInDecimals:c}=o,{assetOutDecimals:u}=l,d=Math.abs(s),p=this.getTwapTradeCount(d),h=i/BigInt(p),[b,g]=await Promise.all([this.getMinimumOrderBudget(t,c),this.router.getBestBuy(o.assetIn,l.assetOut,h)]),f=g.amountIn*BigInt(p),y=p===1,S=f<b,P=g.priceImpactPct<-5,w=[];S||y?w.push("OrderTooSmall"):P&&w.push("OrderImpactTooBig");let T=g.tradeFee*BigInt(p),F=G.build(a),k={assetIn:t,assetOut:e,errors:w,tradeCount:p,tradeImpactPct:g.priceImpactPct,tradePeriod:6,tradeRoute:F,type:"TwapBuy"};return{...k,amountIn:f,amountOut:i,tradeAmountIn:g.amountIn,tradeAmountOut:g.amountOut,tradeFee:T,toHuman(){return{...k,amountIn:D.toDecimal(f,c),amountOut:D.toDecimal(i,u),tradeAmountIn:D.toDecimal(g.amountIn,c),tradeAmountOut:D.toDecimal(g.amountOut,u),tradeFee:D.toDecimal(T,c)}}}}getTwapTradeCount(t){let e=this.getOptimalTradeCount(t);if(this.getTwapExecutionTime(e)>216e5){let r=216e5/(this.blockTime*6);return Math.round(r)}return e}getTwapExecutionTime(t){return t*6*this.blockTime}toBlockPeriod(t){let e=t/this.blockTime,n=Math.round(e);return Math.max(n,6)}};var wr={};I(wr,{BIG_10:()=>Sr,BIG_BILL:()=>dn,StakingApi:()=>re,StakingClient:()=>ie});import{calculate_accumulated_rps as io,calculate_percentage_amount as ao,calculate_period_number as yr,calculate_points as fr,calculate_rewards as so,sigmoid as Pr}from"@galacticcouncil/math-staking";import W from"big.js";var _e={none:.1,locked1x:1,locked2x:2,locked3x:3,locked4x:4,locked5x:5,locked6x:6},hr=m=>Object.keys(_e).includes(m);import{AccountId as eo}from"polkadot-api";import{toHex as no}from"@polkadot-api/utils";import{HYDRATION_SS58_PREFIX as ro}from"@galacticcouncil/common";function br(m){let t=("modl"+m).padEnd(32,"\0"),e=new TextEncoder().encode(t),n=no(e);return eo(ro).dec(n)}var Fe="20000000000000000",Re="2000",Sr=W(10),dn=W(Sr.pow(12)),re=class{client;balance;constructor(t,e){this.client=t,this.balance=e}async getPotBalance(){let t=await this.client.getPalletId(),e=br(t);return await this.balance.getBalance(e,0)}async getStakingPosition(t){let[e,n]=await Promise.all([this.client.getStakingPositionsValue(t),this.client.getStakingVotes(t)]);if(!e)return;let r=e.created_at,i=await n.reduce(async(a,[s,o])=>{let l=await a,c=s,u=o.amount,d=o.conviction.type.toLowerCase(),p=await this.client.getReferendumInfo(c);return p&&(p.type==="Approved"||p.type==="Rejected")&&hr(d)&&l.push({id:c,amount:u,conviction:d}),l},Promise.resolve([]));return{stake:e.stake,rewardPerStake:e.reward_per_stake,createdAt:r,actionPoints:e.action_points,accumulatedUnpaidRewards:e.accumulated_unpaid_rewards,accumulatedSlashPoints:e.accumulated_slash_points,accumulatedLockedRewards:e.accumulated_locked_rewards,votes:i}}async getStake(t){let e=await this.client.getNFTCollectionId(),[n,r]=await Promise.all([this.client.getStaking(),this.client.getUniques(t,e)]),i=r.find(a=>a)?.itemId;return{totalStake:n?.total_stake,accumulatedRewardPerStake:n?.accumulated_reward_per_stake,potReservedBalance:n?.pot_reserved_balance,positionId:i,stakePosition:i?await this.getStakingPosition(i):void 0}}getCurrentActionPoints(t,e,n,r){let i=W(0),a=W(0),s=_e.locked6x,o=W(n.toString()).mul(s),l=100,c=[];t.forEach(p=>{let h=_e[p.conviction],b=r.includes(p.id.toString());b&&c.push(p.id.toString());let g=W(p.amount.toString()).mul(l).div(o);i=i.plus(Math.floor(g.mul(h).toNumber())),a=a.plus(Math.floor(g.mul(b?s:h).toNumber()))});let u=Math.floor(W(n.toString()).mul(s).mul(l).div(o).toNumber());r.forEach(p=>{c.includes(p)||(a=a.plus(u))});let d={democracyVote:1};return i=i.mul(d.democracyVote),i=i.plus(e.toString()||"0"),a=a.mul(d.democracyVote),a=a.plus(e.toString()||"0"),{currentActionPoints:i.toString(),maxActionPoints:a.toString()}}async getRewards(t,e,n){let r=await this.getStake(t),{potReservedBalance:i,accumulatedRewardPerStake:a,totalStake:s,stakePosition:o}=r;if(!o)return;let[l,c,u,d,p,h,b]=await Promise.all([this.getPotBalance(),this.client.getPeriodLength(),this.client.getUnclaimablePeriods(),this.client.getTimePointsPerPeriod(),this.client.getTimePointsWeight(),this.client.getActionPointsWeight(),this.client.getSixBlockSince()]),g=W(l.transferable.toString()).minus(i.toString()),f=g.gt(0)&&s>0?io(a.toString(),g.toString(),s.toString()):a.toString(),y=yr(c.toString(),n,b),S=yr(c.toString(),o.createdAt.toString(),b),P=so(f,o.rewardPerStake.toString(),o.stake.toString()),w=this.getCurrentActionPoints(o.votes,o.actionPoints,o.stake,e),T=fr(S,y,d.toString(),p.toString(),w.currentActionPoints,h.toString(),o.accumulatedSlashPoints.toString()),F=Pr(T,Fe,Re),k=(()=>{if(!e.length)return;let Ot=fr(S,y,d.toString(),p.toString(),w.maxActionPoints.toString(),h.toString(),o.accumulatedSlashPoints.toString());return Pr(Ot,Fe,Re)})(),$=W(P).plus(o.accumulatedUnpaidRewards.toString()).plus(o.accumulatedLockedRewards.toString());if(W(y).minus(S).lte(u.toString()))return{rewards:"0",payablePercentage:F,extraPayablePercentage:k,constants:{a:Fe,b:Re}};let K=ao($.toString(),F),H=W(o.accumulatedLockedRewards.toString()),V=H.gt(K)?H:W(K);return{rewards:V.div(dn).toString(),maxRewards:$.div(dn).toString(),allocatedRewardsPercentage:V.div($).mul(100).toNumber(),points:T,payablePercentage:F,extraPayablePercentage:k,constants:{a:Fe,b:Re}}}};var ie=class extends _{async getPalletId(){let t=this.api.constants.Staking.PalletId;return(await t()).asText()}async getPeriodLength(){let t=this.api.constants.Staking.PeriodLength;return await t()}async getUnclaimablePeriods(){let t=this.api.constants.Staking.UnclaimablePeriods;return await t()}async getNFTCollectionId(){let t=this.api.constants.Staking.NFTCollectionId;return await t()}async getStaking(){return await this.api.query.Staking.Staking.getValue()}async getUniques(t,e){return(await this.api.query.Uniques.Account.getEntries(t,e)).map(({keyArgs:a})=>{let[s,o,l]=a;return{address:s,collectionId:o,itemId:l}})}async getStakingPositionsValue(t){return await this.api.query.Staking.Positions.getValue(t)}async getStakingVotes(t){return await this.api.query.Staking.Votes.getValue(t)}async getReferendumInfo(t){return await this.api.query.Referenda.ReferendumInfoFor.getValue(t)}async getTimePointsPerPeriod(){let t=this.api.constants.Staking.TimePointsPerPeriod;return await t()}async getTimePointsWeight(){let t=this.api.constants.Staking.TimePointsWeight;return await t()/1e6}async getActionPointsWeight(){let t=this.api.constants.Staking.ActionPointsWeight;return await t()/1e9}async getSixBlockSince(){return(await this.api.query.Staking.SixSecBlocksSince.getValue()).toString()}};var xr={};I(xr,{TxBuilderFactory:()=>It});import{Enum as vr}from"polkadot-api";function Tr(m){let t=[],e=m;for(;e&&typeof e=="object"&&"type"in e;)t.push(e.type),e=e.value;return t.join(".")}var xt=class extends _{evm;evmClient;balance;aaveUtils;constructor(t,e){super(t),this.evm=e,this.evmClient=e.getWsProvider(),this.balance=new X(t),this.aaveUtils=new nt(e)}wrapTx(t,e){return{name:t,get:()=>e,dryRun:n=>this.dryRun(n,e)}}async dispatchWithExtraGas(t){return this.api.tx.Dispatcher.dispatch_with_extra_gas({call:t.decodedCall,extra_gas:qe})}async dryRun(t,e){let n=vr("Signed",t),r=vr("system",n),a=await this.client.getUnsafeApi().apis.DryRunApi.dry_run_call(r,e.decodedCall),s=a.success&&!a.value.execution_result.success?a.value.execution_result.value.error:null;if(s){let o=Tr(s.value);throw new Error("Dry run execution error!",{cause:o})}return a}isDirectOmnipoolTrade(t){return t.length===1&&t[0].pool==="Omnipool"}};var Ce=class extends xt{_trade;_beneficiary;_slippagePct=1;setTrade(t){return this._trade=t,this}withBeneficiary(t){return this._beneficiary=t,this}withSlippage(t){return this._slippagePct=t,this}get trade(){if(!this._trade)throw new Error("Trade not set. Use setTrade().");return this._trade}get beneficiary(){if(!this._beneficiary)throw new Error("Beneficiary not set. Use withBeneficiary().");return this._beneficiary}get slippagePct(){return this._slippagePct}async build(){let{amountIn:t,swaps:e,type:n}=this.trade;if(n==="Buy")return this.buildBuyTx();let{assetIn:r}=e[0],i=await this.balance.getBalance(this.beneficiary,r);return t>=i.transferable-5n?this.buildSellAllTx():this.buildSellTx()}async buildBuyTx(){let{amountIn:t,amountOut:e,swaps:n}=this.trade,r=n[0],i=n[n.length-1],a=R.getFraction(t,this.slippagePct),s=r.assetIn,o=i.assetOut,l=t+a,c;return this.isDirectOmnipoolTrade(n)?c=this.api.tx.Omnipool.buy({asset_in:s,asset_out:o,amount:e,max_sell_amount:l}):c=this.api.tx.Router.buy({asset_in:s,asset_out:o,amount_out:e,max_amount_in:l,route:G.build(n)}),await this.aaveUtils.hasBorrowPositions(this.beneficiary)&&(c=await this.dispatchWithExtraGas(c)),this.wrapTx("RouterBuy",c)}async buildSellTx(){let{amountIn:t,amountOut:e,swaps:n}=this.trade,r=n[0],i=n[n.length-1],a=R.getFraction(e,this.slippagePct),s=r.assetIn,o=i.assetOut,l=e-a,c;return this.isDirectOmnipoolTrade(n)?c=this.api.tx.Omnipool.sell({asset_in:s,asset_out:o,amount:t,min_buy_amount:l}):c=this.api.tx.Router.sell({asset_in:s,asset_out:o,amount_in:t,min_amount_out:l,route:G.build(n)}),await this.aaveUtils.hasBorrowPositions(this.beneficiary)&&(c=await this.dispatchWithExtraGas(c)),this.wrapTx("RouterSell",c)}async buildSellAllTx(){let{amountOut:t,swaps:e}=this.trade,n=e[0],r=e[e.length-1],i=R.getFraction(t,this.slippagePct),a=n.assetIn,s=r.assetOut,o=t-i,l=this.api.tx.Router.sell_all({asset_in:a,asset_out:s,min_amount_out:o,route:G.build(e)});return await this.aaveUtils.hasBorrowPositions(this.beneficiary)&&(l=await this.dispatchWithExtraGas(l)),this.wrapTx("RouterSellAll",l)}};import{Enum as gn}from"polkadot-api";var Ee=class extends xt{_order;_beneficiary;_maxRetries=3;_slippagePct=1;setOrder(t){return this._order=t,this}withBeneficiary(t){return this._beneficiary=t,this}withMaxRetries(t){return this._maxRetries=t,this}withSlippage(t){return this._slippagePct=t,this}get order(){if(!this._order)throw new Error("Order not set. Use setOrder().");return this._order}get beneficiary(){if(!this._beneficiary)throw new Error("Beneficiary not set. Use withBeneficiary().");return this._beneficiary}get maxRetries(){return this._maxRetries}get slippagePct(){return this._slippagePct}async build(){let{type:t}=this.order;switch(t){case"Dca":return this.buildDcaTx();case"TwapSell":return this.buildTwapSellTx();case"TwapBuy":return this.buildTwapBuyTx();default:throw new Error(`Unsupported TradeOrderType: ${t}`)}}async buildDcaTx(){let{amountIn:t,assetIn:e,assetOut:n,tradeAmountIn:r,tradePeriod:i,tradeRoute:a}=this.order,s=this.api.tx.DCA.schedule({schedule:{owner:this.beneficiary,period:i,max_retries:this.maxRetries,total_amount:t,slippage:this.slippagePct*1e4,stability_threshold:void 0,order:gn("Sell",{asset_in:e,asset_out:n,amount_in:r,min_amount_out:0n,route:a})},start_execution_block:void 0});return await this.aaveUtils.hasBorrowPositions(this.beneficiary)&&(s=await this.dispatchWithExtraGas(s)),this.wrapTx("DcaSchedule",s)}async buildTwapSellTx(){let{amountIn:t,assetIn:e,assetOut:n,tradeAmountIn:r,tradeAmountOut:i,tradePeriod:a,tradeRoute:s}=this.order,o=R.getFraction(i,this.slippagePct),l=i-o,c=this.api.tx.DCA.schedule({schedule:{owner:this.beneficiary,period:a,max_retries:this.maxRetries,total_amount:t,slippage:this.slippagePct*1e4,stability_threshold:void 0,order:gn("Sell",{asset_in:e,asset_out:n,amount_in:r,min_amount_out:l,route:s})},start_execution_block:void 0});return await this.aaveUtils.hasBorrowPositions(this.beneficiary)&&(c=await this.dispatchWithExtraGas(c)),this.wrapTx("DcaSchedule.twapSell",c)}async buildTwapBuyTx(){let{amountIn:t,assetIn:e,assetOut:n,tradeAmountIn:r,tradeAmountOut:i,tradePeriod:a,tradeRoute:s}=this.order,o=R.getFraction(r,this.slippagePct),l=r+o,c=this.api.tx.DCA.schedule({schedule:{owner:this.beneficiary,period:a,max_retries:this.maxRetries,total_amount:t,slippage:this.slippagePct*1e4,stability_threshold:void 0,order:gn("Buy",{asset_in:e,asset_out:n,amount_out:i,max_amount_in:l,route:s})},start_execution_block:void 0});return await this.aaveUtils.hasBorrowPositions(this.beneficiary)&&(c=await this.dispatchWithExtraGas(c)),this.wrapTx("DcaSchedule.twapBuy",c)}};var It=class{client;evmClient;constructor(t,e){this.client=t,this.evmClient=e}trade(t){return new Ce(this.client,this.evmClient).setTrade(t)}order(t){return new Ee(this.client,this.evmClient).setOrder(t)}};async function Ly(m){let t=new mt(m),e=new Mt(m),[n,r]=await Promise.all([t.getBlockTime(),t.getMinOrderBudget()]),i=new St(m,e).withAave().withOmnipool().withStableswap().withXyk(),a=new X(m),s=new ie(m),o=new qt(m),l=new nt(e),c=new tt(i),u=new vt(i,{blockTime:n,minBudgetInNative:r}),d=new re(s,a),p=new Lt(o,a,{blockTime:n});return{api:{aave:l,router:c,scheduler:u,staking:d,farm:p},client:{asset:new st(m),balance:a,evm:e},ctx:{pool:i},tx:new It(m,e),destroy:()=>{i.destroy()}}}export{be as QueryBus,wn as aave,Pn as api,he as async,R as calc,An as client,Tn as const,Ly as createSdkContext,Bn as error,Cn as evm,Gn as farm,v as fmt,Dt as json,L as math,lr as pool,gr as sor,wr as staking,xr as tx};
|
|
1
|
+
var Fr=Object.defineProperty;var A=(m,t)=>{for(var e in t)Fr(m,e,{get:t[e],enumerable:!0})};import Rr from"buffer";typeof window<"u"&&(window.Buffer=Rr.Buffer);var Tn={};A(Tn,{Papi:()=>B,Watcher:()=>Ot,getSm:()=>Zr,getWs:()=>Qr});import{hydration as $r,hydrationNext as Xr}from"@galacticcouncil/descriptors";import{log as Vr}from"@galacticcouncil/common";import{shareReplay as Ur,tap as Wr}from"rxjs";import{defer as Cr,from as Er,of as Pn,timer as kr}from"rxjs";import{catchError as Mr,distinctUntilChanged as Dr,expand as Lr,map as Le,shareReplay as qr,skip as Nr,switchMap as Hr,timeout as Gr}from"rxjs/operators";function Sn(m,{intervalMs:t=5e3,rpcTimeoutMs:e=1e4}={}){let n=()=>Cr(()=>Er(m._request("system_health",[]))).pipe(Gr({first:e}),Le(()=>"online"),Mr(()=>Pn("offline")));return Pn({state:"offline",delayMs:0}).pipe(Lr(a=>kr(a.delayMs).pipe(Hr(n),Le(i=>({state:i,delayMs:t})))),Nr(1),Le(a=>a.state),Dr(),qr({bufferSize:1,refCount:!0}))}var{logger:Yr}=Vr,Ot=class m{static instance=null;bestBlock$;finalizedBlock$;connection$;constructor(t){this.bestBlock$=this.watched("watcher(bestBlock)",t.getUnsafeApi().query.System.Number.watchValue("best")),this.finalizedBlock$=this.watched("watcher(finalizedBlock)",t.finalizedBlock$),this.connection$=this.watched("watcher(connection)",Sn(t))}static getInstance(t){return this.instance||(this.instance=new m(t)),this.instance}watched(t,e){return e.pipe(Wr({error:n=>Yr.error(t,n)}),Ur({bufferSize:1,refCount:!0}))}};var B=class{client;api;apiNext;watcher;constructor(t){this.client=t,this.api=this.client.getTypedApi($r),this.apiNext=this.client.getTypedApi(Xr),this.watcher=Ot.getInstance(this.client)}};import{getWsProvider as zr}from"polkadot-api/ws-provider";import{withLogsRecorder as Kr}from"polkadot-api/logs-provider";import{withLegacy as jr}from"@polkadot-api/legacy-provider";var Qr=(m,t={})=>{let e=typeof m=="string"?m.split(","):m,n=zr(e,{innerEnhancer:jr(),...t});return Kr(r=>console.log(r),n),n};import{getSmProvider as Jr}from"polkadot-api/sm-provider";async function Zr(m){let{start:t}=await import("polkadot-api/smoldot"),{chainSpec:e}=await import("polkadot-api/chains/polkadot"),n=t(),r=await n.addChain({chainSpec:e}),a=await n.addChain({chainSpec:m,potentialRelayChains:[r]});return Jr(a)}var xn={};A(xn,{AAVE_GAS_LIMIT:()=>et,AAVE_LENDING_POOL_ADDRESS:()=>pe,AAVE_POOL_ABI:()=>qe,AAVE_POOL_DATA_PROVIDER:()=>me,AAVE_POOL_DATA_PROVIDER_ABI:()=>ue,AAVE_POOL_PROXY:()=>Ne,AAVE_ROUNDING_THRESHOLD:()=>jo,AAVE_UINT_256_MAX:()=>ta,AaveClient:()=>_t,AaveUtils:()=>Bt,WEIGHT_PER_GAS:()=>He});var qe=[{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 ue=[{inputs:[{internalType:"contract IEACAggregatorProxy",name:"_networkBaseTokenPriceInUsdProxyAggregator",type:"address"},{internalType:"contract IEACAggregatorProxy",name:"_marketReferenceCurrencyPriceInUsdProxyAggregator",type:"address"}],stateMutability:"nonpayable",type:"constructor"},{inputs:[],name:"ETH_CURRENCY_UNIT",outputs:[{internalType:"uint256",name:"",type:"uint256"}],stateMutability:"view",type:"function"},{inputs:[],name:"MKR_ADDRESS",outputs:[{internalType:"address",name:"",type:"address"}],stateMutability:"view",type:"function"},{inputs:[{internalType:"bytes32",name:"_bytes32",type:"bytes32"}],name:"bytes32ToString",outputs:[{internalType:"string",name:"",type:"string"}],stateMutability:"pure",type:"function"},{inputs:[{internalType:"contract IPoolAddressesProvider",name:"provider",type:"address"}],name:"getReservesData",outputs:[{components:[{internalType:"address",name:"underlyingAsset",type:"address"},{internalType:"string",name:"name",type:"string"},{internalType:"string",name:"symbol",type:"string"},{internalType:"uint256",name:"decimals",type:"uint256"},{internalType:"uint256",name:"baseLTVasCollateral",type:"uint256"},{internalType:"uint256",name:"reserveLiquidationThreshold",type:"uint256"},{internalType:"uint256",name:"reserveLiquidationBonus",type:"uint256"},{internalType:"uint256",name:"reserveFactor",type:"uint256"},{internalType:"bool",name:"usageAsCollateralEnabled",type:"bool"},{internalType:"bool",name:"borrowingEnabled",type:"bool"},{internalType:"bool",name:"stableBorrowRateEnabled",type:"bool"},{internalType:"bool",name:"isActive",type:"bool"},{internalType:"bool",name:"isFrozen",type:"bool"},{internalType:"uint128",name:"liquidityIndex",type:"uint128"},{internalType:"uint128",name:"variableBorrowIndex",type:"uint128"},{internalType:"uint128",name:"liquidityRate",type:"uint128"},{internalType:"uint128",name:"variableBorrowRate",type:"uint128"},{internalType:"uint128",name:"stableBorrowRate",type:"uint128"},{internalType:"uint40",name:"lastUpdateTimestamp",type:"uint40"},{internalType:"address",name:"aTokenAddress",type:"address"},{internalType:"address",name:"stableDebtTokenAddress",type:"address"},{internalType:"address",name:"variableDebtTokenAddress",type:"address"},{internalType:"address",name:"interestRateStrategyAddress",type:"address"},{internalType:"uint256",name:"availableLiquidity",type:"uint256"},{internalType:"uint256",name:"totalPrincipalStableDebt",type:"uint256"},{internalType:"uint256",name:"averageStableRate",type:"uint256"},{internalType:"uint256",name:"stableDebtLastUpdateTimestamp",type:"uint256"},{internalType:"uint256",name:"totalScaledVariableDebt",type:"uint256"},{internalType:"uint256",name:"priceInMarketReferenceCurrency",type:"uint256"},{internalType:"address",name:"priceOracle",type:"address"},{internalType:"uint256",name:"variableRateSlope1",type:"uint256"},{internalType:"uint256",name:"variableRateSlope2",type:"uint256"},{internalType:"uint256",name:"stableRateSlope1",type:"uint256"},{internalType:"uint256",name:"stableRateSlope2",type:"uint256"},{internalType:"uint256",name:"baseStableBorrowRate",type:"uint256"},{internalType:"uint256",name:"baseVariableBorrowRate",type:"uint256"},{internalType:"uint256",name:"optimalUsageRatio",type:"uint256"},{internalType:"bool",name:"isPaused",type:"bool"},{internalType:"bool",name:"isSiloedBorrowing",type:"bool"},{internalType:"uint128",name:"accruedToTreasury",type:"uint128"},{internalType:"uint128",name:"unbacked",type:"uint128"},{internalType:"uint128",name:"isolationModeTotalDebt",type:"uint128"},{internalType:"bool",name:"flashLoanEnabled",type:"bool"},{internalType:"uint256",name:"debtCeiling",type:"uint256"},{internalType:"uint256",name:"debtCeilingDecimals",type:"uint256"},{internalType:"uint8",name:"eModeCategoryId",type:"uint8"},{internalType:"uint256",name:"borrowCap",type:"uint256"},{internalType:"uint256",name:"supplyCap",type:"uint256"},{internalType:"uint16",name:"eModeLtv",type:"uint16"},{internalType:"uint16",name:"eModeLiquidationThreshold",type:"uint16"},{internalType:"uint16",name:"eModeLiquidationBonus",type:"uint16"},{internalType:"address",name:"eModePriceSource",type:"address"},{internalType:"string",name:"eModeLabel",type:"string"},{internalType:"bool",name:"borrowableInIsolation",type:"bool"}],internalType:"struct IUiPoolDataProviderV3.AggregatedReserveData[]",name:"",type:"tuple[]"},{components:[{internalType:"uint256",name:"marketReferenceCurrencyUnit",type:"uint256"},{internalType:"int256",name:"marketReferenceCurrencyPriceInUsd",type:"int256"},{internalType:"int256",name:"networkBaseTokenPriceInUsd",type:"int256"},{internalType:"uint8",name:"networkBaseTokenPriceDecimals",type:"uint8"}],internalType:"struct IUiPoolDataProviderV3.BaseCurrencyInfo",name:"",type:"tuple"}],stateMutability:"view",type:"function"},{inputs:[{internalType:"contract IPoolAddressesProvider",name:"provider",type:"address"}],name:"getReservesList",outputs:[{internalType:"address[]",name:"",type:"address[]"}],stateMutability:"view",type:"function"},{inputs:[{internalType:"contract IPoolAddressesProvider",name:"provider",type:"address"},{internalType:"address",name:"user",type:"address"}],name:"getUserReservesData",outputs:[{components:[{internalType:"address",name:"underlyingAsset",type:"address"},{internalType:"uint256",name:"scaledATokenBalance",type:"uint256"},{internalType:"bool",name:"usageAsCollateralEnabledOnUser",type:"bool"},{internalType:"uint256",name:"stableBorrowRate",type:"uint256"},{internalType:"uint256",name:"scaledVariableDebt",type:"uint256"},{internalType:"uint256",name:"principalStableDebt",type:"uint256"},{internalType:"uint256",name:"stableBorrowLastUpdateTimestamp",type:"uint256"}],internalType:"struct IUiPoolDataProviderV3.UserReserveData[]",name:"",type:"tuple[]"},{internalType:"uint8",name:"",type:"uint8"}],stateMutability:"view",type:"function"},{inputs:[],name:"marketReferenceCurrencyPriceInUsdProxyAggregator",outputs:[{internalType:"contract IEACAggregatorProxy",name:"",type:"address"}],stateMutability:"view",type:"function"},{inputs:[],name:"networkBaseTokenPriceInUsdProxyAggregator",outputs:[{internalType:"contract IEACAggregatorProxy",name:"",type:"address"}],stateMutability:"view",type:"function"}];var Ne="0x1b02E051683b5cfaC5929C25E84adb26ECf87B38",me="0x112b087b60C1a166130d59266363C45F8aa99db0",pe="0xf3Ba4D1b50f78301BDD7EAEa9B67822A15FCA691",et=1000000n,He=25000n,jo=5,ta=BigInt("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");var _t=class{client;constructor(t){this.client=t.getWsProvider()}async getBlockTimestamp(){let t=await this.client.getBlock();return Number(t.timestamp)}async getReservesData(){return await this.client.readContract({abi:ue,address:me,args:[pe],functionName:"getReservesData"})}async getUserReservesData(t){return await this.client.readContract({abi:ue,address:me,args:[pe,t],functionName:"getUserReservesData"})}async getUserAccountData(t){return await this.client.readContract({abi:qe,address:Ne,args:[t],functionName:"getUserAccountData"})}};import E from"big.js";import{big as nt,erc20 as ea,h160 as na}from"@galacticcouncil/common";var{ERC20:it}=ea,{H160:Ge}=na,ra=1.01,aa=31536000n,wn=4,de=-1,ge=10n**27n,Bt=class{client;constructor(t){this.client=new _t(t)}async getSummary(t){let e=Ge.fromAny(t),[n,r,a,i]=await Promise.all([this.client.getReservesData(),this.client.getUserReservesData(e),this.client.getUserAccountData(e),this.client.getBlockTimestamp()]),[s]=n,[o,l]=r,[c,u,d,p,h,b]=a,g=nt.toDecimal(b,18),f=[];for(let y of o){let S=y.underlyingAsset.toLowerCase(),P=s.find(({underlyingAsset:De})=>De.toLowerCase()===S);if(!P)throw new Error("Missing pool reserve for "+S);let T=y.scaledATokenBalance,w=P.liquidityIndex,F=P.liquidityRate,k=P.availableLiquidity,$=P.priceInMarketReferenceCurrency,K=i+6,H=this.calculateLinearInterest(F,P.lastUpdateTimestamp,K),V=w*H/ge,At=T*V/ge,oe=Number(l!==0&&l===P.eModeCategoryId?P.eModeLiquidationThreshold:P.reserveLiquidationThreshold)/1e4,le=P.usageAsCollateralEnabled&&y.usageAsCollateralEnabledOnUser&&y.scaledATokenBalance>0n,ce=it.toAssetId(S);f.push({aTokenBalance:At,availableLiquidity:k,decimals:Number(P.decimals),isCollateral:le,priceInRef:$,reserveId:ce,reserveAsset:S,reserveLiquidationThreshold:oe})}return{healthFactor:Number(g),currentLiquidationThreshold:Number(nt.toDecimal(p,wn)),totalCollateral:c,totalDebt:u,reserves:f}}async hasBorrowPositions(t){let e=Ge.fromAny(t),n=await this.client.getUserAccountData(e),[r,a]=n;return a>0n}async getHealthFactor(t){let e=Ge.fromAny(t),n=await this.client.getUserAccountData(e),[r,a,i,s,o,l]=n;return this.calculateHealthFactorFromBalances(a,r,s)}async getHealthFactorAfterWithdraw(t,e,n){let{totalCollateral:r,totalDebt:a,reserves:i,currentLiquidationThreshold:s}=await this.getSummary(t);if(a===0n)return de;let o=it.fromAssetId(e),l=i.find(S=>S.reserveAsset===o);if(!l)throw new Error("Missing reserve ctx for "+o);let{decimals:c,isCollateral:u,priceInRef:d,reserveLiquidationThreshold:p}=l,h=nt.toBigInt(n,c),b=u?h*d/10n**BigInt(c):0n,g=r-b;if(g<=0n)return 0;let f=E(r.toString()).mul(s).minus(E(b.toString()).mul(p)).div(g.toString()),y=E(g.toString()).mul(f).div(a.toString()).toFixed(6,E.roundDown);return Number(y)}async getHealthFactorAfterSupply(t,e,n){let{totalCollateral:r,totalDebt:a,reserves:i,currentLiquidationThreshold:s}=await this.getSummary(t);if(a===0n)return de;let o=it.fromAssetId(e),l=i.find(y=>y.reserveAsset===o);if(!l)throw new Error("Missing reserve ctx for "+o);let{decimals:c,priceInRef:u,reserveLiquidationThreshold:d}=l,h=nt.toBigInt(n,c)*u/10n**BigInt(c),b=r+h;if(b<=0n)return 0;let g=E(r.toString()).mul(s).plus(E(h.toString()).mul(d)).div(b.toString()),f=E(b.toString()).mul(g).div(a.toString()).toFixed(6,E.roundDown);return Number(f)}async getHealthFactorAfterSwap(t,e,n,r,a){let{totalDebt:i,reserves:s,healthFactor:o}=await this.getSummary(t);if(i===0n)return de;let l=it.fromAssetId(n),c=it.fromAssetId(a),u=s.find(w=>w.reserveAsset===l),d=s.find(w=>w.reserveAsset===c);if(!u)throw new Error(`Missing reserve ctx for ${l}`);if(!d)throw new Error(`Missing reserve ctx for ${d}`);let p=nt.toBigInt(e,u.decimals),h=nt.toBigInt(r,d.decimals),b=p*u.priceInRef/10n**BigInt(u.decimals),g=h*d.priceInRef/10n**BigInt(d.decimals),f=u.isCollateral?E(b.toString()).mul(u.reserveLiquidationThreshold):E(0),P=E(g.toString()).mul(d.reserveLiquidationThreshold).minus(f).div(i.toString()),T=E(o).plus(P).toFixed(6,E.roundDown);return Number(T)}async getMaxWithdraw(t,e){let{totalDebt:n,reserves:r,healthFactor:a}=await this.getSummary(t),i=it.fromAssetId(e),s=r.find(o=>o.reserveAsset===i);if(!s)throw new Error("Missing reserve ctx for "+i);return this.calculateWithdrawMax(s,n,a)}async getMaxWithdrawAll(t){let{totalDebt:e,reserves:n,healthFactor:r}=await this.getSummary(t),a={};for(let i of n){let s=this.calculateWithdrawMax(i,e,r);i.reserveId&&(a[i.reserveId]=s)}return a}calculateWithdrawMax(t,e,n){let{aTokenBalance:r,availableLiquidity:a,decimals:i,priceInRef:s,reserveLiquidationThreshold:o,isCollateral:l}=t,c=r;if(l&&e>0n){let d=n-ra;if(d>0){let p=E(d).mul(e.toString()).div(o).toFixed(0,E.roundDown),h=E(p).div(s.toString()).mul(10**i).toFixed(0,E.roundDown);c=r<BigInt(h)?r:BigInt(h)}else c=0n}return{amount:c<a?c:a,decimals:i}}calculateLinearInterest(t,e,n){let r=n-e;if(r<=0)return ge;let a=t*BigInt(r)/aa;return ge+a}calculateHealthFactorFromBalances(t,e,n){if(t===0n)return de;let r=e*n/t,a=nt.toDecimal(r,wn);return Number(a)}};var Bn={};A(Bn,{AssetClient:()=>st,BalanceClient:()=>X,ChainParams:()=>mt});var st=class extends B{SUPPORTED_TYPES=["StableSwap","Bond","Token","External","Erc20"];constructor(t){super(t)}async queryShares(){let e=await this.api.query.Stableswap.Pools.getEntries();return new Map(e.map(({keyArgs:n,value:r})=>{let[a]=n;return[a,r]}))}async queryBonds(){let e=await this.api.query.Bonds.Bonds.getEntries();return new Map(e.map(({keyArgs:n,value:r})=>{let[a]=n;return[a,r]}))}async queryAssets(){let e=await this.api.query.AssetRegistry.Assets.getEntries();return new Map(e.filter(({value:n})=>{let{asset_type:r}=n;return this.SUPPORTED_TYPES.includes(r.type)}).map(({keyArgs:n,value:r})=>{let[a]=n;return[a,r]}))}async queryAssetLocations(){let e=await this.api.query.AssetRegistry.AssetLocations.getEntries();return new Map(e.map(({keyArgs:n,value:r})=>{let[a]=n;return[a,r]}))}async mapToken(t,e,n,r){let{name:a,asset_type:i,is_sufficient:s,existential_deposit:o}=e,{symbol:l,decimals:c}=n.get(t)??{};return{id:t,name:a?.asText(),symbol:l,decimals:c,icon:l,type:i.type,isSufficient:s,location:r,existentialDeposit:o}}async mapBond(t,e,n,r){let[a,i]=r,{asset_type:s,is_sufficient:o,existential_deposit:l}=e,{symbol:c,decimals:u}=await this.mapToken(a,e,n),d=Number(i),p=new Intl.DateTimeFormat("en-GB"),h=[c,"Bond",p.format(d)].join(" ");return{id:t,name:h,symbol:c+"b",decimals:u,icon:c,type:s.type,isSufficient:o,existentialDeposit:l,underlyingAssetId:a,maturity:d}}async mapShares(t,e,n,r){let{assets:a}=r,{name:i,symbol:s,asset_type:o,is_sufficient:l,existential_deposit:c}=e,u=await Promise.all(a.map(async h=>{let{symbol:b}=await this.mapToken(h,e,n);return[h,b]})),d=Object.fromEntries(u),p=Object.values(d);return{id:t,name:p.join(", "),symbol:s?.asText()||i?.asText(),decimals:18,icon:p.join("/"),type:o.type,isSufficient:l,existentialDeposit:c,meta:d}}async mapExternal(t,e,n,r){let a=await this.mapToken(t,e,new Map,r),i=n?.find(s=>s.internalId===a.id);return i?{...a,decimals:i.decimals,name:i.name,symbol:i.symbol,icon:i.symbol,isWhiteListed:i.isWhiteListed}:a}parseMetadata(t){return new Map(Array.from(t,([e,n])=>[e,{symbol:n.symbol?.asText(),decimals:n.decimals}]))}async getSupported(t,e){let[n,r,a,i]=await Promise.all([this.queryAssets(),this.queryAssetLocations(),this.queryShares(),this.queryBonds()]),s=this.parseMetadata(n),o=[];for(let[l,c]of Array.from(n)){let u=r.get(l),{asset_type:d}=c,p;switch(d.type){case"Bond":let h=i.get(l);p=await this.mapBond(l,c,s,h);break;case"StableSwap":let b=a.get(l);p=await this.mapShares(l,c,s,b);break;case"External":p=await this.mapExternal(l,c,e,u);break;default:p=await this.mapToken(l,c,s,u)}o.push(p)}return t?o:o.filter(l=>this.isValidAsset(l))}isValidAsset(t){let e=Math.sign(t.decimals);return!!t.symbol&&(e===0||e===1)}};import{log as oa}from"@galacticcouncil/common";import{combineLatest as la,concat as ca,defer as Rt,from as In}from"rxjs";import{bufferCount as ua,distinctUntilChanged as An,debounceTime as ma,map as ct,pairwise as pa,retry as da,startWith as On,switchMap as _n,tap as Ct,take as ga,skip as ha,connect as ba}from"rxjs/operators";var vn={};A(vn,{HUB_ASSET_ID:()=>Ft,HYDRATION_OMNIPOOL_ADDRESS:()=>sa,HYDRATION_PARACHAIN_ID:()=>ia,PERBILL_DENOMINATOR:()=>Ve,PERMILL_DENOMINATOR:()=>ot,SYSTEM_ASSET_DECIMALS:()=>he,SYSTEM_ASSET_ID:()=>O,TRADEABLE_DEFAULT:()=>lt});var ot=1e6,Ve=1e9,O=0,he=12,ia=2034,sa="7L53bUTBbfuj14UpdCNPwmgzzHSsrsTWBHX5pys32mVWM3C1",Ft=1,lt=15;var{logger:ut}=oa,X=class extends B{constructor(t){super(t)}async getBalance(t,e){return e===0?this.getSystemBalance(t):this.getBalanceData(t,e)}async getSystemBalance(t){let e=this.api.query.System.Account,{data:n}=await e.getValue(t,{at:"best"});return this.getBreakdown(n)}async getTokenBalance(t,e){let r=await this.api.query.Tokens.Accounts.getValue(t,e,{at:"best"});return this.getBreakdown(r)}async getErc20Balance(t,e){return this.getBalanceData(t,e)}watchBalance(t){return Rt(()=>{let e=this.watchSystemBalance(t),n=this.watchTokensBalance(t),r=this.watchErc20Balance(t);return la([e,n,r]).pipe(ba(a=>ca(a.pipe(ga(1)),a.pipe(ha(1),ma(250)))))}).pipe(ct(e=>e.flat()),On([]),ua(2,1),ct(([e,n],r)=>r===0?n:this.getDeltas(e,n))).pipe(Ct({subscribe:()=>ut.debug("balance: subscribe",t),error:e=>ut.error("balance",e)}),da({delay:1e3}))}watchSystemBalance(t){let e=this.api.query.System.Account;return Rt(()=>e.watchValue(t,"best")).pipe(ct(n=>({id:0,balance:this.getBreakdown(n.data)})),Ct({error:n=>ut.error("balance(system)",n)}))}watchTokenBalance(t,e){let n=this.api.query.Tokens.Accounts;return Rt(()=>n.watchValue(t,e,"best")).pipe(ct(r=>({id:e,balance:this.getBreakdown(r)})),Ct({error:r=>ut.error("balance(token)",r)}))}watchTokensBalance(t){let e=this.api.query.Tokens.Accounts;return Rt(()=>e.watchEntries(t,{at:"best"})).pipe(An((n,r)=>!r.deltas),ct(({deltas:n})=>{let r=[];return n?.deleted.forEach(a=>{let[i,s]=a.args;r.push({id:s,balance:this.getBreakdown({free:0n,reserved:0n,frozen:0n})})}),n?.upserted.forEach(a=>{let[i,s]=a.args;r.push({id:s,balance:this.getBreakdown(a.value)})}),r}),Ct({error:n=>ut.error("balance(tokens)",n)}))}watchErc20Balance(t,e){let n=async()=>(await this.api.query.AssetRegistry.Assets.getEntries({at:"best"})).filter(({value:i})=>i.asset_type.type==="Erc20").map(({keyArgs:i})=>{let[s]=i;return s}),r=async a=>(await Promise.all(a.map(async s=>[s,await this.getBalanceData(t,s)]))).map(([s,o])=>({id:s,balance:o}));return Rt(()=>In(e?Promise.resolve(e):n()).pipe(_n(a=>this.watcher.bestBlock$.pipe(On(null),_n(()=>In(r(a))))),pa(),ct(([a,i],s)=>s===0?i.filter(o=>o.balance.total>0n):this.getDeltas(a,i)),An((a,i)=>i.length===0),Ct({error:a=>ut.error("balance(erc20)",a)})))}async getBalanceData(t,e){let n=await this.api.apis.CurrenciesApi.account(e,t,{at:"best"});return this.getBreakdown(n)}getBreakdown(t){let e=t.free>=t.frozen?t.free-t.frozen:0n,n=t.free+t.reserved;return{free:t.free,reserved:t.reserved,frozen:t.frozen,total:n,transferable:e}}getDeltas(t,e){let n=(a,i)=>a!==void 0&&i!==void 0&&a.transferable===i.transferable&&a.total===i.total,r=t.reduce((a,i)=>(a.set(i.id,i.balance),a),new Map);return e.filter(a=>!n(a.balance,r.get(a.id)))}};var mt=class extends B{_minOrderBudget;_blockTime;constructor(t){super(t)}async getBlockTime(){if(this._blockTime===void 0){let t=await this.api.constants.Aura.SlotDuration();this._blockTime=Number(t)}return this._blockTime}async getMinOrderBudget(){return this._minOrderBudget===void 0&&(this._minOrderBudget=await this.api.constants.DCA.MinBudgetInNativeCurrency()),this._minOrderBudget}};var Fn={};A(Fn,{AssetNotFound:()=>Ue,PoolNotFound:()=>Et,RouteNotFound:()=>kt});var Ue=class extends Error{constructor(t){super(),this.message=`${t} not found`,this.name="AssetNotFound"}},Et=class extends Error{constructor(t){super(),this.message=`${t} pool invalid`,this.name="PoolNotFound"}},kt=class extends Error{constructor(t,e){super(),this.message=`Route from ${t} to ${e} not found in current configuration`,this.name="RouteNotFound"}};var kn={};A(kn,{EvmClient:()=>Dt,EvmRpcAdapter:()=>Mt,createChain:()=>We});import{Binary as ya,FixedSizeBinary as Rn}from"polkadot-api";import{hydration as fa}from"@galacticcouncil/descriptors";import{encodeFunctionData as Pa,decodeFunctionResult as Sa}from"viem";var Ta=10000000n,Mt=class{api;constructor(t){this.api=t.getTypedApi(fa)}async getBlock(){let t=await this.api.query.Ethereum.CurrentBlock.getValue({at:"best"}),{header:e}=t,n=e.timestamp/1000n,[r]=e.number;return{timestamp:n,number:r}}readContract=(async t=>{let{abi:e,address:n,functionName:r,args:a}=t,i=Pa({abi:e,functionName:r,args:a}),s=await this.api.apis.EthereumRuntimeRPCApi.call(Rn.fromText(""),Rn.fromHex(n),ya.fromHex(i),[0n,0n,0n,0n],[Ta,0n,0n,0n],void 0,void 0,void 0,!1,[],[]);if(!s.success)throw console.error(r,s.value.type),new Error("Contract read failure");let{exit_reason:o,value:l,used_gas:c}=s.value;if(console.log(c),o.type==="Succeed")return Sa({abi:e,functionName:r,data:l.asHex()});throw console.log(r,o.type,o.value.type),new Error("Contract read error")})};import{defineChain as wa}from"viem";var xa=["https://hydration-rpc.n.dwellir.com","https://hydration.dotters.network","https://rpc.helikon.io/hydradx","https://hydration.ibp.network","https://rpc.cay.hydration.cloud","https://rpc.parm.hydration.cloud","https://rpc.roach.hydration.cloud","https://rpc.zipp.hydration.cloud","https://rpc.sin.hydration.cloud","https://rpc.coke.hydration.cloud"],We=()=>wa({id:222222,name:"Hydration",network:"hydration",nativeCurrency:{decimals:18,name:"WETH",symbol:"WETH"},rpcUrls:{default:{http:xa}},blockExplorers:{default:{name:"Hydration Explorer",url:"https://hydration.subscan.io"}},testnet:!1});import{createPublicClient as Cn,createWalletClient as va,custom as En,http as Ia}from"viem";var Dt=class{client;chain;constructor(t){this.client=t,this.chain=We()}get chainId(){return this.chain.id}get chainCurrency(){return this.chain.nativeCurrency.symbol}get chainDecimals(){return this.chain.nativeCurrency.decimals}getProvider(){return Cn({chain:this.chain,transport:Ia()})}getWsProvider(){return Cn({transport:En({request:({method:t,params:e})=>this.client._request(t,e||[])})})}getSigner(t){return va({account:t,chain:this.chain,transport:En(window.ethereum)})}getRPCAdapter(){return new Mt(this.client)}};var Un={};A(Un,{LiquidityMiningApi:()=>qt,LiquidityMiningClient:()=>Nt});import{AccountId as Wa}from"polkadot-api";import q from"big.js";import{HYDRATION_SS58_PREFIX as Ya,RUNTIME_DECIMALS as pt}from"@galacticcouncil/common";import{fixed_from_rational as Vn}from"@galacticcouncil/math-liquidity-mining";var be={};A(be,{withTimeout:()=>Aa});function Aa(m,t,e="timeout"){return new Promise((n,r)=>{let a=setTimeout(()=>r(new Error(e)),t);m.then(i=>{clearTimeout(a),n(i)},i=>{clearTimeout(a),r(i)})})}var R={};A(R,{divSpot:()=>_a,getFraction:()=>Ba,mulScaled:()=>Dn,mulSpot:()=>Oa});import{RUNTIME_DECIMALS as Mn}from"@galacticcouncil/common";function Dn(m,t,e,n,r){let a=e+n-r,i=m*t;return a>0?i/BigInt(10)**BigInt(a):a<0?i*BigInt(10)**BigInt(-a):i}function Oa(m,t,e,n){return Dn(m,t,e,Mn,n)}function _a(m,t,e,n){if(t===0n)return 0n;let r=BigInt(10)**BigInt(Mn+n-e);return m*r/t}function Ba(m,t,e=2){if(t<.01||t>100)throw new Error("Supported range is from 0.01% - 100%");let n=BigInt(10)**BigInt(e),r=BigInt(Math.round(t*Number(n)));return m*r/(BigInt(100)*n)}var x={};A(x,{FeeUtils:()=>Ye,shiftNeg:()=>Ra});import Fa from"big.js";var Ye=class m{static toPct(t){let[e,n]=t;return m.safeDivide(e*100,n)}static toRaw(t){let[e,n]=t;return m.safeDivide(e,n)}static fromPermill(t){return[t,1e6]}static fromPerbill(t){return[t,1e9]}static fromRate(t,e){return[t,e]}static safeDivide(t,e,n=12){let r=10**n;return Math.round(t*r/e)/r}static safeRound(t){return parseFloat(t.toPrecision(15))}};function Ra(m,t){let e=Fa(typeof m=="bigint"?m.toString():m);return t===0?e.toString():e.div(Math.pow(10,t)).toString()}var Lt={};A(Lt,{findNestedKey:()=>Ca,findNestedObj:()=>Ea,jsonFormatter:()=>ka});var Ca=(m,t)=>{let e=[];return JSON.stringify(m,(n,r)=>(r&&r[t]&&e.push(r),r)),e[0]},Ea=(m,t,e)=>{let n;return JSON.stringify(m,(r,a)=>(a&&a[t]===e&&(n=a),a)),n},ka=(m,t)=>typeof t=="bigint"?t.toString():t;var L={};A(L,{calculateBuyFee:()=>qa,calculateDiffToAvg:()=>Ma,calculateDiffToRef:()=>Da,calculateSellFee:()=>La});import j from"big.js";function Ma(m,t){let e=j(m.toString()),n=j(t.toString());return e.minus(n).abs().div(e.plus(n).div(2)).mul(100).round(2).toNumber()}function Da(m,t){if(t===0n)return 0;let e=j(m.toString()),n=j(t.toString());return e.minus(n).div(n).mul(100).round(2).toNumber()}function La(m,t){if(m===0n)return 0;let e=j(m.toString()),n=j(t.toString());return j(1).minus(n.div(e)).mul(100).round(2).toNumber()}function qa(m,t){if(m===0n)return 0;let e=j(m.toString());return j(t.toString()).div(e).minus(1).mul(100).round(2).toNumber()}import{TLRUCache as Ln}from"@thi.ng/cache";var ye=class{debug;constructor(t){this.debug=t||!1}log(t,e,n){this.debug&&console.log(t,e,n)}scope(t,e,n,r){let a=new Map,i=r!==void 0?new Ln(null,{ttl:r}):new Ln;return{get:(...c)=>{let u=n(...c);if(a.has(u)){this.log("[live]",t,u);let p=a.get(u);return Promise.resolve(p)}if(i.has(u))return this.log("[memo]",t,u),i.get(u);this.log("[fetch]",t,u);let d=e(...c).catch(p=>{throw i.delete(u),p});return i.set(u,d),d},set:(c,...u)=>{let d=n(...u);this.log("[set-live]",t,d),a.set(d,c)},clear:()=>{this.log("[clear]",t),a.clear(),i.release()}}}};var fe=class{result=new Map;getKey(t,e){return[e,t.toString()].join(",")}constructor(t,e){for(let n=0;n<t.length;++n){let[r,a]=t[n];this.result.set(this.getKey(a,r),e[n].free)}}freeBalance(t,e){return this.result.get(this.getKey(t,e))??0n}transfer(t,e,n,r){let a=this.getKey(t,e),i=this.getKey(t,n),s=this.result.get(a)??0n,o=this.result.get(i)??0n;if(s<r)throw new Error("Attempting to transfer more than is present");this.result.set(a,s+r),this.result.set(i,o+r)}};import rt from"big.js";import{calculate_accumulated_rps as Na,calculate_global_farm_rewards as Ha,calculate_loyalty_multiplier as Ga,calculate_user_reward as Gn,calculate_yield_farm_delta_rpvs as Va}from"@galacticcouncil/math-liquidity-mining";import qn from"big.js";var $e=qn(10).pow(18),Nn=BigInt(qn(1).pow(18).toString()),Hn=6e3;var Ua="1000000000000000000",Pe=class{constructor(t,e,n){this.getAccount=t;this.getAsset=e;this.multiCurrency=n}async syncGlobalFarm(t,e,n){if(t.state.type!=="Active"||t.updated_at===e)return null;if(t.total_shares_z===0n)return t;let r=await this.getAsset(t.reward_currency),a=e-t.updated_at,i=this.getAccount(t.id),s=r?.existential_deposit;if(!s)throw new Error("Missing reward currency asset list");let o=this.multiCurrency.freeBalance(t.reward_currency,i),l=rt(s.toString()),c=rt(o.toString()).minus(l.lt(o.toString())?s.toString():o.toString()),u=rt(Ha(t.total_shares_z.toString(),n.toString(),rt(t.yield_per_period.toString()).mul($e).round(0,rt.roundDown).toFixed(),t.max_reward_per_period.toString(),a.toFixed()));if(c.lt(u)&&(u=c),u.eq(0))return t;let d=this.getAccount(0);return this.multiCurrency.transfer(t.reward_currency,i,d,BigInt(u.toFixed())),{...t,accumulated_rpz:BigInt(Na(t.accumulated_rpz.toString(),t.total_shares_z.toString(),u.toFixed()))}}syncYieldFarm(t,e,n){if(t.state.type!=="Active"||t.updated_at===n)return null;if(t.total_valued_shares===0n)return{...t,updated_at:n};let r=Va(t.accumulated_rpz.toString(),e.accumulated_rpz.toString(),t.multiplier.toString(),t.total_valued_shares.toString());return{...t,accumulated_rpvs:t.accumulated_rpvs+BigInt(r),updated_at:n}}getLoyaltyMultiplier(t,e){let n=rt(1).mul($e).round(0,rt.roundDown).toString();if(!e)return n;let{initial_reward_percentage:r,scale_coef:a}=e;return Ga(t.toFixed(),r.toString(),a.toFixed())}async claimRewards(t,e,n,r,a){if(e.state.type==="Terminated")return null;let i=Math.floor(r/t.blocks_per_period);if(n.updated_at===i)return null;let s=await this.syncGlobalFarm(t,i,a);if(!s)return null;let o=this.syncYieldFarm(e,s,i);if(!o)return null;let l=o.total_stopped-n.stopped_at_creation,c=o.updated_at-n.entered_at-l,u=this.getLoyaltyMultiplier(c,o.loyalty_curve),d=BigInt(Gn(n.accumulated_rpvs.toString(),n.valued_shares.toString(),n.accumulated_claimed_rewards.toString(),o.accumulated_rpvs.toString(),u)),p=BigInt(Gn(n.accumulated_rpvs.toString(),n.valued_shares.toString(),n.accumulated_claimed_rewards.toString(),o.accumulated_rpvs.toString(),Ua));return{reward:d,maxReward:p,assetId:s.reward_currency,yieldFarmId:o.id,isActiveFarm:o.state.type==="Active"}}};var $a=q(365.2425).times(24).times(60).times(60),qt=class{balance;client;options;constructor(t,e,n={}){this.client=t,this.balance=e,this.options=Object.freeze({blockTime:n.blockTime??Hn})}get blockTime(){return this.options.blockTime}async getOraclePrice(t,e){let n=[t,e].sort((a,i)=>a-i);if(t===e)return Nn;let r=await this.client.getOraclePrice(n);if(r){let{n:a,d:i}=r[0].price,s;return t<e?s=Vn(a.toString(),i.toString()):s=Vn(i.toString(),a.toString()),BigInt(s)}}getFarmAddress=(t,e)=>{let n=Buffer.from("modl","utf-8"),r=Buffer.from(e?"78796b4c4d704944":"4f6d6e6957684c4d","hex"),a=Buffer.from([t]),i=Buffer.concat([n,r,a]),o="0x"+Buffer.concat([i,Buffer.alloc(32-i.length)]).toString("hex");return Wa(Ya).dec(o)};getGlobalRewardPerPeriod(t,e,n,r){let a=q(r).times(t.toString()).times(e.toString()).div(Math.pow(10,pt));return a.gte(n.toString())?n.toString():a.toString()}getPoolYieldPerPeriod(t,e,n,r){let a=q(t.toString()).times(e),i=q(n.toString()).times(r);return a.div(i.toString()).toString()}farmData(t,e,n){let{yieldFarm:r,globalFarm:a,priceAdjustment:i,balance:s,id:o}=t,{multiplier:l,loyalty_curve:c}=r,{blocks_per_period:u,yield_per_period:d,total_shares_z:p,max_reward_per_period:h,pending_rewards:b,accumulated_paid_rewards:g,planned_yielding_periods:f,updated_at:y,incentivized_asset:S,reward_currency:P,price_adjustment:T,min_deposit:w}=a,F=x.shiftNeg(i??T,pt),k=x.shiftNeg(l,pt),$=x.shiftNeg(c?.initial_reward_percentage??0,pt),K=$a.div(q(this.blockTime).div(1e3).times(u)).toString(),H;if(p<=0)H=q(k).times(d.toString()).times(K).div(Math.pow(10,pt)).toString();else{let _r=this.getGlobalRewardPerPeriod(p,d,h,F),Br=this.getPoolYieldPerPeriod(_r,k,p,F);H=q(Br).times(K).toString()}let V=b+g,At=h*BigInt(f),se=s.transferable+V,yn=se-V,oe=q(yn.toString()).div(h.toString()),le=q(e).div(u.toString()).toString(),ce=(p>=0?oe.plus(y):oe.plus(le)).toString(),De=q(ce).times(u).toString(),Ar=q(p.toString()).div(q(h.toString()).div(d.toString())).div(Math.pow(10,pt)).times(100).times(F).toFixed(2),fn=q(V.toString()).div(se.toString()).gte(.999);H=fn?"0":q(H).div(n?2:1).times(100).toString();let Or=$?q(H).times($).toString():void 0;return{apr:H,minApr:Or,isDistributed:fn,estimatedEndPeriod:ce,estimatedEndBlock:De,maxRewards:At,incentivizedAsset:S,rewardCurrency:P,loyaltyCurve:c,currentPeriod:le,potMaxRewards:se,fullness:Ar,yieldFarmId:r.id,globalFarmId:a.id,poolId:o,distributedRewards:V,plannedYieldingPeriods:f,minDeposit:w,blocksPerPeriod:u}}async getAllOmnipoolFarms(){let e=(await this.client.getAllOmnipooFarms()).reduce((r,a)=>r.includes(a.keyArgs[0].toString())?r:[...r,a.keyArgs[0].toString()],[]),n=await Promise.all(e.map(async r=>{let a=await this.getOmnipoolFarms(r);if(a)return[r,a]}));return Object.fromEntries(n.filter(r=>!!r))}async getOmnipoolFarms(t){let e=await this.client.getOmnipooFarms(Number(t)),n=await this.client.getRelayBlockNumber(),r=await Promise.all(e.map(async({keyArgs:a,value:i})=>{let[,s]=a,o=i,l=await this.client.getOmnipoolGlobalFarm(s),c=await this.client.getOmnipoolYieldFarm(Number(t),s,o);if(!l||!c)return;let u=l.reward_currency,d=l.incentivized_asset,p=this.getFarmAddress(s),h=await this.getOraclePrice(u,d),b=await this.balance.getBalance(p,u);return{id:t,globalFarm:l,yieldFarm:c,priceAdjustment:h,balance:b}}));return n?r.map(a=>a?this.farmData(a,n):void 0):[]}async getAllIsolatedFarms(){let e=(await this.client.getAllIsolatedFarms()).reduce((r,a)=>r.includes(a.keyArgs[0].toString())?r:[...r,a.keyArgs[0].toString()],[]),n=await Promise.all(e.map(async r=>{let a=await this.getIsolatedFarms(r);if(a)return[r,a]}));return Object.fromEntries(n.filter(r=>!!r))}async getIsolatedFarms(t){let e=await this.client.getIsolatedFarms(t),n=await this.client.getRelayBlockNumber(),r=await Promise.all(e.map(async({keyArgs:a,value:i})=>{let[,s]=a,o=i,l=await this.client.getIsolatedGlobalFarm(s),c=await this.client.getIsolatedYieldFarm(t,s,o);if(!l||!c)return;let u=l.reward_currency,d=l.incentivized_asset,p=this.getFarmAddress(s,!0),h=await this.getOraclePrice(u,d),b=await this.balance.getBalance(p,u);return{id:t,globalFarm:l,yieldFarm:c,priceAdjustment:h,balance:b,farmAddress:p}}));return n?r.map(a=>a?this.farmData(a,n,!0):void 0):[]}async getDepositReward(t,e,n,r){let a=e.global_farm_id,i=e.yield_farm_id,s=n?await this.client.getIsolatedYieldFarm(t,a,i):await this.client.getOmnipoolYieldFarm(Number(t),a,i),o=n?await this.client.getIsolatedGlobalFarm(a):await this.client.getOmnipoolGlobalFarm(a);if(!o||!s)return;let l=o.reward_currency,c=o.incentivized_asset,u=[[this.getFarmAddress(0,n),o.reward_currency],[this.getFarmAddress(o.id,n),o.reward_currency]],d=await this.getAccountAssetBalances(u),p=await this.getOraclePrice(l,c),h=new fe(u,d),g=await new Pe(y=>this.getFarmAddress(y),y=>this.client.getAsset(y),h).claimRewards(o,s,e,r,p??o.price_adjustment);if(!g)return;let f=await this.client.getAsset(g.assetId);if(f&&!(g.reward<=f.existential_deposit))return g}async getAccountAssetBalances(t){let[e,n]=await Promise.all([Promise.all(t.filter(([a,i])=>i!==0).map(([a,i])=>this.balance.getTokenBalance(a,i))),Promise.all(t.filter(([a,i])=>i===0).map(([a])=>this.balance.getSystemBalance(a)))]),r=[];for(let a=0,i=0;a+i<t.length;){let s=a+i,[,o]=t[s];o===0?(r.push(n[i]),i+=1):(r.push(e[a]),a+=1)}return r}};import{Binary as Xa,Enum as za}from"polkadot-api";var Nt=class extends B{omnipoolAssetIds=[];async getOraclePrice(t){return await this.api.query.EmaOracle.Oracles.getValue(Xa.fromText("omnipool"),t,za("TenMinutes"))}async getRelayBlockNumber(){return(await this.api.query.ParachainSystem.ValidationData.getValue())?.relay_parent_number}async getAllOmnipooFarms(){return this.api.query.OmnipoolWarehouseLM.ActiveYieldFarm.getEntries()}async getOmnipooFarms(t){return this.api.query.OmnipoolWarehouseLM.ActiveYieldFarm.getEntries(t)}async getOmnipoolGlobalFarm(t){return this.api.query.OmnipoolWarehouseLM.GlobalFarm.getValue(t,{at:"best"})}async getOmnipoolYieldFarm(t,e,n){return this.api.query.OmnipoolWarehouseLM.YieldFarm.getValue(t,e,n,{at:"best"})}async getAllIsolatedFarms(){return this.api.query.XYKWarehouseLM.ActiveYieldFarm.getEntries()}async getIsolatedFarms(t){return this.api.query.XYKWarehouseLM.ActiveYieldFarm.getEntries(t)}async getIsolatedGlobalFarm(t){return this.api.query.XYKWarehouseLM.GlobalFarm.getValue(t,{at:"best"})}async getIsolatedYieldFarm(t,e,n){return this.api.query.XYKWarehouseLM.YieldFarm.getValue(t,e,n,{at:"best"})}async getAsset(t){return this.api.query.AssetRegistry.Assets.getValue(t)}};var ur={};A(ur,{PoolContextProvider:()=>St,PoolError:()=>Z,PoolFactory:()=>ft,PoolType:()=>I,aave:()=>an,hsm:()=>cn,lbp:()=>je,omni:()=>Ze,stable:()=>en,xyk:()=>nn});var je={};A(je,{LbpMath:()=>Y,LbpPool:()=>Ht,LbpPoolClient:()=>Gt});import{calculate_in_given_out as Ka,calculate_out_given_in as ja,calculate_linear_weights as Qa,calculate_pool_trade_fee as Ja,get_spot_price as Za}from"@galacticcouncil/math-lbp";var Y=class{static getSpotPrice(t,e,n,r,a){return Za(t,e,n,r,a)}static calculateInGivenOut(t,e,n,r,a){return Ka(t,e,n,r,a)}static calculateOutGivenIn(t,e,n,r,a){return ja(t,e,n,r,a)}static calculateLinearWeights(t,e,n,r,a){return Qa(t,e,n,r,a)}static calculatePoolTradeFee(t,e,n){return Ja(t,e,n)}};import{big as Wn,RUNTIME_DECIMALS as Yn}from"@galacticcouncil/common";var I=(i=>(i.Aave="Aave",i.LBP="LBP",i.Omni="Omnipool",i.Stable="Stableswap",i.XYK="XYK",i.HSM="HSM",i))(I||{}),Z=(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))(Z||{});var{FeeUtils:$n}=x,Ht=class m{type;address;tokens;maxInRatio;maxOutRatio;minTradingLimit;fee;repayFeeApply;static fromPool(t){return new m(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 n=new Map(this.tokens.map(i=>[i.id,i])),r=n.get(t),a=n.get(e);if(r==null)throw new Error("Pool does not contain tokenIn");if(a==null)throw new Error("Pool does not contain tokenOut");return{assetIn:t,assetOut:e,balanceIn:r.balance,balanceOut:a.balance,decimalsIn:r.decimals,decimalsOut:a.decimals,weightIn:r.weight,weightOut:a.weight}}validateAndBuy(t,e,n){let r=this.tokens[0].id,a=[];e<this.minTradingLimit&&a.push("InsufficientTradingAmount");let i=t.balanceOut/this.maxOutRatio;if(e>i&&a.push("MaxOutRatioExceeded"),r===t.assetOut){let s=this.calculateTradeFee(e,n),o=$n.toPct(this.repayFeeApply?n.repayFee:n.exchangeFee),l=e+s,c=this.calculateInGivenOut(t,l),u=t.balanceIn/this.maxInRatio;return c>u&&a.push("MaxInRatioExceeded"),{amountIn:c,calculatedIn:c,amountOut:e,feePct:o,errors:a}}else{let s=this.calculateInGivenOut(t,e),o=t.balanceIn/this.maxInRatio;return s>o&&a.push("MaxInRatioExceeded"),{amountIn:s,calculatedIn:s,amountOut:e,feePct:0,errors:a}}}validateAndSell(t,e,n){let r=this.tokens[0].id,a=[];e<this.minTradingLimit&&a.push("InsufficientTradingAmount");let i=t.balanceIn/this.maxInRatio;if(e>i&&a.push("MaxInRatioExceeded"),r===t.assetIn){let s=this.calculateOutGivenIn(t,e),o=t.balanceOut/this.maxOutRatio;return s>o&&a.push("MaxOutRatioExceeded"),{amountIn:e,calculatedOut:s,amountOut:s,feePct:0,errors:a}}else{let s=this.calculateOutGivenIn(t,e),o=this.calculateTradeFee(s,n),l=$n.toPct(this.repayFeeApply?n.repayFee:n.exchangeFee),c=s-o,u=t.balanceOut/this.maxOutRatio;return c>u&&a.push("MaxOutRatioExceeded"),{amountIn:e,calculatedOut:s,amountOut:c,feePct:l,errors:a}}}calculateInGivenOut(t,e){let n=Y.calculateInGivenOut(t.balanceIn.toString(),t.balanceOut.toString(),t.weightIn.toString(),t.weightOut.toString(),e.toString()),r=BigInt(n);return r<0n?0n:r}calculateOutGivenIn(t,e){let n=Y.calculateOutGivenIn(t.balanceIn.toString(),t.balanceOut.toString(),t.weightIn.toString(),t.weightOut.toString(),e.toString()),r=BigInt(n);return r<0n?0n:r}spotPriceInGivenOut(t){let e=Y.getSpotPrice(t.balanceOut.toString(),t.balanceIn.toString(),t.weightOut.toString(),t.weightIn.toString(),Wn.toBigInt(1,Yn).toString());return BigInt(e)}spotPriceOutGivenIn(t){let e=Y.getSpotPrice(t.balanceIn.toString(),t.balanceOut.toString(),t.weightIn.toString(),t.weightOut.toString(),Wn.toBigInt(1,Yn).toString());return BigInt(e)}calculateTradeFee(t,e){let n=Y.calculatePoolTradeFee(t.toString(),this.repayFeeApply?e.repayFee[0]:e.exchangeFee[0],this.repayFeeApply?e.repayFee[1]:e.exchangeFee[1]);return BigInt(n)}};import{CompatibilityLevel as yi}from"polkadot-api";import{Subscription as fi,distinctUntilChanged as Pi,filter as Si}from"rxjs";import{memoize1 as ri}from"@thi.ng/memoize";import{TLRUCache as ai}from"@thi.ng/cache";import{ReplaySubject as Xn,Subscription as zn,combineLatest as ii,defer as si,from as oi,merge as Xe,of as li,EMPTY as xe}from"rxjs";import{bufferCount as ci,bufferTime as ui,catchError as ve,filter as Ie,finalize as ze,map as dt,pairwise as Ke,repeat as Kn,skip as mi,share as pi,startWith as di,switchMap as jn,tap as gt,throttleTime as gi}from"rxjs/operators";import{BehaviorSubject as ti}from"rxjs";var Se=class{store$=new ti([]);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,n=new Map(e.map((s,o)=>[s.address,o])),r=await t(e),a=e.slice(),i=new Set;for(let s of r){let o=n.get(s.address);o===void 0?(n.set(s.address,a.length),a.push(s)):a[o]=s,i.add(s.address)}this.changeset=i,this.store$.next(a)}).catch(console.error)}destroy(){this.store$.complete()}};import{log as ei}from"@galacticcouncil/common";var ni={Aave:"AAVE",LBP:"LBP",Omnipool:"OMNI",Stableswap:"STBL",XYK:"XYK",HSM:"HSM"},{logger:Te}=ei,we=class{type;constructor(t){this.type=t}prefix(){return this.pad(`pool(${ni[this.type]})`,10)}trace(t,...e){Te.trace(`${this.prefix()} ${t} :`,...e)}debug(t,...e){Te.debug(`${this.prefix()} ${t} :`,...e)}info(t,...e){Te.info(`${this.prefix()} ${t} :`,...e)}error(t,...e){Te.error(`${this.prefix()} ${t} :`,...e)}pad(t,e){return t.length>=e?t:t+" ".repeat(e-t.length)}};var{withTimeout:hi}=be,bi=3e3,N=class extends B{evm;balance;store=new Se;log;shared$;resync$=new Xn(1);resyncAt=0;resyncPending=!1;mem=0;memPoolsCache=new ai(null,{ttl:6*1e3});memPools=ri(t=>(this.log.info("pool_sync",{mem:t}),this.loadPools()),this.memPoolsCache);constructor(t,e){super(t),this.evm=e,this.balance=new X(t),this.log=new we(this.getPoolType())}async getMemPools(){return this.memPools(this.mem)}async getPools(){return(await this.getMemPools()).filter(e=>this.hasValidAssets(e))}getSubscriber(){return this.shared$||(this.shared$=this.subscribeStore()),this.shared$.pipe(di([]),ci(2,1),dt(([t,e])=>t.length===0?e:this.store.applyChangeset(e)),Ie(t=>t.length>0),gi(1e3,void 0,{leading:!0,trailing:!0}))}subscribeStore(){return si(()=>{let t=new zn;return t.add(this.startWatchdog()),this.resync$.next(),this.resync$.pipe(jn(()=>{let e=new zn;return oi(hi(this.getMemPools(),6e4,"getMemPools stalled")).pipe(gt(()=>this.log.info("pool_synced",{mem:this.mem})),dt(r=>r.filter(a=>this.hasValidAssets(a))),gt(r=>this.store.set(r)),ve(()=>(this.log.error("pool_seed_error",{mem:this.mem}),this.requestResync(),xe))).pipe(gt(()=>{e.add(this.subscribeBalances()),e.add(this.subscribeUpdates())}),jn(r=>Xe(li(r),this.store.asObservable().pipe(mi(1)))),ze(()=>{e.unsubscribe()}))}),ze(()=>t.unsubscribe()))}).pipe(pi({connector:()=>new Xn(1),resetOnRefCountZero:!0}))}subscribeBalances(){let t=this.store.pools.map(e=>{let{address:n}=e,r=[this.balance.watchTokensBalance(n)];if(this.hasSystemAsset(e)){let a=this.balance.watchSystemBalance(n);r.push(a)}if(this.hasErc20Asset(e)){let a=e.tokens.filter(s=>s.type==="Erc20").map(s=>s.id),i=this.balance.watchErc20Balance(n,a);r.push(i)}return ii(r).pipe(dt(a=>a.flat()),Ke(),dt(([a,i])=>this.balance.getDeltas(a,i)),Ie(a=>a.length>0),dt(a=>[n,a]))});return Xe(...t).pipe(ui(250),Ie(e=>e.length>0),dt(e=>new Map(e)),this.watchGuard("balances")).subscribe(e=>{this.store.update(n=>this.updateBalances(n,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:n})=>n>0n&&!!e)}updateBalances=(t,e)=>{let n=[],r=new Map(t.map(a=>[a.address,a]));for(let[a,i]of e){let s=r.get(a);if(s){let o=s.tokens.map(l=>{let c=i.find(u=>u.id===l.id);return c&&l.id!==s.id?{...l,balance:c.balance.transferable}:l});n.push({...s,tokens:o})}}return n};resync(t=!1){let e=Date.now();!t&&e-this.resyncAt<bi||(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 n=this.watcher.connection$.pipe(Ke(),Ie(([a,i])=>a==="offline"&&i==="online"),gt(()=>{this.log.debug("watchdog_recover_online",{mem:this.mem}),this.requestResync()}),ve(a=>(this.log.error("watchdog_recovery_error",a),xe)),Kn({delay:1e3})),r=this.watcher.finalizedBlock$.pipe(Ke(),gt(([a,i])=>{let s=Number(a.number),o=Number(i.number),l=o-s;l>=3&&(this.log.debug("watchdog_gap",{from:s,to:o,gap:l}),this.requestResync())}),ve(a=>(this.log.error("watchdog_gap_error",a),xe)),Kn({delay:1e3}));return Xe(n,r).subscribe()}watchGuard(t){return e=>e.pipe(gt({error:n=>{this.log.error(t,n),this.requestResync(!0)}}),ze(()=>{this.log.debug(t,"unsub")}),ve(()=>xe))}};var Gt=class extends N{MAX_FINAL_WEIGHT=100000000n;poolsData=new Map([]);getPoolType(){return"LBP"}async getPoolLimits(){let[t,e,n]=await Promise.all([this.api.constants.LBP.MaxInRatio(),this.api.constants.LBP.MaxOutRatio(),this.api.constants.LBP.MinTradingLimit()]);return{maxInRatio:t,maxOutRatio:e,minTradingLimit:n}}getPoolWeights(t,e){let{start:n,end:r,initial_weight:a,final_weight:i}=t,s=Y.calculateLinearWeights(n?n.toString():"0",r?r.toString():"0",a.toString(),i.toString(),e.toString()),o=BigInt(s),l=this.MAX_FINAL_WEIGHT-BigInt(o);return[o,l]}async isSupported(){let t=this.api.query.LBP.PoolData,e=await this.api.compatibilityToken;return t.isCompatible(yi.BackwardsCompatible,e)}async loadPools(){let[t,e,n]=await Promise.all([this.api.query.LBP.PoolData.getEntries({at:"best"}),this.api.query.ParachainSystem.ValidationData.getValue({at:"best"}),this.getPoolLimits()]),r=e?.relay_parent_number||0,a=t.filter(({value:i})=>e&&this.isActivePool(i,r)).map(async({keyArgs:i,value:s})=>{let[o]=i,l=o.toString(),c=await this.getPoolDelta(l,s,r);return{address:l,type:"LBP",fee:s.fee,...c,...n}});return Promise.all(a)}async getPoolDelta(t,e,n){let{assets:r,repay_target:a,fee_collector:i}=e,[s,o]=this.getPoolWeights(e,n),[l,c]=r,[u,d,p,h,b]=await Promise.all([this.isRepayFeeApplied(l,a,i.toString()),this.balance.getBalance(t,l),this.api.query.AssetRegistry.Assets.getValue(l),this.balance.getBalance(t,c),this.api.query.AssetRegistry.Assets.getValue(c)]);return{repayFeeApply:u,tokens:[{id:l,decimals:p?.decimals,existentialDeposit:p?.existential_deposit,balance:d.transferable,weight:s,type:p?.asset_type.type},{id:c,decimals:b?.decimals,existentialDeposit:b?.existential_deposit,balance:h.transferable,weight:o,type:b?.asset_type.type}]}}isActivePool(t,e){let{start:n,end:r}=t;return n&&r?e>=n&&e<r:!1}async isRepayFeeApplied(t,e,n){if(e===0n)return!1;try{return(await this.balance.getBalance(n,t)).transferable<e}catch{return!0}}async getRepayFee(){return await this.api.constants.LBP.repay_fee()}async getPoolFees(t,e){let n=this.store.pools.find(a=>a.address===e);return{repayFee:await this.getRepayFee(),exchangeFee:n.fee}}subscribeValidationData(){return this.api.query.ParachainSystem.ValidationData.watchValue("best").pipe(Si(t=>t!==void 0),Pi((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 n=[];for(let r of e){let a=this.poolsData.get(r.address);if(a){let{assets:i,repay_target:s,fee_collector:o}=a,[l]=i,[c,u]=this.getPoolWeights(a,t),[d,p]=r.tokens,h=[{...d,weight:c},{...p,weight:u}],b=await this.isRepayFeeApplied(l,s,o.toString());n.push({...r,tokens:h,repayFeeApply:b})}}return n})})}subscribeUpdates(){let t=new fi;return t.add(this.subscribeValidationData()),t}};var Ze={};A(Ze,{OmniMath:()=>v,OmniPool:()=>Vt,OmniPoolClient:()=>Wt});import{calculate_in_given_out as Ti,calculate_lrna_in_given_out as wi,calculate_out_given_in as xi,calculate_out_given_lrna_in as vi,calculate_spot_price as Ii,calculate_lrna_spot_price as Ai,calculate_shares as Oi,calculate_liquidity_out as _i,calculate_liquidity_lrna_out as Bi,verify_asset_cap as Fi,calculate_liquidity_hub_in as Ri,is_sell_allowed as Ci,is_buy_allowed as Ei,is_add_liquidity_allowed as ki,is_remove_liquidity_allowed as Mi,recalculate_asset_fee as Di,recalculate_protocol_fee as Li}from"@galacticcouncil/math-omnipool";import ht from"big.js";var v=class{static calculateSpotPrice(t,e,n,r){return Ii(t,e,n,r)}static calculateLrnaSpotPrice(t,e){return Ai(t,e)}static calculateInGivenOut(t,e,n,r,a,i,s,o,l,c){return Ti(t,e,n,r,a,i,s,o,l,c)}static calculateLrnaInGivenOut(t,e,n,r,a,i){return wi(t,e,n,r,a,i)}static calculateOutGivenIn(t,e,n,r,a,i,s,o,l,c){return xi(t,e,n,r,a,i,s,o,l,c)}static calculateOutGivenLrnaIn(t,e,n,r,a,i){return vi(t,e,n,r,a,i)}static calculateShares(t,e,n,r){return Oi(t,e,n,r)}static calculateLiquidityOut(t,e,n,r,a,i,s,o){return _i(t,e,n,r,a,i,s,o)}static calculateLiquidityLRNAOut(t,e,n,r,a,i,s,o){return Bi(t,e,n,r,a,i,s,o)}static calculateCapDifference(t,e,n,r){let a=ht(e),i=ht(t),s=ht(r),o=ht(n),l=ht(10).pow(18),c=o.div(l);if(a.div(s).lt(c)){let d=c.times(s).minus(a).times(i),p=a.times(ht(1).minus(c));return d.div(p).toFixed(0)}else return"0"}static calculateLimitHubIn(t,e,n,r){return Ri(t,e,n,r)}static isSellAllowed(t){return Ci(t)}static isBuyAllowed(t){return Ei(t)}static isAddLiquidityAllowed(t){return ki(t)}static isRemoveLiquidityAllowed(t){return Mi(t)}static recalculateAssetFee(t,e,n,r,a,i,s,o,l,c,u){return Di(t,e,n,r,a,i,s,o,l,c,u)}static recalculateProtocolFee(t,e,n,r,a,i,s,o,l,c,u){return Li(t,e,n,r,a,i,s,o,l,c,u)}static verifyAssetCap(t,e,n,r){return Fi(t,e,n,r)}};import{big as qi}from"@galacticcouncil/common";var{FeeUtils:z}=x,Vt=class m{type;address;tokens;maxInRatio;maxOutRatio;minTradingLimit;hubAssetId;static fromPool(t){return new m(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 n=new Map(this.tokens.map(i=>[i.id,i])),r=n.get(t),a=n.get(e);if(r==null)throw new Error("Pool does not contain tokenIn");if(a==null)throw new Error("Pool does not contain tokenOut");return{assetIn:t,assetOut:e,hubReservesIn:r.hubReserves,hubReservesOut:a.hubReserves,sharesIn:r.shares,sharesOut:a.shares,decimalsIn:r.decimals,decimalsOut:a.decimals,balanceIn:r.balance,balanceOut:a.balance,tradeableIn:r.tradeable,tradeableOut:a.tradeable,assetInEd:r.existentialDeposit,assetOutEd:a.existentialDeposit}}validateAndBuy(t,e,n){let r=this.calculateInGivenOut(t,e),a=this.calculateInGivenOut(t,e,n),i=r===0n?0:L.calculateBuyFee(r,a),s=[],o=v.isSellAllowed(t.tradeableIn),l=v.isBuyAllowed(t.tradeableOut);(!o||!l)&&s.push("TradeNotAllowed"),(e<this.minTradingLimit||r<t.assetInEd)&&s.push("InsufficientTradingAmount");let c=t.balanceOut/this.maxOutRatio;e>c&&s.push("MaxOutRatioExceeded");let u=t.balanceIn/this.maxInRatio;return a>u&&s.push("MaxInRatioExceeded"),{amountIn:a,calculatedIn:r,amountOut:e,feePct:i,errors:s}}validateAndSell(t,e,n){let r=this.calculateOutGivenIn(t,e),a=this.calculateOutGivenIn(t,e,n),i=L.calculateSellFee(r,a),s=[],o=v.isSellAllowed(t.tradeableIn),l=v.isBuyAllowed(t.tradeableOut);(!o||!l)&&s.push("TradeNotAllowed"),(e<this.minTradingLimit||r<t.assetOutEd)&&s.push("InsufficientTradingAmount");let c=t.balanceIn/this.maxInRatio;e>c&&s.push("MaxInRatioExceeded");let u=t.balanceOut/this.maxOutRatio;return a>u&&s.push("MaxOutRatioExceeded"),{amountIn:e,calculatedOut:r,amountOut:a,feePct:i,errors:s}}calculateInGivenOut(t,e,n){if(t.assetIn==this.hubAssetId)return this.calculateLrnaInGivenOut(t,e,n);let r=v.calculateInGivenOut(t.balanceIn.toString(),t.hubReservesIn.toString(),t.sharesIn.toString(),t.balanceOut.toString(),t.hubReservesOut.toString(),t.sharesOut.toString(),e.toString(),n?z.toRaw(n.assetFee).toString():"0",n?z.toRaw(n.protocolFee).toString():"0",n?z.toRaw(n.maxSlipFee).toString():"0"),a=BigInt(r);return a<0n?0n:a}calculateLrnaInGivenOut(t,e,n){let r=v.calculateLrnaInGivenOut(t.balanceOut.toString(),t.hubReservesOut.toString(),t.sharesOut.toString(),e.toString(),n?z.toRaw(n.assetFee).toString():"0",n?z.toRaw(n.maxSlipFee).toString():"0"),a=BigInt(r);return a<0n?0n:a}calculateOutGivenIn(t,e,n){if(t.assetIn==this.hubAssetId)return this.calculateOutGivenLrnaIn(t,e,n);let r=v.calculateOutGivenIn(t.balanceIn.toString(),t.hubReservesIn.toString(),t.sharesIn.toString(),t.balanceOut.toString(),t.hubReservesOut.toString(),t.sharesOut.toString(),e.toString(),n?z.toRaw(n.assetFee).toString():"0",n?z.toRaw(n.protocolFee).toString():"0",n?z.toRaw(n.maxSlipFee).toString():"0"),a=BigInt(r);return a<0n?0n:a}calculateOutGivenLrnaIn(t,e,n){let r=v.calculateOutGivenLrnaIn(t.balanceOut.toString(),t.hubReservesOut.toString(),t.sharesOut.toString(),e.toString(),n?z.toRaw(n.assetFee).toString():"0",n?z.toRaw(n.maxSlipFee).toString():"0"),a=BigInt(r);return a<0n?0n:a}spotPriceInGivenOut(t){if(t.assetIn==this.hubAssetId)return this.spotPriceLrnaInGivenOut(t);let e=v.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=v.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=v.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=v.calculateLrnaSpotPrice(t.balanceOut.toString(),t.hubReservesOut.toString());return this.normalizeSpot(BigInt(e),t.decimalsIn,t.decimalsOut)}normalizeSpot(t,e,n){let r=e-n;if(r===0)return t;let a=qi.pow10(Math.abs(r));return r>0?t*a:t/a}};import{AccountId as Ni,Binary as Hi,CompatibilityLevel as Qn,Enum as Gi}from"polkadot-api";import{toHex as Vi}from"@polkadot-api/utils";import{Subscription as Ui,distinctUntilChanged as Qe,filter as Wi,finalize as Je,map as Ut,merge as Yi,tap as Ae}from"rxjs";import{HYDRATION_SS58_PREFIX as $i}from"@galacticcouncil/common";var{FeeUtils:_}=x,Jn=Hi.fromText("omnipool"),Zn=Gi("Short"),Wt=class extends N{queryBus=new ye;block=0;dynamicFeesConfig=this.queryBus.scope("DynamicFees.AssetFeeConfiguration",t=>this.api.query.DynamicFees.AssetFeeConfiguration.getValue(t,{at:"best"}),t=>String(t));dynamicFees=this.queryBus.scope("DynamicFees.AssetFee",t=>this.api.query.DynamicFees.AssetFee.getValue(t,{at:"best"}),t=>String(t),6*1e3);maxSlipFee=this.queryBus.scope("Omnipool.SlipFee",()=>this.apiNext.query.Omnipool.SlipFee.getValue({at:"best"}),()=>"slipFee");emaOracles=this.queryBus.scope("EmaOracle.Oracles.Short",t=>this.api.query.EmaOracle.Oracles.getValue(Jn,t,Zn,{at:"best"}),t=>t.join(":"),6*1e3);getPoolType(){return"Omnipool"}getPoolAddress(){let t="modlomnipool".padEnd(32,"\0"),e=new TextEncoder().encode(t),n=Vi(e);return Ni($i).dec(n)}getOraclePair(t){return t===0?[0,1]:[1,t]}async getPoolLimits(){let[t,e,n]=await Promise.all([this.api.constants.Omnipool.MaxInRatio(),this.api.constants.Omnipool.MaxOutRatio(),this.api.constants.Omnipool.MinimumTradingLimit()]);return{maxInRatio:t,maxOutRatio:e,minTradingLimit:n}}async isSupported(){let t=this.api.query.Omnipool.Assets,e=await this.api.compatibilityToken;return t.isCompatible(Qn.BackwardsCompatible,e)}async isSlipFeeSupported(){return this.apiNext.query.Omnipool.SlipFee.isCompatible(Qn.Partial)}async loadPools(){let t=await this.api.constants.Omnipool.HubAssetId(),e=this.getPoolAddress(),[n,r,a,i,s]=await Promise.all([this.api.query.Omnipool.Assets.getEntries({at:"best"}),this.api.query.Omnipool.HubAssetTradability.getValue(),this.api.query.AssetRegistry.Assets.getValue(t),this.balance.getBalance(e,t),this.getPoolLimits()]),o=n.map(async({keyArgs:c,value:u})=>{let[d]=c,{hub_reserve:p,shares:h,tradable:b,cap:g,protocol_shares:f}=u,[y,S]=await Promise.all([this.api.query.AssetRegistry.Assets.getValue(d),this.balance.getBalance(e,d)]);return{id:d,decimals:y?.decimals,existentialDeposit:y?.existential_deposit,balance:S.transferable,cap:g,hubReserves:p,protocolShares:f,shares:h,tradeable:b,type:y?.asset_type.type}}),l=await Promise.all(o);return l.push({id:t,decimals:a?.decimals,existentialDeposit:a?.existential_deposit,balance:i.transferable,tradeable:r,type:a?.asset_type.type}),[{address:e,type:"Omnipool",hubAssetId:t,tokens:l,...s}]}async getPoolFees(t){let e=t.assetOut,n=t.assetIn,r=0;await this.isSlipFeeSupported()&&(r=await this.maxSlipFee.get()??0);let i=await this.dynamicFeesConfig.get(e);if(i?.type==="Fixed"){let{asset_fee:P,protocol_fee:T}=i.value;return{assetFee:_.fromPermill(P),protocolFee:_.fromPermill(T),maxSlipFee:_.fromPermill(r)}}let s=this.getOraclePair(e),o=this.getOraclePair(n),[l,c,u]=await Promise.all([this.dynamicFees.get(e),this.emaOracles.get(s),this.emaOracles.get(o)]),[d,p,h]=await this.getAssetFee(t,this.block,l,c,i?.value.asset_fee_params),[b,g,f]=n===1?[0,0,0]:await this.getProtocolFee(t,this.block,l,u,i?.value.protocol_fee_params),y=d+b,S=h+f;return{assetFee:_.fromPermill(p),protocolFee:_.fromPermill(g),maxSlipFee:_.fromPermill(r),min:_.fromPermill(y),max:_.fromPermill(S)}}async getAssetFee(t,e,n,r,a){let{assetOut:i,balanceOut:s}=t,{min_fee:o,max_fee:l,decay:c,amplification:u}=a||await this.api.constants.DynamicFees.AssetFeeParameters();if(!n||!r)return[o,o,l];let d=_.fromPermill(o),p=_.fromPermill(l),[h]=r,{asset_fee:b,timestamp:g}=n,f=Math.max(1,e-g),y=h.volume.b_in.toString(),S=h.volume.b_out.toString(),P=h.liquidity.b.toString();i===0&&(y=h.volume.a_in.toString(),S=h.volume.a_out.toString(),P=h.liquidity.a.toString());let T=_.fromPermill(b),w=v.recalculateAssetFee(y,S,P,"9",s.toString(),_.toRaw(T).toString(),f.toString(),_.toRaw(d).toString(),_.toRaw(p).toString(),c.toString(),u.toString());return[o,Number(w)*1e6,l]}async getProtocolFee(t,e,n,r,a){let{assetIn:i,balanceIn:s}=t,{min_fee:o,max_fee:l,decay:c,amplification:u}=a||await this.api.constants.DynamicFees.ProtocolFeeParameters();if(!n||!r)return[o,o,l];let d=_.fromPermill(o),p=_.fromPermill(l),[h]=r,{protocol_fee:b,timestamp:g}=n,f=Math.max(1,e-g),y=h.volume.b_in.toString(),S=h.volume.b_out.toString(),P=h.liquidity.b.toString();i===0&&(y=h.volume.a_in.toString(),S=h.volume.a_out.toString(),P=h.liquidity.a.toString());let T=_.fromPermill(b),w=v.recalculateProtocolFee(y,S,P,"9",s.toString(),_.toRaw(T).toString(),f.toString(),_.toRaw(d).toString(),_.toRaw(p).toString(),c.toString(),u.toString());return[o,Number(w)*1e6,l]}subscribeEmaOracles(){let[t]=this.store.pools,n=t.tokens.map(r=>r.id).map(r=>this.getOraclePair(r)).map(r=>this.api.query.EmaOracle.Oracles.watchValue(Jn,r,Zn,"best").pipe(Wi(a=>a!==void 0),Ut((a,i)=>({value:a,index:i})),Ae(({index:a})=>{a>0&&this.log.trace("emaOracle.Oracles",r.join(":"))}),Ut(({value:a})=>({pair:r,value:a}))));return Yi(...n).pipe(Je(()=>this.emaOracles.clear()),this.watchGuard("emaOracle.Oracles")).subscribe(r=>{let{pair:a,value:i}=r;this.emaOracles.set(i,a)})}subscribeDynamicFees(){return this.api.query.DynamicFees.AssetFee.watchEntries({at:"best"}).pipe(Qe((t,e)=>!e.deltas),Ut((t,e)=>({value:t,index:e})),Ae(({value:t,index:e})=>{e>0&&this.log.trace("dynamicFees.AssetFee",t.deltas?.upserted)}),Je(()=>this.dynamicFees.clear()),this.watchGuard("dynamicFees.AssetFee")).subscribe(({value:{deltas:t}})=>{t?.upserted.forEach(e=>{let[n]=e.args;this.dynamicFees.set(e.value,n)})})}subscribeDynamicFeesConfig(){return this.api.query.DynamicFees.AssetFeeConfiguration.watchEntries({at:"best"}).pipe(Qe((t,e)=>!e.deltas),Ut((t,e)=>({value:t,index:e})),Ae(({value:t,index:e})=>{e>0&&this.log.trace("dynamicFees.AssetFeeConfiguration",t.deltas?.upserted)}),Je(()=>this.dynamicFeesConfig.clear()),this.watchGuard("dynamicFees.AssetFeeConfiguration")).subscribe(({value:{deltas:t}})=>{t?.upserted.forEach(e=>{let[n]=e.args;this.dynamicFeesConfig.set(e.value,n)})})}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(Qe((t,e)=>!e.deltas),Ut((t,e)=>({value:t,index:e})),Ae(({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 n=t?.upserted.reduce((a,i)=>{let[s]=i.args;return a.set(s,i.value),a},new Map),r=e.tokens.map(a=>{let i=n?.get(a.id);return i?this.updateTokenState(a,i):a});return[{...e,tokens:r}]})})}subscribeUpdates(){let t=new Ui;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:n,shares:r,tradable:a,cap:i,protocol_shares:s}=e;return{...t,cap:i,hubReserves:n,protocolShares:s,shares:r,tradeable:a}}};var en={};A(en,{StableMath:()=>M,StableSwap:()=>at,StableSwapClient:()=>Yt});import{calculate_in_given_out as Xi,calculate_out_given_in as zi,calculate_amplification as Ki,calculate_add_one_asset as ji,calculate_liquidity_out_one_asset as Qi,calculate_shares as Ji,calculate_shares_for_amount as Zi,calculate_spot_price_with_fee as ts,pool_account_name as es,recalculate_peg as ns}from"@galacticcouncil/math-stableswap";var M=class{static getPoolAddress(t){return es(t)}static defaultPegs(t){let e=[];for(let n=0;n<t;n++)e.push(["1","1"]);return e}static calculateAmplification(t,e,n,r,a){return Ki(t,e,n,r,a)}static calculateInGivenOut(t,e,n,r,a,i,s){return Xi(t,e,n,r,a,i,s)}static calculateAddOneAsset(t,e,n,r,a,i,s){return ji(t,e,n,r,a,i,s)}static calculateSharesForAmount(t,e,n,r,a,i,s){return Zi(t,e,n,r,a,i,s)}static calculateOutGivenIn(t,e,n,r,a,i,s){return zi(t,e,n,r,a,i,s)}static calculateLiquidityOutOneAsset(t,e,n,r,a,i,s){return Qi(t,e,n,r,a,i,s)}static calculateShares(t,e,n,r,a,i){return Ji(t,e,n,r,a,i)}static calculateSpotPriceWithFee(t,e,n,r,a,i,s,o){return ts(t,e,n,r,a,i,s,o)}static recalculatePegs(t,e,n,r,a,i){let s=ns(t,e,n,r,a,i);return JSON.parse(s)}};import{RUNTIME_DECIMALS as rs,big as tr}from"@galacticcouncil/common";var{FeeUtils:bt}=x,at=class m{type;address;tokens;maxInRatio;maxOutRatio;minTradingLimit;amplification;isRampPeriod;id;fee;totalIssuance;pegs;static fromPool(t){return new m(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 n=new Map(this.tokens.map(i=>[i.id,i])),r=n.get(t),a=n.get(e);if(r==null)throw new Error("Pool does not contain tokenIn");if(a==null)throw new Error("Pool does not contain tokenOut");return{assetIn:t,assetOut:e,balanceIn:r.balance,balanceOut:a.balance,decimalsIn:r.decimals,decimalsOut:a.decimals,tradeableIn:this.id===t?15:r.tradeable,tradeableOut:this.id===e?15:a.tradeable,assetInEd:r.existentialDeposit,assetOutEd:a.existentialDeposit}}validateAndBuy(t,e,n){let r=this.calculateInGivenOut(t,e),a=this.calculateInGivenOut(t,e,n),i=r===0n?0:L.calculateBuyFee(r,a),s=[],o=v.isSellAllowed(t.tradeableIn),l=v.isBuyAllowed(t.tradeableOut);return(!o||!l)&&s.push("TradeNotAllowed"),(e<this.minTradingLimit||r<t.assetInEd)&&s.push("InsufficientTradingAmount"),{amountIn:a,calculatedIn:r,amountOut:e,feePct:i,errors:s}}validateAndSell(t,e,n){let r=this.calculateOutGivenIn(t,e),a=this.calculateOutGivenIn(t,e,n),i=L.calculateSellFee(r,a),s=[],o=v.isSellAllowed(t.tradeableIn),l=v.isBuyAllowed(t.tradeableOut);return(!o||!l)&&s.push("TradeNotAllowed"),(e<this.minTradingLimit||r<t.assetOutEd)&&s.push("InsufficientTradingAmount"),{amountIn:e,calculatedOut:r,amountOut:a,feePct:i,errors:s}}calculateIn(t,e,n){let r=M.calculateInGivenOut(this.getReserves(),Number(t.assetIn),Number(t.assetOut),e.toString(),this.amplification.toString(),n?bt.toRaw(n.fee).toString():"0",this.getPegs()),a=BigInt(r);return a<0n?0n:a}calculateAddOneAsset(t,e,n){let r=M.calculateAddOneAsset(this.getReserves(),e.toString(),Number(t.assetIn),this.amplification.toString(),this.totalIssuance.toString(),n?bt.toRaw(n.fee).toString():"0",this.getPegs()),a=BigInt(r);return a<0n?0n:a}calculateSharesForAmount(t,e,n){let r=M.calculateSharesForAmount(this.getReserves(),Number(t.assetOut),e.toString(),this.amplification.toString(),this.totalIssuance.toString(),n?bt.toRaw(n.fee).toString():"0",this.getPegs()),a=BigInt(r);return a<0n?0n:a}calculateInGivenOut(t,e,n){return t.assetOut==this.id?this.calculateAddOneAsset(t,e,n):t.assetIn==this.id?this.calculateSharesForAmount(t,e,n):this.calculateIn(t,e,n)}spotPriceInGivenOut(t){let e=M.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,n){let r=M.calculateOutGivenIn(this.getReserves(),Number(t.assetIn),Number(t.assetOut),e.toString(),this.amplification.toString(),n?bt.toRaw(n.fee).toString():"0",this.getPegs()),a=BigInt(r);return a<0n?0n:a}calculateWithdrawOneAsset(t,e,n){let r=M.calculateLiquidityOutOneAsset(this.getReserves(),e.toString(),Number(t.assetOut),this.amplification.toString(),this.totalIssuance.toString(),n?bt.toRaw(n.fee).toString():"0",this.getPegs()),a=BigInt(r);return a<0n?0n:a}calculateShares(t,e,n){let r=M.calculateShares(this.getReserves(),this.getAssets(t.assetIn,e),this.amplification.toString(),this.totalIssuance.toString(),n?bt.toRaw(n.fee).toString():"0",this.getPegs()),a=BigInt(r);return a<0n?0n:a}calculateOutGivenIn(t,e,n){return t.assetIn==this.id?this.calculateWithdrawOneAsset(t,e,n):t.assetOut==this.id?this.calculateShares(t,e,n):this.calculateOut(t,e,n)}spotPriceOutGivenIn(t){let e=M.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:n,decimals:r})=>({asset_id:e,amount:n,decimals:r}));return JSON.stringify(t,Lt.jsonFormatter)}getAssets(t,e){let n={asset_id:Number(t),amount:e.toString()};return JSON.stringify([n],Lt.jsonFormatter)}normalizeSpot(t,e,n,r,a){return e?t*tr.pow10(rs-a):n?t/tr.pow10(a-r):t}};import{AccountId as as,CompatibilityLevel as is}from"polkadot-api";import{toHex as ss}from"@polkadot-api/utils";import{blake2b as os}from"@noble/hashes/blake2b";import{Subscription as ls,distinctUntilChanged as cs,map as tn,merge as us,tap as er}from"rxjs";import{HYDRATION_SS58_PREFIX as ms,RUNTIME_DECIMALS as ps}from"@galacticcouncil/common";var{FeeUtils:ds}=x,Yt=class extends N{poolsData=new Map([]);getPoolType(){return"Stableswap"}getPoolAddress(t){let e=M.getPoolAddress(t),n=os(e,{dkLen:32}),r=ss(n);return as(ms).dec(r)}async getPoolLimits(){return{maxInRatio:0n,maxOutRatio:0n,minTradingLimit:await this.api.constants.Stableswap.MinTradingLimit()}}getPoolAmplification(t,e){let{initial_amplification:n,final_amplification:r,initial_block:a,final_block:i}=t,s=M.calculateAmplification(n.toString(),r.toString(),a.toString(),i.toString(),e.toString()),o=Number(s)<r;return{amplification:BigInt(s),isRampPeriod:o}}async getPoolTokens(t,e){let n=this.getPoolAddress(t),r=e.assets.map(async a=>{let[i,s,o]=await Promise.all([this.api.query.Stableswap.AssetTradability.getValue(t,a),this.api.query.AssetRegistry.Assets.getValue(a),this.balance.getBalance(n,a)]);return{id:a,decimals:s?.decimals,existentialDeposit:s?.existential_deposit,balance:o.transferable,tradeable:i,type:s?.asset_type.type}});return Promise.all(r)}async isSupported(){let t=this.api.query.Stableswap.Pools,e=await this.api.compatibilityToken;return t.isCompatible(is.BackwardsCompatible,e)}async loadPools(){let[t,e,n]=await Promise.all([this.api.query.Stableswap.Pools.getEntries({at:"best"}),this.api.query.System.Number.getValue({at:"best"}),this.getPoolLimits()]),r=t.map(async({keyArgs:a,value:i})=>{let[s]=a,o=this.getPoolAddress(s),[l,c,u]=await Promise.all([this.getPoolTokens(s,i),this.api.query.Stableswap.PoolPegs.getValue(s,{at:"best"}),this.api.query.Tokens.TotalIssuance.getValue(s,{at:"best"})]),d=this.getPoolAmplification(i,e),p=c?this.getRecentPegs(c):this.getDefaultPegs(i);return l.push({id:s,tradeable:15,balance:u,decimals:ps}),this.poolsData.set(s,i),{address:o,id:s,type:"Stableswap",fee:ds.fromPermill(i.fee),tokens:l,totalIssuance:u,pegs:p,...n,...d}});return Promise.all(r)}async getPoolFees(t,e){return{fee:this.store.pools.find(r=>r.address===e).fee}}getDefaultPegs(t){return M.defaultPegs(t.assets.length)}getRecentPegs(t){let{current:e}=t;return Array.from(e.entries()).map(([n,r])=>r.map(a=>a.toString()))}subscribeIssuance(){let e=this.store.pools.map(n=>n.id).map(n=>this.api.query.Tokens.TotalIssuance.watchValue(n,"best").pipe(tn((r,a)=>({value:r,index:a})),er(({index:r,value:a})=>{r>0&&this.log.trace("tokens.TotalIssuance",n,a)}),tn(({value:r})=>({id:n,value:r}))));return us(...e).pipe(this.watchGuard("tokens.TotalIssuance")).subscribe(n=>{let{id:r,value:a}=n;this.store.update(i=>{let s=[];return i.filter(o=>o.id===r).forEach(o=>{let l=o.tokens.map(c=>c.id===r?{...c,balance:a}:c);s.push({...o,tokens:l,totalIssuance:a})}),s})})}subscribePoolPegs(){return this.api.query.Stableswap.PoolPegs.watchEntries({at:"best"}).pipe(cs((t,e)=>!e.deltas),tn((t,e)=>({value:t,index:e})),er(({value:t,index:e})=>{e>0&&this.log.trace("stableswap.PoolPegs",t.deltas?.upserted)}),this.watchGuard("stableswap.PoolPegs")).subscribe({error:t=>this.log.error("stableswap.PoolPegs",t),next:({value:{deltas:t}})=>{this.store.update(e=>{let n=[],r=new Map(e.map(a=>[a.id,a]));return t?.upserted.forEach(({args:a,value:i})=>{let[s]=a,o=r.get(s);if(o){let l=this.getRecentPegs(i);n.push({...o,pegs:l})}}),n})}})}subscribeBlock(){return this.watcher.bestBlock$.pipe(this.watchGuard("watcher.bestBlock")).subscribe(t=>{this.store.update(e=>{let n=[];return e.filter(r=>r.isRampPeriod).forEach(r=>{let a=this.poolsData.get(r.id);if(a){let i=this.getPoolAmplification(a,t);n.push({...r,...i})}}),n})})}subscribeUpdates(){let t=new ls;return t.add(this.subscribePoolPegs()),t.add(this.subscribeIssuance()),this.hasOnRamps()&&t.add(this.subscribeBlock()),t}hasOnRamps(){return this.store.pools.filter(t=>t.isRampPeriod).length>0}};var nn={};A(nn,{XykMath:()=>Q,XykPool:()=>$t,XykPoolClient:()=>Xt});import{calculate_in_given_out as gs,calculate_out_given_in as hs,calculate_pool_trade_fee as bs,get_spot_price as ys,calculate_liquidity_in as fs,calculate_shares as Ps,calculate_spot_price as Ss,calculate_spot_price_with_fee as Ts,calculate_liquidity_out_asset_a as ws,calculate_liquidity_out_asset_b as xs}from"@galacticcouncil/math-xyk";var Q=class{static getSpotPrice(t,e,n){return ys(t,e,n)}static calculateInGivenOut(t,e,n){return gs(t,e,n)}static calculateOutGivenIn(t,e,n){return hs(t,e,n)}static calculatePoolTradeFee(t,e,n){return bs(t,e,n)}static calculateLiquidityIn(t,e,n){return fs(t,e,n)}static calculateSpotPrice(t,e){return Ss(t,e)}static calculateSpotPriceWithFee(t,e,n,r){return Ts(t,e,n,r)}static calculateShares(t,e,n){return Ps(t,e,n)}static calculateLiquidityOutAssetA(t,e,n,r){return ws(t,e,n,r)}static calculateLiquidityOutAssetB(t,e,n,r){return xs(t,e,n,r)}};import{big as vs}from"@galacticcouncil/common";var{FeeUtils:nr}=x,$t=class m{type;address;tokens;maxInRatio;maxOutRatio;minTradingLimit;static fromPool(t){return new m(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 n=new Map(this.tokens.map(i=>[i.id,i])),r=n.get(t),a=n.get(e);if(r==null)throw new Error("Pool does not contain tokenIn");if(a==null)throw new Error("Pool does not contain tokenOut");return{assetIn:t,assetOut:e,decimalsIn:r.decimals,decimalsOut:a.decimals,balanceIn:r.balance,balanceOut:a.balance,assetInEd:r.existentialDeposit,assetOutEd:a.existentialDeposit}}validateAndBuy(t,e,n){let r=this.calculateInGivenOut(t,e),a=this.calculateTradeFee(r,n),i=nr.toPct(n.exchangeFee),s=r+a,o=[];(e<this.minTradingLimit||r<t.assetInEd)&&o.push("InsufficientTradingAmount");let l=t.balanceOut/this.maxOutRatio;e>l&&o.push("MaxOutRatioExceeded");let c=t.balanceIn/this.maxInRatio;return s>c&&o.push("MaxInRatioExceeded"),{amountIn:s,calculatedIn:r,amountOut:e,feePct:i,errors:o}}validateAndSell(t,e,n){let r=this.calculateOutGivenIn(t,e),a=this.calculateTradeFee(r,n),i=nr.toPct(n.exchangeFee),s=r-a,o=[];(e<this.minTradingLimit||r<t.assetOutEd)&&o.push("InsufficientTradingAmount");let l=t.balanceIn/this.maxInRatio;e>l&&o.push("MaxInRatioExceeded");let c=t.balanceOut/this.maxOutRatio;return s>c&&o.push("MaxOutRatioExceeded"),{amountIn:e,calculatedOut:r,amountOut:s,feePct:i,errors:o}}calculateInGivenOut(t,e){let n=Q.calculateInGivenOut(t.balanceIn.toString(),t.balanceOut.toString(),e.toString()),r=BigInt(n);return r<0n?0n:r}calculateOutGivenIn(t,e){let n=Q.calculateOutGivenIn(t.balanceIn.toString(),t.balanceOut.toString(),e.toString()),r=BigInt(n);return r<0n?0n:r}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 n=Q.calculatePoolTradeFee(t.toString(),e.exchangeFee[0],e.exchangeFee[1]);return BigInt(n)}normalizeSpot(t,e,n){let r=e-n;if(r===0)return t;let a=vs.pow10(Math.abs(r));return r>0?t*a:t/a}};import{CompatibilityLevel as Is}from"polkadot-api";import{Subscription as As}from"rxjs";var Xt=class extends N{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,n]=await Promise.all([this.api.constants.XYK.MaxInRatio(),this.api.constants.XYK.MaxOutRatio(),this.api.constants.XYK.MinTradingLimit()]);return{maxInRatio:t,maxOutRatio:e,minTradingLimit:n}}async isSupported(){let t=this.api.query.XYK.PoolAssets,e=await this.api.compatibilityToken;return t.isCompatible(Is.BackwardsCompatible,e)}async loadPools(){let[t,e]=await Promise.all([this.api.query.XYK.PoolAssets.getEntries(),this.getPoolLimits()]),n=t.map(async({keyArgs:r,value:a})=>{let[i]=r,[s,o]=a,[l,c,u,d]=await Promise.all([this.balance.getBalance(i,s),this.api.query.AssetRegistry.Assets.getValue(s),this.balance.getBalance(i,o),this.api.query.AssetRegistry.Assets.getValue(o)]);return{address:i,type:"XYK",tokens:[{id:s,decimals:c?.decimals||this.decimals.get(s),existentialDeposit:c?.existential_deposit,balance:l.transferable,type:c?.asset_type.type},{id:o,decimals:d?.decimals||this.decimals.get(o),existentialDeposit:d?.existential_deposit,balance:u.transferable,type:d?.asset_type.type}],...e}});return Promise.all(n)}async getPoolFees(){return{exchangeFee:await this.getExchangeFee()}}async getExchangeFee(){return await this.api.constants.XYK.GetExchangeFee()}subscribeUpdates(){return As.EMPTY}};var an={};A(an,{AavePool:()=>zt,AavePoolClient:()=>Kt});import{big as rr,RUNTIME_DECIMALS as ar}from"@galacticcouncil/common";var zt=class m{type;address;tokens;maxInRatio;maxOutRatio;minTradingLimit;static fromPool(t){return new m(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 n=new Map(this.tokens.map(i=>[i.id,i])),r=n.get(t),a=n.get(e);if(r==null)throw new Error("Pool does not contain tokenIn");if(a==null)throw new Error("Pool does not contain tokenOut");return{assetIn:t,assetOut:e,balanceIn:r.balance,balanceOut:a.balance,decimalsIn:r.decimals,decimalsOut:a.decimals,assetInEd:0n,assetOutEd:0n}}validateAndBuy(t,e,n){let r=this.calculateInGivenOut(t,e),a=[];return e>t.balanceOut&&a.push("TradeNotAllowed"),{amountIn:r,calculatedIn:r,amountOut:e,feePct:0,errors:a}}validateAndSell(t,e,n){let r=this.calculateOutGivenIn(t,e),a=[];return r>t.balanceOut&&a.push("TradeNotAllowed"),{amountIn:e,calculatedOut:r,amountOut:r,feePct:0,errors:a}}calculateInGivenOut(t,e){return e}calculateOutGivenIn(t,e){return e}spotPriceInGivenOut(t){return rr.toBigInt(1,ar)}spotPriceOutGivenIn(t){return rr.toBigInt(1,ar)}calculateTradeFee(t,e){return 0n}};import{AccountId as Os}from"polkadot-api";import{toHex as _s}from"@polkadot-api/utils";import{Subscription as sr,filter as rn,map as or}from"rxjs";import{decodeEventLog as Bs}from"viem";import{erc20 as Fs,HYDRATION_SS58_PREFIX as Rs}from"@galacticcouncil/common";var ir=[{anonymous:!1,inputs:[{indexed:!0,internalType:"address",name:"reserve",type:"address"},{indexed:!1,internalType:"address",name:"user",type:"address"},{indexed:!0,internalType:"address",name:"onBehalfOf",type:"address"},{indexed:!1,internalType:"uint256",name:"amount",type:"uint256"},{indexed:!0,internalType:"uint16",name:"referralCode",type:"uint16"}],name:"Supply",type:"event"},{anonymous:!1,inputs:[{indexed:!0,internalType:"address",name:"reserve",type:"address"},{indexed:!0,internalType:"address",name:"user",type:"address"},{indexed:!0,internalType:"address",name:"to",type:"address"},{indexed:!1,internalType:"uint256",name:"amount",type:"uint256"}],name:"Withdraw",type:"event"},{anonymous:!1,inputs:[{indexed:!0,internalType:"address",name:"reserve",type:"address"},{indexed:!1,internalType:"address",name:"user",type:"address"},{indexed:!0,internalType:"address",name:"onBehalfOf",type:"address"},{indexed:!1,internalType:"uint256",name:"amount",type:"uint256"},{indexed:!1,internalType:"enum DataTypes.InterestRateMode",name:"interestRateMode",type:"uint8"},{indexed:!1,internalType:"uint256",name:"borrowRate",type:"uint256"},{indexed:!0,internalType:"uint16",name:"referralCode",type:"uint16"}],name:"Borrow",type:"event"},{anonymous:!1,inputs:[{indexed:!0,internalType:"address",name:"reserve",type:"address"},{indexed:!0,internalType:"address",name:"user",type:"address"},{indexed:!0,internalType:"address",name:"repayer",type:"address"},{indexed:!1,internalType:"uint256",name:"amount",type:"uint256"},{indexed:!1,internalType:"bool",name:"useATokens",type:"bool"}],name:"Repay",type:"event"}];var{ERC20:Cs}=Fs,Es=["Supply","Withdraw","Repay","Borrow"],Kt=class extends N{getPoolType(){return"Aave"}async isSupported(){return!0}getPoolId(t,e){let n=t+"/"+e,r=new TextEncoder().encode(n.padEnd(32,"\0")),a=_s(r);return Os(Rs).dec(a)}getPoolLimits(){return{maxInRatio:0n,maxOutRatio:0n,minTradingLimit:0n}}async loadPools(){let e=(await this.api.apis.AaveTradeExecutor.pools({at:"best"})).map(async({reserve:n,atoken:r,liqudity_in:a,liqudity_out:i})=>{let[s,o,l,c]=await Promise.all([this.api.query.AssetRegistry.Assets.getValue(n),this.api.query.AssetRegistry.AssetLocations.getValue(n),this.api.query.AssetRegistry.Assets.getValue(r),this.api.query.AssetRegistry.AssetLocations.getValue(r)]);return{address:this.getPoolId(n,r),type:"Aave",tokens:[{id:n,decimals:s?.decimals,existentialDeposit:s?.existential_deposit,balance:a,location:o,type:s?.asset_type.type},{id:r,decimals:l?.decimals,existentialDeposit:l?.existential_deposit,balance:i,location:c,type:l?.asset_type.type}],...this.getPoolLimits()}});return Promise.all(e)}async getPoolDelta(t){let[e,n]=t.tokens,{liqudity_in:r,liqudity_out:a}=await this.api.apis.AaveTradeExecutor.pool(e.id,n.id,{at:"best"});return t.tokens.map(i=>{let s=i.id===e.id?r:a;return{...i,balance:s}})}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:n}=e.value;return n.key.asHex()}throw new Error("Invalid aave reserve multilocation")}return Cs.fromAssetId(t.id)}parseRouterLog(t){let{asset_in:e,asset_out:n}=t;return{assetIn:e,assetOut:n,key:`${e}:${n}`}}parseEvmLog(t){let{topics:e,data:n}=t.log,r=e.map(i=>i.asHex()),a=n.asHex();try{let{eventName:i,args:s}=Bs({abi:ir,topics:r,data:a}),o=s.reserve.toLowerCase();return{eventName:i,reserve:o,key:`${i}:${o}`}}catch{return}}subscribeRouterExecuted(){let e=this.store.pools.map(n=>n.tokens).map(([n,r])=>r).map(n=>n.id);return this.api.event.Router.Executed.watch().pipe(or(({payload:n})=>this.parseRouterLog(n)),rn(({assetIn:n,assetOut:r})=>e.includes(n)||e.includes(r)),this.watchGuard("router.Execute")).subscribe(({assetIn:n,assetOut:r,key:a})=>{this.log.trace("router.Executed",a),this.store.update(async i=>{let s=[];for(let o of i){let[l,c]=o.tokens;if(c.id===n||c.id===r){let d=await this.getPoolDelta(o);s.push({...o,tokens:d})}}return s})})}subscribeEvmLog(){return this.api.event.EVM.Log.watch().pipe(or(({payload:t})=>this.parseEvmLog(t)),rn(t=>t!==void 0),rn(({eventName:t})=>Es.includes(t)),this.watchGuard("evm.Log")).subscribe(({reserve:t,eventName:e})=>{this.log.trace(`evm.Log.${e}`,t),this.store.update(async n=>{let r=[];for(let a of n){let[i]=a.tokens;if(this.getReserveH160Id(i).toLowerCase()===t){let o=await this.getPoolDelta(a);r.push({...a,tokens:o})}}return r})})}subscribeBalances(){return sr.EMPTY}subscribeUpdates(){let t=new sr;return t.add(this.subscribeRouterExecuted()),t.add(this.subscribeEvmLog()),t}};var cn={};A(cn,{HsmMath:()=>U,HsmPool:()=>jt,HsmPoolClient:()=>Zt});import{calculate_collateral_in_given_hollar_out as ks,calculate_collateral_out_given_hollar_in as Ms,calculate_hollar_in_given_collateral_out as Ds,calculate_hollar_out_given_collateral_in as Ls,calculate_imbalance as qs,calculate_max_price as Ns,calculate_buyback_limit as Hs,calculate_buyback_price_with_fee as Gs}from"@galacticcouncil/math-hsm";var U=class{static calculateCollateralInGivenHollarOut(t,e,n){return ks(t,e,n)}static calculateCollateralOutGivenHollarIn(t,e,n){return Ms(t,e,n)}static calculateHollarOutGivenCollateralIn(t,e,n){return Ls(t,e,n)}static calculateHollarInGivenCollateralOut(t,e,n){return Ds(t,e,n)}static calculateImbalance(t,e,n){return qs(t,e,n)}static calculateBuybackLimit(t,e){return Hs(t,e)}static calculateBuybackPriceWithFee(t,e,n){return Gs(t,e,n)}static calculateMaxPrice(t,e){return Ns(t,e)}};import{big as J,RUNTIME_DECIMALS as Oe}from"@galacticcouncil/common";var{FeeUtils:yt}=x,jt=class m extends at{hsmAddress;hsmMintCapacity;hollarId;hollarH160;collateralId;collateralBalance;maxBuyPriceCoefficient;maxInHolding;purchaseFee;buyBackFee;buyBackRate;static fromPool(t){return new m(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,n){let r=this.parsePair(t.assetOut,t.assetIn),a=super.calculateInGivenOut(r,e,{fee:this.fee}),i=this.calculateBuybackLimit(t);e>i&&n.push("MaxBuyBackExceeded");let s=this.calculateMaxPrice(t);return this.calculateBuyPrice(t,e,a)>s&&n.push("MaxBuyPriceExceeded"),a>this.collateralBalance&&n.push("InsufficientCollateral"),n}validateTradeHollarOut(t,e,n){return this.collateralBalance+t>this.maxInHolding&&n.push("MaxHoldingExceeded"),e>this.hsmMintCapacity&&n.push("FacilitatorCapacityExceeded"),n}validateTradeConstraints(t,e,n){let r=[];return t.assetIn===this.hollarId?this.validateTradeHollarIn(t,e,r):this.validateTradeHollarOut(e,n,r)}validateAndBuy(t,e){let n=this.calculateInGivenOut(t,e),r=this.validateTradeConstraints(t,n,e);return{amountIn:n,calculatedIn:n,amountOut:e,feePct:0,errors:r}}validateAndSell(t,e){let n=this.calculateOutGivenIn(t,e),r=this.validateTradeConstraints(t,e,n);return{amountIn:e,calculatedOut:n,amountOut:n,feePct:0,errors:r}}calculateHollarInGivenCollateralOut(t,e){let n=super.calculateInGivenOut(t,e,{fee:this.fee}),r=U.calculateHollarInGivenCollateralOut(e.toString(),n.toString(),yt.toRaw(this.buyBackFee).toString());return BigInt(r)}calculateCollateralInGivenHollarOut(t){let e=this.getCollateralPeg(),n=U.calculateCollateralInGivenHollarOut(t.toString(),JSON.stringify(e),yt.toRaw(this.purchaseFee).toString());return BigInt(n)}calculateInGivenOut(t,e){return t.assetOut==this.hollarId?this.calculateCollateralInGivenHollarOut(e):this.calculateHollarInGivenCollateralOut(t,e)}calculateCollateralOutGivenHollarIn(t,e){let n=super.calculateOutGivenIn(t,e,{fee:this.fee}),r=U.calculateCollateralOutGivenHollarIn(e.toString(),n.toString(),yt.toRaw(this.buyBackFee).toString());return BigInt(r)}calculateHollarOutGivenCollateralIn(t){let e=this.getCollateralPeg(),n=U.calculateHollarOutGivenCollateralIn(t.toString(),JSON.stringify(e),yt.toRaw(this.purchaseFee).toString());return BigInt(n)}calculateOutGivenIn(t,e){return t.assetIn==this.hollarId?this.calculateCollateralOutGivenHollarIn(t,e):this.calculateHollarOutGivenCollateralIn(e)}calculateImbalance(t){let e=this.getCollateralPeg(),n=U.calculateImbalance(t.balanceIn.toString(),JSON.stringify(e),t.balanceOut.toString());return BigInt(n)}calculateBuybackLimit(t){let e=this.calculateImbalance(t),n=U.calculateBuybackLimit(e.toString(),yt.toRaw(this.buyBackRate).toString());return BigInt(n)}calculateBuyPrice(t,e,n){let r=U.calculateBuybackPriceWithFee(n.toString(),e.toString(),yt.toRaw(this.buyBackFee).toString()),[a,i]=JSON.parse(r),s=J.pow10(t.decimalsIn+Oe-t.decimalsOut);return BigInt(a)*s/BigInt(i)}calculateMaxPrice(t){let e=this.getCollateralPeg(),n=U.calculateMaxPrice(JSON.stringify(e),this.maxBuyPriceCoefficient.toString()),[r,a]=JSON.parse(n),i=J.pow10(Oe-t.decimalsOut);return BigInt(r)*i/BigInt(a)}spotPriceInGivenOut(t){let e=J.toBigInt(1,t.decimalsOut),r=this.calculateInGivenOut(t,e)*J.pow10(Oe-t.decimalsOut);return this.normalizeSpotPrice(r,t.decimalsOut,t.decimalsIn)}spotPriceOutGivenIn(t){let e=J.toBigInt(1,t.decimalsIn),r=this.calculateOutGivenIn(t,e)*J.pow10(Oe-t.decimalsIn);return this.normalizeSpotPrice(r,t.decimalsIn,t.decimalsOut)}getCollateralPeg(){let t=this.tokens.findIndex(r=>r.id!==this.hollarId),e=this.pegs[t],n=this.tokens[t].decimals;return this.isDefaultPeg(e)?[J.toBigInt(1,18).toString(),J.toBigInt(1,n).toString()]:e}isDefaultPeg(t){let[e,n]=t;return Array.isArray(t)&&t.length===2&&e==="1"&&n==="1"}normalizeSpotPrice(t,e,n){let r=e-n;if(r===0)return t;let a=J.pow10(Math.abs(r));return r>0?t*a:t/a}};import{AccountId as Vs,CompatibilityLevel as Us}from"polkadot-api";import{toHex as Ws}from"@polkadot-api/utils";import{Subscription as sn,combineLatest as Ys,filter as lr,map as on,pairwise as $s}from"rxjs";import{decodeEventLog as Xs}from"viem";import{h160 as zs,HYDRATION_SS58_PREFIX as Ks}from"@galacticcouncil/common";var Qt=[{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 Jt=class{client;constructor(t){this.client=t.getWsProvider()}async getFacilitatorCapacity(t,e){let[n,r]=await this.client.readContract({abi:Qt,address:t,functionName:"getFacilitatorBucket",args:[e]});return n-r}};var{FeeUtils:ln}=x,{H160:cr}=zs,js=["FacilitatorBucketCapacityUpdated","FacilitatorBucketLevelUpdated"],Zt=class extends N{ghoClient;stableClient;constructor(t,e,n){super(t,e),this.stableClient=n,this.ghoClient=new Jt(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:n}=e.value;return n.key.asHex()}}throw Error("Invalid hollar multilocation")}getPoolAddress(t){let e=t.padEnd(32,"\0"),n=new TextEncoder().encode(e),r=Ws(n);return Vs(Ks).dec(r)}async isSupported(){let t=this.api.query.HSM.Collaterals,e=await this.api.compatibilityToken;return t.isCompatible(Us.BackwardsCompatible,e)}async loadPools(){let t=await this.api.constants.HSM.HollarId(),[e,n,r]=await Promise.all([this.api.query.AssetRegistry.AssetLocations.getValue(t),this.api.query.HSM.Collaterals.getEntries({at:"best"}),this.stableClient.getPools()]);if(n.length===0)return[];let a=this.getFacilitatorAddress(),i=cr.fromAny(a),s=this.getHollarAddress(e),o=await this.ghoClient.getFacilitatorCapacity(s,i),l=n.map(async({keyArgs:u,value:d})=>{let[p]=u,{pool_id:h,max_buy_price_coefficient:b,max_in_holding:g,purchase_fee:f,buy_back_fee:y,buyback_rate:S}=d,P=r.find(T=>T.id===h);if(P){let T=this.getPoolId(h),w=await this.balance.getBalance(a,p);return{...P,address:T,type:"HSM",tokens:P.tokens.filter(F=>F.id!==h),hsmAddress:a,hsmMintCapacity:o,hollarId:t,hollarH160:s,collateralId:p,collateralBalance:w.transferable,maxBuyPriceCoefficient:b,maxInHolding:g,purchaseFee:ln.fromPermill(f),buyBackFee:ln.fromPermill(y),buyBackRate:ln.fromPerbill(S)}}});return(await Promise.all(l)).filter(u=>u!==null)}async getPoolFees(){return{}}parseEvmLog(t){let{topics:e,data:n}=t.log,r=e.map(i=>i.asHex()),a=n.asHex();try{let{eventName:i,args:s}=Xs({abi:Qt,topics:r,data:a}),o=s.facilitatorAddress.toLowerCase();return{eventName:i,facilitator:o,key:`${i}:${o}`}}catch{return}}subscribeEvmLog(){return this.api.event.EVM.Log.watch().pipe(on(({payload:t})=>this.parseEvmLog(t)),lr(t=>t!==void 0),lr(({eventName:t})=>js.includes(t)),this.watchGuard("evm.Log")).subscribe(({eventName:t,facilitator:e})=>{this.log.trace(`evm.Log.${t}`,e),this.store.update(async n=>{let r=[],[{hsmAddress:a,hollarH160:i}]=n,s=cr.fromAny(a);if(s.toLowerCase()===e){let l=await this.ghoClient.getFacilitatorCapacity(i,s);for(let c of n)r.push({...c,hsmMintCapacity:l})}return r})})}subscribeCollateralBalance(){let t=[],e=[];this.store.pools.forEach(a=>{let{tokens:i,collateralId:s}=a;i.find(l=>l.id===s).type==="Erc20"?e.push(s):t.push(s)});let[{hsmAddress:n}]=this.store.pools,r=[];if(t.length>0){let a=this.balance.watchTokensBalance(n);r.push(a)}if(e.length>0){let a=this.balance.watchErc20Balance(n,e);r.push(a)}return r.length>0?Ys(r).pipe(on(a=>a.flat()),$s(),on(([a,i])=>this.balance.getDeltas(a,i)),this.watchGuard("balances")).subscribe(a=>{this.store.update(i=>{let s=[],o=new Map(i.map(l=>[l.collateralId,l]));return a.forEach(({id:l,balance:c})=>{let u=o.get(l);u&&(this.log.trace("balances",{id:l,balance:c}),s.push({...u,collateralBalance:c.transferable}))}),s})}):sn.EMPTY}subscribeStableswapUpdates(){return this.stableClient.getSubscriber().pipe(this.watchGuard("stableswap.updates")).subscribe(t=>{let e=new Map(t.map(n=>[n.id,n]));this.store.update(n=>{let r=[];for(let a of n){let i=e.get(a.id);i&&r.push({...a,fee:i.fee,tokens:i.tokens.filter(s=>s.id!==a.id),totalIssuance:i.totalIssuance,pegs:i.pegs,amplification:i.amplification,isRampPeriod:i.isRampPeriod})}return r})})}subscribeBalances(){return sn.EMPTY}subscribeUpdates(){let t=new sn;return t.add(this.subscribeCollateralBalance()),t.add(this.subscribeStableswapUpdates()),t.add(this.subscribeEvmLog()),t}};var ft=class{static get(t){switch(t.type){case"Aave":return zt.fromPool(t);case"XYK":return $t.fromPool(t);case"Omnipool":return Vt.fromPool(t);case"LBP":return Ht.fromPool(t);case"Stableswap":return at.fromPool(t);case"HSM":return jt.fromPool(t);default:throw new Error("Pool type "+t.type+" is not supported yet")}}};import{log as Qs}from"@galacticcouncil/common";import{Subject as Js,Subscription as Pt,takeUntil as Zs}from"rxjs";var{logger:to}=Qs,St=class extends B{evm;aave;omnipool;stableswap;hsm;xyk;lbp;active=new Set([]);pools=new Map([]);clients=[];aaveSub=Pt.EMPTY;omniSub=Pt.EMPTY;stableSub=Pt.EMPTY;hsmSub=Pt.EMPTY;xykSub=Pt.EMPTY;lbpSub=Pt.EMPTY;isReady=!1;isDestroyed=new Js;constructor(t,e){super(t),this.evm=e,this.aave=new Kt(t,e),this.omnipool=new Wt(t,e),this.stableswap=new Yt(t,e),this.hsm=new Zt(t,e,this.stableswap),this.xyk=new Xt(t,e),this.lbp=new Gt(t,e),this.clients=[this.aave,this.omnipool,this.stableswap,this.hsm,this.xyk,this.lbp]}subscribe(t){return t.getSubscriber().pipe(Zs(this.isDestroyed)).subscribe(e=>{e.forEach(n=>{this.pools.set(n.address,n)})})}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")||(to.info("[PoolContextProvider] auto-activating stableswap"),this.withStableswap()),this.hsmSub.unsubscribe(),this.hsmSub=this.subscribe(this.hsm),this.active.add("HSM"),this}withXyk(t){return this.xyk.withOverride(t),this.xykSub.unsubscribe(),this.xykSub=this.subscribe(this.xyk),this.active.add("XYK"),this}withLbp(){return this.lbpSub.unsubscribe(),this.lbpSub=this.subscribe(this.lbp),this.active.add("LBP"),this}destroy(){this.isDestroyed.next(!0),this.isDestroyed.complete(),this.active.clear(),this.pools.clear(),this.isReady=!1}async getPools(){if(this.isReady){let e=this.pools.values();return Array.from(e)}let t=await Promise.all(this.clients.filter(e=>this.active.has(e.getPoolType())).map(e=>e.getPools()));return this.isReady=!0,t.flat()}async getPoolFees(t,e){let n=this.clients.find(r=>r.getPoolType()===e.type);if(n)return n.getPoolFees(t,e.address);throw new Et(e.type)}};var br={};A(br,{DCA_TIME_RESERVE:()=>dr,DEFAULT_BLOCK_TIME:()=>pr,DEFAULT_MIN_BUDGET:()=>pn,ORDER_MIN_BLOCK_PERIOD:()=>gr,Router:()=>Tt,TWAP_EXECUTION_INTERVAL:()=>re,TWAP_MAX_DURATION:()=>gn,TWAP_MAX_PRICE_IMPACT:()=>dn,TWAP_TX_MULTIPLIER:()=>rb,TradeOrderError:()=>mn,TradeOrderType:()=>Be,TradeRouteBuilder:()=>G,TradeRouter:()=>tt,TradeScheduler:()=>xt,TradeType:()=>_e});var te=class{constructor(t=1/0){this.capacity=t}storage=[];enqueue(t){if(this.size()===this.capacity)throw Error("Queue has reached max capacity, you cannot add more items");this.storage.push(t)}dequeue(){return this.storage.shift()}size(){return this.storage.length}};var eo=10,ee=class{isNotVisited(t,e){let n=!0;return e.forEach(r=>{(r[0]===t[0]||r[1]===t[1])&&(n=!1)}),n}findPaths(t,e,n){let r=[],a=new te,i=[];for(i.push([e,""]),a.enqueue(i);a.size()>0;){let s=a.dequeue();if(!s||s.length>eo)continue;let o=s[s.length-1];(n===null||o[0]===n)&&r.push(s),t.get(o[0])?.forEach(c=>{if(this.isNotVisited(c,s)){let u=[...s];u.push(c),a.enqueue(u)}})}return r}findShortestPaths(t,e,n){let r=[],a=new te,i=[];i.push([e,""]),a.enqueue(i);let s=1/0;for(;a.size()>0;){let o=a.dequeue();if(!o)continue;let l=o[o.length-1];if(l[0]===n){o.length<s?(s=o.length,r.length=0,r.push(o)):o.length===s&&r.push(o);continue}let c=t.get(l[0]);for(let u of c??[])this.isNotVisited(u,o)&&a.enqueue([...o,u])}return r}buildAndPopulateGraph(t,e){let n=new Map;for(let r of t)n.set(parseInt(r),[]);for(let[r,a,i]of e)n.get(a)?.push([i,r]);return n}};function un(m){let t={};for(let e of m){let n=e.tokens.length;for(let r=0;r<n;r++){t[e.tokens[r].id]||(t[e.tokens[r].id]=[]);for(let a=0;a<n;a++){if(r==a)continue;let i=[e.address,e.tokens[r].id,e.tokens[a].id];t[e.tokens[r].id].push(i)}}}return t}var ne=class{getProposals(t,e,n){let r=n.filter(g=>g.type==="XYK"),a=n.filter(g=>g.type!=="XYK"),i=new Set(a.map(g=>g.tokens).flat().map(g=>g.id)),s=i.has(t),o=i.has(e),l=new ee,c=g=>{let f=un(g),y=Object.keys(f),S=y.flatMap(P=>f[P]);return l.buildAndPopulateGraph(y,S)};if(!s&&!o){let g=r.filter(S=>S.tokens.find(P=>P.id===t)||S.tokens.find(P=>P.id===e)),f=c(g),y=l.findPaths(f,t,e);return this.parsePaths(y)}if(s&&o){let g=c(a),f=l.findPaths(g,t,e);return this.parsePaths(f)}let u=s?e:t,d=r.filter(g=>g.tokens.some(f=>f.id===u));if(d.length===0)return[];let p=[...a,...d],h=c(p),b=l.findPaths(h,t,e);return this.parsePaths(b)}parsePaths(t){let e=[];for(let n of t){let r=[];for(let a=0;a<n.length;a++){let i=n[a],s=n[a+1];if(s==null)break;r.push(this.toEdge(i,s))}e.push(r)}return e}toEdge(t,e){return[e[1],t[0],e[0]]}};var Tt=class{routeSuggester;routeProposals;ctx;filter={};constructor(t){this.ctx=t,this.routeSuggester=new ne,this.routeProposals=new Map}async withFilter(t){this.filter=t||{},this.routeProposals.clear(),this.onFilterChanged()}onFilterChanged(){}buildRouteKey(t,e,n){return`${t}->${e}::${n.length}`}applyPoolFilter(t){let{useOnly:e=[],exclude:n=[]}=this.filter,r=new Set(e),a=new Set(n);return t.filter(i=>a.has(i.type)?!1:r.size>0?r.has(i.type):!0)}async getPools(){let t=await this.ctx.getPools();return this.applyPoolFilter(t)}async getRoutes(t,e){let n=await this.getPools();return this.validateInput(t,e,n),this.getPaths(t,e,n)}async getTradeableAssets(){let t=await this.getPools(),e=this.getAssets(t);return Array.from(e)}async getRouteableAssets(t){let e=await this.getTradeableAssets();return(await Promise.all(e.filter(r=>r!==t).map(r=>this.getRoutes(r,t)))).filter(r=>r.length>0).map(([r])=>r[0].assetIn).sort()}validateInput(t,e,n){if(n.length===0)throw new Error("No pools configured");if(t===e)throw new Error("Trading pair can't be identical");let r=this.getAssets(n);if(!r.has(t))throw new Error(t+" is not supported asset");if(!r.has(e))throw new Error(e+" is not supported asset");return this.toPoolsMap(n)}getAssets(t){let e=t.map(n=>n.tokens.map(r=>r.id)).flat().sort((n,r)=>n>r?1:-1);return new Set(e)}getPaths(t,e,n){let r=this.toPoolsMap(n);return this.getProposals(t,e,n).filter(i=>this.validPath(i,r)).map(i=>this.toHops(i,r))}getProposals(t,e,n){let r=this.buildRouteKey(t,e,n);if(this.routeProposals.has(r))return this.routeProposals.get(r);let a=this.routeSuggester.getProposals(t,e,n);return this.routeProposals.set(r,a),a}validPath(t,e){return t.length>0&&t.map(n=>this.validEdge(n,e)).reduce((n,r)=>n&&r)}validEdge([t,e,n],r){return r.get(t)?.validatePair(e,n)||!1}toPoolsMap(t){return new Map(t.map(e=>[e.address,ft.get(e)]))}toHops(t,e){return t.map(([n,r,a])=>{let i=e.get(n);return{poolAddress:n,poolId:i?.id,pool:i?.type,assetIn:r,assetOut:a}})}};import{big as C,RUNTIME_DECIMALS as wt}from"@galacticcouncil/common";var _e=(e=>(e.Buy="Buy",e.Sell="Sell",e))(_e||{}),Be=(n=>(n.Dca="Dca",n.TwapSell="TwapSell",n.TwapBuy="TwapBuy",n))(Be||{}),mn=(n=>(n.OrderTooSmall="OrderTooSmall",n.OrderTooBig="OrderTooBig",n.OrderImpactTooBig="OrderImpactTooBig",n))(mn||{});var{FeeUtils:mr}=x,tt=class extends Tt{mlr;constructor(t){super(t),this.mlr=new Map}onFilterChanged(){this.mlr.clear()}buildCtxSync(t,e,n){let r=super.validateInput(t,e,n),a=super.getPaths(t,e,n);if(!a.length)throw new kt(t,e);return{paths:a,pools:n,poolsMap:r}}async withCtx(t,e,n){let r=await super.getPools(),a=this.buildCtxSync(t,e,r);return n(a)}isDirectTrade(t){return t.length==1}findBestSellRoute(t){let e=t.sort((n,r)=>{let a=n[n.length-1].amountOut,i=r[r.length-1].amountOut;return a>i?-1:1});return e.find(n=>n.every(r=>r.errors.length==0))||e[0]}getRouteFeeRange(t){if(t.filter(n=>n.tradeFeeRange).length>0){let n=t.map(a=>a.tradeFeeRange?.[0]??a.tradeFeePct).reduce((a,i)=>a+i),r=t.map(a=>a.tradeFeeRange?.[1]??a.tradeFeePct).reduce((a,i)=>a+i);return[n,r]}}getPoolFeeRange(t,e){let n=t.min?mr.toPct(t.min):void 0,r=t.max?mr.toPct(t.max):void 0;if(n&&r)return[n,Math.max(r,e)]}async getBestSell(t,e,n){return this.getSell(t,e,n)}getSellSpot(t){let e=t[t.length-1];return t.length===1?e.spotPrice:this.calculateSpot(t)}async getSell(t,e,n,r){return this.withCtx(t,e,async({paths:a,poolsMap:i})=>{let s;if(r)s=await this.toSellSwaps(n,r,i);else{let o=a.map(c=>this.toSellSwaps(n,c,i)),l=await Promise.all(o);s=this.findBestSellRoute(l)}return this.buildSell(i,s)})}async getSells(t,e,n){return this.withCtx(t,e,async({paths:r,poolsMap:a})=>{let i=r.map(o=>this.toSellSwaps(n,o,a));return(await Promise.all(i)).filter(o=>o.every(l=>l.errors.length==0)).map(o=>this.buildSell(a,o)).sort((o,l)=>o.amountOut>l.amountOut?-1:1)})}buildSell(t,e){let n=e[0],r=e[e.length-1],a=this.isDirectTrade(e),i=this.getSellSpot(e),s=r.amountOut,o=a?r.calculatedOut:this.calculateDelta0Y(n.amountIn,e,t),l=o-s,c=this.getRouteFeeRange(e),u=a?r.tradeFeePct:L.calculateSellFee(o,s),d=R.mulSpot(n.amountIn,i,n.assetInDecimals,r.assetOutDecimals),p=L.calculateDiffToRef(o,d);return{type:"Sell",amountIn:n.amountIn,amountOut:r.amountOut,spotPrice:i,tradeFee:l,tradeFeePct:u,tradeFeeRange:c,priceImpactPct:p,swaps:e,toHuman(){return{type:"Sell",amountIn:C.toDecimal(n.amountIn,n.assetInDecimals),amountOut:C.toDecimal(r.amountOut,r.assetOutDecimals),spotPrice:C.toDecimal(i,wt),tradeFee:C.toDecimal(l,r.assetOutDecimals),tradeFeePct:u,tradeFeeRange:c,priceImpactPct:p,swaps:e.map(h=>h.toHuman())}}}}calculateSpot(t){return t.map(e=>e.spotPrice).reduce((e,n)=>e*n/10n**BigInt(wt))}calculateDelta0Y(t,e,n){let r=[];for(let a=0;a<e.length;a++){let i=e[a],s=n.get(i.poolAddress);if(s==null)throw new Error("Pool does not exit");let o=s.parsePair(i.assetIn,i.assetOut),l;a>0?l=r[a-1]:l=t;let c=s.calculateOutGivenIn(o,l);r.push(c)}return r[r.length-1]}async calculateMostLiquidRoute(t,e,n){let{paths:r,pools:a,poolsMap:i}=n,l=a.filter(b=>b.tokens.some(g=>g.id===t)).map(b=>b.type==="Aave"?b.tokens:b.tokens.filter(g=>g.id===t)).map(b=>b.map(g=>g.balance).reduce((g,f)=>g+f)).sort((b,g)=>g<b?-1:1)[0],c=R.getFraction(l,.1),u=await Promise.all(r.map(b=>this.toSellSwaps(c,b,i))),p=this.findBestSellRoute(u).map(b=>({poolAddress:b.poolAddress,poolId:b?.poolId,pool:b.pool,assetIn:b.assetIn,assetOut:b.assetOut})),h=this.buildRouteKey(t,e,a);return this.mlr.set(h,p),p}async toSellSwaps(t,e,n){let r=[];for(let a=0;a<e.length;a++){let i=e[a],s=n.get(i.poolAddress);if(s==null)throw new Error("Pool does not exit");let o=s.parsePair(i.assetIn,i.assetOut),l;a>0?l=r[a-1].amountOut:l=typeof t=="string"?C.toBigInt(t,o.decimalsIn):t;let c=await this.ctx.getPoolFees(o,s),{amountOut:u,calculatedOut:d,feePct:p,errors:h}=s.validateAndSell(o,l,c),b=this.getPoolFeeRange(c,p),g=s.spotPriceOutGivenIn(o),f=R.mulSpot(l,g,o.decimalsIn,o.decimalsOut),y=L.calculateDiffToRef(d,f);r.push({...i,assetInDecimals:o.decimalsIn,assetOutDecimals:o.decimalsOut,amountIn:l,amountOut:u,calculatedOut:d,spotPrice:g,tradeFeePct:p,tradeFeeRange:b,priceImpactPct:y,errors:h,isSupply(){return s.type==="Aave"&&s.tokens[0].id===i.assetIn},isWithdraw(){return s.type==="Aave"&&s.tokens[1].id===i.assetIn},toHuman(){return{...i,amountIn:C.toDecimal(l,o.decimalsIn),amountOut:C.toDecimal(u,o.decimalsOut),calculatedOut:C.toDecimal(d,o.decimalsOut),spotPrice:C.toDecimal(g,wt),tradeFeePct:p,tradeFeeRange:b,priceImpactPct:y,errors:h}}})}return r}async getMostLiquidRoute(t,e){return this.withCtx(t,e,async n=>{let r=this.buildRouteKey(t,e,n.pools),a=this.mlr.get(r);return a||this.calculateMostLiquidRoute(t,e,n)})}async getSpotPrice(t,e){return this.withCtx(t,e,async n=>{let{pools:r,poolsMap:a}=n,i=this.buildRouteKey(t,e,r),s=this.mlr.get(i);s||(s=await this.calculateMostLiquidRoute(t,e,n));let o=await this.toSellSwaps("1",s,a);return{amount:this.getSellSpot(o),decimals:wt}}).catch(()=>{})}findBestBuyRoute(t){let e=t.sort((n,r)=>{let a=n[0].amountIn,i=r[0].amountIn;return a>i?1:-1});return e.find(n=>n.every(r=>r.errors.length==0))||e[0]}async getBestBuy(t,e,n){return this.getBuy(t,e,n)}getBuySpot(t){let e=t[0];return t.length===1?e.spotPrice:this.calculateSpot(t)}async getBuy(t,e,n,r){return this.withCtx(t,e,async({paths:a,poolsMap:i})=>{let s;if(r)s=await this.toBuySwaps(n,r,i);else{let o=a.map(c=>this.toBuySwaps(n,c,i)),l=await Promise.all(o);s=this.findBestBuyRoute(l)}return this.buildBuy(i,s)})}async getBuys(t,e,n){return this.withCtx(t,e,async({paths:r,poolsMap:a})=>{let i=r.map(o=>this.toBuySwaps(n,o,a));return(await Promise.all(i)).filter(o=>o.every(l=>l.errors.length==0)).map(o=>this.buildBuy(a,o)).sort((o,l)=>o.amountIn>l.amountIn?1:-1)})}buildBuy(t,e){let n=e[e.length-1],r=e[0],a=this.isDirectTrade(e),i=this.getBuySpot(e),s=r.amountIn,o=a?r.calculatedIn:this.calculateDelta0X(n.amountOut,e,t),l=s-o,c=this.getRouteFeeRange(e),u=a?r.tradeFeePct:L.calculateBuyFee(o,s),d=R.mulSpot(n.amountOut,i,n.assetOutDecimals,r.assetInDecimals),p;return o===0n?p=-100:p=L.calculateDiffToRef(d,o),{type:"Buy",amountOut:n.amountOut,amountIn:r.amountIn,spotPrice:i,tradeFee:l,tradeFeePct:u,tradeFeeRange:c,priceImpactPct:p,swaps:e,toHuman(){return{type:"Buy",amountOut:C.toDecimal(n.amountOut,n.assetOutDecimals),amountIn:C.toDecimal(r.amountIn,r.assetInDecimals),spotPrice:C.toDecimal(i,wt),tradeFee:C.toDecimal(l,r.assetInDecimals),tradeFeePct:u,tradeFeeRange:c,priceImpactPct:p,swaps:e.map(h=>h.toHuman())}}}}calculateDelta0X(t,e,n){let r=[];for(let a=e.length-1;a>=0;a--){let i=e[a],s=n.get(i.poolAddress);if(s==null)throw new Error("Pool does not exit");let o=s.parsePair(i.assetIn,i.assetOut),l;a==e.length-1?l=t:l=r[0];let c=s.calculateInGivenOut(o,l);r.unshift(c)}return r[0]}async toBuySwaps(t,e,n){let r=[];for(let a=e.length-1;a>=0;a--){let i=e[a],s=n.get(i.poolAddress);if(s==null)throw new Error("Pool does not exit");let o=s.parsePair(i.assetIn,i.assetOut),l;a==e.length-1?l=typeof t=="string"?C.toBigInt(t,o.decimalsOut):t:l=r[0].amountIn;let c=await this.ctx.getPoolFees(o,s),{amountIn:u,calculatedIn:d,feePct:p,errors:h}=s.validateAndBuy(o,l,c),b=this.getPoolFeeRange(c,p),g=s.spotPriceInGivenOut(o),f=R.mulSpot(l,g,o.decimalsOut,o.decimalsIn),y;d===0n?y=-100:y=L.calculateDiffToRef(f,d),r.unshift({...i,assetInDecimals:o.decimalsIn,assetOutDecimals:o.decimalsOut,amountOut:l,amountIn:u,calculatedIn:d,spotPrice:g,tradeFeePct:p,tradeFeeRange:b,priceImpactPct:y,errors:h,isSupply(){return s.type==="Aave"&&s.tokens[0].id===i.assetIn},isWithdraw(){return s.type==="Aave"&&s.tokens[1].id===i.assetIn},toHuman(){return{...i,amountOut:C.toDecimal(l,o.decimalsOut),amountIn:C.toDecimal(u,o.decimalsIn),calculatedIn:C.toDecimal(d,o.decimalsIn),spotPrice:C.toDecimal(g,wt),tradeFeePct:p,tradeFeeRange:b,priceImpactPct:y,errors:h}}})}return r}};import{big as D}from"@galacticcouncil/common";var pr=6e3,pn=1000000000000000n,re=6,dn=-5,gn=216e5,rb=3,dr=.1,gr=6;import{Enum as hr}from"polkadot-api";var G=class{static build(t){return t.map(({assetIn:e,assetOut:n,pool:r,poolId:a})=>r==="Stableswap"?{pool:hr("Stableswap",a),asset_in:e,asset_out:n}:{pool:hr(r),asset_in:e,asset_out:n})}};var xt=class{schedulerOptions;router;constructor(t,e={}){this.router=new tt(t),this.router.withFilter({exclude:["HSM"]}),this.schedulerOptions=Object.freeze({blockTime:e.blockTime??6e3,minBudgetInNative:e.minBudgetInNative??pn})}get blockTime(){return this.schedulerOptions.blockTime}get minOrderBudget(){return this.schedulerOptions.minBudgetInNative}async getDcaOrder(t,e,n,r,a){let i=await this.router.getBestSell(t,e,n),{amountIn:s,swaps:o,priceImpactPct:l}=i,c=o[0],u=o[o.length-1],{assetInDecimals:d}=c,{assetOutDecimals:p}=u,h=Math.abs(l),b=await this.getMinimumOrderBudget(t,d),g=this.getOptimalTradeCount(h),f=this.getMaximumTradeCount(s,b,r),y=a||Math.min(g,f),S=Math.round(r/y),P=s/BigInt(y),T=await this.router.getBestSell(t,e,P),w=s<b,F=[];w&&F.push("OrderTooSmall");let k=T.amountOut*BigInt(y),$=this.toBlockPeriod(S),K=T.tradeFee*BigInt(y),H=G.build(o),V={assetIn:t,assetOut:e,errors:F,maxTradeCount:f,tradeCount:y,tradeFee:K,tradeImpactPct:T.priceImpactPct,tradePeriod:$,tradeRoute:H,type:"Dca"};return{...V,amountIn:s,amountOut:k,tradeAmountIn:T.amountIn,tradeAmountOut:T.amountOut,toHuman(){return{...V,amountIn:D.toDecimal(s,d),amountOut:D.toDecimal(k,p),tradeAmountIn:D.toDecimal(T.amountIn,d),tradeAmountOut:D.toDecimal(T.amountOut,p)}}}}async getMinimumOrderBudget(t,e){if(0===t)return this.minOrderBudget;let n=await this.router.getSpotPrice(0,t);if(n)return R.mulSpot(this.minOrderBudget,n.amount,12,e);let r=await this.router.getSpotPrice(t,0);if(r)return R.divSpot(this.minOrderBudget,r.amount,12,e);throw new Error("Unable to calculate order budget")}getMaximumTradeCount(t,e,n){let r=e*2n/10n;if(r===0n)return 0;let a=Number(t/r),i=Math.floor(n/this.blockTime),s=Math.max(0,Math.floor(i*(1-.1)));return Math.min(a,s)}getOptimalTradeCount(t){let e=Math.round(t*10)||1;return Math.max(e,3)}async getOpenBudgetDcaOrder(t,e,n,r){let a=await this.router.getBestSell(t,e,n),{swaps:i}=a,s=i[0],o=i[i.length-1],{assetInDecimals:l}=s,{assetOutDecimals:c}=o,u=await this.getMinimumOrderBudget(t,l),d=a.amountIn<u,p=[];d&&p.push("OrderTooSmall");let h=this.toBlockPeriod(r),b=G.build(i),g={assetIn:t,assetOut:e,errors:p,maxTradeCount:0,tradeCount:0,tradeFee:a.tradeFee,tradeImpactPct:a.priceImpactPct,tradePeriod:h,tradeRoute:b,type:"Dca"};return{...g,amountIn:0n,amountOut:0n,tradeAmountIn:a.amountIn,tradeAmountOut:a.amountOut,toHuman(){return{...g,amountIn:"0",amountOut:"0",tradeAmountIn:D.toDecimal(a.amountIn,l),tradeAmountOut:D.toDecimal(a.amountOut,c)}}}}async getTwapSellOrder(t,e,n){let r=await this.router.getBestSell(t,e,n),{amountIn:a,swaps:i,priceImpactPct:s}=r,o=i[0],l=i[i.length-1],{assetInDecimals:c}=o,{assetOutDecimals:u}=l,d=Math.abs(s),p=this.getTwapTradeCount(d),h=a/BigInt(p),[b,g]=await Promise.all([this.getMinimumOrderBudget(t,c),this.router.getBestSell(o.assetIn,l.assetOut,h)]),f=p===1,y=a<b,S=g.priceImpactPct<-5,P=[];y||f?P.push("OrderTooSmall"):S&&P.push("OrderImpactTooBig");let T=g.amountOut*BigInt(p),w=g.tradeFee*BigInt(p),F=G.build(i),k={assetIn:t,assetOut:e,errors:P,tradeCount:p,tradeImpactPct:g.priceImpactPct,tradePeriod:6,tradeRoute:F,type:"TwapSell"};return{...k,amountIn:a,amountOut:T,tradeAmountIn:g.amountIn,tradeAmountOut:g.amountOut,tradeFee:w,toHuman(){return{...k,amountIn:D.toDecimal(a,c),amountOut:D.toDecimal(T,u),tradeAmountIn:D.toDecimal(g.amountIn,c),tradeAmountOut:D.toDecimal(g.amountOut,u),tradeFee:D.toDecimal(w,u)}}}}async getTwapBuyOrder(t,e,n){let r=await this.router.getBestBuy(t,e,n),{amountOut:a,swaps:i,priceImpactPct:s}=r,o=i[0],l=i[i.length-1],{assetInDecimals:c}=o,{assetOutDecimals:u}=l,d=Math.abs(s),p=this.getTwapTradeCount(d),h=a/BigInt(p),[b,g]=await Promise.all([this.getMinimumOrderBudget(t,c),this.router.getBestBuy(o.assetIn,l.assetOut,h)]),f=g.amountIn*BigInt(p),y=p===1,S=f<b,P=g.priceImpactPct<-5,T=[];S||y?T.push("OrderTooSmall"):P&&T.push("OrderImpactTooBig");let w=g.tradeFee*BigInt(p),F=G.build(i),k={assetIn:t,assetOut:e,errors:T,tradeCount:p,tradeImpactPct:g.priceImpactPct,tradePeriod:6,tradeRoute:F,type:"TwapBuy"};return{...k,amountIn:f,amountOut:a,tradeAmountIn:g.amountIn,tradeAmountOut:g.amountOut,tradeFee:w,toHuman(){return{...k,amountIn:D.toDecimal(f,c),amountOut:D.toDecimal(a,u),tradeAmountIn:D.toDecimal(g.amountIn,c),tradeAmountOut:D.toDecimal(g.amountOut,u),tradeFee:D.toDecimal(w,c)}}}}getTwapTradeCount(t){let e=this.getOptimalTradeCount(t);if(this.getTwapExecutionTime(e)>216e5){let r=216e5/(this.blockTime*6);return Math.round(r)}return e}getTwapExecutionTime(t){return t*6*this.blockTime}toBlockPeriod(t){let e=t/this.blockTime,n=Math.round(e);return Math.max(n,6)}};var xr={};A(xr,{BIG_10:()=>wr,BIG_BILL:()=>hn,StakingApi:()=>ae,StakingClient:()=>ie});import{calculate_accumulated_rps as io,calculate_percentage_amount as so,calculate_period_number as Pr,calculate_points as Sr,calculate_rewards as oo,sigmoid as Tr}from"@galacticcouncil/math-staking";import W from"big.js";var Fe={none:.1,locked1x:1,locked2x:2,locked3x:3,locked4x:4,locked5x:5,locked6x:6},yr=m=>Object.keys(Fe).includes(m);import{AccountId as no}from"polkadot-api";import{toHex as ro}from"@polkadot-api/utils";import{HYDRATION_SS58_PREFIX as ao}from"@galacticcouncil/common";function fr(m){let t=("modl"+m).padEnd(32,"\0"),e=new TextEncoder().encode(t),n=ro(e);return no(ao).dec(n)}var Re="20000000000000000",Ce="2000",wr=W(10),hn=W(wr.pow(12)),ae=class{client;balance;constructor(t,e){this.client=t,this.balance=e}async getPotBalance(){let t=await this.client.getPalletId(),e=fr(t);return await this.balance.getBalance(e,0)}async getStakingPosition(t){let[e,n]=await Promise.all([this.client.getStakingPositionsValue(t),this.client.getStakingVotes(t)]);if(!e)return;let r=e.created_at,a=await n.reduce(async(i,[s,o])=>{let l=await i,c=s,u=o.amount,d=o.conviction.type.toLowerCase(),p=await this.client.getReferendumInfo(c);return p&&(p.type==="Approved"||p.type==="Rejected")&&yr(d)&&l.push({id:c,amount:u,conviction:d}),l},Promise.resolve([]));return{stake:e.stake,rewardPerStake:e.reward_per_stake,createdAt:r,actionPoints:e.action_points,accumulatedUnpaidRewards:e.accumulated_unpaid_rewards,accumulatedSlashPoints:e.accumulated_slash_points,accumulatedLockedRewards:e.accumulated_locked_rewards,votes:a}}async getStake(t){let e=await this.client.getNFTCollectionId(),[n,r]=await Promise.all([this.client.getStaking(),this.client.getUniques(t,e)]),a=r.find(i=>i)?.itemId;return{totalStake:n?.total_stake,accumulatedRewardPerStake:n?.accumulated_reward_per_stake,potReservedBalance:n?.pot_reserved_balance,positionId:a,stakePosition:a?await this.getStakingPosition(a):void 0}}getCurrentActionPoints(t,e,n,r){let a=W(0),i=W(0),s=Fe.locked6x,o=W(n.toString()).mul(s),l=100,c=[];t.forEach(p=>{let h=Fe[p.conviction],b=r.includes(p.id.toString());b&&c.push(p.id.toString());let g=W(p.amount.toString()).mul(l).div(o);a=a.plus(Math.floor(g.mul(h).toNumber())),i=i.plus(Math.floor(g.mul(b?s:h).toNumber()))});let u=Math.floor(W(n.toString()).mul(s).mul(l).div(o).toNumber());r.forEach(p=>{c.includes(p)||(i=i.plus(u))});let d={democracyVote:1};return a=a.mul(d.democracyVote),a=a.plus(e.toString()||"0"),i=i.mul(d.democracyVote),i=i.plus(e.toString()||"0"),{currentActionPoints:a.toString(),maxActionPoints:i.toString()}}async getRewards(t,e,n){let r=await this.getStake(t),{potReservedBalance:a,accumulatedRewardPerStake:i,totalStake:s,stakePosition:o}=r;if(!o)return;let[l,c,u,d,p,h,b]=await Promise.all([this.getPotBalance(),this.client.getPeriodLength(),this.client.getUnclaimablePeriods(),this.client.getTimePointsPerPeriod(),this.client.getTimePointsWeight(),this.client.getActionPointsWeight(),this.client.getSixBlockSince()]),g=W(l.transferable.toString()).minus(a.toString()),f=g.gt(0)&&s>0?io(i.toString(),g.toString(),s.toString()):i.toString(),y=Pr(c.toString(),n,b),S=Pr(c.toString(),o.createdAt.toString(),b),P=oo(f,o.rewardPerStake.toString(),o.stake.toString()),T=this.getCurrentActionPoints(o.votes,o.actionPoints,o.stake,e),w=Sr(S,y,d.toString(),p.toString(),T.currentActionPoints,h.toString(),o.accumulatedSlashPoints.toString()),F=Tr(w,Re,Ce),k=(()=>{if(!e.length)return;let At=Sr(S,y,d.toString(),p.toString(),T.maxActionPoints.toString(),h.toString(),o.accumulatedSlashPoints.toString());return Tr(At,Re,Ce)})(),$=W(P).plus(o.accumulatedUnpaidRewards.toString()).plus(o.accumulatedLockedRewards.toString());if(W(y).minus(S).lte(u.toString()))return{rewards:"0",payablePercentage:F,extraPayablePercentage:k,constants:{a:Re,b:Ce}};let K=so($.toString(),F),H=W(o.accumulatedLockedRewards.toString()),V=H.gt(K)?H:W(K);return{rewards:V.div(hn).toString(),maxRewards:$.div(hn).toString(),allocatedRewardsPercentage:V.div($).mul(100).toNumber(),points:w,payablePercentage:F,extraPayablePercentage:k,constants:{a:Re,b:Ce}}}};var ie=class extends B{async getPalletId(){let t=this.api.constants.Staking.PalletId;return(await t()).asText()}async getPeriodLength(){let t=this.api.constants.Staking.PeriodLength;return await t()}async getUnclaimablePeriods(){let t=this.api.constants.Staking.UnclaimablePeriods;return await t()}async getNFTCollectionId(){let t=this.api.constants.Staking.NFTCollectionId;return await t()}async getStaking(){return await this.api.query.Staking.Staking.getValue()}async getUniques(t,e){return(await this.api.query.Uniques.Account.getEntries(t,e)).map(({keyArgs:i})=>{let[s,o,l]=i;return{address:s,collectionId:o,itemId:l}})}async getStakingPositionsValue(t){return await this.api.query.Staking.Positions.getValue(t)}async getStakingVotes(t){return await this.api.query.Staking.Votes.getValue(t)}async getReferendumInfo(t){return await this.api.query.Referenda.ReferendumInfoFor.getValue(t)}async getTimePointsPerPeriod(){let t=this.api.constants.Staking.TimePointsPerPeriod;return await t()}async getTimePointsWeight(){let t=this.api.constants.Staking.TimePointsWeight;return await t()/1e6}async getActionPointsWeight(){let t=this.api.constants.Staking.ActionPointsWeight;return await t()/1e9}async getSixBlockSince(){return(await this.api.query.Staking.SixSecBlocksSince.getValue()).toString()}};var Ir={};A(Ir,{TxBuilderFactory:()=>It});import{Enum as vr}from"polkadot-api";function Ee(m){let t=[],e=m;for(;e&&typeof e=="object"&&"type"in e;)t.push(e.type),e=e.value;return t.join(".")}var vt=class extends B{evm;evmClient;balance;constructor(t,e){super(t),this.evm=e,this.evmClient=e.getWsProvider(),this.balance=new X(t)}wrapTx(t,e){return{name:t,get:()=>e,dryRun:async n=>{let r=await this.dryRun(n,e);if(r.success&&!r.value.execution_result.success){let a=Ee(r.value.execution_result.value.error.value);throw new Error("Dry run execution error!",{cause:a})}return r}}}dispatchWithExtraGas(t,e=et){return this.api.tx.Dispatcher.dispatch_with_extra_gas({call:t.decodedCall,extra_gas:e})}async dryRun(t,e){let n=vr("Signed",t),r=vr("system",n);return await this.client.getUnsafeApi().apis.DryRunApi.dry_run_call(r,e.decodedCall)}isDirectOmnipoolTrade(t){return t.length===1&&t[0].pool==="Omnipool"}};var ke=class extends vt{_trade;_beneficiary;_slippagePct=1;setTrade(t){return this._trade=t,this}withBeneficiary(t){return this._beneficiary=t,this}withSlippage(t){return this._slippagePct=t,this}get trade(){if(!this._trade)throw new Error("Trade not set. Use setTrade().");return this._trade}get beneficiary(){if(!this._beneficiary)throw new Error("Beneficiary not set. Use withBeneficiary().");return this._beneficiary}get slippagePct(){return this._slippagePct}async build(){let{amountIn:t,swaps:e,type:n}=this.trade;if(n==="Buy")return this.buildBuyTx();let{assetIn:r}=e[0],a=await this.balance.getBalance(this.beneficiary,r);return t>=a.transferable-5n?this.buildSellAllTx():this.buildSellTx()}async buildBuyTx(){let{amountIn:t,amountOut:e,swaps:n}=this.trade,r=n[0],a=n[n.length-1],i=R.getFraction(t,this.slippagePct),s=r.assetIn,o=a.assetOut,l=t+i,c;return this.isDirectOmnipoolTrade(n)?c=this.api.tx.Omnipool.buy({asset_in:s,asset_out:o,amount:e,max_sell_amount:l}):c=this.api.tx.Router.buy({asset_in:s,asset_out:o,amount_out:e,max_amount_in:l,route:G.build(n)}),c=await this.applyExtraGas(this.beneficiary,c,n),this.wrapTx("RouterBuy",c)}async buildSellTx(){let{amountIn:t,amountOut:e,swaps:n}=this.trade,r=n[0],a=n[n.length-1],i=R.getFraction(e,this.slippagePct),s=r.assetIn,o=a.assetOut,l=e-i,c;return this.isDirectOmnipoolTrade(n)?c=this.api.tx.Omnipool.sell({asset_in:s,asset_out:o,amount:t,min_buy_amount:l}):c=this.api.tx.Router.sell({asset_in:s,asset_out:o,amount_in:t,min_amount_out:l,route:G.build(n)}),c=await this.applyExtraGas(this.beneficiary,c,n),this.wrapTx("RouterSell",c)}async buildSellAllTx(){let{amountOut:t,swaps:e}=this.trade,n=e[0],r=e[e.length-1],a=R.getFraction(t,this.slippagePct),i=n.assetIn,s=r.assetOut,o=t-a,l=this.api.tx.Router.sell_all({asset_in:i,asset_out:s,min_amount_out:o,route:G.build(e)});return l=await this.applyExtraGas(this.beneficiary,l,e),this.wrapTx("RouterSellAll",l)}async applyExtraGas(t,e,n){if(!n.some(s=>s.pool==="Aave"))return e;let a=await this.dryRun(t,e),i=this.getDryRunError(a);return!i||!i.includes("OutOfGas")?e:this.estimateExtraGas(t,e)}async estimateExtraGas(t,e){let n=this.dispatchWithExtraGas(e,0n),r=this.dispatchWithExtraGas(e,et),[a,i]=await Promise.all([n.getPaymentInfo(t),this.dryRun(t,r)]);if(this.getDryRunError(i))return r;let o=BigInt(a.weight.ref_time),l=this.getActualRefTime(i);if(l<=o)return r;let d=(l-o)/He*110n/100n,p=d>et?et:d;return this.dispatchWithExtraGas(e,p)}getDryRunError(t){if(!t.success)return"DryRun call failed";let e=t.value.execution_result;return e.success?null:Ee(e.value.error.value)}getActualRefTime(t){if(!t.success)return 0n;let e=t.value.execution_result;return e.success?e.value.actual_weight?.ref_time??0n:e.value.post_info?.actual_weight?.ref_time??0n}};import{Enum as bn}from"polkadot-api";var Me=class extends vt{_order;_beneficiary;_maxRetries=3;_slippagePct=1;setOrder(t){return this._order=t,this}withBeneficiary(t){return this._beneficiary=t,this}withMaxRetries(t){return this._maxRetries=t,this}withSlippage(t){return this._slippagePct=t,this}get order(){if(!this._order)throw new Error("Order not set. Use setOrder().");return this._order}get beneficiary(){if(!this._beneficiary)throw new Error("Beneficiary not set. Use withBeneficiary().");return this._beneficiary}get maxRetries(){return this._maxRetries}get slippagePct(){return this._slippagePct}async build(){let{type:t}=this.order;switch(t){case"Dca":return this.buildDcaTx();case"TwapSell":return this.buildTwapSellTx();case"TwapBuy":return this.buildTwapBuyTx();default:throw new Error(`Unsupported TradeOrderType: ${t}`)}}async buildDcaTx(){let{amountIn:t,assetIn:e,assetOut:n,tradeAmountIn:r,tradePeriod:a,tradeRoute:i}=this.order,s=this.api.tx.DCA.schedule({schedule:{owner:this.beneficiary,period:a,max_retries:this.maxRetries,total_amount:t,slippage:this.slippagePct*1e4,stability_threshold:void 0,order:bn("Sell",{asset_in:e,asset_out:n,amount_in:r,min_amount_out:0n,route:i})},start_execution_block:void 0});return this.wrapTx("DcaSchedule",s)}async buildTwapSellTx(){let{amountIn:t,assetIn:e,assetOut:n,tradeAmountIn:r,tradeAmountOut:a,tradePeriod:i,tradeRoute:s}=this.order,o=R.getFraction(a,this.slippagePct),l=a-o,c=this.api.tx.DCA.schedule({schedule:{owner:this.beneficiary,period:i,max_retries:this.maxRetries,total_amount:t,slippage:this.slippagePct*1e4,stability_threshold:void 0,order:bn("Sell",{asset_in:e,asset_out:n,amount_in:r,min_amount_out:l,route:s})},start_execution_block:void 0});return this.wrapTx("DcaSchedule.twapSell",c)}async buildTwapBuyTx(){let{amountIn:t,assetIn:e,assetOut:n,tradeAmountIn:r,tradeAmountOut:a,tradePeriod:i,tradeRoute:s}=this.order,o=R.getFraction(r,this.slippagePct),l=r+o,c=this.api.tx.DCA.schedule({schedule:{owner:this.beneficiary,period:i,max_retries:this.maxRetries,total_amount:t,slippage:this.slippagePct*1e4,stability_threshold:void 0,order:bn("Buy",{asset_in:e,asset_out:n,amount_out:a,max_amount_in:l,route:s})},start_execution_block:void 0});return this.wrapTx("DcaSchedule.twapBuy",c)}};var It=class{client;evmClient;constructor(t,e){this.client=t,this.evmClient=e}trade(t){return new ke(this.client,this.evmClient).setTrade(t)}order(t){return new Me(this.client,this.evmClient).setOrder(t)}};async function Vy(m){let t=new mt(m),e=new Dt(m),[n,r]=await Promise.all([t.getBlockTime(),t.getMinOrderBudget()]),a=new St(m,e).withAave().withOmnipool().withStableswap().withXyk(),i=new X(m),s=new ie(m),o=new Nt(m),l=new Bt(e),c=new tt(a),u=new xt(a,{blockTime:n,minBudgetInNative:r}),d=new ae(s,i),p=new qt(o,i,{blockTime:n});return{api:{aave:l,router:c,scheduler:u,staking:d,farm:p},client:{asset:new st(m),balance:i,evm:e},ctx:{pool:a},tx:new It(m,e),destroy:()=>{a.destroy()}}}export{ye as QueryBus,xn as aave,Tn as api,be as async,R as calc,Bn as client,vn as const,Vy as createSdkContext,Fn as error,kn as evm,Un as farm,x as fmt,Lt as json,L as math,ur as pool,br as sor,xr as staking,Ir as tx};
|