@msafe/sui3-sdk 0.0.13 → 0.0.15-pre-3144325.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,14 +1,23 @@
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,
20
+ IMSafeConfig,
12
21
  } from '@msafe/sui3-utils';
13
22
  import { SerializedSignature } from '@mysten/sui.js/cryptography';
14
23
  import { PublicKey } from '@mysten/sui.js/src/cryptography';
@@ -16,19 +25,15 @@ import axios from 'axios';
16
25
 
17
26
  import { IBackend } from '@/backend/interface';
18
27
  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
28
  import { FutureIntention, PendingTx, ProposeIntention } from '@/types/msafe';
23
- import { PublicKeySerde } from '@/utils/crypto';
24
29
 
25
30
  export class BackendImpl implements IBackend {
26
31
  private _token: JWTToken;
27
32
 
28
33
  constructor(private readonly apiURL: string) {}
29
34
 
30
- async authSign(input: AuthLoginRequest): Promise<JWTToken> {
31
- const res = await axios.post<AuthLoginResponse>(`${this.apiURL}/auth/login`, input);
35
+ async authSign(input: IAuthLoginReq): Promise<JWTToken> {
36
+ const res = await axios.post<IAuthLoginResp>(`${this.apiURL}/auth/login`, input);
32
37
  // TODO unify response struct
33
38
  if (res.status !== 200 && res.status !== 201) {
34
39
  throw new Error(`invalid authSign return: ${res}`);
@@ -55,87 +60,83 @@ export class BackendImpl implements IBackend {
55
60
  }
56
61
 
57
62
  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
- );
63
+ const query: IGetPublicKeyBatchQuery = {
64
+ userAddressList: addresses,
65
+ };
66
+ const res = await axios.get<IGetPublicKeyBatchResp>(`${this.apiURL}/user/public-keys`, {
67
+ params: query,
68
+ headers: this.headers(),
69
+ });
70
+
65
71
  // TODO unify response struct
66
72
  if (res.status !== 200 && res.status !== 201) {
67
73
  throw new Error(`invalid getPublicKeyBatch return: ${res}`);
68
74
  }
69
-
70
75
  return res.data?.map((publicKeyWithSchema) =>
71
- publicKeyWithSchema ? PublicKeySerde.de({ ...publicKeyWithSchema }) : undefined,
76
+ publicKeyWithSchema ? PublicKeySerde.de(publicKeyWithSchema) : undefined,
72
77
  );
73
78
  }
74
79
 
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
-
80
+ async getMSafeAccountInfo(msafeAddress: string): Promise<IMSafeConfig> {
81
+ const q: IGetMSafeQuery = {
82
+ msafeAddress,
83
+ };
84
+ const res = await axios.get<IMSafeInfoResp>(`${this.apiURL}/msafe`, {
85
+ params: q,
86
+ headers: this.headers(),
87
+ });
83
88
  // TODO unify response struct
84
89
  if (res.status !== 200 && res.status !== 201) {
85
90
  throw new Error(`invalid getPublicKeyBatch return: ${res}`);
86
91
  }
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
- };
92
+ return BackendImpl.toMSafeConfig(res.data);
103
93
  }
104
94
 
105
- async getUserInfo(userAddress: string): Promise<UserWithOwnedMSafe> {
106
- const res = await axios.get<UserWithOwnedMSafeResponse>(`${this.apiURL}/account/user/${userAddress}`, {
95
+ async getUserInfo(): Promise<IUserInfoResp> {
96
+ const userRes = await axios.get<IUserInfoResp>(`${this.apiURL}/user`, {
107
97
  headers: this.headers(),
108
98
  });
109
-
110
99
  // TODO unify response struct
111
- if (res.status !== 200 && res.status !== 201) {
112
- throw new Error(`invalid getPublicKeyBatch return: ${res}`);
100
+ if (userRes.status !== 200 && userRes.status !== 201) {
101
+ throw new Error(`invalid getPublicKeyBatch return: ${userRes}`);
113
102
  }
103
+ return userRes.data;
104
+ }
114
105
 
106
+ async getOwnedMSafeByStatus(input: {
107
+ status?: UserMSafeStatus;
108
+ pagination?: IPageOptions;
109
+ }): Promise<IPagedResult<IMSafeConfig>> {
110
+ const q: IGetMSafesQuery = {
111
+ status: input.status ?? UserMSafeStatus.active,
112
+ ...(input.pagination
113
+ ? {
114
+ page: input.pagination.page.toString(),
115
+ limit: input.pagination.limit.toString(),
116
+ }
117
+ : {}),
118
+ };
119
+ const res = await axios.get<IPagedResult<IMSafeInfoResp>>(`${this.apiURL}/msafe/owned`, {
120
+ params: q,
121
+ headers: this.headers(),
122
+ });
123
+ if (res.status !== 200 && res.status !== 201) {
124
+ throw new Error(`invalid getOwnedMSafeByStatus return: ${res}`);
125
+ }
115
126
  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
- ),
127
+ data: res.data.data.map(BackendImpl.toMSafeConfig),
128
+ meta: res.data.meta,
136
129
  };
137
130
  }
138
131
 
132
+ async updateMSafeStatus(input: { msafeAddress: string; status: UserMSafeStatus }): Promise<void> {
133
+ const p: IUpdateMSafeStatusReq = input;
134
+ const res = await axios.post(`${this.apiURL}/msafe/status`, p, { headers: this.headers() });
135
+ if (res.status !== 200 && res.status !== 201) {
136
+ throw new Error(`Invalid updateMSafeStatus return: ${res}`);
137
+ }
138
+ }
139
+
139
140
  async getPendingTransactions(msafeAddress: string): Promise<PendingTx[]> {
140
141
  const res = await axios.get<PendingTx[]>(`${this.apiURL}/transaction/pending/${msafeAddress}`, {
141
142
  headers: this.headers(),
@@ -148,9 +149,9 @@ export class BackendImpl implements IBackend {
148
149
 
149
150
  async getHistoryTransactions(
150
151
  msafeAddress: string,
151
- paginationOption?: PaginationOption,
152
- ): Promise<PagedResult<HistoryTransaction>> {
153
- const res = await axios.get<PagedResult<HistoryTransaction>>(
152
+ paginationOption?: IPageOptions,
153
+ ): Promise<IPagedResult<HistoryTransaction>> {
154
+ const res = await axios.get<IPagedResult<HistoryTransaction>>(
154
155
  `${this.apiURL}/transaction/history?address=${msafeAddress}`,
155
156
  {
156
157
  params: {
@@ -168,9 +169,9 @@ export class BackendImpl implements IBackend {
168
169
 
169
170
  async getFutureIntentions(
170
171
  msafeAddress: string,
171
- paginationOption?: PaginationOption,
172
- ): Promise<PagedResult<FutureIntention>> {
173
- const res = await axios.get<PagedResult<FutureIntention>>(`${this.apiURL}/transaction/intention/${msafeAddress}`, {
172
+ paginationOption?: IPageOptions,
173
+ ): Promise<IPagedResult<FutureIntention>> {
174
+ const res = await axios.get<IPagedResult<FutureIntention>>(`${this.apiURL}/transaction/intention/${msafeAddress}`, {
174
175
  params: {
175
176
  page: paginationOption?.page,
176
177
  limit: paginationOption?.limit,
@@ -203,8 +204,8 @@ export class BackendImpl implements IBackend {
203
204
  return res.data;
204
205
  }
205
206
 
206
- async createMSafeAccount(input: CreateMSafeAccountInfoRequest): Promise<void> {
207
- const res = await axios.post(`${this.apiURL}/account`, input, {
207
+ async createMSafeAccount(input: ICreateMSafeReq): Promise<void> {
208
+ const res = await axios.post(`${this.apiURL}/msafe/create`, input, {
208
209
  headers: this.headers(),
209
210
  });
210
211
  if (res.status !== 200 && res.status !== 201) {
@@ -213,24 +214,23 @@ export class BackendImpl implements IBackend {
213
214
  }
214
215
 
215
216
  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);
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}`);
223
220
  }
224
221
  }
225
222
 
226
223
  // TODO later
227
- async proposePendingTransaction(input: {
224
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
225
+ async proposePendingTransaction(_input: {
228
226
  intention: TxIntention;
229
227
  userAddress: string;
230
228
  msafeAddress: string;
231
229
  digest: string;
232
230
  signature: SerializedSignature;
233
- }): Promise<void> {}
231
+ }): Promise<void> {
232
+ return undefined;
233
+ }
234
234
 
235
235
  async rejectCurrentTx(input: {
236
236
  userAddress: string;
@@ -238,23 +238,19 @@ export class BackendImpl implements IBackend {
238
238
  digest: string;
239
239
  signature: SerializedSignature;
240
240
  }) {
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);
241
+ const res = await axios.post(
242
+ `${this.apiURL}/transaction/pending/reject`,
243
+ {
244
+ address: input.msafeAddress,
245
+ digest: input.digest,
246
+ signature: input.signature,
247
+ },
248
+ {
249
+ headers: this.headers(),
250
+ },
251
+ );
252
+ if (res.status !== 200 && res.status !== 201) {
253
+ throw new Error(`invalid voteForTransaction return: ${res}`);
258
254
  }
259
255
  }
260
256
 
@@ -306,8 +302,8 @@ export class BackendImpl implements IBackend {
306
302
  }
307
303
  }
308
304
 
309
- async getAddressBookEntries(pagination?: PaginationOption): Promise<GetAddressBookResult> {
310
- const res = await axios.get<GetAddressBookResult>(`${this.apiURL}/address-book`, {
305
+ async getAddressBookEntries(pagination?: IPageOptions): Promise<IGetAddressBookResult> {
306
+ const res = await axios.get<IGetAddressBookResult>(`${this.apiURL}/address-book`, {
311
307
  headers: this.headers(),
312
308
  params: pagination,
313
309
  });
@@ -324,9 +320,26 @@ export class BackendImpl implements IBackend {
324
320
  }
325
321
  }
326
322
 
327
- async processExecutedTransaction(digest: string) {}
323
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
324
+ async processExecutedTransaction(_digest: string) {
325
+ return undefined;
326
+ }
328
327
 
329
328
  private headers(token?: string) {
330
329
  return { Authorization: `Bearer ${token || this._token}` };
331
330
  }
331
+
332
+ private static toMSafeConfig(resp: IMSafeInfoResp): IMSafeConfig {
333
+ return {
334
+ ...resp,
335
+ owners: resp.owners.map((owner) => ({
336
+ address: owner.address,
337
+ weight: owner.weight,
338
+ publicKey: PublicKeySerde.de({
339
+ publicKeyEncoded: owner.publicKeyEncoded,
340
+ schema: owner.schema,
341
+ }),
342
+ })),
343
+ };
344
+ }
332
345
  }
@@ -1,36 +1,46 @@
1
1
  import {
2
- AuthLoginRequest,
3
- CreateMSafeAccountInfoRequest,
4
2
  HistoryTransaction,
5
- MSafeAccountInfo,
6
- UserWithOwnedMSafe,
3
+ IAuthLoginReq,
4
+ ICreateMSafeReq,
5
+ IPageOptions,
6
+ IUserInfoResp,
7
+ UserMSafeStatus,
8
+ IGetAddressBookResult,
9
+ IPagedResult,
10
+ UpdateAddressBookEntry,
11
+ JWTToken,
12
+ IMSafeConfig,
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<IMSafeConfig>;
27
+ getUserInfo(): Promise<IUserInfoResp>;
28
+ getOwnedMSafeByStatus(input: {
29
+ status?: UserMSafeStatus;
30
+ pagination?: IPageOptions;
31
+ }): Promise<IPagedResult<IMSafeConfig>>;
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 { IMSafeConfig, IPagedResult, 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): Promise<IPagedResult<IMSafeConfig>> {
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,46 @@
1
- import { buildIntentionTransaction, MSafeAccountInfo, MultisigAccountManager } from '@msafe/sui3-utils';
1
+ import {
2
+ buildIntentionTransaction,
3
+ IMSafeConfig,
4
+ IPageOptions,
5
+ MultiSigAccount,
6
+ SigningMessageHelper,
7
+ } from '@msafe/sui3-utils';
2
8
  import { SuiObjectData } from '@mysten/sui.js/client';
3
9
  import { SerializedSignature } from '@mysten/sui.js/cryptography';
4
10
  import { SuiObjectResponse } from '@mysten/sui.js/src/client';
5
11
  import { normalizeStructTag } from '@mysten/sui.js/utils';
6
12
 
7
- import { MessageHelper } from '@/core/MessageHelper';
8
13
  import { MSafeGlobals } from '@/globals/MSafeGlobals';
9
14
  import { IntentionHelper, TxIntention } from '@/transactions/intention';
10
15
  import { OwnedCoin } from '@/types/assets';
11
- import { PaginationOption } from '@/types/backend';
12
16
  import { PendingTx, SimulationResult } from '@/types/msafe';
13
17
  import { CoinHelper } from '@/utils';
14
18
  import { HexToUint8Array } from '@/utils/buffer';
15
19
  import { BatchObjectOptions, getAllOwnedObjects } from '@/utils/iter/object';
16
20
 
17
21
  export class MSafeAccount {
18
- public multisigManager: MultisigAccountManager;
22
+ public multiSig: MultiSigAccount;
19
23
 
20
24
  private coinHelper: CoinHelper;
21
25
 
22
26
  constructor(
23
27
  public readonly globals: MSafeGlobals,
24
- public readonly info: MSafeAccountInfo,
28
+ public readonly info: IMSafeConfig,
25
29
  ) {
26
- this.multisigManager = new MultisigAccountManager({
30
+ this.multiSig = new MultiSigAccount({
27
31
  threshold: info.threshold,
28
- ownersWithWeight: info.ownersWithWeightPK,
32
+ ownersWithWeight: info.owners,
29
33
  creationNonce: info.creationNonce,
30
34
  });
31
35
  this.coinHelper = new CoinHelper(this.suiClient);
32
36
  }
33
37
 
34
- static async new(globals: MSafeGlobals, address: string) {
35
- return globals.backend.getMSafeAccountInfo(address);
38
+ static async New(globals: MSafeGlobals, address: string) {
39
+ const info = await globals.backend.getMSafeAccountInfo(address);
40
+ const ms = new MSafeAccount(globals, info);
41
+ if (ms.address !== address) {
42
+ throw new Error('Invalid msafe config with address');
43
+ }
36
44
  }
37
45
 
38
46
  async ownedCoins(): Promise<OwnedCoin[]> {
@@ -81,11 +89,11 @@ export class MSafeAccount {
81
89
  };
82
90
  }
83
91
 
84
- async historyTransaction(paginationOption?: PaginationOption) {
92
+ async historyTransaction(paginationOption?: IPageOptions) {
85
93
  return this.backend.getHistoryTransactions(this.address, paginationOption);
86
94
  }
87
95
 
88
- async futureIntentions(paginationOption?: PaginationOption) {
96
+ async futureIntentions(paginationOption?: IPageOptions) {
89
97
  const paginatedIntentions = await this.backend.getFutureIntentions(this.address, paginationOption);
90
98
  return paginatedIntentions.data;
91
99
  }
@@ -105,7 +113,7 @@ export class MSafeAccount {
105
113
  intention: TxIntention;
106
114
  sequenceNumber: number;
107
115
  }) {
108
- const message = MessageHelper.proposeIntentionMessage({
116
+ const message = SigningMessageHelper.proposeIntentionMessage({
109
117
  msafeAddress: this.address,
110
118
  intention: input.intention,
111
119
  sn: input.sequenceNumber,
@@ -229,14 +237,14 @@ export class MSafeAccount {
229
237
  }
230
238
 
231
239
  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());
240
+ for (let i = 0; i < this.info.owners.length; i++) {
241
+ const owner = this.info.owners[i];
242
+ const signature = gotSigs.get(owner.address);
235
243
  if (signature) {
236
244
  sigs.push(signature);
237
245
  }
238
246
  }
239
- const multiSignature = this.multisigManager.combinePartialSignatures(sigs);
247
+ const multiSignature = this.multiSig.combinePartialSignatures(sigs);
240
248
  return this.suiClient.executeTransactionBlock({
241
249
  transactionBlock: HexToUint8Array(payload),
242
250
  signature: multiSignature,
@@ -245,7 +253,7 @@ export class MSafeAccount {
245
253
  }
246
254
 
247
255
  get address() {
248
- return this.info.address;
256
+ return this.multiSig.address;
249
257
  }
250
258
 
251
259
  private get backend() {