@msafe/sui3-sdk 0.0.5 → 0.0.6-pre-fdcc3ff.0

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 CHANGED
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
+ var __create = Object.create;
2
3
  var __defProp = Object.defineProperty;
3
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
5
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
8
  var __export = (target, all) => {
7
9
  for (var name in all)
@@ -15,6 +17,14 @@ var __copyProps = (to, from, except, desc) => {
15
17
  }
16
18
  return to;
17
19
  };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
18
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
29
 
20
30
  // src/index.ts
@@ -25,28 +35,21 @@ __export(src_exports, {
25
35
  Coin: () => Coin,
26
36
  CoinHelper: () => CoinHelper,
27
37
  CreateHelper: () => CreateHelper,
38
+ DEV_API_URL: () => DEV_API_URL,
28
39
  DEV_DATABASE_CONFIG: () => DEV_DATABASE_CONFIG,
29
40
  ENV_CONFIGS: () => ENV_CONFIGS,
30
41
  Formatter: () => Formatter,
31
42
  HexToUint8Array: () => HexToUint8Array,
32
43
  IntentionHelper: () => IntentionHelper,
44
+ LOCAL_API_URL: () => LOCAL_API_URL,
33
45
  LOCAL_DATABASE_CONFIG: () => LOCAL_DATABASE_CONFIG,
34
46
  MAINNET_RPC_URL: () => MAINNET_RPC_URL,
35
- MAX_OWNER_WITHOUT_NONCE: () => MAX_OWNER_WITHOUT_NONCE,
36
- MAX_OWNER_WITH_NONCE: () => MAX_OWNER_WITH_NONCE,
37
- MAX_WEIGHT: () => MAX_WEIGHT,
38
- MIN_THRESHOLD: () => MIN_THRESHOLD,
39
- MIN_WEIGHT: () => MIN_WEIGHT,
40
47
  MSafeAccount: () => MSafeAccount,
41
48
  MSafeClient: () => MSafeClient,
42
49
  MSafeEnv: () => MSafeEnv,
43
50
  MSafeGlobals: () => MSafeGlobals,
44
51
  MessageHelper: () => MessageHelper,
45
- NONCE_PK_PREFIX: () => NONCE_PK_PREFIX,
46
- NONCE_PK_WEIGHT: () => NONCE_PK_WEIGHT,
47
- NONCE_PREFIX_MAX_SIZE: () => NONCE_PREFIX_MAX_SIZE,
48
52
  PublicKeySerde: () => PublicKeySerde,
49
- RawMultiSig: () => RawMultiSig,
50
53
  SUI_COIN: () => SUI_COIN,
51
54
  SignatureVerifier: () => SignatureVerifier,
52
55
  TESTNET_RPC_URL: () => TESTNET_RPC_URL,
@@ -54,16 +57,31 @@ __export(src_exports, {
54
57
  Uint8ArrayToHex: () => Uint8ArrayToHex,
55
58
  getAllCoins: () => getAllCoins,
56
59
  getMSafeConfig: () => getMSafeConfig,
57
- getMultiSigPublicKey: () => getMultiSigPublicKey,
58
60
  getPublicKeyFromChain: () => getPublicKeyFromChain,
59
- makeNoncePublicKey: () => makeNoncePublicKey,
60
- stringToBuffer: () => stringToBuffer,
61
- validateMultiSigConfig: () => validateMultiSigConfig
61
+ stringToBuffer: () => stringToBuffer
62
62
  });
63
63
  module.exports = __toCommonJS(src_exports);
64
64
 
65
- // src/transactions/coin-transfer.ts
66
- var import_transactions = require("@mysten/sui.js/transactions");
65
+ // src/core/CreateHelper.ts
66
+ var import_sui3_utils = require("@msafe/sui3-utils");
67
+
68
+ // src/utils/crypto.ts
69
+ var import_cryptography = require("@mysten/sui.js/cryptography");
70
+ var import_ed25519 = require("@mysten/sui.js/keypairs/ed25519");
71
+ var import_secp256k1 = require("@mysten/sui.js/keypairs/secp256k1");
72
+ var import_secp256r1 = require("@mysten/sui.js/keypairs/secp256r1");
73
+ var import_verify = require("@mysten/sui.js/verify");
74
+
75
+ // src/utils/buffer.ts
76
+ function stringToBuffer(s) {
77
+ return Buffer.from(s, "utf-8");
78
+ }
79
+ function Uint8ArrayToHex(b) {
80
+ return `0x${Array.prototype.map.call(b, (x) => `0${x.toString(16)}`.slice(-2)).join("")}`;
81
+ }
82
+ function HexToUint8Array(hex) {
83
+ return Uint8Array.from(Buffer.from(hex.startsWith("0x") ? hex.slice(2) : hex, "hex"));
84
+ }
67
85
 
68
86
  // src/utils/format.ts
69
87
  var import_utils2 = require("@mysten/sui.js/utils");
@@ -139,28 +157,6 @@ var Formatter = class {
139
157
  }
140
158
  };
141
159
 
142
- // src/utils/sui.ts
143
- var import_cryptography2 = require("@mysten/sui.js/cryptography");
144
- var import_multisig = require("@mysten/sui.js/multisig");
145
-
146
- // src/utils/crypto.ts
147
- var import_cryptography = require("@mysten/sui.js/cryptography");
148
- var import_ed25519 = require("@mysten/sui.js/keypairs/ed25519");
149
- var import_secp256k1 = require("@mysten/sui.js/keypairs/secp256k1");
150
- var import_secp256r1 = require("@mysten/sui.js/keypairs/secp256r1");
151
- var import_verify = require("@mysten/sui.js/verify");
152
-
153
- // src/utils/buffer.ts
154
- function stringToBuffer(s) {
155
- return Buffer.from(s, "utf-8");
156
- }
157
- function Uint8ArrayToHex(b) {
158
- return `0x${Array.prototype.map.call(b, (x) => `0${x.toString(16)}`.slice(-2)).join("")}`;
159
- }
160
- function HexToUint8Array(hex) {
161
- return Uint8Array.from(Buffer.from(hex.startsWith("0x") ? hex.slice(2) : hex, "hex"));
162
- }
163
-
164
160
  // src/utils/crypto.ts
165
161
  var SignatureVerifier = class _SignatureVerifier {
166
162
  static async getPublicKeyFromSignature(input) {
@@ -220,7 +216,78 @@ var PublicKeySerde = class {
220
216
  }
221
217
  };
222
218
 
219
+ // src/core/CreateHelper.ts
220
+ var CreateHelper = class {
221
+ constructor(globals, pkHelper) {
222
+ this.globals = globals;
223
+ this.pkHelper = pkHelper;
224
+ }
225
+ async getPublicKeyBatch(addresses) {
226
+ return this.pkHelper.getPublicKeyBatch(addresses);
227
+ }
228
+ async calculateMSafeAddress(info) {
229
+ const msConfig = await this.reduceCreationInfoToRawConfig(info);
230
+ const ms = new import_sui3_utils.MultisigAccountManager(msConfig);
231
+ return ms.address;
232
+ }
233
+ // Validate the create info and return the msafe address.
234
+ async validateCreateInfo(createInfo) {
235
+ const rawConfig = await this.reduceCreationInfoToRawConfig(createInfo);
236
+ (0, import_sui3_utils.validateCreateAccountRequest)(rawConfig);
237
+ return this.calculateMSafeAddress(createInfo);
238
+ }
239
+ async submitMSafeCreation(creationInfo) {
240
+ const msafeAddress = await this.validateCreateInfo(creationInfo);
241
+ const signingMessage = (0, import_sui3_utils.createAccountCreationMessage)(msafeAddress);
242
+ const signature = await this.globals.wallet.signPersonalMessage({ messageStr: signingMessage });
243
+ await this.submitToBackend(creationInfo, signature.signature);
244
+ return msafeAddress;
245
+ }
246
+ async reduceCreationInfoToRawConfig(info) {
247
+ const publicKeys = await this.getPublicKeyBatch(info.ownerWithWeight.map((oww) => oww.address));
248
+ publicKeys.forEach((pk, i) => {
249
+ if (pk === void 0) {
250
+ throw new Error(`Unknown public key for address: ${info.ownerWithWeight[i].address}`);
251
+ }
252
+ });
253
+ return {
254
+ threshold: info.threshold,
255
+ ownersWithWeight: info.ownerWithWeight.map((owner, i) => ({
256
+ publicKey: publicKeys[i],
257
+ weight: owner.weight
258
+ })),
259
+ creationNonce: info.creationNonce
260
+ };
261
+ }
262
+ async submitToBackend(createInfo, signature) {
263
+ const pks = await this.pkHelper.getPublicKeyBatch(createInfo.ownerWithWeight.map((owner) => owner.address));
264
+ await this.globals.backend.createMSafeAccount({
265
+ ownersWithWeightPKEncoded: createInfo.ownerWithWeight.map((owner, i) => {
266
+ const publicKeySer = PublicKeySerde.ser(pks[i]);
267
+ return {
268
+ address: owner.address,
269
+ weight: owner.weight,
270
+ publicKeyEncoded: publicKeySer.publicKey,
271
+ schema: publicKeySer.scheme
272
+ };
273
+ }),
274
+ threshold: createInfo.threshold,
275
+ name: createInfo.name,
276
+ // name validation is deferred to backend
277
+ description: createInfo.description,
278
+ // description validation is deferred to backend
279
+ creationNonce: createInfo.creationNonce,
280
+ signature
281
+ });
282
+ }
283
+ };
284
+
285
+ // src/transactions/coin-transfer.ts
286
+ var import_transactions = require("@mysten/sui.js/transactions");
287
+
223
288
  // src/utils/sui.ts
289
+ var import_cryptography2 = require("@mysten/sui.js/cryptography");
290
+ var import_multisig = require("@mysten/sui.js/multisig");
224
291
  var SUI_COIN = "0x2::sui::SUI";
225
292
  async function getPublicKeyFromChain(suiClient, address) {
226
293
  let txs;
@@ -488,165 +555,19 @@ var MessageHelper = class {
488
555
  }
489
556
  };
490
557
 
491
- // src/utils/multi-sig.ts
492
- var import_ed255192 = require("@mysten/sui.js/keypairs/ed25519");
493
- var import_multisig2 = require("@mysten/sui.js/multisig");
494
- var NONCE_PK_PREFIX = "maven";
495
- var NONCE_PREFIX_MAX_SIZE = 16;
496
- var NONCE_PK_WEIGHT = 1;
497
- var MAX_WEIGHT = 255;
498
- var MIN_WEIGHT = 1;
499
- var MAX_OWNER_WITH_NONCE = 9;
500
- var MAX_OWNER_WITHOUT_NONCE = 10;
501
- var MIN_THRESHOLD = 1;
502
- var RawMultiSig = class _RawMultiSig {
503
- constructor(config) {
504
- this.config = config;
505
- this.rawMsPK = getMultiSigPublicKey(config);
506
- }
507
- rawMsPK;
508
- static fromMSafeAccountInfo(info) {
509
- const parsed = {
510
- threshold: info.threshold,
511
- ownerWithWeight: info.ownersWithWeightPK,
512
- creationNonce: info.creationNonce
513
- };
514
- return new _RawMultiSig(parsed);
515
- }
516
- get suiAddress() {
517
- return this.rawMsPK.toSuiAddress();
518
- }
519
- get publicKeys() {
520
- return this.rawMsPK.getPublicKeys();
521
- }
522
- get threshold() {
523
- return this.config.threshold;
524
- }
525
- combinePartialSignatures(signatures) {
526
- return this.rawMsPK.combinePartialSignatures(signatures);
527
- }
528
- async verifyPersonalMessage(messageStr, multiSigSignature) {
529
- const message = stringToBuffer(messageStr);
530
- return this.rawMsPK.verifyPersonalMessage(message, multiSigSignature);
531
- }
532
- };
533
- function getMultiSigPublicKey(config) {
534
- const { ownerWithWeight, threshold, creationNonce } = config;
535
- const pks = ownerWithWeight.map((pk) => ({
536
- publicKey: pk.publicKey,
537
- weight: pk.weight
538
- }));
539
- if (creationNonce !== void 0) {
540
- pks.push({
541
- publicKey: makeNoncePublicKey(creationNonce),
542
- weight: NONCE_PK_WEIGHT
543
- });
544
- }
545
- return import_multisig2.MultiSigPublicKey.fromPublicKeys({ threshold, publicKeys: pks });
546
- }
547
- function makeNoncePublicKey(nonce) {
548
- const buffer = new ArrayBuffer(import_ed255192.Ed25519PublicKey.SIZE);
549
- const textEncoder = new TextEncoder();
550
- textEncoder.encodeInto(NONCE_PK_PREFIX, new Uint8Array(buffer, 0, NONCE_PREFIX_MAX_SIZE));
551
- const nonceView = new DataView(buffer, NONCE_PREFIX_MAX_SIZE, 4);
552
- nonceView.setUint32(0, nonce, true);
553
- return new import_ed255192.Ed25519PublicKey(new Uint8Array(buffer));
554
- }
555
- function validateMultiSigConfig(config) {
556
- config.ownerWithWeight.forEach((pk) => {
557
- const { weight } = pk;
558
- if (weight < MIN_WEIGHT || weight > MAX_WEIGHT) {
559
- throw new Error(`Invalid multi-sig weight: ${weight} (1-${MAX_WEIGHT})`);
560
- }
561
- });
562
- const totalWeight = config.ownerWithWeight.reduce((s, pk) => s + pk.weight, 0);
563
- if (config.threshold > totalWeight) {
564
- throw new Error("Threshold is larger than total weight");
565
- }
566
- if (config.threshold < MIN_THRESHOLD) {
567
- throw new Error("Threshold is smaller than 1");
568
- }
569
- const maxOwner = config.creationNonce === void 0 ? MAX_OWNER_WITHOUT_NONCE : MAX_OWNER_WITH_NONCE;
570
- if (config.ownerWithWeight.length > maxOwner) {
571
- throw new Error("Owner number bigger than upper cap");
572
- }
573
- const addressSet = new Set(config.ownerWithWeight.map((pk) => pk.publicKey.toSuiAddress()));
574
- if (addressSet.size !== config.ownerWithWeight.length) {
575
- throw new Error("Duplicate address detected");
576
- }
577
- }
578
-
579
- // src/core/CreateHelper.ts
580
- var CreateHelper = class {
581
- constructor(globals, pkHelper) {
582
- this.globals = globals;
583
- this.pkHelper = pkHelper;
584
- }
585
- async getPublicKeyBatch(addresses) {
586
- return this.pkHelper.getPublicKeyBatch(addresses);
587
- }
588
- async calculateMSafeAddress(info) {
589
- const msConfig = await this.reduceCreationInfoToRawConfig(info);
590
- const ms = new RawMultiSig(msConfig);
591
- return ms.suiAddress;
592
- }
593
- // Validate the create info and return the msafe address.
594
- async validateCreateInfo(createInfo) {
595
- const rawConfig = await this.reduceCreationInfoToRawConfig(createInfo);
596
- validateMultiSigConfig(rawConfig);
597
- return this.calculateMSafeAddress(createInfo);
598
- }
599
- async submitMSafeCreation(creationInfo) {
600
- const msafeAddress = await this.validateCreateInfo(creationInfo);
601
- const signingMessage = MessageHelper.createMSafeMessage(msafeAddress);
602
- const signature = await this.globals.wallet.signPersonalMessage({ messageStr: signingMessage });
603
- await this.submitToBackend(creationInfo, signature.signature);
604
- return msafeAddress;
605
- }
606
- async reduceCreationInfoToRawConfig(info) {
607
- const publicKeys = await this.getPublicKeyBatch(info.ownerWithWeight.map((oww) => oww.address));
608
- publicKeys.forEach((pk, i) => {
609
- if (pk === void 0) {
610
- throw new Error(`Unknown public key for address: ${info.ownerWithWeight[i].address}`);
611
- }
612
- });
613
- return {
614
- threshold: info.threshold,
615
- ownerWithWeight: info.ownerWithWeight.map((owner, i) => ({
616
- publicKey: publicKeys[i],
617
- weight: owner.weight
618
- })),
619
- creationNonce: info.creationNonce
620
- };
621
- }
622
- async submitToBackend(createInfo, signature) {
623
- const pks = await this.pkHelper.getPublicKeyBatch(createInfo.ownerWithWeight.map((owner) => owner.address));
624
- await this.globals.backend.createMSafeAccount({
625
- ownerWithWeight: createInfo.ownerWithWeight.map((owner, i) => ({
626
- address: owner.address,
627
- weight: owner.weight,
628
- publicKey: pks[i]
629
- // PublicKey has been verified.
630
- })),
631
- threshold: createInfo.threshold,
632
- name: createInfo.name,
633
- // name validation is deferred to backend
634
- description: createInfo.description,
635
- // description validation is deferred to backend
636
- creationNonce: createInfo.creationNonce,
637
- signature
638
- });
639
- }
640
- };
641
-
642
558
  // src/core/MSafeAccount.ts
559
+ var import_sui3_utils2 = require("@msafe/sui3-utils");
643
560
  var MSafeAccount = class _MSafeAccount {
644
561
  constructor(globals, info) {
645
562
  this.globals = globals;
646
563
  this.info = info;
647
- this.rawMultiSig = RawMultiSig.fromMSafeAccountInfo(info);
564
+ this.multisigManager = new import_sui3_utils2.MultisigAccountManager({
565
+ threshold: info.threshold,
566
+ ownersWithWeight: info.ownersWithWeightPK,
567
+ creationNonce: info.creationNonce
568
+ });
648
569
  }
649
- rawMultiSig;
570
+ multisigManager;
650
571
  static async new(globals, address) {
651
572
  const info = await globals.backend.getMSafeAccountInfo(address);
652
573
  return new _MSafeAccount(globals, info);
@@ -755,7 +676,7 @@ var MSafeAccount = class _MSafeAccount {
755
676
  sigs.push(signature);
756
677
  }
757
678
  }
758
- const multiSignature = this.rawMultiSig.combinePartialSignatures(sigs);
679
+ const multiSignature = this.multisigManager.combinePartialSignatures(sigs);
759
680
  return this.suiClient.executeTransactionBlock({
760
681
  transactionBlock: HexToUint8Array(pending.payload),
761
682
  signature: multiSignature,
@@ -848,762 +769,6 @@ var PublicKeyHelper = class {
848
769
  // src/globals/MSafeGlobals.ts
849
770
  var import_client = require("@mysten/sui.js/client");
850
771
 
851
- // src/backend/PseudoBackend.ts
852
- var import_reflect_metadata2 = require("reflect-metadata");
853
- var import_typeorm = require("typeorm");
854
-
855
- // src/backend/CoreDatabase.ts
856
- var import_reflect_metadata = require("reflect-metadata");
857
- var import_core = require("@msafe/sui3-model/core");
858
- var WALLET_TYPE_KEY = "wallet_type";
859
- var CoreDB = class _CoreDB {
860
- constructor(coreModel) {
861
- this.coreModel = coreModel;
862
- }
863
- static async New(dbConfig) {
864
- const core = await import_core.CoreModel.New(dbConfig);
865
- return new _CoreDB(core);
866
- }
867
- async upsertUser(input) {
868
- const currentUser = await this.coreModel.user.findOneBy({
869
- address: input.address
870
- });
871
- if (currentUser !== null) {
872
- currentUser.lastLogin = input.lastLogin;
873
- await this.coreModel.user.save(currentUser);
874
- } else {
875
- const serializedPublicKey = PublicKeySerde.ser(input.publicKey);
876
- const user = {
877
- address: input.address,
878
- publicKey: serializedPublicKey.publicKey,
879
- schema: serializedPublicKey.scheme,
880
- nonce: 0,
881
- lastLogin: /* @__PURE__ */ new Date()
882
- };
883
- await this.coreModel.user.save(user);
884
- }
885
- }
886
- async updateUserWalletType(input) {
887
- const exist = await this.coreModel.userSetting.findOneBy({
888
- userAddress: input.address,
889
- key: WALLET_TYPE_KEY
890
- });
891
- const walletType = input.walletType.trim();
892
- if (exist === null || exist.value !== walletType) {
893
- const userSetting = {
894
- userAddress: input.address,
895
- key: WALLET_TYPE_KEY,
896
- value: walletType
897
- };
898
- await this.coreModel.userSetting.save(userSetting);
899
- }
900
- }
901
- };
902
-
903
- // src/backend/PseudoBackend.ts
904
- var PseudoBackend = class _PseudoBackend {
905
- constructor(db, _suiClient) {
906
- this.db = db;
907
- this._suiClient = _suiClient;
908
- }
909
- _token;
910
- static async New(dbConfig, suiClient) {
911
- const db = await CoreDB.New(dbConfig);
912
- return new _PseudoBackend(db, suiClient);
913
- }
914
- // eslint-disable-next-line @typescript-eslint/no-unused-vars,unused-imports/no-unused-vars
915
- async isJWTTokenValid(_jwt) {
916
- return true;
917
- }
918
- async authSign(input) {
919
- const timestamp = MessageHelper.deWelcomeMessage(input.message);
920
- if (!timestamp) {
921
- throw new Error("Invalid welcome message");
922
- }
923
- const date = Date.parse(timestamp);
924
- if ((/* @__PURE__ */ new Date()).getTime() - date < 0) {
925
- throw new Error("Invalid timestamp");
926
- }
927
- if ((/* @__PURE__ */ new Date()).getTime() - date > 10 * 1e3) {
928
- throw new Error("Signing message expired");
929
- }
930
- const publicKey = await SignatureVerifier.getPublicKeyFromPersonalSignature({
931
- messageStr: input.message,
932
- signature: input.signature
933
- });
934
- if (!Formatter.isSuiAddressEqual(input.address, publicKey.toSuiAddress())) {
935
- throw new Error("Invalid signature");
936
- }
937
- await this.db.upsertUser({
938
- address: input.address,
939
- publicKey,
940
- lastLogin: /* @__PURE__ */ new Date()
941
- });
942
- await this.db.updateUserWalletType({
943
- address: input.address,
944
- walletType: input.walletType
945
- });
946
- this._token = "";
947
- return this._token;
948
- }
949
- setJWTToken(token) {
950
- this._token = token;
951
- }
952
- async getPublicKey(address) {
953
- const user = await this.model.user.findOneBy({
954
- address
955
- });
956
- if (user === null) {
957
- return void 0;
958
- }
959
- return PublicKeySerde.de({
960
- publicKey: user.publicKey,
961
- scheme: user.schema
962
- });
963
- }
964
- async getPublicKeyBatch(addresses) {
965
- const res = [];
966
- for (let i = 0; i < addresses.length; i++) {
967
- const address = addresses[i];
968
- const user = await this.getUser(address);
969
- res.push(
970
- user ? PublicKeySerde.de({
971
- publicKey: user.publicKey,
972
- scheme: user.schema
973
- }) : void 0
974
- );
975
- }
976
- return res;
977
- }
978
- async createMSafeAccount(input) {
979
- const ms = new RawMultiSig(input);
980
- const msafeAddr = ms.suiAddress;
981
- const signingMsg = MessageHelper.createMSafeMessage(msafeAddr);
982
- const targetAddr = input.ownerWithWeight[0].address;
983
- const verifyResult = await SignatureVerifier.verifyPersonalSignature({
984
- messageStr: signingMsg,
985
- signature: input.signature,
986
- targetAddress: targetAddr
987
- });
988
- if (!verifyResult) {
989
- throw new Error("Signature verification failed");
990
- }
991
- if (input.name.length > 128) {
992
- throw new Error("Name too long");
993
- }
994
- if (input.description && input.description.length > 512) {
995
- throw new Error("Description too long");
996
- }
997
- const creatorAddress = input.ownerWithWeight[0].address;
998
- const creator = await this.getUser(creatorAddress);
999
- if (creator === null) {
1000
- throw new Error("Creator not found");
1001
- }
1002
- if (creator.nonce !== input.creationNonce) {
1003
- throw new Error("Nonce not match");
1004
- }
1005
- const msafeExistCheck = await this.model.msafe.findOneBy({
1006
- address: msafeAddr
1007
- });
1008
- if (msafeExistCheck !== null) {
1009
- throw new Error("MSafe already exist in database");
1010
- }
1011
- input.ownerWithWeight.forEach((ownerInfo) => {
1012
- if (!Formatter.isSuiAddressEqual(ownerInfo.address, ownerInfo.publicKey.toSuiAddress())) {
1013
- throw new Error("Sui address public key not match");
1014
- }
1015
- });
1016
- for (let i = 0; i !== input.ownerWithWeight.length; i++) {
1017
- const ownerInfo = input.ownerWithWeight[i];
1018
- if (i !== 0) {
1019
- const coManager = await this.getUser(ownerInfo.address);
1020
- const serPK = PublicKeySerde.ser(ownerInfo.publicKey);
1021
- if (coManager === null) {
1022
- const user = {
1023
- address: ownerInfo.address,
1024
- publicKey: serPK.publicKey,
1025
- schema: serPK.scheme,
1026
- nonce: 0,
1027
- lastLogin: /* @__PURE__ */ new Date()
1028
- };
1029
- await this.model.user.save(user);
1030
- }
1031
- }
1032
- const userMSafe = {
1033
- userAddress: ownerInfo.address,
1034
- msafeAddress: msafeAddr,
1035
- index: i,
1036
- weight: ownerInfo.weight,
1037
- status: i === 0 ? "active" : "pending"
1038
- };
1039
- await this.model.userMSafe.save(userMSafe);
1040
- }
1041
- const creationNonce = creator.nonce;
1042
- creator.nonce++;
1043
- await this.model.user.save(creator);
1044
- const msafe = {
1045
- address: msafeAddr,
1046
- creationNonce,
1047
- creator: creatorAddress,
1048
- name: input.name,
1049
- description: input.description,
1050
- threshold: input.threshold
1051
- };
1052
- await this.model.msafe.save(msafe);
1053
- }
1054
- async getMSafeAccountInfo(msafeAddress) {
1055
- const msafe = await this.model.msafe.findOneBy({ address: msafeAddress });
1056
- if (msafe === null) {
1057
- throw new Error("MSafe not found");
1058
- }
1059
- const userMSafes = await this.model.userMSafe.find({
1060
- where: {
1061
- msafeAddress
1062
- },
1063
- order: {
1064
- index: "asc"
1065
- }
1066
- });
1067
- if (userMSafes.length === 0) {
1068
- throw new Error("MSafe does not have user info.");
1069
- }
1070
- const users = await Promise.all(userMSafes.map((um) => this.getUser(um.userAddress)));
1071
- users.forEach((user) => {
1072
- if (user === null) {
1073
- throw new Error("User not found");
1074
- }
1075
- });
1076
- const ownersWithWeightPK = userMSafes.map((userMSafe, i) => ({
1077
- address: userMSafe.userAddress,
1078
- weight: userMSafe.weight,
1079
- publicKey: PublicKeySerde.de({ publicKey: users[i].publicKey, scheme: users[i].schema })
1080
- }));
1081
- return {
1082
- address: msafeAddress,
1083
- ownersWithWeightPK,
1084
- threshold: msafe.threshold,
1085
- name: msafe.name,
1086
- description: msafe.description,
1087
- creationNonce: msafe.creationNonce
1088
- };
1089
- }
1090
- async getUserInfo(userAddress) {
1091
- const user = await this.getUser(userAddress);
1092
- if (user === null) {
1093
- throw new Error("404: user not found");
1094
- }
1095
- const msafeAccounts = await this.model.userMSafe.findBy({ userAddress });
1096
- const ownedMSafe = await Promise.all(
1097
- msafeAccounts.map(async (msafeAccount) => this.getMSafeAccountInfo(msafeAccount.msafeAddress))
1098
- );
1099
- return {
1100
- address: userAddress,
1101
- publicKey: user.publicKey,
1102
- schema: user.schema,
1103
- creationNonce: user.nonce,
1104
- ownedMSafe
1105
- };
1106
- }
1107
- async getPendingTransactions(msafeAddress) {
1108
- const pendings = await this.db.coreModel.pendingTransaction.findBy({
1109
- msafeAddress
1110
- });
1111
- if (pendings.length === 0) {
1112
- return [];
1113
- }
1114
- const votes = await Promise.all(
1115
- pendings.map((pending) => this.db.coreModel.userVote.findBy({ txDigest: pending.digest, isValid: true }))
1116
- );
1117
- const intention = await this.model.transactionIntention.findOneBy({
1118
- msafeAddress,
1119
- sequenceNumber: pendings[0].sequenceNumber
1120
- });
1121
- if (intention === null) {
1122
- throw new Error("Intention not found");
1123
- }
1124
- const intent = IntentionHelper.de(intention.data);
1125
- return pendings.map((pending, i) => ({
1126
- digest: pending.digest,
1127
- payload: pending.payload,
1128
- msafeAddress: pending.msafeAddress,
1129
- isRejectTx: pending.isRejectTx,
1130
- creator: pending.creator,
1131
- createdAt: pending.createdAt,
1132
- votes: votes[i].map((vote) => ({
1133
- userAddress: vote.userAddress,
1134
- signature: vote.signature,
1135
- timestamp: vote.updatedAt
1136
- })),
1137
- sequenceNumber: pending.sequenceNumber,
1138
- intention: pending.isRejectTx ? void 0 : intent
1139
- }));
1140
- }
1141
- async getCurrentSequenceNumber(msafeAddress) {
1142
- const maxSNHistory = await this.model.historyTransaction.findOne({
1143
- where: { msafeAddress },
1144
- order: { sequenceNumber: "desc" }
1145
- });
1146
- return maxSNHistory === null ? 0 : maxSNHistory.sequenceNumber + 1;
1147
- }
1148
- async getNextSequenceNumber(msafeAddress) {
1149
- const maxSNIntention = await this.model.transactionIntention.findOne({
1150
- where: { msafeAddress },
1151
- order: { sequenceNumber: "desc" }
1152
- });
1153
- return maxSNIntention === null ? 0 : maxSNIntention.sequenceNumber + 1;
1154
- }
1155
- async getHistoryTransactions(msafeAddress) {
1156
- const transactions = await this.db.coreModel.historyTransaction.find({
1157
- where: {
1158
- msafeAddress
1159
- },
1160
- order: { sequenceNumber: "desc" }
1161
- });
1162
- const votes = await Promise.all(
1163
- transactions.map(
1164
- (tx) => this.db.coreModel.userVote.findBy({
1165
- txDigest: tx.digest,
1166
- isValid: true
1167
- })
1168
- )
1169
- );
1170
- return transactions.map((tx, i) => ({
1171
- digest: tx.digest,
1172
- payload: tx.payload,
1173
- msafeAddress: tx.msafeAddress,
1174
- isRejectTx: tx.isRejectTx,
1175
- status: tx.status,
1176
- creator: tx.creator,
1177
- createdAt: tx.createdAt,
1178
- sequenceNumber: tx.sequenceNumber,
1179
- votes: votes[i].map((vote) => ({
1180
- userAddress: vote.userAddress,
1181
- timestamp: vote.updatedAt
1182
- }))
1183
- }));
1184
- }
1185
- async getFutureIntentions(msafeAddress) {
1186
- const currentSequenceNumber = await this.getCurrentSequenceNumber(msafeAddress);
1187
- const hasPending = await this.model.pendingTransaction.findOneBy({ msafeAddress }) !== null;
1188
- const futureSNStart = hasPending ? currentSequenceNumber + 1 : currentSequenceNumber;
1189
- const futureTxs = await this.model.transactionIntention.find({
1190
- where: { msafeAddress, sequenceNumber: (0, import_typeorm.MoreThanOrEqual)(futureSNStart) },
1191
- order: { sequenceNumber: "asc" }
1192
- });
1193
- return futureTxs.map((tx) => ({
1194
- intention: IntentionHelper.de(tx.data),
1195
- msafeAddress: tx.msafeAddress,
1196
- sequenceNumber: tx.sequenceNumber,
1197
- rawData: tx.data,
1198
- txType: tx.txType,
1199
- txSubType: tx.txSubType,
1200
- processed: tx.processed,
1201
- status: tx.status,
1202
- statusRemark: tx.statusRemark,
1203
- creator: tx.creator,
1204
- createdAt: tx.createdAt
1205
- }));
1206
- }
1207
- async proposeIntention(input) {
1208
- const userMSafe = await this.model.userMSafe.findOneBy({
1209
- msafeAddress: input.msafeAddress,
1210
- userAddress: input.userAddress
1211
- });
1212
- if (!userMSafe) {
1213
- throw new Error("User does not have permission to propose intention");
1214
- }
1215
- const verified = await SignatureVerifier.verifyPersonalSignature({
1216
- messageStr: MessageHelper.proposeIntentionMessage({ intention: input.intention, sn: input.sequenceNumber }),
1217
- signature: input.signature,
1218
- targetAddress: input.userAddress
1219
- });
1220
- if (!verified) {
1221
- throw new Error("Invalid signature");
1222
- }
1223
- const sequenceNumber = await this.model.transactionIntention.count({
1224
- where: {
1225
- msafeAddress: input.msafeAddress
1226
- }
1227
- });
1228
- if (sequenceNumber !== input.sequenceNumber) {
1229
- throw new Error("Sequence number not expected");
1230
- }
1231
- const intention = {
1232
- msafeAddress: input.msafeAddress,
1233
- sequenceNumber,
1234
- processed: false,
1235
- ...IntentionHelper.getTxType(input.intention),
1236
- data: IntentionHelper.ser(input.intention),
1237
- status: "NEW",
1238
- creator: input.userAddress
1239
- };
1240
- await this.model.transactionIntention.save(intention);
1241
- }
1242
- // Propose a pending transaction. Require the msafe account
1243
- // Does not have any pending transactions.
1244
- async proposePendingTransaction(input) {
1245
- const userMSafe = await this.model.userMSafe.findOneBy({
1246
- msafeAddress: input.msafeAddress,
1247
- userAddress: input.userAddress
1248
- });
1249
- if (userMSafe === null) {
1250
- throw new Error("Unauthorized");
1251
- }
1252
- const msafePendings = await this.model.pendingTransaction.findBy({
1253
- msafeAddress: input.msafeAddress
1254
- });
1255
- if (msafePendings.length !== 0) {
1256
- throw new Error("Still have pending transaction");
1257
- }
1258
- const txb = await IntentionHelper.buildTxb({
1259
- suiClient: this._suiClient,
1260
- intention: input.intention,
1261
- sender: input.msafeAddress
1262
- });
1263
- const payload = await txb.build({ client: this._suiClient });
1264
- const txDigest = await txb.getDigest({ client: this._suiClient });
1265
- if (txDigest !== input.digest) {
1266
- throw new Error("Transaction digest un-match");
1267
- }
1268
- const verified = await SignatureVerifier.verifyTransactionSignature({
1269
- payload,
1270
- targetAddress: input.userAddress,
1271
- signature: input.signature
1272
- });
1273
- if (!verified) {
1274
- throw new Error("Failed to verify signature");
1275
- }
1276
- const maxSNHistory = await this.model.historyTransaction.findOne({
1277
- where: { msafeAddress: input.msafeAddress },
1278
- order: { sequenceNumber: "desc" }
1279
- });
1280
- const sequenceNumber = maxSNHistory === null ? 0 : maxSNHistory.sequenceNumber + 1;
1281
- const intention = {
1282
- msafeAddress: input.msafeAddress,
1283
- sequenceNumber,
1284
- processed: false,
1285
- ...IntentionHelper.getTxType(input.intention),
1286
- data: IntentionHelper.ser(input.intention),
1287
- status: "SUCCESS",
1288
- creator: input.userAddress
1289
- };
1290
- await this.model.transactionIntention.save(intention);
1291
- const pendingTx = {
1292
- digest: txDigest,
1293
- msafeAddress: input.msafeAddress,
1294
- payload: Uint8ArrayToHex(payload),
1295
- sequenceNumber,
1296
- isRejectTx: false,
1297
- creator: input.userAddress
1298
- };
1299
- await this.model.pendingTransaction.save(pendingTx);
1300
- const userVote = {
1301
- userAddress: input.userAddress,
1302
- txDigest,
1303
- msafeAddress: input.msafeAddress,
1304
- signature: input.signature,
1305
- isValid: true
1306
- };
1307
- await this.model.userVote.save(userVote);
1308
- }
1309
- // Calls for the first reject transaction
1310
- async rejectCurrentTx(input) {
1311
- const userMSafe = await this.model.userMSafe.findOneBy({
1312
- userAddress: input.userAddress,
1313
- msafeAddress: input.msafeAddress
1314
- });
1315
- if (userMSafe === null) {
1316
- throw new Error("User does not have permission to MSafe");
1317
- }
1318
- const currentPending = await this.model.pendingTransaction.findOneBy({
1319
- msafeAddress: input.msafeAddress,
1320
- isRejectTx: false
1321
- });
1322
- if (currentPending === null) {
1323
- throw new Error("No active pending transaction");
1324
- }
1325
- const txb = await IntentionHelper.buildRejectTransaction({
1326
- msafeAddress: input.msafeAddress,
1327
- payloadToReject: currentPending.payload
1328
- });
1329
- const payload = await txb.build({ client: this._suiClient });
1330
- const digest = await txb.getDigest({ client: this._suiClient });
1331
- if (input.digest !== digest) {
1332
- throw new Error("Digest not match");
1333
- }
1334
- const verified = await SignatureVerifier.verifyTransactionSignature({
1335
- payload,
1336
- targetAddress: input.userAddress,
1337
- signature: input.signature
1338
- });
1339
- if (!verified) {
1340
- throw new Error("Signature unverified");
1341
- }
1342
- const existPendingReject = await this.model.pendingTransaction.findOneBy({
1343
- msafeAddress: input.msafeAddress,
1344
- isRejectTx: true
1345
- });
1346
- if (existPendingReject !== null) {
1347
- await this.voteForTransaction({
1348
- txDigest: existPendingReject.digest,
1349
- msafeAddress: input.msafeAddress,
1350
- userAddress: input.userAddress,
1351
- signature: input.signature
1352
- });
1353
- return;
1354
- }
1355
- const rejectPayloadStr = Uint8ArrayToHex(payload);
1356
- const rejectDigest = await txb.getDigest({ client: this._suiClient });
1357
- const rejectPending = {
1358
- msafeAddress: input.msafeAddress,
1359
- digest: rejectDigest,
1360
- payload: rejectPayloadStr,
1361
- sequenceNumber: currentPending.sequenceNumber,
1362
- isRejectTx: true,
1363
- creator: input.userAddress
1364
- };
1365
- await this.model.pendingTransaction.save(rejectPending);
1366
- const rejectVote = {
1367
- userAddress: input.userAddress,
1368
- msafeAddress: input.msafeAddress,
1369
- txDigest: rejectDigest,
1370
- signature: input.signature,
1371
- isValid: true
1372
- };
1373
- await this.model.userVote.save(rejectVote);
1374
- const existVote = await this.model.userVote.findOneBy({
1375
- txDigest: currentPending.digest,
1376
- userAddress: input.userAddress
1377
- });
1378
- if (existVote !== null) {
1379
- await this.model.userVote.update(
1380
- { userAddress: input.userAddress, txDigest: currentPending.digest },
1381
- { isValid: false }
1382
- );
1383
- }
1384
- }
1385
- async voteForTransaction(input) {
1386
- const pendingTx = await this.model.pendingTransaction.findOneBy({ digest: input.txDigest });
1387
- if (!pendingTx) {
1388
- throw new Error(`Pending transaction not found: ${input.txDigest}`);
1389
- }
1390
- if (pendingTx.msafeAddress !== input.msafeAddress) {
1391
- throw new Error("MSafe address not match");
1392
- }
1393
- const userMSafe = await this.model.userMSafe.findOneBy({
1394
- userAddress: input.userAddress,
1395
- msafeAddress: input.msafeAddress
1396
- });
1397
- if (userMSafe === null) {
1398
- throw new Error(`User (${input.userAddress}) does not have permission on MSafe account (${input.msafeAddress})`);
1399
- }
1400
- const payload = HexToUint8Array(pendingTx.payload);
1401
- const verified = await SignatureVerifier.verifyTransactionSignature({
1402
- payload,
1403
- targetAddress: input.userAddress,
1404
- signature: input.signature
1405
- });
1406
- if (!verified) {
1407
- throw new Error("Invalid signature");
1408
- }
1409
- const rejectPendingTx = await this.model.pendingTransaction.findOneBy({
1410
- msafeAddress: input.msafeAddress,
1411
- sequenceNumber: pendingTx.sequenceNumber,
1412
- isRejectTx: !pendingTx.isRejectTx
1413
- });
1414
- if (rejectPendingTx !== null) {
1415
- await this.model.userVote.update(
1416
- {
1417
- userAddress: input.userAddress,
1418
- txDigest: rejectPendingTx.digest,
1419
- isValid: true
1420
- },
1421
- { isValid: false }
1422
- );
1423
- }
1424
- const existVote = await this.model.userVote.exist({
1425
- where: {
1426
- txDigest: input.txDigest,
1427
- userAddress: input.userAddress
1428
- }
1429
- });
1430
- if (!existVote) {
1431
- const userVote = {
1432
- txDigest: input.txDigest,
1433
- userAddress: input.userAddress,
1434
- msafeAddress: input.msafeAddress,
1435
- signature: input.signature,
1436
- isValid: true
1437
- };
1438
- await this.model.userVote.save(userVote);
1439
- } else {
1440
- await this.model.userVote.update(
1441
- {
1442
- txDigest: input.txDigest,
1443
- userAddress: input.userAddress
1444
- },
1445
- { isValid: true }
1446
- );
1447
- }
1448
- }
1449
- // Mock the process of an executed transaction
1450
- // Here only the essential logic of transaction processing logic
1451
- // is implemented. Need more transaction parsing from the fetcher
1452
- // module.
1453
- //
1454
- // TODO: User queryRunner to make the transaction atomic.
1455
- async processExecutedTransaction(digest) {
1456
- const historyTx = await this.model.historyTransaction.findOneBy({ digest });
1457
- if (historyTx) {
1458
- return;
1459
- }
1460
- const pendingTx = await this.model.pendingTransaction.findOneBy({ digest });
1461
- if (!pendingTx) {
1462
- throw new Error("Transaction digest not found");
1463
- }
1464
- await this.model.transactionIntention.update(
1465
- { msafeAddress: pendingTx.msafeAddress, sequenceNumber: pendingTx.sequenceNumber },
1466
- { processed: true }
1467
- );
1468
- const pendings = await this.model.pendingTransaction.findBy({
1469
- msafeAddress: pendingTx.msafeAddress,
1470
- sequenceNumber: pendingTx.sequenceNumber
1471
- });
1472
- if (pendings.length === 0) {
1473
- throw new Error("Pending transaction not found");
1474
- }
1475
- const executionResult = "success";
1476
- for (let i = 0; i !== pendings.length; i++) {
1477
- const pending = pendings[i];
1478
- const history = {
1479
- digest: pending.digest,
1480
- payload: pending.payload,
1481
- msafeAddress: pending.msafeAddress,
1482
- sequenceNumber: pending.sequenceNumber,
1483
- isRejectTx: pending.isRejectTx,
1484
- creator: pending.creator,
1485
- createdAt: pending.createdAt,
1486
- // TODO: Fill in this field based on transaction processing result
1487
- status: pending.digest === digest ? executionResult : "rejected"
1488
- };
1489
- await this.model.historyTransaction.save(history);
1490
- await this.model.pendingTransaction.delete({ digest: pending.digest });
1491
- }
1492
- }
1493
- /**
1494
- * Build the next transaction intention, and add the built transaction to pendings.
1495
- * @param input
1496
- */
1497
- async buildNextIntentionAndAddToPending(input) {
1498
- const maxSNHistory = await this.model.historyTransaction.findOne({
1499
- where: { msafeAddress: input.msafeAddress },
1500
- order: { sequenceNumber: "desc" }
1501
- });
1502
- const nextSequenceNumber = maxSNHistory ? maxSNHistory.sequenceNumber + 1 : 0;
1503
- const currentPendings = await this.model.pendingTransaction.findBy({
1504
- msafeAddress: input.msafeAddress
1505
- });
1506
- if (currentPendings.length !== 0) {
1507
- throw new Error("Still have pendings");
1508
- }
1509
- const nextTx = await this.model.transactionIntention.findOneBy({
1510
- msafeAddress: input.msafeAddress,
1511
- sequenceNumber: nextSequenceNumber
1512
- });
1513
- if (nextTx === null) {
1514
- throw new Error("No future intentions to build");
1515
- }
1516
- const nextIntention = IntentionHelper.de(nextTx.data);
1517
- try {
1518
- const newTxb = await IntentionHelper.buildTxb({
1519
- suiClient: this._suiClient,
1520
- sender: input.msafeAddress,
1521
- intention: nextIntention
1522
- });
1523
- const payload = await newTxb.build({ client: this._suiClient });
1524
- const newDigest = await newTxb.getDigest({ client: this._suiClient });
1525
- const newPending = {
1526
- digest: newDigest,
1527
- payload: Uint8ArrayToHex(payload),
1528
- msafeAddress: input.msafeAddress,
1529
- sequenceNumber: nextTx.sequenceNumber,
1530
- isRejectTx: false,
1531
- creator: nextTx.creator
1532
- };
1533
- await this.model.pendingTransaction.save(newPending);
1534
- await this.model.transactionIntention.update(
1535
- {
1536
- msafeAddress: input.msafeAddress,
1537
- sequenceNumber: nextSequenceNumber
1538
- },
1539
- {
1540
- status: "SUCCESS"
1541
- }
1542
- );
1543
- } catch (e) {
1544
- await this.model.transactionIntention.update(
1545
- {
1546
- msafeAddress: input.msafeAddress,
1547
- sequenceNumber: nextSequenceNumber
1548
- },
1549
- {
1550
- status: "FAILED",
1551
- statusRemark: e.toString()
1552
- }
1553
- );
1554
- throw new Error(`Intention build failed: {sequenceNumber: ${nextSequenceNumber}}`);
1555
- }
1556
- }
1557
- /**
1558
- * Skip next failed transaction if build of the intention has been failed before.
1559
- */
1560
- async skipNextFailedIntention(input) {
1561
- const userMSafe = await this.model.userMSafe.findOneBy({
1562
- msafeAddress: input.msafeAddress,
1563
- userAddress: input.userAddress
1564
- });
1565
- if (userMSafe === null) {
1566
- throw new Error("user does not have permission to MSafe");
1567
- }
1568
- const curSequenceNumber = await this.model.historyTransaction.findOne({
1569
- where: { msafeAddress: input.msafeAddress },
1570
- order: { sequenceNumber: "desc" }
1571
- });
1572
- const nextSequenceNumber = curSequenceNumber ? curSequenceNumber.sequenceNumber + 1 : 0;
1573
- const failedIntention = await this.model.transactionIntention.findOneBy({
1574
- msafeAddress: input.msafeAddress,
1575
- sequenceNumber: nextSequenceNumber
1576
- });
1577
- if (failedIntention === null) {
1578
- throw new Error("Next intention not found");
1579
- }
1580
- if (failedIntention.status !== "FAILED") {
1581
- throw new Error("Next intention not failed");
1582
- }
1583
- const history = {
1584
- msafeAddress: input.msafeAddress,
1585
- digest: "0x0",
1586
- // Special case for build has been failed,
1587
- payload: "",
1588
- sequenceNumber: nextSequenceNumber,
1589
- creator: failedIntention.creator,
1590
- isRejectTx: false,
1591
- status: "build-failed"
1592
- };
1593
- await this.model.historyTransaction.save(history);
1594
- await this.model.transactionIntention.update(
1595
- { msafeAddress: input.msafeAddress, sequenceNumber: nextSequenceNumber },
1596
- { processed: true }
1597
- );
1598
- }
1599
- async getUser(address) {
1600
- return this.model.user.findOneBy({ address });
1601
- }
1602
- get model() {
1603
- return this.db.coreModel;
1604
- }
1605
- };
1606
-
1607
772
  // src/globals/const.ts
1608
773
  var MSafeEnv = /* @__PURE__ */ ((MSafeEnv3) => {
1609
774
  MSafeEnv3["local"] = "local";
@@ -1638,6 +803,8 @@ var DEV_DATABASE_CONFIG = {
1638
803
  };
1639
804
  var TESTNET_RPC_URL = "https://sui-testnet.blockvision.org/v1/2Sgk89ivT64MnKdcGzjmyjY2ndD";
1640
805
  var MAINNET_RPC_URL = "https://sui-mainnet.blockvision.org/v1/2Sgk7NPvqkd7mESYkxF01yX15l7";
806
+ var LOCAL_API_URL = "http://127.0.0.1:3000";
807
+ var DEV_API_URL = "http://13.56.226.148";
1641
808
  var ENV_CONFIGS = /* @__PURE__ */ new Map([
1642
809
  [
1643
810
  "unit" /* unit */,
@@ -1645,7 +812,8 @@ var ENV_CONFIGS = /* @__PURE__ */ new Map([
1645
812
  suiClient: {
1646
813
  url: TESTNET_RPC_URL
1647
814
  },
1648
- backend: UNIT_DATABASE_CONFIG
815
+ backend: LOCAL_DATABASE_CONFIG,
816
+ apiURL: LOCAL_API_URL
1649
817
  }
1650
818
  ],
1651
819
  [
@@ -1654,7 +822,8 @@ var ENV_CONFIGS = /* @__PURE__ */ new Map([
1654
822
  suiClient: {
1655
823
  url: TESTNET_RPC_URL
1656
824
  },
1657
- backend: LOCAL_DATABASE_CONFIG
825
+ backend: LOCAL_DATABASE_CONFIG,
826
+ apiURL: LOCAL_API_URL
1658
827
  }
1659
828
  ],
1660
829
  [
@@ -1663,7 +832,8 @@ var ENV_CONFIGS = /* @__PURE__ */ new Map([
1663
832
  suiClient: {
1664
833
  url: TESTNET_RPC_URL
1665
834
  },
1666
- backend: DEV_DATABASE_CONFIG
835
+ backend: DEV_DATABASE_CONFIG,
836
+ apiURL: DEV_API_URL
1667
837
  }
1668
838
  ]
1669
839
  ]);
@@ -1682,6 +852,140 @@ function getMSafeConfig(env, options) {
1682
852
  }
1683
853
  var AUTH_SIGN_MESSAGE = "Welcome to MSafe";
1684
854
 
855
+ // src/backend/BackendImpl.ts
856
+ var import_axios = __toESM(require("axios"), 1);
857
+ var BackendImpl = class {
858
+ constructor(apiURL) {
859
+ this.apiURL = apiURL;
860
+ }
861
+ _token;
862
+ async authSign(input) {
863
+ const res = await import_axios.default.post(`${this.apiURL}/auth/login`, input);
864
+ if (res.status !== 200 && res.status !== 201) {
865
+ throw new Error(`invalid authSign return: ${res}`);
866
+ }
867
+ this._token = res.data.accessToken;
868
+ return this._token;
869
+ }
870
+ setJWTToken(token) {
871
+ this._token = token;
872
+ }
873
+ async getPublicKey(address) {
874
+ return (await this.getPublicKeyBatch([address]))[0];
875
+ }
876
+ async getPublicKeyBatch(addresses) {
877
+ const res = await import_axios.default.post(
878
+ `${this.apiURL}/account/getPublicKeyBatch`,
879
+ addresses,
880
+ {
881
+ headers: this.headers()
882
+ }
883
+ );
884
+ if (res.status !== 200 && res.status !== 201) {
885
+ throw new Error(`invalid getPublicKeyBatch return: ${res}`);
886
+ }
887
+ return res.data?.map(
888
+ (publicKeyWithSchema) => publicKeyWithSchema ? PublicKeySerde.de({ ...publicKeyWithSchema }) : void 0
889
+ );
890
+ }
891
+ async getMSafeAccountInfo(msafeAddress) {
892
+ const res = await import_axios.default.get(
893
+ `${this.apiURL}/account/getMSafeAccountInfo/${msafeAddress}`,
894
+ {
895
+ headers: this.headers()
896
+ }
897
+ );
898
+ if (res.status !== 200 && res.status !== 201) {
899
+ throw new Error(`invalid getPublicKeyBatch return: ${res}`);
900
+ }
901
+ const msafeResp = res.data;
902
+ return {
903
+ address: msafeResp.address,
904
+ ownersWithWeightPK: msafeResp.ownersWithWeightPKEncoded.map(
905
+ (owner) => ({
906
+ publicKey: PublicKeySerde.de({ publicKey: owner.publicKeyEncoded, scheme: owner.schema }),
907
+ address: owner.address,
908
+ weight: owner.weight
909
+ })
910
+ ),
911
+ threshold: msafeResp.threshold,
912
+ name: msafeResp.name,
913
+ description: msafeResp.description,
914
+ creationNonce: msafeResp.creationNonce
915
+ };
916
+ }
917
+ async getUserInfo(userAddress) {
918
+ const res = await import_axios.default.get(`${this.apiURL}/account/user/${userAddress}`, {
919
+ headers: this.headers()
920
+ });
921
+ if (res.status !== 200 && res.status !== 201) {
922
+ throw new Error(`invalid getPublicKeyBatch return: ${res}`);
923
+ }
924
+ return {
925
+ address: res.data.address,
926
+ publicKey: res.data.publicKey,
927
+ schema: res.data.schema,
928
+ creationNonce: res.data.creationNonce,
929
+ ownedMSafe: res.data.ownedMSafe.map(
930
+ (msafe) => ({
931
+ address: msafe.address,
932
+ ownersWithWeightPK: msafe.ownersWithWeightPKEncoded.map(
933
+ (owner) => ({
934
+ publicKey: PublicKeySerde.de({ publicKey: owner.publicKeyEncoded, scheme: owner.schema }),
935
+ address: owner.address,
936
+ weight: owner.weight
937
+ })
938
+ ),
939
+ threshold: msafe.threshold,
940
+ name: msafe.name,
941
+ description: msafe.description,
942
+ creationNonce: msafe.creationNonce
943
+ })
944
+ )
945
+ };
946
+ }
947
+ async getPendingTransactions(msafeAddress) {
948
+ return [];
949
+ }
950
+ async getHistoryTransactions(msafeAddress) {
951
+ return [];
952
+ }
953
+ async getFutureIntentions(msafeAddress) {
954
+ return [];
955
+ }
956
+ async getCurrentSequenceNumber(msafeAddress) {
957
+ return 0;
958
+ }
959
+ async getNextSequenceNumber(msafeAddress) {
960
+ return 0;
961
+ }
962
+ async createMSafeAccount(input) {
963
+ const res = await import_axios.default.post(`${this.apiURL}/account`, input, {
964
+ headers: this.headers()
965
+ });
966
+ if (res.status !== 200 && res.status !== 201) {
967
+ throw new Error(`invalid createMSafeAccount return: ${res}`);
968
+ }
969
+ }
970
+ async proposeIntention(input) {
971
+ }
972
+ async proposePendingTransaction(input) {
973
+ }
974
+ async rejectCurrentTx(input) {
975
+ }
976
+ async voteForTransaction(input) {
977
+ }
978
+ async buildNextIntentionAndAddToPending(input) {
979
+ }
980
+ async skipNextFailedIntention(input) {
981
+ }
982
+ async processExecutedTransaction(digest) {
983
+ }
984
+ headers() {
985
+ return { Authorization: `Bearer ${this._token}` };
986
+ }
987
+ };
988
+
1685
989
  // src/globals/MSafeGlobals.ts
1686
990
  var MSafeGlobals = class _MSafeGlobals {
1687
991
  backend;
@@ -1696,7 +1000,7 @@ var MSafeGlobals = class _MSafeGlobals {
1696
1000
  static async New(env, options) {
1697
1001
  const config = getMSafeConfig(env, options);
1698
1002
  const suiClient = new import_client.SuiClient(config.suiClient);
1699
- const backend = await PseudoBackend.New(config.backend, suiClient);
1003
+ const backend = new BackendImpl(config.apiURL);
1700
1004
  return new _MSafeGlobals({
1701
1005
  backend,
1702
1006
  suiClient,
@@ -1730,11 +1034,6 @@ var MSafeClient = class _MSafeClient {
1730
1034
  }
1731
1035
  async connectWallet(input) {
1732
1036
  this.globals.wallet = input.wallet;
1733
- const isValidJWT = input.jwtToken && await this.backend.isJWTTokenValid(input.jwtToken);
1734
- if (isValidJWT) {
1735
- this.backend.setJWTToken(input.jwtToken);
1736
- return input.jwtToken;
1737
- }
1738
1037
  const messageStr = MessageHelper.welcomeMessage((/* @__PURE__ */ new Date()).toUTCString());
1739
1038
  const sig = await input.wallet.signPersonalMessage({
1740
1039
  messageStr
@@ -1793,28 +1092,21 @@ var MSafeClient = class _MSafeClient {
1793
1092
  Coin,
1794
1093
  CoinHelper,
1795
1094
  CreateHelper,
1095
+ DEV_API_URL,
1796
1096
  DEV_DATABASE_CONFIG,
1797
1097
  ENV_CONFIGS,
1798
1098
  Formatter,
1799
1099
  HexToUint8Array,
1800
1100
  IntentionHelper,
1101
+ LOCAL_API_URL,
1801
1102
  LOCAL_DATABASE_CONFIG,
1802
1103
  MAINNET_RPC_URL,
1803
- MAX_OWNER_WITHOUT_NONCE,
1804
- MAX_OWNER_WITH_NONCE,
1805
- MAX_WEIGHT,
1806
- MIN_THRESHOLD,
1807
- MIN_WEIGHT,
1808
1104
  MSafeAccount,
1809
1105
  MSafeClient,
1810
1106
  MSafeEnv,
1811
1107
  MSafeGlobals,
1812
1108
  MessageHelper,
1813
- NONCE_PK_PREFIX,
1814
- NONCE_PK_WEIGHT,
1815
- NONCE_PREFIX_MAX_SIZE,
1816
1109
  PublicKeySerde,
1817
- RawMultiSig,
1818
1110
  SUI_COIN,
1819
1111
  SignatureVerifier,
1820
1112
  TESTNET_RPC_URL,
@@ -1822,10 +1114,7 @@ var MSafeClient = class _MSafeClient {
1822
1114
  Uint8ArrayToHex,
1823
1115
  getAllCoins,
1824
1116
  getMSafeConfig,
1825
- getMultiSigPublicKey,
1826
1117
  getPublicKeyFromChain,
1827
- makeNoncePublicKey,
1828
- stringToBuffer,
1829
- validateMultiSigConfig
1118
+ stringToBuffer
1830
1119
  });
1831
1120
  //# sourceMappingURL=index.cjs.map