@galacticcouncil/sdk-next 0.40.0 → 0.40.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/index.cjs +1 -1
- package/build/index.mjs +1 -1
- package/package.json +1 -1
package/build/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var Fr=Object.defineProperty;var O=(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 Pn={};O(Pn,{Papi:()=>_,Watcher:()=>At,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 yn,timer as kr}from"rxjs";import{catchError as Mr,distinctUntilChanged as Dr,expand as Lr,map as Me,shareReplay as qr,skip as Nr,switchMap as Hr,timeout as Gr}from"rxjs/operators";function fn(m,{intervalMs:t=5e3,rpcTimeoutMs:e=1e4}={}){let n=()=>Cr(()=>Er(m._request("system_health",[]))).pipe(Gr({first:e}),Me(()=>"online"),Mr(()=>yn("offline")));return yn({state:"offline",delayMs:0}).pipe(Lr(i=>kr(i.delayMs).pipe(Hr(n),Me(a=>({state:a,delayMs:t})))),Nr(1),Me(i=>i.state),Dr(),qr({bufferSize:1,refCount:!0}))}var{logger:Yr}=Vr,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(Wr({error:n=>Yr.error(t,n)}),Ur({bufferSize:1,refCount:!0}))}};var _=class{client;api;apiNext;watcher;constructor(t){this.client=t,this.api=this.client.getTypedApi($r),this.apiNext=this.client.getTypedApi(Xr),this.watcher=At.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}),i=await n.addChain({chainSpec:m,potentialRelayChains:[r]});return Jr(i)}var wn={};O(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:()=>zo,AAVE_UINT_256_MAX:()=>ti,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,zo=5,ti=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 ei,h160 as ni}from"@galacticcouncil/common";var{ERC20:at}=ei,{H160:Ne}=ni,ri=1.01,ii=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-ri;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)/ii;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 Bn={};O(Bn,{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 oi}from"@galacticcouncil/common";import{combineLatest as li,concat as ci,defer as Ft,from as vn}from"rxjs";import{bufferCount as xn,distinctUntilChanged as In,debounceTime as ui,map as ct,retry as mi,startWith as On,switchMap as An,tap as Rt,take as pi,skip as di,connect as gi}from"rxjs/operators";var Tn={};O(Tn,{HUB_ASSET_ID:()=>_t,HYDRATION_OMNIPOOL_ADDRESS:()=>si,HYDRATION_PARACHAIN_ID:()=>ai,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,ai=2034,si="7L53bUTBbfuj14UpdCNPwmgzzHSsrsTWBHX5pys32mVWM3C1",_t=1,lt=15;var{logger:ut}=oi,X=class extends _{erc20Ids=null;constructor(t){super(t)}async getBalance(t,e){return e===0?this.getSystemBalance(t):this.getBalanceData(t,e)}async getSystemBalance(t){let e=this.api.query.System.Account,{data: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 li([e,n,r]).pipe(gi(i=>ci(i.pipe(pi(1)),i.pipe(di(1),ui(250)))))}).pipe(ct(e=>e.flat()),On([]),xn(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)}),mi({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(In((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()=>{if(this.erc20Ids)return this.erc20Ids;let i=await this.api.query.AssetRegistry.Assets.getEntries({at:"best"});return this.erc20Ids=i.filter(({value:a})=>a.asset_type.type==="Erc20").map(({keyArgs:a})=>{let[s]=a;return s}),this.erc20Ids},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(An(i=>this.watcher.bestBlock$.pipe(An(()=>vn(r(i))))),On([]),xn(2,1),ct(([i,a],s)=>s===0?a.filter(o=>o.balance.total>0n):this.getDeltas(i,a)),In((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 _n={};O(_n,{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 En={};O(En,{EvmClient:()=>Mt,EvmRpcAdapter:()=>kt,createChain:()=>Ve});import{Binary as hi,FixedSizeBinary as Fn}from"polkadot-api";import{hydration as bi}from"@galacticcouncil/descriptors";import{encodeFunctionData as yi,decodeFunctionResult as fi}from"viem";var Pi=10000000n,kt=class{api;constructor(t){this.api=t.getTypedApi(bi)}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=yi({abi:e,functionName:r,args:i}),s=await this.api.apis.EthereumRuntimeRPCApi.call(Fn.fromText(""),Fn.fromHex(n),hi.fromHex(a),[0n,0n,0n,0n],[Pi,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 fi({abi:e,functionName:r,data:l.asHex()});throw console.log(r,o.type,o.value.type),new Error("Contract read error")})};import{defineChain as Si}from"viem";var wi=["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=()=>Si({id:222222,name:"Hydration",network:"hydration",nativeCurrency:{decimals:18,name:"WETH",symbol:"WETH"},rpcUrls:{default:{http:wi}},blockExplorers:{default:{name:"Hydration Explorer",url:"https://hydration.subscan.io"}},testnet:!1});import{createPublicClient as Rn,createWalletClient as Ti,custom as Cn,http as vi}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 Rn({chain:this.chain,transport:vi()})}getWsProvider(){return Rn({transport:Cn({request:({method:t,params:e})=>this.client._request(t,e||[])})})}getSigner(t){return Ti({account:t,chain:this.chain,transport:Cn(window.ethereum)})}getRPCAdapter(){return new kt(this.client)}};var Vn={};O(Vn,{LiquidityMiningApi:()=>Lt,LiquidityMiningClient:()=>qt});import{AccountId as Vi}from"polkadot-api";import q from"big.js";import{HYDRATION_SS58_PREFIX as Ui,RUNTIME_DECIMALS as pt}from"@galacticcouncil/common";import{fixed_from_rational as Gn}from"@galacticcouncil/math-liquidity-mining";var he={};O(he,{withTimeout:()=>xi});function xi(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={};O(R,{divSpot:()=>Oi,getFraction:()=>Ai,mulScaled:()=>Mn,mulSpot:()=>Ii});import{RUNTIME_DECIMALS as kn}from"@galacticcouncil/common";function Mn(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 Ii(m,t,e,n){return Mn(m,t,e,kn,n)}function Oi(m,t,e,n){if(t===0n)return 0n;let r=BigInt(10)**BigInt(kn+n-e);return m*r/t}function Ai(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={};O(v,{FeeUtils:()=>Ue,shiftNeg:()=>_i});import Bi 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 _i(m,t){let e=Bi(typeof m=="bigint"?m.toString():m);return t===0?e.toString():e.div(Math.pow(10,t)).toString()}var Dt={};O(Dt,{findNestedKey:()=>Fi,findNestedObj:()=>Ri,jsonFormatter:()=>Ci});var Fi=(m,t)=>{let e=[];return JSON.stringify(m,(n,r)=>(r&&r[t]&&e.push(r),r)),e[0]},Ri=(m,t,e)=>{let n;return JSON.stringify(m,(r,i)=>(i&&i[t]===e&&(n=i),i)),n},Ci=(m,t)=>typeof t=="bigint"?t.toString():t;var L={};O(L,{calculateBuyFee:()=>Di,calculateDiffToAvg:()=>Ei,calculateDiffToRef:()=>ki,calculateSellFee:()=>Mi});import j from"big.js";function Ei(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 ki(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 Mi(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 Di(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 Dn}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 Dn(null,{ttl:r}):new Dn;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 Li,calculate_global_farm_rewards as qi,calculate_loyalty_multiplier as Ni,calculate_user_reward as Hn,calculate_yield_farm_delta_rpvs as Hi}from"@galacticcouncil/math-liquidity-mining";import Ln from"big.js";var We=Ln(10).pow(18),qn=BigInt(Ln(1).pow(18).toString()),Nn=6e3;var Gi="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(qi(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(Li(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=Hi(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 Ni(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(Hn(n.accumulated_rpvs.toString(),n.valued_shares.toString(),n.accumulated_claimed_rewards.toString(),o.accumulated_rpvs.toString(),u)),p=BigInt(Hn(n.accumulated_rpvs.toString(),n.valued_shares.toString(),n.accumulated_claimed_rewards.toString(),o.accumulated_rpvs.toString(),Gi));return{reward:d,maxReward:p,assetId:s.reward_currency,yieldFarmId:o.id,isActiveFarm:o.state.type==="Active"}}};var Wi=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??Nn})}get blockTime(){return this.options.blockTime}async getOraclePrice(t,e){let n=[t,e].sort((i,a)=>i-a);if(t===e)return qn;let r=await this.client.getOraclePrice(n);if(r){let{n:i,d:a}=r[0].price,s;return t<e?s=Gn(i.toString(),a.toString()):s=Gn(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 Vi(Ui).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=Wi.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 Br=this.getGlobalRewardPerPeriod(p,d,h,F),_r=this.getPoolYieldPerPeriod(Br,k,p,F);H=q(_r).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(),Or=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 Ar=$?q(H).times($).toString():void 0;return{apr:H,minApr:Ar,isDistributed:bn,estimatedEndPeriod:le,estimatedEndBlock:ke,maxRewards:Ot,incentivizedAsset:S,rewardCurrency:P,loyaltyCurve:c,currentPeriod:oe,potMaxRewards:ae,fullness:Or,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 Yi,Enum as $i}from"polkadot-api";var qt=class extends _{omnipoolAssetIds=[];async getOraclePrice(t){return await this.api.query.EmaOracle.Oracles.getValue(Yi.fromText("omnipool"),t,$i("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 cr={};O(cr,{PoolContextProvider:()=>St,PoolError:()=>Z,PoolFactory:()=>ft,PoolType:()=>I,aave:()=>nn,hsm:()=>on,lbp:()=>ze,omni:()=>Qe,stable:()=>Ze,xyk:()=>tn});var ze={};O(ze,{LbpMath:()=>Y,LbpPool:()=>Nt,LbpPoolClient:()=>Ht});import{calculate_in_given_out as Xi,calculate_out_given_in as zi,calculate_linear_weights as Ki,calculate_pool_trade_fee as ji,get_spot_price as Qi}from"@galacticcouncil/math-lbp";var Y=class{static getSpotPrice(t,e,n,r,i){return Qi(t,e,n,r,i)}static calculateInGivenOut(t,e,n,r,i){return Xi(t,e,n,r,i)}static calculateOutGivenIn(t,e,n,r,i){return zi(t,e,n,r,i)}static calculateLinearWeights(t,e,n,r,i){return Ki(t,e,n,r,i)}static calculatePoolTradeFee(t,e,n){return ji(t,e,n)}};import{big as Un,RUNTIME_DECIMALS as Wn}from"@galacticcouncil/common";var I=(a=>(a.Aave="Aave",a.LBP="LBP",a.Omni="Omnipool",a.Stable="Stableswap",a.XYK="XYK",a.HSM="HSM",a))(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:Yn}=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=Yn.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=Yn.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(),Un.toBigInt(1,Wn).toString());return BigInt(e)}spotPriceOutGivenIn(t){let e=Y.getSpotPrice(t.balanceIn.toString(),t.balanceOut.toString(),t.weightIn.toString(),t.weightOut.toString(),Un.toBigInt(1,Wn).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 ha}from"polkadot-api";import{Subscription as ba,distinctUntilChanged as ya,filter as fa}from"rxjs";import{memoize1 as ea}from"@thi.ng/memoize";import{TLRUCache as na}from"@thi.ng/cache";import{ReplaySubject as $n,Subscription as Xn,combineLatest as ra,defer as ia,from as aa,merge as Ye,of as sa,EMPTY as Te}from"rxjs";import{bufferCount as oa,bufferTime as la,catchError as ve,filter as xe,finalize as $e,map as dt,pairwise as Xe,repeat as zn,skip as ca,share as ua,startWith as ma,switchMap as Kn,tap as gt,throttleTime as pa}from"rxjs/operators";import{BehaviorSubject as Ji}from"rxjs";var Pe=class{store$=new Ji([]);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 Zi}from"@galacticcouncil/common";var ta={Aave:"AAVE",LBP:"LBP",Omnipool:"OMNI",Stableswap:"STBL",XYK:"XYK",HSM:"HSM"},{logger:Se}=Zi,we=class{type;constructor(t){this.type=t}prefix(){return this.pad(`pool(${ta[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:da}=he,ga=3e3,N=class extends _{evm;balance;store=new Pe;log;shared$;resync$=new $n(1);resyncAt=0;resyncPending=!1;mem=0;memPoolsCache=new na(null,{ttl:6*1e3});memPools=ea(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(ma([]),oa(2,1),dt(([t,e])=>t.length===0?e:this.store.applyChangeset(e)),xe(t=>t.length>0),pa(1e3,void 0,{leading:!0,trailing:!0}))}subscribeStore(){return ia(()=>{let t=new Xn;return t.add(this.startWatchdog()),this.resync$.next(),this.resync$.pipe(Kn(()=>{let e=new Xn;return aa(da(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())}),Kn(r=>Ye(sa(r),this.store.asObservable().pipe(ca(1)))),$e(()=>{e.unsubscribe()}))}),$e(()=>t.unsubscribe()))}).pipe(ua({connector:()=>new $n(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 ra(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(la(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})=>t.type==="XYK"?n>0n&&!!e:!!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<ga||(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)),zn({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)),zn({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(ha.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(fa(t=>t!==void 0),ya((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 ba;return t.add(this.subscribeValidationData()),t}};var Qe={};O(Qe,{OmniMath:()=>x,OmniPool:()=>Gt,OmniPoolClient:()=>Ut});import{calculate_in_given_out as Pa,calculate_lrna_in_given_out as Sa,calculate_out_given_in as wa,calculate_out_given_lrna_in as Ta,calculate_spot_price as va,calculate_lrna_spot_price as xa,calculate_shares as Ia,calculate_liquidity_out as Oa,calculate_liquidity_lrna_out as Aa,verify_asset_cap as Ba,calculate_liquidity_hub_in as _a,is_sell_allowed as Fa,is_buy_allowed as Ra,is_add_liquidity_allowed as Ca,is_remove_liquidity_allowed as Ea,recalculate_asset_fee as ka,recalculate_protocol_fee as Ma}from"@galacticcouncil/math-omnipool";import ht from"big.js";var x=class{static calculateSpotPrice(t,e,n,r){return va(t,e,n,r)}static calculateLrnaSpotPrice(t,e){return xa(t,e)}static calculateInGivenOut(t,e,n,r,i,a,s,o,l,c){return Pa(t,e,n,r,i,a,s,o,l,c)}static calculateLrnaInGivenOut(t,e,n,r,i,a){return Sa(t,e,n,r,i,a)}static calculateOutGivenIn(t,e,n,r,i,a,s,o,l,c){return wa(t,e,n,r,i,a,s,o,l,c)}static calculateOutGivenLrnaIn(t,e,n,r,i,a){return Ta(t,e,n,r,i,a)}static calculateShares(t,e,n,r){return Ia(t,e,n,r)}static calculateLiquidityOut(t,e,n,r,i,a,s,o){return Oa(t,e,n,r,i,a,s,o)}static calculateLiquidityLRNAOut(t,e,n,r,i,a,s,o){return Aa(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 _a(t,e,n,r)}static isSellAllowed(t){return Fa(t)}static isBuyAllowed(t){return Ra(t)}static isAddLiquidityAllowed(t){return Ca(t)}static isRemoveLiquidityAllowed(t){return Ea(t)}static recalculateAssetFee(t,e,n,r,i,a,s,o,l,c,u){return ka(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 Ma(t,e,n,r,i,a,s,o,l,c,u)}static verifyAssetCap(t,e,n,r){return Ba(t,e,n,r)}};import{big as Da}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=Da.pow10(Math.abs(r));return r>0?t*i:t/i}};import{AccountId as La,Binary as qa,CompatibilityLevel as jn,Enum as Na}from"polkadot-api";import{toHex as Ha}from"@polkadot-api/utils";import{Subscription as Ga,distinctUntilChanged as Ke,filter as Va,finalize as je,map as Vt,merge as Ua,tap as Ie}from"rxjs";import{HYDRATION_SS58_PREFIX as Wa}from"@galacticcouncil/common";var{FeeUtils:B}=v,Qn=qa.fromText("omnipool"),Jn=Na("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(Qn,t,Jn,{at:"best"}),t=>t.join(":"),6*1e3);getPoolType(){return"Omnipool"}getPoolAddress(){let t="modlomnipool".padEnd(32,"\0"),e=new TextEncoder().encode(t),n=Ha(e);return La(Wa).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(jn.BackwardsCompatible,e)}async isSlipFeeSupported(){return this.apiNext.query.Omnipool.SlipFee.isCompatible(jn.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(Qn,r,Jn,"best").pipe(Va(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 Ua(...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 Ga;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={};O(Ze,{StableMath:()=>M,StableSwap:()=>it,StableSwapClient:()=>Wt});import{calculate_in_given_out as Ya,calculate_out_given_in as $a,calculate_amplification as Xa,calculate_add_one_asset as za,calculate_liquidity_out_one_asset as Ka,calculate_shares as ja,calculate_shares_for_amount as Qa,calculate_spot_price_with_fee as Ja,pool_account_name as Za,recalculate_peg as ts}from"@galacticcouncil/math-stableswap";var M=class{static getPoolAddress(t){return Za(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 Xa(t,e,n,r,i)}static calculateInGivenOut(t,e,n,r,i,a,s){return Ya(t,e,n,r,i,a,s)}static calculateAddOneAsset(t,e,n,r,i,a,s){return za(t,e,n,r,i,a,s)}static calculateSharesForAmount(t,e,n,r,i,a,s){return Qa(t,e,n,r,i,a,s)}static calculateOutGivenIn(t,e,n,r,i,a,s){return $a(t,e,n,r,i,a,s)}static calculateLiquidityOutOneAsset(t,e,n,r,i,a,s){return Ka(t,e,n,r,i,a,s)}static calculateShares(t,e,n,r,i,a){return ja(t,e,n,r,i,a)}static calculateSpotPriceWithFee(t,e,n,r,i,a,s,o){return Ja(t,e,n,r,i,a,s,o)}static recalculatePegs(t,e,n,r,i,a){let s=ts(t,e,n,r,i,a);return JSON.parse(s)}};import{RUNTIME_DECIMALS as es,big as Zn}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*Zn.pow10(es-i):n?t/Zn.pow10(i-r):t}};import{AccountId as ns,CompatibilityLevel as rs}from"polkadot-api";import{toHex as is}from"@polkadot-api/utils";import{blake2b as as}from"@noble/hashes/blake2b";import{Subscription as ss,distinctUntilChanged as os,map as Je,merge as ls,tap as tr}from"rxjs";import{HYDRATION_SS58_PREFIX as cs,RUNTIME_DECIMALS as us}from"@galacticcouncil/common";var{FeeUtils:ms}=v,Wt=class extends N{poolsData=new Map([]);getPoolType(){return"Stableswap"}getPoolAddress(t){let e=M.getPoolAddress(t),n=as(e,{dkLen:32}),r=is(n);return ns(cs).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(rs.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:us}),this.poolsData.set(s,a),{address:o,id:s,type:"Stableswap",fee:ms.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})),tr(({index:r,value:i})=>{r>0&&this.log.trace("tokens.TotalIssuance",n,i)}),Je(({value:r})=>({id:n,value:r}))));return ls(...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(os((t,e)=>!e.deltas),Je((t,e)=>({value:t,index:e})),tr(({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 ss;return t.add(this.subscribePoolPegs()),t.add(this.subscribeIssuance()),this.hasOnRamps()&&t.add(this.subscribeBlock()),t}hasOnRamps(){return this.store.pools.filter(t=>t.isRampPeriod).length>0}};var tn={};O(tn,{XykMath:()=>Q,XykPool:()=>Yt,XykPoolClient:()=>$t});import{calculate_in_given_out as ps,calculate_out_given_in as ds,calculate_pool_trade_fee as gs,get_spot_price as hs,calculate_liquidity_in as bs,calculate_shares as ys,calculate_spot_price as fs,calculate_spot_price_with_fee as Ps,calculate_liquidity_out_asset_a as Ss,calculate_liquidity_out_asset_b as ws}from"@galacticcouncil/math-xyk";var Q=class{static getSpotPrice(t,e,n){return hs(t,e,n)}static calculateInGivenOut(t,e,n){return ps(t,e,n)}static calculateOutGivenIn(t,e,n){return ds(t,e,n)}static calculatePoolTradeFee(t,e,n){return gs(t,e,n)}static calculateLiquidityIn(t,e,n){return bs(t,e,n)}static calculateSpotPrice(t,e){return fs(t,e)}static calculateSpotPriceWithFee(t,e,n,r){return Ps(t,e,n,r)}static calculateShares(t,e,n){return ys(t,e,n)}static calculateLiquidityOutAssetA(t,e,n,r){return Ss(t,e,n,r)}static calculateLiquidityOutAssetB(t,e,n,r){return ws(t,e,n,r)}};import{big as Ts}from"@galacticcouncil/common";var{FeeUtils:er}=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=er.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=er.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=Ts.pow10(Math.abs(r));return r>0?t*i:t/i}};import{CompatibilityLevel as vs}from"polkadot-api";import{Subscription as xs}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(vs.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 xs.EMPTY}};var nn={};O(nn,{AavePool:()=>Xt,AavePoolClient:()=>zt});import{big as nr,RUNTIME_DECIMALS as rr}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 nr.toBigInt(1,rr)}spotPriceOutGivenIn(t){return nr.toBigInt(1,rr)}calculateTradeFee(t,e){return 0n}};import{AccountId as Is}from"polkadot-api";import{toHex as Os}from"@polkadot-api/utils";import{Subscription as ar,filter as en,map as sr}from"rxjs";import{decodeEventLog as As}from"viem";import{erc20 as Bs,HYDRATION_SS58_PREFIX as _s}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:Fs}=Bs,Rs=["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=Os(r);return Is(_s).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 Fs.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}=As({abi:ir,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(sr(({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(sr(({payload:t})=>this.parseEvmLog(t)),en(t=>t!==void 0),en(({eventName:t})=>Rs.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 ar.EMPTY}subscribeUpdates(){let t=new ar;return t.add(this.subscribeRouterExecuted()),t.add(this.subscribeEvmLog()),t}};var on={};O(on,{HsmMath:()=>U,HsmPool:()=>Kt,HsmPoolClient:()=>Jt});import{calculate_collateral_in_given_hollar_out as Cs,calculate_collateral_out_given_hollar_in as Es,calculate_hollar_in_given_collateral_out as ks,calculate_hollar_out_given_collateral_in as Ms,calculate_imbalance as Ds,calculate_max_price as Ls,calculate_buyback_limit as qs,calculate_buyback_price_with_fee as Ns}from"@galacticcouncil/math-hsm";var U=class{static calculateCollateralInGivenHollarOut(t,e,n){return Cs(t,e,n)}static calculateCollateralOutGivenHollarIn(t,e,n){return Es(t,e,n)}static calculateHollarOutGivenCollateralIn(t,e,n){return Ms(t,e,n)}static calculateHollarInGivenCollateralOut(t,e,n){return ks(t,e,n)}static calculateImbalance(t,e,n){return Ds(t,e,n)}static calculateBuybackLimit(t,e){return qs(t,e)}static calculateBuybackPriceWithFee(t,e,n){return Ns(t,e,n)}static calculateMaxPrice(t,e){return Ls(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 Hs,CompatibilityLevel as Gs}from"polkadot-api";import{toHex as Vs}from"@polkadot-api/utils";import{Subscription as rn,combineLatest as Us,filter as or,map as an,pairwise as Ws}from"rxjs";import{decodeEventLog as Ys}from"viem";import{h160 as $s,HYDRATION_SS58_PREFIX as Xs}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:lr}=$s,zs=["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=Vs(n);return Hs(Xs).dec(r)}async isSupported(){let t=this.api.query.HSM.Collaterals,e=await this.api.compatibilityToken;return t.isCompatible(Gs.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=lr.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}=Ys({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)),or(t=>t!==void 0),or(({eventName:t})=>zs.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=lr.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?Us(r).pipe(an(i=>i.flat()),Ws(),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 Ks}from"@galacticcouncil/common";import{Subject as js,Subscription as Pt,takeUntil as Qs}from"rxjs";var{logger:Js}=Ks,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 js;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(Qs(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")||(Js.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 hr={};O(hr,{DCA_TIME_RESERVE:()=>pr,DEFAULT_BLOCK_TIME:()=>mr,DEFAULT_MIN_BUDGET:()=>un,ORDER_MIN_BLOCK_PERIOD:()=>dr,Router:()=>wt,TWAP_EXECUTION_INTERVAL:()=>ne,TWAP_MAX_DURATION:()=>pn,TWAP_MAX_PRICE_IMPACT:()=>mn,TWAP_TX_MULTIPLIER:()=>ab,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 Zs=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>Zs)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:ur}=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?ur.toPct(t.min):void 0,r=t.max?ur.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 mr=6e3,un=1000000000000000n,ne=6,mn=-5,pn=216e5,ab=3,pr=.1,dr=6;import{Enum as gr}from"polkadot-api";var G=class{static build(t){return t.map(({assetIn:e,assetOut:n,pool:r,poolId:i})=>r==="Stableswap"?{pool:gr("Stableswap",i),asset_in:e,asset_out:n}:{pool:gr(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 Tr={};O(Tr,{BIG_10:()=>wr,BIG_BILL:()=>dn,StakingApi:()=>re,StakingClient:()=>ie});import{calculate_accumulated_rps as ro,calculate_percentage_amount as io,calculate_period_number as fr,calculate_points as Pr,calculate_rewards as ao,sigmoid as Sr}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},br=m=>Object.keys(_e).includes(m);import{AccountId as to}from"polkadot-api";import{toHex as eo}from"@polkadot-api/utils";import{HYDRATION_SS58_PREFIX as no}from"@galacticcouncil/common";function yr(m){let t=("modl"+m).padEnd(32,"\0"),e=new TextEncoder().encode(t),n=eo(e);return to(no).dec(n)}var Fe="20000000000000000",Re="2000",wr=W(10),dn=W(wr.pow(12)),re=class{client;balance;constructor(t,e){this.client=t,this.balance=e}async getPotBalance(){let t=await this.client.getPalletId(),e=yr(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")&&br(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?ro(a.toString(),g.toString(),s.toString()):a.toString(),y=fr(c.toString(),n,b),S=fr(c.toString(),o.createdAt.toString(),b),P=ao(f,o.rewardPerStake.toString(),o.stake.toString()),w=this.getCurrentActionPoints(o.votes,o.actionPoints,o.stake,e),T=Pr(S,y,d.toString(),p.toString(),w.currentActionPoints,h.toString(),o.accumulatedSlashPoints.toString()),F=Sr(T,Fe,Re),k=(()=>{if(!e.length)return;let Ot=Pr(S,y,d.toString(),p.toString(),w.maxActionPoints.toString(),h.toString(),o.accumulatedSlashPoints.toString());return Sr(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=io($.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 Ir={};O(Ir,{TxBuilderFactory:()=>It});import{Enum as xr}from"polkadot-api";function vr(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=xr("Signed",t),r=xr("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=vr(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 Hy(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,Bn as client,Tn as const,Hy as createSdkContext,_n as error,En as evm,Vn as farm,v as fmt,Dt as json,L as math,cr as pool,hr as sor,Tr as staking,Ir as tx};
|
|
1
|
+
var Fr=Object.defineProperty;var O=(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 Pn={};O(Pn,{Papi:()=>_,Watcher:()=>At,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 yn,timer as kr}from"rxjs";import{catchError as Mr,distinctUntilChanged as Dr,expand as Lr,map as Me,shareReplay as qr,skip as Nr,switchMap as Hr,timeout as Gr}from"rxjs/operators";function fn(m,{intervalMs:t=5e3,rpcTimeoutMs:e=1e4}={}){let n=()=>Cr(()=>Er(m._request("system_health",[]))).pipe(Gr({first:e}),Me(()=>"online"),Mr(()=>yn("offline")));return yn({state:"offline",delayMs:0}).pipe(Lr(i=>kr(i.delayMs).pipe(Hr(n),Me(a=>({state:a,delayMs:t})))),Nr(1),Me(i=>i.state),Dr(),qr({bufferSize:1,refCount:!0}))}var{logger:Yr}=Vr,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(Wr({error:n=>Yr.error(t,n)}),Ur({bufferSize:1,refCount:!0}))}};var _=class{client;api;apiNext;watcher;constructor(t){this.client=t,this.api=this.client.getTypedApi($r),this.apiNext=this.client.getTypedApi(Xr),this.watcher=At.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}),i=await n.addChain({chainSpec:m,potentialRelayChains:[r]});return Jr(i)}var wn={};O(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:()=>zo,AAVE_UINT_256_MAX:()=>ti,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,zo=5,ti=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 R from"big.js";import{big as et,erc20 as ei,h160 as ni}from"@galacticcouncil/common";var{ERC20:at}=ei,{H160:Ne}=ni,ri=1.01,ii=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=R(r.toString()).mul(s).minus(R(b.toString()).mul(p)).div(g.toString()),y=R(g.toString()).mul(f).div(i.toString()).toFixed(6,R.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=R(r.toString()).mul(s).plus(R(h.toString()).mul(d)).div(b.toString()),f=R(b.toString()).mul(g).div(i.toString()).toFixed(6,R.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?R(b.toString()).mul(u.reserveLiquidationThreshold):R(0),P=(d.isCollateral?R(g.toString()).mul(d.reserveLiquidationThreshold):R(0)).minus(f).div(a.toString()),w=R(o).plus(P).toFixed(6,R.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-ri;if(d>0){let p=R(d).mul(e.toString()).div(o).toFixed(0,R.roundDown),h=R(p).div(s.toString()).mul(10**a).toFixed(0,R.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)/ii;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 Bn={};O(Bn,{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 oi}from"@galacticcouncil/common";import{combineLatest as li,concat as ci,defer as Ft,from as vn}from"rxjs";import{bufferCount as xn,distinctUntilChanged as In,debounceTime as ui,map as ct,retry as mi,startWith as On,switchMap as An,tap as Rt,take as pi,skip as di,connect as gi}from"rxjs/operators";var Tn={};O(Tn,{HUB_ASSET_ID:()=>_t,HYDRATION_OMNIPOOL_ADDRESS:()=>si,HYDRATION_PARACHAIN_ID:()=>ai,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,ai=2034,si="7L53bUTBbfuj14UpdCNPwmgzzHSsrsTWBHX5pys32mVWM3C1",_t=1,lt=15;var{logger:ut}=oi,X=class extends _{erc20Ids=null;constructor(t){super(t)}async getBalance(t,e){return e===0?this.getSystemBalance(t):this.getBalanceData(t,e)}async getSystemBalance(t){let e=this.api.query.System.Account,{data: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 li([e,n,r]).pipe(gi(i=>ci(i.pipe(pi(1)),i.pipe(di(1),ui(250)))))}).pipe(ct(e=>e.flat()),On([]),xn(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)}),mi({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(In((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()=>{if(this.erc20Ids)return this.erc20Ids;let i=await this.api.query.AssetRegistry.Assets.getEntries({at:"best"});return this.erc20Ids=i.filter(({value:a})=>a.asset_type.type==="Erc20").map(({keyArgs:a})=>{let[s]=a;return s}),this.erc20Ids},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(An(i=>this.watcher.bestBlock$.pipe(An(()=>vn(r(i))))),On([]),xn(2,1),ct(([i,a],s)=>s===0?a.filter(o=>o.balance.total>0n):this.getDeltas(i,a)),In((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 _n={};O(_n,{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 En={};O(En,{EvmClient:()=>Mt,EvmRpcAdapter:()=>kt,createChain:()=>Ve});import{Binary as hi,FixedSizeBinary as Fn}from"polkadot-api";import{hydration as bi}from"@galacticcouncil/descriptors";import{encodeFunctionData as yi,decodeFunctionResult as fi}from"viem";var Pi=10000000n,kt=class{api;constructor(t){this.api=t.getTypedApi(bi)}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=yi({abi:e,functionName:r,args:i}),s=await this.api.apis.EthereumRuntimeRPCApi.call(Fn.fromText(""),Fn.fromHex(n),hi.fromHex(a),[0n,0n,0n,0n],[Pi,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 fi({abi:e,functionName:r,data:l.asHex()});throw console.log(r,o.type,o.value.type),new Error("Contract read error")})};import{defineChain as Si}from"viem";var wi=["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=()=>Si({id:222222,name:"Hydration",network:"hydration",nativeCurrency:{decimals:18,name:"WETH",symbol:"WETH"},rpcUrls:{default:{http:wi}},blockExplorers:{default:{name:"Hydration Explorer",url:"https://hydration.subscan.io"}},testnet:!1});import{createPublicClient as Rn,createWalletClient as Ti,custom as Cn,http as vi}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 Rn({chain:this.chain,transport:vi()})}getWsProvider(){return Rn({transport:Cn({request:({method:t,params:e})=>this.client._request(t,e||[])})})}getSigner(t){return Ti({account:t,chain:this.chain,transport:Cn(window.ethereum)})}getRPCAdapter(){return new kt(this.client)}};var Vn={};O(Vn,{LiquidityMiningApi:()=>Lt,LiquidityMiningClient:()=>qt});import{AccountId as Vi}from"polkadot-api";import q from"big.js";import{HYDRATION_SS58_PREFIX as Ui,RUNTIME_DECIMALS as pt}from"@galacticcouncil/common";import{fixed_from_rational as Gn}from"@galacticcouncil/math-liquidity-mining";var he={};O(he,{withTimeout:()=>xi});function xi(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 C={};O(C,{divSpot:()=>Oi,getFraction:()=>Ai,mulScaled:()=>Mn,mulSpot:()=>Ii});import{RUNTIME_DECIMALS as kn}from"@galacticcouncil/common";function Mn(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 Ii(m,t,e,n){return Mn(m,t,e,kn,n)}function Oi(m,t,e,n){if(t===0n)return 0n;let r=BigInt(10)**BigInt(kn+n-e);return m*r/t}function Ai(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={};O(v,{FeeUtils:()=>Ue,shiftNeg:()=>_i});import Bi 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 _i(m,t){let e=Bi(typeof m=="bigint"?m.toString():m);return t===0?e.toString():e.div(Math.pow(10,t)).toString()}var Dt={};O(Dt,{findNestedKey:()=>Fi,findNestedObj:()=>Ri,jsonFormatter:()=>Ci});var Fi=(m,t)=>{let e=[];return JSON.stringify(m,(n,r)=>(r&&r[t]&&e.push(r),r)),e[0]},Ri=(m,t,e)=>{let n;return JSON.stringify(m,(r,i)=>(i&&i[t]===e&&(n=i),i)),n},Ci=(m,t)=>typeof t=="bigint"?t.toString():t;var L={};O(L,{calculateBuyFee:()=>Di,calculateDiffToAvg:()=>Ei,calculateDiffToRef:()=>ki,calculateSellFee:()=>Mi});import j from"big.js";function Ei(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 ki(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 Mi(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 Di(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 Dn}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 Dn(null,{ttl:r}):new Dn;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 Li,calculate_global_farm_rewards as qi,calculate_loyalty_multiplier as Ni,calculate_user_reward as Hn,calculate_yield_farm_delta_rpvs as Hi}from"@galacticcouncil/math-liquidity-mining";import Ln from"big.js";var We=Ln(10).pow(18),qn=BigInt(Ln(1).pow(18).toString()),Nn=6e3;var Gi="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(qi(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(Li(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=Hi(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 Ni(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(Hn(n.accumulated_rpvs.toString(),n.valued_shares.toString(),n.accumulated_claimed_rewards.toString(),o.accumulated_rpvs.toString(),u)),p=BigInt(Hn(n.accumulated_rpvs.toString(),n.valued_shares.toString(),n.accumulated_claimed_rewards.toString(),o.accumulated_rpvs.toString(),Gi));return{reward:d,maxReward:p,assetId:s.reward_currency,yieldFarmId:o.id,isActiveFarm:o.state.type==="Active"}}};var Wi=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??Nn})}get blockTime(){return this.options.blockTime}async getOraclePrice(t,e){let n=[t,e].sort((i,a)=>i-a);if(t===e)return qn;let r=await this.client.getOraclePrice(n);if(r){let{n:i,d:a}=r[0].price,s;return t<e?s=Gn(i.toString(),a.toString()):s=Gn(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 Vi(Ui).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=Wi.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 Br=this.getGlobalRewardPerPeriod(p,d,h,F),_r=this.getPoolYieldPerPeriod(Br,k,p,F);H=q(_r).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(),Or=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 Ar=$?q(H).times($).toString():void 0;return{apr:H,minApr:Ar,isDistributed:bn,estimatedEndPeriod:le,estimatedEndBlock:ke,maxRewards:Ot,incentivizedAsset:S,rewardCurrency:P,loyaltyCurve:c,currentPeriod:oe,potMaxRewards:ae,fullness:Or,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 Yi,Enum as $i}from"polkadot-api";var qt=class extends _{omnipoolAssetIds=[];async getOraclePrice(t){return await this.api.query.EmaOracle.Oracles.getValue(Yi.fromText("omnipool"),t,$i("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 cr={};O(cr,{PoolContextProvider:()=>St,PoolError:()=>Z,PoolFactory:()=>ft,PoolType:()=>I,aave:()=>nn,hsm:()=>on,lbp:()=>ze,omni:()=>Qe,stable:()=>Ze,xyk:()=>tn});var ze={};O(ze,{LbpMath:()=>Y,LbpPool:()=>Nt,LbpPoolClient:()=>Ht});import{calculate_in_given_out as Xi,calculate_out_given_in as zi,calculate_linear_weights as Ki,calculate_pool_trade_fee as ji,get_spot_price as Qi}from"@galacticcouncil/math-lbp";var Y=class{static getSpotPrice(t,e,n,r,i){return Qi(t,e,n,r,i)}static calculateInGivenOut(t,e,n,r,i){return Xi(t,e,n,r,i)}static calculateOutGivenIn(t,e,n,r,i){return zi(t,e,n,r,i)}static calculateLinearWeights(t,e,n,r,i){return Ki(t,e,n,r,i)}static calculatePoolTradeFee(t,e,n){return ji(t,e,n)}};import{big as Un,RUNTIME_DECIMALS as Wn}from"@galacticcouncil/common";var I=(a=>(a.Aave="Aave",a.LBP="LBP",a.Omni="Omnipool",a.Stable="Stableswap",a.XYK="XYK",a.HSM="HSM",a))(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:Yn}=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=Yn.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=Yn.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(),Un.toBigInt(1,Wn).toString());return BigInt(e)}spotPriceOutGivenIn(t){let e=Y.getSpotPrice(t.balanceIn.toString(),t.balanceOut.toString(),t.weightIn.toString(),t.weightOut.toString(),Un.toBigInt(1,Wn).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 ha}from"polkadot-api";import{Subscription as ba,distinctUntilChanged as ya,filter as fa}from"rxjs";import{memoize1 as ea}from"@thi.ng/memoize";import{TLRUCache as na}from"@thi.ng/cache";import{ReplaySubject as $n,Subscription as Xn,combineLatest as ra,defer as ia,from as aa,merge as Ye,of as sa,EMPTY as Te}from"rxjs";import{bufferCount as oa,bufferTime as la,catchError as ve,filter as xe,finalize as $e,map as dt,pairwise as Xe,repeat as zn,skip as ca,share as ua,startWith as ma,switchMap as Kn,tap as gt,throttleTime as pa}from"rxjs/operators";import{BehaviorSubject as Ji}from"rxjs";var Pe=class{store$=new Ji([]);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 Zi}from"@galacticcouncil/common";var ta={Aave:"AAVE",LBP:"LBP",Omnipool:"OMNI",Stableswap:"STBL",XYK:"XYK",HSM:"HSM"},{logger:Se}=Zi,we=class{type;constructor(t){this.type=t}prefix(){return this.pad(`pool(${ta[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:da}=he,ga=3e3,N=class extends _{evm;balance;store=new Pe;log;shared$;resync$=new $n(1);resyncAt=0;resyncPending=!1;mem=0;memPoolsCache=new na(null,{ttl:6*1e3});memPools=ea(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(ma([]),oa(2,1),dt(([t,e])=>t.length===0?e:this.store.applyChangeset(e)),xe(t=>t.length>0),pa(1e3,void 0,{leading:!0,trailing:!0}))}subscribeStore(){return ia(()=>{let t=new Xn;return t.add(this.startWatchdog()),this.resync$.next(),this.resync$.pipe(Kn(()=>{let e=new Xn;return aa(da(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())}),Kn(r=>Ye(sa(r),this.store.asObservable().pipe(ca(1)))),$e(()=>{e.unsubscribe()}))}),$e(()=>t.unsubscribe()))}).pipe(ua({connector:()=>new $n(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 ra(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(la(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})=>t.type==="XYK"?n>0n&&!!e:!!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<ga||(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)),zn({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)),zn({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(ha.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(fa(t=>t!==void 0),ya((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 ba;return t.add(this.subscribeValidationData()),t}};var Qe={};O(Qe,{OmniMath:()=>x,OmniPool:()=>Gt,OmniPoolClient:()=>Ut});import{calculate_in_given_out as Pa,calculate_lrna_in_given_out as Sa,calculate_out_given_in as wa,calculate_out_given_lrna_in as Ta,calculate_spot_price as va,calculate_lrna_spot_price as xa,calculate_shares as Ia,calculate_liquidity_out as Oa,calculate_liquidity_lrna_out as Aa,verify_asset_cap as Ba,calculate_liquidity_hub_in as _a,is_sell_allowed as Fa,is_buy_allowed as Ra,is_add_liquidity_allowed as Ca,is_remove_liquidity_allowed as Ea,recalculate_asset_fee as ka,recalculate_protocol_fee as Ma}from"@galacticcouncil/math-omnipool";import ht from"big.js";var x=class{static calculateSpotPrice(t,e,n,r){return va(t,e,n,r)}static calculateLrnaSpotPrice(t,e){return xa(t,e)}static calculateInGivenOut(t,e,n,r,i,a,s,o,l,c){return Pa(t,e,n,r,i,a,s,o,l,c)}static calculateLrnaInGivenOut(t,e,n,r,i,a){return Sa(t,e,n,r,i,a)}static calculateOutGivenIn(t,e,n,r,i,a,s,o,l,c){return wa(t,e,n,r,i,a,s,o,l,c)}static calculateOutGivenLrnaIn(t,e,n,r,i,a){return Ta(t,e,n,r,i,a)}static calculateShares(t,e,n,r){return Ia(t,e,n,r)}static calculateLiquidityOut(t,e,n,r,i,a,s,o){return Oa(t,e,n,r,i,a,s,o)}static calculateLiquidityLRNAOut(t,e,n,r,i,a,s,o){return Aa(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 _a(t,e,n,r)}static isSellAllowed(t){return Fa(t)}static isBuyAllowed(t){return Ra(t)}static isAddLiquidityAllowed(t){return Ca(t)}static isRemoveLiquidityAllowed(t){return Ea(t)}static recalculateAssetFee(t,e,n,r,i,a,s,o,l,c,u){return ka(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 Ma(t,e,n,r,i,a,s,o,l,c,u)}static verifyAssetCap(t,e,n,r){return Ba(t,e,n,r)}};import{big as Da}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=Da.pow10(Math.abs(r));return r>0?t*i:t/i}};import{AccountId as La,Binary as qa,CompatibilityLevel as jn,Enum as Na}from"polkadot-api";import{toHex as Ha}from"@polkadot-api/utils";import{Subscription as Ga,distinctUntilChanged as Ke,filter as Va,finalize as je,map as Vt,merge as Ua,tap as Ie}from"rxjs";import{HYDRATION_SS58_PREFIX as Wa}from"@galacticcouncil/common";var{FeeUtils:B}=v,Qn=qa.fromText("omnipool"),Jn=Na("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(Qn,t,Jn,{at:"best"}),t=>t.join(":"),6*1e3);getPoolType(){return"Omnipool"}getPoolAddress(){let t="modlomnipool".padEnd(32,"\0"),e=new TextEncoder().encode(t),n=Ha(e);return La(Wa).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(jn.BackwardsCompatible,e)}async isSlipFeeSupported(){return this.apiNext.query.Omnipool.SlipFee.isCompatible(jn.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(Qn,r,Jn,"best").pipe(Va(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 Ua(...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 Ga;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={};O(Ze,{StableMath:()=>M,StableSwap:()=>it,StableSwapClient:()=>Wt});import{calculate_in_given_out as Ya,calculate_out_given_in as $a,calculate_amplification as Xa,calculate_add_one_asset as za,calculate_liquidity_out_one_asset as Ka,calculate_shares as ja,calculate_shares_for_amount as Qa,calculate_spot_price_with_fee as Ja,pool_account_name as Za,recalculate_peg as ts}from"@galacticcouncil/math-stableswap";var M=class{static getPoolAddress(t){return Za(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 Xa(t,e,n,r,i)}static calculateInGivenOut(t,e,n,r,i,a,s){return Ya(t,e,n,r,i,a,s)}static calculateAddOneAsset(t,e,n,r,i,a,s){return za(t,e,n,r,i,a,s)}static calculateSharesForAmount(t,e,n,r,i,a,s){return Qa(t,e,n,r,i,a,s)}static calculateOutGivenIn(t,e,n,r,i,a,s){return $a(t,e,n,r,i,a,s)}static calculateLiquidityOutOneAsset(t,e,n,r,i,a,s){return Ka(t,e,n,r,i,a,s)}static calculateShares(t,e,n,r,i,a){return ja(t,e,n,r,i,a)}static calculateSpotPriceWithFee(t,e,n,r,i,a,s,o){return Ja(t,e,n,r,i,a,s,o)}static recalculatePegs(t,e,n,r,i,a){let s=ts(t,e,n,r,i,a);return JSON.parse(s)}};import{RUNTIME_DECIMALS as es,big as Zn}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*Zn.pow10(es-i):n?t/Zn.pow10(i-r):t}};import{AccountId as ns,CompatibilityLevel as rs}from"polkadot-api";import{toHex as is}from"@polkadot-api/utils";import{blake2b as as}from"@noble/hashes/blake2b";import{Subscription as ss,distinctUntilChanged as os,map as Je,merge as ls,tap as tr}from"rxjs";import{HYDRATION_SS58_PREFIX as cs,RUNTIME_DECIMALS as us}from"@galacticcouncil/common";var{FeeUtils:ms}=v,Wt=class extends N{poolsData=new Map([]);getPoolType(){return"Stableswap"}getPoolAddress(t){let e=M.getPoolAddress(t),n=as(e,{dkLen:32}),r=is(n);return ns(cs).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(rs.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:us}),this.poolsData.set(s,a),{address:o,id:s,type:"Stableswap",fee:ms.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})),tr(({index:r,value:i})=>{r>0&&this.log.trace("tokens.TotalIssuance",n,i)}),Je(({value:r})=>({id:n,value:r}))));return ls(...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(os((t,e)=>!e.deltas),Je((t,e)=>({value:t,index:e})),tr(({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 ss;return t.add(this.subscribePoolPegs()),t.add(this.subscribeIssuance()),this.hasOnRamps()&&t.add(this.subscribeBlock()),t}hasOnRamps(){return this.store.pools.filter(t=>t.isRampPeriod).length>0}};var tn={};O(tn,{XykMath:()=>Q,XykPool:()=>Yt,XykPoolClient:()=>$t});import{calculate_in_given_out as ps,calculate_out_given_in as ds,calculate_pool_trade_fee as gs,get_spot_price as hs,calculate_liquidity_in as bs,calculate_shares as ys,calculate_spot_price as fs,calculate_spot_price_with_fee as Ps,calculate_liquidity_out_asset_a as Ss,calculate_liquidity_out_asset_b as ws}from"@galacticcouncil/math-xyk";var Q=class{static getSpotPrice(t,e,n){return hs(t,e,n)}static calculateInGivenOut(t,e,n){return ps(t,e,n)}static calculateOutGivenIn(t,e,n){return ds(t,e,n)}static calculatePoolTradeFee(t,e,n){return gs(t,e,n)}static calculateLiquidityIn(t,e,n){return bs(t,e,n)}static calculateSpotPrice(t,e){return fs(t,e)}static calculateSpotPriceWithFee(t,e,n,r){return Ps(t,e,n,r)}static calculateShares(t,e,n){return ys(t,e,n)}static calculateLiquidityOutAssetA(t,e,n,r){return Ss(t,e,n,r)}static calculateLiquidityOutAssetB(t,e,n,r){return ws(t,e,n,r)}};import{big as Ts}from"@galacticcouncil/common";var{FeeUtils:er}=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=er.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=er.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=Ts.pow10(Math.abs(r));return r>0?t*i:t/i}};import{CompatibilityLevel as vs}from"polkadot-api";import{Subscription as xs}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(vs.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 xs.EMPTY}};var nn={};O(nn,{AavePool:()=>Xt,AavePoolClient:()=>zt});import{big as nr,RUNTIME_DECIMALS as rr}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 nr.toBigInt(1,rr)}spotPriceOutGivenIn(t){return nr.toBigInt(1,rr)}calculateTradeFee(t,e){return 0n}};import{AccountId as Is}from"polkadot-api";import{toHex as Os}from"@polkadot-api/utils";import{Subscription as ar,filter as en,map as sr}from"rxjs";import{decodeEventLog as As}from"viem";import{erc20 as Bs,HYDRATION_SS58_PREFIX as _s}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:Fs}=Bs,Rs=["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=Os(r);return Is(_s).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 Fs.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}=As({abi:ir,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(sr(({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(sr(({payload:t})=>this.parseEvmLog(t)),en(t=>t!==void 0),en(({eventName:t})=>Rs.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 ar.EMPTY}subscribeUpdates(){let t=new ar;return t.add(this.subscribeRouterExecuted()),t.add(this.subscribeEvmLog()),t}};var on={};O(on,{HsmMath:()=>U,HsmPool:()=>Kt,HsmPoolClient:()=>Jt});import{calculate_collateral_in_given_hollar_out as Cs,calculate_collateral_out_given_hollar_in as Es,calculate_hollar_in_given_collateral_out as ks,calculate_hollar_out_given_collateral_in as Ms,calculate_imbalance as Ds,calculate_max_price as Ls,calculate_buyback_limit as qs,calculate_buyback_price_with_fee as Ns}from"@galacticcouncil/math-hsm";var U=class{static calculateCollateralInGivenHollarOut(t,e,n){return Cs(t,e,n)}static calculateCollateralOutGivenHollarIn(t,e,n){return Es(t,e,n)}static calculateHollarOutGivenCollateralIn(t,e,n){return Ms(t,e,n)}static calculateHollarInGivenCollateralOut(t,e,n){return ks(t,e,n)}static calculateImbalance(t,e,n){return Ds(t,e,n)}static calculateBuybackLimit(t,e){return qs(t,e)}static calculateBuybackPriceWithFee(t,e,n){return Ns(t,e,n)}static calculateMaxPrice(t,e){return Ls(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 Hs,CompatibilityLevel as Gs}from"polkadot-api";import{toHex as Vs}from"@polkadot-api/utils";import{Subscription as rn,combineLatest as Us,filter as or,map as an,pairwise as Ws}from"rxjs";import{decodeEventLog as Ys}from"viem";import{h160 as $s,HYDRATION_SS58_PREFIX as Xs}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:lr}=$s,zs=["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=Vs(n);return Hs(Xs).dec(r)}async isSupported(){let t=this.api.query.HSM.Collaterals,e=await this.api.compatibilityToken;return t.isCompatible(Gs.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=lr.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}=Ys({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)),or(t=>t!==void 0),or(({eventName:t})=>zs.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=lr.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?Us(r).pipe(an(i=>i.flat()),Ws(),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 Ks}from"@galacticcouncil/common";import{Subject as js,Subscription as Pt,takeUntil as Qs}from"rxjs";var{logger:Js}=Ks,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 js;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(Qs(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")||(Js.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 hr={};O(hr,{DCA_TIME_RESERVE:()=>pr,DEFAULT_BLOCK_TIME:()=>mr,DEFAULT_MIN_BUDGET:()=>un,ORDER_MIN_BLOCK_PERIOD:()=>dr,Router:()=>wt,TWAP_EXECUTION_INTERVAL:()=>ne,TWAP_MAX_DURATION:()=>pn,TWAP_MAX_PRICE_IMPACT:()=>mn,TWAP_TX_MULTIPLIER:()=>ab,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 Zs=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>Zs)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 E,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:ur}=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?ur.toPct(t.min):void 0,r=t.max?ur.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=C.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:E.toDecimal(n.amountIn,n.assetInDecimals),amountOut:E.toDecimal(r.amountOut,r.assetOutDecimals),spotPrice:E.toDecimal(a,Tt),tradeFee:E.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=C.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"?E.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=C.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:E.toDecimal(l,o.decimalsIn),amountOut:E.toDecimal(u,o.decimalsOut),calculatedOut:E.toDecimal(d,o.decimalsOut),spotPrice:E.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=C.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:E.toDecimal(n.amountOut,n.assetOutDecimals),amountIn:E.toDecimal(r.amountIn,r.assetInDecimals),spotPrice:E.toDecimal(a,Tt),tradeFee:E.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"?E.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=C.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:E.toDecimal(l,o.decimalsOut),amountIn:E.toDecimal(u,o.decimalsIn),calculatedIn:E.toDecimal(d,o.decimalsIn),spotPrice:E.toDecimal(g,Tt),tradeFeePct:p,tradeFeeRange:b,priceImpactPct:y,errors:h}}})}return r}};import{big as D}from"@galacticcouncil/common";var mr=6e3,un=1000000000000000n,ne=6,mn=-5,pn=216e5,ab=3,pr=.1,dr=6;import{Enum as gr}from"polkadot-api";var G=class{static build(t){return t.map(({assetIn:e,assetOut:n,pool:r,poolId:i})=>r==="Stableswap"?{pool:gr("Stableswap",i),asset_in:e,asset_out:n}:{pool:gr(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 C.mulSpot(this.minOrderBudget,n.amount,12,e);let r=await this.router.getSpotPrice(t,0);if(r)return C.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 Tr={};O(Tr,{BIG_10:()=>wr,BIG_BILL:()=>dn,StakingApi:()=>re,StakingClient:()=>ie});import{calculate_accumulated_rps as ro,calculate_percentage_amount as io,calculate_period_number as fr,calculate_points as Pr,calculate_rewards as ao,sigmoid as Sr}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},br=m=>Object.keys(_e).includes(m);import{AccountId as to}from"polkadot-api";import{toHex as eo}from"@polkadot-api/utils";import{HYDRATION_SS58_PREFIX as no}from"@galacticcouncil/common";function yr(m){let t=("modl"+m).padEnd(32,"\0"),e=new TextEncoder().encode(t),n=eo(e);return to(no).dec(n)}var Fe="20000000000000000",Re="2000",wr=W(10),dn=W(wr.pow(12)),re=class{client;balance;constructor(t,e){this.client=t,this.balance=e}async getPotBalance(){let t=await this.client.getPalletId(),e=yr(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")&&br(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?ro(a.toString(),g.toString(),s.toString()):a.toString(),y=fr(c.toString(),n,b),S=fr(c.toString(),o.createdAt.toString(),b),P=ao(f,o.rewardPerStake.toString(),o.stake.toString()),w=this.getCurrentActionPoints(o.votes,o.actionPoints,o.stake,e),T=Pr(S,y,d.toString(),p.toString(),w.currentActionPoints,h.toString(),o.accumulatedSlashPoints.toString()),F=Sr(T,Fe,Re),k=(()=>{if(!e.length)return;let Ot=Pr(S,y,d.toString(),p.toString(),w.maxActionPoints.toString(),h.toString(),o.accumulatedSlashPoints.toString());return Sr(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=io($.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 Ir={};O(Ir,{TxBuilderFactory:()=>It});import{Enum as xr}from"polkadot-api";function vr(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=xr("Signed",t),r=xr("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=vr(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=C.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=C.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=C.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=C.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=C.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 Hy(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,C as calc,Bn as client,Tn as const,Hy as createSdkContext,_n as error,En as evm,Vn as farm,v as fmt,Dt as json,L as math,cr as pool,hr as sor,Tr as staking,Ir as tx};
|