@msafe/sui3-sdk 1.0.21 → 1.0.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -352,6 +352,18 @@ declare class InsufficientGasFundsError extends Error {
352
352
  * storageRebate is refunded after execution and must not reduce the budget.
353
353
  */
354
354
  declare function computeGasBudget(gasUsed: Pick<SuiClientTypes.GasCostSummary, 'computationCost' | 'storageCost'>, gasPrice: bigint): bigint;
355
+ /** Object IDs a built payload already pins (inputs + gas payment). */
356
+ declare function collectPayloadObjectIds(payload: string | Uint8Array): string[];
357
+ /**
358
+ * Parked queue item: intention was saved with a built hex payload + digest
359
+ * so build-next can promote it without rebuilding.
360
+ */
361
+ declare function parkedPayloadHex(intention: unknown): string | undefined;
362
+ /** Coins already pinned by the current pending tx and any parked future payloads. */
363
+ declare function collectQueueExcludeObjectIds(input: {
364
+ pendingPayload?: string;
365
+ parkedPayloads?: Array<string | undefined>;
366
+ }): string[];
355
367
  /**
356
368
  * Select gas funding before tx.build() according to mixed coin/addressBalance policy:
357
369
  * 1) budget without storageRebate (caller supplies computeGasBudget result)
@@ -365,12 +377,15 @@ declare function selectGasFunding(input: {
365
377
  suiClient: SuiGrpcClient;
366
378
  owner: string;
367
379
  gasBudget: bigint;
380
+ excludeObjectIds?: Iterable<string>;
368
381
  }): Promise<GasFundingResult>;
369
382
  declare function estimateGasBudget(input: {
370
383
  tx: Transaction;
371
384
  suiClient: SuiGrpcClient;
372
385
  owner: string;
373
386
  gasPrice: bigint;
387
+ excludeObjectIds?: Iterable<string>;
388
+ preferAddressBalance?: boolean;
374
389
  }): Promise<bigint>;
375
390
  /**
376
391
  * Resolve gasBudget (no rebate) and apply gas funding selection before build.
@@ -381,6 +396,16 @@ declare function prepareGasFunding(input: {
381
396
  owner: string;
382
397
  gasPrice: bigint;
383
398
  gasBudget?: bigint;
399
+ /**
400
+ * Force Address Balance gas (`payment: []`). Prefer {@link excludeObjectIds}
401
+ * for queue-behind-pending so unused SUI coins can still pay.
402
+ */
403
+ preferAddressBalance?: boolean;
404
+ /**
405
+ * Queue-behind-pending: do not pick coins the current pending / parked
406
+ * payloads already pin. Those versions will change when the earlier tx executes.
407
+ */
408
+ excludeObjectIds?: Iterable<string>;
384
409
  }): Promise<GasFundingResult>;
385
410
  /**
386
411
  * @deprecated Use {@link prepareGasFunding} / {@link selectGasFunding}.
@@ -398,7 +423,12 @@ declare class Simulator {
398
423
  simulate(input: {
399
424
  txb: Transaction;
400
425
  sender: string;
426
+ preferAddressBalance?: boolean;
427
+ excludeObjectIds?: Iterable<string>;
401
428
  }): Promise<SimulationResult>;
429
+ /** Dry-run a frozen payload without re-selecting gas. */
430
+ simulateBuilt(built: Uint8Array): Promise<SimulationResult>;
431
+ private inspectBuilt;
402
432
  private getGasPrice;
403
433
  private toGasBudget;
404
434
  private copyTransaction;
@@ -440,10 +470,14 @@ declare class MSafeAccount {
440
470
  nextSequenceNumber(): Promise<number>;
441
471
  simulateIntention(request: Omit<IProposeIntentionRequest, 'msafeAddress' | 'signature'> & {
442
472
  txb?: Transaction;
473
+ preferAddressBalance?: boolean;
474
+ excludeObjectIds?: Iterable<string>;
443
475
  }): Promise<SimulationResult>;
444
476
  proposeIntention(input: Omit<IProposeIntentionRequest, 'signature' | 'msafeAddress'>): Promise<void>;
445
477
  proposeIntentionAndBuildVote(input: Omit<IProposeIntentionAndBuildAndVoteRequest, 'signature' | 'msafeAddress' | 'payload' | 'digest'> & {
446
478
  txb?: Transaction;
479
+ preferAddressBalance?: boolean;
480
+ excludeObjectIds?: Iterable<string>;
447
481
  }): Promise<void>;
448
482
  simulateCoinTransferIntention(intention: CoinTransferIntention): Promise<SimulationResult>;
449
483
  proposeCoinTransferIntention(intention: CoinTransferIntention): Promise<void>;
@@ -609,4 +643,4 @@ declare function getIntentionContent(intention: unknown): unknown;
609
643
  */
610
644
  declare function transactionFromContent(content: unknown): Transaction;
611
645
 
612
- export { AddressBookSDK, COIN_RESERVATION_MAGIC, COIN_TYPE_ARG_REGEX, Coin, CoinHelper, CreateHelper, type CreateMSafeInfo, DEV_API_URL, DEV_SYNCING_URL, ENV_CONFIGS, Formatter, type FutureIntention, type GasFundingMode, type GasFundingResult, type GasObjectReference, HexToUint8Array, type HistorySendTx, type HistoryVote, type IWallet, InfoTypeEnabledDto, InfoTypeKey, InsufficientGasFundsError, LOCAL_API_URL, LOCAL_SYNCING_URL, MAINNET_RPC_URL, MSafeAccount, MSafeClient, type MSafeConfig, type MSafeConfigOptions, MSafeEnabledDto, MSafeEnv, MSafeGlobals, type NotificationData, type NotificationInfo, NotificationSubscribeDto, NotificationUpdateDto, PREV_API_URL, PROD_API_URL, type Pagination, type PendingTx, type PendingVote, type ProposeIntention, type ReceiveTransaction, SUI_COIN, SignatureVerifier, type SimulateDryRunResponse, type SimulationFailedResult, type SimulationOption, type SimulationResult, type SimulationSuccessResult, TESTNET_RPC_URL, Uint8ArrayToHex, addPrefix, computeGasBudget, createCoinReservationRef, estimateGasBudget, getAllCoins, getIntentionContent, getMSafeConfig, getPublicKeyFromChain, httpUrlToGrpcBaseUrl, isCoinReservationDigest, msafeChainToSuiNetwork, preferClassicGasPayment, prepareGasFunding, selectGasFunding, stringToBuffer, toSuiTransaction, transactionFromContent };
646
+ export { AddressBookSDK, COIN_RESERVATION_MAGIC, COIN_TYPE_ARG_REGEX, Coin, CoinHelper, CreateHelper, type CreateMSafeInfo, DEV_API_URL, DEV_SYNCING_URL, ENV_CONFIGS, Formatter, type FutureIntention, type GasFundingMode, type GasFundingResult, type GasObjectReference, HexToUint8Array, type HistorySendTx, type HistoryVote, type IWallet, InfoTypeEnabledDto, InfoTypeKey, InsufficientGasFundsError, LOCAL_API_URL, LOCAL_SYNCING_URL, MAINNET_RPC_URL, MSafeAccount, MSafeClient, type MSafeConfig, type MSafeConfigOptions, MSafeEnabledDto, MSafeEnv, MSafeGlobals, type NotificationData, type NotificationInfo, NotificationSubscribeDto, NotificationUpdateDto, PREV_API_URL, PROD_API_URL, type Pagination, type PendingTx, type PendingVote, type ProposeIntention, type ReceiveTransaction, SUI_COIN, SignatureVerifier, type SimulateDryRunResponse, type SimulationFailedResult, type SimulationOption, type SimulationResult, type SimulationSuccessResult, TESTNET_RPC_URL, Uint8ArrayToHex, addPrefix, collectPayloadObjectIds, collectQueueExcludeObjectIds, computeGasBudget, createCoinReservationRef, estimateGasBudget, getAllCoins, getIntentionContent, getMSafeConfig, getPublicKeyFromChain, httpUrlToGrpcBaseUrl, isCoinReservationDigest, msafeChainToSuiNetwork, parkedPayloadHex, preferClassicGasPayment, prepareGasFunding, selectGasFunding, stringToBuffer, toSuiTransaction, transactionFromContent };
package/dist/index.d.ts CHANGED
@@ -352,6 +352,18 @@ declare class InsufficientGasFundsError extends Error {
352
352
  * storageRebate is refunded after execution and must not reduce the budget.
353
353
  */
354
354
  declare function computeGasBudget(gasUsed: Pick<SuiClientTypes.GasCostSummary, 'computationCost' | 'storageCost'>, gasPrice: bigint): bigint;
355
+ /** Object IDs a built payload already pins (inputs + gas payment). */
356
+ declare function collectPayloadObjectIds(payload: string | Uint8Array): string[];
357
+ /**
358
+ * Parked queue item: intention was saved with a built hex payload + digest
359
+ * so build-next can promote it without rebuilding.
360
+ */
361
+ declare function parkedPayloadHex(intention: unknown): string | undefined;
362
+ /** Coins already pinned by the current pending tx and any parked future payloads. */
363
+ declare function collectQueueExcludeObjectIds(input: {
364
+ pendingPayload?: string;
365
+ parkedPayloads?: Array<string | undefined>;
366
+ }): string[];
355
367
  /**
356
368
  * Select gas funding before tx.build() according to mixed coin/addressBalance policy:
357
369
  * 1) budget without storageRebate (caller supplies computeGasBudget result)
@@ -365,12 +377,15 @@ declare function selectGasFunding(input: {
365
377
  suiClient: SuiGrpcClient;
366
378
  owner: string;
367
379
  gasBudget: bigint;
380
+ excludeObjectIds?: Iterable<string>;
368
381
  }): Promise<GasFundingResult>;
369
382
  declare function estimateGasBudget(input: {
370
383
  tx: Transaction;
371
384
  suiClient: SuiGrpcClient;
372
385
  owner: string;
373
386
  gasPrice: bigint;
387
+ excludeObjectIds?: Iterable<string>;
388
+ preferAddressBalance?: boolean;
374
389
  }): Promise<bigint>;
375
390
  /**
376
391
  * Resolve gasBudget (no rebate) and apply gas funding selection before build.
@@ -381,6 +396,16 @@ declare function prepareGasFunding(input: {
381
396
  owner: string;
382
397
  gasPrice: bigint;
383
398
  gasBudget?: bigint;
399
+ /**
400
+ * Force Address Balance gas (`payment: []`). Prefer {@link excludeObjectIds}
401
+ * for queue-behind-pending so unused SUI coins can still pay.
402
+ */
403
+ preferAddressBalance?: boolean;
404
+ /**
405
+ * Queue-behind-pending: do not pick coins the current pending / parked
406
+ * payloads already pin. Those versions will change when the earlier tx executes.
407
+ */
408
+ excludeObjectIds?: Iterable<string>;
384
409
  }): Promise<GasFundingResult>;
385
410
  /**
386
411
  * @deprecated Use {@link prepareGasFunding} / {@link selectGasFunding}.
@@ -398,7 +423,12 @@ declare class Simulator {
398
423
  simulate(input: {
399
424
  txb: Transaction;
400
425
  sender: string;
426
+ preferAddressBalance?: boolean;
427
+ excludeObjectIds?: Iterable<string>;
401
428
  }): Promise<SimulationResult>;
429
+ /** Dry-run a frozen payload without re-selecting gas. */
430
+ simulateBuilt(built: Uint8Array): Promise<SimulationResult>;
431
+ private inspectBuilt;
402
432
  private getGasPrice;
403
433
  private toGasBudget;
404
434
  private copyTransaction;
@@ -440,10 +470,14 @@ declare class MSafeAccount {
440
470
  nextSequenceNumber(): Promise<number>;
441
471
  simulateIntention(request: Omit<IProposeIntentionRequest, 'msafeAddress' | 'signature'> & {
442
472
  txb?: Transaction;
473
+ preferAddressBalance?: boolean;
474
+ excludeObjectIds?: Iterable<string>;
443
475
  }): Promise<SimulationResult>;
444
476
  proposeIntention(input: Omit<IProposeIntentionRequest, 'signature' | 'msafeAddress'>): Promise<void>;
445
477
  proposeIntentionAndBuildVote(input: Omit<IProposeIntentionAndBuildAndVoteRequest, 'signature' | 'msafeAddress' | 'payload' | 'digest'> & {
446
478
  txb?: Transaction;
479
+ preferAddressBalance?: boolean;
480
+ excludeObjectIds?: Iterable<string>;
447
481
  }): Promise<void>;
448
482
  simulateCoinTransferIntention(intention: CoinTransferIntention): Promise<SimulationResult>;
449
483
  proposeCoinTransferIntention(intention: CoinTransferIntention): Promise<void>;
@@ -609,4 +643,4 @@ declare function getIntentionContent(intention: unknown): unknown;
609
643
  */
610
644
  declare function transactionFromContent(content: unknown): Transaction;
611
645
 
612
- export { AddressBookSDK, COIN_RESERVATION_MAGIC, COIN_TYPE_ARG_REGEX, Coin, CoinHelper, CreateHelper, type CreateMSafeInfo, DEV_API_URL, DEV_SYNCING_URL, ENV_CONFIGS, Formatter, type FutureIntention, type GasFundingMode, type GasFundingResult, type GasObjectReference, HexToUint8Array, type HistorySendTx, type HistoryVote, type IWallet, InfoTypeEnabledDto, InfoTypeKey, InsufficientGasFundsError, LOCAL_API_URL, LOCAL_SYNCING_URL, MAINNET_RPC_URL, MSafeAccount, MSafeClient, type MSafeConfig, type MSafeConfigOptions, MSafeEnabledDto, MSafeEnv, MSafeGlobals, type NotificationData, type NotificationInfo, NotificationSubscribeDto, NotificationUpdateDto, PREV_API_URL, PROD_API_URL, type Pagination, type PendingTx, type PendingVote, type ProposeIntention, type ReceiveTransaction, SUI_COIN, SignatureVerifier, type SimulateDryRunResponse, type SimulationFailedResult, type SimulationOption, type SimulationResult, type SimulationSuccessResult, TESTNET_RPC_URL, Uint8ArrayToHex, addPrefix, computeGasBudget, createCoinReservationRef, estimateGasBudget, getAllCoins, getIntentionContent, getMSafeConfig, getPublicKeyFromChain, httpUrlToGrpcBaseUrl, isCoinReservationDigest, msafeChainToSuiNetwork, preferClassicGasPayment, prepareGasFunding, selectGasFunding, stringToBuffer, toSuiTransaction, transactionFromContent };
646
+ export { AddressBookSDK, COIN_RESERVATION_MAGIC, COIN_TYPE_ARG_REGEX, Coin, CoinHelper, CreateHelper, type CreateMSafeInfo, DEV_API_URL, DEV_SYNCING_URL, ENV_CONFIGS, Formatter, type FutureIntention, type GasFundingMode, type GasFundingResult, type GasObjectReference, HexToUint8Array, type HistorySendTx, type HistoryVote, type IWallet, InfoTypeEnabledDto, InfoTypeKey, InsufficientGasFundsError, LOCAL_API_URL, LOCAL_SYNCING_URL, MAINNET_RPC_URL, MSafeAccount, MSafeClient, type MSafeConfig, type MSafeConfigOptions, MSafeEnabledDto, MSafeEnv, MSafeGlobals, type NotificationData, type NotificationInfo, NotificationSubscribeDto, NotificationUpdateDto, PREV_API_URL, PROD_API_URL, type Pagination, type PendingTx, type PendingVote, type ProposeIntention, type ReceiveTransaction, SUI_COIN, SignatureVerifier, type SimulateDryRunResponse, type SimulationFailedResult, type SimulationOption, type SimulationResult, type SimulationSuccessResult, TESTNET_RPC_URL, Uint8ArrayToHex, addPrefix, collectPayloadObjectIds, collectQueueExcludeObjectIds, computeGasBudget, createCoinReservationRef, estimateGasBudget, getAllCoins, getIntentionContent, getMSafeConfig, getPublicKeyFromChain, httpUrlToGrpcBaseUrl, isCoinReservationDigest, msafeChainToSuiNetwork, parkedPayloadHex, preferClassicGasPayment, prepareGasFunding, selectGasFunding, stringToBuffer, toSuiTransaction, transactionFromContent };
package/dist/index.js CHANGED
@@ -134,7 +134,7 @@ import {
134
134
  isSameAddress as isSameAddress2
135
135
  } from "@msafe/sui3-utils";
136
136
  import { Transaction as Transaction4 } from "@mysten/sui/transactions";
137
- import { fromHex as fromHex3, normalizeStructTag as normalizeStructTag4, toHex as toHex2 } from "@mysten/sui/utils";
137
+ import { fromHex as fromHex4, normalizeStructTag as normalizeStructTag4, toHex as toHex2 } from "@mysten/sui/utils";
138
138
  import { SUI_MAINNET_CHAIN, SUI_TESTNET_CHAIN } from "@mysten/wallet-standard";
139
139
 
140
140
  // src/simulate/simulator.ts
@@ -142,7 +142,7 @@ import { Transaction as Transaction2 } from "@mysten/sui/transactions";
142
142
 
143
143
  // src/utils/gasFunding.ts
144
144
  import { Transaction } from "@mysten/sui/transactions";
145
- import { normalizeStructTag as normalizeStructTag3, normalizeSuiObjectId } from "@mysten/sui/utils";
145
+ import { fromHex as fromHex2, normalizeStructTag as normalizeStructTag3, normalizeSuiObjectId } from "@mysten/sui/utils";
146
146
 
147
147
  // src/utils/coinReservation.ts
148
148
  import { bcs, TypeTagSerializer } from "@mysten/sui/bcs";
@@ -437,18 +437,66 @@ function computeGasBudget(gasUsed, gasPrice) {
437
437
  return BigInt(computationCost) + BigInt(storageCost) + safeOverhead;
438
438
  }
439
439
  function collectUsedObjectIds(tx) {
440
- return tx.getData().inputs.reduce((used, input) => {
440
+ const used = tx.getData().inputs.reduce((acc, input) => {
441
441
  const immOrOwned = input.Object?.ImmOrOwnedObject?.objectId;
442
442
  if (immOrOwned) {
443
- used.add(normalizeSuiObjectId(immOrOwned));
444
- return used;
443
+ acc.add(normalizeSuiObjectId(immOrOwned));
444
+ return acc;
445
445
  }
446
446
  const unresolved = input.UnresolvedObject?.objectId;
447
447
  if (unresolved) {
448
- used.add(normalizeSuiObjectId(unresolved));
448
+ acc.add(normalizeSuiObjectId(unresolved));
449
449
  }
450
- return used;
450
+ return acc;
451
451
  }, /* @__PURE__ */ new Set());
452
+ (tx.getData().gasData.payment ?? []).forEach((payment) => {
453
+ if (payment.objectId) {
454
+ used.add(normalizeSuiObjectId(payment.objectId));
455
+ }
456
+ });
457
+ return used;
458
+ }
459
+ function addExcludeObjectIds(used, excludeObjectIds) {
460
+ Array.from(excludeObjectIds ?? [], (id) => used.add(normalizeSuiObjectId(id)));
461
+ return used;
462
+ }
463
+ function payloadToTransaction(payload) {
464
+ if (typeof payload !== "string") {
465
+ return Transaction.from(payload);
466
+ }
467
+ if (/^[0-9a-fA-F]+$/.test(payload) && payload.length % 2 === 0) {
468
+ return Transaction.from(fromHex2(payload));
469
+ }
470
+ return Transaction.from(payload);
471
+ }
472
+ function collectPayloadObjectIds(payload) {
473
+ return [...collectUsedObjectIds(payloadToTransaction(payload))];
474
+ }
475
+ function parkedPayloadHex(intention) {
476
+ if (!intention || typeof intention !== "object") {
477
+ return void 0;
478
+ }
479
+ const { content, digest } = intention;
480
+ if (typeof content !== "string" || typeof digest !== "string" || !digest) {
481
+ return void 0;
482
+ }
483
+ if (!/^[0-9a-fA-F]+$/.test(content) || content.length < 64) {
484
+ return void 0;
485
+ }
486
+ return content;
487
+ }
488
+ function collectQueueExcludeObjectIds(input) {
489
+ const ids = /* @__PURE__ */ new Set();
490
+ if (input.pendingPayload) {
491
+ collectPayloadObjectIds(input.pendingPayload).forEach((id) => ids.add(id));
492
+ }
493
+ (input.parkedPayloads ?? []).forEach((payload) => {
494
+ if (!payload) {
495
+ return;
496
+ }
497
+ collectPayloadObjectIds(payload).forEach((id) => ids.add(id));
498
+ });
499
+ return [...ids];
452
500
  }
453
501
  function txConsumesOwnedSuiCoins(tx) {
454
502
  return tx.getData().commands.some((cmd) => {
@@ -466,8 +514,8 @@ function txConsumesOwnedSuiCoins(tx) {
466
514
  }
467
515
  });
468
516
  }
469
- async function loadSuiGasFunding(suiClient, owner, tx) {
470
- const usedObjectIds = collectUsedObjectIds(tx);
517
+ async function loadSuiGasFunding(suiClient, owner, tx, excludeObjectIds) {
518
+ const usedObjectIds = addExcludeObjectIds(collectUsedObjectIds(tx), excludeObjectIds);
471
519
  const [coins, balanceRes] = await Promise.all([
472
520
  getAllCoins({ suiClient, owner, coinType: SUI_COIN }),
473
521
  suiClient.getBalance({ owner, coinType: SUI_COIN })
@@ -518,7 +566,7 @@ async function selectGasFunding(input) {
518
566
  const { tx, suiClient, owner, gasBudget } = input;
519
567
  const { payment } = tx.getData().gasData;
520
568
  if (payment != null && payment.length > 0) {
521
- const funding2 = await loadSuiGasFunding(suiClient, owner, tx);
569
+ const funding2 = await loadSuiGasFunding(suiClient, owner, tx, input.excludeObjectIds);
522
570
  return {
523
571
  mode: "classic",
524
572
  gasBudget,
@@ -526,7 +574,7 @@ async function selectGasFunding(input) {
526
574
  addressBalance: funding2.addressBalance
527
575
  };
528
576
  }
529
- const funding = await loadSuiGasFunding(suiClient, owner, tx);
577
+ const funding = await loadSuiGasFunding(suiClient, owner, tx, input.excludeObjectIds);
530
578
  const { paymentCoins, coinBalance, addressBalance, total } = funding;
531
579
  if (total < gasBudget) {
532
580
  throw new InsufficientGasFundsError(gasBudget, coinBalance, addressBalance);
@@ -572,8 +620,13 @@ function isPositiveBudget(budget) {
572
620
  }
573
621
  async function estimateGasBudget(input) {
574
622
  const { tx, suiClient, owner, gasPrice } = input;
575
- const funding = await loadSuiGasFunding(suiClient, owner, tx);
576
- if (funding.total <= 0n) {
623
+ const funding = input.preferAddressBalance ? {
624
+ ...await loadSuiGasFunding(suiClient, owner, tx, input.excludeObjectIds),
625
+ paymentCoins: [],
626
+ coinBalance: 0n
627
+ } : await loadSuiGasFunding(suiClient, owner, tx, input.excludeObjectIds);
628
+ const fundingTotal = input.preferAddressBalance ? funding.addressBalance : funding.total;
629
+ if (fundingTotal <= 0n) {
577
630
  throw new InsufficientGasFundsError(0n, funding.coinBalance, funding.addressBalance);
578
631
  }
579
632
  const { budget, payment } = tx.getData().gasData;
@@ -606,7 +659,7 @@ async function estimateGasBudget(input) {
606
659
  return computeGasBudget(effects.gasUsed, gasPrice);
607
660
  }
608
661
  async function prepareGasFunding(input) {
609
- const { tx, suiClient, owner, gasPrice } = input;
662
+ const { tx, suiClient, owner, gasPrice, excludeObjectIds } = input;
610
663
  const { payment, budget: existingBudget } = tx.getData().gasData;
611
664
  const bakedAddressBalanceGas = payment != null && payment.length === 0;
612
665
  let { gasBudget } = input;
@@ -616,7 +669,14 @@ async function prepareGasFunding(input) {
616
669
  const existingPositive = isPositiveBudget(existingBudget) ? BigInt(existingBudget) : null;
617
670
  if (gasBudget == null) {
618
671
  if (bakedAddressBalanceGas || existingPositive == null) {
619
- gasBudget = await estimateGasBudget({ tx, suiClient, owner, gasPrice });
672
+ gasBudget = await estimateGasBudget({
673
+ tx,
674
+ suiClient,
675
+ owner,
676
+ gasPrice,
677
+ excludeObjectIds,
678
+ preferAddressBalance: input.preferAddressBalance
679
+ });
620
680
  } else {
621
681
  gasBudget = existingPositive;
622
682
  }
@@ -625,7 +685,20 @@ async function prepareGasFunding(input) {
625
685
  if (bakedAddressBalanceGas) {
626
686
  tx.setExpiration(null);
627
687
  }
628
- return selectGasFunding({ tx, suiClient, owner, gasBudget });
688
+ if (input.preferAddressBalance) {
689
+ const funding = await loadSuiGasFunding(suiClient, owner, tx, excludeObjectIds);
690
+ if (funding.addressBalance < gasBudget) {
691
+ throw new InsufficientGasFundsError(gasBudget, funding.coinBalance, funding.addressBalance);
692
+ }
693
+ tx.setGasPayment([]);
694
+ return {
695
+ mode: "addressBalance",
696
+ gasBudget,
697
+ coinBalance: funding.coinBalance,
698
+ addressBalance: funding.addressBalance
699
+ };
700
+ }
701
+ return selectGasFunding({ tx, suiClient, owner, gasBudget, excludeObjectIds });
629
702
  }
630
703
  async function preferClassicGasPayment(input) {
631
704
  const { tx, suiClient, owner } = input;
@@ -668,7 +741,9 @@ var Simulator = class {
668
741
  tx,
669
742
  suiClient,
670
743
  owner: input.sender,
671
- gasPrice
744
+ gasPrice,
745
+ preferAddressBalance: input.preferAddressBalance,
746
+ excludeObjectIds: input.excludeObjectIds
672
747
  });
673
748
  } catch (e) {
674
749
  const message = e instanceof Error ? e.message : String(e);
@@ -689,9 +764,17 @@ var Simulator = class {
689
764
  simulationError: message
690
765
  };
691
766
  }
767
+ return this.inspectBuilt(built, gasPrice);
768
+ }
769
+ /** Dry-run a frozen payload without re-selecting gas. */
770
+ async simulateBuilt(built) {
771
+ const gasPrice = await this.getGasPrice();
772
+ return this.inspectBuilt(built, gasPrice);
773
+ }
774
+ async inspectBuilt(built, gasPrice) {
692
775
  let inspectResult;
693
776
  try {
694
- inspectResult = await suiClient.simulateTransaction({
777
+ inspectResult = await this.globals.suiClient.simulateTransaction({
695
778
  transaction: built,
696
779
  include: {
697
780
  effects: true,
@@ -802,7 +885,7 @@ var SignatureVerifier = class _SignatureVerifier {
802
885
 
803
886
  // src/utils/transaction.ts
804
887
  import { Transaction as Transaction3, isTransaction } from "@mysten/sui/transactions";
805
- import { fromHex as fromHex2 } from "@mysten/sui/utils";
888
+ import { fromHex as fromHex3 } from "@mysten/sui/utils";
806
889
  function toSuiTransaction(txb) {
807
890
  if (isTransaction(txb)) {
808
891
  return txb;
@@ -831,7 +914,7 @@ function transactionFromContent(content) {
831
914
  }
832
915
  if (typeof content === "string") {
833
916
  if (isHex(content)) {
834
- return Transaction3.from(fromHex2(content));
917
+ return Transaction3.from(fromHex3(content));
835
918
  }
836
919
  return Transaction3.from(content);
837
920
  }
@@ -1064,7 +1147,12 @@ var MSafeAccount = class _MSafeAccount {
1064
1147
  async simulateIntention(request) {
1065
1148
  const txb = await this.buildTxFromIntention(request);
1066
1149
  txb.setSender(this.address);
1067
- return this.simulator.simulate({ txb, sender: this.address });
1150
+ return this.simulator.simulate({
1151
+ txb,
1152
+ sender: this.address,
1153
+ preferAddressBalance: request.preferAddressBalance,
1154
+ excludeObjectIds: request.excludeObjectIds
1155
+ });
1068
1156
  }
1069
1157
  async proposeIntention(input) {
1070
1158
  const message = SigningMessageHelper3.proposeIntentionMessage({
@@ -1090,13 +1178,19 @@ var MSafeAccount = class _MSafeAccount {
1090
1178
  suiClient: this.globals.suiClient,
1091
1179
  owner: this.address,
1092
1180
  gasPrice: input.gasPrice,
1093
- gasBudget: input.gasBudget
1181
+ gasBudget: input.gasBudget,
1182
+ preferAddressBalance: input.preferAddressBalance,
1183
+ excludeObjectIds: input.excludeObjectIds
1094
1184
  });
1095
1185
  const payload = await txb.build({ client: this.globals.suiClient });
1096
1186
  const digest = await txb.getDigest({ client: this.globals.suiClient });
1097
1187
  const signature = await this.wallet.signTransactionBlock({ transactionBlock: payload });
1188
+ const apiInput = { ...input };
1189
+ delete apiInput.txb;
1190
+ delete apiInput.preferAddressBalance;
1191
+ delete apiInput.excludeObjectIds;
1098
1192
  return this.backend.proposeIntentionAndBuildVote({
1099
- ...input,
1193
+ ...apiInput,
1100
1194
  payload: toHex2(payload),
1101
1195
  digest,
1102
1196
  msafeAddress: this.address,
@@ -1204,6 +1298,10 @@ var MSafeAccount = class _MSafeAccount {
1204
1298
  }
1205
1299
  async simulateBuildTransaction() {
1206
1300
  const intention = await this.backend.getNextIntention({ msafeAddress: this.address });
1301
+ const parked = parkedPayloadHex(intention.intention);
1302
+ if (parked) {
1303
+ return this.simulator.simulateBuilt(fromHex4(parked));
1304
+ }
1207
1305
  const txb = await this.buildTxFromIntention({
1208
1306
  application: intention.application,
1209
1307
  intention: intention.intention,
@@ -1280,7 +1378,7 @@ var MSafeAccount = class _MSafeAccount {
1280
1378
  clientUrl: this.globals.config.suiClient.url,
1281
1379
  account: {
1282
1380
  address: this.address,
1283
- publicKey: fromHex3(this.address),
1381
+ publicKey: fromHex4(this.address),
1284
1382
  chains: [SUI_MAINNET_CHAIN, SUI_TESTNET_CHAIN],
1285
1383
  features: []
1286
1384
  }
@@ -2023,6 +2121,8 @@ export {
2023
2121
  TESTNET_RPC_URL,
2024
2122
  Uint8ArrayToHex,
2025
2123
  addPrefix,
2124
+ collectPayloadObjectIds,
2125
+ collectQueueExcludeObjectIds,
2026
2126
  computeGasBudget,
2027
2127
  createCoinReservationRef,
2028
2128
  estimateGasBudget,
@@ -2033,6 +2133,7 @@ export {
2033
2133
  httpUrlToGrpcBaseUrl,
2034
2134
  isCoinReservationDigest,
2035
2135
  msafeChainToSuiNetwork,
2136
+ parkedPayloadHex,
2036
2137
  preferClassicGasPayment,
2037
2138
  prepareGasFunding,
2038
2139
  selectGasFunding,