@msafe/sui3-sdk 0.0.34 → 0.0.36
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 +141 -34
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +17 -8
- package/dist/index.d.ts +17 -8
- package/dist/index.js +141 -33
- package/dist/index.js.map +1 -1
- package/package.json +3 -2
- package/src/backend/BackendImpl.ts +16 -3
- package/src/backend/interface.ts +3 -0
- package/src/core/MSafeAccount.ts +61 -30
- package/src/globals/const.ts +0 -1
- package/src/simulate/simulator.ts +131 -0
- package/src/types/msafe.ts +9 -6
package/dist/index.cjs
CHANGED
|
@@ -43,7 +43,6 @@ __export(src_exports, {
|
|
|
43
43
|
LOCAL_API_URL: () => LOCAL_API_URL,
|
|
44
44
|
LOCAL_SYNCING_URL: () => LOCAL_SYNCING_URL,
|
|
45
45
|
MAINNET_RPC_URL: () => MAINNET_RPC_URL,
|
|
46
|
-
MSAFE_APPLICATION: () => MSAFE_APPLICATION,
|
|
47
46
|
MSafeAccount: () => MSafeAccount,
|
|
48
47
|
MSafeClient: () => MSafeClient,
|
|
49
48
|
MSafeEnv: () => MSafeEnv,
|
|
@@ -176,10 +175,83 @@ var InvitationSDK = class {
|
|
|
176
175
|
};
|
|
177
176
|
|
|
178
177
|
// src/core/MSafeAccount.ts
|
|
178
|
+
var import_sui_app_store = require("@msafe/sui-app-store");
|
|
179
179
|
var import_sui3_utils4 = require("@msafe/sui3-utils");
|
|
180
|
-
var
|
|
180
|
+
var import_transactions2 = require("@mysten/sui.js/transactions");
|
|
181
181
|
var import_utils3 = require("@mysten/sui.js/utils");
|
|
182
182
|
|
|
183
|
+
// src/simulate/simulator.ts
|
|
184
|
+
var import_transactions = require("@mysten/sui.js/transactions");
|
|
185
|
+
var GAS_SAFE_OVERHEAD = 1000n;
|
|
186
|
+
var DEF_GAS_PRICE_NUM = 120n;
|
|
187
|
+
var DEF_GAS_PRICE_DEN = 100n;
|
|
188
|
+
var DEF_GAS_PRICE_OPTION = {
|
|
189
|
+
multiplier: {
|
|
190
|
+
numerator: DEF_GAS_PRICE_NUM,
|
|
191
|
+
denominator: DEF_GAS_PRICE_DEN
|
|
192
|
+
}
|
|
193
|
+
};
|
|
194
|
+
var Simulator = class {
|
|
195
|
+
constructor(globals) {
|
|
196
|
+
this.globals = globals;
|
|
197
|
+
}
|
|
198
|
+
async simulate(input, options = DEF_GAS_PRICE_OPTION) {
|
|
199
|
+
const tx = this.copyTransactionBlock(input.txb);
|
|
200
|
+
const { suiClient } = this.globals;
|
|
201
|
+
const gasPrice = await this.getGasPrice(options);
|
|
202
|
+
tx.setGasPrice(gasPrice);
|
|
203
|
+
const inspectResult = await suiClient.devInspectTransactionBlock({ transactionBlock: tx, sender: input.sender });
|
|
204
|
+
const { gasUsed } = inspectResult.effects;
|
|
205
|
+
const gasBudget = this.toGasBudget(gasUsed, gasPrice);
|
|
206
|
+
const success = inspectResult.effects.status.status === "success";
|
|
207
|
+
let error;
|
|
208
|
+
if (!success) {
|
|
209
|
+
error = inspectResult.effects.status.error;
|
|
210
|
+
}
|
|
211
|
+
return {
|
|
212
|
+
success,
|
|
213
|
+
gasPrice,
|
|
214
|
+
gasObject: inspectResult.effects.gasObject.reference,
|
|
215
|
+
gasUsed,
|
|
216
|
+
gasBudget,
|
|
217
|
+
simulationError: error
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
async getGasPrice(option) {
|
|
221
|
+
if (this.isFixedValue(option)) {
|
|
222
|
+
return option.fixedVal;
|
|
223
|
+
}
|
|
224
|
+
const refGasPrice = await this.globals.suiClient.getReferenceGasPrice();
|
|
225
|
+
return this.applyGasOption(refGasPrice, option);
|
|
226
|
+
}
|
|
227
|
+
toGasBudget(gasUsed, gasPrice) {
|
|
228
|
+
const { computationCost, storageCost } = gasUsed;
|
|
229
|
+
const safeOverhead = GAS_SAFE_OVERHEAD * gasPrice;
|
|
230
|
+
const baseComputationCostWithOverhead = BigInt(computationCost) + safeOverhead;
|
|
231
|
+
const gasBudget = baseComputationCostWithOverhead + BigInt(storageCost);
|
|
232
|
+
return gasBudget > baseComputationCostWithOverhead ? gasBudget : baseComputationCostWithOverhead;
|
|
233
|
+
}
|
|
234
|
+
isFixedValue(option) {
|
|
235
|
+
return "fixedVal" in option;
|
|
236
|
+
}
|
|
237
|
+
isMultiplier(option) {
|
|
238
|
+
return "multiplier" in option;
|
|
239
|
+
}
|
|
240
|
+
applyGasOption(val, option) {
|
|
241
|
+
if (this.isFixedValue(option)) {
|
|
242
|
+
return option.fixedVal;
|
|
243
|
+
}
|
|
244
|
+
if (this.isMultiplier(option)) {
|
|
245
|
+
const { multiplier } = option;
|
|
246
|
+
return val * multiplier.numerator / multiplier.denominator;
|
|
247
|
+
}
|
|
248
|
+
throw new Error("Sanity: Unknown gas price option");
|
|
249
|
+
}
|
|
250
|
+
copyTransactionBlock(tx) {
|
|
251
|
+
return import_transactions.TransactionBlock.from(tx.serialize());
|
|
252
|
+
}
|
|
253
|
+
};
|
|
254
|
+
|
|
183
255
|
// src/utils/buffer.ts
|
|
184
256
|
function stringToBuffer(s) {
|
|
185
257
|
return Buffer.from(s, "utf-8");
|
|
@@ -529,9 +601,11 @@ var MSafeAccount = class _MSafeAccount {
|
|
|
529
601
|
creationNonce: info.creationNonce
|
|
530
602
|
});
|
|
531
603
|
this.coinHelper = new CoinHelper(this.suiClient);
|
|
604
|
+
this.simulator = new Simulator(globals);
|
|
532
605
|
}
|
|
533
606
|
multiSig;
|
|
534
607
|
coinHelper;
|
|
608
|
+
simulator;
|
|
535
609
|
static async New(globals, address) {
|
|
536
610
|
const info = await globals.backend.getMSafeAccountInfo(address);
|
|
537
611
|
const ms = new _MSafeAccount(globals, info);
|
|
@@ -560,7 +634,6 @@ var MSafeAccount = class _MSafeAccount {
|
|
|
560
634
|
};
|
|
561
635
|
return getAllOwnedObjects(this.suiClient, this.address, filterCoinObjectOptions);
|
|
562
636
|
}
|
|
563
|
-
// TODO: Calculate the votes
|
|
564
637
|
async pendingTransaction() {
|
|
565
638
|
const res = await this.backend.getPendingTransactions({ msafeAddress: this.address });
|
|
566
639
|
if (!res.pending) {
|
|
@@ -586,7 +659,6 @@ var MSafeAccount = class _MSafeAccount {
|
|
|
586
659
|
rejectWeight: this.calculateWeightFromVotes(rejectPending?.votes ?? [])
|
|
587
660
|
};
|
|
588
661
|
}
|
|
589
|
-
// TODO: Calculate the votes.
|
|
590
662
|
async historyTransaction(pagination) {
|
|
591
663
|
return this.backend.getHistoryTransactions({
|
|
592
664
|
msafeAddress: this.address,
|
|
@@ -602,6 +674,22 @@ var MSafeAccount = class _MSafeAccount {
|
|
|
602
674
|
async nextSequenceNumber() {
|
|
603
675
|
return this.backend.getNextSequenceNumber(this.address);
|
|
604
676
|
}
|
|
677
|
+
async simulateIntention(request) {
|
|
678
|
+
const appHelper = import_sui_app_store.appHelpers.getAppHelper(request.application);
|
|
679
|
+
if (!appHelper) {
|
|
680
|
+
throw new Error(`Can't find app helper for application ${request.application}`);
|
|
681
|
+
}
|
|
682
|
+
const txb = await appHelper.build({
|
|
683
|
+
intentionData: request.intention,
|
|
684
|
+
txType: request.txType,
|
|
685
|
+
txSubType: request.txSubType,
|
|
686
|
+
suiClient: this.globals.suiClient,
|
|
687
|
+
account: {
|
|
688
|
+
address: this.address
|
|
689
|
+
}
|
|
690
|
+
});
|
|
691
|
+
return this.simulator.simulate({ txb, sender: this.address });
|
|
692
|
+
}
|
|
605
693
|
async proposeIntention(input) {
|
|
606
694
|
const message = import_sui3_utils4.SigningMessageHelper.proposeIntentionMessage({
|
|
607
695
|
msafeAddress: this.address,
|
|
@@ -611,12 +699,22 @@ var MSafeAccount = class _MSafeAccount {
|
|
|
611
699
|
const signature = await this.wallet.signPersonalMessage({
|
|
612
700
|
messageStr: message
|
|
613
701
|
});
|
|
614
|
-
|
|
702
|
+
return this.backend.proposeIntention({
|
|
615
703
|
...input,
|
|
616
704
|
msafeAddress: this.address,
|
|
617
705
|
signature: signature.signature
|
|
618
706
|
});
|
|
619
707
|
}
|
|
708
|
+
async simulateCoinTransferIntention(intention) {
|
|
709
|
+
const sn = await this.nextSequenceNumber();
|
|
710
|
+
return this.simulateIntention({
|
|
711
|
+
application: import_sui3_utils4.TransactionDefaultApplication,
|
|
712
|
+
txType: import_sui3_utils4.TransactionType.Assets,
|
|
713
|
+
txSubType: import_sui3_utils4.TransactionSubTypes.assets.coin.send,
|
|
714
|
+
sequenceNumber: sn,
|
|
715
|
+
intention
|
|
716
|
+
});
|
|
717
|
+
}
|
|
620
718
|
async proposeCoinTransferIntention(intention) {
|
|
621
719
|
const sn = await this.nextSequenceNumber();
|
|
622
720
|
return this.proposeIntention({
|
|
@@ -640,7 +738,7 @@ var MSafeAccount = class _MSafeAccount {
|
|
|
640
738
|
}
|
|
641
739
|
async proposePlainPayloadIntention(intention) {
|
|
642
740
|
const sn = await this.nextSequenceNumber();
|
|
643
|
-
const tb =
|
|
741
|
+
const tb = import_transactions2.TransactionBlock.from(intention.payload);
|
|
644
742
|
if (!tb.blockData.sender || !(0, import_sui3_utils4.isSameAddress)(tb.blockData.sender, this.address)) {
|
|
645
743
|
throw new Error("Transaction sender is not same as the multisig address");
|
|
646
744
|
}
|
|
@@ -664,7 +762,7 @@ var MSafeAccount = class _MSafeAccount {
|
|
|
664
762
|
// Shortcut for proposing a transaction to be a pending transaction, and add user vote to it.
|
|
665
763
|
// Requires the multi-sig to be empty in pending transaction.
|
|
666
764
|
async proposePendingTransaction(intention) {
|
|
667
|
-
const txb = new
|
|
765
|
+
const txb = new import_transactions2.TransactionBlock();
|
|
668
766
|
const payload = await txb.build({ client: this.suiClient });
|
|
669
767
|
const digest = await txb.getDigest({ client: this.suiClient });
|
|
670
768
|
const signature = await this.wallet.signTransactionBlock({ transactionBlock: payload });
|
|
@@ -692,33 +790,34 @@ var MSafeAccount = class _MSafeAccount {
|
|
|
692
790
|
signature: signature.signature
|
|
693
791
|
});
|
|
694
792
|
}
|
|
695
|
-
async
|
|
696
|
-
|
|
793
|
+
async simulateBuildTransaction() {
|
|
794
|
+
const intention = await this.backend.getNextIntention({ msafeAddress: this.address });
|
|
795
|
+
const appHelper = import_sui_app_store.appHelpers.getAppHelper(intention.application);
|
|
796
|
+
if (!appHelper) {
|
|
797
|
+
throw new Error(`Can't find app helper for application ${intention.application}`);
|
|
798
|
+
}
|
|
799
|
+
const txb = await appHelper.build({
|
|
800
|
+
intentionData: intention.intention,
|
|
801
|
+
txType: intention.txType,
|
|
802
|
+
txSubType: intention.txSubType,
|
|
803
|
+
suiClient: this.globals.suiClient,
|
|
804
|
+
account: {
|
|
805
|
+
address: this.address
|
|
806
|
+
}
|
|
807
|
+
});
|
|
808
|
+
return this.simulator.simulate({ txb, sender: this.address });
|
|
809
|
+
}
|
|
810
|
+
async buildNextIntentionAndAddToPending(gasOption) {
|
|
811
|
+
return this.backend.buildNextIntentionAndAddToPending({
|
|
812
|
+
msafeAddress: this.address,
|
|
813
|
+
forceBuild: gasOption.forceBuild,
|
|
814
|
+
gasPrice: gasOption.gasPrice,
|
|
815
|
+
gasBudget: gasOption.gasBudget
|
|
816
|
+
});
|
|
697
817
|
}
|
|
698
818
|
async skipNextFailedIntention() {
|
|
699
819
|
return this.backend.skipNextFailedIntention({ msafeAddress: this.address });
|
|
700
820
|
}
|
|
701
|
-
async simulateIntention() {
|
|
702
|
-
const txb = new import_transactions.TransactionBlock();
|
|
703
|
-
txb.setSender(this.address);
|
|
704
|
-
if (!txb.blockData.gasConfig.price) {
|
|
705
|
-
const refGas = await this.suiClient.getReferenceGasPrice();
|
|
706
|
-
txb.setGasPrice(refGas);
|
|
707
|
-
}
|
|
708
|
-
const payload = await txb.build({ client: this.suiClient });
|
|
709
|
-
const dryRunResult = await this.suiClient.dryRunTransactionBlock({ transactionBlock: payload });
|
|
710
|
-
const success = dryRunResult.effects.status.status === "success";
|
|
711
|
-
const errorMsg = dryRunResult.effects.status.error;
|
|
712
|
-
const gasPrice = BigInt(txb.blockData.gasConfig.price);
|
|
713
|
-
const { gasUsed } = dryRunResult.effects;
|
|
714
|
-
return {
|
|
715
|
-
success,
|
|
716
|
-
errorMsg,
|
|
717
|
-
gasPrice,
|
|
718
|
-
gasUsed,
|
|
719
|
-
dryRunResult
|
|
720
|
-
};
|
|
721
|
-
}
|
|
722
821
|
async executePendingTx(pending, isRejectTx = false) {
|
|
723
822
|
const votes = isRejectTx ? pending.rejectVotes : pending.votes;
|
|
724
823
|
const payload = isRejectTx ? pending.rejectPayload : pending.payload;
|
|
@@ -958,6 +1057,13 @@ var BackendImpl = class _BackendImpl {
|
|
|
958
1057
|
});
|
|
959
1058
|
return res.data;
|
|
960
1059
|
}
|
|
1060
|
+
async getNextIntention(input) {
|
|
1061
|
+
const res = await this.get(`/transaction/intention/next`, {
|
|
1062
|
+
params: input,
|
|
1063
|
+
headers: this.headers()
|
|
1064
|
+
});
|
|
1065
|
+
return res.data;
|
|
1066
|
+
}
|
|
961
1067
|
async getCurrentSequenceNumber(address) {
|
|
962
1068
|
const res = await this.get(`/transaction/sn/current`, {
|
|
963
1069
|
params: {
|
|
@@ -984,7 +1090,6 @@ var BackendImpl = class _BackendImpl {
|
|
|
984
1090
|
async proposeIntention(input) {
|
|
985
1091
|
await this.post(`/transaction/intention`, input, { headers: this.headers() });
|
|
986
1092
|
}
|
|
987
|
-
// TODO later
|
|
988
1093
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
989
1094
|
async proposePendingTransaction(_input) {
|
|
990
1095
|
return void 0;
|
|
@@ -1000,7 +1105,11 @@ var BackendImpl = class _BackendImpl {
|
|
|
1000
1105
|
});
|
|
1001
1106
|
}
|
|
1002
1107
|
async buildNextIntentionAndAddToPending(input) {
|
|
1003
|
-
await this.post(
|
|
1108
|
+
await this.post(
|
|
1109
|
+
`/transaction/pending/build`,
|
|
1110
|
+
{ ...input, gasPrice: input.gasPrice.toString(), gasBudget: input.gasBudget.toString() },
|
|
1111
|
+
{ headers: this.headers() }
|
|
1112
|
+
);
|
|
1004
1113
|
}
|
|
1005
1114
|
async skipNextFailedIntention(input) {
|
|
1006
1115
|
await this.post(`/transaction/pending/skip`, input, { headers: this.headers() });
|
|
@@ -1103,7 +1212,6 @@ var MSafeEnv = /* @__PURE__ */ ((MSafeEnv3) => {
|
|
|
1103
1212
|
MSafeEnv3["prod"] = "prod";
|
|
1104
1213
|
return MSafeEnv3;
|
|
1105
1214
|
})(MSafeEnv || {});
|
|
1106
|
-
var MSAFE_APPLICATION = "msafe";
|
|
1107
1215
|
var TESTNET_RPC_URL = "https://sui-testnet.blockvision.org/v1/2Sgk89ivT64MnKdcGzjmyjY2ndD";
|
|
1108
1216
|
var MAINNET_RPC_URL = "https://sui-mainnet.blockvision.org/v1/2Sgk7NPvqkd7mESYkxF01yX15l7";
|
|
1109
1217
|
var LOCAL_API_URL = "http://127.0.0.1:3000";
|
|
@@ -1301,7 +1409,6 @@ var MSafeClient = class _MSafeClient {
|
|
|
1301
1409
|
LOCAL_API_URL,
|
|
1302
1410
|
LOCAL_SYNCING_URL,
|
|
1303
1411
|
MAINNET_RPC_URL,
|
|
1304
|
-
MSAFE_APPLICATION,
|
|
1305
1412
|
MSafeAccount,
|
|
1306
1413
|
MSafeClient,
|
|
1307
1414
|
MSafeEnv,
|