import { a as U, f, b7 as I, M as V, b8 as M, i as B, aT as u, d as D, u as c, P as _, o as R, ad as F, b5 as Y, W as l, e as T, aY as G, b9 as W, v as S, ba as E, b as p, h as C, bb as $, bc as w, bd as H, ag as P, be as J, T as g, ae as Z, af as q, aX as tt, bf as at, at as et, K as nt, _ as it, $ as st, b0 as ot, ai as O, m as z } from "./platform-Cil_UtAQ.mjs";
class Q {
  source;
  destination;
  fromChain;
  toChain;
  sender;
  recipient;
  constructor(t, a, e, n, i, s) {
    this.fromChain = t, this.toChain = a, this.source = e, this.destination = n, this.sender = i, this.recipient = s;
  }
  parseAmount(t) {
    return U(t, this.source.decimals);
  }
  amountFromBaseUnits(t) {
    return f(t, this.source.decimals);
  }
  async displayQuote(t, a, e) {
    let n = {
      success: !0,
      sourceToken: {
        token: t.sourceToken.token,
        amount: f(t.sourceToken.amount, this.source.decimals)
      },
      destinationToken: {
        token: t.destinationToken.token,
        amount: f(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: f(t.relayFee.amount, s)
      };
    }
    if (t.destinationNativeGas) {
      const i = await this.toChain.getDecimals("native");
      n.destinationNativeGas = f(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 I(e, a.source, a.sourceDecimals), s = await I(n, a.destination, a.destinationDecimals);
    return new Q(e, n, i, s, a.sender, a.recipient);
  }
}
class ht extends V {
  static NATIVE_GAS_DROPOFF_SUPPORTED = !0;
  static meta = {
    name: "AutomaticTokenBridge"
  };
  static supportedNetworks() {
    return ["Mainnet", "Testnet"];
  }
  // get the list of chains this route supports
  static supportedChains(t) {
    return M.has(t) ? M.get(t) : [];
  }
  // get the list of destination tokens that may be received on the destination chain
  static async supportedDestinationTokens(t, a, e) {
    try {
      if (!B(t) && !await (await a.getAutomaticTokenBridge()).isRegisteredToken(t.address))
        return [];
      const n = await u.lookupDestinationToken(a, e, t);
      return await (await e.getAutomaticTokenBridge()).isRegisteredToken(n.address) ? [n] : [];
    } catch {
      return [];
    }
  }
  getDefaultOptions() {
    return { nativeGas: 0 };
  }
  async validate(t, a) {
    try {
      if (t.fromChain.chain === t.toChain.chain)
        return {
          valid: !1,
          params: a,
          error: new Error("Source and destination chains cannot be the same")
        };
      if (D(t.fromChain.chain) === "Solana" && await t.fromChain.isToken2022(t.source.id.address))
        return {
          valid: !1,
          params: a,
          error: new Error("Transfers of Token-2022 assets from SVM chains are not supported via the Automatic Token Bridge route. Please use the Executor Token Bridge route instead.")
        };
      if (D(t.toChain.chain) === "Solana" && await t.toChain.isToken2022(t.destination.id.address))
        return {
          valid: !1,
          params: a,
          error: new Error("Transfers of Token-2022 assets to SVM chains are not supported via the Automatic Token Bridge route. Please use the Executor Token Bridge route instead.")
        };
      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;
      B(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 = B(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 (c(e) < o)
      throw new _(f(o, e.decimals));
    const r = c(e) - s;
    let h = f(0n, t.source.decimals);
    if (a.options && a.options.nativeGas > 0) {
      let k = await (await t.toChain.getAutomaticTokenBridge()).maxSwapAmount(t.destination.id.address);
      const v = R(f(r, e.decimals), u.MAX_DECIMALS), y = await t.toChain.getDecimals(t.destination.id.address), b = c(F(v, y));
      b < k && (k = b);
      const N = 1e4, X = BigInt(Math.floor(a.options.nativeGas * N)), j = k * X / BigInt(N), K = f(j, t.destination.decimals);
      h = F(R(K, u.MAX_DECIMALS), t.source.decimals), c(h) > r && (h = f(r, t.source.decimals));
    }
    return {
      fee: f(s, t.source.decimals),
      amount: e,
      nativeGasAmount: h
    };
  }
  async quote(t, a) {
    const e = await t.fromChain.getAutomaticTokenBridge();
    if (Y(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 u.quoteTransfer(this.wh, t.fromChain, t.toChain, {
        protocol: "AutomaticTokenBridge",
        amount: c(a.normalizedParams.amount),
        token: t.source.id,
        nativeGas: c(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, l.chainAddress(a.chain(), a.address()), n), o = await u.transfer(t.fromChain, s, a);
    return {
      from: s.from.chain,
      to: s.to.chain,
      state: T.SourceInitiated,
      originTxs: o
    };
  }
  async *track(t, a) {
    try {
      yield* u.track(this.wh, t, a);
    } catch (e) {
      throw e;
    }
  }
  toTransferDetails(t, a, e, n) {
    return {
      from: e,
      to: n,
      protocol: "AutomaticTokenBridge",
      amount: c(a.normalizedParams.amount),
      token: t.source.id,
      nativeGas: c(a.normalizedParams.nativeGasAmount)
    };
  }
}
class ut extends G {
  static meta = {
    name: "ManualTokenBridge"
  };
  static supportedNetworks() {
    return ["Mainnet", "Testnet"];
  }
  // get the list of chains this route supports
  static supportedChains(t) {
    return W(t);
  }
  // get the list of destination tokens that may be received on the destination chain
  static async supportedDestinationTokens(t, a, e) {
    try {
      return [await u.lookupDestinationToken(a, e, t)];
    } catch {
      return [];
    }
  }
  getDefaultOptions() {
    return { payload: void 0 };
  }
  async validate(t, a) {
    if (t.fromChain.chain === t.toChain.chain)
      return {
        valid: !1,
        params: a,
        error: new Error("Source and destination chains cannot be the same")
      };
    if (D(t.fromChain.chain) === "Solana" && await t.fromChain.isToken2022(t.source.id.address))
      return {
        valid: !1,
        params: a,
        error: new Error("Transfers of Token-2022 assets from SVM chains are not supported via the Manual Token Bridge route. Please use the Executor Token Bridge route instead.")
      };
    if (D(t.toChain.chain) === "Solana" && await t.toChain.isToken2022(t.destination.id.address))
      return {
        valid: !1,
        params: a,
        error: new Error("Transfers of Token-2022 assets to SVM chains are not supported via the Manual Token Bridge route. Please use the Executor Token Bridge route instead.")
      };
    const e = U(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 u.quoteTransfer(this.wh, t.fromChain, t.toChain, {
        token: t.source.id,
        amount: c(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 u.destinationOverrides(t.fromChain, t.toChain, this.toTransferDetails(t, i, l.chainAddress(a.chain(), a.address()), n)), o = await u.transfer(t.fromChain, s, a);
    return {
      from: s.from.chain,
      to: s.to.chain,
      state: T.SourceInitiated,
      originTxs: o
    };
  }
  async complete(t, a) {
    if (!S(a))
      throw new Error("The source must be finalized in order to complete the transfer");
    const e = this.wh.getChain(a.to), n = await u.redeem(e, a.attestation.attestation, t);
    return {
      ...a,
      state: T.DestinationInitiated,
      destinationTxs: n
    };
  }
  async resume(t) {
    const a = await u.from(this.wh, t, 1e4);
    if (a.transfer.protocol !== "TokenBridge")
      throw new Error("Transfer is not a TokenBridge transfer");
    return u.getReceipt(a);
  }
  async *track(t, a) {
    yield* u.track(this.wh, t, a);
  }
  toTransferDetails(t, a, e, n) {
    return {
      from: e,
      to: n,
      protocol: "TokenBridge",
      token: t.source.id,
      amount: c(a.normalizedParams.amount),
      ...a.options
    };
  }
}
class lt extends G {
  static meta = {
    name: "ManualCCTP",
    provider: "Circle"
  };
  static supportedNetworks() {
    return ["Mainnet", "Testnet"];
  }
  // get the list of chains this route supports
  static supportedChains(t) {
    return E.has(t) ? E.get(t) : [];
  }
  // get the list of destination tokens that may be received on the destination chain
  static async supportedDestinationTokens(t, a, e) {
    const n = p.get(a.network, a.chain);
    if (!n)
      return [];
    if (!C(t, l.tokenId(a.chain, n)))
      return [];
    const { network: i, chain: s } = e;
    return p.has(i, s) ? [l.chainAddress(s, p.get(i, s))] : [];
  }
  getDefaultOptions() {
    return {
      payload: void 0
    };
  }
  async validate(t, a) {
    return t.fromChain.chain === t.toChain.chain ? {
      valid: !1,
      params: a,
      error: new Error("Source and destination chains cannot be the same")
    } : { valid: !0, params: {
      normalizedParams: {
        amount: t.parseAmount(a.amount)
      },
      options: a.options ?? this.getDefaultOptions(),
      ...a
    } };
  }
  async quote(t, a) {
    try {
      const e = await $();
      return e || t.displayQuote(await w.quoteTransfer(t.fromChain, t.toChain, {
        automatic: !1,
        amount: c(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 w.destinationOverrides(t.fromChain, t.toChain, this.toTransferDetails(i, l.chainAddress(a.chain(), a.address()), n)), o = await w.transfer(t.fromChain, s, a), r = await w.getTransferMessage(t.fromChain, o[o.length - 1].txid);
    return {
      from: s.from.chain,
      to: s.to.chain,
      state: T.SourceFinalized,
      originTxs: o,
      attestation: { id: r.id, attestation: { message: r.message } }
    };
  }
  async complete(t, a) {
    if (!S(a))
      throw new Error("The source must be finalized in order to complete the transfer");
    const { id: e, attestation: n } = a.attestation;
    if (H.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(), h = l.parseAddress(t.chain(), t.address()), m = r.redeem(h, i, s), k = await P(o, m, t);
      return {
        ...a,
        state: T.DestinationInitiated,
        destinationTxs: k
      };
    } else
      return a;
  }
  async resume(t) {
    const a = await w.from(this.wh, t, 1e4);
    return w.getReceipt(a);
  }
  async *track(t, a) {
    yield* w.track(this.wh, t, a);
  }
  toTransferDetails(t, a, e) {
    return {
      from: a,
      to: e,
      amount: c(t.normalizedParams.amount),
      automatic: !1,
      ...t.options
    };
  }
}
class mt extends V {
  static NATIVE_GAS_DROPOFF_SUPPORTED = !0;
  static meta = {
    name: "AutomaticCCTP",
    provider: "Circle"
  };
  static supportedNetworks() {
    return ["Mainnet", "Testnet"];
  }
  // get the list of chains this route supports
  static supportedChains(t) {
    return E.has(t) ? E.get(t).filter((e) => J.get(t, e)?.wormholeRelayer) : [];
  }
  // get the list of destination tokens that may be received on the destination chain
  static async supportedDestinationTokens(t, a, e) {
    const n = p.get(a.network, a.chain);
    if (!n)
      return [];
    if (!C(t, l.tokenId(a.chain, n)))
      return [];
    const { network: i, chain: s } = e;
    return p.has(i, s) ? [l.chainAddress(s, p.get(i, s))] : [];
  }
  getDefaultOptions() {
    return {
      nativeGas: 0
    };
  }
  async validate(t, a) {
    try {
      if (t.fromChain.chain === t.toChain.chain)
        return {
          valid: !1,
          params: a,
          error: new Error("Source and destination chains cannot be the same")
        };
      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 {
      const e = await $();
      return e || t.displayQuote(await w.quoteTransfer(t.fromChain, t.toChain, {
        automatic: !0,
        amount: c(a.normalizedParams.amount),
        nativeGas: c(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 (c(e) < s)
      throw new _(f(s, e.decimals));
    const o = c(e) - i, h = (a.options ?? this.getDefaultOptions()).nativeGas ?? 0;
    if (h > 1 || h < 0)
      throw new Error("Native gas must be between 0.0 and 1.0 (0% and 100%)");
    let m = 0n;
    if (h > 0) {
      let v = await (await t.toChain.getAutomaticCircleBridge()).maxSwapAmount();
      o < v && (v = o);
      const y = 1e4, b = BigInt(Math.floor(h * y));
      m = v * b / BigInt(y), m === o && m > 0n && (m -= 1n);
    }
    return {
      fee: t.amountFromBaseUnits(i),
      amount: e,
      nativeGasAmount: t.amountFromBaseUnits(m)
    };
  }
  toTransferDetails(t, a, e) {
    return {
      from: a,
      to: e,
      amount: c(t.normalizedParams.amount),
      automatic: !0,
      nativeGas: c(t.normalizedParams.nativeGasAmount)
    };
  }
  async initiate(t, a, e, n) {
    const { params: i } = e;
    let s = this.toTransferDetails(i, l.chainAddress(a.chain(), a.address()), n), o = await w.transfer(t.fromChain, s, a);
    const r = await w.getTransferMessage(t.fromChain, o[o.length - 1].txid);
    return {
      from: s.from.chain,
      to: s.to.chain,
      state: T.SourceFinalized,
      originTxs: o,
      attestation: { id: r.id, attestation: { message: r.message } }
    };
  }
  async *track(t, a) {
    yield* w.track(this.wh, t, a);
  }
}
class ft extends G {
  static meta = {
    name: "ManualTBTC"
  };
  static supportedNetworks() {
    return ["Mainnet"];
  }
  static supportedChains(t) {
    return W(t);
  }
  static async supportedDestinationTokens(t, a, e) {
    if (!await this.isSourceTokenSupported(t, a))
      return [];
    const n = g.getNativeTbtcToken(e.chain);
    if (n)
      return [n];
    const i = await e.getTokenBridge(), s = g.getNativeTbtcToken("Ethereum");
    try {
      const o = await i.getWrappedAsset(s);
      return [l.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 t.fromChain.chain === t.toChain.chain ? {
      valid: !1,
      params: a,
      error: new Error("Source and destination chains cannot be the same")
    } : { valid: !0, params: {
      normalizedParams: {
        amount: t.parseAmount(a.amount)
      },
      options: a.options ?? this.getDefaultOptions(),
      ...a
    } };
  }
  async quote(t, a) {
    const e = Z(t.fromChain.chain) + q;
    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: tt(24, 0, 0)
    };
  }
  async initiate(t, a, e, n) {
    const i = c(e.params.normalizedParams.amount), s = t.fromChain.chain === "Ethereum", o = g.getNativeTbtcToken(t.fromChain.chain), r = o && C(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 m = await (await t.fromChain.getTokenBridge()).getOriginalAsset(e.sourceToken.token.address), k = g.getNativeTbtcToken("Ethereum");
      if (!C(m, k))
        throw new Error("Can only transfer wrapped tbtc");
    }
    return await this.transferWrapped(t, a, n, i);
  }
  async transferNative(t, a, e, n) {
    const i = l.parseAddress(a.chain(), a.address()), o = (await t.fromChain.getTBTCBridge()).transfer(i, e, n);
    return {
      originTxs: await P(t.fromChain, o, a),
      state: T.SourceInitiated,
      from: t.fromChain.chain,
      to: t.toChain.chain
    };
  }
  async transferWrapped(t, a, e, n) {
    const i = l.parseAddress(a.chain(), a.address()), s = at.get(t.fromChain.network, e.chain), o = await t.fromChain.getTokenBridge();
    let r;
    return s ? r = o.transfer(
      i,
      l.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 P(t.fromChain, r, a),
      state: T.SourceInitiated,
      from: t.fromChain.chain,
      to: t.toChain.chain
    };
  }
  async complete(t, a) {
    if (!S(a))
      throw new Error("The source must be finalized in order to complete the transfer");
    const e = l.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(), h = et(n), m = nt("TokenBridge:Transfer", h);
      s = r.redeem(e, m);
    }
    const o = await P(i, s, t);
    return {
      ...a,
      state: T.DestinationInitiated,
      destinationTxs: o
    };
  }
  async resume(t) {
    const a = await this.wh.getVaa(t.txid, g.getTransferDiscriminator());
    if (!a)
      throw new Error("No VAA found for transaction: " + t);
    const e = g.getNativeTbtcToken("Ethereum"), { chain: n, address: i } = a.payload.token;
    if (!C(e, { chain: n, address: i }))
      throw new Error("Can only resume tbtc transfers");
    return {
      originTxs: [t],
      state: T.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 (it(t) || st(t)) {
      const { txid: e } = t.originTxs[t.originTxs.length - 1], n = await this.wh.getVaa(e, g.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: T.Attested,
        attestation: {
          id: i,
          attestation: n
        }
      }, yield t;
    }
    S(t) && await (await this.wh.getChain(t.to).getTokenBridge()).isTransferCompleted(t.attestation.attestation) && (t = {
      ...t,
      state: T.DestinationFinalized
    }, yield t), yield t;
  }
  static async isSourceTokenSupported(t, a) {
    if (B(t.address))
      return !1;
    const e = g.getNativeTbtcToken(a.chain);
    if (e && C(t, e))
      return !0;
    const n = await a.getTokenBridge();
    try {
      const i = await n.getOriginalAsset(t.address);
      return C(i, g.getNativeTbtcToken("Ethereum"));
    } catch (i) {
      if (i.message.includes("not a wrapped asset"))
        return !1;
      throw i;
    }
  }
}
const Tt = "0x1::aptos_coin::AptosCoin", x = "::", L = "Aptos", rt = (d) => /^(0x)?[0-9a-fA-F]+::\w+::\w+$/.test(d), wt = (d) => d.split(x)[0];
function ct(d) {
  return d.length % 2 !== 0 || d.length < 66 ? (d = d.startsWith("0x") ? d.slice(2) : d, "0x" + d.padStart(64, "0")) : d;
}
class A {
  static byteSize = 32;
  static platform = L;
  type = "Native";
  // Full 32 bytes of Address
  address;
  // Optional module and contract name
  module;
  constructor(t) {
    if (A.instanceof(t))
      this.address = t.address, this.module = t.module;
    else if (O.instanceof(t))
      this.address = t.toUint8Array();
    else if (typeof t == "string") {
      if (rt(t)) {
        const a = t.split(x);
        this.module = a.slice(1).join(x), t = a[0];
      }
      if (t = ct(t), !z.valid(t))
        throw new Error("Invalid Aptos address: " + t);
      this.address = z.decode(t);
    } else
      this.address = t;
  }
  unwrap() {
    const t = z.encode(this.address).replace(/^0+/, ""), a = this.module ? x + this.module : "";
    return `0x${t}${a}`;
  }
  toString() {
    return this.unwrap();
  }
  toNative() {
    return this;
  }
  toUint8Array() {
    return this.address;
  }
  toUniversalAddress() {
    return new O(this.toUint8Array());
  }
  static instanceof(t) {
    return t.constructor.platform === A.platform;
  }
  equals(t) {
    return A.instanceof(t) ? t.unwrap() === this.unwrap() : this.toUniversalAddress().equals(t);
  }
}
ot(L, A);
export {
  A,
  lt as C,
  Q as R,
  ft as T,
  L as _,
  mt as a,
  ht as b,
  ut as c,
  Tt as d,
  x as e,
  wt as f,
  rt as i
};
