import '@mysten/sui/jsonRpc';
import { normalizeSuiAddress, isValidSuiAddress } from '@mysten/sui/utils';
import { AggregatorClient, Env } from '@cetusprotocol/aggregator-sdk';
import 'bn.js';

var __defProp = Object.defineProperty;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __esm = (fn, res) => function __init() {
  return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
};
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};

// src/errors.ts
var errors_exports = {};
__export(errors_exports, {
  T2000Error: () => T2000Error,
  isMoveAbort: () => isMoveAbort,
  mapMoveAbortCode: () => mapMoveAbortCode,
  mapWalletError: () => mapWalletError,
  parseMoveAbortMessage: () => parseMoveAbortMessage
});
function mapWalletError(error) {
  const msg = error instanceof Error ? error.message : String(error);
  if (msg.includes("rejected") || msg.includes("cancelled")) {
    return new T2000Error("TRANSACTION_FAILED", "Transaction cancelled");
  }
  if (msg.includes("Insufficient") || msg.includes("insufficient")) {
    return new T2000Error("INSUFFICIENT_BALANCE", "Insufficient balance");
  }
  return new T2000Error("UNKNOWN", msg, void 0, true);
}
function mapMoveAbortCode(code) {
  const abortMessages = {
    1: "Protocol is temporarily paused",
    2: "Amount must be greater than zero",
    3: "Invalid operation type",
    4: "Fee rate exceeds maximum",
    5: "Insufficient treasury balance",
    6: "Not authorized",
    7: "Package version mismatch \u2014 upgrade required",
    8: "Timelock is active \u2014 wait for expiry",
    9: "No pending change to execute",
    10: "Already at current version",
    // NAVI Protocol abort codes
    1502: "Oracle price is stale \u2014 try again in a moment",
    1503: 'Withdrawal amount is invalid (zero or dust) \u2014 try a specific amount instead of "all"',
    1600: "Health factor too low \u2014 withdrawal would risk liquidation",
    1605: "Asset borrowing is disabled or at capacity on this protocol",
    // NAVI utils abort codes
    46e3: "Insufficient balance to repay \u2014 withdraw some savings first to get cash"
  };
  return abortMessages[code] ?? `Move abort code: ${code}`;
}
function isMoveAbort(msg) {
  return msg.includes("MoveAbort") || msg.includes("MovePrimitiveRuntimeError");
}
function parseMoveAbortMessage(msg) {
  const abortMatch = msg.match(/abort code:\s*(\d+)/i) ?? msg.match(/MoveAbort[^,]*,\s*(\d+)/);
  if (abortMatch) {
    const code = parseInt(abortMatch[1], 10);
    const moduleMatch = msg.match(/Identifier\("([^"]+)"\)/) ?? msg.match(/in '([^']+)'/);
    const fnMatch = msg.match(/function_name:\s*Some\("([^"]+)"\)/);
    const context = `${moduleMatch?.[1] ?? ""}${fnMatch ? `::${fnMatch[1]}` : ""}`.toLowerCase();
    const suffix = moduleMatch ? ` [${moduleMatch[1]}${fnMatch ? `::${fnMatch[1]}` : ""}]` : "";
    if (context.includes("slippage")) {
      return `Slippage too high \u2014 price moved during execution${suffix}`;
    }
    if (context.includes("balance::split") || context.includes("balance::ENotEnough")) {
      return `Insufficient on-chain balance${suffix}`;
    }
    const mapped = mapMoveAbortCode(code);
    return `${mapped}${suffix}`;
  }
  return msg;
}
var T2000Error;
var init_errors = __esm({
  "src/errors.ts"() {
    T2000Error = class extends Error {
      code;
      data;
      retryable;
      constructor(code, message, data, retryable = false) {
        super(message);
        this.name = "T2000Error";
        this.code = code;
        this.data = data;
        this.retryable = retryable;
      }
      toJSON() {
        return {
          error: this.code,
          message: this.message,
          ...this.data && { data: this.data },
          retryable: this.retryable
        };
      }
    };
  }
});

// src/token-registry.ts
function isTier1(coinType) {
  const meta = BY_TYPE.get(coinType);
  return meta?.tier === 1;
}
function isTier2(coinType) {
  const meta = BY_TYPE.get(coinType);
  return meta?.tier === 2;
}
function isSupported(coinType) {
  const meta = BY_TYPE.get(coinType);
  return meta?.tier !== void 0;
}
function getTier(coinType) {
  return BY_TYPE.get(coinType)?.tier;
}
function getDecimalsForCoinType(coinType) {
  const direct = BY_TYPE.get(coinType);
  if (direct) return direct.decimals;
  const suffix = coinType.split("::").slice(1).join("::").toUpperCase();
  if (suffix) {
    for (const meta of BY_TYPE.values()) {
      const metaSuffix = meta.type.split("::").slice(1).join("::").toUpperCase();
      if (metaSuffix === suffix) return meta.decimals;
    }
  }
  return 9;
}
function resolveSymbol(coinType) {
  const direct = BY_TYPE.get(coinType);
  if (direct) return direct.symbol;
  const suffix = coinType.split("::").slice(1).join("::").toUpperCase();
  if (suffix) {
    for (const meta of BY_TYPE.values()) {
      const metaSuffix = meta.type.split("::").slice(1).join("::").toUpperCase();
      if (metaSuffix === suffix) return meta.symbol;
    }
  }
  return coinType.split("::").pop() ?? coinType;
}
function resolveTokenType(nameOrType) {
  if (nameOrType.includes("::")) return nameOrType;
  return TOKEN_MAP[nameOrType] ?? TOKEN_MAP[nameOrType.toUpperCase()] ?? null;
}
var COIN_REGISTRY, BY_TYPE, TOKEN_MAP, SUI_TYPE, USDC_TYPE, USDT_TYPE, USDSUI_TYPE, USDE_TYPE, ETH_TYPE, WBTC_TYPE, WAL_TYPE, NAVX_TYPE, IKA_TYPE, LOFI_TYPE, MANIFEST_TYPE;
var init_token_registry = __esm({
  "src/token-registry.ts"() {
    COIN_REGISTRY = {
      // ── Tier 1 — Financial layer ──────────────────────────────────────────
      USDC: { type: "0xdba34672e30cb065b1f93e3ab55318768fd6fef66c15942c9f7cb846e2f900e7::usdc::USDC", decimals: 6, symbol: "USDC", tier: 1 },
      // ── Tier 2 — Swap assets (15 tokens) ──────────────────────────────────
      SUI: { type: "0x2::sui::SUI", decimals: 9, symbol: "SUI", tier: 2 },
      wBTC: { type: "0x0041f9f9344cac094454cd574e333c4fdb132d7bcc9379bcd4aab485b2a63942::wbtc::WBTC", decimals: 8, symbol: "wBTC", tier: 2 },
      ETH: { type: "0xd0e89b2af5e4910726fbcd8b8dd37bb79b29e5f83f7491bca830e94f7f226d29::eth::ETH", decimals: 8, symbol: "ETH", tier: 2 },
      GOLD: { type: "0x9d297676e7a4b771ab023291377b2adfaa4938fb9080b8d12430e4b108b836a9::xaum::XAUM", decimals: 9, symbol: "GOLD", tier: 2 },
      DEEP: { type: "0xdeeb7a4662eec9f2f3def03fb937a663dddaa2e215b8078a284d026b7946c270::deep::DEEP", decimals: 6, symbol: "DEEP", tier: 2 },
      WAL: { type: "0x356a26eb9e012a68958082340d4c4116e7f55615cf27affcff209cf0ae544f59::wal::WAL", decimals: 9, symbol: "WAL", tier: 2 },
      NS: { type: "0x5145494a5f5100e645e4b0aa950fa6b68f614e8c59e17bc5ded3495123a79178::ns::NS", decimals: 6, symbol: "NS", tier: 2 },
      IKA: { type: "0x7262fb2f7a3a14c888c438a3cd9b912469a58cf60f367352c46584262e8299aa::ika::IKA", decimals: 9, symbol: "IKA", tier: 2 },
      CETUS: { type: "0x06864a6f921804860930db6ddbe2e16acdf8504495ea7481637a1c8b9a8fe54b::cetus::CETUS", decimals: 9, symbol: "CETUS", tier: 2 },
      NAVX: { type: "0xa99b8952d4f7d947ea77fe0ecdcc9e5fc0bcab2841d6e2a5aa00c3044e5544b5::navx::NAVX", decimals: 9, symbol: "NAVX", tier: 2 },
      vSUI: { type: "0x549e8b69270defbfafd4f94e17ec44cdbdd99820b33bda2278dea3b9a32d3f55::cert::CERT", decimals: 9, symbol: "vSUI", tier: 2 },
      haSUI: { type: "0xbde4ba4c2e274a60ce15c1cfff9e5c42e41654ac8b6d906a57efa4bd3c29f47d::hasui::HASUI", decimals: 9, symbol: "haSUI", tier: 2 },
      afSUI: { type: "0xf325ce1300e8dac124071d3152c5c5ee6174914f8bc2161e88329cf579246efc::afsui::AFSUI", decimals: 9, symbol: "afSUI", tier: 2 },
      LOFI: { type: "0xf22da9a24ad027cccb5f2d496cbe91de953d363513db08a3a734d361c7c17503::LOFI::LOFI", decimals: 9, symbol: "LOFI", tier: 2 },
      MANIFEST: { type: "0xc466c28d87b3d5cd34f3d5c088751532d71a38d93a8aae4551dd56272cfb4355::manifest::MANIFEST", decimals: 9, symbol: "MANIFEST", tier: 2 },
      // ── Legacy — no tier, kept for display accuracy on existing positions ──
      USDT: { type: "0x375f70cf2ae4c00bf37117d0c85a2c71545e6ee05c4a5c7d282cd66a4504b068::usdt::USDT", decimals: 6, symbol: "USDT" },
      USDe: { type: "0x41d587e5336f1c86cad50d38a7136db99333bb9bda91cea4ba69115defeb1402::sui_usde::SUI_USDE", decimals: 6, symbol: "USDe" },
      USDSUI: { type: "0x44f838219cf67b058f3b37907b655f226153c18e33dfcd0da559a844fea9b1c1::usdsui::USDSUI", decimals: 6, symbol: "USDsui" }
    };
    BY_TYPE = /* @__PURE__ */ new Map();
    for (const meta of Object.values(COIN_REGISTRY)) {
      BY_TYPE.set(meta.type, meta);
    }
    TOKEN_MAP = (() => {
      const map = {};
      for (const [name, meta] of Object.entries(COIN_REGISTRY)) {
        map[name] = meta.type;
        map[name.toUpperCase()] = meta.type;
      }
      return map;
    })();
    SUI_TYPE = COIN_REGISTRY.SUI.type;
    USDC_TYPE = COIN_REGISTRY.USDC.type;
    USDT_TYPE = COIN_REGISTRY.USDT.type;
    USDSUI_TYPE = COIN_REGISTRY.USDSUI.type;
    USDE_TYPE = COIN_REGISTRY.USDe.type;
    ETH_TYPE = COIN_REGISTRY.ETH.type;
    WBTC_TYPE = COIN_REGISTRY.wBTC.type;
    WAL_TYPE = COIN_REGISTRY.WAL.type;
    NAVX_TYPE = COIN_REGISTRY.NAVX.type;
    IKA_TYPE = COIN_REGISTRY.IKA.type;
    LOFI_TYPE = COIN_REGISTRY.LOFI.type;
    MANIFEST_TYPE = COIN_REGISTRY.MANIFEST.type;
  }
});

// src/wallet/keypairSigner.ts
var KeypairSigner = class {
  constructor(keypair) {
    this.keypair = keypair;
  }
  getAddress() {
    return this.keypair.getPublicKey().toSuiAddress();
  }
  async signTransaction(txBytes) {
    return this.keypair.signTransaction(txBytes);
  }
  /** Access the underlying keypair for APIs that still require it directly. */
  getKeypair() {
    return this.keypair;
  }
};

// src/wallet/zkLoginSigner.ts
var ZkLoginSigner = class {
  constructor(ephemeralKeypair, zkProof, userAddress, maxEpoch) {
    this.ephemeralKeypair = ephemeralKeypair;
    this.zkProof = zkProof;
    this.userAddress = userAddress;
    this.maxEpoch = maxEpoch;
  }
  getAddress() {
    return this.userAddress;
  }
  async signTransaction(txBytes) {
    const { getZkLoginSignature } = await import('@mysten/zklogin');
    const ephSig = await this.ephemeralKeypair.signTransaction(txBytes);
    return {
      signature: getZkLoginSignature({
        inputs: this.zkProof,
        maxEpoch: this.maxEpoch,
        userSignature: ephSig.signature
      })
    };
  }
  isExpired(currentEpoch) {
    return currentEpoch >= this.maxEpoch;
  }
};

// src/browser.ts
init_errors();

// src/constants.ts
init_errors();
var MIST_PER_SUI = 1000000000n;
var SUI_DECIMALS = 9;
var USDC_DECIMALS = 6;
var BPS_DENOMINATOR = 10000n;
var SAVE_FEE_BPS = 10n;
var BORROW_FEE_BPS = 5n;
var CLOCK_ID = "0x6";
var SUPPORTED_ASSETS = {
  USDC: {
    type: "0xdba34672e30cb065b1f93e3ab55318768fd6fef66c15942c9f7cb846e2f900e7::usdc::USDC",
    decimals: 6,
    symbol: "USDC",
    displayName: "USDC"
  },
  USDT: {
    type: "0x375f70cf2ae4c00bf37117d0c85a2c71545e6ee05c4a5c7d282cd66a4504b068::usdt::USDT",
    decimals: 6,
    symbol: "USDT",
    displayName: "suiUSDT"
  },
  USDe: {
    type: "0x41d587e5336f1c86cad50d38a7136db99333bb9bda91cea4ba69115defeb1402::sui_usde::SUI_USDE",
    decimals: 6,
    symbol: "USDe",
    displayName: "suiUSDe"
  },
  USDsui: {
    type: "0x44f838219cf67b058f3b37907b655f226153c18e33dfcd0da559a844fea9b1c1::usdsui::USDSUI",
    decimals: 6,
    symbol: "USDsui",
    displayName: "USDsui"
  },
  SUI: {
    type: "0x2::sui::SUI",
    decimals: 9,
    symbol: "SUI",
    displayName: "SUI"
  },
  WAL: {
    type: "0x356a26eb9e012a68958082340d4c4116e7f55615cf27affcff209cf0ae544f59::wal::WAL",
    decimals: 9,
    symbol: "WAL",
    displayName: "WAL"
  },
  ETH: {
    type: "0xd0e89b2af5e4910726fbcd8b8dd37bb79b29e5f83f7491bca830e94f7f226d29::eth::ETH",
    decimals: 8,
    symbol: "ETH",
    displayName: "suiETH"
  },
  NAVX: {
    type: "0xa99b8952d4f7d947ea77fe0ecdcc9e5fc0bcab2841d6e2a5aa00c3044e5544b5::navx::NAVX",
    decimals: 9,
    symbol: "NAVX",
    displayName: "NAVX"
  },
  GOLD: {
    type: "0x9d297676e7a4b771ab023291377b2adfaa4938fb9080b8d12430e4b108b836a9::xaum::XAUM",
    decimals: 6,
    symbol: "GOLD",
    displayName: "XAUM"
  }
};
var STABLE_ASSETS = ["USDC"];
var ALL_NAVI_ASSETS = Object.keys(SUPPORTED_ASSETS);
var T2000_OVERLAY_FEE_WALLET = process.env.T2000_OVERLAY_FEE_WALLET ?? "0x5366efbf2b4fe5767fe2e78eb197aa5f5d138d88ac3333fbf3f80a1927da473a";
var DEFAULT_NETWORK = "mainnet";
process.env.T2000_API_URL ?? "https://api.t2000.ai";
var GAS_RESERVE_MIN = 0.05;
init_errors();
function validateAddress(address) {
  const normalized = normalizeSuiAddress(address);
  if (!isValidSuiAddress(normalized)) {
    throw new T2000Error("INVALID_ADDRESS", `Invalid Sui address: ${address}`);
  }
  return normalized;
}
function truncateAddress(address) {
  if (address.length <= 10) return address;
  return `${address.slice(0, 6)}...${address.slice(-4)}`;
}

// src/wallet/classify.ts
init_token_registry();
var KNOWN_TARGETS = [
  [/::suilend|::obligation/, "lending"],
  [/::navi|::lending_core|::incentive_v\d+|::oracle_pro/, "lending"],
  /**
   * DEX modules — both direct calls and aggregator legs. The Cetus
   * aggregator dispatches through a per-DEX module (e.g.
   * `cetus::swap`, `flowx_amm::swap`, `aftermath::swap`, …) plus
   * router glue functions. We list every DEX module the aggregator
   * supports today so a single-DEX call still classifies cleanly.
   */
  [/::cetus(?:_dlmm)?::|::pool::|::deepbook|::flowx_(?:amm|clmm)::|::kriya_(?:amm|clmm)::|::turbos::|::aftermath::|::afsui::|::bluefin::|::bluemove::|::ferra_(?:clmm|dlmm)::|::haedal_hmm::|::hasui::|::hawal::|::magma::|::momentum::|::obric::|::springsui::|::steamm_cpmm::|::fullsail::|::alphafi::|::volo_swap::/, "swap"],
  /**
   * Cetus aggregator router glue. These are the swap-context and
   * balance-handling helpers the aggregator emits around per-DEX
   * legs. Without this entry a tx that ONLY had router calls
   * (theoretically possible for setup/cleanup) would slip through;
   * in practice these always coexist with a DEX leg, but the entry
   * is cheap insurance.
   */
  [/::router::(?:new_swap_context(?:_v)?|confirm_swap|transfer_balance|take_balance|transfer_or_destroy_coin)/, "swap"],
  [/::transfer::public_transfer/, "send"]
];
var LABEL_PATTERNS = [
  [/::pay(?:ment_kit|_kit)?::|::create_payment_link|::pay_link/, "payment_link"],
  [/::create_invoice|::invoice::/, "invoice"],
  [/::deposit|::supply|::mint_ctokens/, "deposit"],
  [/::withdraw|::redeem|::redeem_ctokens/, "withdraw"],
  [/::borrow/, "borrow"],
  [/::repay/, "repay"],
  [/::claim_reward|::claim::|::claim_incentive/, "claim"],
  [/::stake/, "stake"],
  [/::unstake|::burn::/, "unstake"],
  [/::liquidate/, "liquidate"]
];
function resolveOwner(owner) {
  if (typeof owner === "object" && owner.AddressOwner) return owner.AddressOwner;
  if (typeof owner === "string") return owner;
  return null;
}
function classifyAction(targets, commandTypes) {
  for (const target of targets) {
    for (const [pattern, label] of KNOWN_TARGETS) {
      if (pattern.test(target)) return label;
    }
  }
  if (commandTypes.includes("TransferObjects") && !commandTypes.includes("MoveCall")) return "send";
  return "transaction";
}
function fallbackLabel(targets) {
  if (!targets.length) return "on-chain";
  const first = targets[0];
  const parts = first.split("::");
  if (parts.length >= 2 && parts[1]) return parts[1].toLowerCase();
  return "on-chain";
}
function classifyLabel(targets, commandTypes) {
  for (const target of targets) {
    for (const [pattern, label] of LABEL_PATTERNS) {
      if (pattern.test(target)) return label;
    }
  }
  if (commandTypes.includes("TransferObjects") && !commandTypes.includes("MoveCall")) return "send";
  const action = classifyAction(targets, commandTypes);
  if (action !== "transaction") return action;
  return fallbackLabel(targets);
}
function refineLendingLabel(currentAction, currentLabel, moveCallTargets, changes, address) {
  if (currentAction !== "lending") return currentLabel;
  const labelMatchedSpecific = LABEL_PATTERNS.some(
    ([p]) => moveCallTargets.some((t) => p.test(t))
  );
  if (labelMatchedSpecific) return currentLabel;
  const userNonSuiOutflow = changes.find(
    (c) => resolveOwner(c.owner) === address && c.coinType !== SUI_TYPE && BigInt(c.amount) < 0n
  );
  if (userNonSuiOutflow) return "deposit";
  const userNonSuiInflow = changes.find(
    (c) => resolveOwner(c.owner) === address && c.coinType !== SUI_TYPE && BigInt(c.amount) > 0n
  );
  if (userNonSuiInflow) return "withdraw";
  return currentLabel;
}
function classifyTransaction(moveCallTargets, commandTypes, balanceChanges, address) {
  const action = classifyAction(moveCallTargets, commandTypes);
  const baseLabel = classifyLabel(moveCallTargets, commandTypes);
  const label = refineLendingLabel(action, baseLabel, moveCallTargets, balanceChanges, address);
  return { action, label };
}
function extractTransferDetails(changes, sender) {
  if (!changes || changes.length === 0) return {};
  const userChanges = changes.filter((c) => resolveOwner(c.owner) === sender);
  if (userChanges.length === 0) return {};
  const userNonSui = userChanges.filter((c) => c.coinType !== SUI_TYPE);
  const pool = userNonSui.length > 0 ? userNonSui : userChanges;
  let primary = pool[0];
  let primaryAbs = bigintAbs(BigInt(primary.amount));
  for (let i = 1; i < pool.length; i++) {
    const abs = bigintAbs(BigInt(pool[i].amount));
    if (abs > primaryAbs) {
      primary = pool[i];
      primaryAbs = abs;
    }
  }
  const raw = BigInt(primary.amount);
  if (raw === 0n) return {};
  const decimals = getDecimalsForCoinType(primary.coinType);
  const amount = Number(primaryAbs) / 10 ** decimals;
  const asset = resolveSymbol(primary.coinType);
  const direction = raw < 0n ? "out" : "in";
  let recipient;
  if (direction === "out") {
    const recipientChange = changes.find(
      (c) => resolveOwner(c.owner) !== sender && c.coinType === primary.coinType && BigInt(c.amount) > 0n
    );
    recipient = recipientChange ? resolveOwner(recipientChange.owner) ?? void 0 : void 0;
  }
  return { amount, asset, recipient, direction };
}
function bigintAbs(n) {
  return n < 0n ? -n : n;
}
function extractAllUserLegs(changes, sender) {
  if (!changes || changes.length === 0) return [];
  const legs = [];
  for (const c of changes) {
    if (resolveOwner(c.owner) !== sender) continue;
    const raw = BigInt(c.amount);
    if (raw === 0n) continue;
    const decimals = getDecimalsForCoinType(c.coinType);
    const absAmount = bigintAbs(raw);
    legs.push({
      coinType: c.coinType,
      asset: resolveSymbol(c.coinType),
      decimals,
      amount: Number(absAmount) / 10 ** decimals,
      rawAmount: raw.toString(),
      direction: raw < 0n ? "out" : "in"
    });
  }
  return legs;
}

// src/wallet/history.ts
function parseSuiRpcTx(tx, address) {
  return parseTxRecord(tx, address);
}
function extractTxSender(txBlock) {
  try {
    if (!txBlock || typeof txBlock !== "object") return null;
    const data = "data" in txBlock ? txBlock.data : void 0;
    if (!data || typeof data !== "object") return null;
    return data.sender ?? null;
  } catch {
    return null;
  }
}
function extractTxCommands(txBlock) {
  return extractCommands(txBlock);
}
function parseTxRecord(tx, address) {
  const gasUsed = tx.effects?.gasUsed;
  const gasCost = gasUsed ? (Number(gasUsed.computationCost) + Number(gasUsed.storageCost) - Number(gasUsed.storageRebate)) / 1e9 : void 0;
  const { moveCallTargets, commandTypes } = extractCommands(tx.transaction);
  const balanceChanges = tx.balanceChanges ?? [];
  const legs = extractAllUserLegs(balanceChanges, address);
  const { amount, asset, recipient, direction } = extractTransferDetails(balanceChanges, address);
  const { action, label } = classifyTransaction(
    moveCallTargets,
    commandTypes,
    balanceChanges,
    address
  );
  return {
    digest: tx.digest,
    action,
    label,
    legs,
    amount,
    asset,
    recipient,
    direction,
    timestamp: Number(tx.timestampMs ?? 0),
    gasCost
  };
}
function extractCommands(txBlock) {
  const result = { moveCallTargets: [], commandTypes: [] };
  try {
    if (!txBlock || typeof txBlock !== "object") return result;
    const data = "data" in txBlock ? txBlock.data : void 0;
    if (!data || typeof data !== "object") return result;
    const inner = "transaction" in data ? data.transaction : void 0;
    if (!inner || typeof inner !== "object") return result;
    const commands = "commands" in inner ? inner.commands : "transactions" in inner ? inner.transactions : void 0;
    if (!Array.isArray(commands)) return result;
    for (const cmd of commands) {
      if (cmd.MoveCall) {
        const mc = cmd.MoveCall;
        result.moveCallTargets.push(`${mc.package}::${mc.module}::${mc.function}`);
        result.commandTypes.push("MoveCall");
      } else if (cmd.TransferObjects) {
        result.commandTypes.push("TransferObjects");
      }
    }
  } catch {
  }
  return result;
}

// src/utils/format.ts
function mistToSui(mist) {
  return Number(mist) / Number(MIST_PER_SUI);
}
function suiToMist(sui) {
  return BigInt(Math.round(sui * Number(MIST_PER_SUI)));
}
function usdcToRaw(amount) {
  return BigInt(Math.round(amount * 10 ** USDC_DECIMALS));
}
function rawToUsdc(raw) {
  return Number(raw) / 10 ** USDC_DECIMALS;
}
function stableToRaw(amount, decimals) {
  return BigInt(Math.round(amount * 10 ** decimals));
}
function rawToStable(raw, decimals) {
  return Number(raw) / 10 ** decimals;
}
function getDecimals(asset) {
  return SUPPORTED_ASSETS[asset].decimals;
}
function formatUsd(amount) {
  return `$${amount.toFixed(2)}`;
}
function formatSui(amount) {
  if (amount < 1e-3) return `${amount.toFixed(6)} SUI`;
  return `${amount.toFixed(3)} SUI`;
}
function formatAssetAmount(amount, asset) {
  if (asset === "BTC") return amount.toFixed(8);
  if (asset === "GOLD") return amount.toFixed(6);
  if (asset === "ETH") return amount.toFixed(6);
  return amount.toFixed(4);
}
var ASSET_LOOKUP = /* @__PURE__ */ new Map();
for (const [key, info] of Object.entries(SUPPORTED_ASSETS)) {
  ASSET_LOOKUP.set(key.toUpperCase(), key);
  if (info.displayName && info.displayName.toUpperCase() !== key.toUpperCase()) {
    ASSET_LOOKUP.set(info.displayName.toUpperCase(), key);
  }
}

// src/utils/base64.ts
function toBase64(bytes) {
  let binary = "";
  for (const byte of bytes) binary += String.fromCharCode(byte);
  return btoa(binary);
}
function fromBase64(b64) {
  const binary = atob(b64);
  const bytes = new Uint8Array(binary.length);
  for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);
  return bytes;
}

// src/protocols/protocolFee.ts
var FEE_RATES = {
  save: SAVE_FEE_BPS,
  borrow: BORROW_FEE_BPS,
  // Swap uses Cetus's overlay-fee mechanism (taken from output by the aggregator
  // and transferred to `overlayFee.receiver`). We list the rate here for display
  // / quote calculations only — `addFeeTransfer` is NOT called for swaps.
  swap: 10n
  // 0.1%
};
function calculateFee(operation, amount) {
  const bps = FEE_RATES[operation];
  const feeAmount = amount * Number(bps) / Number(BPS_DENOMINATOR);
  const rawAmount = stableToRaw(feeAmount, USDC_DECIMALS);
  return {
    amount: feeAmount,
    asset: "USDC",
    rate: Number(bps) / Number(BPS_DENOMINATOR),
    rawAmount
  };
}
function addFeeTransfer(tx, paymentCoin, feeBps, receiver, amount, decimals = USDC_DECIMALS) {
  if (feeBps <= 0n) return;
  if (amount <= 0) return;
  const feeAmount = amount * Number(feeBps) / Number(BPS_DENOMINATOR);
  const rawFee = stableToRaw(feeAmount, decimals);
  if (rawFee <= 0n) return;
  const [feeCoin] = tx.splitCoins(paymentCoin, [tx.pure.u64(rawFee)]);
  tx.transferObjects([feeCoin], tx.pure.address(receiver));
}

// src/protocols/cetus-swap.ts
init_token_registry();
init_token_registry();
var OVERLAY_FEE_RATE = 1e-3;
var clientCache = /* @__PURE__ */ new Map();
function getClient(walletAddress, overlayFee) {
  const rate = overlayFee?.rate ?? 0;
  const receiver = overlayFee?.receiver ?? "";
  const key = `${walletAddress}|${rate}|${receiver}`;
  const cached = clientCache.get(key);
  if (cached) return cached;
  const client = new AggregatorClient({
    signer: walletAddress,
    env: Env.Mainnet,
    ...rate > 0 && receiver ? { overlayFeeRate: rate, overlayFeeReceiver: receiver } : {}
  });
  clientCache.set(key, client);
  return client;
}
async function findSwapRoute(params) {
  const client = getClient(params.walletAddress, params.overlayFee);
  const findParams = {
    from: params.from,
    target: params.to,
    amount: params.amount.toString(),
    byAmountIn: params.byAmountIn,
    ...params.providers ? { providers: params.providers } : {}
  };
  const routerData = await client.findRouters(findParams);
  if (!routerData) return null;
  if (routerData.insufficientLiquidity) {
    return {
      routerData,
      amountIn: routerData.amountIn.toString(),
      amountOut: routerData.amountOut.toString(),
      byAmountIn: params.byAmountIn,
      priceImpact: normalizePriceImpact(routerData.deviationRatio),
      insufficientLiquidity: true
    };
  }
  if (routerData.error) {
    const { T2000Error: T2000Error2 } = await Promise.resolve().then(() => (init_errors(), errors_exports));
    throw new T2000Error2("SWAP_FAILED", `Cetus routing error: ${routerData.error.msg} (code ${routerData.error.code})`);
  }
  return {
    routerData,
    amountIn: routerData.amountIn.toString(),
    amountOut: routerData.amountOut.toString(),
    byAmountIn: params.byAmountIn,
    priceImpact: normalizePriceImpact(routerData.deviationRatio),
    insufficientLiquidity: false
  };
}
function normalizePriceImpact(value) {
  const n = typeof value === "number" ? value : Number(value);
  return Number.isFinite(n) ? n : 0;
}
async function buildSwapTx(params) {
  const client = getClient(params.walletAddress, params.overlayFee);
  const clampedSlippage = Math.max(1e-3, Math.min(params.slippage, 0.05));
  const outputCoin = await client.routerSwap({
    router: params.route.routerData,
    inputCoin: params.inputCoin,
    slippage: clampedSlippage,
    txb: params.tx
  });
  return outputCoin;
}

// src/safeguards/errors.ts
init_errors();
var SafeguardError = class extends T2000Error {
  rule;
  details;
  constructor(rule, details, message) {
    const msg = message ?? buildMessage(rule, details);
    super("SAFEGUARD_BLOCKED", msg, { rule, ...details });
    this.name = "SafeguardError";
    this.rule = rule;
    this.details = details;
  }
  toJSON() {
    return {
      error: "SAFEGUARD_BLOCKED",
      message: this.message,
      retryable: this.retryable,
      data: { rule: this.rule, ...this.details }
    };
  }
};
function buildMessage(rule, details) {
  switch (rule) {
    case "locked":
      return "Agent is locked. All operations are frozen.";
    case "maxPerTx":
      return `Amount $${(details.attempted ?? 0).toFixed(2)} exceeds per-transaction limit ($${(details.limit ?? 0).toFixed(2)})`;
    case "maxDailySend":
      return `Daily send limit reached ($${(details.current ?? 0).toFixed(2)}/$${(details.limit ?? 0).toFixed(2)} used today)`;
  }
}

// src/safeguards/types.ts
var OUTBOUND_OPS = /* @__PURE__ */ new Set([
  "send",
  "pay"
]);
var DEFAULT_SAFEGUARD_CONFIG = {
  locked: false,
  maxPerTx: 0,
  maxDailySend: 0,
  dailyUsed: 0,
  dailyResetDate: ""
};

// src/browser.ts
init_token_registry();

export { ALL_NAVI_ASSETS, BORROW_FEE_BPS, BPS_DENOMINATOR, CLOCK_ID, COIN_REGISTRY, DEFAULT_NETWORK, DEFAULT_SAFEGUARD_CONFIG, ETH_TYPE, GAS_RESERVE_MIN, IKA_TYPE, KNOWN_TARGETS, KeypairSigner, LABEL_PATTERNS, LOFI_TYPE, MANIFEST_TYPE, MIST_PER_SUI, NAVX_TYPE, OUTBOUND_OPS, OVERLAY_FEE_RATE, SAVE_FEE_BPS, STABLE_ASSETS, SUI_DECIMALS, SUI_TYPE, SUPPORTED_ASSETS, SafeguardError, T2000Error, T2000_OVERLAY_FEE_WALLET, TOKEN_MAP, USDC_DECIMALS, USDC_TYPE, USDE_TYPE, USDSUI_TYPE, USDT_TYPE, WAL_TYPE, WBTC_TYPE, ZkLoginSigner, addFeeTransfer, buildSwapTx, calculateFee, classifyAction, classifyLabel, classifyTransaction, extractAllUserLegs, extractTransferDetails, extractTxCommands, extractTxSender, fallbackLabel, findSwapRoute, formatAssetAmount, formatSui, formatUsd, fromBase64, getDecimals, getDecimalsForCoinType, getTier, isSupported, isTier1, isTier2, mapMoveAbortCode, mapWalletError, mistToSui, parseSuiRpcTx, rawToStable, rawToUsdc, refineLendingLabel, resolveSymbol, resolveTokenType, stableToRaw, suiToMist, toBase64, truncateAddress, usdcToRaw, validateAddress };
//# sourceMappingURL=browser.js.map
//# sourceMappingURL=browser.js.map