@msafe/sui3-sdk 0.0.12 → 0.0.13
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 +681 -698
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +20 -13
- package/dist/index.d.ts +20 -13
- package/dist/index.js +687 -708
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/src/backend/BackendImpl.ts +4 -25
- package/src/backend/interface.ts +2 -11
- package/src/core/MSafeAccount.ts +11 -16
- package/src/types/msafe.ts +12 -0
package/dist/index.cjs
CHANGED
|
@@ -602,811 +602,794 @@ var AddressBookSDK = class {
|
|
|
602
602
|
var import_sui3_utils2 = require("@msafe/sui3-utils");
|
|
603
603
|
var import_utils5 = require("@mysten/sui.js/utils");
|
|
604
604
|
|
|
605
|
-
// src/
|
|
606
|
-
var
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
return MSafeEnv3;
|
|
613
|
-
})(MSafeEnv || {});
|
|
614
|
-
var UNIT_DATABASE_CONFIG = {
|
|
615
|
-
type: "sqlite",
|
|
616
|
-
database: ":memory:",
|
|
617
|
-
logging: false
|
|
618
|
-
};
|
|
619
|
-
var LOCAL_DATABASE_CONFIG = {
|
|
620
|
-
type: "mysql",
|
|
621
|
-
host: "127.0.0.1",
|
|
622
|
-
port: 3306,
|
|
623
|
-
username: "msafe",
|
|
624
|
-
password: "msafe",
|
|
625
|
-
database: "msafe_sui_local",
|
|
626
|
-
logging: false
|
|
627
|
-
};
|
|
628
|
-
var DEV_DATABASE_CONFIG = {
|
|
629
|
-
type: "mysql",
|
|
630
|
-
host: "msafe-dev-database.cluster-caos3ssocrx6.us-west-1.rds.amazonaws.com",
|
|
631
|
-
port: 3306,
|
|
632
|
-
username: "msafe",
|
|
633
|
-
password: "Momentum.Safe2022",
|
|
634
|
-
database: "msafe_sui_dev",
|
|
635
|
-
logging: false
|
|
636
|
-
};
|
|
637
|
-
var MSAFE_APPLICATION = "msafe";
|
|
638
|
-
var TESTNET_RPC_URL = "https://sui-testnet.blockvision.org/v1/2Sgk89ivT64MnKdcGzjmyjY2ndD";
|
|
639
|
-
var MAINNET_RPC_URL = "https://sui-mainnet.blockvision.org/v1/2Sgk7NPvqkd7mESYkxF01yX15l7";
|
|
640
|
-
var LOCAL_API_URL = "http://127.0.0.1:3000";
|
|
641
|
-
var LOCAL_SYNCING_URL = "http://127.0.0.1:3001";
|
|
642
|
-
var DEV_API_URL = "http://13.56.226.148";
|
|
643
|
-
var DEV_SYNCING_URL = "http://52.53.228.20";
|
|
644
|
-
var ENV_CONFIGS = /* @__PURE__ */ new Map([
|
|
645
|
-
[
|
|
646
|
-
"unit" /* unit */,
|
|
647
|
-
{
|
|
648
|
-
suiClient: {
|
|
649
|
-
url: TESTNET_RPC_URL
|
|
650
|
-
},
|
|
651
|
-
backend: LOCAL_DATABASE_CONFIG,
|
|
652
|
-
apiURL: LOCAL_API_URL,
|
|
653
|
-
syncingURL: LOCAL_SYNCING_URL
|
|
654
|
-
}
|
|
655
|
-
],
|
|
656
|
-
[
|
|
657
|
-
"local" /* local */,
|
|
658
|
-
{
|
|
659
|
-
suiClient: {
|
|
660
|
-
url: TESTNET_RPC_URL
|
|
661
|
-
},
|
|
662
|
-
backend: LOCAL_DATABASE_CONFIG,
|
|
663
|
-
apiURL: LOCAL_API_URL,
|
|
664
|
-
syncingURL: LOCAL_SYNCING_URL
|
|
665
|
-
}
|
|
666
|
-
],
|
|
667
|
-
[
|
|
668
|
-
"dev" /* dev */,
|
|
669
|
-
{
|
|
670
|
-
suiClient: {
|
|
671
|
-
url: TESTNET_RPC_URL
|
|
672
|
-
},
|
|
673
|
-
backend: DEV_DATABASE_CONFIG,
|
|
674
|
-
apiURL: DEV_API_URL,
|
|
675
|
-
syncingURL: DEV_SYNCING_URL
|
|
676
|
-
}
|
|
677
|
-
]
|
|
678
|
-
]);
|
|
679
|
-
function getMSafeConfig(env, options) {
|
|
680
|
-
const config = ENV_CONFIGS.get(env);
|
|
681
|
-
if (!config) {
|
|
682
|
-
throw new Error("Unknown environment");
|
|
683
|
-
}
|
|
684
|
-
if (options?.suiClient?.url) {
|
|
685
|
-
config.suiClient.url = options.suiClient.url;
|
|
605
|
+
// src/utils/iter/iterator.ts
|
|
606
|
+
var REQUEST_PAGE_SIZE = 25;
|
|
607
|
+
async function getAllFromIterator(it) {
|
|
608
|
+
const res = [];
|
|
609
|
+
while (await it.hasNext()) {
|
|
610
|
+
const val = await it.next();
|
|
611
|
+
res.push(val);
|
|
686
612
|
}
|
|
687
|
-
if (
|
|
688
|
-
|
|
613
|
+
if (res && Array.isArray(res[0])) {
|
|
614
|
+
return res.flat(1);
|
|
689
615
|
}
|
|
690
|
-
return
|
|
616
|
+
return res;
|
|
691
617
|
}
|
|
692
|
-
var
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
// src/backend/BackendImpl.ts
|
|
698
|
-
var import_axios = __toESM(require("axios"), 1);
|
|
699
|
-
var BackendImpl = class {
|
|
700
|
-
constructor(apiURL) {
|
|
701
|
-
this.apiURL = apiURL;
|
|
618
|
+
var PagedIterator = class {
|
|
619
|
+
constructor(requester) {
|
|
620
|
+
this.requester = requester;
|
|
621
|
+
this.curPage = void 0;
|
|
622
|
+
this.init = true;
|
|
702
623
|
}
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
if (
|
|
707
|
-
|
|
624
|
+
curPage;
|
|
625
|
+
init;
|
|
626
|
+
async hasNext() {
|
|
627
|
+
if (this.init) {
|
|
628
|
+
if (!this.curPage) {
|
|
629
|
+
this.curPage = await this.requester.doNextRequest();
|
|
630
|
+
}
|
|
631
|
+
return !!this.curPage.data?.length || this.curPage.hasNext;
|
|
708
632
|
}
|
|
709
|
-
this.
|
|
710
|
-
|
|
711
|
-
}
|
|
712
|
-
async verifyToken(jwt) {
|
|
713
|
-
try {
|
|
714
|
-
const res = await import_axios.default.get(`${this.apiURL}/auth`, { headers: this.headers(jwt) });
|
|
715
|
-
return res.status === 200;
|
|
716
|
-
} catch (_) {
|
|
717
|
-
return false;
|
|
633
|
+
if (!this.curPage) {
|
|
634
|
+
throw new Error("invalid implementation of iterator");
|
|
718
635
|
}
|
|
636
|
+
return this.curPage.hasNext;
|
|
719
637
|
}
|
|
720
|
-
|
|
721
|
-
this.
|
|
638
|
+
async next() {
|
|
639
|
+
if (this.init) {
|
|
640
|
+
this.init = false;
|
|
641
|
+
if (!this.curPage) {
|
|
642
|
+
this.curPage = await this.requester.doNextRequest();
|
|
643
|
+
}
|
|
644
|
+
return this.curPage.data;
|
|
645
|
+
}
|
|
646
|
+
this.curPage = await this.requester.doNextRequest();
|
|
647
|
+
return this.curPage.data;
|
|
722
648
|
}
|
|
723
|
-
|
|
724
|
-
|
|
649
|
+
};
|
|
650
|
+
var EntryIterator = class {
|
|
651
|
+
constructor(requester) {
|
|
652
|
+
this.requester = requester;
|
|
653
|
+
this.pager = new PagedIterator(requester);
|
|
654
|
+
this.curData = [];
|
|
655
|
+
this.cursor = 0;
|
|
725
656
|
}
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
}
|
|
733
|
-
);
|
|
734
|
-
if (res.status !== 200 && res.status !== 201) {
|
|
735
|
-
throw new Error(`invalid getPublicKeyBatch return: ${res}`);
|
|
657
|
+
cursor;
|
|
658
|
+
pager;
|
|
659
|
+
curData;
|
|
660
|
+
async hasNext() {
|
|
661
|
+
if (this.cursor < this.curData.length - 1) {
|
|
662
|
+
return true;
|
|
736
663
|
}
|
|
737
|
-
return
|
|
738
|
-
(publicKeyWithSchema) => publicKeyWithSchema ? PublicKeySerde.de({ ...publicKeyWithSchema }) : void 0
|
|
739
|
-
);
|
|
664
|
+
return this.pager.hasNext();
|
|
740
665
|
}
|
|
741
|
-
async
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
{
|
|
745
|
-
|
|
666
|
+
async next() {
|
|
667
|
+
this.cursor += 1;
|
|
668
|
+
while (this.cursor >= this.curData.length) {
|
|
669
|
+
if (!await this.pager.hasNext()) {
|
|
670
|
+
throw new Error("not more data");
|
|
671
|
+
} else {
|
|
672
|
+
this.curData = await this.pager.next();
|
|
673
|
+
this.cursor = 0;
|
|
746
674
|
}
|
|
747
|
-
);
|
|
748
|
-
if (res.status !== 200 && res.status !== 201) {
|
|
749
|
-
throw new Error(`invalid getPublicKeyBatch return: ${res}`);
|
|
750
675
|
}
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
676
|
+
return this.curData[this.cursor];
|
|
677
|
+
}
|
|
678
|
+
};
|
|
679
|
+
|
|
680
|
+
// src/utils/iter/object.ts
|
|
681
|
+
async function getAllOwnedObjects(provider, owner, options) {
|
|
682
|
+
const iter = new OwnedObjectIterator(provider, owner, options);
|
|
683
|
+
return await getAllFromIterator(iter);
|
|
684
|
+
}
|
|
685
|
+
var OwnedObjectIterator = class extends EntryIterator {
|
|
686
|
+
constructor(provider, owner, options) {
|
|
687
|
+
super(new OwnedObjectRequester(provider, owner, options));
|
|
688
|
+
this.provider = provider;
|
|
689
|
+
this.owner = owner;
|
|
690
|
+
this.options = options;
|
|
691
|
+
}
|
|
692
|
+
};
|
|
693
|
+
var OwnedObjectRequester = class {
|
|
694
|
+
constructor(provider, owner, options) {
|
|
695
|
+
this.provider = provider;
|
|
696
|
+
this.owner = owner;
|
|
697
|
+
this.options = options;
|
|
698
|
+
this.nextCursor = null;
|
|
699
|
+
this.filter = options?.filter;
|
|
700
|
+
this.pageSize = options?.pageSize || REQUEST_PAGE_SIZE;
|
|
701
|
+
this.objectOptions = options?.objectOptions || {
|
|
702
|
+
showType: true,
|
|
703
|
+
showContent: true
|
|
765
704
|
};
|
|
766
705
|
}
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
706
|
+
nextCursor;
|
|
707
|
+
filter;
|
|
708
|
+
pageSize;
|
|
709
|
+
objectOptions;
|
|
710
|
+
async doNextRequest() {
|
|
711
|
+
const res = await this.provider.getOwnedObjects({
|
|
712
|
+
owner: this.owner,
|
|
713
|
+
options: this.objectOptions,
|
|
714
|
+
cursor: this.nextCursor,
|
|
715
|
+
limit: this.pageSize
|
|
770
716
|
});
|
|
771
|
-
|
|
772
|
-
|
|
717
|
+
this.nextCursor = res.nextCursor;
|
|
718
|
+
let filtered;
|
|
719
|
+
if (this.filter) {
|
|
720
|
+
const { filter } = this;
|
|
721
|
+
filtered = res.data.filter((obj) => filter?.(obj));
|
|
722
|
+
} else {
|
|
723
|
+
filtered = res.data;
|
|
773
724
|
}
|
|
774
725
|
return {
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
schema: res.data.schema,
|
|
778
|
-
creationNonce: res.data.creationNonce,
|
|
779
|
-
ownedMSafe: res.data.ownedMSafe.map(
|
|
780
|
-
(msafe) => ({
|
|
781
|
-
address: msafe.address,
|
|
782
|
-
ownersWithWeightPK: msafe.ownersWithWeightPKEncoded.map(
|
|
783
|
-
(owner) => ({
|
|
784
|
-
publicKey: PublicKeySerde.de({ publicKey: owner.publicKeyEncoded, scheme: owner.schema }),
|
|
785
|
-
address: owner.address,
|
|
786
|
-
weight: owner.weight
|
|
787
|
-
})
|
|
788
|
-
),
|
|
789
|
-
threshold: msafe.threshold,
|
|
790
|
-
name: msafe.name,
|
|
791
|
-
description: msafe.description,
|
|
792
|
-
creationNonce: msafe.creationNonce
|
|
793
|
-
})
|
|
794
|
-
)
|
|
726
|
+
data: filtered.map((r) => r.data).filter((data) => data),
|
|
727
|
+
hasNext: res.hasNextPage
|
|
795
728
|
};
|
|
796
729
|
}
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
730
|
+
};
|
|
731
|
+
|
|
732
|
+
// src/core/MSafeAccount.ts
|
|
733
|
+
var MSafeAccount = class {
|
|
734
|
+
constructor(globals, info) {
|
|
735
|
+
this.globals = globals;
|
|
736
|
+
this.info = info;
|
|
737
|
+
this.multisigManager = new import_sui3_utils2.MultisigAccountManager({
|
|
738
|
+
threshold: info.threshold,
|
|
739
|
+
ownersWithWeight: info.ownersWithWeightPK,
|
|
740
|
+
creationNonce: info.creationNonce
|
|
800
741
|
});
|
|
801
|
-
|
|
802
|
-
throw new Error(`invalid getPublicKeyBatch return: ${res}`);
|
|
803
|
-
}
|
|
804
|
-
return res.data;
|
|
742
|
+
this.coinHelper = new CoinHelper(this.suiClient);
|
|
805
743
|
}
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
params: {
|
|
811
|
-
page: paginationOption?.page,
|
|
812
|
-
limit: paginationOption?.limit
|
|
813
|
-
},
|
|
814
|
-
headers: this.headers()
|
|
815
|
-
}
|
|
816
|
-
);
|
|
817
|
-
if (res.status !== 200 && res.status !== 201) {
|
|
818
|
-
throw new Error(`invalid getCurrentSequenceNumber return: ${res}`);
|
|
819
|
-
}
|
|
820
|
-
return res.data;
|
|
744
|
+
multisigManager;
|
|
745
|
+
coinHelper;
|
|
746
|
+
static async new(globals, address) {
|
|
747
|
+
return globals.backend.getMSafeAccountInfo(address);
|
|
821
748
|
}
|
|
822
|
-
async
|
|
823
|
-
const
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
749
|
+
async ownedCoins() {
|
|
750
|
+
const balances = await this.suiClient.getAllBalances({ owner: this.address });
|
|
751
|
+
return Promise.all(
|
|
752
|
+
balances.map(async (balance) => {
|
|
753
|
+
const meta = await this.coinHelper.getCoinMeta(balance.coinType);
|
|
754
|
+
const unlockedBalance = balance.lockedBalance.number ? BigInt(balance.totalBalance) - BigInt(balance.lockedBalance.number) : BigInt(balance.totalBalance);
|
|
755
|
+
return {
|
|
756
|
+
type: (0, import_utils5.normalizeStructTag)(balance.coinType),
|
|
757
|
+
balance: BigInt(unlockedBalance),
|
|
758
|
+
metadata: meta
|
|
759
|
+
};
|
|
760
|
+
})
|
|
761
|
+
);
|
|
834
762
|
}
|
|
835
|
-
async
|
|
836
|
-
const
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
}
|
|
842
|
-
return res.data;
|
|
763
|
+
async ownedObjects(options) {
|
|
764
|
+
const filterCoinObjectOptions = {
|
|
765
|
+
filter: (objRes) => !objRes?.data?.type?.startsWith("0x2::coin::Coin"),
|
|
766
|
+
...options
|
|
767
|
+
};
|
|
768
|
+
return getAllOwnedObjects(this.suiClient, this.address, filterCoinObjectOptions);
|
|
843
769
|
}
|
|
844
|
-
async
|
|
845
|
-
const
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
if (res.status !== 200 && res.status !== 201) {
|
|
849
|
-
throw new Error(`invalid getNextSequenceNumber return: ${res}`);
|
|
770
|
+
async pendingTransaction() {
|
|
771
|
+
const pendings = await this.backend.getPendingTransactions(this.address);
|
|
772
|
+
if (pendings.length > 2) {
|
|
773
|
+
throw new Error(`invalid backend getPendingTransactions resp, length should not > 2: ${pendings}`);
|
|
850
774
|
}
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
async createMSafeAccount(input) {
|
|
854
|
-
const res = await import_axios.default.post(`${this.apiURL}/account`, input, {
|
|
855
|
-
headers: this.headers()
|
|
856
|
-
});
|
|
857
|
-
if (res.status !== 200 && res.status !== 201) {
|
|
858
|
-
throw new Error(`invalid createMSafeAccount return: ${res}`);
|
|
775
|
+
if (pendings.length === 0) {
|
|
776
|
+
return void 0;
|
|
859
777
|
}
|
|
778
|
+
const pendingTx = pendings.find((tx) => !tx.isRejectTx);
|
|
779
|
+
const rejectPending = pendings.find((tx) => tx.isRejectTx);
|
|
780
|
+
return {
|
|
781
|
+
...pendingTx,
|
|
782
|
+
rejectDigest: rejectPending?.digest ?? "",
|
|
783
|
+
rejectPayload: rejectPending?.payload ?? "",
|
|
784
|
+
rejectVotes: rejectPending?.votes ?? []
|
|
785
|
+
};
|
|
860
786
|
}
|
|
861
|
-
async
|
|
862
|
-
|
|
863
|
-
const res = await import_axios.default.post(
|
|
864
|
-
`${this.apiURL}/transaction/intention`,
|
|
865
|
-
{
|
|
866
|
-
intention: input.intention,
|
|
867
|
-
sequenceNumber: input.sequenceNumber,
|
|
868
|
-
address: input.msafeAddress,
|
|
869
|
-
signature: input.signature,
|
|
870
|
-
application: input.application,
|
|
871
|
-
txType: input.txType,
|
|
872
|
-
txSubType: input.txSubType
|
|
873
|
-
},
|
|
874
|
-
{ headers: this.headers() }
|
|
875
|
-
);
|
|
876
|
-
if (res.status !== 200 && res.status !== 201) {
|
|
877
|
-
throw new Error(`invalid proposeIntention return: ${res}`);
|
|
878
|
-
}
|
|
879
|
-
} catch (e) {
|
|
880
|
-
console.log(e);
|
|
881
|
-
}
|
|
787
|
+
async historyTransaction(paginationOption) {
|
|
788
|
+
return this.backend.getHistoryTransactions(this.address, paginationOption);
|
|
882
789
|
}
|
|
883
|
-
|
|
884
|
-
|
|
790
|
+
async futureIntentions(paginationOption) {
|
|
791
|
+
const paginatedIntentions = await this.backend.getFutureIntentions(this.address, paginationOption);
|
|
792
|
+
return paginatedIntentions.data;
|
|
885
793
|
}
|
|
886
|
-
async
|
|
887
|
-
|
|
888
|
-
const res = await import_axios.default.post(
|
|
889
|
-
`${this.apiURL}/transaction/pending/reject`,
|
|
890
|
-
{
|
|
891
|
-
address: input.msafeAddress,
|
|
892
|
-
digest: input.digest,
|
|
893
|
-
signature: input.signature
|
|
894
|
-
},
|
|
895
|
-
{
|
|
896
|
-
headers: this.headers()
|
|
897
|
-
}
|
|
898
|
-
);
|
|
899
|
-
if (res.status !== 200 && res.status !== 201) {
|
|
900
|
-
throw new Error(`invalid voteForTransaction return: ${res}`);
|
|
901
|
-
}
|
|
902
|
-
} catch (e) {
|
|
903
|
-
console.log("e:", e);
|
|
904
|
-
}
|
|
794
|
+
async currentSequenceNumber() {
|
|
795
|
+
return this.backend.getCurrentSequenceNumber(this.address);
|
|
905
796
|
}
|
|
906
|
-
async
|
|
907
|
-
|
|
908
|
-
`${this.apiURL}/transaction/pending/vote`,
|
|
909
|
-
{
|
|
910
|
-
address: input.msafeAddress,
|
|
911
|
-
digest: input.txDigest,
|
|
912
|
-
signature: input.signature
|
|
913
|
-
},
|
|
914
|
-
{
|
|
915
|
-
headers: this.headers()
|
|
916
|
-
}
|
|
917
|
-
);
|
|
918
|
-
if (res.status !== 200 && res.status !== 201) {
|
|
919
|
-
throw new Error(`invalid voteForTransaction return: ${res}`);
|
|
920
|
-
}
|
|
797
|
+
async nextSequenceNumber() {
|
|
798
|
+
return this.backend.getNextSequenceNumber(this.address);
|
|
921
799
|
}
|
|
922
|
-
async
|
|
923
|
-
const
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
800
|
+
async proposeIntention(input) {
|
|
801
|
+
const message = MessageHelper.proposeIntentionMessage({
|
|
802
|
+
msafeAddress: this.address,
|
|
803
|
+
intention: input.intention,
|
|
804
|
+
sn: input.sequenceNumber
|
|
805
|
+
});
|
|
806
|
+
const signature = await this.wallet.signPersonalMessage({
|
|
807
|
+
messageStr: message
|
|
808
|
+
});
|
|
809
|
+
await this.backend.proposeIntention({
|
|
810
|
+
...input,
|
|
811
|
+
msafeAddress: this.address,
|
|
812
|
+
userAddress: await this.userAddress(),
|
|
813
|
+
signature: signature.signature
|
|
814
|
+
});
|
|
933
815
|
}
|
|
934
|
-
async
|
|
935
|
-
const
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
throw new Error(`invalid skipNextFailedIntention return: ${res}`);
|
|
944
|
-
}
|
|
816
|
+
async voteForTransaction(digest, payload) {
|
|
817
|
+
const payloadBytes = HexToUint8Array(payload);
|
|
818
|
+
const signature = await this.wallet.signTransactionBlock({ transactionBlock: payloadBytes });
|
|
819
|
+
return this.backend.voteForTransaction({
|
|
820
|
+
msafeAddress: this.address,
|
|
821
|
+
userAddress: await this.userAddress(),
|
|
822
|
+
txDigest: digest,
|
|
823
|
+
signature: signature.signature
|
|
824
|
+
});
|
|
945
825
|
}
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
826
|
+
// Shortcut for proposing a transaction to be a pending transaction, and add user vote to it.
|
|
827
|
+
// Requires the multi-sig to be empty in pending transaction.
|
|
828
|
+
async proposePendingTransaction(intention) {
|
|
829
|
+
const txb = await IntentionHelper.buildTxb({
|
|
830
|
+
suiClient: this.suiClient,
|
|
831
|
+
intention,
|
|
832
|
+
sender: this.address
|
|
833
|
+
});
|
|
834
|
+
const payload = await txb.build({ client: this.suiClient });
|
|
835
|
+
const digest = await txb.getDigest({ client: this.suiClient });
|
|
836
|
+
const signature = await this.wallet.signTransactionBlock({ transactionBlock: payload });
|
|
837
|
+
return this.backend.proposePendingTransaction({
|
|
838
|
+
msafeAddress: this.address,
|
|
839
|
+
userAddress: await this.userAddress(),
|
|
840
|
+
intention,
|
|
841
|
+
digest,
|
|
842
|
+
signature: signature.signature
|
|
950
843
|
});
|
|
951
|
-
if (res.status !== 200) {
|
|
952
|
-
throw new Error(`Invalid address-book return: ${res}`);
|
|
953
|
-
}
|
|
954
|
-
return res.data;
|
|
955
844
|
}
|
|
956
|
-
async
|
|
957
|
-
|
|
958
|
-
if (
|
|
959
|
-
|
|
845
|
+
async rejectCurrentTx(pending) {
|
|
846
|
+
let payloadToReject;
|
|
847
|
+
if (pending) {
|
|
848
|
+
if (pending.isRejectTx) {
|
|
849
|
+
throw new Error("Pending not reject transaction");
|
|
850
|
+
}
|
|
851
|
+
payloadToReject = pending.payload;
|
|
852
|
+
} else {
|
|
853
|
+
const pendingTx = await this.pendingTransaction();
|
|
854
|
+
if (!pendingTx || pendingTx.rejectDigest !== "") {
|
|
855
|
+
throw new Error("Already rejected");
|
|
856
|
+
}
|
|
857
|
+
payloadToReject = pendingTx.payload;
|
|
960
858
|
}
|
|
859
|
+
const rejectTxb = await IntentionHelper.buildRejectTransaction({
|
|
860
|
+
msafeAddress: this.address,
|
|
861
|
+
payloadToReject
|
|
862
|
+
});
|
|
863
|
+
const digest = await rejectTxb.getDigest({ client: this.suiClient });
|
|
864
|
+
const payload = await rejectTxb.build({ client: this.suiClient });
|
|
865
|
+
const signature = await this.wallet.signTransactionBlock({ transactionBlock: payload });
|
|
866
|
+
return this.backend.rejectCurrentTx({
|
|
867
|
+
msafeAddress: this.address,
|
|
868
|
+
userAddress: await this.userAddress(),
|
|
869
|
+
digest,
|
|
870
|
+
signature: signature.signature
|
|
871
|
+
});
|
|
961
872
|
}
|
|
962
|
-
async
|
|
873
|
+
async buildNextIntentionAndAddToPending() {
|
|
874
|
+
return this.backend.buildNextIntentionAndAddToPending({ msafeAddress: this.address });
|
|
963
875
|
}
|
|
964
|
-
|
|
965
|
-
return {
|
|
876
|
+
async skipNextFailedIntention() {
|
|
877
|
+
return this.backend.skipNextFailedIntention({ msafeAddress: this.address, userAddress: await this.userAddress() });
|
|
966
878
|
}
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
879
|
+
async simulateIntention(intention) {
|
|
880
|
+
const txb = await (0, import_sui3_utils2.buildIntentionTransaction)(this.suiClient, intention, this.address);
|
|
881
|
+
if (!txb.blockData.gasConfig.price) {
|
|
882
|
+
const refGas = await this.suiClient.getReferenceGasPrice();
|
|
883
|
+
txb.setGasPrice(refGas);
|
|
884
|
+
}
|
|
885
|
+
const payload = await txb.build({ client: this.suiClient });
|
|
886
|
+
const dryRunResult = await this.suiClient.dryRunTransactionBlock({ transactionBlock: payload });
|
|
887
|
+
const success = dryRunResult.effects.status.status === "success";
|
|
888
|
+
const errorMsg = dryRunResult.effects.status.error;
|
|
889
|
+
const gasPrice = BigInt(txb.blockData.gasConfig.price);
|
|
890
|
+
const { gasUsed } = dryRunResult.effects;
|
|
891
|
+
return {
|
|
892
|
+
success,
|
|
893
|
+
errorMsg,
|
|
894
|
+
gasPrice,
|
|
895
|
+
gasUsed,
|
|
896
|
+
dryRunResult
|
|
897
|
+
};
|
|
979
898
|
}
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
899
|
+
async executePendingTx(pending) {
|
|
900
|
+
let gotSigs;
|
|
901
|
+
let payload;
|
|
902
|
+
if (pending.votes.length >= this.info.threshold) {
|
|
903
|
+
gotSigs = new Map(pending.votes.map((vote) => [vote.userAddress, vote.signature]));
|
|
904
|
+
payload = pending.payload;
|
|
905
|
+
} else if (pending.rejectVotes && pending.rejectPayload && pending.rejectVotes?.length >= this.info.threshold) {
|
|
906
|
+
gotSigs = new Map(pending.rejectVotes.map((vote) => [vote.userAddress, vote.signature]));
|
|
907
|
+
payload = pending.rejectPayload;
|
|
908
|
+
} else {
|
|
909
|
+
throw new Error("Not enough signatures");
|
|
910
|
+
}
|
|
911
|
+
const sigs = [];
|
|
912
|
+
for (let i = 0; i < this.info.ownersWithWeightPK.length; i++) {
|
|
913
|
+
const owner = this.info.ownersWithWeightPK[i];
|
|
914
|
+
const signature = gotSigs.get(owner.publicKey.toSuiAddress());
|
|
915
|
+
if (signature) {
|
|
916
|
+
sigs.push(signature);
|
|
917
|
+
}
|
|
918
|
+
}
|
|
919
|
+
const multiSignature = this.multisigManager.combinePartialSignatures(sigs);
|
|
920
|
+
return this.suiClient.executeTransactionBlock({
|
|
921
|
+
transactionBlock: HexToUint8Array(payload),
|
|
922
|
+
signature: multiSignature,
|
|
923
|
+
options: { showEffects: true }
|
|
988
924
|
});
|
|
989
925
|
}
|
|
990
|
-
|
|
991
|
-
this.
|
|
926
|
+
get address() {
|
|
927
|
+
return this.info.address;
|
|
928
|
+
}
|
|
929
|
+
get backend() {
|
|
930
|
+
return this.globals.backend;
|
|
992
931
|
}
|
|
993
932
|
get wallet() {
|
|
994
|
-
|
|
995
|
-
throw new Error("wallet not connected");
|
|
996
|
-
}
|
|
997
|
-
return this._wallet;
|
|
933
|
+
return this.globals.wallet;
|
|
998
934
|
}
|
|
999
|
-
|
|
1000
|
-
this.
|
|
935
|
+
async userAddress() {
|
|
936
|
+
return this.globals.wallet.address();
|
|
937
|
+
}
|
|
938
|
+
get suiClient() {
|
|
939
|
+
return this.globals.suiClient;
|
|
1001
940
|
}
|
|
1002
941
|
};
|
|
1003
942
|
|
|
1004
|
-
// src/
|
|
1005
|
-
var
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
const val = await it.next();
|
|
1010
|
-
res.push(val);
|
|
1011
|
-
}
|
|
1012
|
-
if (res && Array.isArray(res[0])) {
|
|
1013
|
-
return res.flat(1);
|
|
1014
|
-
}
|
|
1015
|
-
return res;
|
|
1016
|
-
}
|
|
1017
|
-
var PagedIterator = class {
|
|
1018
|
-
constructor(requester) {
|
|
1019
|
-
this.requester = requester;
|
|
1020
|
-
this.curPage = void 0;
|
|
1021
|
-
this.init = true;
|
|
943
|
+
// src/core/PublicKeyHelper.ts
|
|
944
|
+
var PublicKeyHelper = class {
|
|
945
|
+
constructor(globals) {
|
|
946
|
+
this.globals = globals;
|
|
947
|
+
this.knownPublicKeys = /* @__PURE__ */ new Map();
|
|
1022
948
|
}
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
if (
|
|
1027
|
-
|
|
1028
|
-
this.curPage = await this.requester.doNextRequest();
|
|
1029
|
-
}
|
|
1030
|
-
return !!this.curPage.data?.length || this.curPage.hasNext;
|
|
949
|
+
knownPublicKeys;
|
|
950
|
+
async getPublicKey(address) {
|
|
951
|
+
const cached = this.knownPublicKeys.get(address);
|
|
952
|
+
if (cached) {
|
|
953
|
+
return cached;
|
|
1031
954
|
}
|
|
1032
|
-
|
|
1033
|
-
|
|
955
|
+
const pk = await this._getPublicKey(address);
|
|
956
|
+
if (pk) {
|
|
957
|
+
this.knownPublicKeys.set(address, pk);
|
|
1034
958
|
}
|
|
1035
|
-
return
|
|
959
|
+
return pk;
|
|
1036
960
|
}
|
|
1037
|
-
async
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
961
|
+
async getPublicKeyBatch(addresses) {
|
|
962
|
+
const results = new Array(addresses.length).fill(void 0);
|
|
963
|
+
for (let i = 0; i < addresses.length; i++) {
|
|
964
|
+
const address = addresses[i];
|
|
965
|
+
results[i] = this.knownPublicKeys.get(address);
|
|
966
|
+
}
|
|
967
|
+
const emptyIndexes = results.map((elem, index) => elem === void 0 ? index : -1).filter((index) => index !== -1);
|
|
968
|
+
const backendResult = await this.globals.backend.getPublicKeyBatch(emptyIndexes.map((index) => addresses[index]));
|
|
969
|
+
for (let i = 0; i < emptyIndexes.length; i++) {
|
|
970
|
+
const index = emptyIndexes[i];
|
|
971
|
+
results[index] = backendResult[i];
|
|
972
|
+
}
|
|
973
|
+
for (let i = 0; i < results.length; i++) {
|
|
974
|
+
if (results[i] === void 0) {
|
|
975
|
+
results[i] = await this.getPublicKeyFromChain(addresses[i]);
|
|
1042
976
|
}
|
|
1043
|
-
return this.curPage.data;
|
|
1044
977
|
}
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
}
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
this.requester = requester;
|
|
1052
|
-
this.pager = new PagedIterator(requester);
|
|
1053
|
-
this.curData = [];
|
|
1054
|
-
this.cursor = 0;
|
|
978
|
+
for (let i = 0; i < addresses.length; i++) {
|
|
979
|
+
if (results[i]) {
|
|
980
|
+
this.knownPublicKeys.set(addresses[i], results[i]);
|
|
981
|
+
}
|
|
982
|
+
}
|
|
983
|
+
return results;
|
|
1055
984
|
}
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
if (this.cursor < this.curData.length - 1) {
|
|
1061
|
-
return true;
|
|
985
|
+
async _getPublicKey(address) {
|
|
986
|
+
const pkBackend = await this.getPublicKeyFromBackend(address);
|
|
987
|
+
if (pkBackend) {
|
|
988
|
+
return pkBackend;
|
|
1062
989
|
}
|
|
1063
|
-
|
|
990
|
+
const pkChain = await this.getPublicKeyFromChain(address);
|
|
991
|
+
if (pkChain) {
|
|
992
|
+
return pkChain;
|
|
993
|
+
}
|
|
994
|
+
return void 0;
|
|
1064
995
|
}
|
|
1065
|
-
async
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
this.curData = await this.pager.next();
|
|
1072
|
-
this.cursor = 0;
|
|
1073
|
-
}
|
|
996
|
+
async getPublicKeyFromBackend(address) {
|
|
997
|
+
try {
|
|
998
|
+
const pk = await this.globals.backend.getPublicKey(address);
|
|
999
|
+
return pk;
|
|
1000
|
+
} catch (_) {
|
|
1001
|
+
return void 0;
|
|
1074
1002
|
}
|
|
1075
|
-
|
|
1003
|
+
}
|
|
1004
|
+
async getPublicKeyFromChain(address) {
|
|
1005
|
+
return getPublicKeyFromChain(this.globals.suiClient, address);
|
|
1076
1006
|
}
|
|
1077
1007
|
};
|
|
1078
1008
|
|
|
1079
|
-
// src/
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
var
|
|
1085
|
-
constructor(
|
|
1086
|
-
|
|
1087
|
-
this.provider = provider;
|
|
1088
|
-
this.owner = owner;
|
|
1089
|
-
this.options = options;
|
|
1009
|
+
// src/globals/MSafeGlobals.ts
|
|
1010
|
+
var import_client = require("@mysten/sui.js/client");
|
|
1011
|
+
|
|
1012
|
+
// src/backend/BackendImpl.ts
|
|
1013
|
+
var import_axios = __toESM(require("axios"), 1);
|
|
1014
|
+
var BackendImpl = class {
|
|
1015
|
+
constructor(apiURL) {
|
|
1016
|
+
this.apiURL = apiURL;
|
|
1090
1017
|
}
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
this.
|
|
1098
|
-
this.
|
|
1099
|
-
this.pageSize = options?.pageSize || REQUEST_PAGE_SIZE;
|
|
1100
|
-
this.objectOptions = options?.objectOptions || {
|
|
1101
|
-
showType: true,
|
|
1102
|
-
showContent: true
|
|
1103
|
-
};
|
|
1018
|
+
_token;
|
|
1019
|
+
async authSign(input) {
|
|
1020
|
+
const res = await import_axios.default.post(`${this.apiURL}/auth/login`, input);
|
|
1021
|
+
if (res.status !== 200 && res.status !== 201) {
|
|
1022
|
+
throw new Error(`invalid authSign return: ${res}`);
|
|
1023
|
+
}
|
|
1024
|
+
this._token = res.data.accessToken;
|
|
1025
|
+
return this._token;
|
|
1104
1026
|
}
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
owner: this.owner,
|
|
1112
|
-
options: this.objectOptions,
|
|
1113
|
-
cursor: this.nextCursor,
|
|
1114
|
-
limit: this.pageSize
|
|
1115
|
-
});
|
|
1116
|
-
this.nextCursor = res.nextCursor;
|
|
1117
|
-
let filtered;
|
|
1118
|
-
if (this.filter) {
|
|
1119
|
-
const { filter } = this;
|
|
1120
|
-
filtered = res.data.filter((obj) => filter?.(obj));
|
|
1121
|
-
} else {
|
|
1122
|
-
filtered = res.data;
|
|
1027
|
+
async verifyToken(jwt) {
|
|
1028
|
+
try {
|
|
1029
|
+
const res = await import_axios.default.get(`${this.apiURL}/auth`, { headers: this.headers(jwt) });
|
|
1030
|
+
return res.status === 200;
|
|
1031
|
+
} catch (_) {
|
|
1032
|
+
return false;
|
|
1123
1033
|
}
|
|
1124
|
-
return {
|
|
1125
|
-
data: filtered.map((r) => r.data).filter((data) => data),
|
|
1126
|
-
hasNext: res.hasNextPage
|
|
1127
|
-
};
|
|
1128
1034
|
}
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
// src/core/MSafeAccount.ts
|
|
1132
|
-
var MSafeAccount = class {
|
|
1133
|
-
constructor(globals, info) {
|
|
1134
|
-
this.globals = globals;
|
|
1135
|
-
this.info = info;
|
|
1136
|
-
this.multisigManager = new import_sui3_utils2.MultisigAccountManager({
|
|
1137
|
-
threshold: info.threshold,
|
|
1138
|
-
ownersWithWeight: info.ownersWithWeightPK,
|
|
1139
|
-
creationNonce: info.creationNonce
|
|
1140
|
-
});
|
|
1141
|
-
this.coinHelper = new CoinHelper(this.suiClient);
|
|
1035
|
+
setJWTToken(token) {
|
|
1036
|
+
this._token = token;
|
|
1142
1037
|
}
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
static async new(globals, address) {
|
|
1146
|
-
return globals.backend.getMSafeAccountInfo(address);
|
|
1038
|
+
async getPublicKey(address) {
|
|
1039
|
+
return (await this.getPublicKeyBatch([address]))[0];
|
|
1147
1040
|
}
|
|
1148
|
-
async
|
|
1149
|
-
const
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1041
|
+
async getPublicKeyBatch(addresses) {
|
|
1042
|
+
const res = await import_axios.default.post(
|
|
1043
|
+
`${this.apiURL}/account/getPublicKeyBatch`,
|
|
1044
|
+
addresses,
|
|
1045
|
+
{
|
|
1046
|
+
headers: this.headers()
|
|
1047
|
+
}
|
|
1048
|
+
);
|
|
1049
|
+
if (res.status !== 200 && res.status !== 201) {
|
|
1050
|
+
throw new Error(`invalid getPublicKeyBatch return: ${res}`);
|
|
1051
|
+
}
|
|
1052
|
+
return res.data?.map(
|
|
1053
|
+
(publicKeyWithSchema) => publicKeyWithSchema ? PublicKeySerde.de({ ...publicKeyWithSchema }) : void 0
|
|
1160
1054
|
);
|
|
1161
1055
|
}
|
|
1162
|
-
async
|
|
1163
|
-
const
|
|
1164
|
-
|
|
1165
|
-
|
|
1056
|
+
async getMSafeAccountInfo(msafeAddress) {
|
|
1057
|
+
const res = await import_axios.default.get(
|
|
1058
|
+
`${this.apiURL}/account/getMSafeAccountInfo/${msafeAddress}`,
|
|
1059
|
+
{
|
|
1060
|
+
headers: this.headers()
|
|
1061
|
+
}
|
|
1062
|
+
);
|
|
1063
|
+
if (res.status !== 200 && res.status !== 201) {
|
|
1064
|
+
throw new Error(`invalid getPublicKeyBatch return: ${res}`);
|
|
1065
|
+
}
|
|
1066
|
+
const msafeResp = res.data;
|
|
1067
|
+
return {
|
|
1068
|
+
address: msafeResp.address,
|
|
1069
|
+
ownersWithWeightPK: msafeResp.ownersWithWeightPKEncoded.map(
|
|
1070
|
+
(owner) => ({
|
|
1071
|
+
publicKey: PublicKeySerde.de({ publicKey: owner.publicKeyEncoded, scheme: owner.schema }),
|
|
1072
|
+
address: owner.address,
|
|
1073
|
+
weight: owner.weight
|
|
1074
|
+
})
|
|
1075
|
+
),
|
|
1076
|
+
threshold: msafeResp.threshold,
|
|
1077
|
+
name: msafeResp.name,
|
|
1078
|
+
description: msafeResp.description,
|
|
1079
|
+
creationNonce: msafeResp.creationNonce
|
|
1166
1080
|
};
|
|
1167
|
-
return getAllOwnedObjects(this.suiClient, this.address, filterCoinObjectOptions);
|
|
1168
1081
|
}
|
|
1169
|
-
async
|
|
1170
|
-
const
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
return void 0;
|
|
1082
|
+
async getUserInfo(userAddress) {
|
|
1083
|
+
const res = await import_axios.default.get(`${this.apiURL}/account/user/${userAddress}`, {
|
|
1084
|
+
headers: this.headers()
|
|
1085
|
+
});
|
|
1086
|
+
if (res.status !== 200 && res.status !== 201) {
|
|
1087
|
+
throw new Error(`invalid getPublicKeyBatch return: ${res}`);
|
|
1176
1088
|
}
|
|
1177
|
-
const pendingTx = pendings.find((tx) => !tx.isRejectTx);
|
|
1178
|
-
const rejectPending = pendings.find((tx) => tx.isRejectTx);
|
|
1179
1089
|
return {
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1090
|
+
address: res.data.address,
|
|
1091
|
+
publicKey: res.data.publicKey,
|
|
1092
|
+
schema: res.data.schema,
|
|
1093
|
+
creationNonce: res.data.creationNonce,
|
|
1094
|
+
ownedMSafe: res.data.ownedMSafe.map(
|
|
1095
|
+
(msafe) => ({
|
|
1096
|
+
address: msafe.address,
|
|
1097
|
+
ownersWithWeightPK: msafe.ownersWithWeightPKEncoded.map(
|
|
1098
|
+
(owner) => ({
|
|
1099
|
+
publicKey: PublicKeySerde.de({ publicKey: owner.publicKeyEncoded, scheme: owner.schema }),
|
|
1100
|
+
address: owner.address,
|
|
1101
|
+
weight: owner.weight
|
|
1102
|
+
})
|
|
1103
|
+
),
|
|
1104
|
+
threshold: msafe.threshold,
|
|
1105
|
+
name: msafe.name,
|
|
1106
|
+
description: msafe.description,
|
|
1107
|
+
creationNonce: msafe.creationNonce
|
|
1108
|
+
})
|
|
1109
|
+
)
|
|
1184
1110
|
};
|
|
1185
1111
|
}
|
|
1186
|
-
async
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
return this.backend.getCurrentSequenceNumber(this.address);
|
|
1112
|
+
async getPendingTransactions(msafeAddress) {
|
|
1113
|
+
const res = await import_axios.default.get(`${this.apiURL}/transaction/pending/${msafeAddress}`, {
|
|
1114
|
+
headers: this.headers()
|
|
1115
|
+
});
|
|
1116
|
+
if (res.status !== 200 && res.status !== 201) {
|
|
1117
|
+
throw new Error(`invalid getPublicKeyBatch return: ${res}`);
|
|
1118
|
+
}
|
|
1119
|
+
return res.data;
|
|
1195
1120
|
}
|
|
1196
|
-
async
|
|
1197
|
-
|
|
1121
|
+
async getHistoryTransactions(msafeAddress, paginationOption) {
|
|
1122
|
+
const res = await import_axios.default.get(
|
|
1123
|
+
`${this.apiURL}/transaction/history?address=${msafeAddress}`,
|
|
1124
|
+
{
|
|
1125
|
+
params: {
|
|
1126
|
+
page: paginationOption?.page,
|
|
1127
|
+
limit: paginationOption?.limit
|
|
1128
|
+
},
|
|
1129
|
+
headers: this.headers()
|
|
1130
|
+
}
|
|
1131
|
+
);
|
|
1132
|
+
if (res.status !== 200 && res.status !== 201) {
|
|
1133
|
+
throw new Error(`invalid getCurrentSequenceNumber return: ${res}`);
|
|
1134
|
+
}
|
|
1135
|
+
return res.data;
|
|
1198
1136
|
}
|
|
1199
|
-
async
|
|
1200
|
-
const
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
messageStr: message
|
|
1207
|
-
});
|
|
1208
|
-
const txType = (0, import_sui3_utils2.getIntentionType)(intention);
|
|
1209
|
-
await this.backend.proposeIntention({
|
|
1210
|
-
intention,
|
|
1211
|
-
sequenceNumber,
|
|
1212
|
-
msafeAddress: this.address,
|
|
1213
|
-
userAddress: await this.userAddress(),
|
|
1214
|
-
signature: signature.signature,
|
|
1215
|
-
application: MSAFE_APPLICATION,
|
|
1216
|
-
txType: txType.txType,
|
|
1217
|
-
txSubType: txType.txSubType
|
|
1137
|
+
async getFutureIntentions(msafeAddress, paginationOption) {
|
|
1138
|
+
const res = await import_axios.default.get(`${this.apiURL}/transaction/intention/${msafeAddress}`, {
|
|
1139
|
+
params: {
|
|
1140
|
+
page: paginationOption?.page,
|
|
1141
|
+
limit: paginationOption?.limit
|
|
1142
|
+
},
|
|
1143
|
+
headers: this.headers()
|
|
1218
1144
|
});
|
|
1145
|
+
if (res.status !== 200 && res.status !== 201) {
|
|
1146
|
+
throw new Error(`invalid getCurrentSequenceNumber return: ${res}`);
|
|
1147
|
+
}
|
|
1148
|
+
return res.data;
|
|
1219
1149
|
}
|
|
1220
|
-
async
|
|
1221
|
-
const
|
|
1222
|
-
|
|
1223
|
-
return this.backend.voteForTransaction({
|
|
1224
|
-
msafeAddress: this.address,
|
|
1225
|
-
userAddress: await this.userAddress(),
|
|
1226
|
-
txDigest: digest,
|
|
1227
|
-
signature: signature.signature
|
|
1150
|
+
async getCurrentSequenceNumber(msafeAddress) {
|
|
1151
|
+
const res = await import_axios.default.get(`${this.apiURL}/transaction/sn/current/${msafeAddress}`, {
|
|
1152
|
+
headers: this.headers()
|
|
1228
1153
|
});
|
|
1154
|
+
if (res.status !== 200 && res.status !== 201) {
|
|
1155
|
+
throw new Error(`invalid getCurrentSequenceNumber return: ${res}`);
|
|
1156
|
+
}
|
|
1157
|
+
return res.data;
|
|
1229
1158
|
}
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
const txb = await IntentionHelper.buildTxb({
|
|
1234
|
-
suiClient: this.suiClient,
|
|
1235
|
-
intention,
|
|
1236
|
-
sender: this.address
|
|
1159
|
+
async getNextSequenceNumber(msafeAddress) {
|
|
1160
|
+
const res = await import_axios.default.get(`${this.apiURL}/transaction/sn/next/${msafeAddress}`, {
|
|
1161
|
+
headers: this.headers()
|
|
1237
1162
|
});
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
return
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
signature: signature.signature
|
|
1163
|
+
if (res.status !== 200 && res.status !== 201) {
|
|
1164
|
+
throw new Error(`invalid getNextSequenceNumber return: ${res}`);
|
|
1165
|
+
}
|
|
1166
|
+
return res.data;
|
|
1167
|
+
}
|
|
1168
|
+
async createMSafeAccount(input) {
|
|
1169
|
+
const res = await import_axios.default.post(`${this.apiURL}/account`, input, {
|
|
1170
|
+
headers: this.headers()
|
|
1247
1171
|
});
|
|
1172
|
+
if (res.status !== 200 && res.status !== 201) {
|
|
1173
|
+
throw new Error(`invalid createMSafeAccount return: ${res}`);
|
|
1174
|
+
}
|
|
1248
1175
|
}
|
|
1249
|
-
async
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
if (
|
|
1253
|
-
throw new Error(
|
|
1254
|
-
}
|
|
1255
|
-
payloadToReject = pending.payload;
|
|
1256
|
-
} else {
|
|
1257
|
-
const pendingTx = await this.pendingTransaction();
|
|
1258
|
-
if (!pendingTx || pendingTx.rejectDigest !== "") {
|
|
1259
|
-
throw new Error("Already rejected");
|
|
1176
|
+
async proposeIntention(input) {
|
|
1177
|
+
try {
|
|
1178
|
+
const res = await import_axios.default.post(`${this.apiURL}/transaction/intention`, input, { headers: this.headers() });
|
|
1179
|
+
if (res.status !== 200 && res.status !== 201) {
|
|
1180
|
+
throw new Error(`invalid proposeIntention return: ${res}`);
|
|
1260
1181
|
}
|
|
1261
|
-
|
|
1182
|
+
} catch (e) {
|
|
1183
|
+
console.log(e);
|
|
1262
1184
|
}
|
|
1263
|
-
const rejectTxb = await IntentionHelper.buildRejectTransaction({
|
|
1264
|
-
msafeAddress: this.address,
|
|
1265
|
-
payloadToReject
|
|
1266
|
-
});
|
|
1267
|
-
const digest = await rejectTxb.getDigest({ client: this.suiClient });
|
|
1268
|
-
const payload = await rejectTxb.build({ client: this.suiClient });
|
|
1269
|
-
const signature = await this.wallet.signTransactionBlock({ transactionBlock: payload });
|
|
1270
|
-
return this.backend.rejectCurrentTx({
|
|
1271
|
-
msafeAddress: this.address,
|
|
1272
|
-
userAddress: await this.userAddress(),
|
|
1273
|
-
digest,
|
|
1274
|
-
signature: signature.signature
|
|
1275
|
-
});
|
|
1276
|
-
}
|
|
1277
|
-
async buildNextIntentionAndAddToPending() {
|
|
1278
|
-
return this.backend.buildNextIntentionAndAddToPending({ msafeAddress: this.address });
|
|
1279
|
-
}
|
|
1280
|
-
async skipNextFailedIntention() {
|
|
1281
|
-
return this.backend.skipNextFailedIntention({ msafeAddress: this.address, userAddress: await this.userAddress() });
|
|
1282
1185
|
}
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
if (!txb.blockData.gasConfig.price) {
|
|
1286
|
-
const refGas = await this.suiClient.getReferenceGasPrice();
|
|
1287
|
-
txb.setGasPrice(refGas);
|
|
1288
|
-
}
|
|
1289
|
-
const payload = await txb.build({ client: this.suiClient });
|
|
1290
|
-
const dryRunResult = await this.suiClient.dryRunTransactionBlock({ transactionBlock: payload });
|
|
1291
|
-
const success = dryRunResult.effects.status.status === "success";
|
|
1292
|
-
const errorMsg = dryRunResult.effects.status.error;
|
|
1293
|
-
const gasPrice = BigInt(txb.blockData.gasConfig.price);
|
|
1294
|
-
const { gasUsed } = dryRunResult.effects;
|
|
1295
|
-
return {
|
|
1296
|
-
success,
|
|
1297
|
-
errorMsg,
|
|
1298
|
-
gasPrice,
|
|
1299
|
-
gasUsed,
|
|
1300
|
-
dryRunResult
|
|
1301
|
-
};
|
|
1186
|
+
// TODO later
|
|
1187
|
+
async proposePendingTransaction(input) {
|
|
1302
1188
|
}
|
|
1303
|
-
async
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1189
|
+
async rejectCurrentTx(input) {
|
|
1190
|
+
try {
|
|
1191
|
+
const res = await import_axios.default.post(
|
|
1192
|
+
`${this.apiURL}/transaction/pending/reject`,
|
|
1193
|
+
{
|
|
1194
|
+
address: input.msafeAddress,
|
|
1195
|
+
digest: input.digest,
|
|
1196
|
+
signature: input.signature
|
|
1197
|
+
},
|
|
1198
|
+
{
|
|
1199
|
+
headers: this.headers()
|
|
1200
|
+
}
|
|
1201
|
+
);
|
|
1202
|
+
if (res.status !== 200 && res.status !== 201) {
|
|
1203
|
+
throw new Error(`invalid voteForTransaction return: ${res}`);
|
|
1204
|
+
}
|
|
1205
|
+
} catch (e) {
|
|
1206
|
+
console.log("e:", e);
|
|
1314
1207
|
}
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1208
|
+
}
|
|
1209
|
+
async voteForTransaction(input) {
|
|
1210
|
+
const res = await import_axios.default.post(
|
|
1211
|
+
`${this.apiURL}/transaction/pending/vote`,
|
|
1212
|
+
{
|
|
1213
|
+
address: input.msafeAddress,
|
|
1214
|
+
digest: input.txDigest,
|
|
1215
|
+
signature: input.signature
|
|
1216
|
+
},
|
|
1217
|
+
{
|
|
1218
|
+
headers: this.headers()
|
|
1321
1219
|
}
|
|
1220
|
+
);
|
|
1221
|
+
if (res.status !== 200 && res.status !== 201) {
|
|
1222
|
+
throw new Error(`invalid voteForTransaction return: ${res}`);
|
|
1322
1223
|
}
|
|
1323
|
-
const multiSignature = this.multisigManager.combinePartialSignatures(sigs);
|
|
1324
|
-
return this.suiClient.executeTransactionBlock({
|
|
1325
|
-
transactionBlock: HexToUint8Array(payload),
|
|
1326
|
-
signature: multiSignature,
|
|
1327
|
-
options: { showEffects: true }
|
|
1328
|
-
});
|
|
1329
1224
|
}
|
|
1330
|
-
|
|
1331
|
-
|
|
1225
|
+
async buildNextIntentionAndAddToPending(input) {
|
|
1226
|
+
const res = await import_axios.default.post(
|
|
1227
|
+
`${this.apiURL}/transaction/pending/build`,
|
|
1228
|
+
{
|
|
1229
|
+
address: input.msafeAddress
|
|
1230
|
+
},
|
|
1231
|
+
{ headers: this.headers() }
|
|
1232
|
+
);
|
|
1233
|
+
if (res.status !== 200 && res.status !== 201) {
|
|
1234
|
+
throw new Error(`invalid buildNextIntentionAndAddToPending return: ${res}`);
|
|
1235
|
+
}
|
|
1332
1236
|
}
|
|
1333
|
-
|
|
1334
|
-
|
|
1237
|
+
async skipNextFailedIntention(input) {
|
|
1238
|
+
const res = await import_axios.default.post(
|
|
1239
|
+
`${this.apiURL}/transaction/pending/skip`,
|
|
1240
|
+
{
|
|
1241
|
+
msafeAddress: input.msafeAddress
|
|
1242
|
+
},
|
|
1243
|
+
{ headers: this.headers() }
|
|
1244
|
+
);
|
|
1245
|
+
if (res.status !== 200 && res.status !== 201) {
|
|
1246
|
+
throw new Error(`invalid skipNextFailedIntention return: ${res}`);
|
|
1247
|
+
}
|
|
1335
1248
|
}
|
|
1336
|
-
|
|
1337
|
-
|
|
1249
|
+
async getAddressBookEntries(pagination) {
|
|
1250
|
+
const res = await import_axios.default.get(`${this.apiURL}/address-book`, {
|
|
1251
|
+
headers: this.headers(),
|
|
1252
|
+
params: pagination
|
|
1253
|
+
});
|
|
1254
|
+
if (res.status !== 200) {
|
|
1255
|
+
throw new Error(`Invalid address-book return: ${res}`);
|
|
1256
|
+
}
|
|
1257
|
+
return res.data;
|
|
1338
1258
|
}
|
|
1339
|
-
async
|
|
1340
|
-
|
|
1259
|
+
async updateAddressBook(input) {
|
|
1260
|
+
const res = await import_axios.default.post(`${this.apiURL}/address-book`, input, { headers: this.headers() });
|
|
1261
|
+
if (res.status !== 200 && res.status !== 201) {
|
|
1262
|
+
throw new Error(`invalid updateAddressBook return: ${res}`);
|
|
1263
|
+
}
|
|
1341
1264
|
}
|
|
1342
|
-
|
|
1343
|
-
|
|
1265
|
+
async processExecutedTransaction(digest) {
|
|
1266
|
+
}
|
|
1267
|
+
headers(token) {
|
|
1268
|
+
return { Authorization: `Bearer ${token || this._token}` };
|
|
1344
1269
|
}
|
|
1345
1270
|
};
|
|
1346
1271
|
|
|
1347
|
-
// src/
|
|
1348
|
-
var
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1272
|
+
// src/globals/const.ts
|
|
1273
|
+
var MSafeEnv = /* @__PURE__ */ ((MSafeEnv3) => {
|
|
1274
|
+
MSafeEnv3["local"] = "local";
|
|
1275
|
+
MSafeEnv3["unit"] = "unit";
|
|
1276
|
+
MSafeEnv3["dev"] = "dev";
|
|
1277
|
+
MSafeEnv3["prev"] = "prev";
|
|
1278
|
+
MSafeEnv3["prod"] = "prod";
|
|
1279
|
+
return MSafeEnv3;
|
|
1280
|
+
})(MSafeEnv || {});
|
|
1281
|
+
var UNIT_DATABASE_CONFIG = {
|
|
1282
|
+
type: "sqlite",
|
|
1283
|
+
database: ":memory:",
|
|
1284
|
+
logging: false
|
|
1285
|
+
};
|
|
1286
|
+
var LOCAL_DATABASE_CONFIG = {
|
|
1287
|
+
type: "mysql",
|
|
1288
|
+
host: "127.0.0.1",
|
|
1289
|
+
port: 3306,
|
|
1290
|
+
username: "msafe",
|
|
1291
|
+
password: "msafe",
|
|
1292
|
+
database: "msafe_sui_local",
|
|
1293
|
+
logging: false
|
|
1294
|
+
};
|
|
1295
|
+
var DEV_DATABASE_CONFIG = {
|
|
1296
|
+
type: "mysql",
|
|
1297
|
+
host: "msafe-dev-database.cluster-caos3ssocrx6.us-west-1.rds.amazonaws.com",
|
|
1298
|
+
port: 3306,
|
|
1299
|
+
username: "msafe",
|
|
1300
|
+
password: "Momentum.Safe2022",
|
|
1301
|
+
database: "msafe_sui_dev",
|
|
1302
|
+
logging: false
|
|
1303
|
+
};
|
|
1304
|
+
var MSAFE_APPLICATION = "msafe";
|
|
1305
|
+
var TESTNET_RPC_URL = "https://sui-testnet.blockvision.org/v1/2Sgk89ivT64MnKdcGzjmyjY2ndD";
|
|
1306
|
+
var MAINNET_RPC_URL = "https://sui-mainnet.blockvision.org/v1/2Sgk7NPvqkd7mESYkxF01yX15l7";
|
|
1307
|
+
var LOCAL_API_URL = "http://127.0.0.1:3000";
|
|
1308
|
+
var LOCAL_SYNCING_URL = "http://127.0.0.1:3001";
|
|
1309
|
+
var DEV_API_URL = "http://13.56.226.148";
|
|
1310
|
+
var DEV_SYNCING_URL = "http://52.53.228.20";
|
|
1311
|
+
var ENV_CONFIGS = /* @__PURE__ */ new Map([
|
|
1312
|
+
[
|
|
1313
|
+
"unit" /* unit */,
|
|
1314
|
+
{
|
|
1315
|
+
suiClient: {
|
|
1316
|
+
url: TESTNET_RPC_URL
|
|
1317
|
+
},
|
|
1318
|
+
backend: LOCAL_DATABASE_CONFIG,
|
|
1319
|
+
apiURL: LOCAL_API_URL,
|
|
1320
|
+
syncingURL: LOCAL_SYNCING_URL
|
|
1376
1321
|
}
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1322
|
+
],
|
|
1323
|
+
[
|
|
1324
|
+
"local" /* local */,
|
|
1325
|
+
{
|
|
1326
|
+
suiClient: {
|
|
1327
|
+
url: TESTNET_RPC_URL
|
|
1328
|
+
},
|
|
1329
|
+
backend: LOCAL_DATABASE_CONFIG,
|
|
1330
|
+
apiURL: LOCAL_API_URL,
|
|
1331
|
+
syncingURL: LOCAL_SYNCING_URL
|
|
1381
1332
|
}
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1333
|
+
],
|
|
1334
|
+
[
|
|
1335
|
+
"dev" /* dev */,
|
|
1336
|
+
{
|
|
1337
|
+
suiClient: {
|
|
1338
|
+
url: TESTNET_RPC_URL
|
|
1339
|
+
},
|
|
1340
|
+
backend: DEV_DATABASE_CONFIG,
|
|
1341
|
+
apiURL: DEV_API_URL,
|
|
1342
|
+
syncingURL: DEV_SYNCING_URL
|
|
1386
1343
|
}
|
|
1387
|
-
|
|
1344
|
+
]
|
|
1345
|
+
]);
|
|
1346
|
+
function getMSafeConfig(env, options) {
|
|
1347
|
+
const config = ENV_CONFIGS.get(env);
|
|
1348
|
+
if (!config) {
|
|
1349
|
+
throw new Error("Unknown environment");
|
|
1388
1350
|
}
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
if (pkBackend) {
|
|
1392
|
-
return pkBackend;
|
|
1393
|
-
}
|
|
1394
|
-
const pkChain = await this.getPublicKeyFromChain(address);
|
|
1395
|
-
if (pkChain) {
|
|
1396
|
-
return pkChain;
|
|
1397
|
-
}
|
|
1398
|
-
return void 0;
|
|
1351
|
+
if (options?.suiClient?.url) {
|
|
1352
|
+
config.suiClient.url = options.suiClient.url;
|
|
1399
1353
|
}
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1354
|
+
if (options?.backend) {
|
|
1355
|
+
config.backend = options.backend;
|
|
1356
|
+
}
|
|
1357
|
+
return config;
|
|
1358
|
+
}
|
|
1359
|
+
var AUTH_SIGN_MESSAGE = "Welcome to MSafe";
|
|
1360
|
+
|
|
1361
|
+
// src/globals/MSafeGlobals.ts
|
|
1362
|
+
var MSafeGlobals = class _MSafeGlobals {
|
|
1363
|
+
backend;
|
|
1364
|
+
suiClient;
|
|
1365
|
+
config;
|
|
1366
|
+
_wallet;
|
|
1367
|
+
constructor(input) {
|
|
1368
|
+
this.backend = input.backend;
|
|
1369
|
+
this.suiClient = input.suiClient;
|
|
1370
|
+
this.config = input.config;
|
|
1371
|
+
}
|
|
1372
|
+
static async New(env, options) {
|
|
1373
|
+
const config = getMSafeConfig(env, options);
|
|
1374
|
+
const suiClient = new import_client.SuiClient(config.suiClient);
|
|
1375
|
+
const backend = new BackendImpl(config.apiURL);
|
|
1376
|
+
return new _MSafeGlobals({
|
|
1377
|
+
backend,
|
|
1378
|
+
suiClient,
|
|
1379
|
+
config
|
|
1380
|
+
});
|
|
1381
|
+
}
|
|
1382
|
+
connectWallet(wallet) {
|
|
1383
|
+
this._wallet = wallet;
|
|
1384
|
+
}
|
|
1385
|
+
get wallet() {
|
|
1386
|
+
if (!this._wallet) {
|
|
1387
|
+
throw new Error("wallet not connected");
|
|
1406
1388
|
}
|
|
1389
|
+
return this._wallet;
|
|
1407
1390
|
}
|
|
1408
|
-
|
|
1409
|
-
|
|
1391
|
+
set wallet(val) {
|
|
1392
|
+
this._wallet = val;
|
|
1410
1393
|
}
|
|
1411
1394
|
};
|
|
1412
1395
|
|