@arcadiasystems/morse-sdk 0.4.2 → 0.4.3
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 +10 -0
- package/README.md +33 -30
- package/package.json +1 -9
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to `morse-sdk` will be documented in this file. Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and the project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
4
4
|
|
|
5
|
+
## [0.4.3] - 2026-07-07
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
|
|
9
|
+
- **`@mysten/seal` and `@mysten/walrus` are now required peer dependencies** (previously marked optional). The package's main entry re-exports the default Seal and Walrus adapters, whose static imports made both packages mandatory at runtime: a "minimal" install following the old README crashed with `ERR_MODULE_NOT_FOUND` on the very first `import` from the SDK. Declaring them required means npm 7+ auto-installs them and every documented install path yields a working import. No code changes; installs that already included all three Mysten packages are unaffected.
|
|
10
|
+
- **README regenerated against the real 0.4.x surface.** The published README still documented the pre-0.4.0 allowlist/file API (`createAllowlist`, `addMember`, `createEncryptedFile`, `uploadEncryptedFileFromBytes`, `RpcFilesReader`, `buildAllowlistSealId`, …— all removed in 0.4.0) and never mentioned the `RecipientFile` API that replaced it. API tables, reader section, Seal identity section, and types now match `dist/index.d.ts`.
|
|
11
|
+
- **Quick-start slug is collision-proof.** The README and examples used the fixed slug `"my-publication"`, which is already registered on testnet — every reader who ran the quick start verbatim hit `ESlugAlreadyExists`. Examples now derive a unique slug and call out that slugs are globally unique on-chain.
|
|
12
|
+
- **Dead Walrus faucet link replaced.** `docs.walrus.site` no longer resolves; WAL acquisition now points at the working [stake-wal.wal.app](https://stake-wal.wal.app/?network=testnet) swap, matching docs.morsecms.xyz.
|
|
13
|
+
- Stale version references cleaned up (compatibility table now lists 0.4.x; removed "at v0.1.0" qualifiers) and a "storage is epoch-funded, not permanent" note added to Known limitations.
|
|
14
|
+
|
|
5
15
|
## [0.4.2] - 2026-06-05
|
|
6
16
|
|
|
7
17
|
### Fixed
|
package/README.md
CHANGED
|
@@ -8,32 +8,27 @@ Pre-release. Testnet only. The Move contract addresses are baked in via `morseCo
|
|
|
8
8
|
|
|
9
9
|
## Install
|
|
10
10
|
|
|
11
|
+
All three Mysten packages are required peer dependencies. Pin the minors the SDK is verified against (see [Compatibility](#compatibility)):
|
|
12
|
+
|
|
11
13
|
Bun:
|
|
12
14
|
|
|
13
15
|
```sh
|
|
14
|
-
bun add @arcadiasystems/morse-sdk @mysten/sui
|
|
15
|
-
# Optional - install only what you use:
|
|
16
|
-
bun add @mysten/walrus # for DefaultWalrusWriteAdapter
|
|
17
|
-
bun add @mysten/seal # for DefaultSealAdapter and encrypted entries
|
|
16
|
+
bun add @arcadiasystems/morse-sdk @mysten/sui@2.16.2 @mysten/walrus@1.1.6 @mysten/seal@1.1.3
|
|
18
17
|
```
|
|
19
18
|
|
|
20
19
|
npm:
|
|
21
20
|
|
|
22
21
|
```sh
|
|
23
|
-
npm install @arcadiasystems/morse-sdk @mysten/sui
|
|
24
|
-
npm install @mysten/walrus # optional
|
|
25
|
-
npm install @mysten/seal # optional
|
|
22
|
+
npm install @arcadiasystems/morse-sdk @mysten/sui@2.16.2 @mysten/walrus@1.1.6 @mysten/seal@1.1.3
|
|
26
23
|
```
|
|
27
24
|
|
|
28
25
|
pnpm:
|
|
29
26
|
|
|
30
27
|
```sh
|
|
31
|
-
pnpm add @arcadiasystems/morse-sdk @mysten/sui
|
|
32
|
-
pnpm add @mysten/walrus # optional
|
|
33
|
-
pnpm add @mysten/seal # optional
|
|
28
|
+
pnpm add @arcadiasystems/morse-sdk @mysten/sui@2.16.2 @mysten/walrus@1.1.6 @mysten/seal@1.1.3
|
|
34
29
|
```
|
|
35
30
|
|
|
36
|
-
`@mysten/sui`
|
|
31
|
+
`@mysten/sui` provides the client, keypairs, and transaction types; `@mysten/walrus` backs the default storage adapters (any publish path needs it); `@mysten/seal` backs threshold encryption. All three are imported by the SDK's public surface, so they must be installed even if you only use a subset — npm 7+ installs required peers automatically when you omit them.
|
|
37
32
|
|
|
38
33
|
## Compatibility
|
|
39
34
|
|
|
@@ -41,9 +36,10 @@ morse-sdk is built and tested against specific minor versions of its Mysten subs
|
|
|
41
36
|
|
|
42
37
|
| morse-sdk | `@mysten/sui` | `@mysten/walrus` | `@mysten/seal` | Sui network | Verified |
|
|
43
38
|
| --------- | ------------- | ---------------- | -------------- | ----------- | --------- |
|
|
39
|
+
| 0.4.x | 2.16.2-2.16.x | 1.1.6-1.1.x | 1.1.3-1.1.x | testnet | 2026-06-05 |
|
|
44
40
|
| 0.1.x | 2.16.2-2.16.x | 1.1.6-1.1.x | 1.1.3-1.1.x | testnet | 2026-05-10 |
|
|
45
41
|
|
|
46
|
-
Mysten ships breaking changes inside major version boundaries.
|
|
42
|
+
Mysten ships breaking changes inside major version boundaries. Newer minors (e.g. `@mysten/walrus@1.2.x`, `@mysten/sui@2.17+`) are outside the verified ranges and may produce runtime errors; morse-sdk needs a coordinated bump and re-verification before a new Mysten minor is supported. Pin via `bun add @arcadiasystems/morse-sdk@~0.4.0` if you want patch updates without surprise minors.
|
|
47
43
|
|
|
48
44
|
The verification protocol is documented in [`CONTRIBUTING.md`](./CONTRIBUTING.md): every Mysten dep bump runs the full `scripts/phase-N-*.ts` smoke suite against testnet before the bump lands.
|
|
49
45
|
|
|
@@ -65,6 +61,7 @@ Setup once at startup:
|
|
|
65
61
|
|
|
66
62
|
```ts
|
|
67
63
|
import { SuiGrpcClient } from "@mysten/sui/grpc";
|
|
64
|
+
import { Ed25519Keypair } from "@mysten/sui/keypairs/ed25519";
|
|
68
65
|
import {
|
|
69
66
|
KeypairAdapter,
|
|
70
67
|
morseConfig,
|
|
@@ -73,7 +70,8 @@ import {
|
|
|
73
70
|
|
|
74
71
|
const config = morseConfig({ network: "testnet" });
|
|
75
72
|
const client = new SuiGrpcClient({ network: "testnet", baseUrl: config.rpcUrl });
|
|
76
|
-
const
|
|
73
|
+
const keypair = Ed25519Keypair.fromSecretKey(privateKey); // Bech32 "suiprivkey1..."
|
|
74
|
+
const adapter = new KeypairAdapter(keypair, client);
|
|
77
75
|
// Browser apps swap KeypairAdapter for a WalletAdapter impl against the
|
|
78
76
|
// connected wallet's signer - see "Adapter pattern" below.
|
|
79
77
|
const reader = RpcPublicationReader.fromMorseConfig(config, client);
|
|
@@ -90,9 +88,11 @@ import {
|
|
|
90
88
|
StorageMode,
|
|
91
89
|
} from "@arcadiasystems/morse-sdk";
|
|
92
90
|
|
|
91
|
+
// Slugs are globally unique on-chain (like usernames) - make yours
|
|
92
|
+
// collision-proof rather than copying a fixed example value.
|
|
93
93
|
const created = await createPublication(adapter, config, {
|
|
94
94
|
name: "My Publication",
|
|
95
|
-
slug:
|
|
95
|
+
slug: `my-pub-${Date.now()}`,
|
|
96
96
|
});
|
|
97
97
|
await createCollection(adapter, config, {
|
|
98
98
|
publicationId: created.publicationId,
|
|
@@ -216,13 +216,12 @@ The full public surface, grouped by concern. Every export carries a JSDoc on its
|
|
|
216
216
|
| `addEntry` / `addEncryptedEntry` | Lower-level: add entry against a pre-uploaded `blobObjectId`. |
|
|
217
217
|
| `appendDraftRevision` / `appendEncryptedDraftRevision` / `publishFromDraft` / `publishDirect` | Revision lifecycle on existing entries. |
|
|
218
218
|
| `deleteEntry` | Remove an entry and its revisions. |
|
|
219
|
-
| `
|
|
220
|
-
| `
|
|
221
|
-
| `
|
|
222
|
-
| `
|
|
223
|
-
| `
|
|
224
|
-
| `
|
|
225
|
-
| `updateFileMetadata` / `transferFileOwnership` / `deleteFile` | File metadata lifecycle (owner-only). |
|
|
219
|
+
| `createRecipientFile(adapter, config, args)` | Register + share a `RecipientFile` for a blob already on Walrus (single PTB). |
|
|
220
|
+
| `createEncryptedRecipientFile(adapter, config, args)` | Same, for a blob already Seal-encrypted under a caller-supplied `sealIdPrefix`. |
|
|
221
|
+
| `uploadRecipientFileFromBytes(adapter, config, args)` | **Recommended.** Upload bytes + register + share a `RecipientFile` addressed to N recipients in 2 wallet popups. |
|
|
222
|
+
| `uploadEncryptedRecipientFileFromBytes(adapter, config, args)` | **Recommended.** Encrypt via Seal + upload + register in 2 wallet popups; returns `{ sealIdPrefix, sealNonce, fileId, ... }` for later decrypt. |
|
|
223
|
+
| `addRecipient` / `removeRecipient` | Mutate the file's embedded recipient set (owner-only). |
|
|
224
|
+
| `updateRecipientFileMetadata` / `transferRecipientFileOwnership` / `deleteRecipientFile` | RecipientFile lifecycle (owner-only). |
|
|
226
225
|
|
|
227
226
|
### Reader (RPC-backed)
|
|
228
227
|
|
|
@@ -232,9 +231,10 @@ The full public surface, grouped by concern. Every export carries a JSDoc on its
|
|
|
232
231
|
| `reader.getPublication` / `getEntry` / `getRevision` / `getPublisherCap` | Single-object reads. |
|
|
233
232
|
| `reader.listPublicationsOwnedBy` / `listPublisherCapsOwnedBy` / `listEntries` | Paginated lists. |
|
|
234
233
|
| `reader.scanEntries` | Async-iterator over every entry in a collection. |
|
|
235
|
-
| `
|
|
236
|
-
| `filesReader.
|
|
237
|
-
| `
|
|
234
|
+
| `RpcRecipientFilesReader.fromMorseConfig(config, client)` | Construct a reader for the `recipient_file` module. |
|
|
235
|
+
| `filesReader.getRecipientFile(id)` | Live single-object read (parses embedded `members`, blob refs). |
|
|
236
|
+
| `buildRecipientFileEventTypes(originPackageId)` | Fully-qualified event type strings for the `RecipientFile*` events; pass `config.recipientFileEventOriginPackageId`. |
|
|
237
|
+
| `reconcileRecipientFilesOwnedBy(events, address, eventTypes)` / `reconcileRecipientFilesAccessibleBy(...)` | Pure event-reconciliation helpers — bring your own indexer, get current file sets back. |
|
|
238
238
|
|
|
239
239
|
### Adapters
|
|
240
240
|
|
|
@@ -258,8 +258,10 @@ The full public surface, grouped by concern. Every export carries a JSDoc on its
|
|
|
258
258
|
| --- | --- |
|
|
259
259
|
| `buildPublisherSealId(publicationId, nonce)` | Build a publisher-policy Seal identity (`pubId(32) \|\| tag(1) \|\| nonce`). |
|
|
260
260
|
| `decodePublisherSealId(sealId)` | Inspect a publisher identity. Throws `ValidationError` on tampered tags. |
|
|
261
|
-
| `
|
|
262
|
-
| `
|
|
261
|
+
| `buildRecipientFileSealId(prefix, nonce)` | Build a recipient-file Seal identity (`prefix \|\| tag(3) \|\| nonce`). |
|
|
262
|
+
| `decodeRecipientFileSealId(sealId, prefixLength)` | Inspect a recipient-file identity (layout is not self-delimiting; caller supplies `prefixLength`). |
|
|
263
|
+
| `randomSealPrefix()` / `randomSealNonce()` | Helpers for the common case: 32 random prefix bytes / 16 random nonce bytes. |
|
|
264
|
+
| `RECOMMENDED_SEAL_PREFIX_BYTES` / `RECOMMENDED_SEAL_NONCE_BYTES` | The recommended sizes as constants (32 / 16). |
|
|
263
265
|
|
|
264
266
|
### Codecs (branded ID constructors)
|
|
265
267
|
|
|
@@ -287,7 +289,7 @@ The full public surface, grouped by concern. Every export carries a JSDoc on its
|
|
|
287
289
|
|
|
288
290
|
### Types
|
|
289
291
|
|
|
290
|
-
`Publication`, `Collection`, `Entry`, `Revision`, `PublisherCap`, `OwnerCap`, `BlobRef`, `AccessPolicy`, `StorageMode`, `SealPolicyTag`, branded ID types (`PublicationId`, `BlobObjectId`, `WalrusBlobId`, `QuiltPatchId`, etc.).
|
|
292
|
+
`Publication`, `Collection`, `Entry`, `Revision`, `PublisherCap`, `OwnerCap`, `BlobRef`, `AccessPolicy`, `StorageMode`, `SealPolicyTag`, `RecipientFile` / `RecipientFileSummary` / `RecipientFileFull`, branded ID types (`PublicationId`, `RecipientFileId`, `BlobObjectId`, `WalrusBlobId`, `QuiltPatchId`, etc.).
|
|
291
293
|
|
|
292
294
|
## Conceptual model
|
|
293
295
|
|
|
@@ -451,8 +453,9 @@ const config = morseConfig({
|
|
|
451
453
|
- **`Subscription` access policy is reserved**, not enforced.
|
|
452
454
|
- **`listEntries` ordering is dynamic-field object-store order**, not chronological. Sort by `entry.id` for insertion order.
|
|
453
455
|
- **Walrus testnet flakiness**. `NotEnoughBlobConfirmationsError` from the underlying client is environmental; rerun. The SDK preserves the original error as the `cause` (use `instanceof` for narrowing — Walrus error classes don't set `.name`). Browser consumers may additionally see `NoBlobMetadataReceivedError` on reads from testnet due to CORS gaps on a subset of Walrus storage nodes; the CLI smoke scripts hit the full node pool and are more reliable for verification.
|
|
454
|
-
- **Walrus uploads need WAL, not just SUI**.
|
|
455
|
-
- **
|
|
456
|
+
- **Walrus uploads need WAL, not just SUI**. Get testnet SUI from the [Sui faucet](https://faucet.sui.io/), then swap some for WAL at [stake-wal.wal.app](https://stake-wal.wal.app/?network=testnet). Uploads error with `Insufficient balance of ::wal::WAL` if you skip this.
|
|
457
|
+
- **Walrus storage is epoch-funded, not permanent**. Blobs persist for the epochs you pay for (a testnet epoch is roughly a day) and expire afterwards unless renewed; Walrus testnet is also periodically wiped. The on-chain revision history is immutable, but treat testnet payloads as disposable.
|
|
458
|
+
- **gRPC client only**. The reader and adapter interfaces are typed against `Pick<SuiGrpcClient, ...>` from `@mysten/sui/grpc`. `SuiJsonRpcClient` from `@mysten/sui/jsonRpc` has differently-named methods (`getDynamicFields` vs `listDynamicFields`, etc.) and is not yet a drop-in alternative. JSON-RPC fallback is planned; for now, environments that block gRPC need to proxy or use a gRPC-compatible RPC endpoint.
|
|
456
459
|
|
|
457
460
|
## Smoke scripts
|
|
458
461
|
|
|
@@ -482,7 +485,7 @@ bun install
|
|
|
482
485
|
bun run lint
|
|
483
486
|
bun run typecheck
|
|
484
487
|
bun run test
|
|
485
|
-
bun run test:coverage #
|
|
488
|
+
bun run test:coverage # per-file coverage report
|
|
486
489
|
bun run build
|
|
487
490
|
```
|
|
488
491
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@arcadiasystems/morse-sdk",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.3",
|
|
4
4
|
"description": "TypeScript SDK for Morse dCMS on the Sui blockchain.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -57,14 +57,6 @@
|
|
|
57
57
|
"@mysten/sui": ">=2.16.2 <2.17.0",
|
|
58
58
|
"@mysten/walrus": ">=1.1.6 <1.2.0"
|
|
59
59
|
},
|
|
60
|
-
"peerDependenciesMeta": {
|
|
61
|
-
"@mysten/seal": {
|
|
62
|
-
"optional": true
|
|
63
|
-
},
|
|
64
|
-
"@mysten/walrus": {
|
|
65
|
-
"optional": true
|
|
66
|
-
}
|
|
67
|
-
},
|
|
68
60
|
"devDependencies": {
|
|
69
61
|
"@biomejs/biome": "2.4.7",
|
|
70
62
|
"@mysten/bcs": "2.0.3",
|