@msafe/sui3-sdk 0.0.75 → 0.0.77
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 +25 -86
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +14 -23
- package/dist/index.d.ts +14 -23
- package/dist/index.js +25 -86
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/backend/BackendImpl.ts +3 -2
- package/src/backend/interface.ts +1 -1
- package/src/simulate/simulator.ts +23 -123
- package/src/types/msafe.ts +12 -4
|
@@ -5,162 +5,62 @@ import { TransactionBlock } from '@mysten/sui.js/transactions';
|
|
|
5
5
|
import { MSafeGlobals } from '@/globals/MSafeGlobals';
|
|
6
6
|
import { SimulationResult } from '@/types';
|
|
7
7
|
|
|
8
|
-
// Gas price option can be either a multiplier or a fixed amount
|
|
9
|
-
export type GasPriceOption = MultiplierOption | FixedValueOption;
|
|
10
|
-
|
|
11
|
-
// Gas budget option can be either a multiplier or a fixed amount
|
|
12
|
-
export type GasBudgetOption = MultiplierOption | FixedValueOption;
|
|
13
|
-
|
|
14
|
-
export interface MultiplierOption {
|
|
15
|
-
multiplier: {
|
|
16
|
-
numerator: bigint;
|
|
17
|
-
denominator: bigint;
|
|
18
|
-
};
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export interface FixedValueOption {
|
|
22
|
-
fixedVal: bigint;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
8
|
const GAS_SAFE_OVERHEAD = 1000n;
|
|
26
|
-
// Default to 120% of the reference gas price
|
|
27
|
-
export const DEF_GAS_PRICE_NUM = 120n;
|
|
28
|
-
export const DEF_GAS_PRICE_DEN = 100n;
|
|
29
|
-
|
|
30
|
-
export const DEF_GAS_PRICE_OPTION: GasPriceOption = {
|
|
31
|
-
multiplier: {
|
|
32
|
-
numerator: DEF_GAS_PRICE_NUM,
|
|
33
|
-
denominator: DEF_GAS_PRICE_DEN,
|
|
34
|
-
},
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
// Default to 120% of the reference gas budget
|
|
38
|
-
export const DEF_GAS_BUDGET_NUM = 120n;
|
|
39
|
-
export const DEF_GAS_BUDGET_DEN = 100n;
|
|
40
|
-
|
|
41
|
-
export const DEF_GAS_BUDGET_OPTION: GasBudgetOption = {
|
|
42
|
-
multiplier: {
|
|
43
|
-
numerator: DEF_GAS_BUDGET_NUM,
|
|
44
|
-
denominator: DEF_GAS_BUDGET_DEN,
|
|
45
|
-
},
|
|
46
|
-
};
|
|
47
9
|
|
|
48
10
|
export class Simulator {
|
|
49
11
|
constructor(private globals: MSafeGlobals) {}
|
|
50
12
|
|
|
51
|
-
public async simulate(
|
|
52
|
-
input: {
|
|
53
|
-
txb: TransactionBlock;
|
|
54
|
-
sender: string;
|
|
55
|
-
},
|
|
56
|
-
gasOption: GasPriceOption = DEF_GAS_PRICE_OPTION,
|
|
57
|
-
budgetOption: GasBudgetOption = DEF_GAS_BUDGET_OPTION,
|
|
58
|
-
): Promise<SimulationResult> {
|
|
13
|
+
public async simulate(input: { txb: TransactionBlock; sender: string }): Promise<SimulationResult> {
|
|
59
14
|
const tx = this.copyTransactionBlock(input.txb);
|
|
60
15
|
|
|
61
16
|
const { suiClient } = this.globals;
|
|
62
17
|
|
|
63
|
-
const gasPrice = await this.getGasPrice(
|
|
18
|
+
const gasPrice = await this.getGasPrice();
|
|
64
19
|
|
|
65
|
-
|
|
66
|
-
// tx.setGasPrice(gasPrice);
|
|
20
|
+
tx.setGasPrice(gasPrice);
|
|
67
21
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
const { gasUsed } = inspectResult.effects;
|
|
73
|
-
const gasBudget = this.toGasBudget(gasUsed, gasPrice);
|
|
74
|
-
const success = inspectResult.effects.status.status === 'success';
|
|
75
|
-
let error: string | undefined;
|
|
76
|
-
|
|
77
|
-
if (!success) {
|
|
78
|
-
error = inspectResult.effects.status.error;
|
|
79
|
-
}
|
|
22
|
+
const inspectResult = await suiClient.dryRunTransactionBlock({
|
|
23
|
+
transactionBlock: await tx.build({ client: suiClient }),
|
|
24
|
+
});
|
|
25
|
+
const success = inspectResult.effects.status.status === 'success';
|
|
80
26
|
|
|
27
|
+
if (!success) {
|
|
81
28
|
return {
|
|
82
29
|
success,
|
|
83
30
|
gasPrice,
|
|
84
|
-
gasObject: inspectResult.effects.gasObject.reference,
|
|
85
|
-
gasUsed,
|
|
86
|
-
gasBudget: this.applyBudgetOption(gasBudget, budgetOption),
|
|
87
|
-
simulationError: error,
|
|
88
31
|
response: inspectResult,
|
|
32
|
+
simulationError: inspectResult.effects.status.error!,
|
|
89
33
|
};
|
|
90
|
-
} catch (err) {
|
|
91
|
-
if (err instanceof Error) {
|
|
92
|
-
return {
|
|
93
|
-
success: false,
|
|
94
|
-
gasObject: { digest: '', objectId: '', version: '' },
|
|
95
|
-
gasPrice: 0n,
|
|
96
|
-
gasBudget: 0n,
|
|
97
|
-
gasUsed: {
|
|
98
|
-
computationCost: '',
|
|
99
|
-
nonRefundableStorageFee: '',
|
|
100
|
-
storageCost: '',
|
|
101
|
-
storageRebate: '',
|
|
102
|
-
},
|
|
103
|
-
simulationError: err.message,
|
|
104
|
-
};
|
|
105
|
-
}
|
|
106
|
-
throw err;
|
|
107
34
|
}
|
|
35
|
+
const gasBudget = this.toGasBudget(inspectResult.effects.gasUsed, gasPrice);
|
|
36
|
+
|
|
37
|
+
return {
|
|
38
|
+
success,
|
|
39
|
+
gasPrice,
|
|
40
|
+
gasObject: inspectResult.effects.gasObject.reference,
|
|
41
|
+
gasUsed: inspectResult.effects.gasUsed,
|
|
42
|
+
gasBudget,
|
|
43
|
+
response: inspectResult,
|
|
44
|
+
};
|
|
108
45
|
}
|
|
109
46
|
|
|
110
|
-
private async getGasPrice(
|
|
111
|
-
|
|
112
|
-
return option.fixedVal;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
const refGasPrice = await this.globals.suiClient.getReferenceGasPrice();
|
|
116
|
-
|
|
117
|
-
return this.applyGasOption(refGasPrice, option);
|
|
47
|
+
private async getGasPrice() {
|
|
48
|
+
return this.globals.suiClient.getReferenceGasPrice();
|
|
118
49
|
}
|
|
119
50
|
|
|
120
51
|
private toGasBudget(gasUsed: GasCostSummary, gasPrice: bigint) {
|
|
121
|
-
const { computationCost, storageCost } = gasUsed;
|
|
52
|
+
const { computationCost, storageCost, storageRebate } = gasUsed;
|
|
122
53
|
const safeOverhead = GAS_SAFE_OVERHEAD * gasPrice;
|
|
123
54
|
|
|
124
55
|
const baseComputationCostWithOverhead = BigInt(computationCost) + safeOverhead;
|
|
125
56
|
|
|
126
57
|
// do not subtract rebate for now, because it may cause normally tx gas to be lower than empty tx gas
|
|
127
|
-
|
|
128
|
-
const gasBudget = baseComputationCostWithOverhead + BigInt(storageCost);
|
|
58
|
+
const gasBudget = baseComputationCostWithOverhead + BigInt(storageCost) - BigInt(storageRebate);
|
|
129
59
|
|
|
130
60
|
// Set the budget to max(computation, computation + storage - rebate)
|
|
131
61
|
return gasBudget > baseComputationCostWithOverhead ? gasBudget : baseComputationCostWithOverhead;
|
|
132
62
|
}
|
|
133
63
|
|
|
134
|
-
private isFixedValue(option: GasPriceOption | GasBudgetOption): option is FixedValueOption {
|
|
135
|
-
return 'fixedVal' in option;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
private isMultiplier(option: GasPriceOption | GasBudgetOption): option is MultiplierOption {
|
|
139
|
-
return 'multiplier' in option;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
private applyGasOption(val: bigint, option: GasPriceOption) {
|
|
143
|
-
if (this.isFixedValue(option)) {
|
|
144
|
-
return option.fixedVal;
|
|
145
|
-
}
|
|
146
|
-
if (this.isMultiplier(option)) {
|
|
147
|
-
const { multiplier } = option;
|
|
148
|
-
return (val * multiplier.numerator) / multiplier.denominator;
|
|
149
|
-
}
|
|
150
|
-
throw new Error('Sanity: Unknown gas price option');
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
private applyBudgetOption(val: bigint, option: GasBudgetOption) {
|
|
154
|
-
if (this.isFixedValue(option)) {
|
|
155
|
-
return option.fixedVal;
|
|
156
|
-
}
|
|
157
|
-
if (this.isMultiplier(option)) {
|
|
158
|
-
const { multiplier } = option;
|
|
159
|
-
return (val * multiplier.numerator) / multiplier.denominator;
|
|
160
|
-
}
|
|
161
|
-
throw new Error('Sanity: Unknown gas budget option');
|
|
162
|
-
}
|
|
163
|
-
|
|
164
64
|
private copyTransactionBlock(tx: TransactionBlock): TransactionBlock {
|
|
165
65
|
return TransactionBlock.from(tx.serialize());
|
|
166
66
|
}
|
package/src/types/msafe.ts
CHANGED
|
@@ -80,14 +80,22 @@ export interface ProposeIntention {
|
|
|
80
80
|
signature: SerializedSignature;
|
|
81
81
|
}
|
|
82
82
|
|
|
83
|
-
export
|
|
84
|
-
|
|
83
|
+
export type SimulationResult = SimulationSuccessResult | SimulationFailedResult;
|
|
84
|
+
|
|
85
|
+
export interface SimulationSuccessResult {
|
|
86
|
+
success: true;
|
|
85
87
|
gasPrice: bigint;
|
|
86
88
|
gasUsed: GasCostSummary;
|
|
87
89
|
gasBudget: bigint;
|
|
88
90
|
gasObject: SuiObjectRef;
|
|
89
|
-
|
|
90
|
-
|
|
91
|
+
response: DryRunTransactionBlockResponse;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export interface SimulationFailedResult {
|
|
95
|
+
success: false;
|
|
96
|
+
gasPrice: bigint;
|
|
97
|
+
response: DryRunTransactionBlockResponse;
|
|
98
|
+
simulationError: string;
|
|
91
99
|
}
|
|
92
100
|
|
|
93
101
|
export interface SimulationOption extends IGasOption {
|