import { Contract } from 'ethers'; import { PoolState, QuoteEngine, QuoteExactInputSingleParams, QuoteExactInputSingleResult, } from './quote-engine'; export type AlgebraQuoteEngineExtras = { limitSqrtPrice?: bigint | number; }; export class AlgebraQuoteEngine implements QuoteEngine { constructor( // eslint-disable-next-line @typescript-eslint/no-explicit-any private quoter: any, private pool?: Contract, ) {} setPool(pool: Contract): void { this.pool = pool; } async quoteExactInputSingle( params: QuoteExactInputSingleParams, ): Promise { const limitSqrtPrice = BigInt( this.resolveLimitSqrtPrice(params).toString(), ); const quoteFn = this.quoter.getFunction('quoteExactInputSingle'); const q = await quoteFn.staticCall({ tokenIn: params.tokenIn, tokenOut: params.tokenOut, amountIn: params.amountIn, limitSqrtPrice, }); return { amountOut: BigInt(q.amountOut.toString()), sqrtPriceX96After: BigInt(q.sqrtPriceX96After.toString()), }; } async getCurrentPoolState(): Promise { if (!this.pool) { throw new Error('AlgebraQuoteEngine: pool contract not set'); } const slot0 = await (this.pool.globalState?.() ?? this.pool.slot0?.()); if (!slot0) { throw new Error('AlgebraQuoteEngine: unable to fetch pool state'); } const sqrtPriceCandidate = slot0.price ?? slot0.sqrtPriceX96 ?? slot0.sqrtPrice ?? slot0[0]; if (!sqrtPriceCandidate) { throw new Error( 'AlgebraQuoteEngine: missing sqrt price in pool state response', ); } const sqrtPriceX96 = BigInt(sqrtPriceCandidate.toString()); const tickCandidate = slot0.tick ?? slot0.currentTick ?? slot0[1]; const tick = tickCandidate === undefined || tickCandidate === null ? undefined : Number( typeof tickCandidate === 'bigint' ? tickCandidate.toString() : tickCandidate.toString(), ); return { sqrtPriceX96, tick, }; } private resolveLimitSqrtPrice(params: QuoteExactInputSingleParams): bigint { const extras = params.extras as AlgebraQuoteEngineExtras | undefined; const limitFromExtras = (extras?.limitSqrtPrice === undefined || extras?.limitSqrtPrice === null ? undefined : typeof extras.limitSqrtPrice === 'number' ? BigInt(extras.limitSqrtPrice) : extras.limitSqrtPrice) ?? (params.extras?.['limit_sqrt_price'] === undefined || params.extras?.['limit_sqrt_price'] === null ? undefined : typeof params.extras?.['limit_sqrt_price'] === 'number' ? BigInt(params.extras?.['limit_sqrt_price']) : (params.extras?.['limit_sqrt_price'] as bigint)); return ( (params.sqrtPriceLimitX96 as bigint | undefined) ?? limitFromExtras ?? 0n ); } }