@msafe/sui3-sdk 0.0.11 → 0.0.12-pre-84adfec.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 +721 -685
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +19 -7
- package/dist/index.d.ts +19 -7
- package/dist/index.js +716 -677
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/src/backend/BackendImpl.ts +6 -0
- package/src/backend/PseudoBackend.ts +3 -0
- package/src/backend/interface.ts +3 -0
- package/src/core/MSafeAccount.ts +58 -19
- package/src/core/MessageHelper.ts +6 -2
- package/src/globals/const.ts +2 -0
- package/src/types/msafe.ts +15 -3
package/src/core/MSafeAccount.ts
CHANGED
|
@@ -1,14 +1,21 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
buildIntentionTransaction,
|
|
3
|
+
getIntentionType,
|
|
4
|
+
MSafeAccountInfo,
|
|
5
|
+
MultisigAccountManager,
|
|
6
|
+
} from '@msafe/sui3-utils';
|
|
2
7
|
import { SuiObjectData } from '@mysten/sui.js/client';
|
|
3
8
|
import { SerializedSignature } from '@mysten/sui.js/cryptography';
|
|
9
|
+
import { SuiObjectResponse } from '@mysten/sui.js/src/client';
|
|
4
10
|
import { normalizeStructTag } from '@mysten/sui.js/utils';
|
|
5
11
|
|
|
6
12
|
import { MessageHelper } from '@/core/MessageHelper';
|
|
13
|
+
import { MSAFE_APPLICATION } from '@/globals';
|
|
7
14
|
import { MSafeGlobals } from '@/globals/MSafeGlobals';
|
|
8
15
|
import { IntentionHelper, TxIntention } from '@/transactions/intention';
|
|
9
16
|
import { OwnedCoin } from '@/types/assets';
|
|
10
17
|
import { PaginationOption } from '@/types/backend';
|
|
11
|
-
import { PendingTx } from '@/types/msafe';
|
|
18
|
+
import { PendingTx, SimulationResult } from '@/types/msafe';
|
|
12
19
|
import { CoinHelper } from '@/utils';
|
|
13
20
|
import { HexToUint8Array } from '@/utils/buffer';
|
|
14
21
|
import { BatchObjectOptions, getAllOwnedObjects } from '@/utils/iter/object';
|
|
@@ -53,11 +60,11 @@ export class MSafeAccount {
|
|
|
53
60
|
}
|
|
54
61
|
|
|
55
62
|
async ownedObjects(options?: BatchObjectOptions): Promise<SuiObjectData[]> {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
return this.
|
|
63
|
+
const filterCoinObjectOptions = {
|
|
64
|
+
filter: (objRes: SuiObjectResponse) => !objRes?.data?.type?.startsWith('0x2::coin::Coin'),
|
|
65
|
+
...options,
|
|
66
|
+
};
|
|
67
|
+
return getAllOwnedObjects(this.suiClient, this.address, filterCoinObjectOptions);
|
|
61
68
|
}
|
|
62
69
|
|
|
63
70
|
async pendingTransaction(): Promise<PendingTx | undefined> {
|
|
@@ -68,21 +75,20 @@ export class MSafeAccount {
|
|
|
68
75
|
if (pendings.length === 0) {
|
|
69
76
|
return undefined;
|
|
70
77
|
}
|
|
71
|
-
if (pendings.length === 1) {
|
|
72
|
-
return pendings[0];
|
|
73
|
-
}
|
|
74
78
|
|
|
75
|
-
const
|
|
76
|
-
|
|
77
|
-
pendingTx.rejectPayload = rejectPending.payload;
|
|
78
|
-
pendingTx.rejectVotes = rejectPending.votes;
|
|
79
|
+
const pendingTx = pendings.find((tx) => !tx.isRejectTx);
|
|
80
|
+
const rejectPending = pendings.find((tx) => tx.isRejectTx);
|
|
79
81
|
|
|
80
|
-
return
|
|
82
|
+
return {
|
|
83
|
+
...pendingTx!,
|
|
84
|
+
rejectDigest: rejectPending?.digest ?? '',
|
|
85
|
+
rejectPayload: rejectPending?.payload ?? '',
|
|
86
|
+
rejectVotes: rejectPending?.votes ?? [],
|
|
87
|
+
};
|
|
81
88
|
}
|
|
82
89
|
|
|
83
90
|
async historyTransaction(paginationOption?: PaginationOption) {
|
|
84
|
-
|
|
85
|
-
return paginatedHistoryTransactions.data;
|
|
91
|
+
return this.backend.getHistoryTransactions(this.address, paginationOption);
|
|
86
92
|
}
|
|
87
93
|
|
|
88
94
|
async futureIntentions(paginationOption?: PaginationOption) {
|
|
@@ -99,16 +105,26 @@ export class MSafeAccount {
|
|
|
99
105
|
}
|
|
100
106
|
|
|
101
107
|
async proposeIntention(intention: TxIntention, sequenceNumber: number) {
|
|
102
|
-
const message = MessageHelper.proposeIntentionMessage({
|
|
108
|
+
const message = MessageHelper.proposeIntentionMessage({
|
|
109
|
+
intention,
|
|
110
|
+
sn: sequenceNumber,
|
|
111
|
+
msafeAddress: this.address,
|
|
112
|
+
});
|
|
103
113
|
const signature = await this.wallet.signPersonalMessage({
|
|
104
114
|
messageStr: message,
|
|
105
115
|
});
|
|
116
|
+
|
|
117
|
+
const txType = getIntentionType(intention);
|
|
118
|
+
// TODO get application from common utils
|
|
106
119
|
await this.backend.proposeIntention({
|
|
107
120
|
intention,
|
|
108
121
|
sequenceNumber,
|
|
109
122
|
msafeAddress: this.address,
|
|
110
123
|
userAddress: await this.userAddress(),
|
|
111
124
|
signature: signature.signature,
|
|
125
|
+
application: MSAFE_APPLICATION,
|
|
126
|
+
txType: txType.txType,
|
|
127
|
+
txSubType: txType.txSubType,
|
|
112
128
|
});
|
|
113
129
|
}
|
|
114
130
|
|
|
@@ -152,7 +168,7 @@ export class MSafeAccount {
|
|
|
152
168
|
payloadToReject = pending.payload;
|
|
153
169
|
} else {
|
|
154
170
|
const pendingTx = await this.pendingTransaction();
|
|
155
|
-
if (!pendingTx || pendingTx
|
|
171
|
+
if (!pendingTx || pendingTx.rejectDigest !== '') {
|
|
156
172
|
throw new Error('Already rejected');
|
|
157
173
|
}
|
|
158
174
|
|
|
@@ -181,6 +197,29 @@ export class MSafeAccount {
|
|
|
181
197
|
return this.backend.skipNextFailedIntention({ msafeAddress: this.address, userAddress: await this.userAddress() });
|
|
182
198
|
}
|
|
183
199
|
|
|
200
|
+
async simulateIntention(intention: TxIntention): Promise<SimulationResult> {
|
|
201
|
+
const txb = await buildIntentionTransaction(this.suiClient, intention, this.address);
|
|
202
|
+
if (!txb.blockData.gasConfig.price) {
|
|
203
|
+
const refGas = await this.suiClient.getReferenceGasPrice();
|
|
204
|
+
txb.setGasPrice(refGas);
|
|
205
|
+
}
|
|
206
|
+
const payload = await txb.build({ client: this.suiClient });
|
|
207
|
+
const dryRunResult = await this.suiClient.dryRunTransactionBlock({ transactionBlock: payload });
|
|
208
|
+
|
|
209
|
+
const success = dryRunResult.effects.status.status === 'success';
|
|
210
|
+
const errorMsg = dryRunResult.effects.status.error;
|
|
211
|
+
const gasPrice = BigInt(txb.blockData.gasConfig.price as string);
|
|
212
|
+
const { gasUsed } = dryRunResult.effects;
|
|
213
|
+
|
|
214
|
+
return {
|
|
215
|
+
success,
|
|
216
|
+
errorMsg,
|
|
217
|
+
gasPrice,
|
|
218
|
+
gasUsed,
|
|
219
|
+
dryRunResult,
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
|
|
184
223
|
async executePendingTx(pending: PendingTx) {
|
|
185
224
|
let gotSigs: Map<string, string>;
|
|
186
225
|
let payload: string;
|
|
@@ -30,11 +30,12 @@ export class MessageHelper {
|
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
static proposeIntentionMessage(data: ProposeIntentionData) {
|
|
33
|
-
const { intention, sn } = data;
|
|
33
|
+
const { msafeAddress, intention, sn } = data;
|
|
34
34
|
const intentionData = IntentionHelper.ser(intention);
|
|
35
35
|
const msg: ProposeIntentionMessage = {
|
|
36
36
|
intentionData,
|
|
37
37
|
sequenceNumber: sn,
|
|
38
|
+
msafeAddress,
|
|
38
39
|
};
|
|
39
40
|
return JSON.stringify(msg);
|
|
40
41
|
}
|
|
@@ -49,8 +50,9 @@ export class MessageHelper {
|
|
|
49
50
|
) {
|
|
50
51
|
throw new Error('Invalid intention data');
|
|
51
52
|
}
|
|
52
|
-
const { sequenceNumber, intentionData } = de;
|
|
53
|
+
const { msafeAddress, sequenceNumber, intentionData } = de;
|
|
53
54
|
return {
|
|
55
|
+
msafeAddress,
|
|
54
56
|
sn: sequenceNumber,
|
|
55
57
|
intention: IntentionHelper.de(intentionData),
|
|
56
58
|
};
|
|
@@ -81,11 +83,13 @@ export class MessageHelper {
|
|
|
81
83
|
}
|
|
82
84
|
|
|
83
85
|
export interface ProposeIntentionData {
|
|
86
|
+
msafeAddress: string;
|
|
84
87
|
intention: TxIntention;
|
|
85
88
|
sn: number;
|
|
86
89
|
}
|
|
87
90
|
|
|
88
91
|
export interface ProposeIntentionMessage {
|
|
92
|
+
msafeAddress: string;
|
|
89
93
|
intentionData: string;
|
|
90
94
|
sequenceNumber: number;
|
|
91
95
|
}
|
package/src/globals/const.ts
CHANGED
|
@@ -53,6 +53,8 @@ export const DEV_DATABASE_CONFIG: DBConfig = {
|
|
|
53
53
|
logging: false,
|
|
54
54
|
};
|
|
55
55
|
|
|
56
|
+
export const MSAFE_APPLICATION = 'msafe';
|
|
57
|
+
|
|
56
58
|
export const TESTNET_RPC_URL = 'https://sui-testnet.blockvision.org/v1/2Sgk89ivT64MnKdcGzjmyjY2ndD';
|
|
57
59
|
export const MAINNET_RPC_URL = 'https://sui-mainnet.blockvision.org/v1/2Sgk7NPvqkd7mESYkxF01yX15l7';
|
|
58
60
|
|
package/src/types/msafe.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { GasCostSummary, DryRunTransactionBlockResponse } from '@mysten/sui.js/client';
|
|
2
|
+
|
|
1
3
|
import { TxIntention } from '@/transactions/intention';
|
|
2
4
|
|
|
3
5
|
export interface PendingTx {
|
|
@@ -10,9 +12,9 @@ export interface PendingTx {
|
|
|
10
12
|
createdAt: Date;
|
|
11
13
|
sequenceNumber: number;
|
|
12
14
|
votes: PendingVote[];
|
|
13
|
-
rejectDigest
|
|
14
|
-
rejectPayload
|
|
15
|
-
rejectVotes
|
|
15
|
+
rejectDigest: string;
|
|
16
|
+
rejectPayload: string;
|
|
17
|
+
rejectVotes: PendingVote[];
|
|
16
18
|
}
|
|
17
19
|
|
|
18
20
|
export interface PendingVote {
|
|
@@ -62,3 +64,13 @@ export interface FutureIntention {
|
|
|
62
64
|
statusRemark?: string;
|
|
63
65
|
createdAt: Date;
|
|
64
66
|
}
|
|
67
|
+
|
|
68
|
+
export interface SimulationResult {
|
|
69
|
+
success: boolean;
|
|
70
|
+
errorMsg?: string;
|
|
71
|
+
// gas price for the simulation
|
|
72
|
+
gasPrice: bigint;
|
|
73
|
+
// detailed gas cost summary
|
|
74
|
+
gasUsed: GasCostSummary;
|
|
75
|
+
dryRunResult: DryRunTransactionBlockResponse;
|
|
76
|
+
}
|