{"version":3,"sources":["../../src/modules/SOREstSwapHandler.ts"],"sourcesContent":["import BigNumber from \"bignumber.js\";\nimport { toBigNumber } from \"../helpers\";\nimport { Entry, SOREstSwapResult, SOROrderBook, SwapSourceField } from \"../types/swap.type\";\n\nexport class SOREstSwapHandler {\n  private _ob: SOROrderBook;\n  private _entries: Entry[];\n  private _sourceField: SwapSourceField;\n  private _amount: string;\n\n  constructor(ob: SOROrderBook, field: SwapSourceField, amount: string) {\n    this._ob = ob\n    this._entries = this._ob.entries;\n    this._sourceField = field;\n    this._amount = amount;\n  }\n\n  get(): SOREstSwapResult {\n    const { amountIn, amountOut, prices, routeIdx, amounts, isExceed } =\n      this._findClosestAmount();\n\n    const compareAmount = this._sourceField == \"input\" ? amountIn : amountOut;\n\n    if (toBigNumber(compareAmount).isZero() || isExceed) {\n      return {\n        sourceAmount: this._amount,\n        destAmount: String(0),\n        amounts: [],\n        sourceField: this._sourceField,\n        destField: this._sourceField == \"input\" ? \"output\" : \"input\",\n        routeIdx: routeIdx,\n        prices: prices,\n        priceImpact: \"0\",\n        estPriceImpact: \"0\",\n        isExceed: isExceed,\n        routeMatrix: []\n      };\n    }\n\n    const singleTargetAmount = toBigNumber(this._amount).div(compareAmount);\n\n    const estimatedAmounts = amounts.map((amount) => {\n      return singleTargetAmount.multipliedBy(amount).toFixed(0);\n    });\n\n    const destAmount =\n      this._sourceField == \"input\"\n        ? estimatedAmounts.at(-1)\n        : estimatedAmounts[0];\n\n    const estPriceImpact = new BigNumber(destAmount ?? 0).gt(0)\n      ? destAmount\n      : String(0);\n\n    let priceImpact = \"\";\n\n    if (prices.length == 1 && this._entries[0]?.prices[0]) {\n      const prevValue = Number(this._entries[0].prices[0]);\n      const difference = Number(prices[0]) - Number(prevValue);\n      const ratio = difference / prevValue;\n\n      let percentageChange: number | string = Math.abs(ratio * 100);\n      if (percentageChange !== Math.floor(percentageChange)) {\n        percentageChange =\n          Number.parseFloat(String(percentageChange)) == 0\n            ? 0.01\n            : Number.parseFloat(percentageChange.toFixed(2));\n      }\n      priceImpact = String(percentageChange);\n    }\n\n    const result: SOREstSwapResult = {\n      sourceAmount: this._amount,\n      destAmount: destAmount!,\n      sourceField: this._sourceField,\n      prices: prices,\n      routeIdx: routeIdx,\n      amounts: estimatedAmounts,\n      destField: this._sourceField == \"input\" ? \"output\" : \"input\",\n      priceImpact: priceImpact,\n      estPriceImpact: estPriceImpact ?? \"\",\n      isExceed: isExceed,\n      routeMatrix: this._ob.routeMatrix[routeIdx] ?? []\n    };\n\n    if (this.isAmountInGreaterThanAllowed) {\n      result.error = new Error(\"Trade size exceeds 40% of LP Pool\");\n    }\n\n    return result;\n  }\n\n  private _findClosestAmount() {\n    if (this._entries.length === 0) {\n      throw new Error(\"Book entries is empty\");\n    }\n\n    const getAmount = (entry: Entry) => {\n      return this._sourceField == \"input\"\n        ? toBigNumber(entry.amounts[0]!).toFixed(0)\n        : toBigNumber(entry.amounts.at(-1)!).toFixed(0);\n    };\n\n    let closest = this._entries[0]!;\n    let closestDiff = toBigNumber(this._amount).minus(getAmount(closest)).abs();\n\n    for (let i = 1; i < this._entries.length; i++) {\n      const entry = this._entries[i];\n      const currentAmount = getAmount(entry!);\n      const currentDiff = toBigNumber(this._amount).minus(currentAmount).abs();\n\n      if (currentDiff.isLessThan(closestDiff)) {\n        closest = this._entries[i]!;\n        closestDiff = currentDiff;\n      }\n    }\n\n    return {\n      amountIn: closest.amounts.at(0)!,\n      amountOut: closest.amounts.at(-1)!,\n      routeIdx: closest.routeIdx,\n      amounts: closest.amounts,\n      prices: closest.prices,\n      isExceed: closest.isExceed,\n    };\n  }\n\n  private get maxAmountIn() {\n    const entries = this._entries.at(-1);\n\n    return toBigNumber(entries?.amounts[0] ?? 0);\n  }\n\n  private get isAmountInGreaterThanAllowed() {\n    return toBigNumber(this._amount).gt(this.maxAmountIn);\n  }\n}\n"],"mappings":"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","names":["BigNumber","SOREstSwapHandler","ob","field","amount","amountIn","amountOut","prices","routeIdx","amounts","isExceed","compareAmount","toBigNumber","singleTargetAmount","estimatedAmounts","destAmount","estPriceImpact","BigNumber","priceImpact","prevValue","ratio","percentageChange","result","getAmount","entry","closest","closestDiff","i","currentAmount","currentDiff","entries"]}