@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.
- package/dist/index.cjs +256 -374
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +76 -145
- package/dist/index.d.ts +76 -145
- package/dist/index.js +260 -369
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/backend/BackendImpl.ts +106 -111
- package/src/backend/interface.ts +24 -14
- package/src/core/AddressBookSDK.ts +4 -5
- package/src/core/CreateHelper.ts +18 -32
- package/src/core/InvitationSDK.ts +15 -0
- package/src/core/MSafeAccount.ts +30 -17
- package/src/core/MSafeClient.ts +15 -8
- package/src/core/PublicKeyHelper.ts +3 -0
- package/src/core/index.ts +0 -1
- package/src/globals/MSafeGlobals.ts +1 -1
- package/src/globals/const.ts +17 -45
- package/src/types/create.ts +11 -0
- package/src/types/index.ts +1 -4
- package/src/types/msafe.ts +2 -2
- package/src/utils/crypto.ts +1 -32
- package/src/utils/sui.ts +2 -2
- package/src/backend/CoreDatabase.ts +0 -55
- package/src/backend/PseudoBackend.ts +0 -936
- package/src/core/MessageHelper.ts +0 -95
- package/src/types/address-book.ts +0 -32
- package/src/types/backend.ts +0 -19
- package/src/types/creation.ts +0 -19
- package/src/types/pagination.ts +0 -15
|
@@ -1,14 +1,22 @@
|
|
|
1
1
|
import {
|
|
2
|
-
AuthLoginRequest,
|
|
3
|
-
AuthLoginResponse,
|
|
4
|
-
CreateMSafeAccountInfoRequest,
|
|
5
|
-
GetMSafeAccountInfoResponse,
|
|
6
2
|
HistoryTransaction,
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
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:
|
|
31
|
-
const res = await axios.post<
|
|
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
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
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(
|
|
75
|
+
publicKeyWithSchema ? PublicKeySerde.de(publicKeyWithSchema) : undefined,
|
|
72
76
|
);
|
|
73
77
|
}
|
|
74
78
|
|
|
75
|
-
async getMSafeAccountInfo(msafeAddress: string): Promise<
|
|
76
|
-
const
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
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(
|
|
106
|
-
const
|
|
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 (
|
|
112
|
-
throw new Error(`invalid getPublicKeyBatch return: ${
|
|
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
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
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?:
|
|
152
|
-
): Promise<
|
|
153
|
-
const res = await axios.get<
|
|
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?:
|
|
172
|
-
): Promise<
|
|
173
|
-
const res = await axios.get<
|
|
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:
|
|
207
|
-
const res = await axios.post(`${this.apiURL}/
|
|
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
|
-
|
|
217
|
-
|
|
218
|
-
|
|
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
|
-
|
|
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
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
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?:
|
|
310
|
-
const res = await axios.get<
|
|
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
|
-
|
|
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}` };
|
package/src/backend/interface.ts
CHANGED
|
@@ -1,36 +1,46 @@
|
|
|
1
1
|
import {
|
|
2
|
-
AuthLoginRequest,
|
|
3
|
-
CreateMSafeAccountInfoRequest,
|
|
4
2
|
HistoryTransaction,
|
|
5
|
-
|
|
6
|
-
|
|
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:
|
|
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<
|
|
23
|
-
getUserInfo(
|
|
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?:
|
|
28
|
-
): Promise<
|
|
29
|
-
getFutureIntentions(msafeAddress: string, paginationOption?:
|
|
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:
|
|
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?:
|
|
68
|
+
getAddressBookEntries(pagination?: IPageOptions): Promise<IGetAddressBookResult>;
|
|
59
69
|
updateAddressBook(input: { updates: UpdateAddressBookEntry[]; signature: SerializedSignature }): Promise<void>;
|
|
60
70
|
}
|
|
@@ -1,17 +1,16 @@
|
|
|
1
|
-
import {
|
|
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?:
|
|
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 =
|
|
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
|
}
|
package/src/core/CreateHelper.ts
CHANGED
|
@@ -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 {
|
|
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:
|
|
18
|
+
async calculateMSafeAddress(info: CreateMSafeInfo) {
|
|
26
19
|
const msConfig = await this.reduceCreationInfoToRawConfig(info);
|
|
27
|
-
const ms = new
|
|
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:
|
|
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:
|
|
30
|
+
async submitMSafeCreation(creationInfo: CreateMSafeInfo) {
|
|
41
31
|
const msafeAddress = await this.validateCreateInfo(creationInfo);
|
|
42
32
|
|
|
43
|
-
const signingMessage =
|
|
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:
|
|
51
|
-
const publicKeys = await this.getPublicKeyBatch(info.
|
|
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.
|
|
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.
|
|
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:
|
|
68
|
-
const pks = await this.pkHelper.getPublicKeyBatch(createInfo.
|
|
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
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
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
|
+
}
|
package/src/core/MSafeAccount.ts
CHANGED
|
@@ -1,38 +1,51 @@
|
|
|
1
|
-
import {
|
|
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
|
|
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:
|
|
29
|
+
public readonly info: IMSafeConfig,
|
|
25
30
|
) {
|
|
26
|
-
this.
|
|
31
|
+
this.multiSig = new MultiSigAccount({
|
|
27
32
|
threshold: info.threshold,
|
|
28
|
-
ownersWithWeight: info.
|
|
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
|
|
35
|
-
|
|
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?:
|
|
97
|
+
async historyTransaction(paginationOption?: IPageOptions) {
|
|
85
98
|
return this.backend.getHistoryTransactions(this.address, paginationOption);
|
|
86
99
|
}
|
|
87
100
|
|
|
88
|
-
async futureIntentions(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 =
|
|
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.
|
|
233
|
-
const owner = this.info.
|
|
234
|
-
const signature = gotSigs.get(owner.
|
|
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.
|
|
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.
|
|
261
|
+
return this.multiSig.address;
|
|
249
262
|
}
|
|
250
263
|
|
|
251
264
|
private get backend() {
|