import { createRequire as __createRequire } from 'module'; import { fileURLToPath as __fileURLToPath } from 'url'; import { dirname as __pathDirname } from 'path'; const require = __createRequire(import.meta.url); const __filename = __fileURLToPath(import.meta.url); const __dirname = __pathDirname(__filename);
import {
  ArgumentSchema,
  BCSBytes,
  FundsWithdrawalArgSchema,
  JsonU64,
  MOVE_STDLIB_ADDRESS,
  NormalizedCallArg,
  ObjectID,
  ObjectRefSchema,
  SUI_CLOCK_OBJECT_ID,
  SUI_DENY_LIST_OBJECT_ID,
  SUI_FRAMEWORK_ADDRESS,
  SUI_RANDOM_OBJECT_ID,
  SUI_SYSTEM_STATE_OBJECT_ID,
  SUI_TYPE_ARG,
  SimulationError,
  SuiAddress,
  TransactionDataBuilder,
  TransactionExpiration,
  TypeTagSerializer,
  ValidDuringSchema,
  array,
  bigint,
  boolean,
  chunk,
  deriveDynamicFieldID,
  findNamesInTransaction,
  getIdFromCallArg,
  init_bcs,
  init_constants,
  init_dynamic_fields,
  init_pure,
  init_type_tag_serializer,
  integer,
  is,
  literal,
  nullable,
  nullish,
  number,
  object,
  optional,
  parse,
  picklist,
  pipe,
  pureBcsSchemaFromTypeName,
  record,
  replaceNames,
  serializeV1TransactionData,
  string,
  suiBcs,
  tuple,
  union,
  unknown
} from "./chunk-6ADWLA5A.js";
import {
  fromBase58,
  fromBase64,
  fromHex,
  init_dist,
  init_sui_types,
  isSerializedBcs,
  normalizeStructTag,
  normalizeSuiAddress,
  normalizeSuiObjectId,
  toBase58,
  toBase64,
  toHex
} from "./chunk-BLV67HXL.js";

// ../../node_modules/.pnpm/@mysten+sui@2.17.0_typescript@5.9.3/node_modules/@mysten/sui/dist/transactions/intents/CoinWithBalance.mjs
init_sui_types();
init_bcs();

// ../../node_modules/.pnpm/@mysten+sui@2.17.0_typescript@5.9.3/node_modules/@mysten/sui/dist/transactions/Commands.mjs
init_sui_types();
init_dist();
var TransactionCommands = {
  MoveCall(input) {
    const [pkg, mod = "", fn = ""] = "target" in input ? input.target.split("::") : [
      input.package,
      input.module,
      input.function
    ];
    return {
      $kind: "MoveCall",
      MoveCall: {
        package: pkg,
        module: mod,
        function: fn,
        typeArguments: input.typeArguments ?? [],
        arguments: input.arguments ?? []
      }
    };
  },
  TransferObjects(objects, address) {
    return {
      $kind: "TransferObjects",
      TransferObjects: {
        objects: objects.map((o) => parse(ArgumentSchema, o)),
        address: parse(ArgumentSchema, address)
      }
    };
  },
  SplitCoins(coin, amounts) {
    return {
      $kind: "SplitCoins",
      SplitCoins: {
        coin: parse(ArgumentSchema, coin),
        amounts: amounts.map((o) => parse(ArgumentSchema, o))
      }
    };
  },
  MergeCoins(destination, sources) {
    return {
      $kind: "MergeCoins",
      MergeCoins: {
        destination: parse(ArgumentSchema, destination),
        sources: sources.map((o) => parse(ArgumentSchema, o))
      }
    };
  },
  Publish({ modules, dependencies }) {
    return {
      $kind: "Publish",
      Publish: {
        modules: modules.map((module) => typeof module === "string" ? module : toBase64(new Uint8Array(module))),
        dependencies: dependencies.map((dep) => normalizeSuiObjectId(dep))
      }
    };
  },
  Upgrade({ modules, dependencies, package: packageId, ticket }) {
    return {
      $kind: "Upgrade",
      Upgrade: {
        modules: modules.map((module) => typeof module === "string" ? module : toBase64(new Uint8Array(module))),
        dependencies: dependencies.map((dep) => normalizeSuiObjectId(dep)),
        package: packageId,
        ticket: parse(ArgumentSchema, ticket)
      }
    };
  },
  MakeMoveVec({ type, elements }) {
    return {
      $kind: "MakeMoveVec",
      MakeMoveVec: {
        type: type ?? null,
        elements: elements.map((o) => parse(ArgumentSchema, o))
      }
    };
  },
  Intent({ name, inputs = {}, data = {} }) {
    return {
      $kind: "$Intent",
      $Intent: {
        name,
        inputs: Object.fromEntries(Object.entries(inputs).map(([key, value]) => [key, Array.isArray(value) ? value.map((o) => parse(ArgumentSchema, o)) : parse(ArgumentSchema, value)])),
        data
      }
    };
  }
};

// ../../node_modules/.pnpm/@mysten+sui@2.17.0_typescript@5.9.3/node_modules/@mysten/sui/dist/transactions/Inputs.mjs
init_sui_types();
init_dist();
function Pure(data) {
  return {
    $kind: "Pure",
    Pure: { bytes: data instanceof Uint8Array ? toBase64(data) : data.toBase64() }
  };
}
var Inputs = {
  Pure,
  ObjectRef({ objectId, digest, version }) {
    return {
      $kind: "Object",
      Object: {
        $kind: "ImmOrOwnedObject",
        ImmOrOwnedObject: {
          digest,
          version,
          objectId: normalizeSuiAddress(objectId)
        }
      }
    };
  },
  SharedObjectRef({ objectId, mutable, initialSharedVersion }) {
    return {
      $kind: "Object",
      Object: {
        $kind: "SharedObject",
        SharedObject: {
          mutable,
          initialSharedVersion,
          objectId: normalizeSuiAddress(objectId)
        }
      }
    };
  },
  ReceivingRef({ objectId, digest, version }) {
    return {
      $kind: "Object",
      Object: {
        $kind: "Receiving",
        Receiving: {
          digest,
          version,
          objectId: normalizeSuiAddress(objectId)
        }
      }
    };
  },
  FundsWithdrawal({ reservation, typeArg, withdrawFrom }) {
    return {
      $kind: "FundsWithdrawal",
      FundsWithdrawal: {
        reservation,
        typeArg,
        withdrawFrom
      }
    };
  }
};

// ../../node_modules/.pnpm/@mysten+sui@2.17.0_typescript@5.9.3/node_modules/@mysten/sui/dist/transactions/intents/CoinWithBalance.mjs
var COIN_WITH_BALANCE = "CoinWithBalance";
var SUI_TYPE = normalizeStructTag("0x2::sui::SUI");
function coinWithBalance({ type = SUI_TYPE, balance, useGasCoin = true }) {
  let coinResult = null;
  return (tx) => {
    if (coinResult) return coinResult;
    tx.addIntentResolver(COIN_WITH_BALANCE, resolveCoinBalance);
    const coinType = type === "gas" ? type : normalizeStructTag(type);
    coinResult = tx.add(TransactionCommands.Intent({
      name: COIN_WITH_BALANCE,
      inputs: {},
      data: {
        type: coinType === SUI_TYPE && useGasCoin ? "gas" : coinType,
        balance: BigInt(balance),
        outputKind: "coin"
      }
    }));
    return coinResult;
  };
}
function createBalance({ type = SUI_TYPE, balance, useGasCoin = true }) {
  let balanceResult = null;
  return (tx) => {
    if (balanceResult) return balanceResult;
    tx.addIntentResolver(COIN_WITH_BALANCE, resolveCoinBalance);
    const coinType = type === "gas" ? type : normalizeStructTag(type);
    balanceResult = tx.add(TransactionCommands.Intent({
      name: COIN_WITH_BALANCE,
      inputs: {},
      data: {
        type: coinType === SUI_TYPE && useGasCoin ? "gas" : coinType,
        balance: BigInt(balance),
        outputKind: "balance"
      }
    }));
    return balanceResult;
  };
}
var CoinWithBalanceData = object({
  type: string(),
  balance: bigint(),
  outputKind: optional(picklist(["coin", "balance"]))
});
async function resolveCoinBalance(transactionData, buildOptions, next) {
  const coinTypes = /* @__PURE__ */ new Set();
  const totalByType = /* @__PURE__ */ new Map();
  const intentsByType = /* @__PURE__ */ new Map();
  if (!transactionData.sender) throw new Error("Sender must be set to resolve CoinWithBalance");
  for (const [i, command] of transactionData.commands.entries()) {
    if (command.$kind !== "$Intent" || command.$Intent.name !== COIN_WITH_BALANCE) continue;
    const { type, balance, outputKind } = parse(CoinWithBalanceData, command.$Intent.data);
    if (balance === 0n) {
      const coinType = type === "gas" ? SUI_TYPE : type;
      transactionData.replaceCommand(i, TransactionCommands.MoveCall({
        target: (outputKind ?? "coin") === "balance" ? "0x2::balance::zero" : "0x2::coin::zero",
        typeArguments: [coinType]
      }));
      continue;
    }
    if (type !== "gas") coinTypes.add(type);
    totalByType.set(type, (totalByType.get(type) ?? 0n) + balance);
    if (!intentsByType.has(type)) intentsByType.set(type, []);
    intentsByType.get(type).push({
      balance,
      outputKind: outputKind ?? "coin"
    });
  }
  if (totalByType.has("gas") && totalByType.has(SUI_TYPE)) throw new Error("Cannot mix SUI CoinWithBalance intents that use the gas coin with ones that do not (useGasCoin: false). Use one or the other.");
  const usedIds = /* @__PURE__ */ new Set();
  for (const input of transactionData.inputs) {
    if (input.Object?.ImmOrOwnedObject) usedIds.add(input.Object.ImmOrOwnedObject.objectId);
    if (input.UnresolvedObject?.objectId) usedIds.add(input.UnresolvedObject.objectId);
  }
  const coinsByType = /* @__PURE__ */ new Map();
  const addressBalanceByType = /* @__PURE__ */ new Map();
  const client = buildOptions.client;
  if (!client) throw new Error("Client must be provided to build or serialize transactions with CoinWithBalance intents");
  await Promise.all([...[...coinTypes].map(async (coinType) => {
    const { coins, addressBalance } = await getCoinsAndBalanceOfType({
      coinType,
      balance: totalByType.get(coinType),
      client,
      owner: transactionData.sender,
      usedIds
    });
    coinsByType.set(coinType, coins);
    addressBalanceByType.set(coinType, addressBalance);
  }), totalByType.has("gas") ? await client.core.getBalance({
    owner: transactionData.sender,
    coinType: SUI_TYPE
  }).then(({ balance }) => {
    addressBalanceByType.set("gas", BigInt(balance.addressBalance));
  }) : null]);
  const mergedCoins = /* @__PURE__ */ new Map();
  const exactBalanceByType = /* @__PURE__ */ new Map();
  const usedAddressBalance = /* @__PURE__ */ new Set();
  const typeState = /* @__PURE__ */ new Map();
  let index = 0;
  while (index < transactionData.commands.length) {
    const transaction = transactionData.commands[index];
    if (transaction.$kind !== "$Intent" || transaction.$Intent.name !== COIN_WITH_BALANCE) {
      index++;
      continue;
    }
    const { type, balance } = transaction.$Intent.data;
    const coinType = type === "gas" ? SUI_TYPE : type;
    const totalRequired = totalByType.get(type);
    const addressBalance = addressBalanceByType.get(type) ?? 0n;
    const commands = [];
    let intentResult;
    const intentsForType = intentsByType.get(type) ?? [];
    if (intentsForType.every((i) => i.outputKind === "balance") && addressBalance >= totalRequired) {
      commands.push(TransactionCommands.MoveCall({
        target: "0x2::balance::redeem_funds",
        typeArguments: [coinType],
        arguments: [transactionData.addInput("withdrawal", Inputs.FundsWithdrawal({
          reservation: {
            $kind: "MaxAmountU64",
            MaxAmountU64: String(balance)
          },
          typeArg: {
            $kind: "Balance",
            Balance: coinType
          },
          withdrawFrom: {
            $kind: "Sender",
            Sender: true
          }
        }))]
      }));
      intentResult = {
        $kind: "NestedResult",
        NestedResult: [index + commands.length - 1, 0]
      };
    } else {
      if (!typeState.has(type)) {
        const intents = intentsForType;
        const sources = [];
        if (addressBalance >= totalRequired) {
          usedAddressBalance.add(type);
          commands.push(TransactionCommands.MoveCall({
            target: "0x2::coin::redeem_funds",
            typeArguments: [coinType],
            arguments: [transactionData.addInput("withdrawal", Inputs.FundsWithdrawal({
              reservation: {
                $kind: "MaxAmountU64",
                MaxAmountU64: String(totalRequired)
              },
              typeArg: {
                $kind: "Balance",
                Balance: coinType
              },
              withdrawFrom: {
                $kind: "Sender",
                Sender: true
              }
            }))]
          }));
          sources.push({
            $kind: "Result",
            Result: index + commands.length - 1
          });
        } else if (type === "gas") sources.push({
          $kind: "GasCoin",
          GasCoin: true
        });
        else {
          const coins = coinsByType.get(type);
          const loadedCoinBalance = coins.reduce((sum, c) => sum + BigInt(c.balance), 0n);
          const abNeeded = totalRequired > loadedCoinBalance ? totalRequired - loadedCoinBalance : 0n;
          exactBalanceByType.set(type, loadedCoinBalance + abNeeded === totalRequired);
          for (const coin of coins) sources.push(transactionData.addInput("object", Inputs.ObjectRef({
            objectId: coin.objectId,
            digest: coin.digest,
            version: coin.version
          })));
          if (abNeeded > 0n) {
            usedAddressBalance.add(type);
            commands.push(TransactionCommands.MoveCall({
              target: "0x2::coin::redeem_funds",
              typeArguments: [coinType],
              arguments: [transactionData.addInput("withdrawal", Inputs.FundsWithdrawal({
                reservation: {
                  $kind: "MaxAmountU64",
                  MaxAmountU64: String(abNeeded)
                },
                typeArg: {
                  $kind: "Balance",
                  Balance: coinType
                },
                withdrawFrom: {
                  $kind: "Sender",
                  Sender: true
                }
              }))]
            }));
            sources.push({
              $kind: "Result",
              Result: index + commands.length - 1
            });
          }
        }
        const baseCoin = sources[0];
        const rest = sources.slice(1);
        for (let i = 0; i < rest.length; i += 500) commands.push(TransactionCommands.MergeCoins(baseCoin, rest.slice(i, i + 500)));
        mergedCoins.set(type, baseCoin);
        const splitCmdIndex = index + commands.length;
        commands.push(TransactionCommands.SplitCoins(baseCoin, intents.map((i) => transactionData.addInput("pure", Inputs.Pure(suiBcs.u64().serialize(i.balance))))));
        const results = [];
        for (let i = 0; i < intents.length; i++) {
          const splitResult = {
            $kind: "NestedResult",
            NestedResult: [splitCmdIndex, i]
          };
          if (intents[i].outputKind === "balance") {
            commands.push(TransactionCommands.MoveCall({
              target: "0x2::coin::into_balance",
              typeArguments: [coinType],
              arguments: [splitResult]
            }));
            results.push({
              $kind: "NestedResult",
              NestedResult: [index + commands.length - 1, 0]
            });
          } else results.push(splitResult);
        }
        typeState.set(type, {
          results,
          nextIntent: 0
        });
      }
      const state = typeState.get(type);
      intentResult = state.results[state.nextIntent++];
    }
    transactionData.replaceCommand(index, commands, intentResult);
    index += commands.length;
  }
  for (const [type, mergedCoin] of mergedCoins) {
    if (type === "gas" && !usedAddressBalance.has(type)) continue;
    const coinType = type === "gas" ? SUI_TYPE : type;
    const hasBalanceIntent = intentsByType.get(type)?.some((i) => i.outputKind === "balance");
    const sourcedFromAB = usedAddressBalance.has(type);
    if (hasBalanceIntent || sourcedFromAB) transactionData.commands.push(TransactionCommands.MoveCall({
      target: "0x2::coin::send_funds",
      typeArguments: [coinType],
      arguments: [mergedCoin, transactionData.addInput("pure", Inputs.Pure(suiBcs.Address.serialize(transactionData.sender)))]
    }));
    else if (exactBalanceByType.get(type)) transactionData.commands.push(TransactionCommands.MoveCall({
      target: "0x2::coin::destroy_zero",
      typeArguments: [coinType],
      arguments: [mergedCoin]
    }));
  }
  return next();
}
async function getCoinsAndBalanceOfType({ coinType, balance, client, owner, usedIds }) {
  let remainingBalance = balance;
  const coins = [];
  const balanceRequest = client.core.getBalance({
    owner,
    coinType
  }).then(({ balance: balance$1 }) => {
    remainingBalance -= BigInt(balance$1.addressBalance);
    return balance$1;
  });
  const [allCoins, balanceResponse] = await Promise.all([loadMoreCoins(), balanceRequest]);
  if (BigInt(balanceResponse.balance) < balance) throw new Error(`Insufficient balance of ${coinType} for owner ${owner}. Required: ${balance}, Available: ${balance - remainingBalance}`);
  return {
    coins: allCoins,
    balance: BigInt(balanceResponse.coinBalance),
    addressBalance: BigInt(balanceResponse.addressBalance),
    coinBalance: BigInt(balanceResponse.coinBalance)
  };
  async function loadMoreCoins(cursor = null) {
    const { objects, hasNextPage, cursor: nextCursor } = await client.core.listCoins({
      owner,
      coinType,
      cursor
    });
    await balanceRequest;
    for (const coin of objects) {
      if (usedIds.has(coin.objectId)) continue;
      coins.push(coin);
      remainingBalance -= BigInt(coin.balance);
    }
    if (remainingBalance > 0n && hasNextPage) return loadMoreCoins(nextCursor);
    return coins;
  }
}

// ../../node_modules/.pnpm/@mysten+sui@2.17.0_typescript@5.9.3/node_modules/@mysten/sui/dist/transactions/Transaction.mjs
init_sui_types();

// ../../node_modules/.pnpm/@mysten+sui@2.17.0_typescript@5.9.3/node_modules/@mysten/sui/dist/transactions/data/v2.mjs
function enumUnion(options) {
  return union(Object.entries(options).map(([key, value]) => object({ [key]: value })));
}
var Argument = enumUnion({
  GasCoin: literal(true),
  Input: pipe(number(), integer()),
  Result: pipe(number(), integer()),
  NestedResult: tuple([pipe(number(), integer()), pipe(number(), integer())])
});
var GasData = object({
  budget: nullable(JsonU64),
  price: nullable(JsonU64),
  owner: nullable(SuiAddress),
  payment: nullable(array(ObjectRefSchema))
});
var ProgrammableMoveCall = object({
  package: ObjectID,
  module: string(),
  function: string(),
  typeArguments: array(string()),
  arguments: array(Argument)
});
var $Intent = object({
  name: string(),
  inputs: record(string(), union([Argument, array(Argument)])),
  data: record(string(), unknown())
});
var Command = enumUnion({
  MoveCall: ProgrammableMoveCall,
  TransferObjects: object({
    objects: array(Argument),
    address: Argument
  }),
  SplitCoins: object({
    coin: Argument,
    amounts: array(Argument)
  }),
  MergeCoins: object({
    destination: Argument,
    sources: array(Argument)
  }),
  Publish: object({
    modules: array(BCSBytes),
    dependencies: array(ObjectID)
  }),
  MakeMoveVec: object({
    type: nullable(string()),
    elements: array(Argument)
  }),
  Upgrade: object({
    modules: array(BCSBytes),
    dependencies: array(ObjectID),
    package: ObjectID,
    ticket: Argument
  }),
  $Intent
});
var CallArg = enumUnion({
  Object: enumUnion({
    ImmOrOwnedObject: ObjectRefSchema,
    SharedObject: object({
      objectId: ObjectID,
      initialSharedVersion: JsonU64,
      mutable: boolean()
    }),
    Receiving: ObjectRefSchema
  }),
  Pure: object({ bytes: BCSBytes }),
  UnresolvedPure: object({ value: unknown() }),
  UnresolvedObject: object({
    objectId: ObjectID,
    version: optional(nullable(JsonU64)),
    digest: optional(nullable(string())),
    initialSharedVersion: optional(nullable(JsonU64)),
    mutable: optional(nullable(boolean()))
  }),
  FundsWithdrawal: FundsWithdrawalArgSchema
});
var TransactionExpiration2 = enumUnion({
  None: literal(true),
  Epoch: JsonU64,
  ValidDuring: ValidDuringSchema
});
var SerializedTransactionDataV2Schema = object({
  version: literal(2),
  sender: nullish(SuiAddress),
  expiration: nullish(TransactionExpiration2),
  gasData: GasData,
  inputs: array(CallArg),
  commands: array(Command),
  digest: optional(nullable(string()))
});

// ../../node_modules/.pnpm/@mysten+sui@2.17.0_typescript@5.9.3/node_modules/@mysten/sui/dist/transactions/resolve.mjs
init_bcs();

// ../../node_modules/.pnpm/@mysten+sui@2.17.0_typescript@5.9.3/node_modules/@mysten/sui/dist/client/core-resolver.mjs
init_sui_types();
init_constants();

// ../../node_modules/.pnpm/@mysten+sui@2.17.0_typescript@5.9.3/node_modules/@mysten/sui/dist/utils/coin-reservation.mjs
init_sui_types();
init_type_tag_serializer();
init_bcs();
init_dynamic_fields();
init_dist();
var SUI_ACCUMULATOR_ROOT_OBJECT_ID = normalizeSuiAddress("0xacc");
var ACCUMULATOR_KEY_TYPE_TAG = TypeTagSerializer.parseFromStr("0x2::accumulator::Key<0x2::balance::Balance<0x2::sui::SUI>>");
var COIN_RESERVATION_MAGIC = new Uint8Array([
  172,
  172,
  172,
  172,
  172,
  172,
  172,
  172,
  172,
  172,
  172,
  172,
  172,
  172,
  172,
  172,
  172,
  172,
  172,
  172
]);
function isCoinReservationDigest(digestBase58) {
  return fromBase58(digestBase58).slice(12, 32).every((byte, i) => byte === COIN_RESERVATION_MAGIC[i]);
}
function deriveReservationObjectId(owner, chainIdentifier) {
  const accBytes = fromHex(deriveDynamicFieldID(SUI_ACCUMULATOR_ROOT_OBJECT_ID, ACCUMULATOR_KEY_TYPE_TAG, suiBcs.Address.serialize(owner).toBytes()).slice(2));
  const chainBytes = fromBase58(chainIdentifier);
  if (chainBytes.length !== 32) throw new Error(`Invalid chain identifier length: expected 32 bytes, got ${chainBytes.length}`);
  const xored = new Uint8Array(32);
  for (let i = 0; i < 32; i++) xored[i] = accBytes[i] ^ chainBytes[i];
  return `0x${toHex(xored)}`;
}
function createCoinReservationRef(reservedBalance, owner, chainIdentifier, epoch) {
  const digestBytes = new Uint8Array(32);
  const view = new DataView(digestBytes.buffer);
  view.setBigUint64(0, reservedBalance, true);
  const epochNum = Number(epoch);
  if (!Number.isSafeInteger(epochNum) || epochNum < 0 || epochNum > 4294967295) throw new Error(`Epoch ${epoch} out of u32 range for coin reservation digest`);
  view.setUint32(8, epochNum, true);
  digestBytes.set(COIN_RESERVATION_MAGIC, 12);
  return parse(ObjectRefSchema, {
    objectId: deriveReservationObjectId(owner, chainIdentifier),
    version: "0",
    digest: toBase58(digestBytes)
  });
}

// ../../node_modules/.pnpm/@mysten+sui@2.17.0_typescript@5.9.3/node_modules/@mysten/sui/dist/transactions/serializer.mjs
init_sui_types();
init_bcs();
init_constants();
function parseTypeName(typeName) {
  const parts = typeName.split("::");
  if (parts.length !== 3) throw new Error(`Invalid type name format: ${typeName}`);
  return {
    package: parts[0],
    module: parts[1],
    name: parts[2]
  };
}
function isTxContext(param) {
  if (param.body.$kind !== "datatype") return false;
  const { package: pkg, module, name } = parseTypeName(param.body.datatype.typeName);
  return normalizeSuiAddress(pkg) === SUI_FRAMEWORK_ADDRESS && module === "tx_context" && name === "TxContext";
}
function getPureBcsSchema(typeSignature) {
  switch (typeSignature.$kind) {
    case "address":
      return suiBcs.Address;
    case "bool":
      return suiBcs.Bool;
    case "u8":
      return suiBcs.U8;
    case "u16":
      return suiBcs.U16;
    case "u32":
      return suiBcs.U32;
    case "u64":
      return suiBcs.U64;
    case "u128":
      return suiBcs.U128;
    case "u256":
      return suiBcs.U256;
    case "vector": {
      if (typeSignature.vector.$kind === "u8") return suiBcs.byteVector().transform({
        input: (val) => typeof val === "string" ? new TextEncoder().encode(val) : val,
        output: (val) => val
      });
      const type = getPureBcsSchema(typeSignature.vector);
      return type ? suiBcs.vector(type) : null;
    }
    case "datatype": {
      const { package: pkg, module, name } = parseTypeName(typeSignature.datatype.typeName);
      const normalizedPkg = normalizeSuiAddress(pkg);
      if (normalizedPkg === MOVE_STDLIB_ADDRESS) {
        if (module === "ascii" && name === "String") return suiBcs.String;
        if (module === "string" && name === "String") return suiBcs.String;
        if (module === "option" && name === "Option") {
          const type = getPureBcsSchema(typeSignature.datatype.typeParameters[0]);
          return type ? suiBcs.vector(type) : null;
        }
      }
      if (normalizedPkg === SUI_FRAMEWORK_ADDRESS) {
        if (module === "object" && name === "ID") return suiBcs.Address;
      }
      return null;
    }
    case "typeParameter":
    case "unknown":
      return null;
  }
}

// ../../node_modules/.pnpm/@mysten+sui@2.17.0_typescript@5.9.3/node_modules/@mysten/sui/dist/client/core-resolver.mjs
var MAX_OBJECTS_PER_FETCH = 50;
var GAS_SAFE_OVERHEAD = 1000n;
var MAX_GAS = 5e10;
function computeGasBudget(gasUsed, gasPrice = 1n) {
  const safeOverhead = GAS_SAFE_OVERHEAD * BigInt(gasPrice);
  const baseComputationCostWithOverhead = BigInt(gasUsed.computationCost) + safeOverhead;
  const gasBudget = baseComputationCostWithOverhead + BigInt(gasUsed.storageCost) - BigInt(gasUsed.storageRebate);
  return String(gasBudget > baseComputationCostWithOverhead ? gasBudget : baseComputationCostWithOverhead);
}
function getClient(options) {
  if (!options.client) throw new Error(`No sui client passed to Transaction#build, but transaction data was not sufficient to build offline.`);
  return options.client;
}
async function coreClientResolveTransactionPlugin(transactionData, options, next) {
  const client = getClient(options);
  const needsGasPrice = !options.onlyTransactionKind && !transactionData.gasData.price;
  const needsPayment = !options.onlyTransactionKind && !transactionData.gasData.payment;
  const gasPayer = transactionData.gasData.owner ?? transactionData.sender;
  let usesGasCoin = false;
  let withdrawals = 0n;
  transactionData.mapArguments((arg) => {
    if (arg.$kind === "GasCoin") usesGasCoin = true;
    return arg;
  });
  const normalizedGasPayer = gasPayer ? normalizeSuiAddress(gasPayer) : null;
  for (const input of transactionData.inputs) {
    if (input.$kind !== "FundsWithdrawal" || !normalizedGasPayer) continue;
    if (normalizeStructTag(input.FundsWithdrawal.typeArg.Balance) !== SUI_TYPE_ARG) continue;
    const withdrawalOwner = input.FundsWithdrawal.withdrawFrom.Sender ? transactionData.sender : gasPayer;
    if (withdrawalOwner && normalizeSuiAddress(withdrawalOwner) === normalizedGasPayer && input.FundsWithdrawal.reservation.$kind === "MaxAmountU64") withdrawals += BigInt(input.FundsWithdrawal.reservation.MaxAmountU64);
  }
  const needsSimulateExpiration = !options.onlyTransactionKind && !transactionData.expiration && !transactionData.gasData.budget;
  const needsSystemState = needsGasPrice || needsPayment && usesGasCoin || needsSimulateExpiration;
  const needsChainId = needsPayment && usesGasCoin || needsSimulateExpiration;
  const [, systemStateResult, balanceResult, coinsResult, chainIdResult] = await Promise.all([
    normalizeInputs(transactionData, client),
    needsSystemState ? client.core.getCurrentSystemState() : null,
    needsPayment && gasPayer ? client.core.getBalance({ owner: gasPayer }) : null,
    needsPayment && gasPayer ? client.core.listCoins({
      owner: gasPayer,
      coinType: SUI_TYPE_ARG
    }) : null,
    needsChainId ? client.core.getChainIdentifier() : null
  ]);
  await resolveObjectReferences(transactionData, client);
  if (!options.onlyTransactionKind) {
    const systemState = systemStateResult?.systemState ?? null;
    const chainIdentifier = chainIdResult?.chainIdentifier ?? null;
    if (systemState && !transactionData.gasData.price) transactionData.gasData.price = systemState.referenceGasPrice;
    await setGasBudget(transactionData, client, needsSimulateExpiration && systemState && chainIdentifier ? buildValidDuringExpiration(systemState, chainIdentifier) : void 0);
    if (needsPayment) {
      if (!balanceResult || !coinsResult) throw new Error("Could not resolve gas payment: a gas owner or sender must be set to fetch balance and coins.");
      setGasPayment({
        transactionData,
        balance: balanceResult,
        coins: coinsResult,
        usesGasCoin,
        withdrawals,
        gasPayer,
        chainIdentifier,
        epoch: systemState?.epoch ?? null
      });
    }
    if (!transactionData.expiration && transactionData.gasData.payment?.length === 0) await setExpiration(transactionData, client, systemState, chainIdentifier);
  }
  return await next();
}
async function setGasBudget(transactionData, client, simulateExpiration) {
  if (transactionData.gasData.budget) return;
  const simulateResult = await client.core.simulateTransaction({
    transaction: transactionData.build({ overrides: {
      gasData: {
        budget: String(MAX_GAS),
        payment: []
      },
      ...simulateExpiration && { expiration: simulateExpiration }
    } }),
    include: { effects: true }
  });
  if (simulateResult.$kind === "FailedTransaction") {
    const executionError = simulateResult.FailedTransaction.status.error ?? void 0;
    throw new SimulationError(`Transaction resolution failed: ${executionError?.message ?? "Unknown error"}`, {
      cause: simulateResult,
      executionError
    });
  }
  transactionData.gasData.budget = computeGasBudget(simulateResult.Transaction.effects.gasUsed, transactionData.gasData.price ? String(transactionData.gasData.price) : void 0);
}
function setGasPayment({ transactionData, balance, coins, usesGasCoin, withdrawals, gasPayer, chainIdentifier, epoch }) {
  const budget = BigInt(transactionData.gasData.budget);
  const addressBalance = BigInt(balance.balance.addressBalance);
  if (budget === 0n || !usesGasCoin && addressBalance >= budget + withdrawals) {
    transactionData.gasData.payment = [];
    return;
  }
  const filteredCoins = coins.objects.filter((coin) => {
    return !transactionData.inputs.find((input) => {
      if (input.Object?.ImmOrOwnedObject) return coin.objectId === input.Object.ImmOrOwnedObject.objectId;
      return false;
    });
  });
  const paymentCoins = filteredCoins.map((coin) => ({
    objectId: coin.objectId,
    digest: coin.digest,
    version: coin.version
  }));
  const reservationAmount = addressBalance - withdrawals;
  if (usesGasCoin && reservationAmount > 0n && chainIdentifier && epoch) transactionData.gasData.payment = [createCoinReservationRef(reservationAmount, gasPayer, chainIdentifier, epoch), ...paymentCoins];
  else if (!filteredCoins.length) throw new Error("No valid gas coins found for the transaction.");
  else transactionData.gasData.payment = paymentCoins;
}
async function setExpiration(transactionData, client, systemState, existingChainIdentifier = null) {
  const [chainIdentifier, resolvedSystemState] = await Promise.all([existingChainIdentifier ?? client.core.getChainIdentifier().then((r) => r.chainIdentifier), systemState ?? client.core.getCurrentSystemState().then((r) => r.systemState)]);
  transactionData.expiration = buildValidDuringExpiration(resolvedSystemState, chainIdentifier);
}
function buildValidDuringExpiration(systemState, chainIdentifier) {
  const currentEpoch = BigInt(systemState.epoch);
  return {
    $kind: "ValidDuring",
    ValidDuring: {
      minEpoch: String(currentEpoch),
      maxEpoch: String(currentEpoch + 1n),
      minTimestamp: null,
      maxTimestamp: null,
      chain: chainIdentifier,
      nonce: Math.random() * 4294967296 >>> 0
    }
  };
}
async function resolveObjectReferences(transactionData, client) {
  const objectsToResolve = transactionData.inputs.filter((input) => {
    return input.UnresolvedObject && !(input.UnresolvedObject.version || input.UnresolvedObject?.initialSharedVersion);
  });
  const dedupedIds = [...new Set(objectsToResolve.map((input) => normalizeSuiObjectId(input.UnresolvedObject.objectId)))];
  const objectChunks = dedupedIds.length ? chunk(dedupedIds, MAX_OBJECTS_PER_FETCH) : [];
  const resolved = (await Promise.all(objectChunks.map((chunkIds) => client.core.getObjects({ objectIds: chunkIds })))).flatMap((result) => result.objects);
  const responsesById = new Map(dedupedIds.map((id, index) => {
    return [id, resolved[index]];
  }));
  const invalidObjects = Array.from(responsesById).filter(([_, obj]) => obj instanceof Error).map(([_, obj]) => obj.message);
  if (invalidObjects.length) throw new Error(`The following input objects are invalid: ${invalidObjects.join(", ")}`);
  const objects = resolved.map((object2) => {
    if (object2 instanceof Error) throw new Error(`Failed to fetch object: ${object2.message}`);
    const owner = object2.owner;
    const initialSharedVersion = owner && typeof owner === "object" ? owner.$kind === "Shared" ? owner.Shared.initialSharedVersion : owner.$kind === "ConsensusAddressOwner" ? owner.ConsensusAddressOwner.startVersion : null : null;
    return {
      objectId: object2.objectId,
      digest: object2.digest,
      version: object2.version,
      initialSharedVersion
    };
  });
  const objectsById = new Map(dedupedIds.map((id, index) => {
    return [id, objects[index]];
  }));
  for (const [index, input] of transactionData.inputs.entries()) {
    if (!input.UnresolvedObject) continue;
    let updated;
    const id = normalizeSuiAddress(input.UnresolvedObject.objectId);
    const object2 = objectsById.get(id);
    if (input.UnresolvedObject.initialSharedVersion ?? object2?.initialSharedVersion) updated = Inputs.SharedObjectRef({
      objectId: id,
      initialSharedVersion: input.UnresolvedObject.initialSharedVersion || object2?.initialSharedVersion,
      mutable: input.UnresolvedObject.mutable || isUsedAsMutable(transactionData, index)
    });
    else if (isUsedAsReceiving(transactionData, index)) updated = Inputs.ReceivingRef({
      objectId: id,
      digest: input.UnresolvedObject.digest ?? object2?.digest,
      version: input.UnresolvedObject.version ?? object2?.version
    });
    transactionData.inputs[transactionData.inputs.indexOf(input)] = updated ?? Inputs.ObjectRef({
      objectId: id,
      digest: input.UnresolvedObject.digest ?? object2?.digest,
      version: input.UnresolvedObject.version ?? object2?.version
    });
  }
}
async function normalizeInputs(transactionData, client) {
  const { inputs, commands } = transactionData;
  const moveCallsToResolve = [];
  const moveFunctionsToResolve = /* @__PURE__ */ new Set();
  commands.forEach((command) => {
    if (command.MoveCall) {
      if (command.MoveCall._argumentTypes) return;
      if (command.MoveCall.arguments.map((arg) => {
        if (arg.$kind === "Input") return transactionData.inputs[arg.Input];
        return null;
      }).some((input) => input?.UnresolvedPure || input?.UnresolvedObject && typeof input?.UnresolvedObject.mutable !== "boolean")) {
        const functionName = `${command.MoveCall.package}::${command.MoveCall.module}::${command.MoveCall.function}`;
        moveFunctionsToResolve.add(functionName);
        moveCallsToResolve.push(command.MoveCall);
      }
    }
  });
  const moveFunctionParameters = /* @__PURE__ */ new Map();
  if (moveFunctionsToResolve.size > 0) await Promise.all([...moveFunctionsToResolve].map(async (functionName) => {
    const [packageId, moduleName, name] = functionName.split("::");
    const { function: def } = await client.core.getMoveFunction({
      packageId,
      moduleName,
      name
    });
    moveFunctionParameters.set(functionName, def.parameters);
  }));
  if (moveCallsToResolve.length) await Promise.all(moveCallsToResolve.map(async (moveCall) => {
    const parameters = moveFunctionParameters.get(`${moveCall.package}::${moveCall.module}::${moveCall.function}`);
    if (!parameters) return;
    moveCall._argumentTypes = parameters.length > 0 && isTxContext(parameters.at(-1)) ? parameters.slice(0, parameters.length - 1) : parameters;
  }));
  commands.forEach((command) => {
    if (!command.MoveCall) return;
    const moveCall = command.MoveCall;
    const fnName = `${moveCall.package}::${moveCall.module}::${moveCall.function}`;
    const params = moveCall._argumentTypes;
    if (!params) return;
    if (params.length !== command.MoveCall.arguments.length) throw new Error(`Incorrect number of arguments for ${fnName}`);
    params.forEach((param, i) => {
      const arg = moveCall.arguments[i];
      if (arg.$kind !== "Input") return;
      const input = inputs[arg.Input];
      if (!input.UnresolvedPure && !input.UnresolvedObject) return;
      const inputValue = input.UnresolvedPure?.value ?? input.UnresolvedObject?.objectId;
      const schema = getPureBcsSchema(param.body);
      if (schema) {
        arg.type = "pure";
        inputs[inputs.indexOf(input)] = Inputs.Pure(schema.serialize(inputValue));
        return;
      }
      if (typeof inputValue !== "string") throw new Error(`Expect the argument to be an object id string, got ${JSON.stringify(inputValue, null, 2)}`);
      arg.type = "object";
      const unresolvedObject = input.UnresolvedPure ? {
        $kind: "UnresolvedObject",
        UnresolvedObject: { objectId: inputValue }
      } : input;
      inputs[arg.Input] = unresolvedObject;
    });
  });
}
function isUsedAsMutable(transactionData, index) {
  let usedAsMutable = false;
  transactionData.getInputUses(index, (arg, tx) => {
    if (tx.MoveCall && tx.MoveCall._argumentTypes) {
      const argIndex = tx.MoveCall.arguments.indexOf(arg);
      usedAsMutable = tx.MoveCall._argumentTypes[argIndex].reference !== "immutable" || usedAsMutable;
    }
    if (tx.$kind === "MakeMoveVec" || tx.$kind === "MergeCoins" || tx.$kind === "SplitCoins" || tx.$kind === "TransferObjects") usedAsMutable = true;
  });
  return usedAsMutable;
}
function isUsedAsReceiving(transactionData, index) {
  let usedAsReceiving = false;
  transactionData.getInputUses(index, (arg, tx) => {
    if (tx.MoveCall && tx.MoveCall._argumentTypes) {
      const argIndex = tx.MoveCall.arguments.indexOf(arg);
      usedAsReceiving = isReceivingType(tx.MoveCall._argumentTypes[argIndex]) || usedAsReceiving;
    }
  });
  return usedAsReceiving;
}
var RECEIVING_TYPE = "0x0000000000000000000000000000000000000000000000000000000000000002::transfer::Receiving";
function isReceivingType(type) {
  if (type.body.$kind !== "datatype") return false;
  return type.body.datatype.typeName === RECEIVING_TYPE;
}

// ../../node_modules/.pnpm/@mysten+sui@2.17.0_typescript@5.9.3/node_modules/@mysten/sui/dist/transactions/resolve.mjs
function needsTransactionResolution(data, options) {
  if (data.inputs.some((input) => {
    return input.UnresolvedObject || input.UnresolvedPure;
  })) return true;
  if (!options.onlyTransactionKind) {
    if (!data.gasData.price || !data.gasData.budget || !data.gasData.payment) return true;
    if (data.gasData.payment.length === 0 && !data.expiration) return true;
  }
  return false;
}
async function resolveTransactionPlugin(transactionData, options, next) {
  normalizeRawArguments(transactionData);
  if (!needsTransactionResolution(transactionData, options)) {
    await validate(transactionData);
    return next();
  }
  return (getClient2(options).core?.resolveTransactionPlugin() ?? coreClientResolveTransactionPlugin)(transactionData, options, async () => {
    await validate(transactionData);
    await next();
  });
}
function validate(transactionData) {
  transactionData.inputs.forEach((input, index) => {
    if (input.$kind !== "Object" && input.$kind !== "Pure" && input.$kind !== "FundsWithdrawal") throw new Error(`Input at index ${index} has not been resolved.  Expected a Pure, Object, or FundsWithdrawal input, but found ${JSON.stringify(input)}`);
  });
}
function getClient2(options) {
  if (!options.client) throw new Error(`No sui client passed to Transaction#build, but transaction data was not sufficient to build offline.`);
  return options.client;
}
function normalizeRawArguments(transactionData) {
  for (const command of transactionData.commands) switch (command.$kind) {
    case "SplitCoins":
      command.SplitCoins.amounts.forEach((amount) => {
        normalizeRawArgument(amount, suiBcs.U64, transactionData);
      });
      break;
    case "TransferObjects":
      normalizeRawArgument(command.TransferObjects.address, suiBcs.Address, transactionData);
      break;
  }
}
function normalizeRawArgument(arg, schema, transactionData) {
  if (arg.$kind !== "Input") return;
  const input = transactionData.inputs[arg.Input];
  if (input.$kind !== "UnresolvedPure") return;
  transactionData.inputs[arg.Input] = Inputs.Pure(schema.serialize(input.UnresolvedPure.value));
}

// ../../node_modules/.pnpm/@mysten+sui@2.17.0_typescript@5.9.3/node_modules/@mysten/sui/dist/transactions/object.mjs
init_constants();
function createObjectMethods(makeObject) {
  function object2(value) {
    return makeObject(value);
  }
  object2.system = (options) => {
    const mutable = options?.mutable;
    if (mutable !== void 0) return object2(Inputs.SharedObjectRef({
      objectId: SUI_SYSTEM_STATE_OBJECT_ID,
      initialSharedVersion: 1,
      mutable
    }));
    return object2({
      $kind: "UnresolvedObject",
      UnresolvedObject: {
        objectId: SUI_SYSTEM_STATE_OBJECT_ID,
        initialSharedVersion: 1
      }
    });
  };
  object2.clock = () => object2(Inputs.SharedObjectRef({
    objectId: SUI_CLOCK_OBJECT_ID,
    initialSharedVersion: 1,
    mutable: false
  }));
  object2.random = () => object2({
    $kind: "UnresolvedObject",
    UnresolvedObject: {
      objectId: SUI_RANDOM_OBJECT_ID,
      mutable: false
    }
  });
  object2.denyList = (options) => {
    return object2({
      $kind: "UnresolvedObject",
      UnresolvedObject: {
        objectId: SUI_DENY_LIST_OBJECT_ID,
        mutable: options?.mutable
      }
    });
  };
  object2.option = ({ type, value }) => (tx) => tx.moveCall({
    typeArguments: [type],
    target: `${MOVE_STDLIB_ADDRESS}::option::${value === null ? "none" : "some"}`,
    arguments: value === null ? [] : [tx.object(value)]
  });
  return object2;
}

// ../../node_modules/.pnpm/@mysten+sui@2.17.0_typescript@5.9.3/node_modules/@mysten/sui/dist/transactions/pure.mjs
init_pure();
init_bcs();
init_dist();
function createPure(makePure) {
  function pure(typeOrSerializedValue, value) {
    if (typeof typeOrSerializedValue === "string") return makePure(pureBcsSchemaFromTypeName(typeOrSerializedValue).serialize(value));
    if (typeOrSerializedValue instanceof Uint8Array || isSerializedBcs(typeOrSerializedValue)) return makePure(typeOrSerializedValue);
    throw new Error("tx.pure must be called either a bcs type name, or a serialized bcs value");
  }
  pure.u8 = (value) => makePure(suiBcs.U8.serialize(value));
  pure.u16 = (value) => makePure(suiBcs.U16.serialize(value));
  pure.u32 = (value) => makePure(suiBcs.U32.serialize(value));
  pure.u64 = (value) => makePure(suiBcs.U64.serialize(value));
  pure.u128 = (value) => makePure(suiBcs.U128.serialize(value));
  pure.u256 = (value) => makePure(suiBcs.U256.serialize(value));
  pure.bool = (value) => makePure(suiBcs.Bool.serialize(value));
  pure.string = (value) => makePure(suiBcs.String.serialize(value));
  pure.address = (value) => makePure(suiBcs.Address.serialize(value));
  pure.id = pure.address;
  pure.vector = (type, value) => {
    return makePure(suiBcs.vector(pureBcsSchemaFromTypeName(type)).serialize(value));
  };
  pure.option = (type, value) => {
    return makePure(suiBcs.option(pureBcsSchemaFromTypeName(type)).serialize(value));
  };
  return pure;
}

// ../../node_modules/.pnpm/@mysten+sui@2.17.0_typescript@5.9.3/node_modules/@mysten/sui/dist/transactions/plugins/NamedPackagesPlugin.mjs
function namedPackagesPlugin() {
  return async (transactionData, buildOptions, next) => {
    const names = findNamesInTransaction(transactionData);
    if (names.types.length === 0 && names.packages.length === 0) return next();
    if (!buildOptions.client) throw new Error(`Transaction contains MVR names but no client was provided to resolve them. Please pass a client to Transaction#build()`);
    replaceNames(transactionData, await buildOptions.client.core.mvr.resolve({
      types: names.types,
      packages: names.packages
    }));
    await next();
  };
}

// ../../node_modules/.pnpm/@mysten+sui@2.17.0_typescript@5.9.3/node_modules/@mysten/sui/dist/transactions/Transaction.mjs
init_dist();
function createTransactionResult(index, length = Infinity) {
  const baseResult = {
    $kind: "Result",
    get Result() {
      return typeof index === "function" ? index() : index;
    }
  };
  const nestedResults = [];
  const nestedResultFor = (resultIndex) => nestedResults[resultIndex] ??= {
    $kind: "NestedResult",
    get NestedResult() {
      return [typeof index === "function" ? index() : index, resultIndex];
    }
  };
  return new Proxy(baseResult, {
    set() {
      throw new Error("The transaction result is a proxy, and does not support setting properties directly");
    },
    get(target, property) {
      if (property in target) return Reflect.get(target, property);
      if (property === Symbol.iterator) return function* () {
        let i = 0;
        while (i < length) {
          yield nestedResultFor(i);
          i++;
        }
      };
      if (typeof property === "symbol") return;
      const resultIndex = parseInt(property, 10);
      if (Number.isNaN(resultIndex) || resultIndex < 0) return;
      return nestedResultFor(resultIndex);
    }
  });
}
var TRANSACTION_BRAND = /* @__PURE__ */ Symbol.for("@mysten/transaction");
function isTransaction(obj) {
  return !!obj && typeof obj === "object" && obj[TRANSACTION_BRAND] === true;
}
var Transaction = class Transaction2 {
  #serializationPlugins;
  #buildPlugins;
  #intentResolvers = /* @__PURE__ */ new Map();
  #inputSection = [];
  #commandSection = [];
  #availableResults = /* @__PURE__ */ new Set();
  #pendingPromises = /* @__PURE__ */ new Set();
  #added = /* @__PURE__ */ new Map();
  /**
  * Converts from a serialize transaction kind (built with `build({ onlyTransactionKind: true })`) to a `Transaction` class.
  * Supports either a byte array, or base64-encoded bytes.
  */
  static fromKind(serialized) {
    const tx = new Transaction2();
    tx.#data = TransactionDataBuilder.fromKindBytes(typeof serialized === "string" ? fromBase64(serialized) : serialized);
    tx.#inputSection = tx.#data.inputs.slice();
    tx.#commandSection = tx.#data.commands.slice();
    tx.#availableResults = new Set(tx.#commandSection.map((_, i) => i));
    return tx;
  }
  /**
  * Converts from a serialized transaction format to a `Transaction` class.
  * There are two supported serialized formats:
  * - A string returned from `Transaction#serialize`. The serialized format must be compatible, or it will throw an error.
  * - A byte array (or base64-encoded bytes) containing BCS transaction data.
  */
  static from(transaction) {
    const newTransaction = new Transaction2();
    if (isTransaction(transaction)) newTransaction.#data = TransactionDataBuilder.restore(transaction.getData());
    else if (typeof transaction !== "string" || !transaction.startsWith("{")) newTransaction.#data = TransactionDataBuilder.fromBytes(typeof transaction === "string" ? fromBase64(transaction) : transaction);
    else newTransaction.#data = TransactionDataBuilder.restore(JSON.parse(transaction));
    newTransaction.#inputSection = newTransaction.#data.inputs.slice();
    newTransaction.#commandSection = newTransaction.#data.commands.slice();
    newTransaction.#availableResults = new Set(newTransaction.#commandSection.map((_, i) => i));
    if (!newTransaction.isPreparedForSerialization({ supportedIntents: [COIN_WITH_BALANCE] })) throw new Error("Transaction has unresolved intents or async thunks. Call `prepareForSerialization` before copying.");
    if (newTransaction.#data.commands.some((cmd) => cmd.$Intent?.name === COIN_WITH_BALANCE)) newTransaction.addIntentResolver(COIN_WITH_BALANCE, resolveCoinBalance);
    return newTransaction;
  }
  addSerializationPlugin(step) {
    this.#serializationPlugins.push(step);
  }
  addBuildPlugin(step) {
    this.#buildPlugins.push(step);
  }
  addIntentResolver(intent, resolver) {
    if (this.#intentResolvers.has(intent) && this.#intentResolvers.get(intent) !== resolver) throw new Error(`Intent resolver for ${intent} already exists`);
    this.#intentResolvers.set(intent, resolver);
  }
  setSender(sender) {
    this.#data.sender = sender;
  }
  /**
  * Sets the sender only if it has not already been set.
  * This is useful for sponsored transaction flows where the sender may not be the same as the signer address.
  */
  setSenderIfNotSet(sender) {
    if (!this.#data.sender) this.#data.sender = sender;
  }
  setExpiration(expiration) {
    this.#data.expiration = expiration ? parse(TransactionExpiration, expiration) : null;
  }
  setGasPrice(price) {
    this.#data.gasData.price = String(price);
  }
  setGasBudget(budget) {
    this.#data.gasData.budget = String(budget);
  }
  setGasBudgetIfNotSet(budget) {
    if (this.#data.gasData.budget == null) this.#data.gasData.budget = String(budget);
  }
  setGasOwner(owner) {
    this.#data.gasData.owner = owner;
  }
  setGasPayment(payments) {
    this.#data.gasData.payment = payments.map((payment) => parse(ObjectRefSchema, payment));
  }
  #data;
  /** Get a snapshot of the transaction data, in JSON form: */
  getData() {
    return this.#data.snapshot();
  }
  get [TRANSACTION_BRAND]() {
    return true;
  }
  get pure() {
    Object.defineProperty(this, "pure", {
      enumerable: false,
      value: createPure((value) => {
        if (isSerializedBcs(value)) return this.#addInput("pure", {
          $kind: "Pure",
          Pure: { bytes: value.toBase64() }
        });
        return this.#addInput("pure", is(NormalizedCallArg, value) ? parse(NormalizedCallArg, value) : value instanceof Uint8Array ? Inputs.Pure(value) : {
          $kind: "UnresolvedPure",
          UnresolvedPure: { value }
        });
      })
    });
    return this.pure;
  }
  constructor() {
    this.object = createObjectMethods((value) => {
      if (typeof value === "function") return this.object(this.add(value));
      if (typeof value === "object" && is(ArgumentSchema, value)) return value;
      const id = getIdFromCallArg(value);
      const inserted = this.#data.inputs.find((i) => id === getIdFromCallArg(i));
      if (inserted?.Object?.SharedObject && typeof value === "object" && value.Object?.SharedObject) inserted.Object.SharedObject.mutable = inserted.Object.SharedObject.mutable || value.Object.SharedObject.mutable;
      return inserted ? {
        $kind: "Input",
        Input: this.#data.inputs.indexOf(inserted),
        type: "object"
      } : this.#addInput("object", typeof value === "string" ? {
        $kind: "UnresolvedObject",
        UnresolvedObject: { objectId: normalizeSuiAddress(value) }
      } : value);
    });
    this.#data = new TransactionDataBuilder();
    this.#buildPlugins = [];
    this.#serializationPlugins = [];
  }
  /** Returns an argument for the gas coin, to be used in a transaction. */
  get gas() {
    return {
      $kind: "GasCoin",
      GasCoin: true
    };
  }
  /**
  * Creates a coin of the specified type and balance.
  * Sourced from address balance when available, falling back to owned coins.
  */
  coin({ type, balance, useGasCoin }) {
    return this.add(coinWithBalance({
      type,
      balance,
      useGasCoin
    }));
  }
  /**
  * Creates a Balance object of the specified type and balance.
  * Sourced from address balance when available, falling back to owned coins.
  */
  balance({ type, balance, useGasCoin }) {
    return this.add(createBalance({
      type,
      balance,
      useGasCoin
    }));
  }
  /**
  * Add a new object input to the transaction using the fully-resolved object reference.
  * If you only have an object ID, use `builder.object(id)` instead.
  */
  objectRef(...args) {
    return this.object(Inputs.ObjectRef(...args));
  }
  /**
  * Add a new receiving input to the transaction using the fully-resolved object reference.
  * If you only have an object ID, use `builder.object(id)` instead.
  */
  receivingRef(...args) {
    return this.object(Inputs.ReceivingRef(...args));
  }
  /**
  * Add a new shared object input to the transaction using the fully-resolved shared object reference.
  * If you only have an object ID, use `builder.object(id)` instead.
  */
  sharedObjectRef(...args) {
    return this.object(Inputs.SharedObjectRef(...args));
  }
  #fork() {
    const fork = new Transaction2();
    fork.#data = this.#data;
    fork.#serializationPlugins = this.#serializationPlugins;
    fork.#buildPlugins = this.#buildPlugins;
    fork.#intentResolvers = this.#intentResolvers;
    fork.#pendingPromises = this.#pendingPromises;
    fork.#availableResults = new Set(this.#availableResults);
    fork.#added = this.#added;
    this.#inputSection.push(fork.#inputSection);
    this.#commandSection.push(fork.#commandSection);
    return fork;
  }
  add(command) {
    if (typeof command === "function") {
      if (this.#added.has(command)) return this.#added.get(command);
      const fork = this.#fork();
      const result = command(fork);
      if (!(result && typeof result === "object" && "then" in result)) {
        this.#availableResults = fork.#availableResults;
        this.#added.set(command, result);
        return result;
      }
      const placeholder = this.#addCommand({
        $kind: "$Intent",
        $Intent: {
          name: "AsyncTransactionThunk",
          inputs: {},
          data: {
            resultIndex: this.#data.commands.length,
            result: null
          }
        }
      });
      this.#pendingPromises.add(Promise.resolve(result).then((result$1) => {
        placeholder.$Intent.data.result = result$1;
      }));
      const txResult = createTransactionResult(() => placeholder.$Intent.data.resultIndex);
      this.#added.set(command, txResult);
      return txResult;
    } else this.#addCommand(command);
    return createTransactionResult(this.#data.commands.length - 1);
  }
  #addCommand(command) {
    const resultIndex = this.#data.commands.length;
    this.#commandSection.push(command);
    this.#availableResults.add(resultIndex);
    this.#data.commands.push(command);
    this.#data.mapCommandArguments(resultIndex, (arg) => {
      if (arg.$kind === "Result" && !this.#availableResults.has(arg.Result)) throw new Error(`Result { Result: ${arg.Result} } is not available to use in the current transaction`);
      if (arg.$kind === "NestedResult" && !this.#availableResults.has(arg.NestedResult[0])) throw new Error(`Result { NestedResult: [${arg.NestedResult[0]}, ${arg.NestedResult[1]}] } is not available to use in the current transaction`);
      if (arg.$kind === "Input" && arg.Input >= this.#data.inputs.length) throw new Error(`Input { Input: ${arg.Input} } references an input that does not exist in the current transaction`);
      return arg;
    });
    return command;
  }
  #addInput(type, input) {
    this.#inputSection.push(input);
    return this.#data.addInput(type, input);
  }
  #normalizeTransactionArgument(arg) {
    if (isSerializedBcs(arg)) return this.pure(arg);
    return this.#resolveArgument(arg);
  }
  #resolveArgument(arg) {
    if (typeof arg === "function") {
      const resolved = this.add(arg);
      if (typeof resolved === "function") return this.#resolveArgument(resolved);
      return parse(ArgumentSchema, resolved);
    }
    return parse(ArgumentSchema, arg);
  }
  splitCoins(coin, amounts) {
    const command = TransactionCommands.SplitCoins(typeof coin === "string" ? this.object(coin) : this.#resolveArgument(coin), amounts.map((amount) => typeof amount === "number" || typeof amount === "bigint" || typeof amount === "string" ? this.pure.u64(amount) : this.#normalizeTransactionArgument(amount)));
    this.#addCommand(command);
    return createTransactionResult(this.#data.commands.length - 1, amounts.length);
  }
  mergeCoins(destination, sources) {
    return this.add(TransactionCommands.MergeCoins(this.object(destination), sources.map((src) => this.object(src))));
  }
  publish({ modules, dependencies }) {
    return this.add(TransactionCommands.Publish({
      modules,
      dependencies
    }));
  }
  upgrade({ modules, dependencies, package: packageId, ticket }) {
    return this.add(TransactionCommands.Upgrade({
      modules,
      dependencies,
      package: packageId,
      ticket: this.object(ticket)
    }));
  }
  moveCall({ arguments: args, ...input }) {
    return this.add(TransactionCommands.MoveCall({
      ...input,
      arguments: args?.map((arg) => this.#normalizeTransactionArgument(arg))
    }));
  }
  transferObjects(objects, address) {
    return this.add(TransactionCommands.TransferObjects(objects.map((obj) => this.object(obj)), typeof address === "string" ? this.pure.address(address) : this.#normalizeTransactionArgument(address)));
  }
  makeMoveVec({ type, elements }) {
    return this.add(TransactionCommands.MakeMoveVec({
      type,
      elements: elements.map((obj) => this.object(obj))
    }));
  }
  /**
  * Create a FundsWithdrawal input for withdrawing Balance<T> from an address balance accumulator.
  * This is used for gas payments from address balances.
  *
  * @param options.amount - The Amount to withdraw (u64).
  * @param options.type - The balance type (e.g., "0x2::sui::SUI"). Defaults to SUI.
  */
  withdrawal({ amount, type }) {
    const input = {
      $kind: "FundsWithdrawal",
      FundsWithdrawal: {
        reservation: {
          $kind: "MaxAmountU64",
          MaxAmountU64: String(amount)
        },
        typeArg: {
          $kind: "Balance",
          Balance: type ?? "0x2::sui::SUI"
        },
        withdrawFrom: {
          $kind: "Sender",
          Sender: true
        }
      }
    };
    return this.#addInput("object", input);
  }
  /**
  * @deprecated Use toJSON instead.
  * For synchronous serialization, you can use `getData()`
  * */
  serialize() {
    return JSON.stringify(serializeV1TransactionData(this.#data.snapshot()));
  }
  async toJSON(options = {}) {
    await this.prepareForSerialization(options);
    const fullyResolved = this.isFullyResolved();
    return JSON.stringify(parse(SerializedTransactionDataV2Schema, fullyResolved ? {
      ...this.#data.snapshot(),
      digest: this.#data.getDigest()
    } : this.#data.snapshot()), (_key, value) => typeof value === "bigint" ? value.toString() : value, 2);
  }
  /** Build the transaction to BCS bytes, and sign it with the provided keypair. */
  async sign(options) {
    const { signer, ...buildOptions } = options;
    const bytes = await this.build(buildOptions);
    return signer.signTransaction(bytes);
  }
  /**
  * Checks if the transaction is prepared for serialization to JSON.
  * This means:
  *  - All async thunks have been fully resolved
  *  - All transaction intents have been resolved (unless in supportedIntents)
  *
  * Unlike `isFullyResolved()`, this does not require the sender, gas payment,
  * budget, or object versions to be set.
  */
  isPreparedForSerialization(options = {}) {
    if (this.#pendingPromises.size > 0) return false;
    if (this.#data.commands.some((cmd) => cmd.$Intent && !options.supportedIntents?.includes(cmd.$Intent.name))) return false;
    return true;
  }
  /**
  *  Ensures that:
  *  - All objects have been fully resolved to a specific version
  *  - All pure inputs have been serialized to bytes
  *  - All async thunks have been fully resolved
  *  - All transaction intents have been resolved
  * 	- The gas payment, budget, and price have been set
  *  - The transaction sender has been set
  *
  *  When true, the transaction will always be built to the same bytes and digest (unless the transaction is mutated)
  */
  isFullyResolved() {
    if (!this.isPreparedForSerialization()) return false;
    if (!this.#data.sender) return false;
    if (needsTransactionResolution(this.#data, {})) return false;
    return true;
  }
  /** Build the transaction to BCS bytes. */
  async build(options = {}) {
    await this.prepareForSerialization(options);
    await this.#prepareBuild(options);
    return this.#data.build({ onlyTransactionKind: options.onlyTransactionKind });
  }
  /** Derive transaction digest */
  async getDigest(options = {}) {
    await this.prepareForSerialization(options);
    await this.#prepareBuild(options);
    return this.#data.getDigest();
  }
  /**
  * Prepare the transaction by validating the transaction data and resolving all inputs
  * so that it can be built into bytes.
  */
  async #prepareBuild(options) {
    if (!options.onlyTransactionKind && !this.#data.sender) throw new Error("Missing transaction sender");
    await this.#runPlugins([...this.#buildPlugins, resolveTransactionPlugin], options);
  }
  async #runPlugins(plugins, options) {
    try {
      const createNext = (i) => {
        if (i >= plugins.length) return () => {
        };
        const plugin = plugins[i];
        return async () => {
          const next = createNext(i + 1);
          let calledNext = false;
          let nextResolved = false;
          await plugin(this.#data, options, async () => {
            if (calledNext) throw new Error(`next() was call multiple times in TransactionPlugin ${i}`);
            calledNext = true;
            await next();
            nextResolved = true;
          });
          if (!calledNext) throw new Error(`next() was not called in TransactionPlugin ${i}`);
          if (!nextResolved) throw new Error(`next() was not awaited in TransactionPlugin ${i}`);
        };
      };
      await createNext(0)();
    } finally {
      this.#inputSection = this.#data.inputs.slice();
      this.#commandSection = this.#data.commands.slice();
      this.#availableResults = new Set(this.#commandSection.map((_, i) => i));
    }
  }
  async #waitForPendingTasks() {
    while (this.#pendingPromises.size > 0) {
      const newPromise = Promise.all(this.#pendingPromises);
      this.#pendingPromises.clear();
      this.#pendingPromises.add(newPromise);
      await newPromise;
      this.#pendingPromises.delete(newPromise);
    }
  }
  #sortCommandsAndInputs() {
    const unorderedCommands = this.#data.commands;
    const unorderedInputs = this.#data.inputs;
    const orderedCommands = this.#commandSection.flat(Infinity);
    const orderedInputs = this.#inputSection.flat(Infinity);
    if (orderedCommands.length !== unorderedCommands.length) throw new Error("Unexpected number of commands found in transaction data");
    if (orderedInputs.length !== unorderedInputs.length) throw new Error("Unexpected number of inputs found in transaction data");
    const filteredCommands = orderedCommands.filter((cmd) => cmd.$Intent?.name !== "AsyncTransactionThunk");
    this.#data.commands = filteredCommands;
    this.#data.inputs = orderedInputs;
    this.#commandSection = filteredCommands;
    this.#inputSection = orderedInputs;
    this.#availableResults = new Set(filteredCommands.map((_, i) => i));
    function getOriginalIndex(index) {
      const command = unorderedCommands[index];
      if (command.$Intent?.name === "AsyncTransactionThunk") {
        const result = command.$Intent.data.result;
        if (result == null) throw new Error("AsyncTransactionThunk has not been resolved");
        return getOriginalIndex(result.Result);
      }
      const updated = filteredCommands.indexOf(command);
      if (updated === -1) throw new Error("Unable to find original index for command");
      return updated;
    }
    this.#data.mapArguments((arg) => {
      if (arg.$kind === "Input") {
        const updated = orderedInputs.indexOf(unorderedInputs[arg.Input]);
        if (updated === -1) throw new Error("Input has not been resolved");
        return {
          ...arg,
          Input: updated
        };
      } else if (arg.$kind === "Result") {
        const updated = getOriginalIndex(arg.Result);
        return {
          ...arg,
          Result: updated
        };
      } else if (arg.$kind === "NestedResult") {
        const updated = getOriginalIndex(arg.NestedResult[0]);
        return {
          ...arg,
          NestedResult: [updated, arg.NestedResult[1]]
        };
      }
      return arg;
    });
    for (const [i, cmd] of unorderedCommands.entries()) if (cmd.$Intent?.name === "AsyncTransactionThunk") try {
      cmd.$Intent.data.resultIndex = getOriginalIndex(i);
    } catch {
    }
  }
  async prepareForSerialization(options) {
    await this.#waitForPendingTasks();
    this.#sortCommandsAndInputs();
    const intents = /* @__PURE__ */ new Set();
    for (const command of this.#data.commands) if (command.$Intent) intents.add(command.$Intent.name);
    const steps = [...this.#serializationPlugins];
    for (const intent of intents) {
      if (options.supportedIntents?.includes(intent)) continue;
      if (!this.#intentResolvers.has(intent)) throw new Error(`Missing intent resolver for ${intent}`);
      steps.push(this.#intentResolvers.get(intent));
    }
    steps.push(namedPackagesPlugin());
    await this.#runPlugins(steps, options);
  }
};

export {
  coinWithBalance,
  isCoinReservationDigest,
  computeGasBudget,
  coreClientResolveTransactionPlugin,
  isTransaction,
  Transaction
};
//# sourceMappingURL=chunk-N5MEZ42L.js.map