@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.
- package/dist/index.cjs +267 -373
- 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 +271 -366
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/backend/BackendImpl.ts +123 -110
- 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 +25 -17
- package/src/core/MSafeClient.ts +22 -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,23 @@
|
|
|
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,
|
|
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:
|
|
31
|
-
const res = await axios.post<
|
|
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
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
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(
|
|
76
|
+
publicKeyWithSchema ? PublicKeySerde.de(publicKeyWithSchema) : undefined,
|
|
72
77
|
);
|
|
73
78
|
}
|
|
74
79
|
|
|
75
|
-
async getMSafeAccountInfo(msafeAddress: string): Promise<
|
|
76
|
-
const
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
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(
|
|
106
|
-
const
|
|
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 (
|
|
112
|
-
throw new Error(`invalid getPublicKeyBatch return: ${
|
|
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
|
-
|
|
117
|
-
|
|
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?:
|
|
152
|
-
): Promise<
|
|
153
|
-
const res = await axios.get<
|
|
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?:
|
|
172
|
-
): Promise<
|
|
173
|
-
const res = await axios.get<
|
|
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:
|
|
207
|
-
const res = await axios.post(`${this.apiURL}/
|
|
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
|
-
|
|
217
|
-
|
|
218
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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);
|
|
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?:
|
|
310
|
-
const res = await axios.get<
|
|
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
|
-
|
|
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
|
}
|
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
|
+
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:
|
|
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<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?:
|
|
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 { 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
|
+
}
|
package/src/core/MSafeAccount.ts
CHANGED
|
@@ -1,38 +1,46 @@
|
|
|
1
|
-
import {
|
|
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
|
|
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:
|
|
28
|
+
public readonly info: IMSafeConfig,
|
|
25
29
|
) {
|
|
26
|
-
this.
|
|
30
|
+
this.multiSig = new MultiSigAccount({
|
|
27
31
|
threshold: info.threshold,
|
|
28
|
-
ownersWithWeight: info.
|
|
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
|
|
35
|
-
|
|
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?:
|
|
92
|
+
async historyTransaction(paginationOption?: IPageOptions) {
|
|
85
93
|
return this.backend.getHistoryTransactions(this.address, paginationOption);
|
|
86
94
|
}
|
|
87
95
|
|
|
88
|
-
async futureIntentions(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 =
|
|
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.
|
|
233
|
-
const owner = this.info.
|
|
234
|
-
const signature = gotSigs.get(owner.
|
|
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.
|
|
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.
|
|
256
|
+
return this.multiSig.address;
|
|
249
257
|
}
|
|
250
258
|
|
|
251
259
|
private get backend() {
|