import { HttpAgent as h } from "@dfinity/agent";
import { Principal as c } from "@dfinity/principal";
import * as p from "node:fs";
import m from "node:fs";
import { IcrcLedgerCanister as y } from "@dfinity/ledger-icrc";
import { Buffer as s } from "node:buffer";
import { Ed25519KeyIdentity as g } from "@dfinity/identity";
import { Secp256k1KeyIdentity as k } from "@dfinity/identity-secp256k1";
import i from "pem-file";
const u = {};
function l(r) {
  const e = i.decode(r);
  if (r.includes("EC PRIVATE KEY")) {
    if (e.length !== 118)
      throw new Error(
        `Invalid Secp256k1 key format: expecting byte length 118 but got ${e.length}`
      );
    return k.fromSecretKey(e.subarray(7, 39));
  }
  if (e.length !== 85)
    throw new Error(
      `Invalid Ed25519 key format: expecting byte length 85 but got ${e.length}`
    );
  const t = e.subarray(16, 48);
  return g.fromSecretKey(t);
}
const b = "aes-256-ctr";
function w(r, e) {
  const t = u.createHash("sha256").update(e).digest("base64").slice(0, 32), n = r.subarray(0, 16), o = r.subarray(16), a = u.createDecipheriv(b, t, n);
  return s.concat([a.update(o), a.final()]);
}
function C(r, e) {
  const t = s.from(r);
  if (r.includes("ENCRYPTED")) {
    if (!e)
      throw new Error("PEM file is encrypted, but no password was provided.");
    const n = w(i.decode(t), e), o = i.encode(n, "PRIVATE KEY");
    return l(s.from(o));
  }
  return l(t);
}
function A(r, e) {
  const t = m.readFileSync(r, "utf-8");
  return C(t, e);
}
function T(r) {
  if (r && typeof r == "object" && "errorType" in r) {
    const { errorType: e } = r, t = Object.keys(e)[0], n = e[t];
    switch (t) {
      case "InsufficientAllowance":
        return `Insufficient allowance: The user has not approved a large enough spending limit for this server. Current allowance: ${Number(n.allowance) / 1e8} tokens.`;
      case "InsufficientFunds":
        return `Insufficient funds: The user's wallet balance is too low. Current balance: ${Number(n.balance) / 1e8} tokens.`;
      case "BadFee":
        return `Bad fee: The transaction fee was incorrect. Expected: ${Number(n.expected_fee) / 1e8} tokens.`;
      case "Duplicate":
        return `Duplicate transaction: This transaction has already been processed. Duplicate of block: ${n.duplicate_of}.`;
      case "TemporarilyUnavailable":
        return "The ledger is temporarily unavailable. Please try again later.";
      case "TooOld":
        return "The transaction is too old to be processed.";
      default:
        return `An unknown ledger error occurred: ${JSON.stringify(e)}`;
    }
  }
  return r instanceof Error ? r.message : "An unknown error occurred.";
}
class R {
  agent;
  payoutPrincipal;
  tokenConfigPath;
  tokenInfoCache = null;
  /**
   * Creates an instance of the PrometheusServerClient.
   * @param config The configuration for the client.
   */
  constructor(e) {
    const t = e.host ?? "https://icp-api.io", n = e.fetchRootKey ?? (t.includes("localhost") || t.includes("127.0.0.1"));
    this.agent = new h({
      host: t,
      identity: e.identity,
      shouldFetchRootKey: n
    }), this.payoutPrincipal = e.payoutPrincipal, this.tokenConfigPath = e.tokenConfigPath;
  }
  /**
   * A private helper to lazily load token info from the local config file.
   */
  async getSupportedTokens() {
    if (this.tokenInfoCache !== null)
      return this.tokenInfoCache;
    try {
      const e = p.readFileSync(this.tokenConfigPath, "utf-8"), t = JSON.parse(e);
      if (t.length === 0)
        throw new Error("Token configuration file is empty.");
      return this.tokenInfoCache = t, this.tokenInfoCache;
    } catch {
      throw console.error(
        `Failed to load or parse token metadata from ${this.tokenConfigPath}.`
      ), new Error(
        `Configuration error: Please ensure '${this.tokenConfigPath}' exists and is valid. Run 'npx prometheus-cli' if needed.`
      );
    }
  }
  /**
   * Charges a user by executing an `icrc2_transfer_from` call.
   * This method automatically uses the first payment token configured in the
   * prometheus-tokens.json file and handles the conversion from a token amount
   * to the correct number of e8s based on the token's decimals.
   *
   * @param options An object containing the details of the charge.
   * @returns A promise that resolves to a result object indicating the outcome of the charge.
   */
  async charge(e) {
    try {
      const n = (await this.getSupportedTokens())[0], o = y.create({
        agent: this.agent,
        canisterId: c.fromText(n.canister_id)
      }), a = typeof e.userToCharge == "string" ? c.fromText(e.userToCharge) : e.userToCharge, f = BigInt(
        Math.round(e.amount * 10 ** n.decimals)
      ), d = {
        from: { owner: a, subaccount: [] },
        to: { owner: this.payoutPrincipal, subaccount: [] },
        amount: f
      };
      return { ok: !0, blockIndex: await o.transferFrom(d) };
    } catch (t) {
      const n = T(t);
      return console.error("Charge operation failed:", n), { ok: !1, error: n };
    }
  }
}
export {
  R as PrometheusServerClient,
  A as identityFromPem
};
//# sourceMappingURL=server.js.map
