import { S as p, V as S, D as T, a as C, s as I, b as P, c as U, t as g, g as x, d as h, e as _, f as w, h as F, M as L, i as R, j as k, k as v, m as N, n as y, o as M, P as O, p as b, q as B } from "./utils-BSxsyW2c.mjs";
import { g as Q } from "./tokenHelpers-DT6mPtNP.mjs";
import { n as z } from "./index-hyk_rzOj.mjs";
import { M as G, N as u, u as V, f as E, e as A, q as H, Y as j, x as X, _ as K, $ as W, v as Y } from "./platform-Cil_UtAQ.mjs";
const $ = (n) => {
  if (!n.estimate.fromAmountUSD)
    throw new p(new S("Missing 'fromAmountUSD' in step estimate."));
  if (!n.estimate.toAmountUSD)
    throw new p(new S("Missing 'toAmountUSD' in step estimate."));
  return {
    id: n.id,
    fromChainId: n.action.fromToken.chainId,
    fromToken: n.action.fromToken,
    fromAmount: n.action.fromAmount,
    fromAmountUSD: n.estimate.fromAmountUSD,
    fromAddress: n.action.fromAddress,
    toChainId: n.action.toToken.chainId,
    toToken: n.action.toToken,
    toAmount: n.estimate.toAmount,
    toAmountMin: n.estimate.toAmountMin,
    toAmountUSD: n.estimate.toAmountUSD,
    toAddress: n.action.toAddress || n.action.fromAddress,
    gasCostUSD: n.estimate.gasCosts?.[0]?.amountUSD || "0",
    steps: [n],
    insurance: { state: "NOT_INSURABLE", feeAmountUsd: "0" }
  };
};
class J extends G {
  static meta = {
    name: "LiFi",
    provider: "LiFi"
  };
  static NATIVE_GAS_DROPOFF_SUPPORTED = !1;
  static IS_AUTOMATIC = !0;
  config;
  getDefaultOptions() {
    return {
      slippage: C,
      maxPriceImpact: T,
      allowDestinationCall: !1
    };
  }
  static supportedNetworks() {
    return ["Mainnet"];
  }
  static supportedChains(t) {
    return I(t);
  }
  static isProtocolSupported(t) {
    return I(t.network).includes(t.chain);
  }
  // LiFi can handle any input and output token that has liquidity on a DeX
  static async supportedDestinationTokens(t, e, i) {
    return Q(i.chain);
  }
  async validate(t, e) {
    if (t.fromChain.chain === t.toChain.chain)
      return {
        valid: !1,
        params: e,
        error: new Error("Same chain swaps are disabled")
      };
    const s = e.options?.slippage ?? C;
    if (s < 0 || s > 1)
      return {
        valid: !1,
        params: e,
        error: new Error("Invalid slippage value")
      };
    const o = e.options?.maxPriceImpact ?? T;
    if (o < 0 || o > 1)
      return {
        valid: !1,
        params: e,
        error: new Error("Invalid maxPriceImpact value")
      };
    const c = e.options?.bridges ?? P, d = e.options?.exchanges ?? U;
    return {
      valid: !0,
      params: {
        ...e,
        normalizedParams: {
          slippage: s,
          maxPriceImpact: o,
          bridges: c,
          exchanges: d
        }
      }
    };
  }
  fetchQuote(t, e) {
    const { fromChain: i, toChain: s } = t, { normalizedParams: a } = e, o = g(i.chain), l = g(s.chain), c = t.sender ? u(t.sender) : x(i.chain), d = t.recipient ? u(t.recipient) : x(s.chain), { integrator: f, feePercent: m } = this.getFeeConfig(t), r = {
      fromChain: o,
      toChain: l,
      fromToken: h(t.source.id),
      toToken: h(t.destination.id),
      fromAmount: V(t.parseAmount(e.amount)).toString(),
      fromAddress: c,
      toAddress: d,
      slippage: e.normalizedParams.slippage,
      maxPriceImpact: e.normalizedParams.maxPriceImpact,
      integrator: f,
      referrer: e.options.referrer,
      fee: m
    };
    return a.bridges?.allow && (r.allowBridges = a.bridges.allow), a.bridges?.deny && (r.denyBridges = a.bridges.deny), a.bridges?.prefer && (r.preferBridges = a.bridges.prefer), a.exchanges?.allow && (r.allowExchanges = a.exchanges.allow), a.exchanges?.deny && (r.denyExchanges = a.exchanges.deny), a.exchanges?.prefer && (r.preferExchanges = a.exchanges.prefer), _(r);
  }
  getFeeConfig(t) {
    return this.config?.getFeeConfig ? this.config.getFeeConfig(t) : { integrator: w, feePercent: 0 };
  }
  async quote(t, e) {
    try {
      const i = await this.fetchQuote(t, e);
      return {
        success: !0,
        params: e,
        sourceToken: {
          token: t.source.id,
          amount: E(
            BigInt(i.estimate?.fromAmount.toString()),
            t.source.decimals
          )
        },
        destinationToken: {
          token: t.destination.id,
          amount: E(
            BigInt(i.estimate?.toAmount.toString()),
            t.destination.decimals
          )
        },
        eta: (i.estimate?.executionDuration || F) * L,
        details: i,
        provider: i.toolDetails.name
      };
    } catch (i) {
      return {
        success: !1,
        error: i
      };
    }
  }
  async initiate(t, e, i, s) {
    const a = e.address(), o = u(s), l = await t.fromChain.getRpc(), c = [], d = {
      ...i.details,
      fromAddress: a,
      toAddress: o
    }, f = $(d), m = { request: t, signer: e, rpc: l, txs: c };
    if (t.fromChain.chain === "Solana")
      await R(f, m);
    else if (t.fromChain.chain === "Sui")
      await k(f, m);
    else {
      const D = await v(t.fromChain);
      await N(
        f,
        m,
        i,
        D,
        h
      );
    }
    const r = {
      from: t.fromChain.chain,
      to: t.toChain.chain,
      state: A.SourceInitiated,
      originTxs: c,
      // TODO: The LiFi API status method has a known issue where it sometimes can't track
      // transfers when no bridge param is specified.
      // Set it here on the receipt for the track() method below.
      // Can remove this when the LiFi API is fixed.
      tool: i.details.tool
    };
    return Object.assign(r, { tool: i.details?.tool });
  }
  async *track(t, e = y) {
    if (H(t) || j(t) || X(t))
      return t;
    let i = e;
    for (; i > 0; ) {
      const s = Date.now();
      if (K(t) || W(t) || Y(t)) {
        const a = await M(
          this.wh.network,
          t.originTxs[t.originTxs.length - 1],
          g(t.from).toString(),
          g(t.to).toString(),
          t.tool
        );
        if (!a)
          throw new Error("Failed to fetch transfer status");
        if (a.status === "DONE") {
          const o = {
            ...t,
            originTxs: [{ chain: t.from, txid: a.sending.txHash }],
            attestation: {},
            state: A.DestinationFinalized
          };
          return yield o, o;
        } else if (a.status === "FAILED") {
          const o = {
            ...t,
            originTxs: [{ chain: t.from, txid: a.sending.txHash }],
            refundTxs: [],
            state: A.Refunded,
            attestation: {}
          };
          return yield o, o;
        }
      }
      await z(O), i -= Date.now() - s;
    }
    return t;
  }
  transferUrl(t) {
    return `https://scan.li.fi/tx/${t}`;
  }
}
function it(n) {
  return b.set({
    // The integrator is required here so just set it to the default.
    // The actual integrator used will be set per-quote in fetchQuote().
    integrator: w,
    apiUrl: n.apiUrl ?? B
  }), class extends J {
    config = n;
  };
}
export {
  J as LiFiRoute,
  it as createLiFiRouteWithConfig
};
