@msafe/sui3-sdk 1.0.7 → 1.0.8
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 +195 -59
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +53 -24
- package/dist/index.d.ts +53 -24
- package/dist/index.js +195 -59
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -63,6 +63,7 @@ __export(src_exports, {
|
|
|
63
63
|
getAllCoins: () => getAllCoins,
|
|
64
64
|
getMSafeConfig: () => getMSafeConfig,
|
|
65
65
|
getPublicKeyFromChain: () => getPublicKeyFromChain,
|
|
66
|
+
httpUrlToGrpcBaseUrl: () => httpUrlToGrpcBaseUrl,
|
|
66
67
|
msafeChainToSuiNetwork: () => msafeChainToSuiNetwork,
|
|
67
68
|
stringToBuffer: () => stringToBuffer,
|
|
68
69
|
toSuiTransaction: () => toSuiTransaction
|
|
@@ -221,6 +222,23 @@ var import_wallet_standard = require("@mysten/wallet-standard");
|
|
|
221
222
|
// src/simulate/simulator.ts
|
|
222
223
|
var import_transactions = require("@mysten/sui/transactions");
|
|
223
224
|
var GAS_SAFE_OVERHEAD = 1000n;
|
|
225
|
+
function formatExecutionError(error) {
|
|
226
|
+
return error.message;
|
|
227
|
+
}
|
|
228
|
+
__name(formatExecutionError, "formatExecutionError");
|
|
229
|
+
function gasObjectToReference(gas) {
|
|
230
|
+
if (!gas?.objectId) {
|
|
231
|
+
throw new Error("Gas object missing from simulation effects");
|
|
232
|
+
}
|
|
233
|
+
const version = gas.outputVersion ?? gas.inputVersion ?? "0";
|
|
234
|
+
const digest = gas.outputDigest ?? gas.inputDigest ?? "";
|
|
235
|
+
return {
|
|
236
|
+
objectId: gas.objectId,
|
|
237
|
+
version,
|
|
238
|
+
digest
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
__name(gasObjectToReference, "gasObjectToReference");
|
|
224
242
|
var Simulator = class {
|
|
225
243
|
static {
|
|
226
244
|
__name(this, "Simulator");
|
|
@@ -234,32 +252,63 @@ var Simulator = class {
|
|
|
234
252
|
const { suiClient } = this.globals;
|
|
235
253
|
const gasPrice = await this.getGasPrice();
|
|
236
254
|
tx.setGasPrice(gasPrice);
|
|
237
|
-
|
|
238
|
-
|
|
255
|
+
let built;
|
|
256
|
+
try {
|
|
257
|
+
built = await tx.build({
|
|
239
258
|
client: suiClient
|
|
240
|
-
})
|
|
241
|
-
})
|
|
242
|
-
|
|
259
|
+
});
|
|
260
|
+
} catch (e) {
|
|
261
|
+
const message = e instanceof Error ? e.message : String(e);
|
|
262
|
+
return {
|
|
263
|
+
success: false,
|
|
264
|
+
gasPrice,
|
|
265
|
+
simulationError: message
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
let inspectResult;
|
|
269
|
+
try {
|
|
270
|
+
inspectResult = await suiClient.simulateTransaction({
|
|
271
|
+
transaction: built,
|
|
272
|
+
include: {
|
|
273
|
+
effects: true
|
|
274
|
+
}
|
|
275
|
+
});
|
|
276
|
+
} catch (e) {
|
|
277
|
+
const message = e instanceof Error ? e.message : String(e);
|
|
278
|
+
return {
|
|
279
|
+
success: false,
|
|
280
|
+
gasPrice,
|
|
281
|
+
simulationError: message
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
const txRow = inspectResult.Transaction ?? inspectResult.FailedTransaction;
|
|
285
|
+
const { effects } = txRow;
|
|
286
|
+
if (!effects) {
|
|
287
|
+
throw new Error("simulateTransaction did not return effects");
|
|
288
|
+
}
|
|
289
|
+
const success = effects.status.success === true;
|
|
243
290
|
if (!success) {
|
|
291
|
+
const err = effects.status.success === false ? effects.status.error : null;
|
|
244
292
|
return {
|
|
245
293
|
success,
|
|
246
294
|
gasPrice,
|
|
247
295
|
response: inspectResult,
|
|
248
|
-
simulationError:
|
|
296
|
+
simulationError: err ? formatExecutionError(err) : "Simulation failed"
|
|
249
297
|
};
|
|
250
298
|
}
|
|
251
|
-
const gasBudget = this.toGasBudget(
|
|
299
|
+
const gasBudget = this.toGasBudget(effects.gasUsed, gasPrice);
|
|
252
300
|
return {
|
|
253
301
|
success,
|
|
254
302
|
gasPrice,
|
|
255
|
-
gasObject:
|
|
256
|
-
gasUsed:
|
|
303
|
+
gasObject: gasObjectToReference(effects.gasObject),
|
|
304
|
+
gasUsed: effects.gasUsed,
|
|
257
305
|
gasBudget,
|
|
258
306
|
response: inspectResult
|
|
259
307
|
};
|
|
260
308
|
}
|
|
261
309
|
async getGasPrice() {
|
|
262
|
-
|
|
310
|
+
const { referenceGasPrice } = await this.globals.suiClient.getReferenceGasPrice();
|
|
311
|
+
return BigInt(referenceGasPrice);
|
|
263
312
|
}
|
|
264
313
|
toGasBudget(gasUsed, gasPrice) {
|
|
265
314
|
const { computationCost, storageCost, storageRebate } = gasUsed;
|
|
@@ -321,7 +370,7 @@ var CoinHelper = class {
|
|
|
321
370
|
const res = await this._client.getCoinMetadata({
|
|
322
371
|
coinType
|
|
323
372
|
});
|
|
324
|
-
return res
|
|
373
|
+
return res.coinMetadata ?? void 0;
|
|
325
374
|
}
|
|
326
375
|
};
|
|
327
376
|
var COIN_TYPE_ARG_REGEX = /^0x0000000000000000000000000000000000000000000000000000000000000002::coin::Coin<(.+)>$/;
|
|
@@ -343,6 +392,13 @@ var Coin = class _Coin {
|
|
|
343
392
|
if (!_Coin.isCoin(data.type)) {
|
|
344
393
|
return void 0;
|
|
345
394
|
}
|
|
395
|
+
if (data.json && typeof data.json === "object" && "balance" in data.json) {
|
|
396
|
+
const { balance: balance2 } = data.json;
|
|
397
|
+
if (balance2 === void 0) {
|
|
398
|
+
return void 0;
|
|
399
|
+
}
|
|
400
|
+
return BigInt(balance2);
|
|
401
|
+
}
|
|
346
402
|
if (data.content?.dataType !== "moveObject") {
|
|
347
403
|
return void 0;
|
|
348
404
|
}
|
|
@@ -428,29 +484,82 @@ var SignatureVerifier = class _SignatureVerifier {
|
|
|
428
484
|
// src/utils/sui.ts
|
|
429
485
|
var import_sui3_utils3 = require("@msafe/sui3-utils");
|
|
430
486
|
var import_cryptography = require("@mysten/sui/cryptography");
|
|
487
|
+
var import_graphql = require("@mysten/sui/graphql");
|
|
431
488
|
var import_multisig = require("@mysten/sui/multisig");
|
|
432
489
|
var SUI_COIN = "0x2::sui::SUI";
|
|
490
|
+
var GRAPHQL_URL_BY_NETWORK = {
|
|
491
|
+
mainnet: "https://sui-mainnet.mystenlabs.com/graphql",
|
|
492
|
+
testnet: "https://sui-testnet.mystenlabs.com/graphql",
|
|
493
|
+
devnet: "https://sui-devnet.mystenlabs.com/graphql"
|
|
494
|
+
};
|
|
495
|
+
function graphqlClientForGrpc(suiClient) {
|
|
496
|
+
const url = GRAPHQL_URL_BY_NETWORK[suiClient.network] ?? GRAPHQL_URL_BY_NETWORK.testnet;
|
|
497
|
+
return new import_graphql.SuiGraphQLClient({
|
|
498
|
+
url,
|
|
499
|
+
network: suiClient.network
|
|
500
|
+
});
|
|
501
|
+
}
|
|
502
|
+
__name(graphqlClientForGrpc, "graphqlClientForGrpc");
|
|
503
|
+
function collectSignatureStrings(value) {
|
|
504
|
+
if (typeof value === "string") {
|
|
505
|
+
return [
|
|
506
|
+
value
|
|
507
|
+
];
|
|
508
|
+
}
|
|
509
|
+
if (!value || typeof value !== "object") {
|
|
510
|
+
return [];
|
|
511
|
+
}
|
|
512
|
+
if ("base64" in value && typeof value.base64 === "string") {
|
|
513
|
+
return [
|
|
514
|
+
value.base64
|
|
515
|
+
];
|
|
516
|
+
}
|
|
517
|
+
if ("scheme" in value && "base64" in value) {
|
|
518
|
+
const b64 = value.base64;
|
|
519
|
+
return typeof b64 === "string" ? [
|
|
520
|
+
b64
|
|
521
|
+
] : [];
|
|
522
|
+
}
|
|
523
|
+
return [];
|
|
524
|
+
}
|
|
525
|
+
__name(collectSignatureStrings, "collectSignatureStrings");
|
|
526
|
+
var TX_SIG_QUERY = `
|
|
527
|
+
query PublicKeyTxSigs($sender: SuiAddress!, $first: Int!) {
|
|
528
|
+
transactions(first: $first, filter: { sentAddress: $sender }) {
|
|
529
|
+
nodes {
|
|
530
|
+
signatures
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
`;
|
|
433
535
|
async function getPublicKeyFromChain(suiClient, address) {
|
|
536
|
+
const graphql = graphqlClientForGrpc(suiClient);
|
|
434
537
|
let txs;
|
|
435
538
|
try {
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
showInput: true
|
|
443
|
-
},
|
|
444
|
-
limit: 2
|
|
539
|
+
const res = await graphql.query({
|
|
540
|
+
query: TX_SIG_QUERY,
|
|
541
|
+
variables: {
|
|
542
|
+
sender: address,
|
|
543
|
+
first: 2
|
|
544
|
+
}
|
|
445
545
|
});
|
|
546
|
+
if (res.errors?.length) {
|
|
547
|
+
return void 0;
|
|
548
|
+
}
|
|
549
|
+
txs = res.data ?? {};
|
|
446
550
|
} catch (e) {
|
|
447
551
|
return void 0;
|
|
448
552
|
}
|
|
449
|
-
|
|
553
|
+
const nodes = txs.transactions?.nodes ?? [];
|
|
554
|
+
if (nodes.length === 0) {
|
|
555
|
+
return void 0;
|
|
556
|
+
}
|
|
557
|
+
const first = nodes[0];
|
|
558
|
+
const rawSigs = first.signatures;
|
|
559
|
+
const signatures = Array.isArray(rawSigs) ? rawSigs.flatMap((item) => collectSignatureStrings(item)) : [];
|
|
560
|
+
if (signatures.length === 0) {
|
|
450
561
|
return void 0;
|
|
451
562
|
}
|
|
452
|
-
const tx = txs.data[0];
|
|
453
|
-
const signatures = tx.transaction?.txSignatures;
|
|
454
563
|
for (let i = 0; i !== signatures.length; i++) {
|
|
455
564
|
const serializedSig = signatures[i];
|
|
456
565
|
const pk = getAddressFromSignatures(serializedSig, address);
|
|
@@ -495,14 +604,14 @@ async function getAllCoins(input) {
|
|
|
495
604
|
let cursor;
|
|
496
605
|
const res = [];
|
|
497
606
|
while (hasNext) {
|
|
498
|
-
const currentPage = await input.suiClient.
|
|
607
|
+
const currentPage = await input.suiClient.listCoins({
|
|
499
608
|
owner: input.owner,
|
|
500
609
|
coinType: input.coinType,
|
|
501
610
|
cursor
|
|
502
611
|
});
|
|
503
|
-
res.push(...currentPage.
|
|
612
|
+
res.push(...currentPage.objects);
|
|
504
613
|
hasNext = currentPage.hasNextPage;
|
|
505
|
-
cursor = currentPage.
|
|
614
|
+
cursor = currentPage.cursor;
|
|
506
615
|
}
|
|
507
616
|
return res;
|
|
508
617
|
}
|
|
@@ -604,6 +713,16 @@ var EntryIterator = class {
|
|
|
604
713
|
};
|
|
605
714
|
|
|
606
715
|
// src/utils/iter/object.ts
|
|
716
|
+
var defaultObjectInclude = {
|
|
717
|
+
json: true
|
|
718
|
+
};
|
|
719
|
+
function mergeInclude(options) {
|
|
720
|
+
return {
|
|
721
|
+
...defaultObjectInclude,
|
|
722
|
+
...options?.objectInclude
|
|
723
|
+
};
|
|
724
|
+
}
|
|
725
|
+
__name(mergeInclude, "mergeInclude");
|
|
607
726
|
async function getAllOwnedObjects(provider, owner, options) {
|
|
608
727
|
const iter = new OwnedObjectIterator(provider, owner, options);
|
|
609
728
|
return await getAllFromIterator(iter);
|
|
@@ -633,7 +752,7 @@ var OwnedObjectRequester = class {
|
|
|
633
752
|
nextCursor;
|
|
634
753
|
filter;
|
|
635
754
|
pageSize;
|
|
636
|
-
|
|
755
|
+
objectInclude;
|
|
637
756
|
constructor(provider, owner, options) {
|
|
638
757
|
this.provider = provider;
|
|
639
758
|
this.owner = owner;
|
|
@@ -641,28 +760,25 @@ var OwnedObjectRequester = class {
|
|
|
641
760
|
this.nextCursor = null;
|
|
642
761
|
this.filter = options?.filter;
|
|
643
762
|
this.pageSize = options?.pageSize || REQUEST_PAGE_SIZE;
|
|
644
|
-
this.
|
|
645
|
-
showType: true,
|
|
646
|
-
showContent: true
|
|
647
|
-
};
|
|
763
|
+
this.objectInclude = mergeInclude(options);
|
|
648
764
|
}
|
|
649
765
|
async doNextRequest() {
|
|
650
|
-
const res = await this.provider.
|
|
766
|
+
const res = await this.provider.listOwnedObjects({
|
|
651
767
|
owner: this.owner,
|
|
652
|
-
|
|
768
|
+
include: this.objectInclude,
|
|
653
769
|
cursor: this.nextCursor,
|
|
654
770
|
limit: this.pageSize
|
|
655
771
|
});
|
|
656
|
-
this.nextCursor = res.
|
|
772
|
+
this.nextCursor = res.cursor;
|
|
657
773
|
let filtered;
|
|
658
774
|
if (this.filter) {
|
|
659
775
|
const { filter } = this;
|
|
660
|
-
filtered = res.
|
|
776
|
+
filtered = res.objects.filter((obj) => filter(obj));
|
|
661
777
|
} else {
|
|
662
|
-
filtered = res.
|
|
778
|
+
filtered = res.objects;
|
|
663
779
|
}
|
|
664
780
|
return {
|
|
665
|
-
data: filtered
|
|
781
|
+
data: filtered,
|
|
666
782
|
hasNext: res.hasNextPage
|
|
667
783
|
};
|
|
668
784
|
}
|
|
@@ -697,23 +813,31 @@ var MSafeAccount = class _MSafeAccount {
|
|
|
697
813
|
}
|
|
698
814
|
}
|
|
699
815
|
async ownedCoins() {
|
|
700
|
-
const balances =
|
|
701
|
-
|
|
702
|
-
|
|
816
|
+
const balances = [];
|
|
817
|
+
let cursor = null;
|
|
818
|
+
let hasNext = true;
|
|
819
|
+
while (hasNext) {
|
|
820
|
+
const page = await this.suiClient.listBalances({
|
|
821
|
+
owner: this.address,
|
|
822
|
+
cursor,
|
|
823
|
+
limit: 50
|
|
824
|
+
});
|
|
825
|
+
balances.push(...page.balances);
|
|
826
|
+
hasNext = page.hasNextPage;
|
|
827
|
+
cursor = page.cursor;
|
|
828
|
+
}
|
|
703
829
|
return Promise.all(balances.map(async (balance) => {
|
|
704
830
|
const meta = await this.coinHelper.getCoinMeta(balance.coinType);
|
|
705
|
-
const lockedEntry = balance.lockedBalance && typeof balance.lockedBalance === "object" && "number" in balance.lockedBalance && balance.lockedBalance.number ? BigInt(balance.lockedBalance.number) : 0n;
|
|
706
|
-
const unlockedBalance = lockedEntry ? BigInt(balance.totalBalance) - lockedEntry : BigInt(balance.totalBalance);
|
|
707
831
|
return {
|
|
708
832
|
type: (0, import_utils3.normalizeStructTag)(balance.coinType),
|
|
709
|
-
balance:
|
|
833
|
+
balance: BigInt(balance.addressBalance),
|
|
710
834
|
metadata: meta
|
|
711
835
|
};
|
|
712
836
|
}));
|
|
713
837
|
}
|
|
714
838
|
async ownedObjects(options) {
|
|
715
839
|
const filterCoinObjectOptions = {
|
|
716
|
-
filter: (
|
|
840
|
+
filter: (obj) => !obj?.type?.startsWith("0x2::coin::Coin"),
|
|
717
841
|
...options
|
|
718
842
|
};
|
|
719
843
|
return getAllOwnedObjects(this.suiClient, this.address, filterCoinObjectOptions);
|
|
@@ -1034,12 +1158,14 @@ var MSafeAccount = class _MSafeAccount {
|
|
|
1034
1158
|
}
|
|
1035
1159
|
}
|
|
1036
1160
|
const multiSignature = this.multiSig.combinePartialSignatures(sortedSigs);
|
|
1037
|
-
return this.suiClient.
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1161
|
+
return this.suiClient.executeTransaction({
|
|
1162
|
+
transaction: HexToUint8Array(payload),
|
|
1163
|
+
signatures: [
|
|
1164
|
+
multiSignature
|
|
1165
|
+
],
|
|
1166
|
+
include: {
|
|
1167
|
+
effects: true,
|
|
1168
|
+
events: true
|
|
1043
1169
|
}
|
|
1044
1170
|
});
|
|
1045
1171
|
}
|
|
@@ -1174,7 +1300,7 @@ var ReportSDK = class {
|
|
|
1174
1300
|
};
|
|
1175
1301
|
|
|
1176
1302
|
// src/globals/MSafeGlobals.ts
|
|
1177
|
-
var
|
|
1303
|
+
var import_grpc = require("@mysten/sui/grpc");
|
|
1178
1304
|
|
|
1179
1305
|
// src/backend/BackendImpl.ts
|
|
1180
1306
|
var import_sui3_utils6 = require("@msafe/sui3-utils");
|
|
@@ -1531,6 +1657,17 @@ var MSafeEnv;
|
|
|
1531
1657
|
MSafeEnv2["prev"] = "prev";
|
|
1532
1658
|
MSafeEnv2["prod"] = "prod";
|
|
1533
1659
|
})(MSafeEnv || (MSafeEnv = {}));
|
|
1660
|
+
function httpUrlToGrpcBaseUrl(url) {
|
|
1661
|
+
const parsed = new URL(url);
|
|
1662
|
+
if (parsed.protocol === "https:" && parsed.port === "") {
|
|
1663
|
+
return `https://${parsed.hostname}:443${parsed.pathname}${parsed.search}`;
|
|
1664
|
+
}
|
|
1665
|
+
if (parsed.protocol === "http:" && parsed.port === "") {
|
|
1666
|
+
return `http://${parsed.hostname}:80${parsed.pathname}${parsed.search}`;
|
|
1667
|
+
}
|
|
1668
|
+
return `${parsed.origin}${parsed.pathname}${parsed.search}`;
|
|
1669
|
+
}
|
|
1670
|
+
__name(httpUrlToGrpcBaseUrl, "httpUrlToGrpcBaseUrl");
|
|
1534
1671
|
var TESTNET_RPC_URL = "https://fullnode.testnet.sui.io";
|
|
1535
1672
|
var MAINNET_RPC_URL = "https://fullnode.mainnet.sui.io";
|
|
1536
1673
|
var LOCAL_API_URL = "http://127.0.0.1:3000";
|
|
@@ -1547,9 +1684,9 @@ var ENV_CONFIGS = /* @__PURE__ */ new Map([
|
|
|
1547
1684
|
url: TESTNET_RPC_URL
|
|
1548
1685
|
},
|
|
1549
1686
|
backend: {
|
|
1550
|
-
url:
|
|
1687
|
+
url: DEV_API_URL
|
|
1551
1688
|
},
|
|
1552
|
-
syncingURL:
|
|
1689
|
+
syncingURL: DEV_SYNCING_URL,
|
|
1553
1690
|
network: "sui:testnet"
|
|
1554
1691
|
}
|
|
1555
1692
|
],
|
|
@@ -1640,12 +1777,11 @@ var MSafeGlobals = class _MSafeGlobals {
|
|
|
1640
1777
|
}
|
|
1641
1778
|
static async New(env, options) {
|
|
1642
1779
|
const config = getMSafeConfig(env, options);
|
|
1643
|
-
const suiClient = new
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
},
|
|
1780
|
+
const suiClient = config.suiClient.transport ? new import_grpc.SuiGrpcClient({
|
|
1781
|
+
transport: config.suiClient.transport,
|
|
1782
|
+
network: msafeChainToSuiNetwork(config.network)
|
|
1783
|
+
}) : new import_grpc.SuiGrpcClient({
|
|
1784
|
+
baseUrl: httpUrlToGrpcBaseUrl(config.suiClient.url),
|
|
1649
1785
|
network: msafeChainToSuiNetwork(config.network)
|
|
1650
1786
|
});
|
|
1651
1787
|
const backend = new BackendImpl(config.backend.url, options?.mockAddress);
|