@msafe/sui3-sdk 0.0.17 → 0.0.19
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 +58 -219
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -38
- package/dist/index.d.ts +4 -38
- package/dist/index.js +61 -219
- package/dist/index.js.map +1 -1
- package/package.json +3 -2
- package/src/backend/BackendImpl.ts +1 -1
- package/src/backend/interface.ts +1 -2
- package/src/core/MSafeAccount.ts +7 -11
- package/src/index.ts +0 -1
- package/src/types/msafe.ts +1 -3
- package/src/transactions/coin-transfer.ts +0 -64
- package/src/transactions/index.ts +0 -3
- package/src/transactions/intention.ts +0 -63
- package/src/transactions/object-transfer.ts +0 -66
- package/src/transactions/reject.ts +0 -17
- package/src/transactions/stream.ts +0 -1
package/dist/index.js
CHANGED
|
@@ -100,13 +100,26 @@ import {
|
|
|
100
100
|
SigningMessageHelper as SigningMessageHelper3,
|
|
101
101
|
TransactionDefaultApplication,
|
|
102
102
|
TransactionSubTypes,
|
|
103
|
-
TransactionType
|
|
103
|
+
TransactionType,
|
|
104
|
+
buildObjectTransferTxb,
|
|
105
|
+
buildRejectTxb
|
|
104
106
|
} from "@msafe/sui3-utils";
|
|
105
|
-
import { TransactionBlock
|
|
107
|
+
import { TransactionBlock } from "@mysten/sui.js/transactions";
|
|
106
108
|
import { normalizeStructTag as normalizeStructTag3 } from "@mysten/sui.js/utils";
|
|
107
109
|
|
|
108
|
-
// src/
|
|
109
|
-
|
|
110
|
+
// src/utils/buffer.ts
|
|
111
|
+
function stringToBuffer(s) {
|
|
112
|
+
return Buffer.from(s, "utf-8");
|
|
113
|
+
}
|
|
114
|
+
function Uint8ArrayToHex(b) {
|
|
115
|
+
return `0x${Array.prototype.map.call(b, (x) => `0${x.toString(16)}`.slice(-2)).join("")}`;
|
|
116
|
+
}
|
|
117
|
+
function HexToUint8Array(hex) {
|
|
118
|
+
return Uint8Array.from(Buffer.from(hex.startsWith("0x") ? hex.slice(2) : hex, "hex"));
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// src/utils/crypto.ts
|
|
122
|
+
import { verifyPersonalMessage, verifyTransactionBlock } from "@mysten/sui.js/verify";
|
|
110
123
|
|
|
111
124
|
// src/utils/format.ts
|
|
112
125
|
import { normalizeSuiAddress, normalizeStructTag as normalizeStructTag2 } from "@mysten/sui.js/utils";
|
|
@@ -182,6 +195,45 @@ var Formatter = class {
|
|
|
182
195
|
}
|
|
183
196
|
};
|
|
184
197
|
|
|
198
|
+
// src/utils/crypto.ts
|
|
199
|
+
var SignatureVerifier = class _SignatureVerifier {
|
|
200
|
+
static async getPublicKeyFromSignature(input) {
|
|
201
|
+
if (input.messageType === "TransactionBlock") {
|
|
202
|
+
return verifyTransactionBlock(input.message, input.signature);
|
|
203
|
+
}
|
|
204
|
+
return verifyPersonalMessage(input.message, input.signature);
|
|
205
|
+
}
|
|
206
|
+
static async getPublicKeyFromPersonalSignature(input) {
|
|
207
|
+
const message = stringToBuffer(input.messageStr);
|
|
208
|
+
return this.getPublicKeyFromSignature({
|
|
209
|
+
message,
|
|
210
|
+
messageType: "Personal",
|
|
211
|
+
signature: input.signature
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
static async verifySignature(input) {
|
|
215
|
+
const publicKey = await _SignatureVerifier.getPublicKeyFromSignature(input);
|
|
216
|
+
return Formatter.isSuiAddressEqual(publicKey.toSuiAddress(), input.targetAddress);
|
|
217
|
+
}
|
|
218
|
+
static async verifyPersonalSignature(input) {
|
|
219
|
+
const message = stringToBuffer(input.messageStr);
|
|
220
|
+
return this.verifySignature({
|
|
221
|
+
message,
|
|
222
|
+
messageType: "Personal",
|
|
223
|
+
signature: input.signature,
|
|
224
|
+
targetAddress: input.targetAddress
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
static async verifyTransactionSignature(input) {
|
|
228
|
+
return this.verifySignature({
|
|
229
|
+
messageType: "TransactionBlock",
|
|
230
|
+
message: input.payload,
|
|
231
|
+
signature: input.signature,
|
|
232
|
+
targetAddress: input.targetAddress
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
};
|
|
236
|
+
|
|
185
237
|
// src/utils/sui.ts
|
|
186
238
|
import { PublicKeySerde as PublicKeySerde2 } from "@msafe/sui3-utils";
|
|
187
239
|
import { parseSerializedSignature } from "@mysten/sui.js/cryptography";
|
|
@@ -260,209 +312,6 @@ async function getAllCoins(input) {
|
|
|
260
312
|
return res;
|
|
261
313
|
}
|
|
262
314
|
|
|
263
|
-
// src/transactions/coin-transfer.ts
|
|
264
|
-
async function buildCoinTransferTxb(input) {
|
|
265
|
-
if (Formatter.isSuiStructEqual(input.intention.coinType, SUI_COIN)) {
|
|
266
|
-
return buildSuiCoinTransferTxb(input);
|
|
267
|
-
}
|
|
268
|
-
return buildOtherCoinTransferTxb(input);
|
|
269
|
-
}
|
|
270
|
-
function buildSuiCoinTransferTxb(input) {
|
|
271
|
-
const txb = new TransactionBlock();
|
|
272
|
-
const [coin] = txb.splitCoins(txb.gas, [txb.pure(input.intention.amount)]);
|
|
273
|
-
txb.transferObjects([coin], txb.pure(input.intention.recipient));
|
|
274
|
-
txb.setSender(input.sender);
|
|
275
|
-
return txb;
|
|
276
|
-
}
|
|
277
|
-
async function buildOtherCoinTransferTxb(input) {
|
|
278
|
-
const { suiClient, sender, intention } = input;
|
|
279
|
-
const objs = await getAllCoins({
|
|
280
|
-
suiClient,
|
|
281
|
-
owner: sender,
|
|
282
|
-
coinType: intention.coinType
|
|
283
|
-
});
|
|
284
|
-
if (objs.length === 0) {
|
|
285
|
-
throw new Error("No valid coin found to send");
|
|
286
|
-
}
|
|
287
|
-
const totalBal = objs.reduce((sum, coin2) => sum + BigInt(coin2.balance), 0n);
|
|
288
|
-
if (totalBal < BigInt(intention.amount)) {
|
|
289
|
-
throw new Error("Not enough balance");
|
|
290
|
-
}
|
|
291
|
-
const txb = new TransactionBlock();
|
|
292
|
-
const primary = txb.object(objs[0].coinObjectId);
|
|
293
|
-
if (objs.length > 1) {
|
|
294
|
-
txb.mergeCoins(
|
|
295
|
-
primary,
|
|
296
|
-
objs.slice(1).map((obj) => txb.object(obj.coinObjectId))
|
|
297
|
-
);
|
|
298
|
-
}
|
|
299
|
-
const [coin] = txb.splitCoins(primary, [txb.pure(intention.amount)]);
|
|
300
|
-
txb.transferObjects([coin], txb.pure(intention.recipient));
|
|
301
|
-
txb.setSender(input.sender);
|
|
302
|
-
return txb;
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
// src/transactions/object-transfer.ts
|
|
306
|
-
import { TransactionBlock as TransactionBlock2 } from "@mysten/sui.js/transactions";
|
|
307
|
-
async function buildObjectTransferTxb(input) {
|
|
308
|
-
await validateObjectTransfer(input);
|
|
309
|
-
const txb = new TransactionBlock2();
|
|
310
|
-
txb.transferObjects([txb.object(input.intention.objectId)], txb.pure(input.intention.receiver));
|
|
311
|
-
txb.setSender(input.sender);
|
|
312
|
-
return txb;
|
|
313
|
-
}
|
|
314
|
-
async function validateObjectTransfer(input) {
|
|
315
|
-
const { suiClient, sender, intention } = input;
|
|
316
|
-
const obj = await suiClient.getObject({
|
|
317
|
-
id: intention.objectId
|
|
318
|
-
});
|
|
319
|
-
if (obj.data === void 0) {
|
|
320
|
-
throw new Error("Object not found");
|
|
321
|
-
}
|
|
322
|
-
if (!obj.data?.type) {
|
|
323
|
-
throw new Error("Object type is null");
|
|
324
|
-
}
|
|
325
|
-
if (!Formatter.isSuiStructEqual(obj.data.type, intention.objectType)) {
|
|
326
|
-
throw new Error("Object type not expected");
|
|
327
|
-
}
|
|
328
|
-
if (Formatter.isCoinObjectType(obj.data.type)) {
|
|
329
|
-
throw new Error("Can not transfer coin object in Object Transfer transactions");
|
|
330
|
-
}
|
|
331
|
-
const addressOwner = getAddressOwner(obj);
|
|
332
|
-
if (!Formatter.isSuiAddressEqual(addressOwner, sender)) {
|
|
333
|
-
throw new Error("Object owner not match");
|
|
334
|
-
}
|
|
335
|
-
}
|
|
336
|
-
function getAddressOwner(object) {
|
|
337
|
-
const owner = object.data?.owner;
|
|
338
|
-
if (!owner) {
|
|
339
|
-
throw new Error("Object Owner not found");
|
|
340
|
-
}
|
|
341
|
-
if (typeof owner !== "object" || !("AddressOwner" in owner)) {
|
|
342
|
-
throw new Error("Invalid object owner");
|
|
343
|
-
}
|
|
344
|
-
return owner.AddressOwner;
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
// src/transactions/reject.ts
|
|
348
|
-
import { TransactionBlock as TransactionBlock3 } from "@mysten/sui.js/transactions";
|
|
349
|
-
|
|
350
|
-
// src/utils/buffer.ts
|
|
351
|
-
function stringToBuffer(s) {
|
|
352
|
-
return Buffer.from(s, "utf-8");
|
|
353
|
-
}
|
|
354
|
-
function Uint8ArrayToHex(b) {
|
|
355
|
-
return `0x${Array.prototype.map.call(b, (x) => `0${x.toString(16)}`.slice(-2)).join("")}`;
|
|
356
|
-
}
|
|
357
|
-
function HexToUint8Array(hex) {
|
|
358
|
-
return Uint8Array.from(Buffer.from(hex.startsWith("0x") ? hex.slice(2) : hex, "hex"));
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
// src/transactions/reject.ts
|
|
362
|
-
async function buildRejectTxb(input) {
|
|
363
|
-
const approveTxb = TransactionBlock3.from(HexToUint8Array(input.payloadToReject));
|
|
364
|
-
const gasPayment = approveTxb.blockData.gasConfig.payment;
|
|
365
|
-
if (!gasPayment) {
|
|
366
|
-
throw new Error("No gas payment found for approve payload");
|
|
367
|
-
}
|
|
368
|
-
const txb = new TransactionBlock3();
|
|
369
|
-
txb.setGasPayment(gasPayment);
|
|
370
|
-
txb.setSender(input.sender);
|
|
371
|
-
return txb;
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
// src/transactions/intention.ts
|
|
375
|
-
var IntentionHelper = class {
|
|
376
|
-
static ser(intention) {
|
|
377
|
-
return JSON.stringify(intention);
|
|
378
|
-
}
|
|
379
|
-
static de(val) {
|
|
380
|
-
const intention = JSON.parse(val);
|
|
381
|
-
if (typeof intention !== "object" || !("txType" in intention)) {
|
|
382
|
-
throw new Error(`Failed to deserialize intention: ${val}`);
|
|
383
|
-
}
|
|
384
|
-
return JSON.parse(val);
|
|
385
|
-
}
|
|
386
|
-
// TODO: Add gas option here.
|
|
387
|
-
static buildTxb(input) {
|
|
388
|
-
switch (input.intention.txType) {
|
|
389
|
-
case "CoinTransfer":
|
|
390
|
-
return buildCoinTransferTxb({
|
|
391
|
-
suiClient: input.suiClient,
|
|
392
|
-
sender: input.sender,
|
|
393
|
-
intention: input.intention
|
|
394
|
-
});
|
|
395
|
-
case "ObjectTransfer":
|
|
396
|
-
return buildObjectTransferTxb({
|
|
397
|
-
suiClient: input.suiClient,
|
|
398
|
-
sender: input.sender,
|
|
399
|
-
intention: input.intention
|
|
400
|
-
});
|
|
401
|
-
default:
|
|
402
|
-
throw new Error(`Unknown tx type: ${input.intention}`);
|
|
403
|
-
}
|
|
404
|
-
}
|
|
405
|
-
static getTxType(intention) {
|
|
406
|
-
switch (intention.txType) {
|
|
407
|
-
case "CoinTransfer":
|
|
408
|
-
return {
|
|
409
|
-
txType: "CoinTransfer",
|
|
410
|
-
txSubType: "CoinTransfer"
|
|
411
|
-
};
|
|
412
|
-
case "ObjectTransfer":
|
|
413
|
-
return {
|
|
414
|
-
txType: "ObjectTransfer",
|
|
415
|
-
txSubType: "ObjectTransfer"
|
|
416
|
-
};
|
|
417
|
-
default:
|
|
418
|
-
throw new Error("Unknown intention type");
|
|
419
|
-
}
|
|
420
|
-
}
|
|
421
|
-
static buildRejectTransaction(input) {
|
|
422
|
-
return buildRejectTxb({ sender: input.msafeAddress, payloadToReject: input.payloadToReject });
|
|
423
|
-
}
|
|
424
|
-
};
|
|
425
|
-
|
|
426
|
-
// src/utils/crypto.ts
|
|
427
|
-
import { verifyPersonalMessage, verifyTransactionBlock } from "@mysten/sui.js/verify";
|
|
428
|
-
var SignatureVerifier = class _SignatureVerifier {
|
|
429
|
-
static async getPublicKeyFromSignature(input) {
|
|
430
|
-
if (input.messageType === "TransactionBlock") {
|
|
431
|
-
return verifyTransactionBlock(input.message, input.signature);
|
|
432
|
-
}
|
|
433
|
-
return verifyPersonalMessage(input.message, input.signature);
|
|
434
|
-
}
|
|
435
|
-
static async getPublicKeyFromPersonalSignature(input) {
|
|
436
|
-
const message = stringToBuffer(input.messageStr);
|
|
437
|
-
return this.getPublicKeyFromSignature({
|
|
438
|
-
message,
|
|
439
|
-
messageType: "Personal",
|
|
440
|
-
signature: input.signature
|
|
441
|
-
});
|
|
442
|
-
}
|
|
443
|
-
static async verifySignature(input) {
|
|
444
|
-
const publicKey = await _SignatureVerifier.getPublicKeyFromSignature(input);
|
|
445
|
-
return Formatter.isSuiAddressEqual(publicKey.toSuiAddress(), input.targetAddress);
|
|
446
|
-
}
|
|
447
|
-
static async verifyPersonalSignature(input) {
|
|
448
|
-
const message = stringToBuffer(input.messageStr);
|
|
449
|
-
return this.verifySignature({
|
|
450
|
-
message,
|
|
451
|
-
messageType: "Personal",
|
|
452
|
-
signature: input.signature,
|
|
453
|
-
targetAddress: input.targetAddress
|
|
454
|
-
});
|
|
455
|
-
}
|
|
456
|
-
static async verifyTransactionSignature(input) {
|
|
457
|
-
return this.verifySignature({
|
|
458
|
-
messageType: "TransactionBlock",
|
|
459
|
-
message: input.payload,
|
|
460
|
-
signature: input.signature,
|
|
461
|
-
targetAddress: input.targetAddress
|
|
462
|
-
});
|
|
463
|
-
}
|
|
464
|
-
};
|
|
465
|
-
|
|
466
315
|
// src/utils/iter/iterator.ts
|
|
467
316
|
var REQUEST_PAGE_SIZE = 25;
|
|
468
317
|
async function getAllFromIterator(it) {
|
|
@@ -696,6 +545,7 @@ var MSafeAccount = class _MSafeAccount {
|
|
|
696
545
|
});
|
|
697
546
|
}
|
|
698
547
|
async proposeObjectTransferIntention(intention) {
|
|
548
|
+
await buildObjectTransferTxb(this.suiClient, intention, this.address);
|
|
699
549
|
const sn = await this.nextSequenceNumber();
|
|
700
550
|
return this.proposeIntention({
|
|
701
551
|
application: TransactionDefaultApplication,
|
|
@@ -717,11 +567,7 @@ var MSafeAccount = class _MSafeAccount {
|
|
|
717
567
|
// Shortcut for proposing a transaction to be a pending transaction, and add user vote to it.
|
|
718
568
|
// Requires the multi-sig to be empty in pending transaction.
|
|
719
569
|
async proposePendingTransaction(intention) {
|
|
720
|
-
const txb =
|
|
721
|
-
suiClient: this.suiClient,
|
|
722
|
-
intention,
|
|
723
|
-
sender: this.address
|
|
724
|
-
});
|
|
570
|
+
const txb = new TransactionBlock();
|
|
725
571
|
const payload = await txb.build({ client: this.suiClient });
|
|
726
572
|
const digest = await txb.getDigest({ client: this.suiClient });
|
|
727
573
|
const signature = await this.wallet.signTransactionBlock({ transactionBlock: payload });
|
|
@@ -739,10 +585,7 @@ var MSafeAccount = class _MSafeAccount {
|
|
|
739
585
|
throw new Error("Already rejected");
|
|
740
586
|
}
|
|
741
587
|
const payloadToReject = pendingTx.payload;
|
|
742
|
-
const rejectTxb =
|
|
743
|
-
msafeAddress: this.address,
|
|
744
|
-
payloadToReject
|
|
745
|
-
});
|
|
588
|
+
const rejectTxb = buildRejectTxb(this.address, payloadToReject);
|
|
746
589
|
const digest = await rejectTxb.getDigest({ client: this.suiClient });
|
|
747
590
|
const payload = await rejectTxb.build({ client: this.suiClient });
|
|
748
591
|
const signature = await this.wallet.signTransactionBlock({ transactionBlock: payload });
|
|
@@ -758,8 +601,8 @@ var MSafeAccount = class _MSafeAccount {
|
|
|
758
601
|
async skipNextFailedIntention() {
|
|
759
602
|
return this.backend.skipNextFailedIntention({ msafeAddress: this.address });
|
|
760
603
|
}
|
|
761
|
-
async simulateIntention(
|
|
762
|
-
const txb = new
|
|
604
|
+
async simulateIntention() {
|
|
605
|
+
const txb = new TransactionBlock();
|
|
763
606
|
txb.setSender(this.address);
|
|
764
607
|
if (!txb.blockData.gasConfig.price) {
|
|
765
608
|
const refGas = await this.suiClient.getReferenceGasPrice();
|
|
@@ -1331,7 +1174,6 @@ export {
|
|
|
1331
1174
|
ENV_CONFIGS,
|
|
1332
1175
|
Formatter,
|
|
1333
1176
|
HexToUint8Array,
|
|
1334
|
-
IntentionHelper,
|
|
1335
1177
|
LOCAL_API_URL,
|
|
1336
1178
|
LOCAL_SYNCING_URL,
|
|
1337
1179
|
MAINNET_RPC_URL,
|