var H = Object.defineProperty;
var J = (l, e, t) => e in l ? H(l, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : l[e] = t;
var c = (l, e, t) => J(l, typeof e != "symbol" ? e + "" : e, t);
import { bE as V, bF as w, bG as g, bH as x, aj as P, h as b, bI as f, u as R, bJ as j, t as K, a8 as B, p as D, bK as Y, aA as O, E as z, a as M, bL as U, bM as X, l as Q, bN as Z, bO as q, bP as tt, bQ as et, bR as nt, _ as rt } from "./index-CjwA7HmM.mjs";
import "./index-DIddLRbN.mjs";
const _ = new V([
  "function start((bytes32,address,address,address,address,address,uint256,uint256,uint256,uint256)) returns (address,uint16,uint64)",
  "function receiveMessageAndSwap(bytes)"
]), st = new V([
  "function quoteExactInputSingle((address,address,uint256,uint24,uint160)) public view returns (uint256,uint160,uint32,uint256)"
]), k = 100, ot = "https://gfx.relayers.xlabs.xyz/api/v1/swap/quote", it = "https://thermae.fly.dev/api/order/create";
class G {
  // Post the order to the portico API
  static async createOrder(e, t, n, r, s, i, o, d) {
    var a, p;
    try {
      const { minAmountStart: h, minAmountFinish: m } = o.swapAmounts, A = w(n), [u, T] = g(e, t, r), [E, v] = g(e, n.chain, i), y = w(T), S = w(v), C = x.get(e, t).portico, I = x.get(e, n.chain).portico, F = P.get(e, t), N = P.get(e, n.chain), $ = {
        startingChainId: Number(F),
        startingToken: y.toLowerCase(),
        destinationChainId: Number(N),
        destinationToken: S.toLowerCase(),
        destinationAddress: A,
        porticoAddress: C,
        destinationPorticoAddress: I,
        startingTokenAmount: s.toString(),
        minAmountStart: h.toString(),
        minAmountEnd: m.toString(),
        bridgeNonce: d,
        relayerFee: o.relayerFee.toString(),
        feeTierStart: k,
        feeTierEnd: k,
        shouldWrapNative: u,
        shouldUnwrapNative: E
      }, W = await b.post(it, $);
      return this.validateCreateOrderResponse(W.data, $), W.data;
    } catch (h) {
      if (b.isAxiosError(h)) {
        const m = `${(a = h.response) == null ? void 0 : a.statusText}: ${(p = h.response) == null ? void 0 : p.data.message}`;
        throw new Error(`Could not create order: ${m},`);
      }
      throw h;
    }
  }
  static async quoteRelayer(e, t, n) {
    var d;
    if (D(t) || D(n))
      throw new Error("how did you get here tho?");
    const r = R.encode(t.toUniversalAddress().toUint8Array(), !1), s = R.encode(n.toUniversalAddress().toUint8Array(), !1), o = { targetChain: B(e), sourceToken: r, targetToken: s };
    try {
      const a = await b.post(ot, o);
      return BigInt(a.data.fee);
    } catch (a) {
      throw b.isAxiosError(a) ? new Error(`Error getting relayer fee: ${(d = a.response) == null ? void 0 : d.statusText}`) : a;
    }
  }
}
/**
 * Validates that the response from the order creation API matches the request
 * throws an error if there is a mismatch
 */
c(G, "validateCreateOrderResponse", (e, t) => {
  if (!f(t.porticoAddress || "", e.transactionTarget))
    throw new Error("portico address mismatch");
  const n = _.decodeFunctionData("start", e.transactionData);
  if (n.length !== 1 || n[0].length !== 10)
    throw new Error("decoded length mismatch");
  const r = R.decode(n[0][0]);
  if (r.length !== 32)
    throw new Error("flag set length mismatch");
  const { recipientChain: s, feeTierStart: i, feeTierFinish: o, flags: d } = j.deserializeFlagSet(r), { shouldWrapNative: a, shouldUnwrapNative: p } = d, [h, m] = K("Evm", BigInt(t.destinationChainId));
  if (s !== B(m))
    throw new Error("recipient chain mismatch");
  if (i !== t.feeTierStart)
    throw new Error("fee tier start mismatch");
  if (o !== t.feeTierEnd)
    throw new Error("fee tier end mismatch");
  if (!!a !== t.shouldWrapNative)
    throw new Error("should wrap native mismatch");
  if (!!p !== t.shouldUnwrapNative)
    throw new Error("should unwrap native mismatch");
  const A = n[0][1];
  if (!f(A, t.startingToken))
    throw new Error("start token address mismatch");
  const u = n[0][3];
  if (!f(u, t.destinationToken))
    throw new Error("final token address mismatch");
  const T = n[0][4];
  if (!f(T, t.destinationAddress))
    throw new Error("recipient address mismatch");
  const E = n[0][5];
  if (!f(E, t.destinationPorticoAddress || ""))
    throw new Error("destination portico address mismatch");
  if (n[0][6].toString() !== t.startingTokenAmount)
    throw new Error("amount mismatch");
  if (n[0][7].toString() !== t.minAmountStart)
    throw new Error("min amount start mismatch");
  if (n[0][8].toString() !== t.minAmountEnd)
    throw new Error("min amount finish mismatch");
  if (n[0][9].toString() !== t.relayerFee)
    throw new Error("relayer fee mismatch");
});
class L {
  constructor(e, t, n, r) {
    c(this, "network");
    c(this, "chain");
    c(this, "provider");
    c(this, "contracts");
    c(this, "chainId");
    c(this, "porticoAddress");
    c(this, "uniswapAddress");
    c(this, "porticoContract");
    c(this, "uniswapContract");
    c(this, "core");
    if (this.network = e, this.chain = t, this.provider = n, this.contracts = r, !r.portico)
      throw new Error("Unsupported chain, no contract addresses for: " + t);
    this.core = new Y(e, t, n, r);
    const { portico: s, uniswapQuoterV2: i } = r.portico;
    this.porticoAddress = s, this.uniswapAddress = i, this.chainId = P.get(e, t), this.porticoContract = new O(this.porticoAddress, _.fragments, this.provider), this.uniswapContract = new O(this.uniswapAddress, st.fragments, this.provider);
  }
  static async fromRpc(e, t) {
    const [n, r] = await z.chainFromRpc(e), s = t[r];
    if (s.network !== n)
      throw new Error(`Network mismatch: ${s.network} != ${n}`);
    return new L(n, r, e, s.contracts);
  }
  async *transfer(e, t, n, r, s, i) {
    const { minAmountStart: o, minAmountFinish: d } = i.swapAmounts;
    if (o === 0n)
      throw new Error("Invalid min swap amount");
    if (d === 0n)
      throw new Error("Invalid min swap amount");
    const a = new M(e).toString(), [p, h] = g(this.network, this.chain, n), [m, A] = g(this.network, t.chain, s), u = w(h), T = w(this.getTransferrableToken(u)), E = w(t), v = w(A), y = x.get(this.network, t.chain).portico, S = (/* @__PURE__ */ new Date()).valueOf() % 2 ** 4, C = j.serializeFlagSet({
      flags: {
        shouldWrapNative: p,
        shouldUnwrapNative: m
      },
      recipientChain: B(t.chain),
      bridgeNonce: S,
      feeTierStart: k,
      feeTierFinish: k,
      padding: new Uint8Array(19)
    }), I = _.encodeFunctionData("start", [
      [
        C,
        u.toLowerCase(),
        T,
        v.toLowerCase(),
        E,
        y,
        r.toString(),
        o.toString(),
        d.toString(),
        i.relayerFee.toString()
      ]
    ]);
    p || (yield* this.approve(u, a, r, this.porticoAddress));
    const F = await this.core.getMessageFee(), N = {
      to: this.porticoAddress,
      data: I,
      value: F + (p ? r : 0n)
    };
    yield this.createUnsignedTransaction(U(N, a), "PorticoBridge.Transfer");
  }
  async *redeem(e, t) {
    const n = await this.porticoContract.getFunction("receiveMessageAndSwap").populateTransaction(X(t)), r = new M(e).toString();
    yield this.createUnsignedTransaction(U(n, r), "PorticoBridge.Redeem");
  }
  async quoteSwap(e, t, n) {
    const [, r] = g(this.network, this.chain, e), [, s] = g(this.network, this.chain, t), i = w(r), o = w(s);
    return f(i, o) ? n : (await this.uniswapContract.getFunction("quoteExactInputSingle").staticCall([i, o, n, k, 0]))[0];
  }
  async quoteRelay(e, t) {
    return await G.quoteRelayer(this.chain, e, t);
  }
  // For a given token, return the corresponding
  // Wormhole wrapped token that originated on Ethereum
  getTransferrableToken(e) {
    var r;
    if (this.chain === "Ethereum")
      return Q.tokenId("Ethereum", e);
    const t = Z(this.network, this.chain, e);
    if (!t)
      throw new Error("Unsupported source token: " + e);
    const n = (r = q(this.network, this.chain, t.symbol)) == null ? void 0 : r.find((s) => s.original === "Ethereum");
    if (!n)
      throw new Error(`Unsupported symbol for chain ${t.symbol}: ${this.chain} `);
    return Q.tokenId(n.chain, n.address);
  }
  async *approve(e, t, n, r) {
    const s = z.getTokenImplementation(this.provider, e);
    if (await s.allowance(t, r) < n) {
      const o = await s.approve.populateTransaction(r, n);
      yield this.createUnsignedTransaction(U(o, t), "PorticoBridge.Approve");
    }
  }
  createUnsignedTransaction(e, t) {
    return new tt(et(e, this.chainId), this.network, this.chain, t, !1);
  }
}
nt(rt, "PorticoBridge", L);
export {
  L as EvmPorticoBridge
};
