@misofm/sdk 0.15.7 → 0.15.9

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.
Files changed (51) hide show
  1. package/README.md +8 -3
  2. package/dist/client.d.ts +22 -2
  3. package/dist/client.d.ts.map +1 -1
  4. package/dist/client.js +15 -1
  5. package/dist/client.js.map +1 -1
  6. package/dist/contracts/vault/vault.d.ts +149 -23
  7. package/dist/contracts/vault/vault.d.ts.map +1 -1
  8. package/dist/contracts/vault/vault.js +144 -18
  9. package/dist/contracts/vault/vault.js.map +1 -1
  10. package/dist/deployments.d.ts +10 -7
  11. package/dist/deployments.d.ts.map +1 -1
  12. package/dist/deployments.js +8 -7
  13. package/dist/deployments.js.map +1 -1
  14. package/dist/publication.d.ts.map +1 -1
  15. package/dist/publication.js +8 -4
  16. package/dist/publication.js.map +1 -1
  17. package/dist/read/catalog.d.ts.map +1 -1
  18. package/dist/read/catalog.js +24 -13
  19. package/dist/read/catalog.js.map +1 -1
  20. package/dist/read/config.d.ts +2 -0
  21. package/dist/read/config.d.ts.map +1 -1
  22. package/dist/read/config.js +1 -0
  23. package/dist/read/config.js.map +1 -1
  24. package/dist/read/internal/walrus.d.ts +2 -0
  25. package/dist/read/internal/walrus.d.ts.map +1 -1
  26. package/dist/read/internal/walrus.js +5 -0
  27. package/dist/read/internal/walrus.js.map +1 -1
  28. package/dist/read/types.d.ts +2 -0
  29. package/dist/read/types.d.ts.map +1 -1
  30. package/dist/read/wallet.js +1 -1
  31. package/dist/read/wallet.js.map +1 -1
  32. package/dist/recording-extensions.d.ts +14 -1
  33. package/dist/recording-extensions.d.ts.map +1 -1
  34. package/dist/recording-extensions.js +65 -0
  35. package/dist/recording-extensions.js.map +1 -1
  36. package/dist/vault.d.ts +31 -4
  37. package/dist/vault.d.ts.map +1 -1
  38. package/dist/vault.js +41 -7
  39. package/dist/vault.js.map +1 -1
  40. package/package.json +1 -1
  41. package/src/client.ts +22 -1
  42. package/src/contracts/vault/vault.ts +226 -21
  43. package/src/deployments.ts +10 -7
  44. package/src/publication.ts +9 -5
  45. package/src/read/catalog.ts +31 -13
  46. package/src/read/config.ts +3 -0
  47. package/src/read/internal/walrus.ts +9 -0
  48. package/src/read/types.ts +2 -0
  49. package/src/read/wallet.ts +1 -1
  50. package/src/recording-extensions.ts +104 -1
  51. package/src/vault.ts +86 -9
@@ -1,13 +1,17 @@
1
1
  // Copyright (c) Miso Labs, Inc.
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
 
4
- /** Cap-authorized builders for data-only Recording metadata extensions. */
4
+ /** Cap-authorized builders and reads for data-only Recording metadata extensions. */
5
5
 
6
+ import { bcs } from "@mysten/sui/bcs";
7
+ import type { ClientWithCoreApi } from "@mysten/sui/client";
6
8
  import type { Transaction, TransactionArgument, TransactionObjectArgument } from "@mysten/sui/transactions";
9
+ import { deriveDynamicFieldID } from "@mysten/sui/utils";
7
10
  import type { TxThunk } from "./transactions.ts";
8
11
  import { invokeWithAdminCap, type AdminCapAuthority, type ObjectInput } from "./vault.ts";
9
12
  import * as advisory from "./contracts/recording_advisory/recording_advisory.ts";
10
13
  import * as language from "./contracts/recording_language/recording_language.ts";
14
+ import * as walrusData from "./contracts/recording_master_reference/deps/ori/walrus_data.ts";
11
15
  import * as masterReference from "./contracts/recording_master_reference/recording_master_reference.ts";
12
16
  import * as preview from "./contracts/recording_preview/recording_preview.ts";
13
17
 
@@ -104,3 +108,102 @@ export function setRecordingPreview(p: SetRecordingPreviewParams): TxThunk {
104
108
  });
105
109
  };
106
110
  }
111
+
112
+ // ── Master-reference reads ───────────────────────────────────────────────────
113
+
114
+ // recording_master_reference stores the ori::WalrusData value inline in a
115
+ // dynamic field on the Recording. Its empty ExtensionKey serializes to one false
116
+ // byte, so the field object id can be derived without listing the Recording's
117
+ // dynamic fields.
118
+ const MasterReferenceField = bcs.struct("Field", {
119
+ id: bcs.Address,
120
+ name: masterReference.ExtensionKey,
121
+ value: walrusData.WalrusData,
122
+ });
123
+ const MASTER_REFERENCE_KEY_BYTES = masterReference.ExtensionKey.serialize([
124
+ false,
125
+ ]).toBytes();
126
+
127
+ type ParsedWalrusData =
128
+ | { $kind: "Blob"; Blob: [string | number | bigint, unknown] }
129
+ | {
130
+ $kind: "QuiltPatch";
131
+ QuiltPatch: [string | number | bigint, number, number, number];
132
+ };
133
+
134
+ /** Parse an attached master reference's standalone Walrus blob id. */
135
+ export function parseRecordingMasterReferenceContent(
136
+ content: Uint8Array,
137
+ ): string | null {
138
+ const reference = MasterReferenceField.parse(content)
139
+ .value as ParsedWalrusData;
140
+ return reference.$kind === "Blob" ? String(reference.Blob[0]) : null;
141
+ }
142
+
143
+ /** Deterministic dynamic-field id for a Recording's master reference. */
144
+ export function recordingMasterReferenceFieldId(
145
+ recordingId: string,
146
+ recordingMasterReferencePackageId: string,
147
+ ): string {
148
+ return deriveDynamicFieldID(
149
+ recordingId,
150
+ `${recordingMasterReferencePackageId}::recording_master_reference::ExtensionKey`,
151
+ MASTER_REFERENCE_KEY_BYTES,
152
+ );
153
+ }
154
+
155
+ /** Read one Recording's master-reference blob id, or null when absent. */
156
+ export async function getRecordingMasterReference(
157
+ client: ClientWithCoreApi,
158
+ recordingId: string,
159
+ recordingMasterReferencePackageId: string,
160
+ ): Promise<string | null> {
161
+ return (
162
+ (
163
+ await getRecordingMasterReferencesByIds(
164
+ client,
165
+ [recordingId],
166
+ recordingMasterReferencePackageId,
167
+ )
168
+ )[recordingId] ?? null
169
+ );
170
+ }
171
+
172
+ /**
173
+ * Read master-reference blob ids for many Recordings in one Core request.
174
+ *
175
+ * Missing fields and malformed individual objects are omitted so one Recording
176
+ * without a playable master cannot make the rest of an album unplayable.
177
+ */
178
+ export async function getRecordingMasterReferencesByIds(
179
+ client: ClientWithCoreApi,
180
+ recordingIdsInput: readonly string[],
181
+ recordingMasterReferencePackageId: string,
182
+ ): Promise<Partial<Record<string, string>>> {
183
+ const recordingIds = [...new Set(recordingIdsInput)];
184
+ const targets = recordingIds.map((recordingId) => ({
185
+ recordingId,
186
+ fieldId: recordingMasterReferenceFieldId(
187
+ recordingId,
188
+ recordingMasterReferencePackageId,
189
+ ),
190
+ }));
191
+ if (targets.length === 0) return {};
192
+
193
+ const { objects } = await client.core.getObjects({
194
+ objectIds: targets.map((target) => target.fieldId),
195
+ include: { content: true },
196
+ });
197
+ const out: Partial<Record<string, string>> = {};
198
+ objects.forEach((object, index) => {
199
+ const target = targets[index];
200
+ if (!target || object instanceof Error || !object.content) return;
201
+ try {
202
+ const blobId = parseRecordingMasterReferenceContent(object.content);
203
+ if (blobId) out[target.recordingId] = blobId;
204
+ } catch {
205
+ // Extension metadata is soft: retain valid tracks when one field is stale.
206
+ }
207
+ });
208
+ return out;
209
+ }
package/src/vault.ts CHANGED
@@ -17,7 +17,7 @@ import type {
17
17
  TransactionArgument,
18
18
  TransactionObjectArgument,
19
19
  } from "@mysten/sui/transactions";
20
- import { normalizeStructTag } from "@mysten/sui/utils";
20
+ import { deriveObjectID, normalizeStructTag } from "@mysten/sui/utils";
21
21
  import * as vault from "./contracts/vault/vault.ts";
22
22
  import * as compositionRoyaltyPool from "./contracts/composition_royalty_pool/composition_royalty_pool.ts";
23
23
  import * as recordingRoyaltyPool from "./contracts/recording_royalty_pool/recording_royalty_pool.ts";
@@ -145,6 +145,8 @@ export function invokeWithAdminCap(
145
145
  export interface CustodyNewAdminCapParams {
146
146
  /** The freshly-created raw protocol cap, consumed into the Vault. */
147
147
  readonly adminCap: TransactionObjectArgument;
148
+ /** Shared singleton from which canonical Vault IDs are derived. */
149
+ readonly vaultRegistry: ObjectInput;
148
150
  readonly capType: string;
149
151
  readonly vaultPackageId: string;
150
152
  /** Recipient of the only owner-held authority: VaultAdminCap. */
@@ -162,6 +164,7 @@ export type AdminCapCustody =
162
164
  | {
163
165
  readonly kind: "vault";
164
166
  readonly owner: string | TransactionArgument;
167
+ readonly vaultRegistry: ObjectInput;
165
168
  readonly capType: string;
166
169
  readonly vaultPackageId: string;
167
170
  readonly configure?: CustodyNewAdminCapParams["configure"];
@@ -179,6 +182,7 @@ export function disposeNewAdminCap(
179
182
  }
180
183
  custodyNewAdminCap(tx, {
181
184
  adminCap,
185
+ vaultRegistry: custody.vaultRegistry,
182
186
  capType: custody.capType,
183
187
  vaultPackageId: custody.vaultPackageId,
184
188
  owner: custody.owner,
@@ -186,23 +190,60 @@ export function disposeNewAdminCap(
186
190
  });
187
191
  }
188
192
 
189
- /** Destroy a vault only while deliberately disposing of its returned raw cap. */
190
- export function destroyVault(
193
+ /** Withdraw the raw capability while leaving its canonical Vault shell intact. */
194
+ export function withdrawVaultCapability(
191
195
  tx: Transaction,
192
196
  params: {
193
197
  readonly vault: ObjectInput;
194
198
  readonly vaultAdminCap: ObjectInput;
195
199
  readonly capType: string;
196
200
  readonly vaultPackageId: string;
197
- readonly disposition: AdminCapCustody;
198
201
  },
199
- ): void {
200
- const cap = tx.add(vault.destroy({
202
+ ): TransactionObjectArgument {
203
+ return tx.add(vault.withdrawCap({
201
204
  package: params.vaultPackageId,
202
205
  typeArguments: [params.capType],
203
206
  arguments: [object(tx, params.vault), object(tx, params.vaultAdminCap)],
204
207
  }));
205
- disposeNewAdminCap(tx, cap, params.disposition);
208
+ }
209
+
210
+ /** Restore the one exact capability permanently assigned to a Vault. */
211
+ export function restoreVaultCapability(
212
+ tx: Transaction,
213
+ params: {
214
+ readonly vault: ObjectInput;
215
+ readonly vaultAdminCap: ObjectInput;
216
+ readonly adminCap: ObjectInput;
217
+ readonly capType: string;
218
+ readonly vaultPackageId: string;
219
+ },
220
+ ): void {
221
+ tx.add(vault.restoreCap({
222
+ package: params.vaultPackageId,
223
+ typeArguments: [params.capType],
224
+ arguments: [
225
+ object(tx, params.vault),
226
+ object(tx, params.vaultAdminCap),
227
+ object(tx, params.adminCap),
228
+ ],
229
+ }));
230
+ }
231
+
232
+ /** Transfer the key-only VaultAdminCap through the Vault module. */
233
+ export function transferVaultAdminCap(
234
+ tx: Transaction,
235
+ params: {
236
+ readonly vaultAdminCap: ObjectInput;
237
+ readonly owner: string | TransactionArgument;
238
+ readonly capType: string;
239
+ readonly vaultPackageId: string;
240
+ },
241
+ ): void {
242
+ tx.add(vault.transferAdminCap({
243
+ package: params.vaultPackageId,
244
+ typeArguments: [params.capType],
245
+ arguments: [object(tx, params.vaultAdminCap), params.owner],
246
+ }));
206
247
  }
207
248
 
208
249
  /**
@@ -217,7 +258,7 @@ export function custodyNewAdminCap(
217
258
  vault._new({
218
259
  package: params.vaultPackageId,
219
260
  typeArguments: [params.capType],
220
- arguments: [params.adminCap],
261
+ arguments: [object(tx, params.vaultRegistry), params.adminCap],
221
262
  }),
222
263
  );
223
264
  const vaultObject = requiredVaultResult(created, 0, "vault::_new");
@@ -230,7 +271,43 @@ export function custodyNewAdminCap(
230
271
  arguments: [vaultObject],
231
272
  }),
232
273
  );
233
- tx.transferObjects([vaultAdminCap], params.owner);
274
+ transferVaultAdminCap(tx, {
275
+ vaultAdminCap,
276
+ owner: params.owner,
277
+ capType: params.capType,
278
+ vaultPackageId: params.vaultPackageId,
279
+ });
280
+ }
281
+
282
+ export interface VaultIdParams {
283
+ readonly vaultRegistryId: string;
284
+ readonly capId: string;
285
+ readonly capType: string;
286
+ readonly vaultPackageId: string;
287
+ }
288
+
289
+ /** Derive the canonical Vault ID without an RPC lookup. */
290
+ export function deriveVaultId(params: VaultIdParams): string {
291
+ const keyType = normalizeStructTag(
292
+ `${params.vaultPackageId}::vault::VaultKey<${params.capType}>`,
293
+ );
294
+ return deriveObjectID(
295
+ params.vaultRegistryId,
296
+ keyType,
297
+ vault.VaultKey.serialize([params.capId]).toBytes(),
298
+ );
299
+ }
300
+
301
+ /** Derive the canonical VaultAdminCap ID from its Vault ID. */
302
+ export function deriveVaultAdminCapId(
303
+ vaultId: string,
304
+ vaultPackageId: string,
305
+ ): string {
306
+ return deriveObjectID(
307
+ vaultId,
308
+ `${vaultPackageId}::vault::VaultAdminCapKey`,
309
+ vault.VaultAdminCapKey.serialize([false]).toBytes(),
310
+ );
234
311
  }
235
312
 
236
313
  export interface CompositionRoyaltyPoolPluginParams {