@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.cjs +120 -19
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +35 -1
- package/dist/index.d.ts +35 -1
- package/dist/index.js +125 -24
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/core/MSafeAccount.ts +22 -3
- package/src/simulate/simulator.ts +19 -2
- package/src/utils/gasFunding.ts +125 -16
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
|
|
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
|
-
|
|
440
|
+
const used = tx.getData().inputs.reduce((acc, input) => {
|
|
441
441
|
const immOrOwned = input.Object?.ImmOrOwnedObject?.objectId;
|
|
442
442
|
if (immOrOwned) {
|
|
443
|
-
|
|
444
|
-
return
|
|
443
|
+
acc.add(normalizeSuiObjectId(immOrOwned));
|
|
444
|
+
return acc;
|
|
445
445
|
}
|
|
446
446
|
const unresolved = input.UnresolvedObject?.objectId;
|
|
447
447
|
if (unresolved) {
|
|
448
|
-
|
|
448
|
+
acc.add(normalizeSuiObjectId(unresolved));
|
|
449
449
|
}
|
|
450
|
-
return
|
|
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 =
|
|
576
|
-
|
|
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({
|
|
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
|
-
|
|
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
|
|
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(
|
|
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({
|
|
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
|
-
...
|
|
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:
|
|
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,
|