UNPKG

astra-router-sdk

Version:

An sdk for routing swaps using Astra Classic and Astra CL.

2,185 lines 97.5 kB
'use strict';

Object.defineProperty(exports, '__esModule', { value: true });

function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }

var astraSdkCore = require('astra-sdk-core');
var JSBI = _interopDefault(require('jsbi'));
var abi = require('@ethersproject/abi');
var invariant = _interopDefault(require('tiny-invariant'));
var IApproveAndCall_json = require('@airdao/swap-router-contracts/artifacts/contracts/interfaces/IApproveAndCall.sol/IApproveAndCall.json');
var astraClSdkDev = require('astra-cl-sdk-dev');
var IMulticallExtended_json = require('@airdao/swap-router-contracts/artifacts/contracts/interfaces/IMulticallExtended.sol/IMulticallExtended.json');
var IPeripheryPaymentsWithFeeExtended_json = require('@airdao/swap-router-contracts/artifacts/contracts/interfaces/IPeripheryPaymentsWithFeeExtended.sol/IPeripheryPaymentsWithFeeExtended.json');
var ISwapRouter02_json = require('@airdao/swap-router-contracts/artifacts/contracts/interfaces/ISwapRouter02.sol/ISwapRouter02.json');
var astraClassicSdk = require('astra-classic-sdk');
var solidity = require('@ethersproject/solidity');

var ADDRESS_ZERO = '0x0000000000000000000000000000000000000000';
var MSG_SENDER = '0x0000000000000000000000000000000000000001';
var ADDRESS_THIS = '0x0000000000000000000000000000000000000002';
var ZERO = /*#__PURE__*/JSBI.BigInt(0);
var ONE = /*#__PURE__*/JSBI.BigInt(1);
// = 1 << 23 or 0b0100000000000000000000000
var MIXED_QUOTER_V1_CLASSIC_FEE_PATH_PLACEHOLDER = 1 << 23;
// = 10 << 4 or 0b00100000
var MIXED_QUOTER_CLASSIC_CLASSIC_FEE_PATH_PLACEHOLDER = 2 << 4;
// = 11 << 20 or 0b001100000000000000000000
var MIXED_QUOTER_CLASSIC_CL_FEE_PATH_PLACEHOLDER = 3 << 20;
var ZERO_PERCENT = /*#__PURE__*/new astraSdkCore.Percent(ZERO);
var ONE_HUNDRED_PERCENT = /*#__PURE__*/new astraSdkCore.Percent(100, 100);

(function (ApprovalTypes) {
  ApprovalTypes[ApprovalTypes["NOT_REQUIRED"] = 0] = "NOT_REQUIRED";
  ApprovalTypes[ApprovalTypes["MAX"] = 1] = "MAX";
  ApprovalTypes[ApprovalTypes["MAX_MINUS_ONE"] = 2] = "MAX_MINUS_ONE";
  ApprovalTypes[ApprovalTypes["ZERO_THEN_MAX"] = 3] = "ZERO_THEN_MAX";
  ApprovalTypes[ApprovalTypes["ZERO_THEN_MAX_MINUS_ONE"] = 4] = "ZERO_THEN_MAX_MINUS_ONE";
})(exports.ApprovalTypes || (exports.ApprovalTypes = {}));
// type guard
function isMint(options) {
  return Object.keys(options).some(function (k) {
    return k === 'recipient';
  });
}
var ApproveAndCall = /*#__PURE__*/function () {
  /**
   * Cannot be constructed.
   */
  function ApproveAndCall() {}
  ApproveAndCall.encodeApproveMax = function encodeApproveMax(token) {
    return ApproveAndCall.INTERFACE.encodeFunctionData('approveMax', [token.address]);
  };
  ApproveAndCall.encodeApproveMaxMinusOne = function encodeApproveMaxMinusOne(token) {
    return ApproveAndCall.INTERFACE.encodeFunctionData('approveMaxMinusOne', [token.address]);
  };
  ApproveAndCall.encodeApproveZeroThenMax = function encodeApproveZeroThenMax(token) {
    return ApproveAndCall.INTERFACE.encodeFunctionData('approveZeroThenMax', [token.address]);
  };
  ApproveAndCall.encodeApproveZeroThenMaxMinusOne = function encodeApproveZeroThenMaxMinusOne(token) {
    return ApproveAndCall.INTERFACE.encodeFunctionData('approveZeroThenMaxMinusOne', [token.address]);
  };
  ApproveAndCall.encodeCallPositionManager = function encodeCallPositionManager(calldatas) {
    !(calldatas.length > 0) ?  invariant(false, 'NULL_CALLDATA')  : void 0;
    if (calldatas.length === 1) {
      return ApproveAndCall.INTERFACE.encodeFunctionData('callPositionManager', calldatas);
    } else {
      var encodedMulticall = astraClSdkDev.NonfungiblePositionManager.INTERFACE.encodeFunctionData('multicall', [calldatas]);
      return ApproveAndCall.INTERFACE.encodeFunctionData('callPositionManager', [encodedMulticall]);
    }
  }
  /**
   * Encode adding liquidity to a position in the nft manager contract
   * @param position Forcasted position with expected amount out from swap
   * @param minimalPosition Forcasted position with custom minimal token amounts
   * @param addLiquidityOptions Options for adding liquidity
   * @param slippageTolerance Defines maximum slippage
   */;
  ApproveAndCall.encodeAddLiquidity = function encodeAddLiquidity(position, minimalPosition, addLiquidityOptions, slippageTolerance) {
    var _position$mintAmounts = position.mintAmountsWithSlippage(slippageTolerance),
      amount0Min = _position$mintAmounts.amount0,
      amount1Min = _position$mintAmounts.amount1;
    // position.mintAmountsWithSlippage() can create amounts not dependenable in scenarios
    // such as range orders. Allow the option to provide a position with custom minimum amounts
    // for these scenarios
    if (JSBI.lessThan(minimalPosition.amount0.quotient, amount0Min)) {
      amount0Min = minimalPosition.amount0.quotient;
    }
    if (JSBI.lessThan(minimalPosition.amount1.quotient, amount1Min)) {
      amount1Min = minimalPosition.amount1.quotient;
    }
    if (isMint(addLiquidityOptions)) {
      return ApproveAndCall.INTERFACE.encodeFunctionData('mint', [{
        token0: position.pool.token0.address,
        token1: position.pool.token1.address,
        fee: position.pool.fee,
        tickLower: position.tickLower,
        tickUpper: position.tickUpper,
        amount0Min: astraClSdkDev.toHex(amount0Min),
        amount1Min: astraClSdkDev.toHex(amount1Min),
        recipient: addLiquidityOptions.recipient
      }]);
    } else {
      return ApproveAndCall.INTERFACE.encodeFunctionData('increaseLiquidity', [{
        token0: position.pool.token0.address,
        token1: position.pool.token1.address,
        amount0Min: astraClSdkDev.toHex(amount0Min),
        amount1Min: astraClSdkDev.toHex(amount1Min),
        tokenId: astraClSdkDev.toHex(addLiquidityOptions.tokenId)
      }]);
    }
  };
  ApproveAndCall.encodeApprove = function encodeApprove(token, approvalType) {
    switch (approvalType) {
      case exports.ApprovalTypes.MAX:
        return ApproveAndCall.encodeApproveMax(token.wrapped);
      case exports.ApprovalTypes.MAX_MINUS_ONE:
        return ApproveAndCall.encodeApproveMaxMinusOne(token.wrapped);
      case exports.ApprovalTypes.ZERO_THEN_MAX:
        return ApproveAndCall.encodeApproveZeroThenMax(token.wrapped);
      case exports.ApprovalTypes.ZERO_THEN_MAX_MINUS_ONE:
        return ApproveAndCall.encodeApproveZeroThenMaxMinusOne(token.wrapped);
      default:
        throw new Error('Error: invalid ApprovalType');
    }
  };
  return ApproveAndCall;
}();
ApproveAndCall.INTERFACE = /*#__PURE__*/new abi.Interface(IApproveAndCall_json.abi);

function validateAndParseBytes32(bytes32) {
  if (!bytes32.match(/^0x[0-9a-fA-F]{64}$/)) {
    throw new Error(bytes32 + " is not valid bytes32.");
  }
  return bytes32.toLowerCase();
}
var MulticallExtended = /*#__PURE__*/function () {
  /**
   * Cannot be constructed.
   */
  function MulticallExtended() {}
  MulticallExtended.encodeMulticall = function encodeMulticall(calldatas, validation) {
    // if there's no validation, we can just fall back to regular multicall
    if (typeof validation === 'undefined') {
      return astraClSdkDev.Multicall.encodeMulticall(calldatas);
    }
    // if there is validation, we have to normalize calldatas
    if (!Array.isArray(calldatas)) {
      calldatas = [calldatas];
    }
    // this means the validation value should be a previousBlockhash
    if (typeof validation === 'string' && validation.startsWith('0x')) {
      var previousBlockhash = validateAndParseBytes32(validation);
      return MulticallExtended.INTERFACE.encodeFunctionData('multicall(bytes32,bytes[])', [previousBlockhash, calldatas]);
    } else {
      var deadline = astraClSdkDev.toHex(validation);
      return MulticallExtended.INTERFACE.encodeFunctionData('multicall(uint256,bytes[])', [deadline, calldatas]);
    }
  };
  return MulticallExtended;
}();
MulticallExtended.INTERFACE = /*#__PURE__*/new abi.Interface(IMulticallExtended_json.abi);

function encodeFeeBips(fee) {
  return astraClSdkDev.toHex(fee.multiply(10000).quotient);
}
var PaymentsExtended = /*#__PURE__*/function () {
  /**
   * Cannot be constructed.
   */
  function PaymentsExtended() {}
  PaymentsExtended.encodeUnwrapSAMB = function encodeUnwrapSAMB(amountMinimum, recipient, feeOptions) {
    // if there's a recipient, just pass it along
    if (typeof recipient === 'string') {
      return astraClSdkDev.Payments.encodeUnwrapSAMB(amountMinimum, recipient, feeOptions);
    }
    if (!!feeOptions) {
      var feeBips = encodeFeeBips(feeOptions.fee);
      var feeRecipient = astraSdkCore.validateAndParseAddress(feeOptions.recipient);
      return PaymentsExtended.INTERFACE.encodeFunctionData('unwrapSAMBWithFee(uint256,uint256,address)', [astraClSdkDev.toHex(amountMinimum), feeBips, feeRecipient]);
    } else {
      return PaymentsExtended.INTERFACE.encodeFunctionData('unwrapSAMB(uint256)', [astraClSdkDev.toHex(amountMinimum)]);
    }
  };
  PaymentsExtended.encodeSweepToken = function encodeSweepToken(token, amountMinimum, recipient, feeOptions) {
    // if there's a recipient, just pass it along
    if (typeof recipient === 'string') {
      return astraClSdkDev.Payments.encodeSweepToken(token, amountMinimum, recipient, feeOptions);
    }
    if (!!feeOptions) {
      var feeBips = encodeFeeBips(feeOptions.fee);
      var feeRecipient = astraSdkCore.validateAndParseAddress(feeOptions.recipient);
      return PaymentsExtended.INTERFACE.encodeFunctionData('sweepTokenWithFee(address,uint256,uint256,address)', [token.address, astraClSdkDev.toHex(amountMinimum), feeBips, feeRecipient]);
    } else {
      return PaymentsExtended.INTERFACE.encodeFunctionData('sweepToken(address,uint256)', [token.address, astraClSdkDev.toHex(amountMinimum)]);
    }
  };
  PaymentsExtended.encodePull = function encodePull(token, amount) {
    return PaymentsExtended.INTERFACE.encodeFunctionData('pull', [token.address, astraClSdkDev.toHex(amount)]);
  };
  PaymentsExtended.encodeWrapAMB = function encodeWrapAMB(amount) {
    return PaymentsExtended.INTERFACE.encodeFunctionData('wrapAMB', [astraClSdkDev.toHex(amount)]);
  };
  return PaymentsExtended;
}();
PaymentsExtended.INTERFACE = /*#__PURE__*/new abi.Interface(IPeripheryPaymentsWithFeeExtended_json.abi);

function _arrayLikeToArray(r, a) {
  (null == a || a > r.length) && (a = r.length);
  for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];
  return n;
}
function asyncGeneratorStep(n, t, e, r, o, a, c) {
  try {
    var i = n[a](c),
      u = i.value;
  } catch (n) {
    return void e(n);
  }
  i.done ? t(u) : Promise.resolve(u).then(r, o);
}
function _asyncToGenerator(n) {
  return function () {
    var t = this,
      e = arguments;
    return new Promise(function (r, o) {
      var a = n.apply(t, e);
      function _next(n) {
        asyncGeneratorStep(a, r, o, _next, _throw, "next", n);
      }
      function _throw(n) {
        asyncGeneratorStep(a, r, o, _next, _throw, "throw", n);
      }
      _next(void 0);
    });
  };
}
function _defineProperties(e, r) {
  for (var t = 0; t < r.length; t++) {
    var o = r[t];
    o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o);
  }
}
function _createClass(e, r, t) {
  return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", {
    writable: !1
  }), e;
}
function _createForOfIteratorHelperLoose(r, e) {
  var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
  if (t) return (t = t.call(r)).next.bind(t);
  if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) {
    t && (r = t);
    var o = 0;
    return function () {
      return o >= r.length ? {
        done: !0
      } : {
        done: !1,
        value: r[o++]
      };
    };
  }
  throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
function _extends() {
  return _extends = Object.assign ? Object.assign.bind() : function (n) {
    for (var e = 1; e < arguments.length; e++) {
      var t = arguments[e];
      for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]);
    }
    return n;
  }, _extends.apply(null, arguments);
}
function _inheritsLoose(t, o) {
  t.prototype = Object.create(o.prototype), t.prototype.constructor = t, _setPrototypeOf(t, o);
}
function _regeneratorRuntime() {
  _regeneratorRuntime = function () {
    return e;
  };
  var t,
    e = {},
    r = Object.prototype,
    n = r.hasOwnProperty,
    o = Object.defineProperty || function (t, e, r) {
      t[e] = r.value;
    },
    i = "function" == typeof Symbol ? Symbol : {},
    a = i.iterator || "@@iterator",
    c = i.asyncIterator || "@@asyncIterator",
    u = i.toStringTag || "@@toStringTag";
  function define(t, e, r) {
    return Object.defineProperty(t, e, {
      value: r,
      enumerable: !0,
      configurable: !0,
      writable: !0
    }), t[e];
  }
  try {
    define({}, "");
  } catch (t) {
    define = function (t, e, r) {
      return t[e] = r;
    };
  }
  function wrap(t, e, r, n) {
    var i = e && e.prototype instanceof Generator ? e : Generator,
      a = Object.create(i.prototype),
      c = new Context(n || []);
    return o(a, "_invoke", {
      value: makeInvokeMethod(t, r, c)
    }), a;
  }
  function tryCatch(t, e, r) {
    try {
      return {
        type: "normal",
        arg: t.call(e, r)
      };
    } catch (t) {
      return {
        type: "throw",
        arg: t
      };
    }
  }
  e.wrap = wrap;
  var h = "suspendedStart",
    l = "suspendedYield",
    f = "executing",
    s = "completed",
    y = {};
  function Generator() {}
  function GeneratorFunction() {}
  function GeneratorFunctionPrototype() {}
  var p = {};
  define(p, a, function () {
    return this;
  });
  var d = Object.getPrototypeOf,
    v = d && d(d(values([])));
  v && v !== r && n.call(v, a) && (p = v);
  var g = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(p);
  function defineIteratorMethods(t) {
    ["next", "throw", "return"].forEach(function (e) {
      define(t, e, function (t) {
        return this._invoke(e, t);
      });
    });
  }
  function AsyncIterator(t, e) {
    function invoke(r, o, i, a) {
      var c = tryCatch(t[r], t, o);
      if ("throw" !== c.type) {
        var u = c.arg,
          h = u.value;
        return h && "object" == typeof h && n.call(h, "__await") ? e.resolve(h.__await).then(function (t) {
          invoke("next", t, i, a);
        }, function (t) {
          invoke("throw", t, i, a);
        }) : e.resolve(h).then(function (t) {
          u.value = t, i(u);
        }, function (t) {
          return invoke("throw", t, i, a);
        });
      }
      a(c.arg);
    }
    var r;
    o(this, "_invoke", {
      value: function (t, n) {
        function callInvokeWithMethodAndArg() {
          return new e(function (e, r) {
            invoke(t, n, e, r);
          });
        }
        return r = r ? r.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg();
      }
    });
  }
  function makeInvokeMethod(e, r, n) {
    var o = h;
    return function (i, a) {
      if (o === f) throw Error("Generator is already running");
      if (o === s) {
        if ("throw" === i) throw a;
        return {
          value: t,
          done: !0
        };
      }
      for (n.method = i, n.arg = a;;) {
        var c = n.delegate;
        if (c) {
          var u = maybeInvokeDelegate(c, n);
          if (u) {
            if (u === y) continue;
            return u;
          }
        }
        if ("next" === n.method) n.sent = n._sent = n.arg;else if ("throw" === n.method) {
          if (o === h) throw o = s, n.arg;
          n.dispatchException(n.arg);
        } else "return" === n.method && n.abrupt("return", n.arg);
        o = f;
        var p = tryCatch(e, r, n);
        if ("normal" === p.type) {
          if (o = n.done ? s : l, p.arg === y) continue;
          return {
            value: p.arg,
            done: n.done
          };
        }
        "throw" === p.type && (o = s, n.method = "throw", n.arg = p.arg);
      }
    };
  }
  function maybeInvokeDelegate(e, r) {
    var n = r.method,
      o = e.iterator[n];
    if (o === t) return r.delegate = null, "throw" === n && e.iterator.return && (r.method = "return", r.arg = t, maybeInvokeDelegate(e, r), "throw" === r.method) || "return" !== n && (r.method = "throw", r.arg = new TypeError("The iterator does not provide a '" + n + "' method")), y;
    var i = tryCatch(o, e.iterator, r.arg);
    if ("throw" === i.type) return r.method = "throw", r.arg = i.arg, r.delegate = null, y;
    var a = i.arg;
    return a ? a.done ? (r[e.resultName] = a.value, r.next = e.nextLoc, "return" !== r.method && (r.method = "next", r.arg = t), r.delegate = null, y) : a : (r.method = "throw", r.arg = new TypeError("iterator result is not an object"), r.delegate = null, y);
  }
  function pushTryEntry(t) {
    var e = {
      tryLoc: t[0]
    };
    1 in t && (e.catchLoc = t[1]), 2 in t && (e.finallyLoc = t[2], e.afterLoc = t[3]), this.tryEntries.push(e);
  }
  function resetTryEntry(t) {
    var e = t.completion || {};
    e.type = "normal", delete e.arg, t.completion = e;
  }
  function Context(t) {
    this.tryEntries = [{
      tryLoc: "root"
    }], t.forEach(pushTryEntry, this), this.reset(!0);
  }
  function values(e) {
    if (e || "" === e) {
      var r = e[a];
      if (r) return r.call(e);
      if ("function" == typeof e.next) return e;
      if (!isNaN(e.length)) {
        var o = -1,
          i = function next() {
            for (; ++o < e.length;) if (n.call(e, o)) return next.value = e[o], next.done = !1, next;
            return next.value = t, next.done = !0, next;
          };
        return i.next = i;
      }
    }
    throw new TypeError(typeof e + " is not iterable");
  }
  return GeneratorFunction.prototype = GeneratorFunctionPrototype, o(g, "constructor", {
    value: GeneratorFunctionPrototype,
    configurable: !0
  }), o(GeneratorFunctionPrototype, "constructor", {
    value: GeneratorFunction,
    configurable: !0
  }), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, u, "GeneratorFunction"), e.isGeneratorFunction = function (t) {
    var e = "function" == typeof t && t.constructor;
    return !!e && (e === GeneratorFunction || "GeneratorFunction" === (e.displayName || e.name));
  }, e.mark = function (t) {
    return Object.setPrototypeOf ? Object.setPrototypeOf(t, GeneratorFunctionPrototype) : (t.__proto__ = GeneratorFunctionPrototype, define(t, u, "GeneratorFunction")), t.prototype = Object.create(g), t;
  }, e.awrap = function (t) {
    return {
      __await: t
    };
  }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, c, function () {
    return this;
  }), e.AsyncIterator = AsyncIterator, e.async = function (t, r, n, o, i) {
    void 0 === i && (i = Promise);
    var a = new AsyncIterator(wrap(t, r, n, o), i);
    return e.isGeneratorFunction(r) ? a : a.next().then(function (t) {
      return t.done ? t.value : a.next();
    });
  }, defineIteratorMethods(g), define(g, u, "Generator"), define(g, a, function () {
    return this;
  }), define(g, "toString", function () {
    return "[object Generator]";
  }), e.keys = function (t) {
    var e = Object(t),
      r = [];
    for (var n in e) r.push(n);
    return r.reverse(), function next() {
      for (; r.length;) {
        var t = r.pop();
        if (t in e) return next.value = t, next.done = !1, next;
      }
      return next.done = !0, next;
    };
  }, e.values = values, Context.prototype = {
    constructor: Context,
    reset: function (e) {
      if (this.prev = 0, this.next = 0, this.sent = this._sent = t, this.done = !1, this.delegate = null, this.method = "next", this.arg = t, this.tryEntries.forEach(resetTryEntry), !e) for (var r in this) "t" === r.charAt(0) && n.call(this, r) && !isNaN(+r.slice(1)) && (this[r] = t);
    },
    stop: function () {
      this.done = !0;
      var t = this.tryEntries[0].completion;
      if ("throw" === t.type) throw t.arg;
      return this.rval;
    },
    dispatchException: function (e) {
      if (this.done) throw e;
      var r = this;
      function handle(n, o) {
        return a.type = "throw", a.arg = e, r.next = n, o && (r.method = "next", r.arg = t), !!o;
      }
      for (var o = this.tryEntries.length - 1; o >= 0; --o) {
        var i = this.tryEntries[o],
          a = i.completion;
        if ("root" === i.tryLoc) return handle("end");
        if (i.tryLoc <= this.prev) {
          var c = n.call(i, "catchLoc"),
            u = n.call(i, "finallyLoc");
          if (c && u) {
            if (this.prev < i.catchLoc) return handle(i.catchLoc, !0);
            if (this.prev < i.finallyLoc) return handle(i.finallyLoc);
          } else if (c) {
            if (this.prev < i.catchLoc) return handle(i.catchLoc, !0);
          } else {
            if (!u) throw Error("try statement without catch or finally");
            if (this.prev < i.finallyLoc) return handle(i.finallyLoc);
          }
        }
      }
    },
    abrupt: function (t, e) {
      for (var r = this.tryEntries.length - 1; r >= 0; --r) {
        var o = this.tryEntries[r];
        if (o.tryLoc <= this.prev && n.call(o, "finallyLoc") && this.prev < o.finallyLoc) {
          var i = o;
          break;
        }
      }
      i && ("break" === t || "continue" === t) && i.tryLoc <= e && e <= i.finallyLoc && (i = null);
      var a = i ? i.completion : {};
      return a.type = t, a.arg = e, i ? (this.method = "next", this.next = i.finallyLoc, y) : this.complete(a);
    },
    complete: function (t, e) {
      if ("throw" === t.type) throw t.arg;
      return "break" === t.type || "continue" === t.type ? this.next = t.arg : "return" === t.type ? (this.rval = this.arg = t.arg, this.method = "return", this.next = "end") : "normal" === t.type && e && (this.next = e), y;
    },
    finish: function (t) {
      for (var e = this.tryEntries.length - 1; e >= 0; --e) {
        var r = this.tryEntries[e];
        if (r.finallyLoc === t) return this.complete(r.completion, r.afterLoc), resetTryEntry(r), y;
      }
    },
    catch: function (t) {
      for (var e = this.tryEntries.length - 1; e >= 0; --e) {
        var r = this.tryEntries[e];
        if (r.tryLoc === t) {
          var n = r.completion;
          if ("throw" === n.type) {
            var o = n.arg;
            resetTryEntry(r);
          }
          return o;
        }
      }
      throw Error("illegal catch attempt");
    },
    delegateYield: function (e, r, n) {
      return this.delegate = {
        iterator: values(e),
        resultName: r,
        nextLoc: n
      }, "next" === this.method && (this.arg = t), y;
    }
  }, e;
}
function _setPrototypeOf(t, e) {
  return _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function (t, e) {
    return t.__proto__ = e, t;
  }, _setPrototypeOf(t, e);
}
function _toPrimitive(t, r) {
  if ("object" != typeof t || !t) return t;
  var e = t[Symbol.toPrimitive];
  if (void 0 !== e) {
    var i = e.call(t, r || "default");
    if ("object" != typeof i) return i;
    throw new TypeError("@@toPrimitive must return a primitive value.");
  }
  return ("string" === r ? String : Number)(t);
}
function _toPropertyKey(t) {
  var i = _toPrimitive(t, "string");
  return "symbol" == typeof i ? i : i + "";
}
function _unsupportedIterableToArray(r, a) {
  if (r) {
    if ("string" == typeof r) return _arrayLikeToArray(r, a);
    var t = {}.toString.call(r).slice(8, -1);
    return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0;
  }
}

function isValidTokenPath(currentPool, inputToken) {
  return !!currentPool.involvesToken(inputToken);
}

function amountWithPathCurrency(amount, pool) {
  return astraSdkCore.CurrencyAmount.fromFractionalAmount(getPathCurrency(amount.currency, pool), amount.numerator, amount.denominator);
}
function getPathCurrency(currency, pool) {
  // return currency if the currency matches a currency of the pool
  if (pool.involvesToken(currency)) {
    return currency;
    // return if currency.wrapped if pool involves wrapped currency
  } else if (pool.involvesToken(currency.wrapped)) {
    return currency.wrapped;
  } else {
    throw new Error("Expected currency " + currency.symbol + " to be either " + pool.token0.symbol + " or " + pool.token1.symbol);
  }
  // return currency // this line needed for typescript to compile
}

/**
 * Represents a list of pools or pairs through which a swap can occur
 * @template TInput The input token
 * @template TOutput The output token
 */
var MixedRouteSDK = /*#__PURE__*/function () {
  /**
   * Creates an instance of route.
   * @param pools An array of `TPool` objects (pools or pairs), ordered by the route the swap will take
   * @param input The input token
   * @param output The output token
   */
  function MixedRouteSDK(pools, input, output) {
    this._midPrice = null;
    !(pools.length > 0) ?  invariant(false, 'POOLS')  : void 0;
    var chainId = pools[0].chainId;
    var allOnSameChain = pools.every(function (pool) {
      return pool.chainId === chainId;
    });
    !allOnSameChain ?  invariant(false, 'CHAIN_IDS')  : void 0;
    this.pathInput = getPathCurrency(input, pools[0]);
    this.pathOutput = getPathCurrency(output, pools[pools.length - 1]);
    !pools[0].involvesToken(this.pathInput) ?  invariant(false, 'INPUT')  : void 0;
    var lastPool = pools[pools.length - 1];
    !lastPool.involvesToken(output.wrapped) ?  invariant(false, 'OUTPUT')  : void 0;
    /**
     * Normalizes token0-token1 order and selects the next token/fee step to add to the path
     * */
    var tokenPath = [this.pathInput];
    pools[0].token0.equals(this.pathInput) ? tokenPath.push(pools[0].token1) : tokenPath.push(pools[0].token0);
    for (var i = 1; i < pools.length; i++) {
      var pool = pools[i];
      var inputToken = tokenPath[i];
      var outputToken = pool.token0.wrapped.equals(inputToken.wrapped) ? pool.token1 : pool.token0;
      !isValidTokenPath(pool, inputToken) ?  invariant(false, 'PATH')  : void 0;
      tokenPath.push(outputToken);
    }
    this.pools = pools;
    this.path = tokenPath;
    this.input = input;
    this.output = output != null ? output : tokenPath[tokenPath.length - 1];
  }
  return _createClass(MixedRouteSDK, [{
    key: "chainId",
    get: function get() {
      return this.pools[0].chainId;
    }
    /**
     * Returns the mid price of the route
     */
  }, {
    key: "midPrice",
    get: function get() {
      if (this._midPrice !== null) return this._midPrice;
      var price = this.pools.slice(1).reduce(function (_ref, pool) {
        var nextInput = _ref.nextInput,
          price = _ref.price;
        return nextInput.equals(pool.token0) ? {
          nextInput: pool.token1,
          price: price.multiply(pool.token0Price.asFraction)
        } : {
          nextInput: pool.token0,
          price: price.multiply(pool.token1Price.asFraction)
        };
      }, this.pools[0].token0.equals(this.pathInput) ? {
        nextInput: this.pools[0].token1,
        price: this.pools[0].token0Price.asFraction
      } : {
        nextInput: this.pools[0].token0,
        price: this.pools[0].token1Price.asFraction
      }).price;
      return this._midPrice = new astraSdkCore.Price(this.input, this.output, price.denominator, price.numerator);
    }
  }]);
}();

/**
 * Trades comparator, an extension of the input output comparator that also considers other dimensions of the trade in ranking them
 * @template TInput The input token, either Amber or an ERC-20
 * @template TOutput The output token, either Amber or an ERC-20
 * @template TTradeType The trade type, either exact input or exact output
 * @param a The first trade to compare
 * @param b The second trade to compare
 * @returns A sorted ordering for two neighboring elements in a trade array
 */
function tradeComparator(a, b) {
  // must have same input and output token for comparison
  !a.inputAmount.currency.equals(b.inputAmount.currency) ?  invariant(false, 'INPUT_CURRENCY')  : void 0;
  !a.outputAmount.currency.equals(b.outputAmount.currency) ?  invariant(false, 'OUTPUT_CURRENCY')  : void 0;
  if (a.outputAmount.equalTo(b.outputAmount)) {
    if (a.inputAmount.equalTo(b.inputAmount)) {
      // consider the number of hops since each hop costs gas
      var aHops = a.swaps.reduce(function (total, cur) {
        return total + cur.route.path.length;
      }, 0);
      var bHops = b.swaps.reduce(function (total, cur) {
        return total + cur.route.path.length;
      }, 0);
      return aHops - bHops;
    }
    // trade A requires less input than trade B, so A should come first
    if (a.inputAmount.lessThan(b.inputAmount)) {
      return -1;
    } else {
      return 1;
    }
  } else {
    // tradeA has less output than trade B, so should come second
    if (a.outputAmount.lessThan(b.outputAmount)) {
      return 1;
    } else {
      return -1;
    }
  }
}
/**
 * Represents a trade executed against a set of routes where some percentage of the input is
 * split across each route.
 *
 * Each route has its own set of pools. Pools can not be re-used across routes.
 *
 * Does not account for slippage, i.e., changes in price environment that can occur between
 * the time the trade is submitted and when it is executed.
 * @notice This class is functionally the same as the `Trade` class in the `@airdao/astra-cl-sdk` package, aside from typing and some input validation.
 * @template TInput The input token, either Amber or an ERC-20
 * @template TOutput The output token, either Amber or an ERC-20
 * @template TTradeType The trade type, either exact input or exact output
 */
var MixedRouteTrade = /*#__PURE__*/function () {
  /**
   * Construct a trade by passing in the pre-computed property values
   * @param routes The routes through which the trade occurs
   * @param tradeType The type of trade, exact input or exact output
   */
  function MixedRouteTrade(_ref) {
    var routes = _ref.routes,
      tradeType = _ref.tradeType;
    var inputCurrency = routes[0].inputAmount.currency;
    var outputCurrency = routes[0].outputAmount.currency;
    !routes.every(function (_ref2) {
      var route = _ref2.route;
      return inputCurrency.wrapped.equals(route.input.wrapped);
    }) ?  invariant(false, 'INPUT_CURRENCY_MATCH')  : void 0;
    !routes.every(function (_ref3) {
      var route = _ref3.route;
      return outputCurrency.wrapped.equals(route.output.wrapped);
    }) ?  invariant(false, 'OUTPUT_CURRENCY_MATCH')  : void 0;
    var numPools = routes.map(function (_ref4) {
      var route = _ref4.route;
      return route.pools.length;
    }).reduce(function (total, cur) {
      return total + cur;
    }, 0);
    var poolIdentifierSet = new Set();
    for (var _iterator = _createForOfIteratorHelperLoose(routes), _step; !(_step = _iterator()).done;) {
      var route = _step.value.route;
      for (var _iterator2 = _createForOfIteratorHelperLoose(route.pools), _step2; !(_step2 = _iterator2()).done;) {
        var pool = _step2.value;
        if (pool instanceof astraClSdkDev.Pool) {
          poolIdentifierSet.add(astraClSdkDev.Pool.getAddress(pool.token0, pool.token1, pool.fee));
        } else if (pool instanceof astraClassicSdk.Pair) {
          var pair = pool;
          poolIdentifierSet.add(astraClassicSdk.Pair.getAddress(pair.token0, pair.token1));
        } else {
          throw new Error('Unexpected pool type in route when constructing trade object');
        }
      }
    }
    !(numPools === poolIdentifierSet.size) ?  invariant(false, 'POOLS_DUPLICATED')  : void 0;
    !(tradeType === astraSdkCore.TradeType.EXACT_INPUT) ?  invariant(false, 'TRADE_TYPE')  : void 0;
    this.swaps = routes;
    this.tradeType = tradeType;
  }
  /**
   * @deprecated Deprecated in favor of 'swaps' property. If the trade consists of multiple routes
   * this will return an error.
   *
   * When the trade consists of just a single route, this returns the route of the trade,
   * i.e. which pools the trade goes through.
   */
  /**
   * Constructs a trade by simulating swaps through the given route
   * @template TInput The input token, either Amber or an ERC-20.
   * @template TOutput The output token, either Amber or an ERC-20.
   * @template TTradeType The type of the trade, either exact in or exact out.
   * @param route route to swap through
   * @param amount the amount specified, either input or output, depending on tradeType
   * @param tradeType whether the trade is an exact input or exact output swap
   * @returns The route
   */
  MixedRouteTrade.fromRoute =
  /*#__PURE__*/
  function () {
    var _fromRoute = /*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee(route, amount, tradeType) {
      var amounts, inputAmount, outputAmount, i, pool, _yield$pool$getOutput, _outputAmount;
      return _regeneratorRuntime().wrap(function _callee$(_context) {
        while (1) switch (_context.prev = _context.next) {
          case 0:
            amounts = new Array(route.path.length);
            !(tradeType === astraSdkCore.TradeType.EXACT_INPUT) ?  invariant(false, 'TRADE_TYPE')  : void 0;
            !amount.currency.equals(route.input) ?  invariant(false, 'INPUT')  : void 0;
            amounts[0] = amountWithPathCurrency(amount, route.pools[0]);
            i = 0;
          case 5:
            if (!(i < route.path.length - 1)) {
              _context.next = 15;
              break;
            }
            pool = route.pools[i];
            _context.next = 9;
            return pool.getOutputAmount(amountWithPathCurrency(amounts[i], pool));
          case 9:
            _yield$pool$getOutput = _context.sent;
            _outputAmount = _yield$pool$getOutput[0];
            amounts[i + 1] = _outputAmount;
          case 12:
            i++;
            _context.next = 5;
            break;
          case 15:
            inputAmount = astraSdkCore.CurrencyAmount.fromFractionalAmount(route.input, amount.numerator, amount.denominator);
            outputAmount = astraSdkCore.CurrencyAmount.fromFractionalAmount(route.output, amounts[amounts.length - 1].numerator, amounts[amounts.length - 1].denominator);
            return _context.abrupt("return", new MixedRouteTrade({
              routes: [{
                inputAmount: inputAmount,
                outputAmount: outputAmount,
                route: route
              }],
              tradeType: tradeType
            }));
          case 18:
          case "end":
            return _context.stop();
        }
      }, _callee);
    }));
    function fromRoute(_x, _x2, _x3) {
      return _fromRoute.apply(this, arguments);
    }
    return fromRoute;
  }()
  /**
   * Constructs a trade from routes by simulating swaps
   *
   * @template TInput The input token, either Amber or an ERC-20.
   * @template TOutput The output token, either Amber or an ERC-20.
   * @template TTradeType The type of the trade, either exact in or exact out.
   * @param routes the routes to swap through and how much of the amount should be routed through each
   * @param tradeType whether the trade is an exact input or exact output swap
   * @returns The trade
   */
  ;
  MixedRouteTrade.fromRoutes =
  /*#__PURE__*/
  function () {
    var _fromRoutes = /*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee2(routes, tradeType) {
      var populatedRoutes, _iterator3, _step3, _step3$value, route, amount, amounts, inputAmount, outputAmount, i, pool, _yield$pool$getOutput2, _outputAmount2;
      return _regeneratorRuntime().wrap(function _callee2$(_context2) {
        while (1) switch (_context2.prev = _context2.next) {
          case 0:
            populatedRoutes = [];
            !(tradeType === astraSdkCore.TradeType.EXACT_INPUT) ?  invariant(false, 'TRADE_TYPE')  : void 0;
            _iterator3 = _createForOfIteratorHelperLoose(routes);
          case 3:
            if ((_step3 = _iterator3()).done) {
              _context2.next = 26;
              break;
            }
            _step3$value = _step3.value, route = _step3$value.route, amount = _step3$value.amount;
            amounts = new Array(route.path.length);
            inputAmount = void 0;
            outputAmount = void 0;
            !amount.currency.equals(route.input) ?  invariant(false, 'INPUT')  : void 0;
            inputAmount = astraSdkCore.CurrencyAmount.fromFractionalAmount(route.input, amount.numerator, amount.denominator);
            amounts[0] = astraSdkCore.CurrencyAmount.fromFractionalAmount(route.pathInput, amount.numerator, amount.denominator);
            i = 0;
          case 12:
            if (!(i < route.path.length - 1)) {
              _context2.next = 22;
              break;
            }
            pool = route.pools[i];
            _context2.next = 16;
            return pool.getOutputAmount(amountWithPathCurrency(amounts[i], pool));
          case 16:
            _yield$pool$getOutput2 = _context2.sent;
            _outputAmount2 = _yield$pool$getOutput2[0];
            amounts[i + 1] = _outputAmount2;
          case 19:
            i++;
            _context2.next = 12;
            break;
          case 22:
            outputAmount = astraSdkCore.CurrencyAmount.fromFractionalAmount(route.output, amounts[amounts.length - 1].numerator, amounts[amounts.length - 1].denominator);
            populatedRoutes.push({
              route: route,
              inputAmount: inputAmount,
              outputAmount: outputAmount
            });
          case 24:
            _context2.next = 3;
            break;
          case 26:
            return _context2.abrupt("return", new MixedRouteTrade({
              routes: populatedRoutes,
              tradeType: tradeType
            }));
          case 27:
          case "end":
            return _context2.stop();
        }
      }, _callee2);
    }));
    function fromRoutes(_x4, _x5) {
      return _fromRoutes.apply(this, arguments);
    }
    return fromRoutes;
  }()
  /**
   * Creates a trade without computing the result of swapping through the route. Useful when you have simulated the trade
   * elsewhere and do not have any tick data
   * @template TInput The input token, either Amber or an ERC-20
   * @template TOutput The output token, either Amber or an ERC-20
   * @template TTradeType The type of the trade, either exact in or exact out
   * @param constructorArguments The arguments passed to the trade constructor
   * @returns The unchecked trade
   */
  ;
  MixedRouteTrade.createUncheckedTrade = function createUncheckedTrade(constructorArguments) {
    return new MixedRouteTrade(_extends({}, constructorArguments, {
      routes: [{
        inputAmount: constructorArguments.inputAmount,
        outputAmount: constructorArguments.outputAmount,
        route: constructorArguments.route
      }]
    }));
  }
  /**
   * Creates a trade without computing the result of swapping through the routes. Useful when you have simulated the trade
   * elsewhere and do not have any tick data
   * @template TInput The input token, either Amber or an ERC-20
   * @template TOutput The output token, either Amber or an ERC-20
   * @template TTradeType The type of the trade, either exact in or exact out
   * @param constructorArguments The arguments passed to the trade constructor
   * @returns The unchecked trade
   */;
  MixedRouteTrade.createUncheckedTradeWithMultipleRoutes = function createUncheckedTradeWithMultipleRoutes(constructorArguments) {
    return new MixedRouteTrade(constructorArguments);
  }
  /**
   * Get the minimum amount that must be received from this trade for the given slippage tolerance
   * @param slippageTolerance The tolerance of unfavorable slippage from the execution price of this trade
   * @param amountOut
   * @returns The amount out
   */;
  var _proto = MixedRouteTrade.prototype;
  _proto.minimumAmountOut = function minimumAmountOut(slippageTolerance, amountOut) {
    if (amountOut === void 0) {
      amountOut = this.outputAmount;
    }
    !!slippageTolerance.lessThan(ZERO) ?  invariant(false, 'SLIPPAGE_TOLERANCE')  : void 0;
    /// does not support exactOutput, as enforced in the constructor
    var slippageAdjustedAmountOut = new astraSdkCore.Fraction(ONE).add(slippageTolerance).invert().multiply(amountOut.quotient).quotient;
    return astraSdkCore.CurrencyAmount.fromRawAmount(amountOut.currency, slippageAdjustedAmountOut);
  }
  /**
   * Get the maximum amount in that can be spent via this trade for the given slippage tolerance
   * @param slippageTolerance The tolerance of unfavorable slippage from the execution price of this trade
   * @param amountIn
   * @returns The amount in
   */;
  _proto.maximumAmountIn = function maximumAmountIn(slippageTolerance, amountIn) {
    if (amountIn === void 0) {
      amountIn = this.inputAmount;
    }
    !!slippageTolerance.lessThan(ZERO) ?  invariant(false, 'SLIPPAGE_TOLERANCE')  : void 0;
    return amountIn;
    /// does not support exactOutput
  }
  /**
   * Return the execution price after accounting for slippage tolerance
   * @param slippageTolerance the allowed tolerated slippage
   * @returns The execution price
   */;
  _proto.worstExecutionPrice = function worstExecutionPrice(slippageTolerance) {
    return new astraSdkCore.Price(this.inputAmount.currency, this.outputAmount.currency, this.maximumAmountIn(slippageTolerance).quotient, this.minimumAmountOut(slippageTolerance).quotient);
  }
  /**
   * Given a list of pools, and a fixed amount in, returns the top `maxNumResults` trades that go from an input token
   * amount to an output token, making at most `maxHops` hops.
   * Note this does not consider aggregation, as routes are linear. It's possible a better route exists by splitting
   * the amount in among multiple routes.
   * @param pools the pools to consider in finding the best trade
   * @param nextAmountIn exact amount of input currency to spend
   * @param currencyOut the desired currency out
   * @param maxNumResults maximum number of results to return
   * @param maxHops maximum number of hops a returned trade can make, e.g. 1 hop goes through a single pool
   * @param currentPools used in recursion; the current list of pools
   * @param currencyAmountIn used in recursion; the original value of the currencyAmountIn parameter
   * @param bestTrades used in recursion; the current list of best trades
   * @returns The exact in trade
   */;
  MixedRouteTrade.bestTradeExactIn =
  /*#__PURE__*/
  function () {
    var _bestTradeExactIn = /*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee3(pools, currencyAmountIn, currencyOut, _temp,
    // used in recursion.
    currentPools, nextAmountIn, bestTrades) {
      var _ref5, _ref5$maxNumResults, maxNumResults, _ref5$maxHops, maxHops, i, pool, amountInAdjusted, amountOut, _yield$pool$getOutput3, poolsExcludingThisPool;
      return _regeneratorRuntime().wrap(function _callee3$(_context3) {
        while (1) switch (_context3.prev = _context3.next) {
          case 0:
            _ref5 = _temp === void 0 ? {} : _temp, _ref5$maxNumResults = _ref5.maxNumResults, maxNumResults = _ref5$maxNumResults === void 0 ? 3 : _ref5$maxNumResults, _ref5$maxHops = _ref5.maxHops, maxHops = _ref5$maxHops === void 0 ? 3 : _ref5$maxHops;
            if (currentPools === void 0) {
              currentPools = [];
            }
            if (nextAmountIn === void 0) {
              nextAmountIn = currencyAmountIn;
            }
            if (bestTrades === void 0) {
              bestTrades = [];
            }
            !(pools.length > 0) ?  invariant(false, 'POOLS')  : void 0;
            !(maxHops > 0) ?  invariant(false, 'MAX_HOPS')  : void 0;
            !(currencyAmountIn === nextAmountIn || currentPools.length > 0) ?  invariant(false, 'INVALID_RECURSION')  : void 0;
            i = 0;
          case 8:
            if (!(i < pools.length)) {
              _context3.next = 48;
              break;
            }
            pool = pools[i];
            amountInAdjusted = nextAmountIn.wrapped; // pool irrelevant
            if (!(!pool.token0.equals(amountInAdjusted.currency) && !pool.token1.equals(amountInAdjusted.currency))) {
              _context3.next = 13;
              break;
            }
            return _context3.abrupt("continue", 45);
          case 13:
            if (!(pool instanceof astraClassicSdk.Pair)) {
              _context3.next = 16;
              break;
            }
            if (!(pool.reserve0.equalTo(ZERO) || pool.reserve1.equalTo(ZERO))) {
              _context3.next = 16;
              break;
            }
            return _context3.abrupt("continue", 45);
          case 16:
            amountOut = void 0;
            _context3.prev = 17;
            _context3.next = 21;
            return pool.getOutputAmount(amountInAdjusted.wrapped);
          case 21:
            _yield$pool$getOutput3 = _context3.sent;
            amountOut = _yield$pool$getOutput3[0];
            _context3.next = 30;
            break;
          case 25:
            _context3.prev = 25;
            _context3.t0 = _context3["catch"](17);
            if (!_context3.t0.isInsufficientInputAmountError) {
              _context3.next = 29;
              break;
            }
            return _context3.abrupt("continue", 45);
          case 29:
            throw _context3.t0;
          case 30:
            if (!amountOut.currency.wrapped.equals(currencyOut.wrapped)) {
              _context3.next = 41;
              break;
            }
            _context3.t1 = astraSdkCore.sortedInsert;
            _context3.t2 = bestTrades;
            _context3.next = 35;
            return MixedRouteTrade.fromRoute(new MixedRouteSDK([].concat(currentPools, [pool]), currencyAmountIn.currency, currencyOut), currencyAmountIn, astraSdkCore.TradeType.EXACT_INPUT);
          case 35:
            _context3.t3 = _context3.sent;
            _context3.t4 = maxNumResults;
            _context3.t5 = tradeComparator;
            (0, _context3.t1)(_context3.t2, _context3.t3, _context3.t4, _context3.t5);
            _context3.next = 45;
            break;
          case 41:
            if (!(maxHops > 1 && pools.length > 1)) {
              _context3.next = 45;
              break;
            }
            poolsExcludingThisPool = pools.slice(0, i).concat(pools.slice(i + 1, pools.length)); // otherwise, consider all the other paths that lead from this token as long as we have not exceeded maxHops
            _context3.next = 45;
            return MixedRouteTrade.bestTradeExactIn(poolsExcludingThisPool, currencyAmountIn, currencyOut, {
              maxNumResults: maxNumResults,
              maxHops: maxHops - 1
            }, [].concat(currentPools, [pool]), amountOut, bestTrades);
          case 45:
            i++;
            _context3.next = 8;
            break;
          case 48:
            return _context3.abrupt("return", bestTrades);
          case 49:
          case "end":
            return _context3.stop();
        }
      }, _callee3, null, [[17, 25]]);
    }));
    function bestTradeExactIn(_x6, _x7, _x8, _x9, _x10, _x11, _x12) {
      return _bestTradeExactIn.apply(this, arguments);
    }
    return bestTradeExactIn;
  }();
  return _createClass(MixedRouteTrade, [{
    key: "route",
    get: function get() {
      !(this.swaps.length === 1) ?  invariant(false, 'MULTIPLE_ROUTES')  : void 0;
      return this.swaps[0].route;
    }
    /**
     * The input amount for the trade assuming no slippage.
     */
  }, {
    key: "inputAmount",
    get: function get() {
      if (this._inputAmount) {
        return this._inputAmount;
      }
      var inputCurrency = this.swaps[0].inputAmount.currency;
      var totalInputFromRoutes = this.swaps.map(function (_ref6) {
        var inputAmount = _ref6.inputAmount;
        return inputAmount;
      }).reduce(function (total, cur) {
        return total.add(cur);
      }, astraSdkCore.CurrencyAmount.fromRawAmount(inputCurrency, 0));
      this._inputAmount = totalInputFromRoutes;
      return this._inputAmount;
    }
    /**
     * The output amount for the trade assuming no slippage.
     */
  }, {
    key: "outputAmount",
    get: function get() {
      if (this._outputAmount) {
        return this._outputAmount;
      }
      var outputCurrency = this.swaps[0].outputAmount.currency;
      this._outputAmount = this.swaps.map(function (_ref7) {
        var outputAmount = _ref7.outputAmount;
        return outputAmount;
      }).reduce(function (total, cur) {
        return total.add(cur);
      }, astraSdkCore.CurrencyAmount.fromRawAmount(outputCurrency, 0));
      return this._outputAmount;
    }
    /**
     * The price expressed in terms of output amount/input amount.
     */
  }, {
    key: "executionPrice",
    get: function get() {
      var _this$_executionPrice;
      return (_this$_executionPrice = this._executionPrice) != null ? _this$_executionPrice : this._executionPrice = new astraSdkCore.Price(this.inputAmount.currency, this.outputAmount.currency, this.inputAmount.quotient, this.outputAmount.quotient);
    }
    /**
     * Returns the percent difference between the route's mid price and the price impact
     */
  }, {
    key: "priceImpact",
    get: function get() {
      if (this._priceImpact) {
        return this._priceImpact;
      }
      var spotOutputAmount = astraSdkCore.CurrencyAmount.fromRawAmount(this.outputAmount.currency, 0);
      for (var _iterator4 = _createForOfIteratorHelperLoose(this.swaps), _step4; !(_step4 = _iterator4()).done;) {
        var _step4$value = _step4.value,
          route = _step4$value.route,
          inputAmount = _step4$value.inputAmount;
        var midPrice = route.midPrice;
        spotOutputAmount = spotOutputAmount.add(midPrice.quote(inputAmount));
      }
      var priceImpact = spotOutputAmount.subtract(this.outputAmount).divide(spotOutputAmount);
      this._priceImpact = new astraSdkCore.Percent(priceImpact.numerator, priceImpact.denominator);
      return this._priceImpact;
    }
  }]);
}();

(function (Protocol) {
  Protocol["Classic"] = "Classic";
  Protocol["CL"] = "CL";
  Protocol["MIXED"] = "MIXED";
})(exports.Protocol || (exports.Protocol = {}));

// Classic route wrapper
var RouteClassic = /*#__PURE__*/function (_ClassicRouteSDK) {
  function RouteClassic(classicRoute) {
    var _this;
    _this = _ClassicRouteSDK.call(this, classicRoute.pairs, classicRoute.input, classicRoute.output) || this;
    _this.protocol = exports.Protocol.Classic;
    _this.pools = _this.pairs;
    return _this;
  }
  _inheritsLoose(RouteClassic, _ClassicRouteSDK);
  return RouteClassic;
}(astraClassicSdk.Route);
// CL route wrapper
var RouteCL = /*#__PURE__*/function (_CLRouteSDK) {
  function RouteCL(clRoute) {
    var _this2;
    _this2 = _CLRouteSDK.call(this, clRoute.pools, clRoute.input, clRoute.output) || this;
    _this2.protocol = exports.Protocol.CL;
    _this2.path = clRoute.tokenPath;
    return _this2;
  }
  _inheritsLoose(RouteCL, _CLRouteSDK);
  return RouteCL;
}(astraClSdkDev.Route);
// Mixed route wrapper
var MixedRoute = /*#__PURE__*/function (_MixedRouteSDK) {
  function MixedRoute(mixedRoute) {
    var _this3;
    _this3 = _MixedRouteSDK.call(this, mixedRoute.pools, mixedRoute.input, mixedRoute.output) || this;
    _this3.protocol = exports.Protocol.MIXED;
    return _this3;
  }
  _inheritsLoose(MixedRoute, _MixedRouteSDK);
  return MixedRoute;
}(MixedRouteSDK);

var Trade = /*#__PURE__*/function () {
  //  construct a trade across classic and cl routes from pre-computed amounts
  function Trade(_ref) {
    var _ref$classicRoutes = _ref.classicRoutes,
      classicRoutes = _ref$classicRoutes === void 0 ? [] : _ref$classicRoutes,
      _ref$clRoutes = _ref.clRoutes,
      clRoutes = _ref$clRoutes === void 0 ? [] : _ref$clRoutes,
      _ref$mixedRoutes = _ref.mixedRoutes,
      mixedRoutes = _ref$mixedRoutes === void 0 ? [] : _ref$mixedRoutes,
      tradeType = _ref.tradeType;
    this.swaps = [];
    this.routes = [];
    // wrap classic routes
    for (var _iterator = _createForOfIteratorHelperLoose(classicRoutes), _step; !(_step = _iterator()).done;) {
      var _step$value = _step.value,
        routeclassic = _step$value.routeclassic,
        inputAmount = _step$value.inputAmount,
        outputAmount = _step$value.outputAmount;
      var route = new RouteClassic(routeclassic);
      this.routes.push(route);
      this.swaps.push({
        route: route,
        inputAmount: inputAmount,
        outputAmount: outputAmount
      });
    }
    // wrap cl routes
    for (var _iterator2 = _createForOfIteratorHelperLoose(clRoutes), _step2; !(_step2 = _iterator2()).done;) {
      var _step2$value = _step2.value,
        routecl = _step2$value.routecl,
        _inputAmount = _step2$value.inputAmount,
        _outputAmount = _step2$value.outputAmount;
      var _route = new RouteCL(routecl);
      this.routes.push(_route);
      this.swaps.push({
        route: _route,
        inputAmount: _inputAmount,
        outputAmount: _outputAmount
      });
    }
    for (var _iterator3 = _createForOfIteratorHelperLoose(mixedRoutes), _step3; !(_step3 = _iterator3()).done;) {
      var _step3$value = _step3.value,
        mixedRoute = _step3$value.mixedRoute,
        _inputAmount2 = _step3$value.inputAmount,
        _outputAmount2 = _step3$value.outputAmount;
      var _route2 = new MixedRoute(mixedRoute);
      this.routes.push(_route2);
      this.swaps.push({
        route: _route2,
        inputAmount: _inputAmount2,
        outputAmount: _outputAmount2
      });
    }
    if (this.swaps.length === 0) {
      throw new Error('No routes provided when calling Trade constructor');
    }
    this.tradeType = tradeType;
    // each route must have the same input and output currency
    var inputCurrency = this.swaps[0].inputAmount.currency;
    var outputCurrency = this.swaps[0].outputAmount.currency;
    !this.swaps.every(function (_ref2) {
      var route = _ref2.route;
      return inputCurrency.wrapped.equals(route.input.wrapped);
    }) ?  invariant(false, 'INPUT_CURRENCY_MATCH')  : void 0;
    !this.swaps.every(function (_ref3) {
      var route = _ref3.route;
      return outputCurrency.wrapped.equals(route.output.wrapped);
    }) ?  invariant(false, 'OUTPUT_CURRENCY_MATCH')  : void 0;
    // pools must be unique inter protocols
    var numPools = this.swaps.map(function (_ref4) {
      var route = _ref4.route;
      return route.pools.length;
    }).reduce(function (total, cur) {
      return total + cur;
    }, 0);
    var poolIdentifierSet = new Set();
    for (var _iterator4 = _createForOfIteratorHelperLoose(this.swaps), _step4; !(_step4 = _iterator4()).done;) {
      var _route3 = _step4.value.route;
      for (var _iterator5 = _createForOfIteratorHelperLoose(_route3.pools), _step5; !(_step5 = _iterator5()).done;) {
        var pool = _step5.value;
        if (pool instanceof astraClSdkDev.Pool) {
          poolIdentifierSet.add(astraClSdkDev.Pool.getAddress(pool.token0, pool.token1, pool.fee));
        } else if (pool instanceof astraClassicSdk.Pair) {
          var pair = pool;
          poolIdentifierSet.add(astraClassicSdk.Pair.getAddress(pair.token0, pair.token1));
        } else {
          throw new Error('Unexpected pool type in route when constructing trade object');
        }
      }
    }
    !(numPools === poolIdentifierSet.size) ?  invariant(false, 'POOLS_DUPLICATED')  : void 0;
  }
  var _proto = Trade.prototype;
  /**
   * Get the minimum amount that must be received from this trade for the given slippage tolerance
   * @param slippageTolerance The tolerance of unfavorable slippage from the execution price of this trade
   * @param amountOut
   * @returns The amount out
   */
  _proto.minimumAmountOut = function minimumAmountOut(slippageTolerance, amountOut) {
    if (amountOut === void 0) {
      amountOut = this.outputAmount;
    }
    !!slippageTolerance.lessThan(ZERO) ?  invariant(false, 'SLIPPAGE_TOLERANCE')  : void 0;
    if (this.tradeType === astraSdkCore.TradeType.EXACT_OUTPUT) {
      return amountOut;
    } else {
      var slippageAdjustedAmountOut = new astraSdkCore.Fraction(ONE).add(slippageTolerance).invert().multiply(amountOut.quotient).quotient;
      return astraSdkCore.CurrencyAmount.fromRawAmount(amountOut.currency, slippageAdjustedAmountOut);
    }
  }
  /**
   * Get the maximum amount in that can be spent via this trade for the given slippage tolerance
   * @param slippageTolerance The tolerance of unfavorable slippage from the execution price of this trade
   * @param amountIn
   * @returns The amount in
   */;
  _proto.maximumAmountIn = function maximumAmountIn(slippageTolerance, amountIn) {
    if (amountIn === void 0) {
      amountIn = this.inputAmount;
    }
    !!slippageTolerance.lessThan(ZERO) ?  invariant(false, 'SLIPPAGE_TOLERANCE')  : void 0;
    if (this.tradeType === astraSdkCore.TradeType.EXACT_INPUT) {
      return amountIn;
    } else {
      var slippageAdjustedAmountIn = new astraSdkCore.Fraction(ONE).add(slippageTolerance).multiply(amountIn.quotient).quotient;
      return astraSdkCore.CurrencyAmount.fromRawAmount(amountIn.currency, slippageAdjustedAmountIn);
    }
  }
  /**
   * Return the execution price after accounting for slippage tolerance
   * @param slippageTolerance the allowed tolerated slippage
   * @returns The execution price
   */;
  _proto.worstExecutionPrice = function worstExecutionPrice(slippageTolerance) {
    return new astraSdkCore.Price(this.inputAmount.currency, this.outputAmount.currency, this.maximumAmountIn(slippageTolerance).quotient, this.minimumAmountOut(slippageTolerance).quotient);
  };
  Trade.fromRoutes = /*#__PURE__*/function () {
    var _fromRoutes = /*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee(classicRoutes, clRoutes, tradeType, mixedRoutes) {
      var populatedClassicRoutes, populatedCLRoutes, populatedMixedRoutes, _iterator6, _step6, _step6$value, routeclassic, _amount, classicTrade, _inputAmount3, _outputAmount3, _iterator7, _step7, _step7$value, routecl, _amount2, clTrade, _inputAmount4, _outputAmount4, _iterator8, _step8, _step8$value, mixedRoute, amount, mixedRouteTrade, inputAmount, outputAmount;
      return _regeneratorRuntime().wrap(function _callee$(_context) {
        while (1) switch (_context.prev = _context.next) {
          case 0:
            populatedClassicRoutes = [];
            populatedCLRoutes = [];
            populatedMixedRoutes = [];
            for (_iterator6 = _createForOfIteratorHelperLoose(classicRoutes); !(_step6 = _iterator6()).done;) {
              _step6$value = _step6.value, routeclassic = _step6$value.routeclassic, _amount = _step6$value.amount;
              classicTrade = new astraClassicSdk.Trade(routeclassic, _amount, tradeType);
              _inputAmount3 = classicTrade.inputAmount, _outputAmount3 = classicTrade.outputAmount;
              populatedClassicRoutes.push({
                routeclassic: routeclassic,
                inputAmount: _inputAmount3,
                outputAmount: _outputAmount3
              });
            }
            _iterator7 = _createForOfIteratorHelperLoose(clRoutes);
          case 5:
            if ((_step7 = _iterator7()).done) {
              _context.next = 14;
              break;
            }
            _step7$value = _step7.value, routecl = _step7$value.routecl, _amount2 = _step7$value.amount;
            _context.next = 9;
            return astraClSdkDev.Trade.fromRoute(routecl, _amount2, tradeType);
          case 9:
            clTrade = _context.sent;
            _inputAmount4 = clTrade.inputAmount, _outputAmount4 = clTrade.outputAmount;
            populatedCLRoutes.push({
              routecl: routecl,
              inputAmount: _inputAmount4,
              outputAmount: _outputAmount4
            });
          case 12:
            _context.next = 5;
            break;
          case 14:
            if (!mixedRoutes) {
              _context.next = 25;
              break;
            }
            _iterator8 = _createForOfIteratorHelperLoose(mixedRoutes);
          case 16:
            if ((_step8 = _iterator8()).done) {
              _context.next = 25;
              break;
            }
            _step8$value = _step8.value, mixedRoute = _step8$value.mixedRoute, amount = _step8$value.amount;
            _context.next = 20;
            return MixedRouteTrade.fromRoute(mixedRoute, amount, tradeType);
          case 20:
            mixedRouteTrade = _context.sent;
            inputAmount = mixedRouteTrade.inputAmount, outputAmount = mixedRouteTrade.outputAmount;
            populatedMixedRoutes.push({
              mixedRoute: mixedRoute,
              inputAmount: inputAmount,
              outputAmount: outputAmount
            });
          case 23:
            _context.next = 16;
            break;
          case 25:
            return _context.abrupt("return", new Trade({
              classicRoutes: populatedClassicRoutes,
              clRoutes: populatedCLRoutes,
              mixedRoutes: populatedMixedRoutes,
              tradeType: tradeType
            }));
          case 26:
          case "end":
            return _context.stop();
        }
      }, _callee);
    }));
    function fromRoutes(_x, _x2, _x3, _x4) {
      return _fromRoutes.apply(this, arguments);
    }
    return fromRoutes;
  }();
  Trade.fromRoute = /*#__PURE__*/function () {
    var _fromRoute = /*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee2(route, amount, tradeType) {
      var classicRoutes, clRoutes, mixedRoutes, classicTrade, inputAmount, outputAmount, clTrade, _inputAmount5, _outputAmount5, mixedRouteTrade, _inputAmount6, _outputAmount6;
      return _regeneratorRuntime().wrap(function _callee2$(_context2) {
        while (1) switch (_context2.prev = _context2.next) {
          case 0:
            classicRoutes = [];
            clRoutes = [];
            mixedRoutes = [];
            if (!(route instanceof astraClassicSdk.Route)) {
              _context2.next = 9;
              break;
            }
            classicTrade = new astraClassicSdk.Trade(route, amount, tradeType);
            inputAmount = classicTrade.inputAmount, outputAmount = classicTrade.outputAmount;
            classicRoutes = [{
              routeclassic: route,
              inputAmount: inputAmount,
              outputAmount: outputAmount
            }];
            _context2.next = 26;
            break;
          case 9:
            if (!(route instanceof astraClSdkDev.Route)) {
              _context2.next = 17;
              break;
            }
            _context2.next = 12;
            return astraClSdkDev.Trade.fromRoute(route, amount, tradeType);
          case 12:
            clTrade = _context2.sent;
            _inputAmount5 = clTrade.inputAmount, _outputAmount5 = clTrade.outputAmount;
            clRoutes = [{
              routecl: route,
              inputAmount: _inputAmount5,
              outputAmount: _outputAmount5
            }];
            _context2.next = 26;
            break;
          case 17:
            if (!(route instanceof MixedRouteSDK)) {
              _context2.next = 25;
              break;
            }
            _context2.next = 20;
            return MixedRouteTrade.fromRoute(route, amount, tradeType);
          case 20:
            mixedRouteTrade = _context2.sent;
            _inputAmount6 = mixedRouteTrade.inputAmount, _outputAmount6 = mixedRouteTrade.outputAmount;
            mixedRoutes = [{
              mixedRoute: route,
              inputAmount: _inputAmount6,
              outputAmount: _outputAmount6
            }];
            _context2.next = 26;
            break;
          case 25:
            throw new Error('Invalid route type');
          case 26:
            return _context2.abrupt("return", new Trade({
              classicRoutes: classicRoutes,
              clRoutes: clRoutes,
              mixedRoutes: mixedRoutes,
              tradeType: tradeType
            }));
          case 27:
          case "end":
            return _context2.stop();
        }
      }, _callee2);
    }));
    function fromRoute(_x5, _x6, _x7) {
      return _fromRoute.apply(this, arguments);
    }
    return fromRoute;
  }();
  return _createClass(Trade, [{
    key: "inputAmount",
    get: function get() {
      if (this._inputAmount) {
        return this._inputAmount;
      }
      var inputCurrency = this.swaps[0].inputAmount.currency;
      this._inputAmount = this.swaps.map(function (_ref5) {
        var inputAmount = _ref5.inputAmount;
        return inputAmount;
      }).reduce(function (total, cur) {
        return total.add(cur);
      }, astraSdkCore.CurrencyAmount.fromRawAmount(inputCurrency, 0));
      return this._inputAmount;
    }
  }, {
    key: "outputAmount",
    get: function get() {
      if (this._outputAmount) {
        return this._outputAmount;
      }
      var outputCurrency = this.swaps[0].outputAmount.currency;
      this._outputAmount = this.swaps.map(function (_ref6) {
        var outputAmount = _ref6.outputAmount;
        return outputAmount;
      }).reduce(function (total, cur) {
        return total.add(cur);
      }, astraSdkCore.CurrencyAmount.fromRawAmount(outputCurrency, 0));
      return this._outputAmount;
    }
    /**
     * The price expressed in terms of output amount/input amount.
     */
  }, {
    key: "executionPrice",
    get: function get() {
      var _this$_executionPrice;
      return (_this$_executionPrice = this._executionPrice) != null ? _this$_executionPrice : this._executionPrice = new astraSdkCore.Price(this.inputAmount.currency, this.outputAmount.currency, this.inputAmount.quotient, this.outputAmount.quotient);
    }
    /**
     * Returns the sell tax of the input token
     */
  }, {
    key: "inputTax",
    get: function get() {
      var inputCurrency = this.inputAmount.currency;
      if (inputCurrency.isNative || !inputCurrency.wrapped.sellFeeBps) return ZERO_PERCENT;
      return new astraSdkCore.Percent(inputCurrency.wrapped.sellFeeBps.toNumber(), 10000);
    }
    /**
     * Returns the buy tax of the output token
     */
  }, {
    key: "outputTax",
    get: function get() {
      var outputCurrency = this.outputAmount.currency;
      if (outputCurrency.isNative || !outputCurrency.wrapped.buyFeeBps) return ZERO_PERCENT;
      return new astraSdkCore.Percent(outputCurrency.wrapped.buyFeeBps.toNumber(), 10000);
    }
    /**
     * Returns the percent difference between the route's mid price and the expected execution price
     * In order to exclude token taxes from the price impact calculation, the spot price is calculated
     * using a ratio of values that go into the pools, which are the post-tax input amount and pre-tax output amount.
     */
  }, {
    key: "priceImpact",
    get: function get() {
      if (this._priceImpact) {
        return this._priceImpact;
      }
      // returns 0% price impact even though this may be inaccurate as a swap may have occured.
      // because we're unable to derive the pre-buy-tax amount, use 0% as a placeholder.
      if (this.outputTax.equalTo(ONE_HUNDRED_PERCENT)) return ZERO_PERCENT;
      var spotOutputAmount = astraSdkCore.CurrencyAmount.fromRawAmount(this.outputAmount.currency, 0);
      for (var _iterator9 = _createForOfIteratorHelperLoose(this.swaps), _step9; !(_step9 = _iterator9()).done;) {
        var _step9$value = _step9.value,
          route = _step9$value.route,
          inputAmount = _step9$value.inputAmount;
        var midPrice = route.midPrice;
        var postTaxInputAmount = inputAmount.multiply(new astraSdkCore.Fraction(ONE).subtract(this.inputTax));
        spotOutputAmount = spotOutputAmount.add(midPrice.quote(postTaxInputAmount));
      }
      // if the total output of this trade is 0, then most likely the post-tax input was also 0, and therefore this swap
      // does not move the pools' market price
      if (spotOutputAmount.equalTo(ZERO)) return ZERO_PERCENT;
      var preTaxOutputAmount = this.outputAmount.divide(new astraSdkCore.Fraction(ONE).subtract(this.outputTax));
      var priceImpact = spotOutputAmount.subtract(preTaxOutputAmount).divide(spotOutputAmount);
      this._priceImpact = new astraSdkCore.Percent(priceImpact.numerator, priceImpact.denominator);
      return this._priceImpact;
    }
  }]);
}();

/**
 * Converts a route to a hex encoded path
 * @notice only supports exactIn route encodings
 * @param route the mixed path to convert to an encoded path
 * @returns the exactIn encoded path
 */
function encodeMixedRouteToPath(route) {
  var path;
  var types;
  var result = route.pools.reduce(function (_ref, pool, index) {
    var inputToken = _ref.inputToken,
      path = _ref.path,
      types = _ref.types;
    var outputToken = pool.token0.equals(inputToken) ? pool.token1 : pool.token0;
    if (index === 0) {
      return {
        inputToken: outputToken,
        types: ['address', 'uint24', 'address'],
        path: [inputToken.wrapped.address, pool instanceof astraClSdkDev.Pool ? pool.fee : MIXED_QUOTER_V1_CLASSIC_FEE_PATH_PLACEHOLDER, outputToken.wrapped.address]
      };
    } else {
      return {
        inputToken: outputToken,
        types: [].concat(types, ['uint24', 'address']),
        path: [].concat(path, [pool instanceof astraClSdkDev.Pool ? pool.fee : MIXED_QUOTER_V1_CLASSIC_FEE_PATH_PLACEHOLDER, outputToken.wrapped.address])
      };
    }
  }, {
    inputToken: route.input,
    path: [],
    types: []
  });
  path = result.path;
  types = result.types;
  return solidity.pack(types, path);
}

/**
 * Utility function to return each consecutive section of Pools or Pairs in a MixedRoute
 * @param route
 * @returns a nested array of Pools or Pairs in the order of the route
 */
var partitionMixedRouteByProtocol = function partitionMixedRouteByProtocol(route) {
  var acc = [];
  var left = 0;
  var right = 0;
  while (right < route.pools.length) {
    if (route.pools[left] instanceof astraClSdkDev.Pool && !(route.pools[right] instanceof astraClSdkDev.Pool) || route.pools[left] instanceof astraClassicSdk.Pair && !(route.pools[right] instanceof astraClassicSdk.Pair)) {
      acc.push(route.pools.slice(left, right));
      left = right;
    }
    // seek forward with right pointer
    right++;
    if (right === route.pools.length) {
      /// we reached the end, take the rest
      acc.push(route.pools.slice(left, right));
    }
  }
  return acc;
};
/**
 * Simple utility function to get the output of an array of Pools or Pairs
 * @param pools
 * @param firstInputToken
 * @returns the output token of the last pool in the array
 */
var getOutputOfPools = function getOutputOfPools(pools, firstInputToken) {
  var _pools$reduce = pools.reduce(function (_ref, pool) {
      var inputToken = _ref.inputToken;
      if (!pool.involvesToken(inputToken)) throw new Error('PATH');
      var outputToken = pool.token0.equals(inputToken) ? pool.token1 : pool.token0;
      return {
        inputToken: outputToken
      };
    }, {
      inputToken: firstInputToken
    }),
    outputToken = _pools$reduce.inputToken;
  return outputToken;
};

var ZERO$1 = /*#__PURE__*/JSBI.BigInt(0);
var REFUND_AMB_PRICE_IMPACT_THRESHOLD = /*#__PURE__*/new astraSdkCore.Percent(/*#__PURE__*/JSBI.BigInt(50), /*#__PURE__*/JSBI.BigInt(100));
/**
 * Represents the Astra Classic + CL SwapRouter02, and has static methods for helping execute trades.
 */
var SwapRouter = /*#__PURE__*/function () {
  /**
   * Cannot be constructed.
   */
  function SwapRouter() {}
  /**
   * @notice Generates the calldata for a Swap with a Classic Route.
   * @param trade The ClassicTrade to encode.
   * @param options SwapOptions to use for the trade.
   * @param routerMustCustody Flag for whether funds should be sent to the router
   * @param performAggregatedSlippageCheck Flag for whether we want to perform an aggregated slippage check
   * @returns A string array of calldatas for the trade.
   */
  SwapRouter.encodeClassicSwap = function encodeClassicSwap(trade, options, routerMustCustody, performAggregatedSlippageCheck) {
    var amountIn = astraClSdkDev.toHex(trade.maximumAmountIn(options.slippageTolerance).quotient);
    var amountOut = astraClSdkDev.toHex(trade.minimumAmountOut(options.slippageTolerance).quotient);
    var path = trade.route.path.map(function (token) {
      return token.address;
    });
    var recipient = routerMustCustody ? ADDRESS_THIS : typeof options.recipient === 'undefined' ? MSG_SENDER : astraSdkCore.validateAndParseAddress(options.recipient);
    if (trade.tradeType === astraSdkCore.TradeType.EXACT_INPUT) {
      var exactInputParams = [amountIn, performAggregatedSlippageCheck ? 0 : amountOut, path, recipient];
      return SwapRouter.INTERFACE.encodeFunctionData('swapExactTokensForTokens', exactInputParams);
    } else {
      var exactOutputParams = [amountOut, amountIn, path, recipient];
      return SwapRouter.INTERFACE.encodeFunctionData('swapTokensForExactTokens', exactOutputParams);
    }
  }
  /**
   * @notice Generates the calldata for a Swap with a CL Route.
   * @param trade The CLTrade to encode.
   * @param options SwapOptions to use for the trade.
   * @param routerMustCustody Flag for whether funds should be sent to the router
   * @param performAggregatedSlippageCheck Flag for whether we want to perform an aggregated slippage check
   * @returns A string array of calldatas for the trade.
   */;
  SwapRouter.encodeCLSwap = function encodeCLSwap(trade, options, routerMustCustody, performAggregatedSlippageCheck) {
    var calldatas = [];
    for (var _iterator = _createForOfIteratorHelperLoose(trade.swaps), _step; !(_step = _iterator()).done;) {
      var _step$value = _step.value,
        route = _step$value.route,
        inputAmount = _step$value.inputAmount,
        outputAmount = _step$value.outputAmount;
      var amountIn = astraClSdkDev.toHex(trade.maximumAmountIn(options.slippageTolerance, inputAmount).quotient);
      var amountOut = astraClSdkDev.toHex(trade.minimumAmountOut(options.slippageTolerance, outputAmount).quotient);
      // flag for whether the trade is single hop or not
      var singleHop = route.pools.length === 1;
      var recipient = routerMustCustody ? ADDRESS_THIS : typeof options.recipient === 'undefined' ? MSG_SENDER : astraSdkCore.validateAndParseAddress(options.recipient);
      if (singleHop) {
        if (trade.tradeType === astraSdkCore.TradeType.EXACT_INPUT) {
          var exactInputSingleParams = {
            tokenIn: route.tokenPath[0].address,
            tokenOut: route.tokenPath[1].address,
            fee: route.pools[0].fee,
            recipient: recipient,
            amountIn: amountIn,
            amountOutMinimum: performAggregatedSlippageCheck ? 0 : amountOut,
            sqrtPriceLimitX96: 0
          };
          calldatas.push(SwapRouter.INTERFACE.encodeFunctionData('exactInputSingle', [exactInputSingleParams]));
        } else {
          var exactOutputSingleParams = {
            tokenIn: route.tokenPath[0].address,
            tokenOut: route.tokenPath[1].address,
            fee: route.pools[0].fee,
            recipient: recipient,
            amountOut: amountOut,
            amountInMaximum: amountIn,
            sqrtPriceLimitX96: 0
          };
          calldatas.push(SwapRouter.INTERFACE.encodeFunctionData('exactOutputSingle', [exactOutputSingleParams]));
        }
      } else {
        var path = astraClSdkDev.encodeRouteToPath(route, trade.tradeType === astraSdkCore.TradeType.EXACT_OUTPUT);
        if (trade.tradeType === astraSdkCore.TradeType.EXACT_INPUT) {
          var exactInputParams = {
            path: path,
            recipient: recipient,
            amountIn: amountIn,
            amountOutMinimum: performAggregatedSlippageCheck ? 0 : amountOut
          };
          calldatas.push(SwapRouter.INTERFACE.encodeFunctionData('exactInput', [exactInputParams]));
        } else {
          var exactOutputParams = {
            path: path,
            recipient: recipient,
            amountOut: amountOut,
            amountInMaximum: amountIn
          };
          calldatas.push(SwapRouter.INTERFACE.encodeFunctionData('exactOutput', [exactOutputParams]));
        }
      }
    }
    return calldatas;
  }
  /**
   * @notice Generates the calldata for a MixedRouteSwap. Since single hop routes are not MixedRoutes, we will instead generate
   *         them via the existing encodeCLSwap and encodeClassicSwap methods.
   * @param trade The MixedRouteTrade to encode.
   * @param options SwapOptions to use for the trade.
   * @param routerMustCustody Flag for whether funds should be sent to the router
   * @param performAggregatedSlippageCheck Flag for whether we want to perform an aggregated slippage check
   * @returns A string array of calldatas for the trade.
   */;
  SwapRouter.encodeMixedRouteSwap = function encodeMixedRouteSwap(trade, options, routerMustCustody, performAggregatedSlippageCheck) {
    var calldatas = [];
    !(trade.tradeType === astraSdkCore.TradeType.EXACT_INPUT) ?  invariant(false, 'TRADE_TYPE')  : void 0;
    var _loop = function _loop() {
      var _step2$value = _step2.value,
        route = _step2$value.route,
        inputAmount = _step2$value.inputAmount,
        outputAmount = _step2$value.outputAmount;
      var amountIn = astraClSdkDev.toHex(trade.maximumAmountIn(options.slippageTolerance, inputAmount).quotient);
      var amountOut = astraClSdkDev.toHex(trade.minimumAmountOut(options.slippageTolerance, outputAmount).quotient);
      // flag for whether the trade is single hop or not
      var singleHop = route.pools.length === 1;
      var recipient = routerMustCustody ? ADDRESS_THIS : typeof options.recipient === 'undefined' ? MSG_SENDER : astraSdkCore.validateAndParseAddress(options.recipient);
      var mixedRouteIsAllCL = function mixedRouteIsAllCL(route) {
        return route.pools.every(function (pool) {
          return pool instanceof astraClSdkDev.Pool;
        });
      };
      if (singleHop) {
        /// For single hop, since it isn't really a mixedRoute, we'll just mimic behavior of CL or Classic
        /// We don't use encodeCLSwap() or encodeClassicSwap() because casting the trade to a CLTrade or ClassicTrade is overcomplex
        if (mixedRouteIsAllCL(route)) {
          var exactInputSingleParams = {
            tokenIn: route.path[0].wrapped.address,
            tokenOut: route.path[1].wrapped.address,
            fee: route.pools[0].fee,
            recipient: recipient,
            amountIn: amountIn,
            amountOutMinimum: performAggregatedSlippageCheck ? 0 : amountOut,
            sqrtPriceLimitX96: 0
          };
          calldatas.push(SwapRouter.INTERFACE.encodeFunctionData('exactInputSingle', [exactInputSingleParams]));
        } else {
          var path = route.path.map(function (token) {
            return token.wrapped.address;
          });
          var exactInputParams = [amountIn, performAggregatedSlippageCheck ? 0 : amountOut, path, recipient];
          calldatas.push(SwapRouter.INTERFACE.encodeFunctionData('swapExactTokensForTokens', exactInputParams));
        }
      } else {
        var sections = partitionMixedRouteByProtocol(route);
        var isLastSectionInRoute = function isLastSectionInRoute(i) {
          return i === sections.length - 1;
        };
        var outputToken;
        var inputToken = route.input.wrapped;
        for (var i = 0; i < sections.length; i++) {
          var section = sections[i];
          /// Now, we get output of this section
          outputToken = getOutputOfPools(section, inputToken);
          var newRouteOriginal = new MixedRouteSDK([].concat(section), section[0].token0.equals(inputToken) ? section[0].token0 : section[0].token1, outputToken);
          var newRoute = new MixedRoute(newRouteOriginal);
          /// Previous output is now input
          inputToken = outputToken.wrapped;
          if (mixedRouteIsAllCL(newRoute)) {
            var _path = encodeMixedRouteToPath(newRoute);
            var _exactInputParams = {
              path: _path,
              // By default router holds funds until the last swap, then it is sent to the recipient
              // special case exists where we are unwrapping SAMB output, in which case `routerMustCustody` is set to true
              // and router still holds the funds. That logic bundled into how the value of `recipient` is calculated
              recipient: isLastSectionInRoute(i) ? recipient : ADDRESS_THIS,
              amountIn: i === 0 ? amountIn : 0,
              amountOutMinimum: !isLastSectionInRoute(i) ? 0 : amountOut
            };
            calldatas.push(SwapRouter.INTERFACE.encodeFunctionData('exactInput', [_exactInputParams]));
          } else {
            var _exactInputParams2 = [i === 0 ? amountIn : 0, !isLastSectionInRoute(i) ? 0 : amountOut, newRoute.path.map(function (token) {
              return token.wrapped.address;
            }), isLastSectionInRoute(i) ? recipient : ADDRESS_THIS];
            calldatas.push(SwapRouter.INTERFACE.encodeFunctionData('swapExactTokensForTokens', _exactInputParams2));
          }
        }
      }
    };
    for (var _iterator2 = _createForOfIteratorHelperLoose(trade.swaps), _step2; !(_step2 = _iterator2()).done;) {
      _loop();
    }
    return calldatas;
  };
  SwapRouter.encodeSwaps = function encodeSwaps(trades, options, isSwapAndAdd) {
    // If dealing with an instance of the aggregated Trade object, unbundle it to individual trade objects.
    if (trades instanceof Trade) {
      !trades.swaps.every(function (swap) {
        return swap.route.protocol === exports.Protocol.CL || swap.route.protocol === exports.Protocol.Classic || swap.route.protocol === exports.Protocol.MIXED;
      }) ?  invariant(false, 'UNSUPPORTED_PROTOCOL (encoding routes with v4 not supported)')  : void 0;
      var individualTrades = [];
      for (var _iterator3 = _createForOfIteratorHelperLoose(trades.swaps), _step3; !(_step3 = _iterator3()).done;) {
        var _step3$value = _step3.value,
          route = _step3$value.route,
          inputAmount = _step3$value.inputAmount,
          outputAmount = _step3$value.outputAmount;
        if (route.protocol === exports.Protocol.Classic) {
          individualTrades.push(new astraClassicSdk.Trade(route, trades.tradeType === astraSdkCore.TradeType.EXACT_INPUT ? inputAmount : outputAmount, trades.tradeType));
        } else if (route.protocol === exports.Protocol.CL) {
          individualTrades.push(astraClSdkDev.Trade.createUncheckedTrade({
            route: route,
            inputAmount: inputAmount,
            outputAmount: outputAmount,
            tradeType: trades.tradeType
          }));
        } else if (route.protocol === exports.Protocol.MIXED) {
          individualTrades.push(
          /// we can change the naming of this function on MixedRouteTrade if needed
          MixedRouteTrade.createUncheckedTrade({
            route: route,
            inputAmount: inputAmount,
            outputAmount: outputAmount,
            tradeType: trades.tradeType
          }));
        } else {
          throw new Error('UNSUPPORTED_TRADE_PROTOCOL');
        }
      }
      trades = individualTrades;
    }
    if (!Array.isArray(trades)) {
      trades = [trades];
    }
    var numberOfTrades = trades.reduce(function (numberOfTrades, trade) {
      return numberOfTrades + (trade instanceof astraClSdkDev.Trade || trade instanceof MixedRouteTrade ? trade.swaps.length : 1);
    }, 0);
    var sampleTrade = trades[0];
    // All trades should have the same starting/ending currency and trade type
    !trades.every(function (trade) {
      return trade.inputAmount.currency.equals(sampleTrade.inputAmount.currency);
    }) ?  invariant(false, 'TOKEN_IN_DIFF')  : void 0;
    !trades.every(function (trade) {
      return trade.outputAmount.currency.equals(sampleTrade.outputAmount.currency);
    }) ?  invariant(false, 'TOKEN_OUT_DIFF')  : void 0;
    !trades.every(function (trade) {
      return trade.tradeType === sampleTrade.tradeType;
    }) ?  invariant(false, 'TRADE_TYPE_DIFF')  : void 0;
    var calldatas = [];
    var inputIsNative = sampleTrade.inputAmount.currency.isNative;
    var outputIsNative = sampleTrade.outputAmount.currency.isNative;
    // flag for whether we want to perform an aggregated slippage check
    //   1. when there are >2 exact input trades. this is only a heuristic,
    //      as it's still more gas-expensive even in this case, but has benefits
    //      in that the reversion probability is lower
    var performAggregatedSlippageCheck = sampleTrade.tradeType === astraSdkCore.TradeType.EXACT_INPUT && numberOfTrades > 2;
    // flag for whether funds should be send first to the router
    //   1. when receiving AMB (which much be unwrapped from SAMB)
    //   2. when a fee on the output is being taken
    //   3. when performing swap and add
    //   4. when performing an aggregated slippage check
    var routerMustCustody = outputIsNative || !!options.fee || !!isSwapAndAdd || performAggregatedSlippageCheck;
    // encode permit if necessary
    if (options.inputTokenPermit) {
      !sampleTrade.inputAmount.currency.isToken ?  invariant(false, 'NON_TOKEN_PERMIT')  : void 0;
      calldatas.push(astraClSdkDev.SelfPermit.encodePermit(sampleTrade.inputAmount.currency, options.inputTokenPermit));
    }
    for (var _iterator4 = _createForOfIteratorHelperLoose(trades), _step4; !(_step4 = _iterator4()).done;) {
      var trade = _step4.value;
      if (trade instanceof astraClassicSdk.Trade) {
        calldatas.push(SwapRouter.encodeClassicSwap(trade, options, routerMustCustody, performAggregatedSlippageCheck));
      } else if (trade instanceof astraClSdkDev.Trade) {
        for (var _iterator5 = _createForOfIteratorHelperLoose(SwapRouter.encodeCLSwap(trade, options, routerMustCustody, performAggregatedSlippageCheck)), _step5; !(_step5 = _iterator5()).done;) {
          var calldata = _step5.value;
          calldatas.push(calldata);
        }
      } else if (trade instanceof MixedRouteTrade) {
        for (var _iterator6 = _createForOfIteratorHelperLoose(SwapRouter.encodeMixedRouteSwap(trade, options, routerMustCustody, performAggregatedSlippageCheck)), _step6; !(_step6 = _iterator6()).done;) {
          var _calldata = _step6.value;
          calldatas.push(_calldata);
        }
      } else {
        throw new Error('Unsupported trade object');
      }
    }
    var ZERO_IN = astraSdkCore.CurrencyAmount.fromRawAmount(sampleTrade.inputAmount.currency, 0);
    var ZERO_OUT = astraSdkCore.CurrencyAmount.fromRawAmount(sampleTrade.outputAmount.currency, 0);
    var minimumAmountOut = trades.reduce(function (sum, trade) {
      return sum.add(trade.minimumAmountOut(options.slippageTolerance));
    }, ZERO_OUT);
    var quoteAmountOut = trades.reduce(function (sum, trade) {
      return sum.add(trade.outputAmount);
    }, ZERO_OUT);
    var totalAmountIn = trades.reduce(function (sum, trade) {
      return sum.add(trade.maximumAmountIn(options.slippageTolerance));
    }, ZERO_IN);
    return {
      calldatas: calldatas,
      sampleTrade: sampleTrade,
      routerMustCustody: routerMustCustody,
      inputIsNative: inputIsNative,
      outputIsNative: outputIsNative,
      totalAmountIn: totalAmountIn,
      minimumAmountOut: minimumAmountOut,
      quoteAmountOut: quoteAmountOut
    };
  }
  /**
   * Produces the on-chain method name to call and the hex encoded parameters to pass as arguments for a given trade.
   * @param trades to produce call parameters for
   * @param options options for the call parameters
   */;
  SwapRouter.swapCallParameters = function swapCallParameters(trades, options) {
    var _SwapRouter$encodeSwa = SwapRouter.encodeSwaps(trades, options),
      calldatas = _SwapRouter$encodeSwa.calldatas,
      sampleTrade = _SwapRouter$encodeSwa.sampleTrade,
      routerMustCustody = _SwapRouter$encodeSwa.routerMustCustody,
      inputIsNative = _SwapRouter$encodeSwa.inputIsNative,
      outputIsNative = _SwapRouter$encodeSwa.outputIsNative,
      totalAmountIn = _SwapRouter$encodeSwa.totalAmountIn,
      minimumAmountOut = _SwapRouter$encodeSwa.minimumAmountOut;
    // unwrap or sweep
    if (routerMustCustody) {
      if (outputIsNative) {
        calldatas.push(PaymentsExtended.encodeUnwrapSAMB(minimumAmountOut.quotient, options.recipient, options.fee));
      } else {
        calldatas.push(PaymentsExtended.encodeSweepToken(sampleTrade.outputAmount.currency.wrapped, minimumAmountOut.quotient, options.recipient, options.fee));
      }
    }
    // must refund when paying in AMB: either with an uncertain input amount OR if there's a chance of a partial fill.
    // unlike ERC20's, the full AMB value must be sent in the transaction, so the rest must be refunded.
    if (inputIsNative && (sampleTrade.tradeType === astraSdkCore.TradeType.EXACT_OUTPUT || SwapRouter.riskOfPartialFill(trades))) {
      calldatas.push(astraClSdkDev.Payments.encodeRefundAMB());
    }
    return {
      calldata: MulticallExtended.encodeMulticall(calldatas, options.deadlineOrPreviousBlockhash),
      value: astraClSdkDev.toHex(inputIsNative ? totalAmountIn.quotient : ZERO$1)
    };
  }
  /**
   * Produces the on-chain method name to call and the hex encoded parameters to pass as arguments for a given trade.
   * @param trades to produce call parameters for
   * @param options options for the call parameters
   */;
  SwapRouter.swapAndAddCallParameters = function swapAndAddCallParameters(trades, options, position, addLiquidityOptions, tokenInApprovalType, tokenOutApprovalType) {
    var _SwapRouter$encodeSwa2 = SwapRouter.encodeSwaps(trades, options, true),
      calldatas = _SwapRouter$encodeSwa2.calldatas,
      inputIsNative = _SwapRouter$encodeSwa2.inputIsNative,
      outputIsNative = _SwapRouter$encodeSwa2.outputIsNative,
      sampleTrade = _SwapRouter$encodeSwa2.sampleTrade,
      totalAmountSwapped = _SwapRouter$encodeSwa2.totalAmountIn,
      quoteAmountOut = _SwapRouter$encodeSwa2.quoteAmountOut,
      minimumAmountOut = _SwapRouter$encodeSwa2.minimumAmountOut;
    // encode output token permit if necessary
    if (options.outputTokenPermit) {
      !quoteAmountOut.currency.isToken ?  invariant(false, 'NON_TOKEN_PERMIT_OUTPUT')  : void 0;
      calldatas.push(astraClSdkDev.SelfPermit.encodePermit(quoteAmountOut.currency, options.outputTokenPermit));
    }
    var chainId = sampleTrade.route.chainId;
    var zeroForOne = position.pool.token0.wrapped.address === totalAmountSwapped.currency.wrapped.address;
    var _SwapRouter$getPositi = SwapRouter.getPositionAmounts(position, zeroForOne),
      positionAmountIn = _SwapRouter$getPositi.positionAmountIn,
      positionAmountOut = _SwapRouter$getPositi.positionAmountOut;
    // if tokens are native they will be converted to SAMB
    var tokenIn = inputIsNative ? astraSdkCore.SAMB[chainId] : positionAmountIn.currency.wrapped;
    var tokenOut = outputIsNative ? astraSdkCore.SAMB[chainId] : positionAmountOut.currency.wrapped;
    // if swap output does not make up whole outputTokenBalanceDesired, pull in remaining tokens for adding liquidity
    var amountOutRemaining = positionAmountOut.subtract(quoteAmountOut.wrapped);
    if (amountOutRemaining.greaterThan(astraSdkCore.CurrencyAmount.fromRawAmount(positionAmountOut.currency, 0))) {
      // if output is native, this means the remaining portion is included as native value in the transaction
      // and must be wrapped. Otherwise, pull in remaining ERC20 token.
      outputIsNative ? calldatas.push(PaymentsExtended.encodeWrapAMB(amountOutRemaining.quotient)) : calldatas.push(PaymentsExtended.encodePull(tokenOut, amountOutRemaining.quotient));
    }
    // if input is native, convert to SAMB, else pull ERC20 token
    inputIsNative ? calldatas.push(PaymentsExtended.encodeWrapAMB(positionAmountIn.quotient)) : calldatas.push(PaymentsExtended.encodePull(tokenIn, positionAmountIn.quotient));
    // approve token balances to NFTManager
    if (tokenInApprovalType !== exports.ApprovalTypes.NOT_REQUIRED) calldatas.push(ApproveAndCall.encodeApprove(tokenIn, tokenInApprovalType));
    if (tokenOutApprovalType !== exports.ApprovalTypes.NOT_REQUIRED) calldatas.push(ApproveAndCall.encodeApprove(tokenOut, tokenOutApprovalType));
    // represents a position with token amounts resulting from a swap with maximum slippage
    // hence the minimal amount out possible.
    var minimalPosition = astraClSdkDev.Position.fromAmounts({
      pool: position.pool,
      tickLower: position.tickLower,
      tickUpper: position.tickUpper,
      amount0: zeroForOne ? position.amount0.quotient.toString() : minimumAmountOut.quotient.toString(),
      amount1: zeroForOne ? minimumAmountOut.quotient.toString() : position.amount1.quotient.toString(),
      useFullPrecision: false
    });
    // encode NFTManager add liquidity
    calldatas.push(ApproveAndCall.encodeAddLiquidity(position, minimalPosition, addLiquidityOptions, options.slippageTolerance));
    // sweep remaining tokens
    inputIsNative ? calldatas.push(PaymentsExtended.encodeUnwrapSAMB(ZERO$1)) : calldatas.push(PaymentsExtended.encodeSweepToken(tokenIn, ZERO$1));
    outputIsNative ? calldatas.push(PaymentsExtended.encodeUnwrapSAMB(ZERO$1)) : calldatas.push(PaymentsExtended.encodeSweepToken(tokenOut, ZERO$1));
    var value;
    if (inputIsNative) {
      value = totalAmountSwapped.wrapped.add(positionAmountIn.wrapped).quotient;
    } else if (outputIsNative) {
      value = amountOutRemaining.quotient;
    } else {
      value = ZERO$1;
    }
    return {
      calldata: MulticallExtended.encodeMulticall(calldatas, options.deadlineOrPreviousBlockhash),
      value: value.toString()
    };
  }
  // if price impact is very high, there's a chance of hitting max/min prices resulting in a partial fill of the swap
  ;
  SwapRouter.riskOfPartialFill = function riskOfPartialFill(trades) {
    if (Array.isArray(trades)) {
      return trades.some(function (trade) {
        return SwapRouter.clTradeWithHighPriceImpact(trade);
      });
    } else {
      return SwapRouter.clTradeWithHighPriceImpact(trades);
    }
  };
  SwapRouter.clTradeWithHighPriceImpact = function clTradeWithHighPriceImpact(trade) {
    return !(trade instanceof astraClassicSdk.Trade) && trade.priceImpact.greaterThan(REFUND_AMB_PRICE_IMPACT_THRESHOLD);
  };
  SwapRouter.getPositionAmounts = function getPositionAmounts(position, zeroForOne) {
    var _position$mintAmounts = position.mintAmounts,
      amount0 = _position$mintAmounts.amount0,
      amount1 = _position$mintAmounts.amount1;
    var currencyAmount0 = astraSdkCore.CurrencyAmount.fromRawAmount(position.pool.token0, amount0);
    var currencyAmount1 = astraSdkCore.CurrencyAmount.fromRawAmount(position.pool.token1, amount1);
    var _ref = zeroForOne ? [currencyAmount0, currencyAmount1] : [currencyAmount1, currencyAmount0],
      positionAmountIn = _ref[0],
      positionAmountOut = _ref[1];
    return {
      positionAmountIn: positionAmountIn,
      positionAmountOut: positionAmountOut
    };
  };
  return SwapRouter;
}();
SwapRouter.INTERFACE = /*#__PURE__*/new abi.Interface(ISwapRouter02_json.abi);

exports.ADDRESS_THIS = ADDRESS_THIS;
exports.ADDRESS_ZERO = ADDRESS_ZERO;
exports.ApproveAndCall = ApproveAndCall;
exports.MIXED_QUOTER_CLASSIC_CLASSIC_FEE_PATH_PLACEHOLDER = MIXED_QUOTER_CLASSIC_CLASSIC_FEE_PATH_PLACEHOLDER;
exports.MIXED_QUOTER_CLASSIC_CL_FEE_PATH_PLACEHOLDER = MIXED_QUOTER_CLASSIC_CL_FEE_PATH_PLACEHOLDER;
exports.MIXED_QUOTER_V1_CLASSIC_FEE_PATH_PLACEHOLDER = MIXED_QUOTER_V1_CLASSIC_FEE_PATH_PLACEHOLDER;
exports.MSG_SENDER = MSG_SENDER;
exports.MixedRoute = MixedRoute;
exports.MixedRouteSDK = MixedRouteSDK;
exports.MixedRouteTrade = MixedRouteTrade;
exports.MulticallExtended = MulticallExtended;
exports.ONE = ONE;
exports.ONE_HUNDRED_PERCENT = ONE_HUNDRED_PERCENT;
exports.PaymentsExtended = PaymentsExtended;
exports.RouteCL = RouteCL;
exports.RouteClassic = RouteClassic;
exports.SwapRouter = SwapRouter;
exports.Trade = Trade;
exports.ZERO = ZERO;
exports.ZERO_PERCENT = ZERO_PERCENT;
exports.amountWithPathCurrency = amountWithPathCurrency;
exports.encodeMixedRouteToPath = encodeMixedRouteToPath;
exports.getOutputOfPools = getOutputOfPools;
exports.getPathCurrency = getPathCurrency;
exports.isMint = isMint;
exports.partitionMixedRouteByProtocol = partitionMixedRouteByProtocol;
exports.tradeComparator = tradeComparator;
//# sourceMappingURL=astra-router-sdk.cjs.development.js.map