@arcadiasystems/morse-cli 0.6.0 → 0.6.1
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 +21 -0
- package/README.md +17 -2
- package/dist/index.js +25 -10
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,27 @@ 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.1] - 2026-09-09
|
|
8
|
+
|
|
9
|
+
Picks up `@arcadiasystems/morse-sdk@0.6.0` and fixes a download regression it exposed. Upgrade if you use mainnet at all.
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
|
|
13
|
+
- **`file download` worked on no mainnet file, public or not.** `buildFileDownloadContext` constructed the Seal adapter eagerly, so once SDK 0.6.0 stopped pinning mainnet key servers, every download failed at context build with a Seal error before the file was even looked up. Downloading a public file never touches Seal, so the adapter is now built on first use and memoized, matching the lazy-signer pattern the same context already used. Regression covered in `test/program.test.ts` against the real context builder.
|
|
14
|
+
- **Encrypted commands now explain themselves on mainnet.** They previously surfaced the SDK's `ConfigurationError`, whose advice ("pass seal.serverConfigs", "start from MAINNET_SEAL_COMMITTEE") names an API the CLI does not expose: there is no flag or env var for key servers, so on mainnet these commands cannot work at all. `entry add-encrypted`, `entry decrypt`, `file upload --encrypt` / `--recipient`, and file decryption now exit 2 with a message that says that and points at testnet or the SDK.
|
|
15
|
+
- **`file upload --public` is not caught by that guard.** It shares the encrypt context but never encrypts, so `EncryptContext.seal` became a lazy factory too. Building the adapter eagerly there would have blocked public mainnet uploads the same way the eager build blocked public downloads. Both the refusal and the exemption are covered in `test/program.test.ts`.
|
|
16
|
+
- **`file download` refused every public file, on every network.** The check asked whether the file had recipients, on the assumption that "a public file has no recipients". The Move contract auto-includes the owner on creation, so `members` is non-empty for every file that exists, public or not: a public file and an encrypted one both report exactly one member. The result was that `file upload --public` produced a file the CLI would not download, telling the user their plaintext was "unusable ciphertext" and pointing at `--raw`, which then wrote the correct bytes anyway.
|
|
17
|
+
|
|
18
|
+
Encryption is now determined by the Seal id prefix via the new `getRecipientFileSealPrefix` in SDK 0.7.0, which is the only reliable signal. This bug predates the mainnet work and shipped in 0.6.0 and earlier.
|
|
19
|
+
|
|
20
|
+
It escaped the tests because the download fixture defaulted to `members: []`, modelling an object the contract cannot produce. The fixture now carries a realistic owner-member, and a regression test covers a public file that has members.
|
|
21
|
+
- Dependency moves to `@arcadiasystems/morse-sdk@^0.7.0`. The published 0.6.0 declared `^0.5.0`, which resolves to the SDK release whose mainnet Seal default could produce permanently unreadable ciphertext.
|
|
22
|
+
|
|
23
|
+
### Known gaps
|
|
24
|
+
|
|
25
|
+
- `file list` still needs `--indexer-url` on every network; public Sui fullnodes have retired the JSON-RPC event query it walks.
|
|
26
|
+
- Encrypted mainnet stays blocked until Seal operator credentials are available and the CLI grows a way to pass them.
|
|
27
|
+
|
|
7
28
|
## [0.6.0] - 2026-09-09
|
|
8
29
|
|
|
9
30
|
Mainnet support, consuming `@arcadiasystems/morse-sdk@0.5.0`. The Move contracts
|
package/README.md
CHANGED
|
@@ -6,8 +6,20 @@ 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.6.
|
|
10
|
-
> stable.
|
|
9
|
+
> Status: v0.6.1. Mainnet and testnet are both supported for public content;
|
|
10
|
+
> the command surface is stable.
|
|
11
|
+
>
|
|
12
|
+
> **Encrypted commands are testnet-only.** `entry add-encrypted`, `entry
|
|
13
|
+
> decrypt`, `file upload --encrypt` (and `--recipient`, which implies it), and
|
|
14
|
+
> decrypting a downloaded file all need Seal key servers. Testnet has an open
|
|
15
|
+
> set; mainnet does not, because every mainnet Seal operator is commercial, and
|
|
16
|
+
> the CLI has no flag or env var for supplying one. These commands exit 2 on
|
|
17
|
+
> mainnet with an explanation.
|
|
18
|
+
>
|
|
19
|
+
> Everything that does not encrypt works on both networks, including
|
|
20
|
+
> `file upload --public`, `file download` of a public file, and the whole
|
|
21
|
+
> publication, collection and entry surface. All of that is verified against
|
|
22
|
+
> live mainnet, including a public upload and download round trip.
|
|
11
23
|
>
|
|
12
24
|
> **The Move contracts are unaudited.** On mainnet, gas and Walrus storage cost
|
|
13
25
|
> real SUI and WAL, there is no faucet, and deletions are irreversible. Nothing
|
|
@@ -327,6 +339,9 @@ to fetch the full record per file (one read each) when you need them.
|
|
|
327
339
|
created but not yet populated through the CLI; `entry add` refuses them.
|
|
328
340
|
- There is no command to query Walrus blob storage expiry; `--epochs` sets the
|
|
329
341
|
lease at upload time, but remaining lease time is not exposed by the SDK.
|
|
342
|
+
- Encrypted commands do not work on mainnet, per the status note above. There
|
|
343
|
+
is no way to supply Seal key servers to the CLI; if you have credentials from
|
|
344
|
+
an operator, use the SDK directly for now.
|
|
330
345
|
- `localnet` is accepted as a network but has no canonical deployment, so it
|
|
331
346
|
fails at startup unless you point the SDK at your own package and registry.
|
|
332
347
|
- `file list` walks a JSON-RPC event query that public Sui fullnodes have
|
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.6.
|
|
151
|
+
version: "0.6.1",
|
|
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.7.0",
|
|
207
207
|
"@mysten/seal": "1.1.3",
|
|
208
208
|
"@mysten/sui": "2.16.2",
|
|
209
209
|
"@mysten/walrus": "1.1.6",
|
|
@@ -1000,10 +1000,15 @@ async function buildContentContext(command) {
|
|
|
1000
1000
|
walrus
|
|
1001
1001
|
};
|
|
1002
1002
|
}
|
|
1003
|
+
function assertSealAvailable(config) {
|
|
1004
|
+
if (config.sealKeyServers.length > 0) {
|
|
1005
|
+
return;
|
|
1006
|
+
}
|
|
1007
|
+
throw new CliError(`Encrypted commands are not available on ${config.network}. Seal key servers there are operated commercially and the CLI cannot yet be pointed at one. Use --network testnet, or drive @arcadiasystems/morse-sdk directly with your own seal.serverConfigs.`, ExitCode.Usage);
|
|
1008
|
+
}
|
|
1003
1009
|
async function buildEncryptContext(command) {
|
|
1004
1010
|
const ctx = await buildContentContext(command);
|
|
1005
|
-
|
|
1006
|
-
return { ...ctx, seal };
|
|
1011
|
+
return { ...ctx, seal: lazySeal(ctx) };
|
|
1007
1012
|
}
|
|
1008
1013
|
function walrusReadAdapter(base, network, viaAggregator) {
|
|
1009
1014
|
if (viaAggregator) {
|
|
@@ -1031,6 +1036,7 @@ async function buildDecryptContext(command, opts = {}) {
|
|
|
1031
1036
|
if (network === "localnet") {
|
|
1032
1037
|
throw new CliError("Seal decryption is not available on localnet. Use testnet or mainnet.", ExitCode.Usage);
|
|
1033
1038
|
}
|
|
1039
|
+
assertSealAvailable(base.config);
|
|
1034
1040
|
const seal = DefaultSealAdapter.fromMorseConfig(base.config, {}, base.client);
|
|
1035
1041
|
return {
|
|
1036
1042
|
...base,
|
|
@@ -1052,10 +1058,18 @@ async function buildFileDownloadContext(command, opts = {}) {
|
|
|
1052
1058
|
packageId: base.config.packageId
|
|
1053
1059
|
}),
|
|
1054
1060
|
walrusRead: walrusReadAdapter(base, network, Boolean(opts.viaAggregator)),
|
|
1055
|
-
seal:
|
|
1061
|
+
seal: lazySeal(base),
|
|
1056
1062
|
unlockSigner: () => resolveSigner(base.settings.account, process.env, base.signal)
|
|
1057
1063
|
};
|
|
1058
1064
|
}
|
|
1065
|
+
function lazySeal(base) {
|
|
1066
|
+
let adapter;
|
|
1067
|
+
return () => {
|
|
1068
|
+
assertSealAvailable(base.config);
|
|
1069
|
+
adapter ??= DefaultSealAdapter.fromMorseConfig(base.config, {}, base.client);
|
|
1070
|
+
return adapter;
|
|
1071
|
+
};
|
|
1072
|
+
}
|
|
1059
1073
|
async function buildFileListContext(command, opts = {}) {
|
|
1060
1074
|
const base = await buildReadContext(command);
|
|
1061
1075
|
const originPackageId = base.config.recipientFileEventOriginPackageId;
|
|
@@ -1681,7 +1695,7 @@ async function runEntryAddEncrypted(ctx, name, options) {
|
|
|
1681
1695
|
ctx.output.info(`Encrypting and uploading ${plaintext.length} bytes...`);
|
|
1682
1696
|
const result = await addEncryptedEntryFromBytes(ctx.adapter, ctx.config, {
|
|
1683
1697
|
walrus: ctx.walrus,
|
|
1684
|
-
seal: ctx.seal,
|
|
1698
|
+
seal: ctx.seal(),
|
|
1685
1699
|
publicationId: id,
|
|
1686
1700
|
publisherCapId,
|
|
1687
1701
|
collectionName: collection,
|
|
@@ -2168,7 +2182,7 @@ async function runFileUpload(ctx, path, options) {
|
|
|
2168
2182
|
}
|
|
2169
2183
|
const result = await uploadEncryptedRecipientFileFromBytes(ctx.adapter, ctx.config, {
|
|
2170
2184
|
walrus: ctx.walrus,
|
|
2171
|
-
seal: ctx.seal,
|
|
2185
|
+
seal: ctx.seal(),
|
|
2172
2186
|
plaintext: bytes,
|
|
2173
2187
|
recipients,
|
|
2174
2188
|
name: options.name,
|
|
@@ -2238,7 +2252,7 @@ async function decryptRecipientFile(ctx, fileId, ciphertext, prefix, nonce) {
|
|
|
2238
2252
|
signer: keypair,
|
|
2239
2253
|
suiClient: ctx.client
|
|
2240
2254
|
});
|
|
2241
|
-
return ctx.seal.decryptUnderRecipientFile(ciphertext, {
|
|
2255
|
+
return ctx.seal().decryptUnderRecipientFile(ciphertext, {
|
|
2242
2256
|
sessionKey,
|
|
2243
2257
|
sealId,
|
|
2244
2258
|
fileId
|
|
@@ -2254,9 +2268,10 @@ async function runFileDownload(ctx, positional, options) {
|
|
|
2254
2268
|
}
|
|
2255
2269
|
const fileId = toRecipientFileId(target.fileId);
|
|
2256
2270
|
const file = await ctx.filesReader.getRecipientFile(fileId, ctx.signal);
|
|
2257
|
-
|
|
2271
|
+
const encrypted = target.decrypt !== undefined || await ctx.filesReader.getRecipientFileSealPrefix(fileId, ctx.signal) !== null;
|
|
2272
|
+
if (target.decrypt === undefined && encrypted) {
|
|
2258
2273
|
if (!options.raw) {
|
|
2259
|
-
throw new UsageError("This file
|
|
2274
|
+
throw new UsageError("This file is encrypted. Pass --share (or --prefix and --nonce) to decrypt, or --raw to write the raw ciphertext anyway.");
|
|
2260
2275
|
}
|
|
2261
2276
|
ctx.output.warn("Writing raw ciphertext (--raw); the output is unusable without decryption.");
|
|
2262
2277
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@arcadiasystems/morse-cli",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.1",
|
|
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.7.0",
|
|
59
59
|
"@mysten/seal": "1.1.3",
|
|
60
60
|
"@mysten/sui": "2.16.2",
|
|
61
61
|
"@mysten/walrus": "1.1.6",
|