var Ct = Object.defineProperty;
var At = (m, t, a) => t in m ? Ct(m, t, { enumerable: !0, configurable: !0, writable: !0, value: a }) : m[t] = a;
var l = (m, t, a) => At(m, typeof t != "symbol" ? t + "" : t, a);
import { G as Y, u as k, b8 as nt, T as g, O as yt, B as ct, Q as b, C as dt, ak as vt, ad as I, b9 as it, m as N, ba as f, F as h, af as Z, N as st, aQ as U, q as Pt, W as T, bb as q, o as P, V as bt, t as xt, aT as E, bc as Q, bd as ot, be as W, bf as Dt, bg as mt, aR as ut, al as lt, am as ht, bh as _, D as G, A as D, bi as C, bj as Bt, bk as Et, I as y, aS as St, bl as zt, aD as Ft, ab as Gt, aP as Ot, R as It, bm as Nt, bn as Rt, ae as Mt, bo as Ut, r as _t, U as rt, k as $ } from "./address-QpeLv2yn.mjs";
class tt {
  constructor(t, a, e, n, i) {
    l(this, "source");
    l(this, "destination");
    l(this, "fromChain");
    l(this, "toChain");
    l(this, "recipient");
    this.fromChain = t, this.toChain = a, this.source = e, this.destination = n, this.recipient = i;
  }
  parseAmount(t) {
    return Y(t, this.source.decimals);
  }
  amountFromBaseUnits(t) {
    return k(t, this.source.decimals);
  }
  async displayQuote(t, a, e) {
    let n = {
      success: !0,
      sourceToken: {
        token: t.sourceToken.token,
        amount: k(t.sourceToken.amount, this.source.decimals)
      },
      destinationToken: {
        token: t.destinationToken.token,
        amount: k(t.destinationToken.amount, this.destination.decimals)
      },
      params: a
    };
    if (t.relayFee) {
      const s = await (t.relayFee.token.chain === this.fromChain.chain ? this.fromChain : this.toChain).getDecimals(t.relayFee.token.address);
      n.relayFee = {
        token: t.relayFee.token,
        amount: k(t.relayFee.amount, s)
      };
    }
    if (t.destinationNativeGas) {
      const i = await this.toChain.getDecimals("native");
      n.destinationNativeGas = k(t.destinationNativeGas, i);
    }
    return t.warnings && t.warnings.length > 0 && (n.warnings = [...t.warnings]), n.eta = t.eta, n.expires = t.expires, e && (n.details = e), n;
  }
  static async create(t, a, e, n) {
    e = e ?? t.getChain(a.source.chain), n = n ?? t.getChain(a.destination.chain);
    const i = await nt(e, a.source, a.sourceDecimals), s = await nt(n, a.destination, a.destinationDecimals);
    return new tt(e, n, i, s, a.recipient);
  }
}
async function ft(m, t, a, e = 120 * 1e3, n = console.log) {
  const i = Date.now();
  n("Checking transfer state...");
  for await (t of m.track(t, 120 * 1e3))
    n("Current Transfer State: ", g[t.state]);
  if (yt(t))
    return t;
  if (ct(m) && b(t) && a) {
    n("Completing transfer...");
    const o = await m.complete(a, t);
    n("Completed transfer with txids: ", o);
  }
  if (dt(m) && vt(t) && a) {
    n("Finalizing transfer...");
    const o = await m.finalize(a, t);
    n("Finalized transfer with txids: ", o);
  }
  const s = e - (Date.now() - i);
  return s > 0 ? (n("Transfer not complete, trying again in a 2000ms..."), await new Promise((r) => setTimeout(r, 2e3)), ft(m, t, a, s)) : t;
}
class H extends I {
  static supportedNetworks() {
    return ["Mainnet", "Testnet"];
  }
  // get the list of chains this route supports
  static supportedChains(t) {
    return it.has(t) ? it.get(t) : [];
  }
  // get the list of destination tokens that may be received on the destination chain
  static async supportedDestinationTokens(t, a, e) {
    try {
      if (!N(t) && !await (await a.getAutomaticTokenBridge()).isRegisteredToken(t.address))
        return [];
      const n = await f.lookupDestinationToken(a, e, t);
      return await (await e.getAutomaticTokenBridge()).isRegisteredToken(n.address) ? [n] : [];
    } catch {
      return [];
    }
  }
  getDefaultOptions() {
    return { nativeGas: 0 };
  }
  async validate(t, a) {
    try {
      const e = a.options ?? this.getDefaultOptions();
      if (e.nativeGas && (e.nativeGas > 1 || e.nativeGas < 0))
        throw new Error("Native gas must be between 0.0 and 1.0 (0% and 100%)");
      const { destination: n } = t;
      N(n.id.address) && e.nativeGas === 0 && (e.nativeGas = 0);
      const i = { ...a, options: e };
      return { valid: !0, params: {
        ...i,
        normalizedParams: await this.normalizeTransferParams(t, i)
      } };
    } catch (e) {
      return { valid: !1, params: a, error: e };
    }
  }
  async normalizeTransferParams(t, a) {
    const e = t.parseAmount(a.amount), n = N(t.source.id.address) ? await t.fromChain.getNativeWrappedTokenId() : t.source.id, s = await (await t.fromChain.getAutomaticTokenBridge()).getRelayerFee(t.toChain.chain, n.address), o = s * 105n / 100n;
    if (h(e) < o)
      throw new Z(k(o, e.decimals));
    const r = h(e) - s;
    let c = k(0n, t.source.decimals);
    if (a.options && a.options.nativeGas > 0) {
      let u = await (await t.toChain.getAutomaticTokenBridge()).maxSwapAmount(t.destination.id.address);
      const p = st(k(r, e.decimals), f.MAX_DECIMALS), w = await t.toChain.getDecimals(t.destination.id.address), v = h(U(p, w));
      v < u && (u = v);
      const S = 1e4, V = BigInt(Math.floor(a.options.nativeGas * S)), O = u * V / BigInt(S), L = k(O, t.destination.decimals);
      c = U(st(L, f.MAX_DECIMALS), t.source.decimals), h(c) > r && (c = k(r, t.source.decimals));
    }
    return {
      fee: k(s, t.source.decimals),
      amount: e,
      nativeGasAmount: c
    };
  }
  async quote(t, a) {
    const e = await t.fromChain.getAutomaticTokenBridge();
    if (Pt(t.source.id) && !await e.isRegisteredToken(t.source.id.address))
      return {
        success: !1,
        error: new Error("Source token is not registered")
      };
    try {
      let n = await f.quoteTransfer(this.wh, t.fromChain, t.toChain, {
        protocol: "AutomaticTokenBridge",
        amount: h(a.normalizedParams.amount),
        token: t.source.id,
        nativeGas: h(a.normalizedParams.nativeGasAmount)
      });
      return t.displayQuote(n, a);
    } catch (n) {
      return {
        success: !1,
        error: n
      };
    }
  }
  async initiate(t, a, e, n) {
    const { params: i } = e, s = this.toTransferDetails(t, i, T.chainAddress(a.chain(), a.address()), n), o = await f.transfer(t.fromChain, s, a);
    return {
      from: s.from.chain,
      to: s.to.chain,
      state: g.SourceInitiated,
      originTxs: o
    };
  }
  async *track(t, a) {
    try {
      yield* f.track(this.wh, t, a);
    } catch (e) {
      throw e;
    }
  }
  toTransferDetails(t, a, e, n) {
    return {
      from: e,
      to: n,
      protocol: "AutomaticTokenBridge",
      amount: h(a.normalizedParams.amount),
      token: t.source.id,
      nativeGas: h(a.normalizedParams.nativeGasAmount)
    };
  }
}
l(H, "NATIVE_GAS_DROPOFF_SUPPORTED", !0), l(H, "meta", {
  name: "AutomaticTokenBridge"
});
function Qt(m = {}) {
  class t extends z {
  }
  return l(t, "config", m), t;
}
class z extends I {
  constructor() {
    super(...arguments);
    // @ts-ignore
    // Since we set the config on the static class, access it with this param
    // the ExecutorTokenBridgeRoute.config will always be empty
    l(this, "staticConfig", this.constructor.config);
  }
  static supportedNetworks() {
    return ["Mainnet", "Testnet"];
  }
  static supportedChains(a) {
    return q(a);
  }
  static async supportedDestinationTokens(a, e, n) {
    try {
      return [await f.lookupDestinationToken(e, n, a)];
    } catch {
      return [];
    }
  }
  getDefaultOptions() {
    return { nativeGas: 0 };
  }
  async validate(a, e) {
    const n = Y(e.amount, a.source.decimals), i = e.options ?? this.getDefaultOptions();
    if (i.nativeGas && (i.nativeGas > 1 || i.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: n },
      options: i
    } };
  }
  async quote(a, e) {
    var n, i, s, o, r, c, d, u, p;
    try {
      let w;
      const v = await a.toChain.getExecutorTokenBridge();
      let { gasLimit: S, msgValue: V } = await v.estimateMsgValueAndGasLimit(a.destination.id, a.recipient);
      if (((n = this.staticConfig.referrerFee) == null ? void 0 : n.referrerFeeDbps) !== void 0 && (w = this.staticConfig.referrerFee.referrerFeeDbps), (i = this.staticConfig.referrerFee) != null && i.tokenFeeOverrides) {
        const A = P(a.source.id), x = (o = (s = this.staticConfig.referrerFee.tokenFeeOverrides[this.wh.network]) == null ? void 0 : s[a.fromChain.chain]) == null ? void 0 : o[A];
        x !== void 0 && (w = x);
      }
      if (this.staticConfig.tokenOverrides) {
        const A = P(a.destination.id), x = (c = (r = this.staticConfig.tokenOverrides[this.wh.network]) == null ? void 0 : r[a.destination.id.chain]) == null ? void 0 : c[A];
        (x == null ? void 0 : x.gasLimit) !== void 0 && (S = x.gasLimit);
      }
      let O;
      if (w !== void 0 && w > 0n) {
        const A = (p = (u = (d = this.staticConfig.referrerFee) == null ? void 0 : d.referrerAddresses) == null ? void 0 : u[this.wh.network]) == null ? void 0 : p[a.fromChain.chain];
        if (!A)
          throw new Error(`No referrer address configured for network ${this.wh.network} and chain ${a.fromChain.chain}`);
        O = T.chainAddress(a.fromChain.chain, A);
      }
      const L = w !== void 0 && O !== void 0 ? { feeDbps: w, referrer: O } : void 0;
      let at;
      if (e.options.nativeGas !== void 0) {
        const A = await f.getExecutorGasDropOffLimit(this.wh, a.toChain);
        at = A > 0n ? BigInt(Math.round(e.options.nativeGas * 100)) * A / 100n : 0n;
      }
      const et = await f.quoteTransfer(this.wh, a.fromChain, a.toChain, {
        token: a.source.id,
        amount: h(e.normalizedParams.amount),
        protocol: "ExecutorTokenBridge",
        nativeGas: at,
        msgValue: V,
        gasLimit: S,
        referrerFee: L
      });
      return a.displayQuote(et, e, et.details);
    } catch (w) {
      return {
        success: !1,
        error: w
      };
    }
  }
  async initiate(a, e, n, i) {
    const { fromChain: s, toChain: o } = a, { params: r } = n, c = await f.destinationOverrides(s, o, this.toTransferDetails(a, r, T.chainAddress(e.chain(), e.address()), i, n)), d = await f.transfer(s, c, e);
    let u = 0;
    return (async () => {
      for (; u < 20; ) {
        try {
          const [w] = await this.wh.getExecutorTxStatus(d.at(-1).txid, s.chain);
          if (w)
            break;
        } catch {
        }
        u++, await new Promise((w) => setTimeout(w, 2e3));
      }
    })(), {
      from: c.from.chain,
      to: c.to.chain,
      state: g.SourceInitiated,
      originTxs: d
    };
  }
  async complete(a, e) {
    if (!b(e) && !bt(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 n = this.wh.getChain(e.to), i = await n.getExecutorTokenBridge(), s = xt(a.chain(), a.address()), o = i.redeem(s, e.attestation.attestation), r = await E(n, o, a);
    return {
      ...e,
      state: g.DestinationInitiated,
      attestation: e.attestation,
      destinationTxs: r
    };
  }
  async resume(a) {
    const e = await f.from(this.wh, a, 1e4);
    if (e.transfer.protocol !== "ExecutorTokenBridge")
      throw new Error("Can only resume ExecutorTokenBridge transfers");
    return f.getReceipt(e);
  }
  async *track(a, e) {
    for await (const n of f.track(this.wh, a, e))
      yield n;
  }
  toTransferDetails(a, e, n, i, s) {
    if (!s.details)
      throw new Error("Missing quote details");
    return {
      from: n,
      to: i,
      token: a.source.id,
      amount: h(e.normalizedParams.amount),
      protocol: "ExecutorTokenBridge",
      executorQuote: s.details.executorQuote,
      referrerFee: s.details.referrerFee
    };
  }
}
l(z, "IS_EXECUTOR_ROUTE", !0), l(z, "NATIVE_GAS_DROPOFF_SUPPORTED", !0), l(z, "config", {}), l(z, "meta", {
  name: "TokenBridgeExecutorRoute"
});
class wt extends Q {
  static supportedNetworks() {
    return ["Mainnet", "Testnet"];
  }
  // get the list of chains this route supports
  static supportedChains(t) {
    return q(t);
  }
  // get the list of destination tokens that may be received on the destination chain
  static async supportedDestinationTokens(t, a, e) {
    try {
      return [await f.lookupDestinationToken(a, e, t)];
    } catch {
      return [];
    }
  }
  getDefaultOptions() {
    return { payload: void 0 };
  }
  async validate(t, a) {
    const e = Y(a.amount, t.source.decimals);
    return { valid: !0, params: {
      amount: a.amount,
      normalizedParams: { amount: e },
      options: {}
    } };
  }
  async quote(t, a) {
    try {
      return t.displayQuote(await f.quoteTransfer(this.wh, t.fromChain, t.toChain, {
        token: t.source.id,
        amount: h(a.normalizedParams.amount),
        protocol: "TokenBridge",
        ...a.options
      }), a);
    } catch (e) {
      return {
        success: !1,
        error: e
      };
    }
  }
  async initiate(t, a, e, n) {
    const { params: i } = e, s = await f.destinationOverrides(t.fromChain, t.toChain, this.toTransferDetails(t, i, T.chainAddress(a.chain(), a.address()), n)), o = await f.transfer(t.fromChain, s, a);
    return {
      from: s.from.chain,
      to: s.to.chain,
      state: g.SourceInitiated,
      originTxs: o
    };
  }
  async complete(t, a) {
    if (!b(a))
      throw new Error("The source must be finalized in order to complete the transfer");
    const e = this.wh.getChain(a.to), n = await f.redeem(e, a.attestation.attestation, t);
    return {
      ...a,
      state: g.DestinationInitiated,
      destinationTxs: n
    };
  }
  async resume(t) {
    const a = await f.from(this.wh, t, 1e4);
    if (a.transfer.protocol !== "TokenBridge")
      throw new Error("Transfer is not a TokenBridge transfer");
    return f.getReceipt(a);
  }
  async *track(t, a) {
    yield* f.track(this.wh, t, a);
  }
  toTransferDetails(t, a, e, n) {
    return {
      from: e,
      to: n,
      protocol: "TokenBridge",
      token: t.source.id,
      amount: h(a.normalizedParams.amount),
      ...a.options
    };
  }
}
l(wt, "meta", {
  name: "ManualTokenBridge"
});
const j = 15n, gt = 100n, R = 10000n, F = class F extends I {
  static supportedNetworks() {
    return ["Mainnet"];
  }
  static supportedChains(t) {
    return ot.has(t) ? ot.get(t) : [];
  }
  static async supportedDestinationTokens(t, a, e) {
    const [, n] = W(a.network, a.chain, t), i = P(n), s = await a.getPorticoBridge();
    if (!s.supportedTokens().some((u) => P(u.token) === i))
      return [];
    try {
      const u = await s.getTransferrableToken(i);
      await f.lookupDestinationToken(a, e, u);
    } catch {
      return [];
    }
    const r = (await e.getPorticoBridge()).supportedTokens(), { tokenMap: c } = e.config, d = s.getTokenGroup(i);
    return r.filter((u) => (u.group === d || // ETH/WETH supports wrapping/unwrapping
    u.group === "ETH" && d === "WETH" || u.group === "WETH" && d === "ETH") && (!c || Dt.byAddress(c, P(u.token)))).map((u) => u.token);
  }
  getDefaultOptions() {
    return {};
  }
  async validate(t, a) {
    try {
      if (!F.supportedChains(t.fromChain.network).includes(t.fromChain.chain) || !F.supportedChains(t.toChain.network).includes(t.toChain.chain))
        throw new Error("Protocol not supported");
      const { fromChain: e, toChain: n, source: i, destination: s } = t, { network: o } = e, [, r] = W(o, e.chain, i.id), [, c] = W(o, n.chain, s.id), d = await e.getPorticoBridge(), u = await n.getPorticoBridge(), p = await d.getTransferrableToken(P(r)), w = await u.getTransferrableToken(P(c));
      return { valid: !0, params: {
        amount: a.amount,
        options: a.options ?? this.getDefaultOptions(),
        normalizedParams: {
          amount: t.parseAmount(a.amount),
          canonicalSourceToken: p,
          canonicalDestinationToken: w,
          sourceToken: r,
          destinationToken: c
        }
      } };
    } catch (e) {
      return { valid: !1, error: e, params: a };
    }
  }
  async quote(t, a) {
    try {
      const e = await this.fetchSwapQuote(t, a), n = Math.max(t.source.decimals, t.destination.decimals), i = h(U(a.normalizedParams.amount, n));
      if (h(U(k(e.minAmountFinish, t.destination.decimals), n)) < i - i * gt / R)
        throw new Error("Slippage too high");
      const r = await (await t.toChain.getPorticoBridge()).quoteRelay(a.normalizedParams.canonicalDestinationToken.address, a.normalizedParams.destinationToken.address), c = {
        swapAmounts: e,
        relayerFee: r
      }, d = c.swapAmounts.minAmountFinish - r;
      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: a.normalizedParams.sourceToken,
          amount: h(a.normalizedParams.amount)
        },
        destinationToken: {
          token: a.normalizedParams.destinationToken,
          amount: c.swapAmounts.minAmountFinish - r
        },
        relayFee: {
          token: a.normalizedParams.destinationToken,
          amount: r
        },
        eta: ut(t.fromChain.chain),
        expires: mt(0, 5, 0)
      }, a, c);
    } catch (e) {
      return {
        success: !1,
        error: e
      };
    }
  }
  async initiate(t, a, e, n) {
    const { params: i, details: s } = e, o = t.source.id.address, r = t.destination.id, c = await t.fromChain.getPorticoBridge(), d = c.getTokenGroup(o.toString()), p = (await t.toChain.getPorticoBridge()).getPorticoAddress(d), w = c.transfer(T.parseAddress(a.chain(), a.address()), n, o, h(i.normalizedParams.amount), r, p, s);
    return {
      originTxs: await E(t.fromChain, w, a),
      state: g.SourceInitiated,
      from: t.fromChain.chain,
      to: t.toChain.chain
    };
  }
  async *track(t, a) {
    if (lt(t) || ht(t)) {
      const { txid: e } = t.originTxs[t.originTxs.length - 1], n = await this.wh.getVaa(e, "PorticoBridge:Transfer", a);
      if (!n)
        throw new Error("No VAA found for transaction: " + e);
      const i = {
        chain: n.emitterChain,
        emitter: n.emitterAddress,
        sequence: n.sequence
      };
      t = {
        ...t,
        state: g.Attested,
        attestation: {
          id: i,
          attestation: n
        }
      }, yield t;
    }
    b(t) && await (await this.wh.getChain(t.to).getPorticoBridge()).isTransferCompleted(t.attestation.attestation) && (t = {
      ...t,
      state: g.DestinationFinalized
    }, yield t), yield t;
  }
  async complete(t, a) {
    if (!b(a))
      throw new Error("Source must be attested");
    const e = await this.wh.getChain(a.to), n = await e.getPorticoBridge(), i = T.chainAddress(t.chain(), t.address()), s = n.redeem(i.address, a.attestation.attestation);
    return await E(e, s, t);
  }
  async fetchSwapQuote(t, a) {
    const e = await t.fromChain.getPorticoBridge(), n = h(a.normalizedParams.amount), i = e.getTokenGroup(P(a.normalizedParams.sourceToken)), s = await e.quoteSwap(a.normalizedParams.sourceToken.address, a.normalizedParams.canonicalSourceToken.address, i, n), o = s * j / R;
    if (o >= s)
      throw new Error("Start slippage too high");
    const r = await t.toChain.getPorticoBridge(), c = s - o, d = await r.quoteSwap(a.normalizedParams.canonicalDestinationToken.address, a.normalizedParams.destinationToken.address, i, c), u = d * j / R;
    if (u >= d)
      throw new Error("Finish slippage too high");
    const p = d - u;
    return {
      minAmountStart: c,
      minAmountFinish: p
    };
  }
};
l(F, "NATIVE_GAS_DROPOFF_SUPPORTED", !1), l(F, "meta", {
  name: "AutomaticPortico"
});
let X = F;
class Tt extends Q {
  static supportedNetworks() {
    return ["Mainnet", "Testnet"];
  }
  // get the list of chains this route supports
  static supportedChains(t) {
    return _.has(t) ? _.get(t) : [];
  }
  // get the list of destination tokens that may be received on the destination chain
  static async supportedDestinationTokens(t, a, e) {
    const n = G.get(a.network, a.chain);
    if (!n)
      return [];
    if (!D(t, T.tokenId(a.chain, n)))
      return [];
    const { network: i, chain: s } = e;
    return G.has(i, s) ? [T.chainAddress(s, G.get(i, s))] : [];
  }
  getDefaultOptions() {
    return {
      payload: void 0
    };
  }
  async validate(t, a) {
    return { valid: !0, params: {
      normalizedParams: {
        amount: t.parseAmount(a.amount)
      },
      options: a.options ?? this.getDefaultOptions(),
      ...a
    } };
  }
  async quote(t, a) {
    try {
      return t.displayQuote(await C.quoteTransfer(t.fromChain, t.toChain, {
        automatic: !1,
        amount: h(a.normalizedParams.amount),
        ...a.options
      }), a);
    } catch (e) {
      return {
        success: !1,
        error: e
      };
    }
  }
  async initiate(t, a, e, n) {
    const { params: i } = e, s = await C.destinationOverrides(t.fromChain, t.toChain, this.toTransferDetails(i, T.chainAddress(a.chain(), a.address()), n)), o = await C.transfer(t.fromChain, s, a), r = await C.getTransferMessage(t.fromChain, o[o.length - 1].txid);
    return {
      from: s.from.chain,
      to: s.to.chain,
      state: g.SourceFinalized,
      originTxs: o,
      attestation: { id: r.id, attestation: { message: r.message } }
    };
  }
  async complete(t, a) {
    if (!b(a))
      throw new Error("The source must be finalized in order to complete the transfer");
    const { id: e, attestation: n } = a.attestation;
    if (Bt.isCircleAttestation(n)) {
      const { message: i, attestation: s } = n;
      if (!s)
        throw new Error(`No Circle attestation for ${e}`);
      const o = this.wh.getChain(a.to), r = await o.getCircleBridge(), c = T.parseAddress(t.chain(), t.address()), d = r.redeem(c, i, s), u = await E(o, d, t);
      return {
        ...a,
        state: g.DestinationInitiated,
        destinationTxs: u
      };
    } else
      return a;
  }
  async resume(t) {
    const a = await C.from(this.wh, t, 1e4);
    return C.getReceipt(a);
  }
  async *track(t, a) {
    yield* C.track(this.wh, t, a);
  }
  toTransferDetails(t, a, e) {
    return {
      from: a,
      to: e,
      amount: h(t.normalizedParams.amount),
      automatic: !1,
      ...t.options
    };
  }
}
l(Tt, "meta", {
  name: "ManualCCTP",
  provider: "Circle"
});
class J extends I {
  static supportedNetworks() {
    return ["Mainnet", "Testnet"];
  }
  // get the list of chains this route supports
  static supportedChains(t) {
    return _.has(t) ? _.get(t).filter((e) => {
      var n;
      return (n = Et.get(t, e)) == null ? void 0 : n.wormholeRelayer;
    }) : [];
  }
  // get the list of destination tokens that may be received on the destination chain
  static async supportedDestinationTokens(t, a, e) {
    const n = G.get(a.network, a.chain);
    if (!n)
      return [];
    if (!D(t, T.tokenId(a.chain, n)))
      return [];
    const { network: i, chain: s } = e;
    return G.has(i, s) ? [T.chainAddress(s, G.get(i, s))] : [];
  }
  getDefaultOptions() {
    return {
      nativeGas: 0
    };
  }
  async validate(t, a) {
    try {
      const e = a.options ?? this.getDefaultOptions();
      return { valid: !0, params: {
        normalizedParams: await this.normalizeTransferParams(t, a),
        options: e,
        ...a
      } };
    } catch (e) {
      return {
        valid: !1,
        params: a,
        error: e
      };
    }
  }
  async quote(t, a) {
    try {
      return t.displayQuote(await C.quoteTransfer(t.fromChain, t.toChain, {
        automatic: !0,
        amount: h(a.normalizedParams.amount),
        nativeGas: h(a.normalizedParams.nativeGasAmount)
      }), a);
    } catch (e) {
      return {
        success: !1,
        error: e
      };
    }
  }
  async normalizeTransferParams(t, a) {
    const e = t.parseAmount(a.amount), i = await (await t.fromChain.getAutomaticCircleBridge()).getRelayerFee(t.toChain.chain), s = i * 105n / 100n;
    if (h(e) < s)
      throw new Z(k(s, e.decimals));
    const o = h(e) - i, c = (a.options ?? this.getDefaultOptions()).nativeGas ?? 0;
    if (c > 1 || c < 0)
      throw new Error("Native gas must be between 0.0 and 1.0 (0% and 100%)");
    let d = 0n;
    if (c > 0) {
      let p = await (await t.toChain.getAutomaticCircleBridge()).maxSwapAmount();
      o < p && (p = o);
      const w = 1e4, v = BigInt(Math.floor(c * w));
      d = p * v / BigInt(w), d === o && d > 0n && (d -= 1n);
    }
    return {
      fee: t.amountFromBaseUnits(i),
      amount: e,
      nativeGasAmount: t.amountFromBaseUnits(d)
    };
  }
  toTransferDetails(t, a, e) {
    return {
      from: a,
      to: e,
      amount: h(t.normalizedParams.amount),
      automatic: !0,
      nativeGas: h(t.normalizedParams.nativeGasAmount)
    };
  }
  async initiate(t, a, e, n) {
    const { params: i } = e;
    let s = this.toTransferDetails(i, T.chainAddress(a.chain(), a.address()), n), o = await C.transfer(t.fromChain, s, a);
    const r = await C.getTransferMessage(t.fromChain, o[o.length - 1].txid);
    return {
      from: s.from.chain,
      to: s.to.chain,
      state: g.SourceFinalized,
      originTxs: o,
      attestation: { id: r.id, attestation: { message: r.message } }
    };
  }
  async *track(t, a) {
    yield* C.track(this.wh, t, a);
  }
}
l(J, "NATIVE_GAS_DROPOFF_SUPPORTED", !0), l(J, "meta", {
  name: "AutomaticCCTP",
  provider: "Circle"
});
class pt extends Q {
  static supportedNetworks() {
    return ["Mainnet"];
  }
  static supportedChains(t) {
    return q(t);
  }
  static async supportedDestinationTokens(t, a, e) {
    if (!await this.isSourceTokenSupported(t, a))
      return [];
    const n = y.getNativeTbtcToken(e.chain);
    if (n)
      return [n];
    const i = await e.getTokenBridge(), s = y.getNativeTbtcToken("Ethereum");
    try {
      const o = await i.getWrappedAsset(s);
      return [T.tokenId(e.chain, o.toString())];
    } catch (o) {
      if (o.message.includes("not a wrapped asset"))
        return [];
      throw o;
    }
  }
  getDefaultOptions() {
    return {};
  }
  async validate(t, a) {
    return { valid: !0, params: {
      normalizedParams: {
        amount: t.parseAmount(a.amount)
      },
      options: a.options ?? this.getDefaultOptions(),
      ...a
    } };
  }
  async quote(t, a) {
    const e = ut(t.fromChain.chain) + St;
    return {
      success: !0,
      params: a,
      sourceToken: {
        token: t.source.id,
        amount: a.normalizedParams.amount
      },
      destinationToken: {
        token: t.destination.id,
        amount: a.normalizedParams.amount
      },
      eta: e,
      expires: mt(24, 0, 0)
    };
  }
  async initiate(t, a, e, n) {
    const i = h(e.params.normalizedParams.amount), s = t.fromChain.chain === "Ethereum", o = y.getNativeTbtcToken(t.fromChain.chain), r = o && D(e.sourceToken.token, o);
    if (r && !s)
      return await this.transferNative(t, a, n, i);
    if (!r && s)
      throw new Error("Only tbtc can be transferred on Ethereum");
    if (!r) {
      const d = await (await t.fromChain.getTokenBridge()).getOriginalAsset(e.sourceToken.token.address), u = y.getNativeTbtcToken("Ethereum");
      if (!D(d, u))
        throw new Error("Can only transfer wrapped tbtc");
    }
    return await this.transferWrapped(t, a, n, i);
  }
  async transferNative(t, a, e, n) {
    const i = T.parseAddress(a.chain(), a.address()), o = (await t.fromChain.getTBTCBridge()).transfer(i, e, n);
    return {
      originTxs: await E(t.fromChain, o, a),
      state: g.SourceInitiated,
      from: t.fromChain.chain,
      to: t.toChain.chain
    };
  }
  async transferWrapped(t, a, e, n) {
    const i = T.parseAddress(a.chain(), a.address()), s = zt.get(t.fromChain.network, e.chain), o = await t.fromChain.getTokenBridge();
    let r;
    return s ? r = o.transfer(
      i,
      T.chainAddress(t.toChain.chain, s),
      t.source.id.address,
      n,
      // payload is the recipient address
      e.address.toUniversalAddress().toUint8Array()
    ) : r = o.transfer(i, e, t.source.id.address, n), {
      originTxs: await E(t.fromChain, r, a),
      state: g.SourceInitiated,
      from: t.fromChain.chain,
      to: t.toChain.chain
    };
  }
  async complete(t, a) {
    if (!b(a))
      throw new Error("The source must be finalized in order to complete the transfer");
    const e = T.parseAddress(t.chain(), t.address()), n = a.attestation.attestation, i = this.wh.getChain(a.to);
    let s;
    if (n.payloadLiteral === "TBTCBridge:GatewayTransfer")
      s = (await i.getTBTCBridge()).redeem(e, n);
    else {
      const r = await i.getTokenBridge(), c = Ft(n), d = Gt("TokenBridge:Transfer", c);
      s = r.redeem(e, d);
    }
    const o = await E(i, s, t);
    return {
      ...a,
      state: g.DestinationInitiated,
      destinationTxs: o
    };
  }
  async resume(t) {
    const a = await this.wh.getVaa(t.txid, y.getTransferDiscriminator());
    if (!a)
      throw new Error("No VAA found for transaction: " + t);
    const e = y.getNativeTbtcToken("Ethereum"), { chain: n, address: i } = a.payload.token;
    if (!D(e, { chain: n, address: i }))
      throw new Error("Can only resume tbtc transfers");
    return {
      originTxs: [t],
      state: g.Attested,
      from: a.emitterChain,
      to: a.payload.to.chain,
      attestation: {
        id: {
          chain: a.emitterChain,
          emitter: a.emitterAddress,
          sequence: a.sequence
        },
        attestation: a
      }
    };
  }
  async *track(t, a) {
    if (lt(t) || ht(t)) {
      const { txid: e } = t.originTxs[t.originTxs.length - 1], n = await this.wh.getVaa(e, y.getTransferDiscriminator(), a);
      if (!n)
        throw new Error("No VAA found for transaction: " + e);
      const i = {
        chain: n.emitterChain,
        emitter: n.emitterAddress,
        sequence: n.sequence
      };
      t = {
        ...t,
        state: g.Attested,
        attestation: {
          id: i,
          attestation: n
        }
      }, yield t;
    }
    b(t) && await (await this.wh.getChain(t.to).getTokenBridge()).isTransferCompleted(t.attestation.attestation) && (t = {
      ...t,
      state: g.DestinationFinalized
    }, yield t), yield t;
  }
  static async isSourceTokenSupported(t, a) {
    if (N(t.address))
      return !1;
    const e = y.getNativeTbtcToken(a.chain);
    if (e && D(t, e))
      return !0;
    const n = await a.getTokenBridge();
    try {
      const i = await n.getOriginalAsset(t.address);
      return D(i, y.getNativeTbtcToken("Ethereum"));
    } catch (i) {
      if (i.message.includes("not a wrapped asset"))
        return !1;
      throw i;
    }
  }
}
l(pt, "meta", {
  name: "ManualTBTC"
});
const Ht = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
  __proto__: null,
  AutomaticCCTPRoute: J,
  AutomaticPorticoRoute: X,
  AutomaticRoute: I,
  AutomaticTokenBridgeRoute: H,
  BPS_PER_HUNDRED_PERCENT: R,
  CCTPRoute: Tt,
  ExecutorTokenBridgeRoute: z,
  FinalizableRoute: Ot,
  MAX_SLIPPAGE_BPS: gt,
  ManualRoute: Q,
  MinAmountError: Z,
  RelayFailedError: It,
  Route: Nt,
  RouteResolver: Rt,
  RouteTransferRequest: tt,
  SLIPPAGE_BPS: j,
  TBTCRoute: pt,
  TokenBridgeRoute: wt,
  UnavailableError: Mt,
  checkAndCompleteTransfer: ft,
  executorTokenBridgeRoute: Qt,
  isAutomatic: Ut,
  isFinalizable: dt,
  isManual: ct
}, Symbol.toStringTag, { value: "Module" })), jt = "0x1::aptos_coin::AptosCoin", M = "::", kt = "Aptos", Vt = (m) => /^(0x)?[0-9a-fA-F]+::\w+::\w+$/.test(m), Xt = (m) => m.split(M)[0];
function Lt(m) {
  return m.length % 2 !== 0 || m.length < 66 ? (m = m.startsWith("0x") ? m.slice(2) : m, "0x" + m.padStart(64, "0")) : m;
}
const B = class B {
  constructor(t) {
    l(this, "type", "Native");
    // Full 32 bytes of Address
    l(this, "address");
    // Optional module and contract name
    l(this, "module");
    if (B.instanceof(t))
      this.address = t.address, this.module = t.module;
    else if (rt.instanceof(t))
      this.address = t.toUint8Array();
    else if (typeof t == "string") {
      if (Vt(t)) {
        const a = t.split(M);
        this.module = a.slice(1).join(M), t = a[0];
      }
      if (t = Lt(t), !$.valid(t))
        throw new Error("Invalid Aptos address: " + t);
      this.address = $.decode(t);
    } else
      this.address = t;
  }
  unwrap() {
    const t = $.encode(this.address).replace(/^0+/, ""), a = this.module ? M + this.module : "";
    return `0x${t}${a}`;
  }
  toString() {
    return this.unwrap();
  }
  toNative() {
    return this;
  }
  toUint8Array() {
    return this.address;
  }
  toUniversalAddress() {
    return new rt(this.toUint8Array());
  }
  static instanceof(t) {
    return t.constructor.platform === B.platform;
  }
  equals(t) {
    return B.instanceof(t) ? t.unwrap() === this.unwrap() : this.toUniversalAddress().equals(t);
  }
};
l(B, "byteSize", 32), l(B, "platform", kt);
let K = B;
_t(kt, K);
export {
  J as A,
  Tt as C,
  tt as R,
  wt as T,
  kt as _,
  H as a,
  X as b,
  pt as c,
  K as d,
  jt as e,
  M as f,
  Xt as g,
  Vt as i,
  Ht as r
};
