@arcadiasystems/morse-cli 0.5.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +45 -0
- package/README.md +27 -15
- package/dist/index.js +49 -17
- package/docs/QUICKSTART.md +11 -2
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,51 @@ All notable changes to `@arcadiasystems/morse-cli` are documented here. The
|
|
|
4
4
|
format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and this
|
|
5
5
|
project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
6
|
|
|
7
|
+
## [0.6.0] - 2026-09-09
|
|
8
|
+
|
|
9
|
+
Mainnet support, consuming `@arcadiasystems/morse-sdk@0.5.0`. The Move contracts
|
|
10
|
+
went live on Sui mainnet on 2026-09-09; the CLI rejected `mainnet` outright until
|
|
11
|
+
now.
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
|
|
15
|
+
- **`--network mainnet` works**, as do `MORSE_NETWORK=mainnet` and
|
|
16
|
+
`morse config add <name> --network mainnet`. `coerceNetwork` no longer
|
|
17
|
+
special-cases mainnet, and `localnet` is accepted too (it still fails at
|
|
18
|
+
startup unless you point the SDK at your own package and registry, which is
|
|
19
|
+
`morseConfig`'s error to raise, not the flag parser's).
|
|
20
|
+
- **Commands that spend gas now name the network they spent on.** The resolved
|
|
21
|
+
network appears as the first detail line under the result headline, and as a
|
|
22
|
+
`network` field in `--json` output. Applied on the write contexts only, so read
|
|
23
|
+
and list output is byte-for-byte unchanged. Nothing selects mainnet implicitly
|
|
24
|
+
(with no flag, env var, or profile the CLI targets testnet), so this is there
|
|
25
|
+
to make a mainnet spend visible after the fact rather than to gate it.
|
|
26
|
+
|
|
27
|
+
### Fixed
|
|
28
|
+
|
|
29
|
+
- Status banner claimed v0.3.0, two releases stale, and said mainnet support was
|
|
30
|
+
pending.
|
|
31
|
+
- `--network` help text listed only testnet and localnet, in both the global
|
|
32
|
+
flag (`morse --help`) and `config add --network`, as did the `MORSE_NETWORK`
|
|
33
|
+
row of the README env table.
|
|
34
|
+
- Seven README links pointed into `examples/`, which is not in the package
|
|
35
|
+
`files` array, so they 404'd on the npm page. Now absolute GitHub URLs;
|
|
36
|
+
`docs/QUICKSTART.md` stays relative because `docs` does ship.
|
|
37
|
+
- Dead Walrus faucet link in `docs/QUICKSTART.md`. `docs.walrus.site` no longer
|
|
38
|
+
resolves; WAL acquisition now points at the working stake-wal.wal.app swap,
|
|
39
|
+
matching the README and morse-sdk.
|
|
40
|
+
- Known limitations now record that `file list` requires `--indexer-url`, since
|
|
41
|
+
public Sui fullnodes have retired the JSON-RPC event query it walks. This
|
|
42
|
+
affects testnet as well as mainnet and predates this release.
|
|
43
|
+
|
|
44
|
+
### Known gaps
|
|
45
|
+
|
|
46
|
+
- `file list` is unusable without `--indexer-url` on every network, per above.
|
|
47
|
+
Porting the event source off `suix_queryEvents` is tracked separately.
|
|
48
|
+
- No mainnet run of the opt-in `bun run test:e2e` lifecycle; it stays pointed at
|
|
49
|
+
testnet, where it costs nothing real.
|
|
50
|
+
- The Move contracts remain unaudited.
|
|
51
|
+
|
|
7
52
|
## [0.5.0] - 2026-06-09
|
|
8
53
|
|
|
9
54
|
Hardening pass from CLI testing: fail fast before paying for Walrus storage,
|
package/README.md
CHANGED
|
@@ -6,16 +6,24 @@ content entries from your terminal, signing with a locally encrypted key.
|
|
|
6
6
|
Content is stored on [Walrus](https://walrus.xyz); private entries are encrypted
|
|
7
7
|
with [Seal](https://github.com/MystenLabs/seal).
|
|
8
8
|
|
|
9
|
-
> Status: v0.
|
|
10
|
-
>
|
|
9
|
+
> Status: v0.6.0. Mainnet and testnet are both supported; the command surface is
|
|
10
|
+
> stable.
|
|
11
|
+
>
|
|
12
|
+
> **The Move contracts are unaudited.** On mainnet, gas and Walrus storage cost
|
|
13
|
+
> real SUI and WAL, there is no faucet, and deletions are irreversible. Nothing
|
|
14
|
+
> selects mainnet for you: with no `--network`, `MORSE_NETWORK`, or profile
|
|
15
|
+
> setting, the CLI targets testnet. Every command that spends gas prints the
|
|
16
|
+
> network it used, and `--json` output carries a `network` field.
|
|
11
17
|
|
|
12
18
|
## Requirements
|
|
13
19
|
|
|
14
20
|
- [Node.js](https://nodejs.org) >= 18, or [Bun](https://bun.sh) >= 1.2. The
|
|
15
21
|
published CLI runs under either.
|
|
16
|
-
- A funded Sui
|
|
17
|
-
|
|
18
|
-
|
|
22
|
+
- A funded Sui address for gas, and WAL for Walrus storage when adding content.
|
|
23
|
+
On testnet, get SUI from the [Sui faucet](https://faucet.sui.io/) and swap some
|
|
24
|
+
for WAL at [stake-wal.wal.app](https://stake-wal.wal.app/?network=testnet). On
|
|
25
|
+
mainnet there is no faucet: both have to be acquired, and every write spends
|
|
26
|
+
real value.
|
|
19
27
|
|
|
20
28
|
## Install
|
|
21
29
|
|
|
@@ -91,7 +99,7 @@ Environment variables (override the config file, overridden by flags):
|
|
|
91
99
|
| Variable | Overrides | Notes |
|
|
92
100
|
| --- | --- | --- |
|
|
93
101
|
| `MORSE_PROFILE` | `--profile` | Profile to use. |
|
|
94
|
-
| `MORSE_NETWORK` | `--network` | `testnet
|
|
102
|
+
| `MORSE_NETWORK` | `--network` | `mainnet`, `testnet`, or `localnet`. |
|
|
95
103
|
| `MORSE_RPC_URL` | `--rpc` | Sui RPC URL override. |
|
|
96
104
|
| `MORSE_ADDRESS` | (no flag) | Active account address, selecting which keystore to use. |
|
|
97
105
|
| `MORSE_PUBLICATION` | `-P, --publication` | Active publication id. |
|
|
@@ -123,7 +131,7 @@ Global options apply to every command and must appear before the subcommand
|
|
|
123
131
|
|
|
124
132
|
| Global option | Purpose |
|
|
125
133
|
| --- | --- |
|
|
126
|
-
| `--network <testnet\|localnet>` | Network to target (default: testnet). |
|
|
134
|
+
| `--network <mainnet\|testnet\|localnet>` | Network to target (default: testnet). `localnet` needs a custom deployment. |
|
|
127
135
|
| `-p, --profile <name>` | Config profile to use. |
|
|
128
136
|
| `--rpc <url>` | Override the Sui RPC URL. |
|
|
129
137
|
| `--json` | Machine-readable JSON on stdout. |
|
|
@@ -290,13 +298,13 @@ to fetch the full record per file (one read each) when you need them.
|
|
|
290
298
|
## Examples
|
|
291
299
|
|
|
292
300
|
- [docs/QUICKSTART.md](./docs/QUICKSTART.md): a full, copy-pasteable walkthrough.
|
|
293
|
-
- Runnable shell recipes in [examples/](
|
|
294
|
-
- [`lifecycle.sh`](
|
|
295
|
-
- [`content.sh`](
|
|
296
|
-
- [`encrypt-decrypt.sh`](
|
|
297
|
-
- [`delegation.sh`](
|
|
298
|
-
- [`ci-noninteractive.sh`](
|
|
299
|
-
- [`files.sh`](
|
|
301
|
+
- Runnable shell recipes in [examples/](https://github.com/arcadiasystems/morse-dcms/tree/main/morse-cli/examples):
|
|
302
|
+
- [`lifecycle.sh`](https://github.com/arcadiasystems/morse-dcms/blob/main/morse-cli/examples/lifecycle.sh): create, add an entry, read, revise, tear down.
|
|
303
|
+
- [`content.sh`](https://github.com/arcadiasystems/morse-dcms/blob/main/morse-cli/examples/content.sh): upload an image and a post, publish a revision, fetch content back, get a link, remove a collection.
|
|
304
|
+
- [`encrypt-decrypt.sh`](https://github.com/arcadiasystems/morse-dcms/blob/main/morse-cli/examples/encrypt-decrypt.sh): encrypt with Seal and decrypt back.
|
|
305
|
+
- [`delegation.sh`](https://github.com/arcadiasystems/morse-dcms/blob/main/morse-cli/examples/delegation.sh): issue a PublisherCap to a delegate, then revoke it.
|
|
306
|
+
- [`ci-noninteractive.sh`](https://github.com/arcadiasystems/morse-dcms/blob/main/morse-cli/examples/ci-noninteractive.sh): env-var auth, `--yes`, and `--json` parsing.
|
|
307
|
+
- [`files.sh`](https://github.com/arcadiasystems/morse-dcms/blob/main/morse-cli/examples/files.sh): RecipientFile round-trip (upload an encrypted file, download/decrypt via its share string, manage recipients, plus a public file).
|
|
300
308
|
|
|
301
309
|
## Limitations
|
|
302
310
|
|
|
@@ -319,7 +327,11 @@ to fetch the full record per file (one read each) when you need them.
|
|
|
319
327
|
created but not yet populated through the CLI; `entry add` refuses them.
|
|
320
328
|
- There is no command to query Walrus blob storage expiry; `--epochs` sets the
|
|
321
329
|
lease at upload time, but remaining lease time is not exposed by the SDK.
|
|
322
|
-
-
|
|
330
|
+
- `localnet` is accepted as a network but has no canonical deployment, so it
|
|
331
|
+
fails at startup unless you point the SDK at your own package and registry.
|
|
332
|
+
- `file list` walks a JSON-RPC event query that public Sui fullnodes have
|
|
333
|
+
retired, so it needs `--indexer-url` pointing at a source that serves the same
|
|
334
|
+
query. This affects testnet as well as mainnet.
|
|
323
335
|
|
|
324
336
|
## Publishing
|
|
325
337
|
|
package/dist/index.js
CHANGED
|
@@ -148,7 +148,7 @@ import { Command } from "commander";
|
|
|
148
148
|
// package.json
|
|
149
149
|
var package_default = {
|
|
150
150
|
name: "@arcadiasystems/morse-cli",
|
|
151
|
-
version: "0.
|
|
151
|
+
version: "0.6.0",
|
|
152
152
|
description: "Command-line interface for the Morse decentralized CMS on Sui.",
|
|
153
153
|
license: "MIT",
|
|
154
154
|
type: "module",
|
|
@@ -203,7 +203,7 @@ var package_default = {
|
|
|
203
203
|
prepublishOnly: "bun run check && bun run build"
|
|
204
204
|
},
|
|
205
205
|
dependencies: {
|
|
206
|
-
"@arcadiasystems/morse-sdk": "^0.
|
|
206
|
+
"@arcadiasystems/morse-sdk": "^0.5.0",
|
|
207
207
|
"@mysten/seal": "1.1.3",
|
|
208
208
|
"@mysten/sui": "2.16.2",
|
|
209
209
|
"@mysten/walrus": "1.1.6",
|
|
@@ -219,7 +219,7 @@ var package_default = {
|
|
|
219
219
|
// src/cli/program.ts
|
|
220
220
|
function buildProgram() {
|
|
221
221
|
const program = new Command;
|
|
222
|
-
program.name("morse").description("Command-line interface for the Morse decentralized CMS on Sui.").version(package_default.version, "-V, --version", "Print the version and exit").option("--network <network>", "Sui network: testnet or localnet [env: MORSE_NETWORK]").option("-p, --profile <name>", "Config profile to use [env: MORSE_PROFILE]").option("--rpc <url>", "Override the Sui RPC URL [env: MORSE_RPC_URL]").option("--json", "Output machine-readable JSON on stdout").option("-q, --quiet", "Suppress progress and informational output").option("-y, --yes", "Assume yes for confirmation prompts").option("--debug", "Print stack traces on error").enablePositionalOptions().showHelpAfterError().exitOverride();
|
|
222
|
+
program.name("morse").description("Command-line interface for the Morse decentralized CMS on Sui.").version(package_default.version, "-V, --version", "Print the version and exit").option("--network <network>", "Sui network: mainnet, testnet, or localnet [env: MORSE_NETWORK]").option("-p, --profile <name>", "Config profile to use [env: MORSE_PROFILE]").option("--rpc <url>", "Override the Sui RPC URL [env: MORSE_RPC_URL]").option("--json", "Output machine-readable JSON on stdout").option("-q, --quiet", "Suppress progress and informational output").option("-y, --yes", "Assume yes for confirmation prompts").option("--debug", "Print stack traces on error").enablePositionalOptions().showHelpAfterError().exitOverride();
|
|
223
223
|
return program;
|
|
224
224
|
}
|
|
225
225
|
|
|
@@ -316,14 +316,39 @@ class Output {
|
|
|
316
316
|
get isJson() {
|
|
317
317
|
return this.options.json;
|
|
318
318
|
}
|
|
319
|
+
withNetwork(network) {
|
|
320
|
+
return new Output({ ...this.options, network });
|
|
321
|
+
}
|
|
319
322
|
result(human, data) {
|
|
320
323
|
if (this.options.json) {
|
|
321
|
-
this.out(`${toJson(data)}
|
|
324
|
+
this.out(`${toJson(this.stampJson(data))}
|
|
322
325
|
`);
|
|
323
326
|
return;
|
|
324
327
|
}
|
|
325
|
-
this.out(`${human}
|
|
328
|
+
this.out(`${this.stampHuman(human)}
|
|
326
329
|
`);
|
|
330
|
+
}
|
|
331
|
+
stampJson(data) {
|
|
332
|
+
const network = this.options.network;
|
|
333
|
+
if (network === undefined || !isPlainObject(data) || "network" in data) {
|
|
334
|
+
return data;
|
|
335
|
+
}
|
|
336
|
+
return { network, ...data };
|
|
337
|
+
}
|
|
338
|
+
stampHuman(human) {
|
|
339
|
+
const network = this.options.network;
|
|
340
|
+
if (network === undefined) {
|
|
341
|
+
return human;
|
|
342
|
+
}
|
|
343
|
+
const line = ` network: ${network}`;
|
|
344
|
+
const breakAt = human.indexOf(`
|
|
345
|
+
`);
|
|
346
|
+
if (breakAt === -1) {
|
|
347
|
+
return `${human}
|
|
348
|
+
${line}`;
|
|
349
|
+
}
|
|
350
|
+
return `${human.slice(0, breakAt)}
|
|
351
|
+
${line}${human.slice(breakAt)}`;
|
|
327
352
|
}
|
|
328
353
|
info(message) {
|
|
329
354
|
if (this.options.quiet || this.options.json) {
|
|
@@ -369,6 +394,9 @@ function resolveColor(json) {
|
|
|
369
394
|
}
|
|
370
395
|
return Boolean(process.stderr.isTTY);
|
|
371
396
|
}
|
|
397
|
+
function isPlainObject(value) {
|
|
398
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
399
|
+
}
|
|
372
400
|
function createOutput(opts) {
|
|
373
401
|
const json = Boolean(opts.json);
|
|
374
402
|
return new Output({
|
|
@@ -397,13 +425,10 @@ function isNetwork(value) {
|
|
|
397
425
|
return typeof value === "string" && NETWORKS.has(value);
|
|
398
426
|
}
|
|
399
427
|
function coerceNetwork(value) {
|
|
400
|
-
if (value === Network.Mainnet) {
|
|
401
|
-
throw new UsageError("Morse is not yet deployed on mainnet. Use testnet or localnet.");
|
|
402
|
-
}
|
|
403
428
|
if (isNetwork(value)) {
|
|
404
429
|
return value;
|
|
405
430
|
}
|
|
406
|
-
throw new UsageError(`Unknown network "${value}". Use one of: testnet, localnet.`);
|
|
431
|
+
throw new UsageError(`Unknown network "${value}". Use one of: mainnet, testnet, localnet.`);
|
|
407
432
|
}
|
|
408
433
|
function parseConfig(raw, source) {
|
|
409
434
|
if (!isRecord(raw)) {
|
|
@@ -945,6 +970,7 @@ async function buildWriteContext(command) {
|
|
|
945
970
|
const { base, keypair, address } = await buildSignedBase(command);
|
|
946
971
|
return {
|
|
947
972
|
...base,
|
|
973
|
+
output: base.output.withNetwork(base.settings.network),
|
|
948
974
|
adapter: new KeypairAdapter(keypair, base.client),
|
|
949
975
|
address
|
|
950
976
|
};
|
|
@@ -966,7 +992,13 @@ async function buildContentContext(command) {
|
|
|
966
992
|
}
|
|
967
993
|
const adapter = new KeypairAdapter(keypair, base.client);
|
|
968
994
|
const walrus = DefaultWalrusWriteAdapter.fromConfig({ network, suiClient: base.client }, keypair);
|
|
969
|
-
return {
|
|
995
|
+
return {
|
|
996
|
+
...base,
|
|
997
|
+
output: base.output.withNetwork(network),
|
|
998
|
+
adapter,
|
|
999
|
+
address,
|
|
1000
|
+
walrus
|
|
1001
|
+
};
|
|
970
1002
|
}
|
|
971
1003
|
async function buildEncryptContext(command) {
|
|
972
1004
|
const ctx = await buildContentContext(command);
|
|
@@ -1536,7 +1568,7 @@ function registerConfigCommands(program) {
|
|
|
1536
1568
|
config.command("list").description("List profiles and show the default").action(async (_options, command) => {
|
|
1537
1569
|
await runConfigList(outputFor(command));
|
|
1538
1570
|
});
|
|
1539
|
-
config.command("add <name>").description("Create or update a profile").requiredOption("--network <network>", "Sui network: testnet or localnet").option("--rpc <url>", "RPC URL override for this profile").action(async (name, options, command) => {
|
|
1571
|
+
config.command("add <name>").description("Create or update a profile").requiredOption("--network <network>", "Sui network: mainnet, testnet, or localnet").option("--rpc <url>", "RPC URL override for this profile").action(async (name, options, command) => {
|
|
1540
1572
|
await runConfigAdd(outputFor(command), name, options);
|
|
1541
1573
|
});
|
|
1542
1574
|
config.command("use <name>").description("Set the default profile").action(async (name, _options, command) => {
|
|
@@ -2117,7 +2149,7 @@ async function runFileUpload(ctx, path, options) {
|
|
|
2117
2149
|
const upload = { epochs, deletable: true };
|
|
2118
2150
|
const onProgress = uploadProgress(ctx.output);
|
|
2119
2151
|
if (options.public) {
|
|
2120
|
-
const
|
|
2152
|
+
const result = await uploadRecipientFileFromBytes(ctx.adapter, ctx.config, {
|
|
2121
2153
|
walrus: ctx.walrus,
|
|
2122
2154
|
bytes,
|
|
2123
2155
|
recipients: [],
|
|
@@ -2128,10 +2160,10 @@ async function runFileUpload(ctx, path, options) {
|
|
|
2128
2160
|
onProgress
|
|
2129
2161
|
});
|
|
2130
2162
|
const aggregator = ctx.config.walrusEndpoints.aggregator;
|
|
2131
|
-
const viewUrl = aggregator.length > 0 ? `${aggregator}/v1/blobs/${
|
|
2132
|
-
const
|
|
2163
|
+
const viewUrl = aggregator.length > 0 ? `${aggregator}/v1/blobs/${result.blobId}` : undefined;
|
|
2164
|
+
const human = viewUrl === undefined ? `Uploaded public file ${result.fileId}. (tx: ${result.digest})` : `Uploaded public file ${result.fileId}. (tx: ${result.digest})
|
|
2133
2165
|
view: ${viewUrl}`;
|
|
2134
|
-
ctx.output.result(
|
|
2166
|
+
ctx.output.result(human, { ...result, viewUrl: viewUrl ?? null });
|
|
2135
2167
|
return;
|
|
2136
2168
|
}
|
|
2137
2169
|
const result = await uploadEncryptedRecipientFileFromBytes(ctx.adapter, ctx.config, {
|
|
@@ -2588,11 +2620,11 @@ function registerRevisionCommands(program) {
|
|
|
2588
2620
|
// src/commands/use.ts
|
|
2589
2621
|
async function runUse(output, gopts, publication, collection, options, makeContext) {
|
|
2590
2622
|
if (options.clear) {
|
|
2591
|
-
const
|
|
2623
|
+
const profile = await updateActiveProfile(gopts, {
|
|
2592
2624
|
publication: undefined,
|
|
2593
2625
|
collection: undefined
|
|
2594
2626
|
});
|
|
2595
|
-
output.result(`Cleared the active publication and collection (profile "${
|
|
2627
|
+
output.result(`Cleared the active publication and collection (profile "${profile}").`, { profile, publication: null, collection: null });
|
|
2596
2628
|
return;
|
|
2597
2629
|
}
|
|
2598
2630
|
if (publication === undefined) {
|
package/docs/QUICKSTART.md
CHANGED
|
@@ -5,14 +5,21 @@ Sui testnet, then tears it down. Every command is copy-pasteable; expected
|
|
|
5
5
|
output is shown beneath each step. Replace IDs in later steps with the ones your
|
|
6
6
|
own runs print.
|
|
7
7
|
|
|
8
|
+
The walkthrough uses testnet on purpose: it creates a publication, uploads
|
|
9
|
+
content to Walrus, and deletes it all again. On mainnet that sequence costs real
|
|
10
|
+
SUI and WAL. Once it works for you, the only change needed is the network on the
|
|
11
|
+
profile in step 1 (`--network mainnet`); every later command reads the network
|
|
12
|
+
from the profile and prints which one it spent on.
|
|
13
|
+
|
|
8
14
|
## 0. Prerequisites
|
|
9
15
|
|
|
10
16
|
- Install [Bun](https://bun.sh) >= 1.2.
|
|
11
17
|
- Have a Sui testnet keypair. If you use the Sui CLI, export one with
|
|
12
18
|
`sui keytool export --key-identity <alias>` to get a `suiprivkey1...` string.
|
|
13
19
|
- Fund the address with testnet SUI ([faucet](https://faucet.sui.io/)) for gas,
|
|
14
|
-
and with WAL
|
|
15
|
-
for content
|
|
20
|
+
and with WAL by swapping some SUI at
|
|
21
|
+
[stake-wal.wal.app](https://stake-wal.wal.app/?network=testnet) for content
|
|
22
|
+
uploads.
|
|
16
23
|
|
|
17
24
|
Install the CLI:
|
|
18
25
|
|
|
@@ -24,6 +31,8 @@ morse --version
|
|
|
24
31
|
## 1. Create a profile
|
|
25
32
|
|
|
26
33
|
A profile pins the network. The first profile you add becomes the default.
|
|
34
|
+
`--network` takes `mainnet`, `testnet`, or `localnet`; with no profile, flag, or
|
|
35
|
+
`MORSE_NETWORK`, the CLI targets testnet.
|
|
27
36
|
|
|
28
37
|
```sh
|
|
29
38
|
morse config add testnet --network testnet
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@arcadiasystems/morse-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "Command-line interface for the Morse decentralized CMS on Sui.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
"prepublishOnly": "bun run check && bun run build"
|
|
56
56
|
},
|
|
57
57
|
"dependencies": {
|
|
58
|
-
"@arcadiasystems/morse-sdk": "^0.
|
|
58
|
+
"@arcadiasystems/morse-sdk": "^0.5.0",
|
|
59
59
|
"@mysten/seal": "1.1.3",
|
|
60
60
|
"@mysten/sui": "2.16.2",
|
|
61
61
|
"@mysten/walrus": "1.1.6",
|