var S = Object.defineProperty;
var x = (i, t, e) => t in i ? S(i, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : i[t] = e;
var m = (i, t, e) => x(i, typeof t != "symbol" ? t + "" : t, e);
import { am as I, an as R, ae as y, e as _, ao as A, ap as M, aq as L, ar as U, af as O, ah as w, r as C } from "./index-6NRj6D5S.mjs";
const F = 0.5, b = 1, E = 1, T = 1e8, k = 5, D = 25e4;
async function N(i, t, e) {
  const [s, r] = await _.chainFromRpc(i), n = typeof t == "string" ? A.fromSecretKey(M.decode(t)) : t;
  if (e != null && e.priorityFee && e.priorityFee.percentile && e.priorityFee.percentile > 1)
    throw new Error("priorityFeePercentile must be a number between 0 and 1");
  return new K(i, r, n, (e == null ? void 0 : e.debug) ?? !1, (e == null ? void 0 : e.priorityFee) ?? {}, (e == null ? void 0 : e.retries) ?? k, e == null ? void 0 : e.sendOpts);
}
class K {
  constructor(t, e, s, r = !1, n, o = k, u) {
    m(this, "_rpc");
    m(this, "_chain");
    m(this, "_keypair");
    m(this, "_debug");
    m(this, "_priorityFee");
    m(this, "_maxResubmits");
    m(this, "_sendOpts");
    this._rpc = t, this._chain = e, this._keypair = s, this._debug = r, this._priorityFee = n, this._maxResubmits = o, this._sendOpts = u, this._sendOpts = this._sendOpts ?? {
      preflightCommitment: this._rpc.commitment
    };
  }
  chain() {
    return this._chain;
  }
  address() {
    return this._keypair.publicKey.toBase58();
  }
  // Handles retrying a Transaction if the error is deemed to be
  // recoverable. Currently handles:
  // - Transaction expired
  // - Blockhash not found
  // - Not enough bytes (storage account not seen yet)
  retryable(t) {
    var s;
    if (t instanceof L)
      return !0;
    if (!(t instanceof U) || !t.message.includes("Transaction simulation failed"))
      return !1;
    if (t.message.includes("Blockhash not found"))
      return !0;
    const e = (s = t.logs) == null ? void 0 : s.find((r) => r.startsWith("Program log: Error: "));
    return e ? !!(e.includes("Not enough bytes") || e.includes("Unexpected length of input")) : !1;
  }
  async signAndSend(t) {
    var u;
    let { blockhash: e, lastValidBlockHeight: s } = await _.latestBlock(this._rpc);
    const r = [];
    for (const c of t) {
      const { description: g, transaction: { transaction: a, signers: l } } = c;
      this._debug && console.log(`Signing: ${g} for ${this.address()}`);
      let h;
      (u = this._priorityFee) != null && u.percentile && this._priorityFee.percentile > 0 && (h = await z(this._rpc, a, this._priorityFee.percentile, this._priorityFee.percentileMultiple, this._priorityFee.min, this._priorityFee.max)), this._debug && W(a);
      for (let d = 0; d < this._maxResubmits; d++)
        try {
          if (y(a)) {
            if (h && d === 0) {
              const p = O.decompile(a.message);
              p.instructions.push(...h), a.message = p.compileToV0Message();
            }
            a.message.recentBlockhash = e, a.sign([this._keypair, ...l ?? []]);
          } else
            h && d === 0 && a.add(...h), a.recentBlockhash = e, a.lastValidBlockHeight = s, a.partialSign(this._keypair, ...l ?? []);
          this._debug && console.log("Submitting transactions ");
          const { signature: f } = await _.sendTxWithRetry(this._rpc, a.serialize(), this._sendOpts);
          r.push(f);
          break;
        } catch (f) {
          if (d === this._maxResubmits - 1 || !this.retryable(f))
            throw f;
          this._debug && console.log(`Failed to send transaction on attempt ${d}, retrying: `, f);
          const { blockhash: p, lastValidBlockHeight: P } = await _.latestBlock(this._rpc);
          s = P, e = p;
        }
    }
    this._debug && console.log("Waiting for confirmation for: ", r);
    const o = (await Promise.all(r.map(async (c) => {
      try {
        return await this._rpc.confirmTransaction({
          signature: c,
          blockhash: e,
          lastValidBlockHeight: s
        }, this._rpc.commitment);
      } catch (g) {
        throw console.error("Failed to confirm transaction: ", g), g;
      }
    }))).filter((c) => c.value.err).map((c) => c.value.err);
    if (o.length > 0)
      throw new Error(`Failed to confirm transaction: ${o}`);
    return r;
  }
}
function W(i) {
  if (y(i)) {
    console.log(i.signatures);
    const t = i.message, e = t.getAccountKeys();
    t.compiledInstructions.forEach((s) => {
      console.log("Program", e.get(s.programIdIndex).toBase58()), console.log("Data: ", C.encode(s.data)), console.log("Keys: ", s.accountKeyIndexes.map((r) => [r, e.get(r).toBase58()]));
    });
  } else
    console.log(i.signatures), console.log(i.feePayer), i.instructions.forEach((t) => {
      console.log("Program", t.programId.toBase58()), console.log("Data: ", t.data.toString("hex")), console.log("Keys: ", t.keys.map((e) => [e, e.pubkey.toBase58()]));
    });
}
async function z(i, t, e = F, s = b, r = E, n = T) {
  const [o, u] = await Promise.all([
    $(i, t),
    v(i, t, e, s, r, n)
  ]);
  return [
    w.setComputeUnitLimit({
      units: o
    }),
    w.setComputeUnitPrice({
      microLamports: u
    })
  ];
}
async function $(i, t) {
  var s;
  let e = D;
  try {
    const r = await (y(t), i.simulateTransaction(t));
    r.value.err && console.error(`Error simulating Solana transaction: ${r.value.err}`), (s = r == null ? void 0 : r.value) != null && s.unitsConsumed && (e = Math.round(r.value.unitsConsumed * 1.2));
  } catch (r) {
    console.error(`Failed to calculate compute unit limit for Solana transaction: ${r}`);
  }
  return e;
}
async function B(i, t) {
  if (y(t)) {
    const e = (await Promise.all(t.message.addressTableLookups.map((n) => i.getAddressLookupTable(n.accountKey)))).map((n) => n.value).filter((n) => n !== null), s = t.message, r = s.getAccountKeys({
      addressLookupTableAccounts: e ?? void 0
    });
    return s.compiledInstructions.flatMap((n) => n.accountKeyIndexes).map((n) => s.isAccountWritable(n) ? r.get(n) : null).filter(Boolean);
  } else
    return t.instructions.flatMap((e) => e.keys).map((e) => e.isWritable ? e.pubkey : null).filter(Boolean);
}
async function v(i, t, e = F, s = b, r = E, n = T) {
  let o = r;
  const u = await B(i, t);
  try {
    const c = await i.getRecentPrioritizationFees({
      lockedWritableAccounts: u
    });
    if (c) {
      const g = c.map((l) => l.prioritizationFee).sort((l, h) => l - h), a = Math.ceil(g.length * e);
      if (g.length > a) {
        let l = g[a];
        s > 0 && (l *= s), o = Math.max(o, l);
      }
    }
  } catch (c) {
    console.error("Error fetching Solana recent fees", c);
  }
  return Math.min(Math.max(o, r), n);
}
async function q(i, t, e = F, s = b, r = E, n = T) {
  const o = e * 1e4;
  if (o < 1 || o > 1e4)
    throw new Error("percentile must be between 0.0001 and 1");
  const u = i._rpcRequest, g = [
    await B(i, t),
    {
      percentile: o
    }
  ], a = await u("getRecentPrioritizationFees", g);
  if (a.error)
    throw new Error(a.error);
  const l = a.result.map((d) => d.prioritizationFee);
  if (l.length === 0)
    return r;
  const h = Math.floor(I(l) * (s > 0 ? s : 1));
  return R(h, r, n);
}
export {
  v as a,
  q as d,
  N as g
};
