@msafe/sui3-sdk 0.0.13 → 0.0.14

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.
@@ -1,14 +1,22 @@
1
1
  import {
2
- AuthLoginRequest,
3
- AuthLoginResponse,
4
- CreateMSafeAccountInfoRequest,
5
- GetMSafeAccountInfoResponse,
6
2
  HistoryTransaction,
7
- MSafeAccountInfo,
8
- OwnerWithWeightPK,
9
- PublicKeyWithScheme,
10
- UserWithOwnedMSafe,
11
- UserWithOwnedMSafeResponse,
3
+ IAuthLoginReq,
4
+ IAuthLoginResp,
5
+ ICreateMSafeReq,
6
+ IGetMSafeQuery,
7
+ IGetMSafesQuery,
8
+ IGetPublicKeyBatchQuery,
9
+ IGetPublicKeyBatchResp,
10
+ IMSafeInfoResp,
11
+ IPagedResult,
12
+ IPageOptions,
13
+ IUpdateMSafeStatusReq,
14
+ IUserInfoResp,
15
+ JWTToken,
16
+ PublicKeySerde,
17
+ UserMSafeStatus,
18
+ IGetAddressBookResult,
19
+ UpdateAddressBookEntry,
12
20
  } from '@msafe/sui3-utils';
13
21
  import { SerializedSignature } from '@mysten/sui.js/cryptography';
14
22
  import { PublicKey } from '@mysten/sui.js/src/cryptography';
@@ -16,19 +24,15 @@ import axios from 'axios';
16
24
 
17
25
  import { IBackend } from '@/backend/interface';
18
26
  import { TxIntention } from '@/transactions/intention';
19
- import { PagedResult } from '@/types';
20
- import { GetAddressBookResult, UpdateAddressBookEntry } from '@/types/address-book';
21
- import { JWTToken, PaginationOption } from '@/types/backend';
22
27
  import { FutureIntention, PendingTx, ProposeIntention } from '@/types/msafe';
23
- import { PublicKeySerde } from '@/utils/crypto';
24
28
 
25
29
  export class BackendImpl implements IBackend {
26
30
  private _token: JWTToken;
27
31
 
28
32
  constructor(private readonly apiURL: string) {}
29
33
 
30
- async authSign(input: AuthLoginRequest): Promise<JWTToken> {
31
- const res = await axios.post<AuthLoginResponse>(`${this.apiURL}/auth/login`, input);
34
+ async authSign(input: IAuthLoginReq): Promise<JWTToken> {
35
+ const res = await axios.post<IAuthLoginResp>(`${this.apiURL}/auth/login`, input);
32
36
  // TODO unify response struct
33
37
  if (res.status !== 200 && res.status !== 201) {
34
38
  throw new Error(`invalid authSign return: ${res}`);
@@ -55,85 +59,78 @@ export class BackendImpl implements IBackend {
55
59
  }
56
60
 
57
61
  async getPublicKeyBatch(addresses: string[]): Promise<(PublicKey | undefined)[]> {
58
- const res = await axios.post<(PublicKeyWithScheme | undefined)[]>(
59
- `${this.apiURL}/account/getPublicKeyBatch`,
60
- addresses,
61
- {
62
- headers: this.headers(),
63
- },
64
- );
62
+ const query: IGetPublicKeyBatchQuery = {
63
+ userAddressList: addresses,
64
+ };
65
+ const res = await axios.get<IGetPublicKeyBatchResp>(`${this.apiURL}/user/public-keys`, {
66
+ params: query,
67
+ headers: this.headers(),
68
+ });
69
+
65
70
  // TODO unify response struct
66
71
  if (res.status !== 200 && res.status !== 201) {
67
72
  throw new Error(`invalid getPublicKeyBatch return: ${res}`);
68
73
  }
69
-
70
74
  return res.data?.map((publicKeyWithSchema) =>
71
- publicKeyWithSchema ? PublicKeySerde.de({ ...publicKeyWithSchema }) : undefined,
75
+ publicKeyWithSchema ? PublicKeySerde.de(publicKeyWithSchema) : undefined,
72
76
  );
73
77
  }
74
78
 
75
- async getMSafeAccountInfo(msafeAddress: string): Promise<MSafeAccountInfo> {
76
- const res = await axios.get<GetMSafeAccountInfoResponse>(
77
- `${this.apiURL}/account/getMSafeAccountInfo/${msafeAddress}`,
78
- {
79
- headers: this.headers(),
80
- },
81
- );
82
-
79
+ async getMSafeAccountInfo(msafeAddress: string): Promise<IMSafeInfoResp> {
80
+ const q: IGetMSafeQuery = {
81
+ msafeAddress,
82
+ };
83
+ const res = await axios.get<IMSafeInfoResp>(`${this.apiURL}/msafe`, {
84
+ params: q,
85
+ headers: this.headers(),
86
+ });
83
87
  // TODO unify response struct
84
88
  if (res.status !== 200 && res.status !== 201) {
85
89
  throw new Error(`invalid getPublicKeyBatch return: ${res}`);
86
90
  }
87
-
88
- const msafeResp = res.data;
89
- return {
90
- address: msafeResp.address,
91
- ownersWithWeightPK: msafeResp.ownersWithWeightPKEncoded.map(
92
- (owner): OwnerWithWeightPK => ({
93
- publicKey: PublicKeySerde.de({ publicKey: owner.publicKeyEncoded, scheme: owner.schema }),
94
- address: owner.address,
95
- weight: owner.weight,
96
- }),
97
- ),
98
- threshold: msafeResp.threshold,
99
- name: msafeResp.name,
100
- description: msafeResp.description,
101
- creationNonce: msafeResp.creationNonce,
102
- };
91
+ return res.data;
103
92
  }
104
93
 
105
- async getUserInfo(userAddress: string): Promise<UserWithOwnedMSafe> {
106
- const res = await axios.get<UserWithOwnedMSafeResponse>(`${this.apiURL}/account/user/${userAddress}`, {
94
+ async getUserInfo(): Promise<IUserInfoResp> {
95
+ const userRes = await axios.get<IUserInfoResp>(`${this.apiURL}/user`, {
107
96
  headers: this.headers(),
108
97
  });
109
-
110
98
  // TODO unify response struct
111
- if (res.status !== 200 && res.status !== 201) {
112
- throw new Error(`invalid getPublicKeyBatch return: ${res}`);
99
+ if (userRes.status !== 200 && userRes.status !== 201) {
100
+ throw new Error(`invalid getPublicKeyBatch return: ${userRes}`);
113
101
  }
102
+ return userRes.data;
103
+ }
114
104
 
115
- return {
116
- address: res.data.address,
117
- publicKey: res.data.publicKey,
118
- schema: res.data.schema,
119
- creationNonce: res.data.creationNonce,
120
- ownedMSafe: res.data.ownedMSafe.map(
121
- (msafe): MSafeAccountInfo => ({
122
- address: msafe.address,
123
- ownersWithWeightPK: msafe.ownersWithWeightPKEncoded.map(
124
- (owner): OwnerWithWeightPK => ({
125
- publicKey: PublicKeySerde.de({ publicKey: owner.publicKeyEncoded, scheme: owner.schema }),
126
- address: owner.address,
127
- weight: owner.weight,
128
- }),
129
- ),
130
- threshold: msafe.threshold,
131
- name: msafe.name,
132
- description: msafe.description,
133
- creationNonce: msafe.creationNonce,
134
- }),
135
- ),
105
+ async getOwnedMSafeByStatus(input: {
106
+ status?: UserMSafeStatus;
107
+ pagination?: IPageOptions;
108
+ }): Promise<IPagedResult<IMSafeInfoResp>> {
109
+ const q: IGetMSafesQuery = {
110
+ status: input.status ?? UserMSafeStatus.active,
111
+ ...(input.pagination
112
+ ? {
113
+ page: input.pagination.page.toString(),
114
+ limit: input.pagination.limit.toString(),
115
+ }
116
+ : {}),
136
117
  };
118
+ const res = await axios.get<IPagedResult<IMSafeInfoResp>>(`${this.apiURL}/msafe/owned`, {
119
+ params: q,
120
+ headers: this.headers(),
121
+ });
122
+ if (res.status !== 200 && res.status !== 201) {
123
+ throw new Error(`invalid getOwnedMSafeByStatus return: ${res}`);
124
+ }
125
+ return res.data;
126
+ }
127
+
128
+ async updateMSafeStatus(input: { msafeAddress: string; status: UserMSafeStatus }): Promise<void> {
129
+ const p: IUpdateMSafeStatusReq = input;
130
+ const res = await axios.post(`${this.apiURL}/msafe/status`, p, { headers: this.headers() });
131
+ if (res.status !== 200 && res.status !== 201) {
132
+ throw new Error(`Invalid updateMSafeStatus return: ${res}`);
133
+ }
137
134
  }
138
135
 
139
136
  async getPendingTransactions(msafeAddress: string): Promise<PendingTx[]> {
@@ -148,9 +145,9 @@ export class BackendImpl implements IBackend {
148
145
 
149
146
  async getHistoryTransactions(
150
147
  msafeAddress: string,
151
- paginationOption?: PaginationOption,
152
- ): Promise<PagedResult<HistoryTransaction>> {
153
- const res = await axios.get<PagedResult<HistoryTransaction>>(
148
+ paginationOption?: IPageOptions,
149
+ ): Promise<IPagedResult<HistoryTransaction>> {
150
+ const res = await axios.get<IPagedResult<HistoryTransaction>>(
154
151
  `${this.apiURL}/transaction/history?address=${msafeAddress}`,
155
152
  {
156
153
  params: {
@@ -168,9 +165,9 @@ export class BackendImpl implements IBackend {
168
165
 
169
166
  async getFutureIntentions(
170
167
  msafeAddress: string,
171
- paginationOption?: PaginationOption,
172
- ): Promise<PagedResult<FutureIntention>> {
173
- const res = await axios.get<PagedResult<FutureIntention>>(`${this.apiURL}/transaction/intention/${msafeAddress}`, {
168
+ paginationOption?: IPageOptions,
169
+ ): Promise<IPagedResult<FutureIntention>> {
170
+ const res = await axios.get<IPagedResult<FutureIntention>>(`${this.apiURL}/transaction/intention/${msafeAddress}`, {
174
171
  params: {
175
172
  page: paginationOption?.page,
176
173
  limit: paginationOption?.limit,
@@ -203,8 +200,8 @@ export class BackendImpl implements IBackend {
203
200
  return res.data;
204
201
  }
205
202
 
206
- async createMSafeAccount(input: CreateMSafeAccountInfoRequest): Promise<void> {
207
- const res = await axios.post(`${this.apiURL}/account`, input, {
203
+ async createMSafeAccount(input: ICreateMSafeReq): Promise<void> {
204
+ const res = await axios.post(`${this.apiURL}/msafe/create`, input, {
208
205
  headers: this.headers(),
209
206
  });
210
207
  if (res.status !== 200 && res.status !== 201) {
@@ -213,24 +210,23 @@ export class BackendImpl implements IBackend {
213
210
  }
214
211
 
215
212
  async proposeIntention(input: ProposeIntention): Promise<void> {
216
- try {
217
- const res = await axios.post(`${this.apiURL}/transaction/intention`, input, { headers: this.headers() });
218
- if (res.status !== 200 && res.status !== 201) {
219
- throw new Error(`invalid proposeIntention return: ${res}`);
220
- }
221
- } catch (e) {
222
- console.log(e);
213
+ const res = await axios.post(`${this.apiURL}/transaction/intention`, input, { headers: this.headers() });
214
+ if (res.status !== 200 && res.status !== 201) {
215
+ throw new Error(`invalid proposeIntention return: ${res}`);
223
216
  }
224
217
  }
225
218
 
226
219
  // TODO later
227
- async proposePendingTransaction(input: {
220
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
221
+ async proposePendingTransaction(_input: {
228
222
  intention: TxIntention;
229
223
  userAddress: string;
230
224
  msafeAddress: string;
231
225
  digest: string;
232
226
  signature: SerializedSignature;
233
- }): Promise<void> {}
227
+ }): Promise<void> {
228
+ return undefined;
229
+ }
234
230
 
235
231
  async rejectCurrentTx(input: {
236
232
  userAddress: string;
@@ -238,23 +234,19 @@ export class BackendImpl implements IBackend {
238
234
  digest: string;
239
235
  signature: SerializedSignature;
240
236
  }) {
241
- try {
242
- const res = await axios.post(
243
- `${this.apiURL}/transaction/pending/reject`,
244
- {
245
- address: input.msafeAddress,
246
- digest: input.digest,
247
- signature: input.signature,
248
- },
249
- {
250
- headers: this.headers(),
251
- },
252
- );
253
- if (res.status !== 200 && res.status !== 201) {
254
- throw new Error(`invalid voteForTransaction return: ${res}`);
255
- }
256
- } catch (e) {
257
- console.log('e:', e);
237
+ const res = await axios.post(
238
+ `${this.apiURL}/transaction/pending/reject`,
239
+ {
240
+ address: input.msafeAddress,
241
+ digest: input.digest,
242
+ signature: input.signature,
243
+ },
244
+ {
245
+ headers: this.headers(),
246
+ },
247
+ );
248
+ if (res.status !== 200 && res.status !== 201) {
249
+ throw new Error(`invalid voteForTransaction return: ${res}`);
258
250
  }
259
251
  }
260
252
 
@@ -306,8 +298,8 @@ export class BackendImpl implements IBackend {
306
298
  }
307
299
  }
308
300
 
309
- async getAddressBookEntries(pagination?: PaginationOption): Promise<GetAddressBookResult> {
310
- const res = await axios.get<GetAddressBookResult>(`${this.apiURL}/address-book`, {
301
+ async getAddressBookEntries(pagination?: IPageOptions): Promise<IGetAddressBookResult> {
302
+ const res = await axios.get<IGetAddressBookResult>(`${this.apiURL}/address-book`, {
311
303
  headers: this.headers(),
312
304
  params: pagination,
313
305
  });
@@ -324,7 +316,10 @@ export class BackendImpl implements IBackend {
324
316
  }
325
317
  }
326
318
 
327
- async processExecutedTransaction(digest: string) {}
319
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
320
+ async processExecutedTransaction(_digest: string) {
321
+ return undefined;
322
+ }
328
323
 
329
324
  private headers(token?: string) {
330
325
  return { Authorization: `Bearer ${token || this._token}` };
@@ -1,36 +1,46 @@
1
1
  import {
2
- AuthLoginRequest,
3
- CreateMSafeAccountInfoRequest,
4
2
  HistoryTransaction,
5
- MSafeAccountInfo,
6
- UserWithOwnedMSafe,
3
+ IAuthLoginReq,
4
+ ICreateMSafeReq,
5
+ IMSafeInfoResp,
6
+ IPageOptions,
7
+ IUserInfoResp,
8
+ UserMSafeStatus,
9
+ IGetAddressBookResult,
10
+ IPagedResult,
11
+ UpdateAddressBookEntry,
12
+ JWTToken,
7
13
  } from '@msafe/sui3-utils';
8
14
  import { PublicKey, SerializedSignature } from '@mysten/sui.js/cryptography';
9
15
 
10
16
  import { TxIntention } from '@/transactions/intention';
11
- import { GetAddressBookResult, PagedResult, UpdateAddressBookEntry } from '@/types';
12
- import { JWTToken, PaginationOption } from '@/types/backend';
13
17
  import { FutureIntention, PendingTx, ProposeIntention } from '@/types/msafe';
14
18
 
15
19
  export interface IBackend {
16
- authSign(input: AuthLoginRequest): Promise<JWTToken>;
20
+ authSign(input: IAuthLoginReq): Promise<JWTToken>;
17
21
  verifyToken(jwt?: JWTToken): Promise<boolean>;
18
22
  setJWTToken(token: JWTToken): void;
19
23
 
20
24
  getPublicKey(address: string): Promise<PublicKey | undefined>;
21
25
  getPublicKeyBatch(addresses: string[]): Promise<(PublicKey | undefined)[]>;
22
- getMSafeAccountInfo(msafeAddress: string): Promise<MSafeAccountInfo>;
23
- getUserInfo(userAddress: string): Promise<UserWithOwnedMSafe>;
26
+ getMSafeAccountInfo(msafeAddress: string): Promise<IMSafeInfoResp>;
27
+ getUserInfo(): Promise<IUserInfoResp>;
28
+ getOwnedMSafeByStatus(input: {
29
+ status?: UserMSafeStatus;
30
+ pagination?: IPageOptions;
31
+ }): Promise<IPagedResult<IMSafeInfoResp>>;
32
+ updateMSafeStatus(input: { msafeAddress: string; status: UserMSafeStatus }): Promise<void>;
33
+
24
34
  getPendingTransactions(msafeAddress: string): Promise<PendingTx[]>;
25
35
  getHistoryTransactions(
26
36
  msafeAddress: string,
27
- paginationOption?: PaginationOption,
28
- ): Promise<PagedResult<HistoryTransaction>>;
29
- getFutureIntentions(msafeAddress: string, paginationOption?: PaginationOption): Promise<PagedResult<FutureIntention>>;
37
+ paginationOption?: IPageOptions,
38
+ ): Promise<IPagedResult<HistoryTransaction>>;
39
+ getFutureIntentions(msafeAddress: string, paginationOption?: IPageOptions): Promise<IPagedResult<FutureIntention>>;
30
40
  getCurrentSequenceNumber(msafeAddress: string): Promise<number>;
31
41
  getNextSequenceNumber(msafeAddress: string): Promise<number>;
32
42
 
33
- createMSafeAccount(input: CreateMSafeAccountInfoRequest): Promise<void>;
43
+ createMSafeAccount(input: ICreateMSafeReq): Promise<void>;
34
44
  proposeIntention(input: ProposeIntention): Promise<void>;
35
45
  proposePendingTransaction(input: {
36
46
  intention: TxIntention;
@@ -55,6 +65,6 @@ export interface IBackend {
55
65
  skipNextFailedIntention(input: { msafeAddress: string; userAddress: string }): Promise<void>;
56
66
  processExecutedTransaction(digest: string): Promise<void>;
57
67
 
58
- getAddressBookEntries(pagination?: PaginationOption): Promise<GetAddressBookResult>;
68
+ getAddressBookEntries(pagination?: IPageOptions): Promise<IGetAddressBookResult>;
59
69
  updateAddressBook(input: { updates: UpdateAddressBookEntry[]; signature: SerializedSignature }): Promise<void>;
60
70
  }
@@ -1,17 +1,16 @@
1
- import { MessageHelper } from '@/core/MessageHelper';
1
+ import { IPageOptions, SigningMessageHelper, UpdateAddressBookEntry } from '@msafe/sui3-utils';
2
+
2
3
  import { MSafeGlobals } from '@/globals';
3
- import { UpdateAddressBookEntry } from '@/types';
4
- import { PaginationOption } from '@/types/backend';
5
4
 
6
5
  export class AddressBookSDK {
7
6
  constructor(public readonly globals: MSafeGlobals) {}
8
7
 
9
- async getEntries(pagination?: PaginationOption) {
8
+ async getEntries(pagination?: IPageOptions) {
10
9
  return this.globals.backend.getAddressBookEntries(pagination);
11
10
  }
12
11
 
13
12
  async update(updates: UpdateAddressBookEntry[]) {
14
- const messageStr = MessageHelper.updateAddressBookMessage(updates);
13
+ const messageStr = SigningMessageHelper.updateAddressBookMessage(updates);
15
14
  const sig = await this.globals.wallet.signPersonalMessage({ messageStr });
16
15
  return this.globals.backend.updateAddressBook({ updates, signature: sig.signature });
17
16
  }
@@ -1,16 +1,9 @@
1
- import {
2
- createAccountCreationMessage,
3
- MultisigAccountManager,
4
- MultiSigConfig,
5
- OwnerWithWeightPKEncoded,
6
- validateCreateAccountRequest,
7
- } from '@msafe/sui3-utils';
1
+ import { MultiSigAccount, MultiSigConfig, PublicKeySerde, SigningMessageHelper } from '@msafe/sui3-utils';
8
2
  import { PublicKey, SerializedSignature } from '@mysten/sui.js/cryptography';
9
3
 
10
4
  import { PublicKeyHelper } from '@/core/PublicKeyHelper';
11
5
  import { MSafeGlobals } from '@/globals/MSafeGlobals';
12
- import { CreateMSafeAccountInfo, CreatePermissionInfo } from '@/types/creation';
13
- import { PublicKeySerde } from '@/utils/crypto';
6
+ import { CreateMSafeInfo } from '@/types';
14
7
 
15
8
  export class CreateHelper {
16
9
  constructor(
@@ -22,41 +15,38 @@ export class CreateHelper {
22
15
  return this.pkHelper.getPublicKeyBatch(addresses);
23
16
  }
24
17
 
25
- async calculateMSafeAddress(info: CreatePermissionInfo) {
18
+ async calculateMSafeAddress(info: CreateMSafeInfo) {
26
19
  const msConfig = await this.reduceCreationInfoToRawConfig(info);
27
- const ms = new MultisigAccountManager(msConfig);
20
+ const ms = new MultiSigAccount(msConfig);
28
21
  return ms.address;
29
22
  }
30
23
 
31
24
  // Validate the create info and return the msafe address.
32
- async validateCreateInfo(createInfo: CreateMSafeAccountInfo) {
33
- const rawConfig = await this.reduceCreationInfoToRawConfig(createInfo);
34
- validateCreateAccountRequest(rawConfig);
35
-
25
+ async validateCreateInfo(createInfo: CreateMSafeInfo) {
36
26
  // Calculate the sui address will check the multi-sig
37
27
  return this.calculateMSafeAddress(createInfo);
38
28
  }
39
29
 
40
- async submitMSafeCreation(creationInfo: CreateMSafeAccountInfo) {
30
+ async submitMSafeCreation(creationInfo: CreateMSafeInfo) {
41
31
  const msafeAddress = await this.validateCreateInfo(creationInfo);
42
32
 
43
- const signingMessage = createAccountCreationMessage(msafeAddress);
33
+ const signingMessage = SigningMessageHelper.createMSafeMessage(msafeAddress);
44
34
  const signature = await this.globals.wallet.signPersonalMessage({ messageStr: signingMessage });
45
35
 
46
36
  await this.submitToBackend(creationInfo, signature.signature);
47
37
  return msafeAddress;
48
38
  }
49
39
 
50
- private async reduceCreationInfoToRawConfig(info: CreatePermissionInfo): Promise<MultiSigConfig> {
51
- const publicKeys = await this.getPublicKeyBatch(info.ownerWithWeight.map((oww) => oww.address));
40
+ private async reduceCreationInfoToRawConfig(info: CreateMSafeInfo): Promise<MultiSigConfig> {
41
+ const publicKeys = await this.getPublicKeyBatch(info.owners.map((owner) => owner.address));
52
42
  publicKeys.forEach((pk, i) => {
53
43
  if (pk === undefined) {
54
- throw new Error(`Unknown public key for address: ${info.ownerWithWeight[i].address}`);
44
+ throw new Error(`Unknown public key for address: ${info.owners[i].address}`);
55
45
  }
56
46
  });
57
47
  return {
58
48
  threshold: info.threshold,
59
- ownersWithWeight: info.ownerWithWeight.map((owner, i) => ({
49
+ ownersWithWeight: info.owners.map((owner, i) => ({
60
50
  publicKey: publicKeys[i] as PublicKey,
61
51
  weight: owner.weight,
62
52
  })),
@@ -64,18 +54,14 @@ export class CreateHelper {
64
54
  };
65
55
  }
66
56
 
67
- private async submitToBackend(createInfo: CreateMSafeAccountInfo, signature: SerializedSignature) {
68
- const pks = await this.pkHelper.getPublicKeyBatch(createInfo.ownerWithWeight.map((owner) => owner.address));
57
+ private async submitToBackend(createInfo: CreateMSafeInfo, signature: SerializedSignature) {
58
+ const pks = await this.pkHelper.getPublicKeyBatch(createInfo.owners.map((owner) => owner.address));
69
59
  await this.globals.backend.createMSafeAccount({
70
- ownersWithWeightPKEncoded: createInfo.ownerWithWeight.map((owner, i): OwnerWithWeightPKEncoded => {
71
- const publicKeySer = PublicKeySerde.ser(pks[i] as PublicKey);
72
- return {
73
- address: owner.address,
74
- weight: owner.weight,
75
- publicKeyEncoded: publicKeySer.publicKey,
76
- schema: publicKeySer.scheme,
77
- };
78
- }),
60
+ owners: createInfo.owners.map((owner, i) => ({
61
+ address: owner.address,
62
+ weight: owner.weight,
63
+ ...PublicKeySerde.ser(pks[i] as PublicKey),
64
+ })),
79
65
  threshold: createInfo.threshold,
80
66
  name: createInfo.name, // name validation is deferred to backend
81
67
  description: createInfo.description, // description validation is deferred to backend
@@ -0,0 +1,15 @@
1
+ import { IPageOptions, UserMSafeStatus } from '@msafe/sui3-utils';
2
+
3
+ import { MSafeGlobals } from '@/globals';
4
+
5
+ export class InvitationSDK {
6
+ constructor(public readonly globals: MSafeGlobals) {}
7
+
8
+ async getMSafeByStatus(status: UserMSafeStatus, pagination?: IPageOptions) {
9
+ return this.globals.backend.getOwnedMSafeByStatus({ status, pagination });
10
+ }
11
+
12
+ async updateMSafeStatus(msafeAddress: string, status: UserMSafeStatus) {
13
+ return this.globals.backend.updateMSafeStatus({ msafeAddress, status });
14
+ }
15
+ }
@@ -1,38 +1,51 @@
1
- import { buildIntentionTransaction, MSafeAccountInfo, MultisigAccountManager } from '@msafe/sui3-utils';
1
+ import {
2
+ buildIntentionTransaction,
3
+ IMSafeConfig,
4
+ IPageOptions,
5
+ MultiSigAccount,
6
+ PublicKeySerde,
7
+ SigningMessageHelper,
8
+ } from '@msafe/sui3-utils';
2
9
  import { SuiObjectData } from '@mysten/sui.js/client';
3
10
  import { SerializedSignature } from '@mysten/sui.js/cryptography';
4
11
  import { SuiObjectResponse } from '@mysten/sui.js/src/client';
5
12
  import { normalizeStructTag } from '@mysten/sui.js/utils';
6
13
 
7
- import { MessageHelper } from '@/core/MessageHelper';
8
14
  import { MSafeGlobals } from '@/globals/MSafeGlobals';
9
15
  import { IntentionHelper, TxIntention } from '@/transactions/intention';
10
16
  import { OwnedCoin } from '@/types/assets';
11
- import { PaginationOption } from '@/types/backend';
12
17
  import { PendingTx, SimulationResult } from '@/types/msafe';
13
18
  import { CoinHelper } from '@/utils';
14
19
  import { HexToUint8Array } from '@/utils/buffer';
15
20
  import { BatchObjectOptions, getAllOwnedObjects } from '@/utils/iter/object';
16
21
 
17
22
  export class MSafeAccount {
18
- public multisigManager: MultisigAccountManager;
23
+ public multiSig: MultiSigAccount;
19
24
 
20
25
  private coinHelper: CoinHelper;
21
26
 
22
27
  constructor(
23
28
  public readonly globals: MSafeGlobals,
24
- public readonly info: MSafeAccountInfo,
29
+ public readonly info: IMSafeConfig,
25
30
  ) {
26
- this.multisigManager = new MultisigAccountManager({
31
+ this.multiSig = new MultiSigAccount({
27
32
  threshold: info.threshold,
28
- ownersWithWeight: info.ownersWithWeightPK,
33
+ ownersWithWeight: info.owners.map((owner) => ({
34
+ address: owner.address,
35
+ weight: owner.weight,
36
+ publicKey: PublicKeySerde.de({ publicKeyEncoded: owner.publicKeyEncoded, schema: owner.schema }),
37
+ })),
29
38
  creationNonce: info.creationNonce,
30
39
  });
31
40
  this.coinHelper = new CoinHelper(this.suiClient);
32
41
  }
33
42
 
34
- static async new(globals: MSafeGlobals, address: string) {
35
- return globals.backend.getMSafeAccountInfo(address);
43
+ static async New(globals: MSafeGlobals, address: string) {
44
+ const info = await globals.backend.getMSafeAccountInfo(address);
45
+ const ms = new MSafeAccount(globals, info);
46
+ if (ms.address !== address) {
47
+ throw new Error('Invalid msafe config with address');
48
+ }
36
49
  }
37
50
 
38
51
  async ownedCoins(): Promise<OwnedCoin[]> {
@@ -81,11 +94,11 @@ export class MSafeAccount {
81
94
  };
82
95
  }
83
96
 
84
- async historyTransaction(paginationOption?: PaginationOption) {
97
+ async historyTransaction(paginationOption?: IPageOptions) {
85
98
  return this.backend.getHistoryTransactions(this.address, paginationOption);
86
99
  }
87
100
 
88
- async futureIntentions(paginationOption?: PaginationOption) {
101
+ async futureIntentions(paginationOption?: IPageOptions) {
89
102
  const paginatedIntentions = await this.backend.getFutureIntentions(this.address, paginationOption);
90
103
  return paginatedIntentions.data;
91
104
  }
@@ -105,7 +118,7 @@ export class MSafeAccount {
105
118
  intention: TxIntention;
106
119
  sequenceNumber: number;
107
120
  }) {
108
- const message = MessageHelper.proposeIntentionMessage({
121
+ const message = SigningMessageHelper.proposeIntentionMessage({
109
122
  msafeAddress: this.address,
110
123
  intention: input.intention,
111
124
  sn: input.sequenceNumber,
@@ -229,14 +242,14 @@ export class MSafeAccount {
229
242
  }
230
243
 
231
244
  const sigs: SerializedSignature[] = [];
232
- for (let i = 0; i < this.info.ownersWithWeightPK.length; i++) {
233
- const owner = this.info.ownersWithWeightPK[i];
234
- const signature = gotSigs.get(owner.publicKey.toSuiAddress());
245
+ for (let i = 0; i < this.info.owners.length; i++) {
246
+ const owner = this.info.owners[i];
247
+ const signature = gotSigs.get(owner.address);
235
248
  if (signature) {
236
249
  sigs.push(signature);
237
250
  }
238
251
  }
239
- const multiSignature = this.multisigManager.combinePartialSignatures(sigs);
252
+ const multiSignature = this.multiSig.combinePartialSignatures(sigs);
240
253
  return this.suiClient.executeTransactionBlock({
241
254
  transactionBlock: HexToUint8Array(payload),
242
255
  signature: multiSignature,
@@ -245,7 +258,7 @@ export class MSafeAccount {
245
258
  }
246
259
 
247
260
  get address() {
248
- return this.info.address;
261
+ return this.multiSig.address;
249
262
  }
250
263
 
251
264
  private get backend() {