@msafe/sui3-sdk 1.0.14 → 1.0.17
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 +615 -556
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +76 -2
- package/dist/index.d.ts +76 -2
- package/dist/index.js +631 -555
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/core/MSafeAccount.ts +16 -1
- package/src/simulate/simulator.ts +21 -13
- package/src/utils/coinReservation.ts +65 -0
- package/src/utils/gasFunding.ts +309 -0
- package/src/utils/index.ts +2 -0
- package/src/utils/transaction.ts +16 -3
package/dist/index.js
CHANGED
|
@@ -1,14 +1,11 @@
|
|
|
1
|
-
var __defProp = Object.defineProperty;
|
|
2
|
-
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
3
|
-
|
|
4
1
|
// src/core/CreateHelper.ts
|
|
5
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
isSameAddress,
|
|
4
|
+
MultiSigAccount,
|
|
5
|
+
PublicKeySerde,
|
|
6
|
+
SigningMessageHelper
|
|
7
|
+
} from "@msafe/sui3-utils";
|
|
6
8
|
var CreateHelper = class {
|
|
7
|
-
static {
|
|
8
|
-
__name(this, "CreateHelper");
|
|
9
|
-
}
|
|
10
|
-
globals;
|
|
11
|
-
pkHelper;
|
|
12
9
|
constructor(globals, pkHelper) {
|
|
13
10
|
this.globals = globals;
|
|
14
11
|
this.pkHelper = pkHelper;
|
|
@@ -26,13 +23,13 @@ var CreateHelper = class {
|
|
|
26
23
|
return this.calculateMSafeAddress(createInfo);
|
|
27
24
|
}
|
|
28
25
|
/**
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
26
|
+
* Add user manually added public key for an address. If user input the public key with
|
|
27
|
+
* extra signature scheme flag, the scheme value will be automatically fixed.
|
|
28
|
+
*
|
|
29
|
+
* @param address
|
|
30
|
+
* @param pkEncoded
|
|
31
|
+
* @throws error if the public key does not match
|
|
32
|
+
*/
|
|
36
33
|
addPublicKey(address, pkEncoded) {
|
|
37
34
|
const pk = PublicKeySerde.de(pkEncoded);
|
|
38
35
|
if (!isSameAddress(address, pk.toSuiAddress())) {
|
|
@@ -43,9 +40,7 @@ var CreateHelper = class {
|
|
|
43
40
|
async submitMSafeCreation(creationInfo) {
|
|
44
41
|
const msafeAddress = await this.validateCreateInfo(creationInfo);
|
|
45
42
|
const signingMessage = SigningMessageHelper.createMSafeMessage(msafeAddress);
|
|
46
|
-
const signature = await this.globals.wallet.signPersonalMessage({
|
|
47
|
-
messageStr: signingMessage
|
|
48
|
-
});
|
|
43
|
+
const signature = await this.globals.wallet.signPersonalMessage({ messageStr: signingMessage });
|
|
49
44
|
await this.submitToBackend(creationInfo, signature.signature);
|
|
50
45
|
return msafeAddress;
|
|
51
46
|
}
|
|
@@ -76,7 +71,9 @@ var CreateHelper = class {
|
|
|
76
71
|
})),
|
|
77
72
|
threshold: createInfo.threshold,
|
|
78
73
|
name: createInfo.name,
|
|
74
|
+
// name validation is deferred to backend
|
|
79
75
|
description: createInfo.description,
|
|
76
|
+
// description validation is deferred to backend
|
|
80
77
|
creationNonce: createInfo.creationNonce,
|
|
81
78
|
signature
|
|
82
79
|
});
|
|
@@ -84,15 +81,14 @@ var CreateHelper = class {
|
|
|
84
81
|
};
|
|
85
82
|
|
|
86
83
|
// src/core/MSafeClient.ts
|
|
87
|
-
import {
|
|
84
|
+
import {
|
|
85
|
+
SigningMessageHelper as SigningMessageHelper4,
|
|
86
|
+
UserMSafeStatus as UserMSafeStatus2
|
|
87
|
+
} from "@msafe/sui3-utils";
|
|
88
88
|
|
|
89
89
|
// src/core/AddressBookSDK.ts
|
|
90
90
|
import { SigningMessageHelper as SigningMessageHelper2 } from "@msafe/sui3-utils";
|
|
91
91
|
var AddressBookSDK = class {
|
|
92
|
-
static {
|
|
93
|
-
__name(this, "AddressBookSDK");
|
|
94
|
-
}
|
|
95
|
-
globals;
|
|
96
92
|
constructor(globals) {
|
|
97
93
|
this.globals = globals;
|
|
98
94
|
}
|
|
@@ -101,192 +97,130 @@ var AddressBookSDK = class {
|
|
|
101
97
|
}
|
|
102
98
|
async update(updates) {
|
|
103
99
|
const messageStr = SigningMessageHelper2.updateAddressBookMessage(updates);
|
|
104
|
-
const sig = await this.globals.wallet.signPersonalMessage({
|
|
105
|
-
|
|
106
|
-
});
|
|
107
|
-
return this.globals.backend.updateAddressBook({
|
|
108
|
-
updates,
|
|
109
|
-
signature: sig.signature
|
|
110
|
-
});
|
|
100
|
+
const sig = await this.globals.wallet.signPersonalMessage({ messageStr });
|
|
101
|
+
return this.globals.backend.updateAddressBook({ updates, signature: sig.signature });
|
|
111
102
|
}
|
|
112
103
|
async getMode() {
|
|
113
104
|
const res = await this.globals.backend.getAddressBookMode();
|
|
114
105
|
return res.mode;
|
|
115
106
|
}
|
|
116
107
|
async setMode(mode) {
|
|
117
|
-
return this.globals.backend.setAddressBookMode({
|
|
118
|
-
mode
|
|
119
|
-
});
|
|
108
|
+
return this.globals.backend.setAddressBookMode({ mode });
|
|
120
109
|
}
|
|
121
110
|
};
|
|
122
111
|
|
|
123
112
|
// src/core/InvitationSDK.ts
|
|
124
113
|
var InvitationSDK = class {
|
|
125
|
-
static {
|
|
126
|
-
__name(this, "InvitationSDK");
|
|
127
|
-
}
|
|
128
|
-
globals;
|
|
129
114
|
constructor(globals) {
|
|
130
115
|
this.globals = globals;
|
|
131
116
|
}
|
|
132
117
|
async getMSafeByStatus(status, pagination) {
|
|
133
|
-
return this.globals.backend.getOwnedMSafeByStatus({
|
|
134
|
-
status,
|
|
135
|
-
pagination
|
|
136
|
-
});
|
|
118
|
+
return this.globals.backend.getOwnedMSafeByStatus({ status, pagination });
|
|
137
119
|
}
|
|
138
120
|
async updateMSafeStatus(msafeAddress, status) {
|
|
139
|
-
return this.globals.backend.updateMSafeStatus({
|
|
140
|
-
msafeAddress,
|
|
141
|
-
status
|
|
142
|
-
});
|
|
121
|
+
return this.globals.backend.updateMSafeStatus({ msafeAddress, status });
|
|
143
122
|
}
|
|
144
123
|
};
|
|
145
124
|
|
|
146
125
|
// src/core/MSafeAccount.ts
|
|
147
126
|
import { appHelpers } from "@msafe/sui-app-store";
|
|
148
|
-
import {
|
|
149
|
-
|
|
150
|
-
|
|
127
|
+
import {
|
|
128
|
+
MultiSigAccount as MultiSigAccount2,
|
|
129
|
+
SigningMessageHelper as SigningMessageHelper3,
|
|
130
|
+
TransactionDefaultApplication,
|
|
131
|
+
TransactionSubTypes,
|
|
132
|
+
TransactionType,
|
|
133
|
+
buildRejectTxb,
|
|
134
|
+
isSameAddress as isSameAddress2
|
|
135
|
+
} from "@msafe/sui3-utils";
|
|
136
|
+
import { Transaction as Transaction4 } from "@mysten/sui/transactions";
|
|
137
|
+
import { fromHex as fromHex2, normalizeStructTag as normalizeStructTag3, toHex as toHex2 } from "@mysten/sui/utils";
|
|
151
138
|
import { SUI_MAINNET_CHAIN, SUI_TESTNET_CHAIN } from "@mysten/wallet-standard";
|
|
152
139
|
|
|
153
140
|
// src/simulate/simulator.ts
|
|
141
|
+
import { Transaction as Transaction2 } from "@mysten/sui/transactions";
|
|
142
|
+
|
|
143
|
+
// src/utils/gasFunding.ts
|
|
154
144
|
import { Transaction } from "@mysten/sui/transactions";
|
|
155
|
-
|
|
156
|
-
function formatExecutionError(error) {
|
|
157
|
-
return error.message;
|
|
158
|
-
}
|
|
159
|
-
__name(formatExecutionError, "formatExecutionError");
|
|
160
|
-
function gasObjectToReference(gas) {
|
|
161
|
-
if (!gas?.objectId) {
|
|
162
|
-
throw new Error("Gas object missing from simulation effects");
|
|
163
|
-
}
|
|
164
|
-
const version = gas.outputVersion ?? gas.inputVersion ?? "0";
|
|
165
|
-
const digest = gas.outputDigest ?? gas.inputDigest ?? "";
|
|
166
|
-
return {
|
|
167
|
-
objectId: gas.objectId,
|
|
168
|
-
version,
|
|
169
|
-
digest
|
|
170
|
-
};
|
|
171
|
-
}
|
|
172
|
-
__name(gasObjectToReference, "gasObjectToReference");
|
|
173
|
-
var Simulator = class {
|
|
174
|
-
static {
|
|
175
|
-
__name(this, "Simulator");
|
|
176
|
-
}
|
|
177
|
-
globals;
|
|
178
|
-
constructor(globals) {
|
|
179
|
-
this.globals = globals;
|
|
180
|
-
}
|
|
181
|
-
async simulate(input) {
|
|
182
|
-
const tx = this.copyTransaction(input.txb);
|
|
183
|
-
const { suiClient } = this.globals;
|
|
184
|
-
const gasPrice = await this.getGasPrice();
|
|
185
|
-
tx.setGasPrice(gasPrice);
|
|
186
|
-
tx.setSender(input.sender);
|
|
187
|
-
let built;
|
|
188
|
-
try {
|
|
189
|
-
built = await tx.build({
|
|
190
|
-
client: suiClient
|
|
191
|
-
});
|
|
192
|
-
} catch (e) {
|
|
193
|
-
const message = e instanceof Error ? e.message : String(e);
|
|
194
|
-
return {
|
|
195
|
-
success: false,
|
|
196
|
-
gasPrice,
|
|
197
|
-
simulationError: message
|
|
198
|
-
};
|
|
199
|
-
}
|
|
200
|
-
let inspectResult;
|
|
201
|
-
try {
|
|
202
|
-
inspectResult = await suiClient.simulateTransaction({
|
|
203
|
-
transaction: built,
|
|
204
|
-
include: {
|
|
205
|
-
effects: true,
|
|
206
|
-
balanceChanges: true,
|
|
207
|
-
events: true,
|
|
208
|
-
objectTypes: true,
|
|
209
|
-
transaction: true,
|
|
210
|
-
bcs: true,
|
|
211
|
-
commandResults: true
|
|
212
|
-
}
|
|
213
|
-
});
|
|
214
|
-
} catch (e) {
|
|
215
|
-
const message = e instanceof Error ? e.message : String(e);
|
|
216
|
-
return {
|
|
217
|
-
success: false,
|
|
218
|
-
gasPrice,
|
|
219
|
-
simulationError: message
|
|
220
|
-
};
|
|
221
|
-
}
|
|
222
|
-
const txRow = inspectResult.Transaction ?? inspectResult.FailedTransaction;
|
|
223
|
-
const { effects } = txRow;
|
|
224
|
-
if (!effects) {
|
|
225
|
-
throw new Error("simulateTransaction did not return effects");
|
|
226
|
-
}
|
|
227
|
-
const success = effects.status.success === true;
|
|
228
|
-
if (!success) {
|
|
229
|
-
const err = effects.status.success === false ? effects.status.error : null;
|
|
230
|
-
return {
|
|
231
|
-
success,
|
|
232
|
-
gasPrice,
|
|
233
|
-
response: inspectResult,
|
|
234
|
-
simulationError: err ? formatExecutionError(err) : "Simulation failed"
|
|
235
|
-
};
|
|
236
|
-
}
|
|
237
|
-
const gasBudget = this.toGasBudget(effects.gasUsed, gasPrice);
|
|
238
|
-
return {
|
|
239
|
-
success,
|
|
240
|
-
gasPrice,
|
|
241
|
-
gasObject: gasObjectToReference(effects.gasObject),
|
|
242
|
-
gasUsed: effects.gasUsed,
|
|
243
|
-
gasBudget,
|
|
244
|
-
response: inspectResult
|
|
245
|
-
};
|
|
246
|
-
}
|
|
247
|
-
async getGasPrice() {
|
|
248
|
-
const { referenceGasPrice } = await this.globals.suiClient.getReferenceGasPrice();
|
|
249
|
-
return BigInt(referenceGasPrice);
|
|
250
|
-
}
|
|
251
|
-
toGasBudget(gasUsed, gasPrice) {
|
|
252
|
-
const { computationCost, storageCost, storageRebate } = gasUsed;
|
|
253
|
-
const safeOverhead = GAS_SAFE_OVERHEAD * gasPrice;
|
|
254
|
-
const baseComputationCostWithOverhead = BigInt(computationCost) + safeOverhead;
|
|
255
|
-
const gasBudget = baseComputationCostWithOverhead + BigInt(storageCost) - BigInt(storageRebate);
|
|
256
|
-
return gasBudget > baseComputationCostWithOverhead ? gasBudget : baseComputationCostWithOverhead;
|
|
257
|
-
}
|
|
258
|
-
copyTransaction(tx) {
|
|
259
|
-
return Transaction.from(tx.serialize());
|
|
260
|
-
}
|
|
261
|
-
};
|
|
145
|
+
import { normalizeSuiObjectId } from "@mysten/sui/utils";
|
|
262
146
|
|
|
263
|
-
// src/utils/
|
|
264
|
-
import {
|
|
265
|
-
|
|
266
|
-
|
|
147
|
+
// src/utils/coinReservation.ts
|
|
148
|
+
import { bcs, TypeTagSerializer } from "@mysten/sui/bcs";
|
|
149
|
+
import { deriveDynamicFieldID, fromBase58, fromHex, normalizeSuiAddress, toBase58, toHex } from "@mysten/sui/utils";
|
|
150
|
+
var SUI_ACCUMULATOR_ROOT_OBJECT_ID = normalizeSuiAddress("0xacc");
|
|
151
|
+
var ACCUMULATOR_KEY_TYPE_TAG = TypeTagSerializer.parseFromStr(
|
|
152
|
+
"0x2::accumulator::Key<0x2::balance::Balance<0x2::sui::SUI>>"
|
|
153
|
+
);
|
|
154
|
+
var COIN_RESERVATION_MAGIC = new Uint8Array([
|
|
155
|
+
172,
|
|
156
|
+
172,
|
|
157
|
+
172,
|
|
158
|
+
172,
|
|
159
|
+
172,
|
|
160
|
+
172,
|
|
161
|
+
172,
|
|
162
|
+
172,
|
|
163
|
+
172,
|
|
164
|
+
172,
|
|
165
|
+
172,
|
|
166
|
+
172,
|
|
167
|
+
172,
|
|
168
|
+
172,
|
|
169
|
+
172,
|
|
170
|
+
172,
|
|
171
|
+
172,
|
|
172
|
+
172,
|
|
173
|
+
172,
|
|
174
|
+
172
|
|
175
|
+
]);
|
|
176
|
+
function isCoinReservationDigest(digestBase58) {
|
|
177
|
+
const digestBytes = fromBase58(digestBase58);
|
|
178
|
+
const last20Bytes = digestBytes.slice(12, 32);
|
|
179
|
+
return last20Bytes.every((byte, i) => byte === COIN_RESERVATION_MAGIC[i]);
|
|
267
180
|
}
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
181
|
+
function deriveReservationObjectId(owner, chainIdentifier) {
|
|
182
|
+
const keyBcs = bcs.Address.serialize(owner).toBytes();
|
|
183
|
+
const accumulatorId = deriveDynamicFieldID(SUI_ACCUMULATOR_ROOT_OBJECT_ID, ACCUMULATOR_KEY_TYPE_TAG, keyBcs);
|
|
184
|
+
const accBytes = fromHex(accumulatorId.slice(2));
|
|
185
|
+
const chainBytes = fromBase58(chainIdentifier);
|
|
186
|
+
if (chainBytes.length !== 32) {
|
|
187
|
+
throw new Error(`Invalid chain identifier length: expected 32 bytes, got ${chainBytes.length}`);
|
|
188
|
+
}
|
|
189
|
+
const xored = new Uint8Array(32);
|
|
190
|
+
for (let i = 0; i < 32; i++) {
|
|
191
|
+
xored[i] = accBytes[i] ^ chainBytes[i];
|
|
192
|
+
}
|
|
193
|
+
return `0x${toHex(xored)}`;
|
|
271
194
|
}
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
195
|
+
function createCoinReservationRef(reservedBalance, owner, chainIdentifier, epoch) {
|
|
196
|
+
const digestBytes = new Uint8Array(32);
|
|
197
|
+
const view = new DataView(digestBytes.buffer);
|
|
198
|
+
view.setBigUint64(0, reservedBalance, true);
|
|
199
|
+
const epochNum = Number(epoch);
|
|
200
|
+
if (!Number.isSafeInteger(epochNum) || epochNum < 0 || epochNum > 4294967295) {
|
|
201
|
+
throw new Error(`Epoch ${epoch} out of u32 range for coin reservation digest`);
|
|
202
|
+
}
|
|
203
|
+
view.setUint32(8, epochNum, true);
|
|
204
|
+
digestBytes.set(COIN_RESERVATION_MAGIC, 12);
|
|
205
|
+
return {
|
|
206
|
+
objectId: deriveReservationObjectId(owner, chainIdentifier),
|
|
207
|
+
version: "0",
|
|
208
|
+
digest: toBase58(digestBytes)
|
|
209
|
+
};
|
|
275
210
|
}
|
|
276
|
-
__name(HexToUint8Array, "HexToUint8Array");
|
|
277
211
|
|
|
278
|
-
// src/utils/
|
|
279
|
-
import {
|
|
212
|
+
// src/utils/sui.ts
|
|
213
|
+
import { PublicKeySerde as PublicKeySerde2 } from "@msafe/sui3-utils";
|
|
214
|
+
import { parseSerializedSignature } from "@mysten/sui/cryptography";
|
|
215
|
+
import { SuiGraphQLClient } from "@mysten/sui/graphql";
|
|
216
|
+
import { MultiSigPublicKey } from "@mysten/sui/multisig";
|
|
280
217
|
|
|
281
218
|
// src/utils/format.ts
|
|
282
|
-
import { normalizeSuiAddress, normalizeStructTag as normalizeStructTag2 } from "@mysten/sui/utils";
|
|
219
|
+
import { normalizeSuiAddress as normalizeSuiAddress2, normalizeStructTag as normalizeStructTag2 } from "@mysten/sui/utils";
|
|
283
220
|
|
|
284
221
|
// src/utils/coin.ts
|
|
285
222
|
import { normalizeStructTag } from "@mysten/sui/utils";
|
|
286
223
|
var CoinHelper = class {
|
|
287
|
-
static {
|
|
288
|
-
__name(this, "CoinHelper");
|
|
289
|
-
}
|
|
290
224
|
_client;
|
|
291
225
|
_coinMetaReg;
|
|
292
226
|
constructor(client) {
|
|
@@ -305,17 +239,12 @@ var CoinHelper = class {
|
|
|
305
239
|
return meta;
|
|
306
240
|
}
|
|
307
241
|
async queryCoinMeta(coinType) {
|
|
308
|
-
const res = await this._client.getCoinMetadata({
|
|
309
|
-
coinType
|
|
310
|
-
});
|
|
242
|
+
const res = await this._client.getCoinMetadata({ coinType });
|
|
311
243
|
return res.coinMetadata ?? void 0;
|
|
312
244
|
}
|
|
313
245
|
};
|
|
314
246
|
var COIN_TYPE_ARG_REGEX = /^0x0000000000000000000000000000000000000000000000000000000000000002::coin::Coin<(.+)>$/;
|
|
315
247
|
var Coin = class _Coin {
|
|
316
|
-
static {
|
|
317
|
-
__name(this, "Coin");
|
|
318
|
-
}
|
|
319
248
|
static isCoin(type) {
|
|
320
249
|
if (!type) {
|
|
321
250
|
return false;
|
|
@@ -350,17 +279,14 @@ var Coin = class _Coin {
|
|
|
350
279
|
|
|
351
280
|
// src/utils/format.ts
|
|
352
281
|
var Formatter = class {
|
|
353
|
-
static {
|
|
354
|
-
__name(this, "Formatter");
|
|
355
|
-
}
|
|
356
282
|
static normalizeSuiAddress(addr) {
|
|
357
|
-
return
|
|
283
|
+
return normalizeSuiAddress2(addr);
|
|
358
284
|
}
|
|
359
285
|
static normalizeStructTag(struct) {
|
|
360
286
|
return normalizeStructTag2(struct);
|
|
361
287
|
}
|
|
362
288
|
static isSuiAddressEqual(addr1, addr2) {
|
|
363
|
-
return
|
|
289
|
+
return normalizeSuiAddress2(addr1) === normalizeSuiAddress2(addr2);
|
|
364
290
|
}
|
|
365
291
|
static isSuiStructEqual(struct1, struct2) {
|
|
366
292
|
return normalizeStructTag2(struct1) === normalizeStructTag2(struct2);
|
|
@@ -375,55 +301,8 @@ function addPrefix(s, prefix) {
|
|
|
375
301
|
}
|
|
376
302
|
return prefix + s;
|
|
377
303
|
}
|
|
378
|
-
__name(addPrefix, "addPrefix");
|
|
379
|
-
|
|
380
|
-
// src/utils/crypto.ts
|
|
381
|
-
var SignatureVerifier = class _SignatureVerifier {
|
|
382
|
-
static {
|
|
383
|
-
__name(this, "SignatureVerifier");
|
|
384
|
-
}
|
|
385
|
-
static async getPublicKeyFromSignature(input) {
|
|
386
|
-
if (input.messageType === "TransactionBlock") {
|
|
387
|
-
return verifyTransactionSignature(input.message, input.signature);
|
|
388
|
-
}
|
|
389
|
-
return verifyPersonalMessageSignature(input.message, input.signature);
|
|
390
|
-
}
|
|
391
|
-
static async getPublicKeyFromPersonalSignature(input) {
|
|
392
|
-
const message = stringToBuffer(input.messageStr);
|
|
393
|
-
return this.getPublicKeyFromSignature({
|
|
394
|
-
message,
|
|
395
|
-
messageType: "Personal",
|
|
396
|
-
signature: input.signature
|
|
397
|
-
});
|
|
398
|
-
}
|
|
399
|
-
static async verifySignature(input) {
|
|
400
|
-
const publicKey = await _SignatureVerifier.getPublicKeyFromSignature(input);
|
|
401
|
-
return Formatter.isSuiAddressEqual(publicKey.toSuiAddress(), input.targetAddress);
|
|
402
|
-
}
|
|
403
|
-
static async verifyPersonalSignature(input) {
|
|
404
|
-
const message = stringToBuffer(input.messageStr);
|
|
405
|
-
return this.verifySignature({
|
|
406
|
-
message,
|
|
407
|
-
messageType: "Personal",
|
|
408
|
-
signature: input.signature,
|
|
409
|
-
targetAddress: input.targetAddress
|
|
410
|
-
});
|
|
411
|
-
}
|
|
412
|
-
static async verifyTransactionSignature(input) {
|
|
413
|
-
return this.verifySignature({
|
|
414
|
-
messageType: "TransactionBlock",
|
|
415
|
-
message: input.payload,
|
|
416
|
-
signature: input.signature,
|
|
417
|
-
targetAddress: input.targetAddress
|
|
418
|
-
});
|
|
419
|
-
}
|
|
420
|
-
};
|
|
421
304
|
|
|
422
305
|
// src/utils/sui.ts
|
|
423
|
-
import { PublicKeySerde as PublicKeySerde2 } from "@msafe/sui3-utils";
|
|
424
|
-
import { parseSerializedSignature } from "@mysten/sui/cryptography";
|
|
425
|
-
import { SuiGraphQLClient } from "@mysten/sui/graphql";
|
|
426
|
-
import { MultiSigPublicKey } from "@mysten/sui/multisig";
|
|
427
306
|
var SUI_COIN = "0x2::sui::SUI";
|
|
428
307
|
var GRAPHQL_URL_BY_NETWORK = {
|
|
429
308
|
mainnet: "https://sui-mainnet.mystenlabs.com/graphql",
|
|
@@ -432,35 +311,24 @@ var GRAPHQL_URL_BY_NETWORK = {
|
|
|
432
311
|
};
|
|
433
312
|
function graphqlClientForGrpc(suiClient) {
|
|
434
313
|
const url = GRAPHQL_URL_BY_NETWORK[suiClient.network] ?? GRAPHQL_URL_BY_NETWORK.testnet;
|
|
435
|
-
return new SuiGraphQLClient({
|
|
436
|
-
url,
|
|
437
|
-
network: suiClient.network
|
|
438
|
-
});
|
|
314
|
+
return new SuiGraphQLClient({ url, network: suiClient.network });
|
|
439
315
|
}
|
|
440
|
-
__name(graphqlClientForGrpc, "graphqlClientForGrpc");
|
|
441
316
|
function collectSignatureStrings(value) {
|
|
442
317
|
if (typeof value === "string") {
|
|
443
|
-
return [
|
|
444
|
-
value
|
|
445
|
-
];
|
|
318
|
+
return [value];
|
|
446
319
|
}
|
|
447
320
|
if (!value || typeof value !== "object") {
|
|
448
321
|
return [];
|
|
449
322
|
}
|
|
450
323
|
if ("base64" in value && typeof value.base64 === "string") {
|
|
451
|
-
return [
|
|
452
|
-
value.base64
|
|
453
|
-
];
|
|
324
|
+
return [value.base64];
|
|
454
325
|
}
|
|
455
326
|
if ("scheme" in value && "base64" in value) {
|
|
456
327
|
const b64 = value.base64;
|
|
457
|
-
return typeof b64 === "string" ? [
|
|
458
|
-
b64
|
|
459
|
-
] : [];
|
|
328
|
+
return typeof b64 === "string" ? [b64] : [];
|
|
460
329
|
}
|
|
461
330
|
return [];
|
|
462
331
|
}
|
|
463
|
-
__name(collectSignatureStrings, "collectSignatureStrings");
|
|
464
332
|
var TX_SIG_QUERY = `
|
|
465
333
|
query PublicKeyTxSigs($sender: SuiAddress!, $first: Int!) {
|
|
466
334
|
transactions(first: $first, filter: { sentAddress: $sender }) {
|
|
@@ -476,10 +344,7 @@ async function getPublicKeyFromChain(suiClient, address) {
|
|
|
476
344
|
try {
|
|
477
345
|
const res = await graphql.query({
|
|
478
346
|
query: TX_SIG_QUERY,
|
|
479
|
-
variables: {
|
|
480
|
-
sender: address,
|
|
481
|
-
first: 2
|
|
482
|
-
}
|
|
347
|
+
variables: { sender: address, first: 2 }
|
|
483
348
|
});
|
|
484
349
|
if (res.errors?.length) {
|
|
485
350
|
return void 0;
|
|
@@ -508,7 +373,6 @@ async function getPublicKeyFromChain(suiClient, address) {
|
|
|
508
373
|
}
|
|
509
374
|
return void 0;
|
|
510
375
|
}
|
|
511
|
-
__name(getPublicKeyFromChain, "getPublicKeyFromChain");
|
|
512
376
|
function getAddressFromSignatures(serializedSig, targetAddress) {
|
|
513
377
|
const decoded = parseSerializedSignature(serializedSig);
|
|
514
378
|
switch (decoded.signatureScheme) {
|
|
@@ -523,10 +387,7 @@ function getAddressFromSignatures(serializedSig, targetAddress) {
|
|
|
523
387
|
case "ED25519":
|
|
524
388
|
case "Secp256k1":
|
|
525
389
|
case "Secp256r1": {
|
|
526
|
-
const pk = PublicKeySerde2.de({
|
|
527
|
-
publicKeyEncoded: decoded.publicKey,
|
|
528
|
-
schema: decoded.signatureScheme
|
|
529
|
-
});
|
|
390
|
+
const pk = PublicKeySerde2.de({ publicKeyEncoded: decoded.publicKey, schema: decoded.signatureScheme });
|
|
530
391
|
if (Formatter.isSuiAddressEqual(pk.toSuiAddress(), targetAddress)) {
|
|
531
392
|
return pk;
|
|
532
393
|
}
|
|
@@ -536,7 +397,6 @@ function getAddressFromSignatures(serializedSig, targetAddress) {
|
|
|
536
397
|
throw new Error("Unknown schema");
|
|
537
398
|
}
|
|
538
399
|
}
|
|
539
|
-
__name(getAddressFromSignatures, "getAddressFromSignatures");
|
|
540
400
|
async function getAllCoins(input) {
|
|
541
401
|
let hasNext = true;
|
|
542
402
|
let cursor;
|
|
@@ -553,18 +413,357 @@ async function getAllCoins(input) {
|
|
|
553
413
|
}
|
|
554
414
|
return res;
|
|
555
415
|
}
|
|
556
|
-
|
|
416
|
+
|
|
417
|
+
// src/utils/gasFunding.ts
|
|
418
|
+
var GAS_SAFE_OVERHEAD = 1000n;
|
|
419
|
+
var InsufficientGasFundsError = class extends Error {
|
|
420
|
+
gasBudget;
|
|
421
|
+
coinBalance;
|
|
422
|
+
addressBalance;
|
|
423
|
+
constructor(gasBudget, coinBalance, addressBalance) {
|
|
424
|
+
const total = coinBalance + addressBalance;
|
|
425
|
+
super(
|
|
426
|
+
`Insufficient gas funds: need ${gasBudget}, have coinBalance=${coinBalance} + addressBalance=${addressBalance} = ${total}`
|
|
427
|
+
);
|
|
428
|
+
this.name = "InsufficientGasFundsError";
|
|
429
|
+
this.gasBudget = gasBudget;
|
|
430
|
+
this.coinBalance = coinBalance;
|
|
431
|
+
this.addressBalance = addressBalance;
|
|
432
|
+
}
|
|
433
|
+
};
|
|
434
|
+
function computeGasBudget(gasUsed, gasPrice) {
|
|
435
|
+
const { computationCost, storageCost } = gasUsed;
|
|
436
|
+
const safeOverhead = GAS_SAFE_OVERHEAD * gasPrice;
|
|
437
|
+
return BigInt(computationCost) + BigInt(storageCost) + safeOverhead;
|
|
438
|
+
}
|
|
439
|
+
function collectUsedObjectIds(tx) {
|
|
440
|
+
return tx.getData().inputs.reduce((used, input) => {
|
|
441
|
+
const immOrOwned = input.Object?.ImmOrOwnedObject?.objectId;
|
|
442
|
+
if (immOrOwned) {
|
|
443
|
+
used.add(normalizeSuiObjectId(immOrOwned));
|
|
444
|
+
return used;
|
|
445
|
+
}
|
|
446
|
+
const unresolved = input.UnresolvedObject?.objectId;
|
|
447
|
+
if (unresolved) {
|
|
448
|
+
used.add(normalizeSuiObjectId(unresolved));
|
|
449
|
+
}
|
|
450
|
+
return used;
|
|
451
|
+
}, /* @__PURE__ */ new Set());
|
|
452
|
+
}
|
|
453
|
+
async function loadSuiGasFunding(suiClient, owner, tx) {
|
|
454
|
+
const usedObjectIds = collectUsedObjectIds(tx);
|
|
455
|
+
const [coins, balanceRes] = await Promise.all([
|
|
456
|
+
getAllCoins({ suiClient, owner, coinType: SUI_COIN }),
|
|
457
|
+
suiClient.getBalance({ owner, coinType: SUI_COIN })
|
|
458
|
+
]);
|
|
459
|
+
const paymentCoins = coins.filter((coin) => !usedObjectIds.has(normalizeSuiObjectId(coin.objectId)) && BigInt(coin.balance) > 0n).map((coin) => ({
|
|
460
|
+
objectId: coin.objectId,
|
|
461
|
+
version: coin.version,
|
|
462
|
+
digest: coin.digest,
|
|
463
|
+
balance: BigInt(coin.balance)
|
|
464
|
+
}));
|
|
465
|
+
const coinBalance = paymentCoins.reduce((sum, coin) => sum + coin.balance, 0n);
|
|
466
|
+
const addressBalance = BigInt(balanceRes.balance.addressBalance);
|
|
467
|
+
return {
|
|
468
|
+
paymentCoins,
|
|
469
|
+
coinBalance,
|
|
470
|
+
addressBalance,
|
|
471
|
+
total: coinBalance + addressBalance
|
|
472
|
+
};
|
|
473
|
+
}
|
|
474
|
+
function toObjectRefs(coins) {
|
|
475
|
+
return coins.map(({ objectId, version, digest }) => ({ objectId, version, digest }));
|
|
476
|
+
}
|
|
477
|
+
async function applyMixedTopUp(input) {
|
|
478
|
+
const { tx, suiClient, owner, paymentCoins, topUpAmount } = input;
|
|
479
|
+
if (paymentCoins.length === 0) {
|
|
480
|
+
throw new Error("mixed gas top-up requires at least one SUI coin object");
|
|
481
|
+
}
|
|
482
|
+
if (topUpAmount <= 0n) {
|
|
483
|
+
tx.setGasPayment(toObjectRefs(paymentCoins));
|
|
484
|
+
return;
|
|
485
|
+
}
|
|
486
|
+
const [{ chainIdentifier }, { systemState }] = await Promise.all([
|
|
487
|
+
suiClient.core.getChainIdentifier(),
|
|
488
|
+
suiClient.core.getCurrentSystemState()
|
|
489
|
+
]);
|
|
490
|
+
const reservation = createCoinReservationRef(topUpAmount, owner, chainIdentifier, systemState.epoch);
|
|
491
|
+
tx.setGasPayment([...toObjectRefs(paymentCoins), reservation]);
|
|
492
|
+
}
|
|
493
|
+
async function selectGasFunding(input) {
|
|
494
|
+
const { tx, suiClient, owner, gasBudget } = input;
|
|
495
|
+
const { payment } = tx.getData().gasData;
|
|
496
|
+
if (payment != null && payment.length > 0) {
|
|
497
|
+
const funding2 = await loadSuiGasFunding(suiClient, owner, tx);
|
|
498
|
+
return {
|
|
499
|
+
mode: "classic",
|
|
500
|
+
gasBudget,
|
|
501
|
+
coinBalance: funding2.coinBalance,
|
|
502
|
+
addressBalance: funding2.addressBalance
|
|
503
|
+
};
|
|
504
|
+
}
|
|
505
|
+
const funding = await loadSuiGasFunding(suiClient, owner, tx);
|
|
506
|
+
const { paymentCoins, coinBalance, addressBalance, total } = funding;
|
|
507
|
+
if (total < gasBudget) {
|
|
508
|
+
throw new InsufficientGasFundsError(gasBudget, coinBalance, addressBalance);
|
|
509
|
+
}
|
|
510
|
+
if (paymentCoins.length > 0 && coinBalance >= gasBudget) {
|
|
511
|
+
tx.setGasPayment(toObjectRefs(paymentCoins));
|
|
512
|
+
return { mode: "classic", gasBudget, coinBalance, addressBalance };
|
|
513
|
+
}
|
|
514
|
+
if (paymentCoins.length > 0 && total >= gasBudget) {
|
|
515
|
+
const topUpAmount = gasBudget - coinBalance;
|
|
516
|
+
await applyMixedTopUp({
|
|
517
|
+
tx,
|
|
518
|
+
suiClient,
|
|
519
|
+
owner,
|
|
520
|
+
paymentCoins,
|
|
521
|
+
topUpAmount
|
|
522
|
+
});
|
|
523
|
+
return { mode: "mixedTopUp", gasBudget, coinBalance, addressBalance };
|
|
524
|
+
}
|
|
525
|
+
if (addressBalance >= gasBudget) {
|
|
526
|
+
tx.setGasPayment([]);
|
|
527
|
+
return { mode: "addressBalance", gasBudget, coinBalance, addressBalance };
|
|
528
|
+
}
|
|
529
|
+
throw new InsufficientGasFundsError(gasBudget, coinBalance, addressBalance);
|
|
530
|
+
}
|
|
531
|
+
async function estimateGasBudget(input) {
|
|
532
|
+
const { tx, suiClient, owner, gasPrice } = input;
|
|
533
|
+
const funding = await loadSuiGasFunding(suiClient, owner, tx);
|
|
534
|
+
if (funding.total <= 0n) {
|
|
535
|
+
throw new InsufficientGasFundsError(0n, funding.coinBalance, funding.addressBalance);
|
|
536
|
+
}
|
|
537
|
+
const probe = Transaction.from(tx);
|
|
538
|
+
probe.setSender(owner);
|
|
539
|
+
probe.setGasPrice(gasPrice);
|
|
540
|
+
if (funding.paymentCoins.length > 0) {
|
|
541
|
+
probe.setGasPayment(toObjectRefs(funding.paymentCoins));
|
|
542
|
+
}
|
|
543
|
+
let built;
|
|
544
|
+
try {
|
|
545
|
+
built = await probe.build({ client: suiClient });
|
|
546
|
+
} catch (e) {
|
|
547
|
+
const message = e instanceof Error ? e.message : String(e);
|
|
548
|
+
throw new Error(`Failed to estimate gas budget: ${message}`);
|
|
549
|
+
}
|
|
550
|
+
const inspect = await suiClient.simulateTransaction({
|
|
551
|
+
transaction: built,
|
|
552
|
+
include: { effects: true }
|
|
553
|
+
});
|
|
554
|
+
const effects = (inspect.Transaction ?? inspect.FailedTransaction)?.effects;
|
|
555
|
+
if (!effects?.gasUsed) {
|
|
556
|
+
throw new Error("Failed to estimate gas budget: simulateTransaction returned no gasUsed");
|
|
557
|
+
}
|
|
558
|
+
if (effects.status.success !== true) {
|
|
559
|
+
const err = effects.status.success === false ? effects.status.error?.message : void 0;
|
|
560
|
+
throw new Error(`Failed to estimate gas budget: ${err ?? "simulation failed"}`);
|
|
561
|
+
}
|
|
562
|
+
return computeGasBudget(effects.gasUsed, gasPrice);
|
|
563
|
+
}
|
|
564
|
+
async function prepareGasFunding(input) {
|
|
565
|
+
const { tx, suiClient, owner, gasPrice } = input;
|
|
566
|
+
const { payment, budget: existingBudget } = tx.getData().gasData;
|
|
567
|
+
const bakedAddressBalanceGas = payment != null && payment.length === 0;
|
|
568
|
+
let { gasBudget } = input;
|
|
569
|
+
if (gasBudget == null) {
|
|
570
|
+
if (bakedAddressBalanceGas || existingBudget == null) {
|
|
571
|
+
gasBudget = await estimateGasBudget({ tx, suiClient, owner, gasPrice });
|
|
572
|
+
} else {
|
|
573
|
+
gasBudget = BigInt(existingBudget);
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
tx.setGasBudget(gasBudget);
|
|
577
|
+
return selectGasFunding({ tx, suiClient, owner, gasBudget });
|
|
578
|
+
}
|
|
579
|
+
async function preferClassicGasPayment(input) {
|
|
580
|
+
const { tx, suiClient, owner } = input;
|
|
581
|
+
const { payment } = tx.getData().gasData;
|
|
582
|
+
if (payment != null) {
|
|
583
|
+
return payment.length > 0;
|
|
584
|
+
}
|
|
585
|
+
const funding = await loadSuiGasFunding(suiClient, owner, tx);
|
|
586
|
+
if (funding.paymentCoins.length === 0) {
|
|
587
|
+
return false;
|
|
588
|
+
}
|
|
589
|
+
tx.setGasPayment(toObjectRefs(funding.paymentCoins));
|
|
590
|
+
return true;
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
// src/simulate/simulator.ts
|
|
594
|
+
function formatExecutionError(error) {
|
|
595
|
+
return error.message;
|
|
596
|
+
}
|
|
597
|
+
function gasObjectToReference(gas) {
|
|
598
|
+
if (!gas?.objectId) {
|
|
599
|
+
throw new Error("Gas object missing from simulation effects");
|
|
600
|
+
}
|
|
601
|
+
const version = gas.outputVersion ?? gas.inputVersion ?? "0";
|
|
602
|
+
const digest = gas.outputDigest ?? gas.inputDigest ?? "";
|
|
603
|
+
return { objectId: gas.objectId, version, digest };
|
|
604
|
+
}
|
|
605
|
+
var Simulator = class {
|
|
606
|
+
constructor(globals) {
|
|
607
|
+
this.globals = globals;
|
|
608
|
+
}
|
|
609
|
+
async simulate(input) {
|
|
610
|
+
const tx = this.copyTransaction(input.txb);
|
|
611
|
+
const { suiClient } = this.globals;
|
|
612
|
+
const gasPrice = await this.getGasPrice();
|
|
613
|
+
tx.setGasPrice(gasPrice);
|
|
614
|
+
tx.setSender(input.sender);
|
|
615
|
+
try {
|
|
616
|
+
await prepareGasFunding({
|
|
617
|
+
tx,
|
|
618
|
+
suiClient,
|
|
619
|
+
owner: input.sender,
|
|
620
|
+
gasPrice
|
|
621
|
+
});
|
|
622
|
+
} catch (e) {
|
|
623
|
+
const message = e instanceof Error ? e.message : String(e);
|
|
624
|
+
return {
|
|
625
|
+
success: false,
|
|
626
|
+
gasPrice,
|
|
627
|
+
simulationError: message
|
|
628
|
+
};
|
|
629
|
+
}
|
|
630
|
+
let built;
|
|
631
|
+
try {
|
|
632
|
+
built = await tx.build({ client: suiClient });
|
|
633
|
+
} catch (e) {
|
|
634
|
+
const message = e instanceof Error ? e.message : String(e);
|
|
635
|
+
return {
|
|
636
|
+
success: false,
|
|
637
|
+
gasPrice,
|
|
638
|
+
simulationError: message
|
|
639
|
+
};
|
|
640
|
+
}
|
|
641
|
+
let inspectResult;
|
|
642
|
+
try {
|
|
643
|
+
inspectResult = await suiClient.simulateTransaction({
|
|
644
|
+
transaction: built,
|
|
645
|
+
include: {
|
|
646
|
+
effects: true,
|
|
647
|
+
balanceChanges: true,
|
|
648
|
+
events: true,
|
|
649
|
+
objectTypes: true,
|
|
650
|
+
transaction: true,
|
|
651
|
+
bcs: true,
|
|
652
|
+
commandResults: true
|
|
653
|
+
}
|
|
654
|
+
});
|
|
655
|
+
} catch (e) {
|
|
656
|
+
const message = e instanceof Error ? e.message : String(e);
|
|
657
|
+
return {
|
|
658
|
+
success: false,
|
|
659
|
+
gasPrice,
|
|
660
|
+
simulationError: message
|
|
661
|
+
};
|
|
662
|
+
}
|
|
663
|
+
const txRow = inspectResult.Transaction ?? inspectResult.FailedTransaction;
|
|
664
|
+
const { effects } = txRow;
|
|
665
|
+
if (!effects) {
|
|
666
|
+
throw new Error("simulateTransaction did not return effects");
|
|
667
|
+
}
|
|
668
|
+
const success = effects.status.success === true;
|
|
669
|
+
if (!success) {
|
|
670
|
+
const err = effects.status.success === false ? effects.status.error : null;
|
|
671
|
+
return {
|
|
672
|
+
success,
|
|
673
|
+
gasPrice,
|
|
674
|
+
response: inspectResult,
|
|
675
|
+
simulationError: err ? formatExecutionError(err) : "Simulation failed"
|
|
676
|
+
};
|
|
677
|
+
}
|
|
678
|
+
const gasBudget = this.toGasBudget(effects.gasUsed, gasPrice);
|
|
679
|
+
return {
|
|
680
|
+
success,
|
|
681
|
+
gasPrice,
|
|
682
|
+
gasObject: gasObjectToReference(effects.gasObject),
|
|
683
|
+
gasUsed: effects.gasUsed,
|
|
684
|
+
gasBudget,
|
|
685
|
+
response: inspectResult
|
|
686
|
+
};
|
|
687
|
+
}
|
|
688
|
+
async getGasPrice() {
|
|
689
|
+
const { referenceGasPrice } = await this.globals.suiClient.getReferenceGasPrice();
|
|
690
|
+
return BigInt(referenceGasPrice);
|
|
691
|
+
}
|
|
692
|
+
toGasBudget(gasUsed, gasPrice) {
|
|
693
|
+
return computeGasBudget(gasUsed, gasPrice);
|
|
694
|
+
}
|
|
695
|
+
copyTransaction(tx) {
|
|
696
|
+
return Transaction2.from(tx);
|
|
697
|
+
}
|
|
698
|
+
};
|
|
699
|
+
|
|
700
|
+
// src/utils/buffer.ts
|
|
701
|
+
import { Buffer } from "buffer";
|
|
702
|
+
function stringToBuffer(s) {
|
|
703
|
+
return Buffer.from(s, "utf-8");
|
|
704
|
+
}
|
|
705
|
+
function Uint8ArrayToHex(b) {
|
|
706
|
+
return `0x${Array.prototype.map.call(b, (x) => `0${x.toString(16)}`.slice(-2)).join("")}`;
|
|
707
|
+
}
|
|
708
|
+
function HexToUint8Array(hex) {
|
|
709
|
+
return Uint8Array.from(Buffer.from(hex.startsWith("0x") ? hex.slice(2) : hex, "hex"));
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
// src/utils/crypto.ts
|
|
713
|
+
import { verifyPersonalMessageSignature, verifyTransactionSignature } from "@mysten/sui/verify";
|
|
714
|
+
var SignatureVerifier = class _SignatureVerifier {
|
|
715
|
+
static async getPublicKeyFromSignature(input) {
|
|
716
|
+
if (input.messageType === "TransactionBlock") {
|
|
717
|
+
return verifyTransactionSignature(input.message, input.signature);
|
|
718
|
+
}
|
|
719
|
+
return verifyPersonalMessageSignature(input.message, input.signature);
|
|
720
|
+
}
|
|
721
|
+
static async getPublicKeyFromPersonalSignature(input) {
|
|
722
|
+
const message = stringToBuffer(input.messageStr);
|
|
723
|
+
return this.getPublicKeyFromSignature({
|
|
724
|
+
message,
|
|
725
|
+
messageType: "Personal",
|
|
726
|
+
signature: input.signature
|
|
727
|
+
});
|
|
728
|
+
}
|
|
729
|
+
static async verifySignature(input) {
|
|
730
|
+
const publicKey = await _SignatureVerifier.getPublicKeyFromSignature(input);
|
|
731
|
+
return Formatter.isSuiAddressEqual(publicKey.toSuiAddress(), input.targetAddress);
|
|
732
|
+
}
|
|
733
|
+
static async verifyPersonalSignature(input) {
|
|
734
|
+
const message = stringToBuffer(input.messageStr);
|
|
735
|
+
return this.verifySignature({
|
|
736
|
+
message,
|
|
737
|
+
messageType: "Personal",
|
|
738
|
+
signature: input.signature,
|
|
739
|
+
targetAddress: input.targetAddress
|
|
740
|
+
});
|
|
741
|
+
}
|
|
742
|
+
static async verifyTransactionSignature(input) {
|
|
743
|
+
return this.verifySignature({
|
|
744
|
+
messageType: "TransactionBlock",
|
|
745
|
+
message: input.payload,
|
|
746
|
+
signature: input.signature,
|
|
747
|
+
targetAddress: input.targetAddress
|
|
748
|
+
});
|
|
749
|
+
}
|
|
750
|
+
};
|
|
557
751
|
|
|
558
752
|
// src/utils/transaction.ts
|
|
559
|
-
import { Transaction as
|
|
753
|
+
import { Transaction as Transaction3, isTransaction } from "@mysten/sui/transactions";
|
|
560
754
|
function toSuiTransaction(txb) {
|
|
561
755
|
if (isTransaction(txb)) {
|
|
562
756
|
return txb;
|
|
563
757
|
}
|
|
758
|
+
if (typeof txb === "string" || txb instanceof Uint8Array) {
|
|
759
|
+
return Transaction3.from(txb);
|
|
760
|
+
}
|
|
564
761
|
const legacy = txb;
|
|
565
|
-
|
|
762
|
+
if (typeof legacy?.serialize === "function") {
|
|
763
|
+
return Transaction3.from(legacy.serialize());
|
|
764
|
+
}
|
|
765
|
+
throw new Error("Unsupported transaction value for toSuiTransaction");
|
|
566
766
|
}
|
|
567
|
-
__name(toSuiTransaction, "toSuiTransaction");
|
|
568
767
|
|
|
569
768
|
// src/utils/iter/iterator.ts
|
|
570
769
|
var REQUEST_PAGE_SIZE = 25;
|
|
@@ -579,19 +778,14 @@ async function getAllFromIterator(it) {
|
|
|
579
778
|
}
|
|
580
779
|
return res;
|
|
581
780
|
}
|
|
582
|
-
__name(getAllFromIterator, "getAllFromIterator");
|
|
583
781
|
var PagedIterator = class {
|
|
584
|
-
static {
|
|
585
|
-
__name(this, "PagedIterator");
|
|
586
|
-
}
|
|
587
|
-
requester;
|
|
588
|
-
curPage;
|
|
589
|
-
init;
|
|
590
782
|
constructor(requester) {
|
|
591
783
|
this.requester = requester;
|
|
592
784
|
this.curPage = void 0;
|
|
593
785
|
this.init = true;
|
|
594
786
|
}
|
|
787
|
+
curPage;
|
|
788
|
+
init;
|
|
595
789
|
async hasNext() {
|
|
596
790
|
if (this.init) {
|
|
597
791
|
if (!this.curPage) {
|
|
@@ -617,19 +811,15 @@ var PagedIterator = class {
|
|
|
617
811
|
}
|
|
618
812
|
};
|
|
619
813
|
var EntryIterator = class {
|
|
620
|
-
static {
|
|
621
|
-
__name(this, "EntryIterator");
|
|
622
|
-
}
|
|
623
|
-
requester;
|
|
624
|
-
cursor;
|
|
625
|
-
pager;
|
|
626
|
-
curData;
|
|
627
814
|
constructor(requester) {
|
|
628
815
|
this.requester = requester;
|
|
629
816
|
this.pager = new PagedIterator(requester);
|
|
630
817
|
this.curData = [];
|
|
631
818
|
this.cursor = 0;
|
|
632
819
|
}
|
|
820
|
+
cursor;
|
|
821
|
+
pager;
|
|
822
|
+
curData;
|
|
633
823
|
async hasNext() {
|
|
634
824
|
if (this.cursor < this.curData.length - 1) {
|
|
635
825
|
return true;
|
|
@@ -651,28 +841,15 @@ var EntryIterator = class {
|
|
|
651
841
|
};
|
|
652
842
|
|
|
653
843
|
// src/utils/iter/object.ts
|
|
654
|
-
var defaultObjectInclude = {
|
|
655
|
-
json: true
|
|
656
|
-
};
|
|
844
|
+
var defaultObjectInclude = { json: true };
|
|
657
845
|
function mergeInclude(options) {
|
|
658
|
-
return {
|
|
659
|
-
...defaultObjectInclude,
|
|
660
|
-
...options?.objectInclude
|
|
661
|
-
};
|
|
846
|
+
return { ...defaultObjectInclude, ...options?.objectInclude };
|
|
662
847
|
}
|
|
663
|
-
__name(mergeInclude, "mergeInclude");
|
|
664
848
|
async function getAllOwnedObjects(provider, owner, options) {
|
|
665
849
|
const iter = new OwnedObjectIterator(provider, owner, options);
|
|
666
850
|
return await getAllFromIterator(iter);
|
|
667
851
|
}
|
|
668
|
-
__name(getAllOwnedObjects, "getAllOwnedObjects");
|
|
669
852
|
var OwnedObjectIterator = class extends EntryIterator {
|
|
670
|
-
static {
|
|
671
|
-
__name(this, "OwnedObjectIterator");
|
|
672
|
-
}
|
|
673
|
-
provider;
|
|
674
|
-
owner;
|
|
675
|
-
options;
|
|
676
853
|
constructor(provider, owner, options) {
|
|
677
854
|
super(new OwnedObjectRequester(provider, owner, options));
|
|
678
855
|
this.provider = provider;
|
|
@@ -681,16 +858,6 @@ var OwnedObjectIterator = class extends EntryIterator {
|
|
|
681
858
|
}
|
|
682
859
|
};
|
|
683
860
|
var OwnedObjectRequester = class {
|
|
684
|
-
static {
|
|
685
|
-
__name(this, "OwnedObjectRequester");
|
|
686
|
-
}
|
|
687
|
-
provider;
|
|
688
|
-
owner;
|
|
689
|
-
options;
|
|
690
|
-
nextCursor;
|
|
691
|
-
filter;
|
|
692
|
-
pageSize;
|
|
693
|
-
objectInclude;
|
|
694
861
|
constructor(provider, owner, options) {
|
|
695
862
|
this.provider = provider;
|
|
696
863
|
this.owner = owner;
|
|
@@ -700,6 +867,10 @@ var OwnedObjectRequester = class {
|
|
|
700
867
|
this.pageSize = options?.pageSize || REQUEST_PAGE_SIZE;
|
|
701
868
|
this.objectInclude = mergeInclude(options);
|
|
702
869
|
}
|
|
870
|
+
nextCursor;
|
|
871
|
+
filter;
|
|
872
|
+
pageSize;
|
|
873
|
+
objectInclude;
|
|
703
874
|
async doNextRequest() {
|
|
704
875
|
const res = await this.provider.listOwnedObjects({
|
|
705
876
|
owner: this.owner,
|
|
@@ -724,14 +895,6 @@ var OwnedObjectRequester = class {
|
|
|
724
895
|
|
|
725
896
|
// src/core/MSafeAccount.ts
|
|
726
897
|
var MSafeAccount = class _MSafeAccount {
|
|
727
|
-
static {
|
|
728
|
-
__name(this, "MSafeAccount");
|
|
729
|
-
}
|
|
730
|
-
globals;
|
|
731
|
-
info;
|
|
732
|
-
multiSig;
|
|
733
|
-
simulator;
|
|
734
|
-
coinHelper;
|
|
735
898
|
constructor(globals, info) {
|
|
736
899
|
this.globals = globals;
|
|
737
900
|
this.info = info;
|
|
@@ -743,6 +906,9 @@ var MSafeAccount = class _MSafeAccount {
|
|
|
743
906
|
this.coinHelper = new CoinHelper(this.suiClient);
|
|
744
907
|
this.simulator = new Simulator(globals);
|
|
745
908
|
}
|
|
909
|
+
multiSig;
|
|
910
|
+
simulator;
|
|
911
|
+
coinHelper;
|
|
746
912
|
static async New(globals, address) {
|
|
747
913
|
const info = await globals.backend.getMSafeAccountInfo(address);
|
|
748
914
|
const ms = new _MSafeAccount(globals, info);
|
|
@@ -755,23 +921,21 @@ var MSafeAccount = class _MSafeAccount {
|
|
|
755
921
|
let cursor = null;
|
|
756
922
|
let hasNext = true;
|
|
757
923
|
while (hasNext) {
|
|
758
|
-
const page = await this.suiClient.listBalances({
|
|
759
|
-
owner: this.address,
|
|
760
|
-
cursor,
|
|
761
|
-
limit: 50
|
|
762
|
-
});
|
|
924
|
+
const page = await this.suiClient.listBalances({ owner: this.address, cursor, limit: 50 });
|
|
763
925
|
balances.push(...page.balances);
|
|
764
926
|
hasNext = page.hasNextPage;
|
|
765
927
|
cursor = page.cursor;
|
|
766
928
|
}
|
|
767
|
-
return Promise.all(
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
929
|
+
return Promise.all(
|
|
930
|
+
balances.map(async (balance) => {
|
|
931
|
+
const meta = await this.coinHelper.getCoinMeta(balance.coinType);
|
|
932
|
+
return {
|
|
933
|
+
type: normalizeStructTag3(balance.coinType),
|
|
934
|
+
balance: BigInt(balance.addressBalance),
|
|
935
|
+
metadata: meta
|
|
936
|
+
};
|
|
937
|
+
})
|
|
938
|
+
);
|
|
775
939
|
}
|
|
776
940
|
async ownedObjects(options) {
|
|
777
941
|
const filterCoinObjectOptions = {
|
|
@@ -781,9 +945,7 @@ var MSafeAccount = class _MSafeAccount {
|
|
|
781
945
|
return getAllOwnedObjects(this.suiClient, this.address, filterCoinObjectOptions);
|
|
782
946
|
}
|
|
783
947
|
async pendingTransaction() {
|
|
784
|
-
const res = await this.backend.getPendingTransactions({
|
|
785
|
-
msafeAddress: this.address
|
|
786
|
-
});
|
|
948
|
+
const res = await this.backend.getPendingTransactions({ msafeAddress: this.address });
|
|
787
949
|
if (!res?.pending) {
|
|
788
950
|
return void 0;
|
|
789
951
|
}
|
|
@@ -815,10 +977,7 @@ var MSafeAccount = class _MSafeAccount {
|
|
|
815
977
|
});
|
|
816
978
|
}
|
|
817
979
|
async futureIntentions(pagination) {
|
|
818
|
-
return this.backend.getFutureIntentions({
|
|
819
|
-
msafeAddress: this.address,
|
|
820
|
-
...pagination
|
|
821
|
-
});
|
|
980
|
+
return this.backend.getFutureIntentions({ msafeAddress: this.address, ...pagination });
|
|
822
981
|
}
|
|
823
982
|
async currentSequenceNumber() {
|
|
824
983
|
return this.backend.getCurrentSequenceNumber(this.address);
|
|
@@ -835,28 +994,24 @@ var MSafeAccount = class _MSafeAccount {
|
|
|
835
994
|
if (!appHelper) {
|
|
836
995
|
throw new Error(`Can't find app helper for application ${request.application}`);
|
|
837
996
|
}
|
|
838
|
-
txb = toSuiTransaction(
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
SUI_MAINNET_CHAIN,
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
}));
|
|
997
|
+
txb = toSuiTransaction(
|
|
998
|
+
await appHelper.build({
|
|
999
|
+
network: this.globals.config.network,
|
|
1000
|
+
intentionData: request.intention,
|
|
1001
|
+
txType: request.txType,
|
|
1002
|
+
txSubType: request.txSubType,
|
|
1003
|
+
clientUrl: this.globals.config.suiClient.url,
|
|
1004
|
+
account: {
|
|
1005
|
+
address: this.address,
|
|
1006
|
+
publicKey: fromHex2(this.address),
|
|
1007
|
+
chains: [SUI_MAINNET_CHAIN, SUI_TESTNET_CHAIN],
|
|
1008
|
+
features: []
|
|
1009
|
+
}
|
|
1010
|
+
})
|
|
1011
|
+
);
|
|
854
1012
|
}
|
|
855
1013
|
txb.setSender(this.address);
|
|
856
|
-
return this.simulator.simulate({
|
|
857
|
-
txb,
|
|
858
|
-
sender: this.address
|
|
859
|
-
});
|
|
1014
|
+
return this.simulator.simulate({ txb, sender: this.address });
|
|
860
1015
|
}
|
|
861
1016
|
async proposeIntention(input) {
|
|
862
1017
|
const message = SigningMessageHelper3.proposeIntentionMessage({
|
|
@@ -882,38 +1037,37 @@ var MSafeAccount = class _MSafeAccount {
|
|
|
882
1037
|
if (!appHelper) {
|
|
883
1038
|
throw new Error(`Can't find app helper for application ${input.application}`);
|
|
884
1039
|
}
|
|
885
|
-
txb = toSuiTransaction(
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
SUI_MAINNET_CHAIN,
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
}));
|
|
1040
|
+
txb = toSuiTransaction(
|
|
1041
|
+
await appHelper.build({
|
|
1042
|
+
network: this.globals.config.network,
|
|
1043
|
+
intentionData: input.intention,
|
|
1044
|
+
txType: input.txType,
|
|
1045
|
+
txSubType: input.txSubType,
|
|
1046
|
+
clientUrl: this.globals.config.suiClient.url,
|
|
1047
|
+
account: {
|
|
1048
|
+
address: this.address,
|
|
1049
|
+
publicKey: fromHex2(this.address),
|
|
1050
|
+
chains: [SUI_MAINNET_CHAIN, SUI_TESTNET_CHAIN],
|
|
1051
|
+
features: []
|
|
1052
|
+
}
|
|
1053
|
+
})
|
|
1054
|
+
);
|
|
901
1055
|
}
|
|
902
1056
|
txb.setGasPrice(input.gasPrice);
|
|
903
|
-
txb.setGasBudget(input.gasBudget);
|
|
904
1057
|
txb.setSender(this.address);
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
});
|
|
1058
|
+
await prepareGasFunding({
|
|
1059
|
+
tx: txb,
|
|
1060
|
+
suiClient: this.globals.suiClient,
|
|
1061
|
+
owner: this.address,
|
|
1062
|
+
gasPrice: input.gasPrice,
|
|
1063
|
+
gasBudget: input.gasBudget
|
|
1064
|
+
});
|
|
1065
|
+
const payload = await txb.build({ client: this.globals.suiClient });
|
|
1066
|
+
const digest = await txb.getDigest({ client: this.globals.suiClient });
|
|
1067
|
+
const signature = await this.wallet.signTransactionBlock({ transactionBlock: payload });
|
|
914
1068
|
return this.backend.proposeIntentionAndBuildVote({
|
|
915
1069
|
...input,
|
|
916
|
-
payload:
|
|
1070
|
+
payload: toHex2(payload),
|
|
917
1071
|
digest,
|
|
918
1072
|
msafeAddress: this.address,
|
|
919
1073
|
signature: signature.signature
|
|
@@ -971,7 +1125,7 @@ var MSafeAccount = class _MSafeAccount {
|
|
|
971
1125
|
}
|
|
972
1126
|
async proposePlainPayloadIntention(intention) {
|
|
973
1127
|
const sn = await this.nextSequenceNumber();
|
|
974
|
-
const tb =
|
|
1128
|
+
const tb = Transaction4.from(intention.payload);
|
|
975
1129
|
const data = tb.getData();
|
|
976
1130
|
if (!data.sender || !isSameAddress2(data.sender, this.address)) {
|
|
977
1131
|
throw new Error("Transaction sender is not same as the multisig address");
|
|
@@ -986,9 +1140,7 @@ var MSafeAccount = class _MSafeAccount {
|
|
|
986
1140
|
}
|
|
987
1141
|
async voteForTransaction(digest, payload) {
|
|
988
1142
|
const payloadBytes = HexToUint8Array(payload);
|
|
989
|
-
const signature = await this.wallet.signTransactionBlock({
|
|
990
|
-
transactionBlock: payloadBytes
|
|
991
|
-
});
|
|
1143
|
+
const signature = await this.wallet.signTransactionBlock({ transactionBlock: payloadBytes });
|
|
992
1144
|
return this.backend.voteForTransaction({
|
|
993
1145
|
msafeAddress: this.address,
|
|
994
1146
|
digest,
|
|
@@ -1002,10 +1154,7 @@ var MSafeAccount = class _MSafeAccount {
|
|
|
1002
1154
|
}
|
|
1003
1155
|
const txb = toSuiTransaction(buildRejectTxb(this.address));
|
|
1004
1156
|
txb.setSender(this.address);
|
|
1005
|
-
return this.simulator.simulate({
|
|
1006
|
-
txb,
|
|
1007
|
-
sender: this.address
|
|
1008
|
-
});
|
|
1157
|
+
return this.simulator.simulate({ txb, sender: this.address });
|
|
1009
1158
|
}
|
|
1010
1159
|
async rejectCurrentTx(input) {
|
|
1011
1160
|
const pendingTx = await this.pendingTransaction();
|
|
@@ -1013,15 +1162,17 @@ var MSafeAccount = class _MSafeAccount {
|
|
|
1013
1162
|
throw new Error("Already rejected");
|
|
1014
1163
|
}
|
|
1015
1164
|
const rejectTxb = toSuiTransaction(buildRejectTxb(this.address));
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
});
|
|
1165
|
+
rejectTxb.setGasPrice(input.gasPrice);
|
|
1166
|
+
await prepareGasFunding({
|
|
1167
|
+
tx: rejectTxb,
|
|
1168
|
+
suiClient: this.suiClient,
|
|
1169
|
+
owner: this.address,
|
|
1170
|
+
gasPrice: input.gasPrice,
|
|
1171
|
+
gasBudget: input.gasBudget
|
|
1172
|
+
});
|
|
1173
|
+
const digest = await rejectTxb.getDigest({ client: this.suiClient });
|
|
1174
|
+
const payload = await rejectTxb.build({ client: this.suiClient });
|
|
1175
|
+
const signature = await this.wallet.signTransactionBlock({ transactionBlock: payload });
|
|
1025
1176
|
return this.backend.rejectCurrentTx({
|
|
1026
1177
|
msafeAddress: this.address,
|
|
1027
1178
|
digest,
|
|
@@ -1030,34 +1181,28 @@ var MSafeAccount = class _MSafeAccount {
|
|
|
1030
1181
|
});
|
|
1031
1182
|
}
|
|
1032
1183
|
async simulateBuildTransaction() {
|
|
1033
|
-
const intention = await this.backend.getNextIntention({
|
|
1034
|
-
msafeAddress: this.address
|
|
1035
|
-
});
|
|
1184
|
+
const intention = await this.backend.getNextIntention({ msafeAddress: this.address });
|
|
1036
1185
|
const appHelper = appHelpers.getAppHelper(intention.application);
|
|
1037
1186
|
if (!appHelper) {
|
|
1038
1187
|
throw new Error(`Can't find app helper for application ${intention.application}`);
|
|
1039
1188
|
}
|
|
1040
|
-
const txb = toSuiTransaction(
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
SUI_MAINNET_CHAIN,
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
}));
|
|
1189
|
+
const txb = toSuiTransaction(
|
|
1190
|
+
await appHelper.build({
|
|
1191
|
+
network: this.globals.config.network,
|
|
1192
|
+
intentionData: intention.intention,
|
|
1193
|
+
txType: intention.txType,
|
|
1194
|
+
txSubType: intention.txSubType,
|
|
1195
|
+
clientUrl: this.globals.config.suiClient.url,
|
|
1196
|
+
account: {
|
|
1197
|
+
address: this.address,
|
|
1198
|
+
publicKey: fromHex2(this.address),
|
|
1199
|
+
chains: [SUI_MAINNET_CHAIN, SUI_TESTNET_CHAIN],
|
|
1200
|
+
features: []
|
|
1201
|
+
}
|
|
1202
|
+
})
|
|
1203
|
+
);
|
|
1056
1204
|
txb.setSender(this.address);
|
|
1057
|
-
return this.simulator.simulate({
|
|
1058
|
-
txb,
|
|
1059
|
-
sender: this.address
|
|
1060
|
-
});
|
|
1205
|
+
return this.simulator.simulate({ txb, sender: this.address });
|
|
1061
1206
|
}
|
|
1062
1207
|
async buildNextIntentionAndAddToPending(gasOption) {
|
|
1063
1208
|
return this.backend.buildNextIntentionAndAddToPending({
|
|
@@ -1068,14 +1213,10 @@ var MSafeAccount = class _MSafeAccount {
|
|
|
1068
1213
|
});
|
|
1069
1214
|
}
|
|
1070
1215
|
async skipNextFailedIntention() {
|
|
1071
|
-
return this.backend.skipNextFailedIntention({
|
|
1072
|
-
msafeAddress: this.address
|
|
1073
|
-
});
|
|
1216
|
+
return this.backend.skipNextFailedIntention({ msafeAddress: this.address });
|
|
1074
1217
|
}
|
|
1075
1218
|
async fetchTransaction() {
|
|
1076
|
-
return this.backend.fetchTransaction({
|
|
1077
|
-
msafeAddress: this.address
|
|
1078
|
-
});
|
|
1219
|
+
return this.backend.fetchTransaction({ msafeAddress: this.address });
|
|
1079
1220
|
}
|
|
1080
1221
|
async executePendingTx(pending, isRejectTx = false) {
|
|
1081
1222
|
const votes = isRejectTx ? pending.rejectVotes : pending.votes;
|
|
@@ -1084,10 +1225,7 @@ var MSafeAccount = class _MSafeAccount {
|
|
|
1084
1225
|
throw new Error("Not enough signature");
|
|
1085
1226
|
}
|
|
1086
1227
|
const sortedSigs = [];
|
|
1087
|
-
const gotSigs = new Map(votes.map((vote) => [
|
|
1088
|
-
vote.userAddress,
|
|
1089
|
-
vote.signature
|
|
1090
|
-
]));
|
|
1228
|
+
const gotSigs = new Map(votes.map((vote) => [vote.userAddress, vote.signature]));
|
|
1091
1229
|
for (let i = 0; i < this.info.owners.length; i++) {
|
|
1092
1230
|
const owner = this.info.owners[i];
|
|
1093
1231
|
const signature = gotSigs.get(owner.address);
|
|
@@ -1098,13 +1236,8 @@ var MSafeAccount = class _MSafeAccount {
|
|
|
1098
1236
|
const multiSignature = this.multiSig.combinePartialSignatures(sortedSigs);
|
|
1099
1237
|
return this.suiClient.executeTransaction({
|
|
1100
1238
|
transaction: HexToUint8Array(payload),
|
|
1101
|
-
signatures: [
|
|
1102
|
-
|
|
1103
|
-
],
|
|
1104
|
-
include: {
|
|
1105
|
-
effects: true,
|
|
1106
|
-
events: true
|
|
1107
|
-
}
|
|
1239
|
+
signatures: [multiSignature],
|
|
1240
|
+
include: { effects: true, events: true }
|
|
1108
1241
|
});
|
|
1109
1242
|
}
|
|
1110
1243
|
async dashboard() {
|
|
@@ -1144,17 +1277,13 @@ var MSafeAccount = class _MSafeAccount {
|
|
|
1144
1277
|
|
|
1145
1278
|
// src/core/PublicKeyHelper.ts
|
|
1146
1279
|
import { isSameAddress as isSameAddress3 } from "@msafe/sui3-utils";
|
|
1147
|
-
import { normalizeSuiAddress as
|
|
1280
|
+
import { normalizeSuiAddress as normalizeSuiAddress3 } from "@mysten/sui/utils";
|
|
1148
1281
|
var PublicKeyHelper = class {
|
|
1149
|
-
static {
|
|
1150
|
-
__name(this, "PublicKeyHelper");
|
|
1151
|
-
}
|
|
1152
|
-
globals;
|
|
1153
|
-
knownPublicKeys;
|
|
1154
1282
|
constructor(globals) {
|
|
1155
1283
|
this.globals = globals;
|
|
1156
1284
|
this.knownPublicKeys = /* @__PURE__ */ new Map();
|
|
1157
1285
|
}
|
|
1286
|
+
knownPublicKeys;
|
|
1158
1287
|
async getPublicKey(address) {
|
|
1159
1288
|
const cached = this.knownPublicKeys.get(address);
|
|
1160
1289
|
if (cached) {
|
|
@@ -1197,7 +1326,7 @@ var PublicKeyHelper = class {
|
|
|
1197
1326
|
if (!isSameAddress3(address, publicKey.toSuiAddress())) {
|
|
1198
1327
|
throw new Error("Invalid public key");
|
|
1199
1328
|
}
|
|
1200
|
-
this.knownPublicKeys.set(
|
|
1329
|
+
this.knownPublicKeys.set(normalizeSuiAddress3(address), publicKey);
|
|
1201
1330
|
}
|
|
1202
1331
|
async _getPublicKey(address) {
|
|
1203
1332
|
const pkBackend = await this.getPublicKeyFromBackend(address);
|
|
@@ -1225,10 +1354,6 @@ var PublicKeyHelper = class {
|
|
|
1225
1354
|
|
|
1226
1355
|
// src/core/ReportSDK.ts
|
|
1227
1356
|
var ReportSDK = class {
|
|
1228
|
-
static {
|
|
1229
|
-
__name(this, "ReportSDK");
|
|
1230
|
-
}
|
|
1231
|
-
globals;
|
|
1232
1357
|
constructor(globals) {
|
|
1233
1358
|
this.globals = globals;
|
|
1234
1359
|
}
|
|
@@ -1241,19 +1366,17 @@ var ReportSDK = class {
|
|
|
1241
1366
|
import { SuiGrpcClient } from "@mysten/sui/grpc";
|
|
1242
1367
|
|
|
1243
1368
|
// src/backend/BackendImpl.ts
|
|
1244
|
-
import {
|
|
1369
|
+
import {
|
|
1370
|
+
PublicKeySerde as PublicKeySerde3,
|
|
1371
|
+
UserMSafeStatus
|
|
1372
|
+
} from "@msafe/sui3-utils";
|
|
1245
1373
|
import axios from "axios";
|
|
1246
1374
|
var BackendImpl = class _BackendImpl {
|
|
1247
|
-
static {
|
|
1248
|
-
__name(this, "BackendImpl");
|
|
1249
|
-
}
|
|
1250
|
-
apiURL;
|
|
1251
|
-
mockAddress;
|
|
1252
|
-
_token;
|
|
1253
1375
|
constructor(apiURL, mockAddress) {
|
|
1254
1376
|
this.apiURL = apiURL;
|
|
1255
1377
|
this.mockAddress = mockAddress;
|
|
1256
1378
|
}
|
|
1379
|
+
_token;
|
|
1257
1380
|
getNotificationInfo() {
|
|
1258
1381
|
return this.get(`/notification`, {
|
|
1259
1382
|
headers: this.headers()
|
|
@@ -1276,9 +1399,7 @@ var BackendImpl = class _BackendImpl {
|
|
|
1276
1399
|
}
|
|
1277
1400
|
async verifyToken(jwt) {
|
|
1278
1401
|
try {
|
|
1279
|
-
const res = await this.get(`/auth`, {
|
|
1280
|
-
headers: this.headers(jwt)
|
|
1281
|
-
});
|
|
1402
|
+
const res = await this.get(`/auth`, { headers: this.headers(jwt) });
|
|
1282
1403
|
return res.status === 200;
|
|
1283
1404
|
} catch (_) {
|
|
1284
1405
|
return false;
|
|
@@ -1288,9 +1409,7 @@ var BackendImpl = class _BackendImpl {
|
|
|
1288
1409
|
this._token = token;
|
|
1289
1410
|
}
|
|
1290
1411
|
async getPublicKey(address) {
|
|
1291
|
-
return (await this.getPublicKeyBatch([
|
|
1292
|
-
address
|
|
1293
|
-
]))[0];
|
|
1412
|
+
return (await this.getPublicKeyBatch([address]))[0];
|
|
1294
1413
|
}
|
|
1295
1414
|
async getPublicKeyBatch(addresses) {
|
|
1296
1415
|
const query = {
|
|
@@ -1300,7 +1419,9 @@ var BackendImpl = class _BackendImpl {
|
|
|
1300
1419
|
params: query,
|
|
1301
1420
|
headers: this.headers()
|
|
1302
1421
|
});
|
|
1303
|
-
return res.data?.map(
|
|
1422
|
+
return res.data?.map(
|
|
1423
|
+
(publicKeyWithSchema) => publicKeyWithSchema ? PublicKeySerde3.de(publicKeyWithSchema) : void 0
|
|
1424
|
+
);
|
|
1304
1425
|
}
|
|
1305
1426
|
async getMSafeAccountInfo(msafeAddress) {
|
|
1306
1427
|
const q = {
|
|
@@ -1337,9 +1458,7 @@ var BackendImpl = class _BackendImpl {
|
|
|
1337
1458
|
}
|
|
1338
1459
|
async updateMSafeStatus(input) {
|
|
1339
1460
|
const p = input;
|
|
1340
|
-
await this.post(`/msafe/status`, p, {
|
|
1341
|
-
headers: this.headers()
|
|
1342
|
-
});
|
|
1461
|
+
await this.post(`/msafe/status`, p, { headers: this.headers() });
|
|
1343
1462
|
}
|
|
1344
1463
|
async getPendingTransactions(input) {
|
|
1345
1464
|
const res = await this.get(`/transaction/pending`, {
|
|
@@ -1393,18 +1512,16 @@ var BackendImpl = class _BackendImpl {
|
|
|
1393
1512
|
});
|
|
1394
1513
|
}
|
|
1395
1514
|
async proposeIntention(input) {
|
|
1396
|
-
await this.post(`/transaction/intention`, input, {
|
|
1397
|
-
headers: this.headers()
|
|
1398
|
-
});
|
|
1515
|
+
await this.post(`/transaction/intention`, input, { headers: this.headers() });
|
|
1399
1516
|
}
|
|
1400
1517
|
async rejectCurrentTx(input) {
|
|
1401
|
-
await this.post(
|
|
1402
|
-
|
|
1403
|
-
gasPrice: input.gasPrice.toString(),
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1518
|
+
await this.post(
|
|
1519
|
+
`/transaction/pending/reject`,
|
|
1520
|
+
{ ...input, gasPrice: input.gasPrice.toString(), gasBudget: input.gasBudget.toString() },
|
|
1521
|
+
{
|
|
1522
|
+
headers: this.headers()
|
|
1523
|
+
}
|
|
1524
|
+
);
|
|
1408
1525
|
}
|
|
1409
1526
|
async voteForTransaction(input) {
|
|
1410
1527
|
await this.post(`/transaction/pending/vote`, input, {
|
|
@@ -1412,32 +1529,24 @@ var BackendImpl = class _BackendImpl {
|
|
|
1412
1529
|
});
|
|
1413
1530
|
}
|
|
1414
1531
|
async buildNextIntentionAndAddToPending(input) {
|
|
1415
|
-
await this.post(
|
|
1416
|
-
|
|
1417
|
-
gasPrice: input.gasPrice.toString(),
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
headers: this.headers()
|
|
1421
|
-
});
|
|
1532
|
+
await this.post(
|
|
1533
|
+
`/transaction/pending/build`,
|
|
1534
|
+
{ ...input, gasPrice: input.gasPrice.toString(), gasBudget: input.gasBudget.toString() },
|
|
1535
|
+
{ headers: this.headers() }
|
|
1536
|
+
);
|
|
1422
1537
|
}
|
|
1423
1538
|
async proposeIntentionAndBuildVote(input) {
|
|
1424
|
-
await this.post(
|
|
1425
|
-
|
|
1426
|
-
gasPrice: input.gasPrice.toString(),
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
headers: this.headers()
|
|
1430
|
-
});
|
|
1539
|
+
await this.post(
|
|
1540
|
+
`/transaction/intention/build`,
|
|
1541
|
+
{ ...input, gasPrice: input.gasPrice.toString(), gasBudget: input.gasBudget.toString() },
|
|
1542
|
+
{ headers: this.headers() }
|
|
1543
|
+
);
|
|
1431
1544
|
}
|
|
1432
1545
|
async skipNextFailedIntention(input) {
|
|
1433
|
-
await this.post(`/transaction/pending/skip`, input, {
|
|
1434
|
-
headers: this.headers()
|
|
1435
|
-
});
|
|
1546
|
+
await this.post(`/transaction/pending/skip`, input, { headers: this.headers() });
|
|
1436
1547
|
}
|
|
1437
1548
|
async fetchTransaction(input) {
|
|
1438
|
-
const res = await this.post(`/transaction/fetch`, input, {
|
|
1439
|
-
headers: this.headers()
|
|
1440
|
-
});
|
|
1549
|
+
const res = await this.post(`/transaction/fetch`, input, { headers: this.headers() });
|
|
1441
1550
|
return res.data;
|
|
1442
1551
|
}
|
|
1443
1552
|
async getAddressBookEntries(pagination) {
|
|
@@ -1448,22 +1557,14 @@ var BackendImpl = class _BackendImpl {
|
|
|
1448
1557
|
return res.data;
|
|
1449
1558
|
}
|
|
1450
1559
|
async updateAddressBook(input) {
|
|
1451
|
-
await this.post(`/address-book`, input, {
|
|
1452
|
-
headers: this.headers()
|
|
1453
|
-
});
|
|
1560
|
+
await this.post(`/address-book`, input, { headers: this.headers() });
|
|
1454
1561
|
}
|
|
1455
1562
|
async getAddressBookMode() {
|
|
1456
|
-
const res = await this.get("/address-book/mode", {
|
|
1457
|
-
headers: this.headers()
|
|
1458
|
-
});
|
|
1563
|
+
const res = await this.get("/address-book/mode", { headers: this.headers() });
|
|
1459
1564
|
return res.data;
|
|
1460
1565
|
}
|
|
1461
1566
|
async setAddressBookMode(input) {
|
|
1462
|
-
await this.post("/address-book/mode", {
|
|
1463
|
-
mode: input.mode
|
|
1464
|
-
}, {
|
|
1465
|
-
headers: this.headers()
|
|
1466
|
-
});
|
|
1567
|
+
await this.post("/address-book/mode", { mode: input.mode }, { headers: this.headers() });
|
|
1467
1568
|
}
|
|
1468
1569
|
async submitReport(report) {
|
|
1469
1570
|
await this.post("/report", report);
|
|
@@ -1476,10 +1577,7 @@ var BackendImpl = class _BackendImpl {
|
|
|
1476
1577
|
return res.data;
|
|
1477
1578
|
}
|
|
1478
1579
|
headers(token) {
|
|
1479
|
-
return {
|
|
1480
|
-
Authorization: `Bearer ${token || this._token}`,
|
|
1481
|
-
"sui-mock-user": this.mockAddress
|
|
1482
|
-
};
|
|
1580
|
+
return { Authorization: `Bearer ${token || this._token}`, "sui-mock-user": this.mockAddress };
|
|
1483
1581
|
}
|
|
1484
1582
|
static toMSafeConfig(resp) {
|
|
1485
1583
|
return {
|
|
@@ -1535,9 +1633,7 @@ var BackendImpl = class _BackendImpl {
|
|
|
1535
1633
|
} else if (transformRequest instanceof Array) {
|
|
1536
1634
|
transformRequests = transformRequest;
|
|
1537
1635
|
} else {
|
|
1538
|
-
transformRequests = [
|
|
1539
|
-
transformRequest
|
|
1540
|
-
];
|
|
1636
|
+
transformRequests = [transformRequest];
|
|
1541
1637
|
}
|
|
1542
1638
|
return [
|
|
1543
1639
|
(d) => JSON.parse(JSON.stringify(d, (_, value) => typeof value === "bigint" ? `${value.toString()}n` : value)),
|
|
@@ -1546,10 +1642,6 @@ var BackendImpl = class _BackendImpl {
|
|
|
1546
1642
|
}
|
|
1547
1643
|
};
|
|
1548
1644
|
var BackendError = class _BackendError extends Error {
|
|
1549
|
-
static {
|
|
1550
|
-
__name(this, "BackendError");
|
|
1551
|
-
}
|
|
1552
|
-
e;
|
|
1553
1645
|
constructor(e) {
|
|
1554
1646
|
super();
|
|
1555
1647
|
this.e = e;
|
|
@@ -1586,15 +1678,14 @@ var BackendError = class _BackendError extends Error {
|
|
|
1586
1678
|
function msafeChainToSuiNetwork(chain) {
|
|
1587
1679
|
return chain === "sui:mainnet" ? "mainnet" : "testnet";
|
|
1588
1680
|
}
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
})(MSafeEnv || (MSafeEnv = {}));
|
|
1681
|
+
var MSafeEnv = /* @__PURE__ */ ((MSafeEnv3) => {
|
|
1682
|
+
MSafeEnv3["local"] = "local";
|
|
1683
|
+
MSafeEnv3["unit"] = "unit";
|
|
1684
|
+
MSafeEnv3["dev"] = "dev";
|
|
1685
|
+
MSafeEnv3["prev"] = "prev";
|
|
1686
|
+
MSafeEnv3["prod"] = "prod";
|
|
1687
|
+
return MSafeEnv3;
|
|
1688
|
+
})(MSafeEnv || {});
|
|
1598
1689
|
function httpUrlToGrpcBaseUrl(url) {
|
|
1599
1690
|
const parsed = new URL(url);
|
|
1600
1691
|
if (parsed.protocol === "https:" && parsed.port === "") {
|
|
@@ -1605,7 +1696,6 @@ function httpUrlToGrpcBaseUrl(url) {
|
|
|
1605
1696
|
}
|
|
1606
1697
|
return `${parsed.origin}${parsed.pathname}${parsed.search}`;
|
|
1607
1698
|
}
|
|
1608
|
-
__name(httpUrlToGrpcBaseUrl, "httpUrlToGrpcBaseUrl");
|
|
1609
1699
|
var TESTNET_RPC_URL = "https://fullnode.testnet.sui.io";
|
|
1610
1700
|
var MAINNET_RPC_URL = "https://fullnode.mainnet.sui.io";
|
|
1611
1701
|
var LOCAL_API_URL = "http://127.0.0.1:3000";
|
|
@@ -1616,7 +1706,7 @@ var PREV_API_URL = "https://sui-preview.m-safe.link";
|
|
|
1616
1706
|
var PROD_API_URL = "https://sui.m-safe.link";
|
|
1617
1707
|
var ENV_CONFIGS = /* @__PURE__ */ new Map([
|
|
1618
1708
|
[
|
|
1619
|
-
"unit"
|
|
1709
|
+
"unit" /* unit */,
|
|
1620
1710
|
{
|
|
1621
1711
|
suiClient: {
|
|
1622
1712
|
url: TESTNET_RPC_URL
|
|
@@ -1629,7 +1719,7 @@ var ENV_CONFIGS = /* @__PURE__ */ new Map([
|
|
|
1629
1719
|
}
|
|
1630
1720
|
],
|
|
1631
1721
|
[
|
|
1632
|
-
"local"
|
|
1722
|
+
"local" /* local */,
|
|
1633
1723
|
{
|
|
1634
1724
|
suiClient: {
|
|
1635
1725
|
url: TESTNET_RPC_URL
|
|
@@ -1642,7 +1732,7 @@ var ENV_CONFIGS = /* @__PURE__ */ new Map([
|
|
|
1642
1732
|
}
|
|
1643
1733
|
],
|
|
1644
1734
|
[
|
|
1645
|
-
"dev"
|
|
1735
|
+
"dev" /* dev */,
|
|
1646
1736
|
{
|
|
1647
1737
|
suiClient: {
|
|
1648
1738
|
url: TESTNET_RPC_URL
|
|
@@ -1655,7 +1745,7 @@ var ENV_CONFIGS = /* @__PURE__ */ new Map([
|
|
|
1655
1745
|
}
|
|
1656
1746
|
],
|
|
1657
1747
|
[
|
|
1658
|
-
"prev"
|
|
1748
|
+
"prev" /* prev */,
|
|
1659
1749
|
{
|
|
1660
1750
|
suiClient: {
|
|
1661
1751
|
url: MAINNET_RPC_URL
|
|
@@ -1668,7 +1758,7 @@ var ENV_CONFIGS = /* @__PURE__ */ new Map([
|
|
|
1668
1758
|
}
|
|
1669
1759
|
],
|
|
1670
1760
|
[
|
|
1671
|
-
"prod"
|
|
1761
|
+
"prod" /* prod */,
|
|
1672
1762
|
{
|
|
1673
1763
|
suiClient: {
|
|
1674
1764
|
url: MAINNET_RPC_URL
|
|
@@ -1697,13 +1787,9 @@ function getMSafeConfig(env, options) {
|
|
|
1697
1787
|
}
|
|
1698
1788
|
return config;
|
|
1699
1789
|
}
|
|
1700
|
-
__name(getMSafeConfig, "getMSafeConfig");
|
|
1701
1790
|
|
|
1702
1791
|
// src/globals/MSafeGlobals.ts
|
|
1703
1792
|
var MSafeGlobals = class _MSafeGlobals {
|
|
1704
|
-
static {
|
|
1705
|
-
__name(this, "MSafeGlobals");
|
|
1706
|
-
}
|
|
1707
1793
|
backend;
|
|
1708
1794
|
suiClient;
|
|
1709
1795
|
config;
|
|
@@ -1745,15 +1831,11 @@ var MSafeGlobals = class _MSafeGlobals {
|
|
|
1745
1831
|
|
|
1746
1832
|
// src/core/MSafeClient.ts
|
|
1747
1833
|
var MSafeClient = class _MSafeClient {
|
|
1748
|
-
static {
|
|
1749
|
-
__name(this, "MSafeClient");
|
|
1750
|
-
}
|
|
1751
|
-
globals;
|
|
1752
|
-
_creationHelper;
|
|
1753
|
-
_publicKeyHelper;
|
|
1754
1834
|
constructor(globals) {
|
|
1755
1835
|
this.globals = globals;
|
|
1756
1836
|
}
|
|
1837
|
+
_creationHelper;
|
|
1838
|
+
_publicKeyHelper;
|
|
1757
1839
|
static async New(env, options) {
|
|
1758
1840
|
const globals = await MSafeGlobals.New(env, options);
|
|
1759
1841
|
return new _MSafeClient(globals);
|
|
@@ -1788,10 +1870,7 @@ var MSafeClient = class _MSafeClient {
|
|
|
1788
1870
|
return this.globals.backend.getUserInfo();
|
|
1789
1871
|
}
|
|
1790
1872
|
async ownedMSafe(pagination) {
|
|
1791
|
-
return this.globals.backend.getOwnedMSafeByStatus({
|
|
1792
|
-
status: UserMSafeStatus2.active,
|
|
1793
|
-
pagination
|
|
1794
|
-
});
|
|
1873
|
+
return this.globals.backend.getOwnedMSafeByStatus({ status: UserMSafeStatus2.active, pagination });
|
|
1795
1874
|
}
|
|
1796
1875
|
async createAccount(info) {
|
|
1797
1876
|
return this.creationHelper.submitMSafeCreation(info);
|
|
@@ -1841,43 +1920,32 @@ var MSafeClient = class _MSafeClient {
|
|
|
1841
1920
|
};
|
|
1842
1921
|
|
|
1843
1922
|
// src/backend/types/notification.ts
|
|
1844
|
-
var InfoTypeKey
|
|
1845
|
-
(function(InfoTypeKey2) {
|
|
1923
|
+
var InfoTypeKey = /* @__PURE__ */ ((InfoTypeKey2) => {
|
|
1846
1924
|
InfoTypeKey2["receive"] = "info_type_receive";
|
|
1847
1925
|
InfoTypeKey2["send"] = "info_type_send";
|
|
1848
1926
|
InfoTypeKey2["invitation"] = "info_type_invitation";
|
|
1849
1927
|
InfoTypeKey2["awaitApproval"] = "info_type_await_approval";
|
|
1850
|
-
|
|
1928
|
+
return InfoTypeKey2;
|
|
1929
|
+
})(InfoTypeKey || {});
|
|
1851
1930
|
var NotificationSubscribeDto = class {
|
|
1852
|
-
static {
|
|
1853
|
-
__name(this, "NotificationSubscribeDto");
|
|
1854
|
-
}
|
|
1855
1931
|
email;
|
|
1856
1932
|
};
|
|
1857
1933
|
var NotificationUpdateDto = class {
|
|
1858
|
-
static {
|
|
1859
|
-
__name(this, "NotificationUpdateDto");
|
|
1860
|
-
}
|
|
1861
1934
|
email;
|
|
1862
1935
|
infoTypes;
|
|
1863
1936
|
msafeEnabled;
|
|
1864
1937
|
};
|
|
1865
1938
|
var InfoTypeEnabledDto = class {
|
|
1866
|
-
static {
|
|
1867
|
-
__name(this, "InfoTypeEnabledDto");
|
|
1868
|
-
}
|
|
1869
1939
|
infoType;
|
|
1870
1940
|
enabled;
|
|
1871
1941
|
};
|
|
1872
1942
|
var MSafeEnabledDto = class {
|
|
1873
|
-
static {
|
|
1874
|
-
__name(this, "MSafeEnabledDto");
|
|
1875
|
-
}
|
|
1876
1943
|
msafeAddress;
|
|
1877
1944
|
enabled;
|
|
1878
1945
|
};
|
|
1879
1946
|
export {
|
|
1880
1947
|
AddressBookSDK,
|
|
1948
|
+
COIN_RESERVATION_MAGIC,
|
|
1881
1949
|
COIN_TYPE_ARG_REGEX,
|
|
1882
1950
|
Coin,
|
|
1883
1951
|
CoinHelper,
|
|
@@ -1889,6 +1957,7 @@ export {
|
|
|
1889
1957
|
HexToUint8Array,
|
|
1890
1958
|
InfoTypeEnabledDto,
|
|
1891
1959
|
InfoTypeKey,
|
|
1960
|
+
InsufficientGasFundsError,
|
|
1892
1961
|
LOCAL_API_URL,
|
|
1893
1962
|
LOCAL_SYNCING_URL,
|
|
1894
1963
|
MAINNET_RPC_URL,
|
|
@@ -1906,11 +1975,18 @@ export {
|
|
|
1906
1975
|
TESTNET_RPC_URL,
|
|
1907
1976
|
Uint8ArrayToHex,
|
|
1908
1977
|
addPrefix,
|
|
1978
|
+
computeGasBudget,
|
|
1979
|
+
createCoinReservationRef,
|
|
1980
|
+
estimateGasBudget,
|
|
1909
1981
|
getAllCoins,
|
|
1910
1982
|
getMSafeConfig,
|
|
1911
1983
|
getPublicKeyFromChain,
|
|
1912
1984
|
httpUrlToGrpcBaseUrl,
|
|
1985
|
+
isCoinReservationDigest,
|
|
1913
1986
|
msafeChainToSuiNetwork,
|
|
1987
|
+
preferClassicGasPayment,
|
|
1988
|
+
prepareGasFunding,
|
|
1989
|
+
selectGasFunding,
|
|
1914
1990
|
stringToBuffer,
|
|
1915
1991
|
toSuiTransaction
|
|
1916
1992
|
};
|