@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.js
CHANGED
|
@@ -153,6 +153,23 @@ import { SUI_MAINNET_CHAIN, SUI_TESTNET_CHAIN } from "@mysten/wallet-standard";
|
|
|
153
153
|
// src/simulate/simulator.ts
|
|
154
154
|
import { Transaction } from "@mysten/sui/transactions";
|
|
155
155
|
var GAS_SAFE_OVERHEAD = 1000n;
|
|
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");
|
|
156
173
|
var Simulator = class {
|
|
157
174
|
static {
|
|
158
175
|
__name(this, "Simulator");
|
|
@@ -166,32 +183,63 @@ var Simulator = class {
|
|
|
166
183
|
const { suiClient } = this.globals;
|
|
167
184
|
const gasPrice = await this.getGasPrice();
|
|
168
185
|
tx.setGasPrice(gasPrice);
|
|
169
|
-
|
|
170
|
-
|
|
186
|
+
let built;
|
|
187
|
+
try {
|
|
188
|
+
built = await tx.build({
|
|
171
189
|
client: suiClient
|
|
172
|
-
})
|
|
173
|
-
})
|
|
174
|
-
|
|
190
|
+
});
|
|
191
|
+
} catch (e) {
|
|
192
|
+
const message = e instanceof Error ? e.message : String(e);
|
|
193
|
+
return {
|
|
194
|
+
success: false,
|
|
195
|
+
gasPrice,
|
|
196
|
+
simulationError: message
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
let inspectResult;
|
|
200
|
+
try {
|
|
201
|
+
inspectResult = await suiClient.simulateTransaction({
|
|
202
|
+
transaction: built,
|
|
203
|
+
include: {
|
|
204
|
+
effects: true
|
|
205
|
+
}
|
|
206
|
+
});
|
|
207
|
+
} catch (e) {
|
|
208
|
+
const message = e instanceof Error ? e.message : String(e);
|
|
209
|
+
return {
|
|
210
|
+
success: false,
|
|
211
|
+
gasPrice,
|
|
212
|
+
simulationError: message
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
const txRow = inspectResult.Transaction ?? inspectResult.FailedTransaction;
|
|
216
|
+
const { effects } = txRow;
|
|
217
|
+
if (!effects) {
|
|
218
|
+
throw new Error("simulateTransaction did not return effects");
|
|
219
|
+
}
|
|
220
|
+
const success = effects.status.success === true;
|
|
175
221
|
if (!success) {
|
|
222
|
+
const err = effects.status.success === false ? effects.status.error : null;
|
|
176
223
|
return {
|
|
177
224
|
success,
|
|
178
225
|
gasPrice,
|
|
179
226
|
response: inspectResult,
|
|
180
|
-
simulationError:
|
|
227
|
+
simulationError: err ? formatExecutionError(err) : "Simulation failed"
|
|
181
228
|
};
|
|
182
229
|
}
|
|
183
|
-
const gasBudget = this.toGasBudget(
|
|
230
|
+
const gasBudget = this.toGasBudget(effects.gasUsed, gasPrice);
|
|
184
231
|
return {
|
|
185
232
|
success,
|
|
186
233
|
gasPrice,
|
|
187
|
-
gasObject:
|
|
188
|
-
gasUsed:
|
|
234
|
+
gasObject: gasObjectToReference(effects.gasObject),
|
|
235
|
+
gasUsed: effects.gasUsed,
|
|
189
236
|
gasBudget,
|
|
190
237
|
response: inspectResult
|
|
191
238
|
};
|
|
192
239
|
}
|
|
193
240
|
async getGasPrice() {
|
|
194
|
-
|
|
241
|
+
const { referenceGasPrice } = await this.globals.suiClient.getReferenceGasPrice();
|
|
242
|
+
return BigInt(referenceGasPrice);
|
|
195
243
|
}
|
|
196
244
|
toGasBudget(gasUsed, gasPrice) {
|
|
197
245
|
const { computationCost, storageCost, storageRebate } = gasUsed;
|
|
@@ -253,7 +301,7 @@ var CoinHelper = class {
|
|
|
253
301
|
const res = await this._client.getCoinMetadata({
|
|
254
302
|
coinType
|
|
255
303
|
});
|
|
256
|
-
return res
|
|
304
|
+
return res.coinMetadata ?? void 0;
|
|
257
305
|
}
|
|
258
306
|
};
|
|
259
307
|
var COIN_TYPE_ARG_REGEX = /^0x0000000000000000000000000000000000000000000000000000000000000002::coin::Coin<(.+)>$/;
|
|
@@ -275,6 +323,13 @@ var Coin = class _Coin {
|
|
|
275
323
|
if (!_Coin.isCoin(data.type)) {
|
|
276
324
|
return void 0;
|
|
277
325
|
}
|
|
326
|
+
if (data.json && typeof data.json === "object" && "balance" in data.json) {
|
|
327
|
+
const { balance: balance2 } = data.json;
|
|
328
|
+
if (balance2 === void 0) {
|
|
329
|
+
return void 0;
|
|
330
|
+
}
|
|
331
|
+
return BigInt(balance2);
|
|
332
|
+
}
|
|
278
333
|
if (data.content?.dataType !== "moveObject") {
|
|
279
334
|
return void 0;
|
|
280
335
|
}
|
|
@@ -360,29 +415,82 @@ var SignatureVerifier = class _SignatureVerifier {
|
|
|
360
415
|
// src/utils/sui.ts
|
|
361
416
|
import { PublicKeySerde as PublicKeySerde2 } from "@msafe/sui3-utils";
|
|
362
417
|
import { parseSerializedSignature } from "@mysten/sui/cryptography";
|
|
418
|
+
import { SuiGraphQLClient } from "@mysten/sui/graphql";
|
|
363
419
|
import { MultiSigPublicKey } from "@mysten/sui/multisig";
|
|
364
420
|
var SUI_COIN = "0x2::sui::SUI";
|
|
421
|
+
var GRAPHQL_URL_BY_NETWORK = {
|
|
422
|
+
mainnet: "https://sui-mainnet.mystenlabs.com/graphql",
|
|
423
|
+
testnet: "https://sui-testnet.mystenlabs.com/graphql",
|
|
424
|
+
devnet: "https://sui-devnet.mystenlabs.com/graphql"
|
|
425
|
+
};
|
|
426
|
+
function graphqlClientForGrpc(suiClient) {
|
|
427
|
+
const url = GRAPHQL_URL_BY_NETWORK[suiClient.network] ?? GRAPHQL_URL_BY_NETWORK.testnet;
|
|
428
|
+
return new SuiGraphQLClient({
|
|
429
|
+
url,
|
|
430
|
+
network: suiClient.network
|
|
431
|
+
});
|
|
432
|
+
}
|
|
433
|
+
__name(graphqlClientForGrpc, "graphqlClientForGrpc");
|
|
434
|
+
function collectSignatureStrings(value) {
|
|
435
|
+
if (typeof value === "string") {
|
|
436
|
+
return [
|
|
437
|
+
value
|
|
438
|
+
];
|
|
439
|
+
}
|
|
440
|
+
if (!value || typeof value !== "object") {
|
|
441
|
+
return [];
|
|
442
|
+
}
|
|
443
|
+
if ("base64" in value && typeof value.base64 === "string") {
|
|
444
|
+
return [
|
|
445
|
+
value.base64
|
|
446
|
+
];
|
|
447
|
+
}
|
|
448
|
+
if ("scheme" in value && "base64" in value) {
|
|
449
|
+
const b64 = value.base64;
|
|
450
|
+
return typeof b64 === "string" ? [
|
|
451
|
+
b64
|
|
452
|
+
] : [];
|
|
453
|
+
}
|
|
454
|
+
return [];
|
|
455
|
+
}
|
|
456
|
+
__name(collectSignatureStrings, "collectSignatureStrings");
|
|
457
|
+
var TX_SIG_QUERY = `
|
|
458
|
+
query PublicKeyTxSigs($sender: SuiAddress!, $first: Int!) {
|
|
459
|
+
transactions(first: $first, filter: { sentAddress: $sender }) {
|
|
460
|
+
nodes {
|
|
461
|
+
signatures
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
`;
|
|
365
466
|
async function getPublicKeyFromChain(suiClient, address) {
|
|
467
|
+
const graphql = graphqlClientForGrpc(suiClient);
|
|
366
468
|
let txs;
|
|
367
469
|
try {
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
showInput: true
|
|
375
|
-
},
|
|
376
|
-
limit: 2
|
|
470
|
+
const res = await graphql.query({
|
|
471
|
+
query: TX_SIG_QUERY,
|
|
472
|
+
variables: {
|
|
473
|
+
sender: address,
|
|
474
|
+
first: 2
|
|
475
|
+
}
|
|
377
476
|
});
|
|
477
|
+
if (res.errors?.length) {
|
|
478
|
+
return void 0;
|
|
479
|
+
}
|
|
480
|
+
txs = res.data ?? {};
|
|
378
481
|
} catch (e) {
|
|
379
482
|
return void 0;
|
|
380
483
|
}
|
|
381
|
-
|
|
484
|
+
const nodes = txs.transactions?.nodes ?? [];
|
|
485
|
+
if (nodes.length === 0) {
|
|
486
|
+
return void 0;
|
|
487
|
+
}
|
|
488
|
+
const first = nodes[0];
|
|
489
|
+
const rawSigs = first.signatures;
|
|
490
|
+
const signatures = Array.isArray(rawSigs) ? rawSigs.flatMap((item) => collectSignatureStrings(item)) : [];
|
|
491
|
+
if (signatures.length === 0) {
|
|
382
492
|
return void 0;
|
|
383
493
|
}
|
|
384
|
-
const tx = txs.data[0];
|
|
385
|
-
const signatures = tx.transaction?.txSignatures;
|
|
386
494
|
for (let i = 0; i !== signatures.length; i++) {
|
|
387
495
|
const serializedSig = signatures[i];
|
|
388
496
|
const pk = getAddressFromSignatures(serializedSig, address);
|
|
@@ -427,14 +535,14 @@ async function getAllCoins(input) {
|
|
|
427
535
|
let cursor;
|
|
428
536
|
const res = [];
|
|
429
537
|
while (hasNext) {
|
|
430
|
-
const currentPage = await input.suiClient.
|
|
538
|
+
const currentPage = await input.suiClient.listCoins({
|
|
431
539
|
owner: input.owner,
|
|
432
540
|
coinType: input.coinType,
|
|
433
541
|
cursor
|
|
434
542
|
});
|
|
435
|
-
res.push(...currentPage.
|
|
543
|
+
res.push(...currentPage.objects);
|
|
436
544
|
hasNext = currentPage.hasNextPage;
|
|
437
|
-
cursor = currentPage.
|
|
545
|
+
cursor = currentPage.cursor;
|
|
438
546
|
}
|
|
439
547
|
return res;
|
|
440
548
|
}
|
|
@@ -536,6 +644,16 @@ var EntryIterator = class {
|
|
|
536
644
|
};
|
|
537
645
|
|
|
538
646
|
// src/utils/iter/object.ts
|
|
647
|
+
var defaultObjectInclude = {
|
|
648
|
+
json: true
|
|
649
|
+
};
|
|
650
|
+
function mergeInclude(options) {
|
|
651
|
+
return {
|
|
652
|
+
...defaultObjectInclude,
|
|
653
|
+
...options?.objectInclude
|
|
654
|
+
};
|
|
655
|
+
}
|
|
656
|
+
__name(mergeInclude, "mergeInclude");
|
|
539
657
|
async function getAllOwnedObjects(provider, owner, options) {
|
|
540
658
|
const iter = new OwnedObjectIterator(provider, owner, options);
|
|
541
659
|
return await getAllFromIterator(iter);
|
|
@@ -565,7 +683,7 @@ var OwnedObjectRequester = class {
|
|
|
565
683
|
nextCursor;
|
|
566
684
|
filter;
|
|
567
685
|
pageSize;
|
|
568
|
-
|
|
686
|
+
objectInclude;
|
|
569
687
|
constructor(provider, owner, options) {
|
|
570
688
|
this.provider = provider;
|
|
571
689
|
this.owner = owner;
|
|
@@ -573,28 +691,25 @@ var OwnedObjectRequester = class {
|
|
|
573
691
|
this.nextCursor = null;
|
|
574
692
|
this.filter = options?.filter;
|
|
575
693
|
this.pageSize = options?.pageSize || REQUEST_PAGE_SIZE;
|
|
576
|
-
this.
|
|
577
|
-
showType: true,
|
|
578
|
-
showContent: true
|
|
579
|
-
};
|
|
694
|
+
this.objectInclude = mergeInclude(options);
|
|
580
695
|
}
|
|
581
696
|
async doNextRequest() {
|
|
582
|
-
const res = await this.provider.
|
|
697
|
+
const res = await this.provider.listOwnedObjects({
|
|
583
698
|
owner: this.owner,
|
|
584
|
-
|
|
699
|
+
include: this.objectInclude,
|
|
585
700
|
cursor: this.nextCursor,
|
|
586
701
|
limit: this.pageSize
|
|
587
702
|
});
|
|
588
|
-
this.nextCursor = res.
|
|
703
|
+
this.nextCursor = res.cursor;
|
|
589
704
|
let filtered;
|
|
590
705
|
if (this.filter) {
|
|
591
706
|
const { filter } = this;
|
|
592
|
-
filtered = res.
|
|
707
|
+
filtered = res.objects.filter((obj) => filter(obj));
|
|
593
708
|
} else {
|
|
594
|
-
filtered = res.
|
|
709
|
+
filtered = res.objects;
|
|
595
710
|
}
|
|
596
711
|
return {
|
|
597
|
-
data: filtered
|
|
712
|
+
data: filtered,
|
|
598
713
|
hasNext: res.hasNextPage
|
|
599
714
|
};
|
|
600
715
|
}
|
|
@@ -629,23 +744,31 @@ var MSafeAccount = class _MSafeAccount {
|
|
|
629
744
|
}
|
|
630
745
|
}
|
|
631
746
|
async ownedCoins() {
|
|
632
|
-
const balances =
|
|
633
|
-
|
|
634
|
-
|
|
747
|
+
const balances = [];
|
|
748
|
+
let cursor = null;
|
|
749
|
+
let hasNext = true;
|
|
750
|
+
while (hasNext) {
|
|
751
|
+
const page = await this.suiClient.listBalances({
|
|
752
|
+
owner: this.address,
|
|
753
|
+
cursor,
|
|
754
|
+
limit: 50
|
|
755
|
+
});
|
|
756
|
+
balances.push(...page.balances);
|
|
757
|
+
hasNext = page.hasNextPage;
|
|
758
|
+
cursor = page.cursor;
|
|
759
|
+
}
|
|
635
760
|
return Promise.all(balances.map(async (balance) => {
|
|
636
761
|
const meta = await this.coinHelper.getCoinMeta(balance.coinType);
|
|
637
|
-
const lockedEntry = balance.lockedBalance && typeof balance.lockedBalance === "object" && "number" in balance.lockedBalance && balance.lockedBalance.number ? BigInt(balance.lockedBalance.number) : 0n;
|
|
638
|
-
const unlockedBalance = lockedEntry ? BigInt(balance.totalBalance) - lockedEntry : BigInt(balance.totalBalance);
|
|
639
762
|
return {
|
|
640
763
|
type: normalizeStructTag3(balance.coinType),
|
|
641
|
-
balance:
|
|
764
|
+
balance: BigInt(balance.addressBalance),
|
|
642
765
|
metadata: meta
|
|
643
766
|
};
|
|
644
767
|
}));
|
|
645
768
|
}
|
|
646
769
|
async ownedObjects(options) {
|
|
647
770
|
const filterCoinObjectOptions = {
|
|
648
|
-
filter: (
|
|
771
|
+
filter: (obj) => !obj?.type?.startsWith("0x2::coin::Coin"),
|
|
649
772
|
...options
|
|
650
773
|
};
|
|
651
774
|
return getAllOwnedObjects(this.suiClient, this.address, filterCoinObjectOptions);
|
|
@@ -966,12 +1089,14 @@ var MSafeAccount = class _MSafeAccount {
|
|
|
966
1089
|
}
|
|
967
1090
|
}
|
|
968
1091
|
const multiSignature = this.multiSig.combinePartialSignatures(sortedSigs);
|
|
969
|
-
return this.suiClient.
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
1092
|
+
return this.suiClient.executeTransaction({
|
|
1093
|
+
transaction: HexToUint8Array(payload),
|
|
1094
|
+
signatures: [
|
|
1095
|
+
multiSignature
|
|
1096
|
+
],
|
|
1097
|
+
include: {
|
|
1098
|
+
effects: true,
|
|
1099
|
+
events: true
|
|
975
1100
|
}
|
|
976
1101
|
});
|
|
977
1102
|
}
|
|
@@ -1106,7 +1231,7 @@ var ReportSDK = class {
|
|
|
1106
1231
|
};
|
|
1107
1232
|
|
|
1108
1233
|
// src/globals/MSafeGlobals.ts
|
|
1109
|
-
import {
|
|
1234
|
+
import { SuiGrpcClient } from "@mysten/sui/grpc";
|
|
1110
1235
|
|
|
1111
1236
|
// src/backend/BackendImpl.ts
|
|
1112
1237
|
import { PublicKeySerde as PublicKeySerde3, UserMSafeStatus } from "@msafe/sui3-utils";
|
|
@@ -1463,6 +1588,17 @@ var MSafeEnv;
|
|
|
1463
1588
|
MSafeEnv2["prev"] = "prev";
|
|
1464
1589
|
MSafeEnv2["prod"] = "prod";
|
|
1465
1590
|
})(MSafeEnv || (MSafeEnv = {}));
|
|
1591
|
+
function httpUrlToGrpcBaseUrl(url) {
|
|
1592
|
+
const parsed = new URL(url);
|
|
1593
|
+
if (parsed.protocol === "https:" && parsed.port === "") {
|
|
1594
|
+
return `https://${parsed.hostname}:443${parsed.pathname}${parsed.search}`;
|
|
1595
|
+
}
|
|
1596
|
+
if (parsed.protocol === "http:" && parsed.port === "") {
|
|
1597
|
+
return `http://${parsed.hostname}:80${parsed.pathname}${parsed.search}`;
|
|
1598
|
+
}
|
|
1599
|
+
return `${parsed.origin}${parsed.pathname}${parsed.search}`;
|
|
1600
|
+
}
|
|
1601
|
+
__name(httpUrlToGrpcBaseUrl, "httpUrlToGrpcBaseUrl");
|
|
1466
1602
|
var TESTNET_RPC_URL = "https://fullnode.testnet.sui.io";
|
|
1467
1603
|
var MAINNET_RPC_URL = "https://fullnode.mainnet.sui.io";
|
|
1468
1604
|
var LOCAL_API_URL = "http://127.0.0.1:3000";
|
|
@@ -1479,9 +1615,9 @@ var ENV_CONFIGS = /* @__PURE__ */ new Map([
|
|
|
1479
1615
|
url: TESTNET_RPC_URL
|
|
1480
1616
|
},
|
|
1481
1617
|
backend: {
|
|
1482
|
-
url:
|
|
1618
|
+
url: DEV_API_URL
|
|
1483
1619
|
},
|
|
1484
|
-
syncingURL:
|
|
1620
|
+
syncingURL: DEV_SYNCING_URL,
|
|
1485
1621
|
network: "sui:testnet"
|
|
1486
1622
|
}
|
|
1487
1623
|
],
|
|
@@ -1572,12 +1708,11 @@ var MSafeGlobals = class _MSafeGlobals {
|
|
|
1572
1708
|
}
|
|
1573
1709
|
static async New(env, options) {
|
|
1574
1710
|
const config = getMSafeConfig(env, options);
|
|
1575
|
-
const suiClient = new
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
},
|
|
1711
|
+
const suiClient = config.suiClient.transport ? new SuiGrpcClient({
|
|
1712
|
+
transport: config.suiClient.transport,
|
|
1713
|
+
network: msafeChainToSuiNetwork(config.network)
|
|
1714
|
+
}) : new SuiGrpcClient({
|
|
1715
|
+
baseUrl: httpUrlToGrpcBaseUrl(config.suiClient.url),
|
|
1581
1716
|
network: msafeChainToSuiNetwork(config.network)
|
|
1582
1717
|
});
|
|
1583
1718
|
const backend = new BackendImpl(config.backend.url, options?.mockAddress);
|
|
@@ -1767,6 +1902,7 @@ export {
|
|
|
1767
1902
|
getAllCoins,
|
|
1768
1903
|
getMSafeConfig,
|
|
1769
1904
|
getPublicKeyFromChain,
|
|
1905
|
+
httpUrlToGrpcBaseUrl,
|
|
1770
1906
|
msafeChainToSuiNetwork,
|
|
1771
1907
|
stringToBuffer,
|
|
1772
1908
|
toSuiTransaction
|