@msafe/sui3-sdk 1.0.17 → 1.0.19

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
@@ -366,12 +366,6 @@ declare function selectGasFunding(input: {
366
366
  owner: string;
367
367
  gasBudget: bigint;
368
368
  }): Promise<GasFundingResult>;
369
- /**
370
- * Estimate gas budget (no storageRebate) using a probe build/simulate.
371
- * Prefers classic coin gas when coin objects exist so the estimate matches the
372
- * cheaper payment path. Budget is left unset so Mysten can dry-run with MAX_GAS
373
- * overrides (avoids locking the full balance away from GasCoin splits).
374
- */
375
369
  declare function estimateGasBudget(input: {
376
370
  tx: Transaction;
377
371
  suiClient: SuiGrpcClient;
package/dist/index.d.ts CHANGED
@@ -366,12 +366,6 @@ declare function selectGasFunding(input: {
366
366
  owner: string;
367
367
  gasBudget: bigint;
368
368
  }): Promise<GasFundingResult>;
369
- /**
370
- * Estimate gas budget (no storageRebate) using a probe build/simulate.
371
- * Prefers classic coin gas when coin objects exist so the estimate matches the
372
- * cheaper payment path. Budget is left unset so Mysten can dry-run with MAX_GAS
373
- * overrides (avoids locking the full balance away from GasCoin splits).
374
- */
375
369
  declare function estimateGasBudget(input: {
376
370
  tx: Transaction;
377
371
  suiClient: SuiGrpcClient;
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 fromHex2, normalizeStructTag as normalizeStructTag3, toHex as toHex2 } from "@mysten/sui/utils";
137
+ import { fromHex as fromHex2, 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 { normalizeSuiObjectId } from "@mysten/sui/utils";
145
+ import { 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";
@@ -450,12 +450,37 @@ function collectUsedObjectIds(tx) {
450
450
  return used;
451
451
  }, /* @__PURE__ */ new Set());
452
452
  }
453
+ function txConsumesOwnedSuiCoins(tx) {
454
+ return tx.getData().commands.some((cmd) => {
455
+ if (cmd.$kind !== "$Intent" || cmd.$Intent.name !== "CoinWithBalance") {
456
+ return false;
457
+ }
458
+ const type = cmd.$Intent.data?.type;
459
+ if (!type || type === "gas") {
460
+ return false;
461
+ }
462
+ try {
463
+ return normalizeStructTag3(type) === normalizeStructTag3(SUI_COIN);
464
+ } catch {
465
+ return false;
466
+ }
467
+ });
468
+ }
453
469
  async function loadSuiGasFunding(suiClient, owner, tx) {
454
470
  const usedObjectIds = collectUsedObjectIds(tx);
455
471
  const [coins, balanceRes] = await Promise.all([
456
472
  getAllCoins({ suiClient, owner, coinType: SUI_COIN }),
457
473
  suiClient.getBalance({ owner, coinType: SUI_COIN })
458
474
  ]);
475
+ const addressBalance = BigInt(balanceRes.balance.addressBalance);
476
+ if (txConsumesOwnedSuiCoins(tx)) {
477
+ return {
478
+ paymentCoins: [],
479
+ coinBalance: 0n,
480
+ addressBalance,
481
+ total: addressBalance
482
+ };
483
+ }
459
484
  const paymentCoins = coins.filter((coin) => !usedObjectIds.has(normalizeSuiObjectId(coin.objectId)) && BigInt(coin.balance) > 0n).map((coin) => ({
460
485
  objectId: coin.objectId,
461
486
  version: coin.version,
@@ -463,7 +488,6 @@ async function loadSuiGasFunding(suiClient, owner, tx) {
463
488
  balance: BigInt(coin.balance)
464
489
  }));
465
490
  const coinBalance = paymentCoins.reduce((sum, coin) => sum + coin.balance, 0n);
466
- const addressBalance = BigInt(balanceRes.balance.addressBalance);
467
491
  return {
468
492
  paymentCoins,
469
493
  coinBalance,
@@ -528,13 +552,33 @@ async function selectGasFunding(input) {
528
552
  }
529
553
  throw new InsufficientGasFundsError(gasBudget, coinBalance, addressBalance);
530
554
  }
555
+ function cloneWithClearedGasConfig(tx) {
556
+ const data = structuredClone(tx.getData());
557
+ data.gasData.budget = null;
558
+ data.gasData.price = null;
559
+ data.gasData.payment = null;
560
+ data.expiration = null;
561
+ return Transaction.from(JSON.stringify(data));
562
+ }
563
+ function isPositiveBudget(budget) {
564
+ if (budget == null) {
565
+ return false;
566
+ }
567
+ try {
568
+ return BigInt(budget) > 0n;
569
+ } catch {
570
+ return false;
571
+ }
572
+ }
531
573
  async function estimateGasBudget(input) {
532
574
  const { tx, suiClient, owner, gasPrice } = input;
533
575
  const funding = await loadSuiGasFunding(suiClient, owner, tx);
534
576
  if (funding.total <= 0n) {
535
577
  throw new InsufficientGasFundsError(0n, funding.coinBalance, funding.addressBalance);
536
578
  }
537
- const probe = Transaction.from(tx);
579
+ const { budget, payment } = tx.getData().gasData;
580
+ const mustResetGas = payment != null && payment.length === 0 || budget != null && !isPositiveBudget(budget);
581
+ const probe = mustResetGas ? cloneWithClearedGasConfig(tx) : Transaction.from(tx);
538
582
  probe.setSender(owner);
539
583
  probe.setGasPrice(gasPrice);
540
584
  if (funding.paymentCoins.length > 0) {
@@ -566,14 +610,21 @@ async function prepareGasFunding(input) {
566
610
  const { payment, budget: existingBudget } = tx.getData().gasData;
567
611
  const bakedAddressBalanceGas = payment != null && payment.length === 0;
568
612
  let { gasBudget } = input;
613
+ if (gasBudget != null && gasBudget <= 0n) {
614
+ gasBudget = void 0;
615
+ }
616
+ const existingPositive = isPositiveBudget(existingBudget) ? BigInt(existingBudget) : null;
569
617
  if (gasBudget == null) {
570
- if (bakedAddressBalanceGas || existingBudget == null) {
618
+ if (bakedAddressBalanceGas || existingPositive == null) {
571
619
  gasBudget = await estimateGasBudget({ tx, suiClient, owner, gasPrice });
572
620
  } else {
573
- gasBudget = BigInt(existingBudget);
621
+ gasBudget = existingPositive;
574
622
  }
575
623
  }
576
624
  tx.setGasBudget(gasBudget);
625
+ if (bakedAddressBalanceGas) {
626
+ tx.setExpiration(null);
627
+ }
577
628
  return selectGasFunding({ tx, suiClient, owner, gasBudget });
578
629
  }
579
630
  async function preferClassicGasPayment(input) {
@@ -930,7 +981,7 @@ var MSafeAccount = class _MSafeAccount {
930
981
  balances.map(async (balance) => {
931
982
  const meta = await this.coinHelper.getCoinMeta(balance.coinType);
932
983
  return {
933
- type: normalizeStructTag3(balance.coinType),
984
+ type: normalizeStructTag4(balance.coinType),
934
985
  balance: BigInt(balance.addressBalance),
935
986
  metadata: meta
936
987
  };