import { e as T, q as O, A as b, v as C, B as S, Y as G, M as B, aS as _, aT as m, a as I, N as w, W as p, u as g, y as M, t as N, ag as x, aU as v, aV as E, aW as U, ad as F, f as L, aX as Q, ae as $, _ as V, $ as W, ac as H, aY as X, P as j, R as Y, aZ as Z, a_ as J, U as K, a$ as q } from "./platform-Cil_UtAQ.mjs";
import { a as tt, b as et, C as nt, R as at, T as ot, c as it } from "./address-rVHWlcKQ.mjs";
async function D(l, t, e, a = 120 * 1e3, n = console.log) {
  const o = Date.now();
  n("Checking transfer state...");
  for await (t of l.track(t, 120 * 1e3))
    n("Current Transfer State: ", T[t.state]);
  if (O(t))
    return t;
  if (b(l) && C(t) && e) {
    n("Completing transfer...");
    const r = await l.complete(e, t);
    n("Completed transfer with txids: ", r);
  }
  if (S(l) && G(t) && e) {
    n("Finalizing transfer...");
    const r = await l.finalize(e, t);
    n("Finalized transfer with txids: ", r);
  }
  const i = a - (Date.now() - o);
  return i > 0 ? (n("Transfer not complete, trying again in a 2000ms..."), await new Promise((s) => setTimeout(s, 2e3)), D(l, t, e, i)) : t;
}
function st(l = {}) {
  class t extends A {
    static config = l;
  }
  return t;
}
class A extends B {
  static IS_EXECUTOR_ROUTE = !0;
  static NATIVE_GAS_DROPOFF_SUPPORTED = !0;
  // @ts-ignore
  // Since we set the config on the static class, access it with this param
  // the ExecutorTokenBridgeRoute.config will always be empty
  staticConfig = this.constructor.config;
  static config = {};
  static meta = {
    name: "TokenBridgeExecutorRoute"
  };
  static supportedNetworks() {
    return ["Mainnet", "Testnet"];
  }
  static supportedChains(t) {
    return t === "Devnet" ? [] : _(t);
  }
  static async supportedDestinationTokens(t, e, a) {
    try {
      return [await m.lookupDestinationToken(e, a, t)];
    } catch {
      return [];
    }
  }
  getDefaultOptions() {
    return { nativeGas: 0 };
  }
  async validate(t, e) {
    if (t.fromChain.chain === t.toChain.chain)
      return {
        valid: !1,
        params: e,
        error: new Error("Source and destination chains cannot be the same")
      };
    const a = I(e.amount, t.source.decimals), n = e.options ?? this.getDefaultOptions();
    if (n.nativeGas && (n.nativeGas > 1 || n.nativeGas < 0))
      throw new Error("Native gas must be between 0.0 and 1.0 (0% and 100%)");
    return { valid: !0, params: {
      amount: e.amount,
      normalizedParams: { amount: a },
      options: n
    } };
  }
  async quote(t, e) {
    const a = A.supportedChains(t.fromChain.network);
    if (!a.includes(t.fromChain.chain) || !a.includes(t.toChain.chain))
      return {
        success: !1,
        error: new Error(`Executor Token Bridge does not support transfers from ${t.fromChain.chain} to ${t.toChain.chain}`)
      };
    try {
      let n;
      const o = await t.toChain.getExecutorTokenBridge();
      let { gasLimit: i, msgValue: r } = await o.estimateMsgValueAndGasLimit(t.destination.id, t.recipient);
      if (this.staticConfig.referrerFee?.referrerFeeDbps !== void 0 && (n = this.staticConfig.referrerFee.referrerFeeDbps), this.staticConfig.referrerFee?.tokenFeeOverrides) {
        const f = w(t.source.id), h = this.staticConfig.referrerFee.tokenFeeOverrides[this.wh.network]?.[t.fromChain.chain]?.[f];
        h !== void 0 && (n = h);
      }
      if (this.staticConfig.tokenOverrides) {
        const f = w(t.destination.id), h = this.staticConfig.tokenOverrides[this.wh.network]?.[t.destination.id.chain]?.[f];
        h?.gasLimit !== void 0 && (i = h.gasLimit);
      }
      let s;
      if (n !== void 0 && n > 0n) {
        const f = this.staticConfig.referrerFee?.referrerAddresses?.[this.wh.network]?.[t.fromChain.chain];
        if (!f)
          throw new Error(`No referrer address configured for network ${this.wh.network} and chain ${t.fromChain.chain}`);
        s = p.chainAddress(t.fromChain.chain, f);
      }
      const c = n !== void 0 && s !== void 0 ? { feeDbps: n, referrer: s } : void 0;
      let d;
      if (e.options.nativeGas !== void 0) {
        const f = await m.getExecutorGasDropOffLimit(this.wh, t.toChain);
        d = f > 0n ? BigInt(Math.round(e.options.nativeGas * 100)) * f / 100n : 0n;
      }
      const u = await m.quoteTransfer(this.wh, t.fromChain, t.toChain, {
        token: t.source.id,
        amount: g(e.normalizedParams.amount),
        protocol: "ExecutorTokenBridge",
        nativeGas: d,
        msgValue: r,
        gasLimit: i,
        referrerFee: c
      });
      return t.displayQuote(u, e, u.details);
    } catch (n) {
      return {
        success: !1,
        error: n
      };
    }
  }
  async initiate(t, e, a, n) {
    const { fromChain: o, toChain: i } = t, { params: r } = a, s = await m.destinationOverrides(o, i, this.toTransferDetails(t, r, p.chainAddress(e.chain(), e.address()), n, a)), c = await m.transfer(o, s, e);
    let d = 0;
    return (async () => {
      for (; d < 20; ) {
        try {
          const [f] = await this.wh.getExecutorTxStatus(c.at(-1).txid, o.chain);
          if (f)
            break;
        } catch {
        }
        d++, await new Promise((f) => setTimeout(f, 2e3));
      }
    })(), {
      from: s.from.chain,
      to: s.to.chain,
      state: T.SourceInitiated,
      originTxs: c
    };
  }
  async complete(t, e) {
    if (!C(e) && !M(e))
      throw new Error("The source must be finalized in order to complete the transfer");
    if (!e.attestation)
      throw new Error("The receipt must have an attestation to complete the transfer");
    const a = this.wh.getChain(e.to), n = await a.getExecutorTokenBridge(), o = N(t.chain(), t.address()), i = n.redeem(o, e.attestation.attestation), r = await x(a, i, t);
    return {
      ...e,
      state: T.DestinationInitiated,
      attestation: e.attestation,
      destinationTxs: r
    };
  }
  async resume(t) {
    const e = await m.from(this.wh, t, 1e4);
    if (e.transfer.protocol !== "ExecutorTokenBridge")
      throw new Error("Can only resume ExecutorTokenBridge transfers");
    return m.getReceipt(e);
  }
  async *track(t, e) {
    for await (const a of m.track(this.wh, t, e))
      yield a;
  }
  toTransferDetails(t, e, a, n, o) {
    if (!o.details)
      throw new Error("Missing quote details");
    return {
      from: a,
      to: n,
      token: t.source.id,
      amount: g(e.normalizedParams.amount),
      protocol: "ExecutorTokenBridge",
      executorQuote: o.details.executorQuote,
      referrerFee: o.details.referrerFee
    };
  }
}
const y = 15n, R = 100n, k = 10000n;
class P extends B {
  static NATIVE_GAS_DROPOFF_SUPPORTED = !1;
  static meta = {
    name: "AutomaticPortico"
  };
  static supportedNetworks() {
    return ["Mainnet"];
  }
  static supportedChains(t) {
    return v.has(t) ? v.get(t) : [];
  }
  static async supportedDestinationTokens(t, e, a) {
    const [, n] = E(e.network, e.chain, t), o = w(n), i = await e.getPorticoBridge();
    if (!i.supportedTokens().some((u) => w(u.token) === o))
      return [];
    try {
      const u = await i.getTransferrableToken(o);
      await m.lookupDestinationToken(e, a, u);
    } catch {
      return [];
    }
    const s = (await a.getPorticoBridge()).supportedTokens(), { tokenMap: c } = a.config, d = i.getTokenGroup(o);
    return s.filter((u) => (u.group === d || // ETH/WETH supports wrapping/unwrapping
    u.group === "ETH" && d === "WETH" || u.group === "WETH" && d === "ETH") && (!c || U.byAddress(c, w(u.token)))).map((u) => u.token);
  }
  getDefaultOptions() {
    return {};
  }
  async validate(t, e) {
    try {
      if (t.fromChain.chain === t.toChain.chain)
        return {
          valid: !1,
          params: e,
          error: new Error("Source and destination chains cannot be the same")
        };
      if (!P.supportedChains(t.fromChain.network).includes(t.fromChain.chain) || !P.supportedChains(t.toChain.network).includes(t.toChain.chain))
        throw new Error("Protocol not supported");
      const { fromChain: a, toChain: n, source: o, destination: i } = t, { network: r } = a, [, s] = E(r, a.chain, o.id), [, c] = E(r, n.chain, i.id), d = await a.getPorticoBridge(), u = await n.getPorticoBridge(), f = await d.getTransferrableToken(w(s)), h = await u.getTransferrableToken(w(c));
      return { valid: !0, params: {
        amount: e.amount,
        options: e.options ?? this.getDefaultOptions(),
        normalizedParams: {
          amount: t.parseAmount(e.amount),
          canonicalSourceToken: f,
          canonicalDestinationToken: h,
          sourceToken: s,
          destinationToken: c
        }
      } };
    } catch (a) {
      return { valid: !1, error: a, params: e };
    }
  }
  async quote(t, e) {
    try {
      const a = await this.fetchSwapQuote(t, e), n = Math.max(t.source.decimals, t.destination.decimals), o = g(F(e.normalizedParams.amount, n));
      if (g(F(L(a.minAmountFinish, t.destination.decimals), n)) < o - o * R / k)
        throw new Error("Slippage too high");
      const s = await (await t.toChain.getPorticoBridge()).quoteRelay(e.normalizedParams.canonicalDestinationToken.address, e.normalizedParams.destinationToken.address), c = {
        swapAmounts: a,
        relayerFee: s
      }, d = c.swapAmounts.minAmountFinish - s;
      return d < 0n ? {
        success: !1,
        error: new Error(`Amount too low for slippage and fee, would result in negative destination amount (${d})`)
      } : await t.displayQuote({
        sourceToken: {
          token: e.normalizedParams.sourceToken,
          amount: g(e.normalizedParams.amount)
        },
        destinationToken: {
          token: e.normalizedParams.destinationToken,
          amount: c.swapAmounts.minAmountFinish - s
        },
        relayFee: {
          token: e.normalizedParams.destinationToken,
          amount: s
        },
        eta: $(t.fromChain.chain),
        expires: Q(0, 5, 0)
      }, e, c);
    } catch (a) {
      return {
        success: !1,
        error: a
      };
    }
  }
  async initiate(t, e, a, n) {
    const { params: o, details: i } = a, r = t.source.id.address, s = t.destination.id, c = await t.fromChain.getPorticoBridge(), d = c.getTokenGroup(r.toString()), f = (await t.toChain.getPorticoBridge()).getPorticoAddress(d), h = c.transfer(p.parseAddress(e.chain(), e.address()), n, r, g(o.normalizedParams.amount), s, f, i);
    return {
      originTxs: await x(t.fromChain, h, e),
      state: T.SourceInitiated,
      from: t.fromChain.chain,
      to: t.toChain.chain
    };
  }
  async *track(t, e) {
    if (V(t) || W(t)) {
      const { txid: a } = t.originTxs[t.originTxs.length - 1], n = await this.wh.getVaa(a, "PorticoBridge:Transfer", e);
      if (!n)
        throw new Error("No VAA found for transaction: " + a);
      const o = {
        chain: n.emitterChain,
        emitter: n.emitterAddress,
        sequence: n.sequence
      };
      t = {
        ...t,
        state: T.Attested,
        attestation: {
          id: o,
          attestation: n
        }
      }, yield t;
    }
    C(t) && await (await this.wh.getChain(t.to).getPorticoBridge()).isTransferCompleted(t.attestation.attestation) && (t = {
      ...t,
      state: T.DestinationFinalized
    }, yield t), yield t;
  }
  async complete(t, e) {
    if (!C(e))
      throw new Error("Source must be attested");
    const a = await this.wh.getChain(e.to), n = await a.getPorticoBridge(), o = p.chainAddress(t.chain(), t.address()), i = n.redeem(o.address, e.attestation.attestation);
    return await x(a, i, t);
  }
  async fetchSwapQuote(t, e) {
    const a = await t.fromChain.getPorticoBridge(), n = g(e.normalizedParams.amount), o = a.getTokenGroup(w(e.normalizedParams.sourceToken)), i = await a.quoteSwap(e.normalizedParams.sourceToken.address, e.normalizedParams.canonicalSourceToken.address, o, n), r = i * y / k;
    if (r >= i)
      throw new Error("Start slippage too high");
    const s = await t.toChain.getPorticoBridge(), c = i - r, d = await s.quoteSwap(e.normalizedParams.canonicalDestinationToken.address, e.normalizedParams.destinationToken.address, o, c), u = d * y / k;
    if (u >= d)
      throw new Error("Finish slippage too high");
    const f = d - u;
    return {
      minAmountStart: c,
      minAmountFinish: f
    };
  }
}
const ut = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
  __proto__: null,
  AutomaticCCTPRoute: tt,
  AutomaticPorticoRoute: P,
  AutomaticRoute: B,
  AutomaticTokenBridgeRoute: et,
  BPS_PER_HUNDRED_PERCENT: k,
  CCTPRoute: nt,
  ExecutorTokenBridgeRoute: A,
  FinalizableRoute: H,
  MAX_SLIPPAGE_BPS: R,
  ManualRoute: X,
  MinAmountError: j,
  RelayFailedError: Y,
  Route: Z,
  RouteResolver: J,
  RouteTransferRequest: at,
  SLIPPAGE_BPS: y,
  TBTCRoute: ot,
  TokenBridgeRoute: it,
  UnavailableError: K,
  checkAndCompleteTransfer: D,
  executorTokenBridgeRoute: st,
  isAutomatic: q,
  isFinalizable: S,
  isManual: b
}, Symbol.toStringTag, { value: "Module" }));
export {
  ut as r
};
