@msafe/sui3-sdk 0.0.21 → 0.0.23

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.js CHANGED
@@ -102,7 +102,8 @@ import {
102
102
  TransactionSubTypes,
103
103
  TransactionType,
104
104
  buildObjectTransferTxb,
105
- buildRejectTxb
105
+ buildRejectTxb,
106
+ isSameAddress
106
107
  } from "@msafe/sui3-utils";
107
108
  import { TransactionBlock } from "@mysten/sui.js/transactions";
108
109
  import { normalizeStructTag as normalizeStructTag3 } from "@mysten/sui.js/utils";
@@ -194,6 +195,12 @@ var Formatter = class {
194
195
  return Coin.isCoin(struct);
195
196
  }
196
197
  };
198
+ function addPrefix(s, prefix) {
199
+ if (s.startsWith(prefix)) {
200
+ return s;
201
+ }
202
+ return prefix + s;
203
+ }
197
204
 
198
205
  // src/utils/crypto.ts
199
206
  var SignatureVerifier = class _SignatureVerifier {
@@ -481,6 +488,7 @@ var MSafeAccount = class _MSafeAccount {
481
488
  };
482
489
  return getAllOwnedObjects(this.suiClient, this.address, filterCoinObjectOptions);
483
490
  }
491
+ // TODO: Calculate the votes
484
492
  async pendingTransaction() {
485
493
  const res = await this.backend.getPendingTransactions({ msafeAddress: this.address });
486
494
  if (!res.pending) {
@@ -498,12 +506,15 @@ var MSafeAccount = class _MSafeAccount {
498
506
  sequenceNumber: pendingTx.sequenceNumber,
499
507
  payload: pendingTx.payload,
500
508
  votes: pendingTx.votes,
509
+ approvalWeight: this.calculateWeightFromVotes(pendingTx.votes),
501
510
  msafeAddress: pendingTx.msafeAddress,
502
511
  rejectDigest: rejectPending?.digest ?? "",
503
512
  rejectPayload: rejectPending?.payload ?? "",
504
- rejectVotes: rejectPending?.votes ?? []
513
+ rejectVotes: rejectPending?.votes ?? [],
514
+ rejectWeight: this.calculateWeightFromVotes(rejectPending?.votes ?? [])
505
515
  };
506
516
  }
517
+ // TODO: Calculate the votes.
507
518
  async historyTransaction(pagination) {
508
519
  return this.backend.getHistoryTransactions({
509
520
  msafeAddress: this.address,
@@ -622,33 +633,41 @@ var MSafeAccount = class _MSafeAccount {
622
633
  dryRunResult
623
634
  };
624
635
  }
625
- async executePendingTx(pending) {
626
- let gotSigs;
627
- let payload;
628
- if (pending.votes.length >= this.info.threshold) {
629
- gotSigs = new Map(pending.votes.map((vote) => [vote.userAddress, vote.signature]));
630
- payload = pending.payload;
631
- } else if (pending.rejectVotes && pending.rejectPayload && pending.rejectVotes?.length >= this.info.threshold) {
632
- gotSigs = new Map(pending.rejectVotes.map((vote) => [vote.userAddress, vote.signature]));
633
- payload = pending.rejectPayload;
634
- } else {
635
- throw new Error("Not enough signatures");
636
+ async executePendingTx(pending, isRejectTx = false) {
637
+ const votes = isRejectTx ? pending.rejectVotes : pending.votes;
638
+ const payload = isRejectTx ? pending.rejectPayload : pending.payload;
639
+ if (this.calculateWeightFromVotes(votes) < this.info.threshold) {
640
+ throw new Error("Not enough signature");
636
641
  }
637
- const sigs = [];
642
+ const sortedSigs = [];
643
+ const gotSigs = new Map(votes.map((vote) => [vote.userAddress, vote.signature]));
638
644
  for (let i = 0; i < this.info.owners.length; i++) {
639
645
  const owner = this.info.owners[i];
640
646
  const signature = gotSigs.get(owner.address);
641
647
  if (signature) {
642
- sigs.push(signature);
648
+ sortedSigs.push(signature);
643
649
  }
644
650
  }
645
- const multiSignature = this.multiSig.combinePartialSignatures(sigs);
651
+ const multiSignature = this.multiSig.combinePartialSignatures(sortedSigs);
646
652
  return this.suiClient.executeTransactionBlock({
647
653
  transactionBlock: HexToUint8Array(payload),
648
654
  signature: multiSignature,
649
655
  options: { showEffects: true }
650
656
  });
651
657
  }
658
+ calculateWeightFromVotes(votes) {
659
+ return this.calculateWeight(votes.map((vote) => vote.userAddress));
660
+ }
661
+ calculateWeight(addressList) {
662
+ let gotWeight = 0;
663
+ for (let i = 0; i < addressList.length; i++) {
664
+ const found = this.info.owners.find((owner) => isSameAddress(owner.address, addressList[i]));
665
+ if (found) {
666
+ gotWeight += found.weight;
667
+ }
668
+ }
669
+ return gotWeight;
670
+ }
652
671
  get address() {
653
672
  return this.multiSig.address;
654
673
  }
@@ -750,16 +769,13 @@ var BackendImpl = class _BackendImpl {
750
769
  }
751
770
  _token;
752
771
  async authSign(input) {
753
- const res = await axios.post(`${this.apiURL}/auth/login`, input);
754
- if (res.status !== 200 && res.status !== 201) {
755
- throw new Error(`invalid authSign return: ${res}`);
756
- }
772
+ const res = await this.post(`/auth/login`, input);
757
773
  this._token = res.data.accessToken;
758
774
  return this._token;
759
775
  }
760
776
  async verifyToken(jwt) {
761
777
  try {
762
- const res = await axios.get(`${this.apiURL}/auth`, { headers: this.headers(jwt) });
778
+ const res = await this.get(`/auth`, { headers: this.headers(jwt) });
763
779
  return res.status === 200;
764
780
  } catch (_) {
765
781
  return false;
@@ -775,13 +791,10 @@ var BackendImpl = class _BackendImpl {
775
791
  const query = {
776
792
  userAddressList: addresses
777
793
  };
778
- const res = await axios.get(`${this.apiURL}/user/public-keys`, {
794
+ const res = await this.get(`/user/public-keys`, {
779
795
  params: query,
780
796
  headers: this.headers()
781
797
  });
782
- if (res.status !== 200 && res.status !== 201) {
783
- throw new Error(`invalid getPublicKeyBatch return: ${res}`);
784
- }
785
798
  return res.data?.map(
786
799
  (publicKeyWithSchema) => publicKeyWithSchema ? PublicKeySerde3.de(publicKeyWithSchema) : void 0
787
800
  );
@@ -790,22 +803,16 @@ var BackendImpl = class _BackendImpl {
790
803
  const q = {
791
804
  msafeAddress
792
805
  };
793
- const res = await axios.get(`${this.apiURL}/msafe`, {
806
+ const res = await this.get(`/msafe`, {
794
807
  params: q,
795
808
  headers: this.headers()
796
809
  });
797
- if (res.status !== 200 && res.status !== 201) {
798
- throw new Error(`invalid getPublicKeyBatch return: ${res}`);
799
- }
800
810
  return _BackendImpl.toMSafeConfig(res.data);
801
811
  }
802
812
  async getUserInfo() {
803
- const userRes = await axios.get(`${this.apiURL}/user`, {
813
+ const userRes = await this.get(`/user`, {
804
814
  headers: this.headers()
805
815
  });
806
- if (userRes.status !== 200 && userRes.status !== 201) {
807
- throw new Error(`invalid getPublicKeyBatch return: ${userRes}`);
808
- }
809
816
  return userRes.data;
810
817
  }
811
818
  async getOwnedMSafeByStatus(input) {
@@ -816,13 +823,10 @@ var BackendImpl = class _BackendImpl {
816
823
  limit: input.pagination.limit.toString()
817
824
  } : {}
818
825
  };
819
- const res = await axios.get(`${this.apiURL}/msafe/owned`, {
826
+ const res = await this.get(`/msafe/owned`, {
820
827
  params: q,
821
828
  headers: this.headers()
822
829
  });
823
- if (res.status !== 200 && res.status !== 201) {
824
- throw new Error(`invalid getOwnedMSafeByStatus return: ${res}`);
825
- }
826
830
  return {
827
831
  data: res.data.data.map(_BackendImpl.toMSafeConfig),
828
832
  meta: res.data.meta
@@ -830,78 +834,54 @@ var BackendImpl = class _BackendImpl {
830
834
  }
831
835
  async updateMSafeStatus(input) {
832
836
  const p = input;
833
- const res = await axios.post(`${this.apiURL}/msafe/status`, p, { headers: this.headers() });
834
- if (res.status !== 200 && res.status !== 201) {
835
- throw new Error(`Invalid updateMSafeStatus return: ${res}`);
836
- }
837
+ await this.post(`/msafe/status`, p, { headers: this.headers() });
837
838
  }
838
839
  async getPendingTransactions(input) {
839
- const res = await axios.get(`${this.apiURL}/transaction/pending`, {
840
+ const res = await this.get(`/transaction/pending`, {
840
841
  params: input,
841
842
  headers: this.headers()
842
843
  });
843
- if (res.status !== 200 && res.status !== 201) {
844
- throw new Error(`invalid getPublicKeyBatch return: ${res}`);
845
- }
846
844
  return res.data;
847
845
  }
848
846
  async getHistoryTransactions(input) {
849
- const res = await axios.get(`${this.apiURL}/transaction/history`, {
847
+ const res = await this.get(`/transaction/history`, {
850
848
  params: input,
851
849
  headers: this.headers()
852
850
  });
853
- if (res.status !== 200 && res.status !== 201) {
854
- throw new Error(`invalid getCurrentSequenceNumber return: ${res}`);
855
- }
856
851
  return res.data;
857
852
  }
858
853
  async getFutureIntentions(input) {
859
- const res = await axios.get(`${this.apiURL}/transaction/intention`, {
854
+ const res = await this.get(`/transaction/intention`, {
860
855
  params: input,
861
856
  headers: this.headers()
862
857
  });
863
- if (res.status !== 200 && res.status !== 201) {
864
- throw new Error(`invalid getCurrentSequenceNumber return: ${res}`);
865
- }
866
858
  return res.data;
867
859
  }
868
860
  async getCurrentSequenceNumber(address) {
869
- const res = await axios.get(`${this.apiURL}/transaction/sn/current`, {
861
+ const res = await this.get(`/transaction/sn/current`, {
870
862
  params: {
871
863
  msafeAddress: address
872
864
  },
873
865
  headers: this.headers()
874
866
  });
875
- if (res.status !== 200 && res.status !== 201) {
876
- throw new Error(`invalid getCurrentSequenceNumber return: ${res}`);
877
- }
878
867
  return res.data;
879
868
  }
880
869
  async getNextSequenceNumber(address) {
881
- const res = await axios.get(`${this.apiURL}/transaction/sn/next`, {
870
+ const res = await this.get(`/transaction/sn/next`, {
882
871
  params: {
883
872
  msafeAddress: address
884
873
  },
885
874
  headers: this.headers()
886
875
  });
887
- if (res.status !== 200 && res.status !== 201) {
888
- throw new Error(`invalid getNextSequenceNumber return: ${res}`);
889
- }
890
876
  return res.data;
891
877
  }
892
878
  async createMSafeAccount(input) {
893
- const res = await axios.post(`${this.apiURL}/msafe/create`, input, {
879
+ await this.post(`/msafe/create`, input, {
894
880
  headers: this.headers()
895
881
  });
896
- if (res.status !== 200 && res.status !== 201) {
897
- throw new Error(`invalid createMSafeAccount return: ${res}`);
898
- }
899
882
  }
900
883
  async proposeIntention(input) {
901
- const res = await axios.post(`${this.apiURL}/transaction/intention`, input, { headers: this.headers() });
902
- if (res.status !== 200 && res.status !== 201) {
903
- throw new Error(`invalid proposeIntention return: ${res}`);
904
- }
884
+ await this.post(`/transaction/intention`, input, { headers: this.headers() });
905
885
  }
906
886
  // TODO later
907
887
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
@@ -909,52 +889,30 @@ var BackendImpl = class _BackendImpl {
909
889
  return void 0;
910
890
  }
911
891
  async rejectCurrentTx(input) {
912
- const res = await axios.post(`${this.apiURL}/transaction/pending/reject`, input, {
892
+ await this.post(`/transaction/pending/reject`, input, {
913
893
  headers: this.headers()
914
894
  });
915
- if (res.status !== 200 && res.status !== 201) {
916
- throw new Error(`invalid voteForTransaction return: ${res}`);
917
- }
918
895
  }
919
896
  async voteForTransaction(input) {
920
- const res = await axios.post(`${this.apiURL}/transaction/pending/vote`, input, {
897
+ await this.post(`/transaction/pending/vote`, input, {
921
898
  headers: this.headers()
922
899
  });
923
- if (res.status !== 200 && res.status !== 201) {
924
- throw new Error(`invalid voteForTransaction return: ${res}`);
925
- }
926
900
  }
927
901
  async buildNextIntentionAndAddToPending(input) {
928
- const res = await axios.post(`${this.apiURL}/transaction/pending/build`, input, { headers: this.headers() });
929
- if (res.status !== 200 && res.status !== 201) {
930
- throw new Error(`invalid buildNextIntentionAndAddToPending return: ${res}`);
931
- }
902
+ await this.post(`/transaction/pending/build`, input, { headers: this.headers() });
932
903
  }
933
904
  async skipNextFailedIntention(input) {
934
- const res = await axios.post(`${this.apiURL}/transaction/pending/skip`, input, { headers: this.headers() });
935
- if (res.status !== 200 && res.status !== 201) {
936
- throw new Error(`invalid skipNextFailedIntention return: ${res}`);
937
- }
905
+ await this.post(`/transaction/pending/skip`, input, { headers: this.headers() });
938
906
  }
939
907
  async getAddressBookEntries(pagination) {
940
- const res = await axios.get(`${this.apiURL}/address-book`, {
908
+ const res = await this.get(`/address-book`, {
941
909
  headers: this.headers(),
942
910
  params: pagination
943
911
  });
944
- if (res.status !== 200) {
945
- throw new Error(`Invalid address-book return: ${res}`);
946
- }
947
912
  return res.data;
948
913
  }
949
914
  async updateAddressBook(input) {
950
- const res = await axios.post(`${this.apiURL}/address-book`, input, { headers: this.headers() });
951
- if (res.status !== 200 && res.status !== 201) {
952
- throw new Error(`invalid updateAddressBook return: ${res}`);
953
- }
954
- }
955
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
956
- async processExecutedTransaction(_digest) {
957
- return void 0;
915
+ await this.post(`/address-book`, input, { headers: this.headers() });
958
916
  }
959
917
  headers(token) {
960
918
  return { Authorization: `Bearer ${token || this._token}` };
@@ -972,6 +930,57 @@ var BackendImpl = class _BackendImpl {
972
930
  }))
973
931
  };
974
932
  }
933
+ async get(url, config) {
934
+ const fullUrl = this.getFullUrl(url);
935
+ try {
936
+ return await axios.get(fullUrl, config);
937
+ } catch (e) {
938
+ throw BackendError.fromError(e) ?? e;
939
+ }
940
+ }
941
+ async post(url, data, config) {
942
+ const fullUrl = this.getFullUrl(url);
943
+ try {
944
+ return await axios.post(fullUrl, data, config);
945
+ } catch (e) {
946
+ throw BackendError.fromError(e) ?? e;
947
+ }
948
+ }
949
+ getFullUrl(url) {
950
+ return url.startsWith(this.apiURL) ? url : `${this.apiURL}${addPrefix(url, "/")}`;
951
+ }
952
+ };
953
+ var BackendError = class _BackendError extends Error {
954
+ constructor(e) {
955
+ super();
956
+ this.e = e;
957
+ Error.captureStackTrace(this, this.constructor);
958
+ }
959
+ name;
960
+ static fromError(e) {
961
+ if (axios.isAxiosError(e) && e?.response?.data && "message" in e.response.data) {
962
+ return new _BackendError(e);
963
+ }
964
+ return void 0;
965
+ }
966
+ get status() {
967
+ return this.e.response?.status ?? void 0;
968
+ }
969
+ get message() {
970
+ return `Request to ${this.endpoint} failed: ${this.status} ${this.respMessage() ?? "Unknown resp"}`;
971
+ }
972
+ respMessage() {
973
+ if (!this.e.response?.data) {
974
+ return void 0;
975
+ }
976
+ return (this.e.response?.data).message ?? void 0;
977
+ }
978
+ get endpoint() {
979
+ return this.e.config?.url ?? "";
980
+ }
981
+ toString() {
982
+ return this.message;
983
+ }
975
984
  };
976
985
 
977
986
  // src/globals/const.ts
@@ -1186,6 +1195,7 @@ export {
1186
1195
  SignatureVerifier,
1187
1196
  TESTNET_RPC_URL,
1188
1197
  Uint8ArrayToHex,
1198
+ addPrefix,
1189
1199
  getAllCoins,
1190
1200
  getMSafeConfig,
1191
1201
  getPublicKeyFromChain,