@msafe/sui3-sdk 1.0.23 → 1.0.24
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 +27 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +16 -1
- package/dist/index.d.ts +16 -1
- package/dist/index.js +27 -4
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/utils/gasFunding.ts +43 -6
package/package.json
CHANGED
package/src/utils/gasFunding.ts
CHANGED
|
@@ -8,6 +8,12 @@ import { getAllCoins, SUI_COIN } from '@/utils/sui';
|
|
|
8
8
|
|
|
9
9
|
const GAS_SAFE_OVERHEAD = 1000n;
|
|
10
10
|
|
|
11
|
+
/** Protocol cap: a transaction may smash at most this many gas payment objects. */
|
|
12
|
+
export const MAX_GAS_PAYMENT_OBJECTS = 256;
|
|
13
|
+
|
|
14
|
+
/** Cover target for estimate probes (1 SUI is enough for a normal dry-run). */
|
|
15
|
+
const ESTIMATE_GAS_COVER = 1_000_000_000n;
|
|
16
|
+
|
|
11
17
|
export type GasFundingMode = 'classic' | 'addressBalance' | 'mixedTopUp';
|
|
12
18
|
|
|
13
19
|
export interface GasFundingResult {
|
|
@@ -49,7 +55,37 @@ export function computeGasBudget(
|
|
|
49
55
|
return BigInt(computationCost) + BigInt(storageCost) + safeOverhead;
|
|
50
56
|
}
|
|
51
57
|
|
|
52
|
-
type PaymentCoinRef = { objectId: string; version: string; digest: string; balance: bigint };
|
|
58
|
+
export type PaymentCoinRef = { objectId: string; version: string; digest: string; balance: bigint };
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Pick the fewest large SUI coins that cover `cover`, capped at 256.
|
|
62
|
+
* Never attach every owned coin — accounts with hundreds of SUI objects
|
|
63
|
+
* exceed max_gas_payment_objects and trip gasless estimate
|
|
64
|
+
* ("gas_budget must be 0 for gasless transactions").
|
|
65
|
+
*/
|
|
66
|
+
export function pickGasPaymentCoins(coins: PaymentCoinRef[], cover: bigint): PaymentCoinRef[] {
|
|
67
|
+
if (cover <= 0n) {
|
|
68
|
+
return [];
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const sorted = [...coins]
|
|
72
|
+
.filter((coin) => coin.balance > 0n)
|
|
73
|
+
.sort((a, b) => (a.balance === b.balance ? 0 : a.balance < b.balance ? 1 : -1));
|
|
74
|
+
|
|
75
|
+
const selected: PaymentCoinRef[] = [];
|
|
76
|
+
let sum = 0n;
|
|
77
|
+
for (const coin of sorted) {
|
|
78
|
+
if (selected.length >= MAX_GAS_PAYMENT_OBJECTS) {
|
|
79
|
+
break;
|
|
80
|
+
}
|
|
81
|
+
selected.push(coin);
|
|
82
|
+
sum += coin.balance;
|
|
83
|
+
if (sum >= cover) {
|
|
84
|
+
break;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return selected;
|
|
88
|
+
}
|
|
53
89
|
|
|
54
90
|
interface SuiGasFunding {
|
|
55
91
|
paymentCoins: PaymentCoinRef[];
|
|
@@ -285,17 +321,18 @@ export async function selectGasFunding(input: {
|
|
|
285
321
|
// gas (payment: []) is stricter on budget and is what Mysten auto-picks when
|
|
286
322
|
// addressBalance > 0 — avoid it unless there is no usable gas coin.
|
|
287
323
|
if (paymentCoins.length > 0 && coinBalance >= gasBudget) {
|
|
288
|
-
tx.setGasPayment(toObjectRefs(paymentCoins));
|
|
324
|
+
tx.setGasPayment(toObjectRefs(pickGasPaymentCoins(paymentCoins, gasBudget)));
|
|
289
325
|
return { mode: 'classic', gasBudget, coinBalance, addressBalance };
|
|
290
326
|
}
|
|
291
327
|
|
|
292
328
|
if (paymentCoins.length > 0 && total >= gasBudget) {
|
|
293
329
|
const topUpAmount = gasBudget - coinBalance; // > 0 and <= addressBalance
|
|
330
|
+
// One real coin is enough — reservation smashes into it.
|
|
294
331
|
await applyMixedTopUp({
|
|
295
332
|
tx,
|
|
296
333
|
suiClient,
|
|
297
334
|
owner,
|
|
298
|
-
paymentCoins,
|
|
335
|
+
paymentCoins: pickGasPaymentCoins(paymentCoins, 1n),
|
|
299
336
|
topUpAmount,
|
|
300
337
|
});
|
|
301
338
|
return { mode: 'mixedTopUp', gasBudget, coinBalance, addressBalance };
|
|
@@ -381,9 +418,9 @@ export async function estimateGasBudget(input: {
|
|
|
381
418
|
probe.setSender(owner);
|
|
382
419
|
probe.setGasPrice(gasPrice);
|
|
383
420
|
|
|
384
|
-
// Prefer classic coins for the probe
|
|
421
|
+
// Prefer a few large classic coins for the probe (never attach every owned coin).
|
|
385
422
|
if (funding.paymentCoins.length > 0) {
|
|
386
|
-
probe.setGasPayment(toObjectRefs(funding.paymentCoins));
|
|
423
|
+
probe.setGasPayment(toObjectRefs(pickGasPaymentCoins(funding.paymentCoins, ESTIMATE_GAS_COVER)));
|
|
387
424
|
}
|
|
388
425
|
|
|
389
426
|
let built: Uint8Array;
|
|
@@ -500,6 +537,6 @@ export async function preferClassicGasPayment(input: {
|
|
|
500
537
|
if (funding.paymentCoins.length === 0) {
|
|
501
538
|
return false;
|
|
502
539
|
}
|
|
503
|
-
tx.setGasPayment(toObjectRefs(funding.paymentCoins));
|
|
540
|
+
tx.setGasPayment(toObjectRefs(pickGasPaymentCoins(funding.paymentCoins, ESTIMATE_GAS_COVER)));
|
|
504
541
|
return true;
|
|
505
542
|
}
|