@misofm/sdk 0.15.10 → 0.16.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.
Files changed (145) hide show
  1. package/README.md +153 -56
  2. package/dist/client.d.ts +175 -47
  3. package/dist/client.d.ts.map +1 -1
  4. package/dist/client.js +302 -47
  5. package/dist/client.js.map +1 -1
  6. package/dist/contracts/composition_royalty_pool/composition_royalty_pool.d.ts +11 -11
  7. package/dist/contracts/composition_royalty_pool/composition_royalty_pool.d.ts.map +1 -1
  8. package/dist/contracts/composition_royalty_pool/composition_royalty_pool.js +9 -9
  9. package/dist/contracts/composition_royalty_pool/composition_royalty_pool.js.map +1 -1
  10. package/dist/contracts/miso_record/deps/std/type_name.d.ts.map +1 -0
  11. package/dist/contracts/miso_record/deps/std/type_name.js.map +1 -0
  12. package/dist/contracts/miso_record/deps/sui/vec_set.d.ts +21 -0
  13. package/dist/contracts/miso_record/deps/sui/vec_set.d.ts.map +1 -0
  14. package/dist/contracts/miso_record/deps/sui/vec_set.js +20 -0
  15. package/dist/contracts/miso_record/deps/sui/vec_set.js.map +1 -0
  16. package/dist/contracts/miso_record/pressing.d.ts +327 -0
  17. package/dist/contracts/miso_record/pressing.d.ts.map +1 -0
  18. package/dist/contracts/miso_record/pressing.js +345 -0
  19. package/dist/contracts/miso_record/pressing.js.map +1 -0
  20. package/dist/contracts/miso_record/record.d.ts +190 -0
  21. package/dist/contracts/miso_record/record.d.ts.map +1 -0
  22. package/dist/contracts/miso_record/record.js +226 -0
  23. package/dist/contracts/miso_record/record.js.map +1 -0
  24. package/dist/contracts/miso_record_shop/deps/std/type_name.d.ts +18 -0
  25. package/dist/contracts/miso_record_shop/deps/std/type_name.d.ts.map +1 -0
  26. package/dist/contracts/miso_record_shop/deps/std/type_name.js +20 -0
  27. package/dist/contracts/miso_record_shop/deps/std/type_name.js.map +1 -0
  28. package/dist/contracts/miso_record_shop/listing.d.ts +387 -0
  29. package/dist/contracts/miso_record_shop/listing.d.ts.map +1 -0
  30. package/dist/contracts/miso_record_shop/listing.js +380 -0
  31. package/dist/contracts/miso_record_shop/listing.js.map +1 -0
  32. package/dist/contracts/miso_record_shop/witness.d.ts +7 -0
  33. package/dist/contracts/miso_record_shop/witness.d.ts.map +1 -0
  34. package/dist/contracts/miso_record_shop/witness.js +9 -0
  35. package/dist/contracts/miso_record_shop/witness.js.map +1 -0
  36. package/dist/contracts/recording_royalty_pool/recording_royalty_pool.d.ts +10 -12
  37. package/dist/contracts/recording_royalty_pool/recording_royalty_pool.d.ts.map +1 -1
  38. package/dist/contracts/recording_royalty_pool/recording_royalty_pool.js +8 -10
  39. package/dist/contracts/recording_royalty_pool/recording_royalty_pool.js.map +1 -1
  40. package/dist/contracts/vault/vault.d.ts +149 -23
  41. package/dist/contracts/vault/vault.d.ts.map +1 -1
  42. package/dist/contracts/vault/vault.js +144 -18
  43. package/dist/contracts/vault/vault.js.map +1 -1
  44. package/dist/contracts.d.ts +3 -3
  45. package/dist/contracts.d.ts.map +1 -1
  46. package/dist/contracts.js +5 -4
  47. package/dist/contracts.js.map +1 -1
  48. package/dist/deployments.d.ts +47 -11
  49. package/dist/deployments.d.ts.map +1 -1
  50. package/dist/deployments.js +48 -9
  51. package/dist/deployments.js.map +1 -1
  52. package/dist/index.d.ts +2 -0
  53. package/dist/index.d.ts.map +1 -1
  54. package/dist/index.js +2 -0
  55. package/dist/index.js.map +1 -1
  56. package/dist/mix.d.ts +144 -0
  57. package/dist/mix.d.ts.map +1 -0
  58. package/dist/mix.js +656 -0
  59. package/dist/mix.js.map +1 -0
  60. package/dist/pressing.d.ts +72 -156
  61. package/dist/pressing.d.ts.map +1 -1
  62. package/dist/pressing.js +269 -261
  63. package/dist/pressing.js.map +1 -1
  64. package/dist/publication.d.ts +5 -2
  65. package/dist/publication.d.ts.map +1 -1
  66. package/dist/publication.js +63 -34
  67. package/dist/publication.js.map +1 -1
  68. package/dist/read/catalog.d.ts +8 -5
  69. package/dist/read/catalog.d.ts.map +1 -1
  70. package/dist/read/catalog.js +47 -35
  71. package/dist/read/catalog.js.map +1 -1
  72. package/dist/read/config.d.ts +6 -4
  73. package/dist/read/config.d.ts.map +1 -1
  74. package/dist/read/config.js +1 -2
  75. package/dist/read/config.js.map +1 -1
  76. package/dist/read/index.d.ts +1 -1
  77. package/dist/read/index.d.ts.map +1 -1
  78. package/dist/read/index.js +1 -1
  79. package/dist/read/index.js.map +1 -1
  80. package/dist/read/internal/scalars.d.ts.map +1 -1
  81. package/dist/read/internal/scalars.js +4 -3
  82. package/dist/read/internal/scalars.js.map +1 -1
  83. package/dist/read/internal/walrus.d.ts.map +1 -1
  84. package/dist/read/internal/walrus.js +2 -1
  85. package/dist/read/internal/walrus.js.map +1 -1
  86. package/dist/read/receipts.d.ts +21 -12
  87. package/dist/read/receipts.d.ts.map +1 -1
  88. package/dist/read/receipts.js +159 -56
  89. package/dist/read/receipts.js.map +1 -1
  90. package/dist/read/types.d.ts +40 -26
  91. package/dist/read/types.d.ts.map +1 -1
  92. package/dist/read/wallet.d.ts +3 -4
  93. package/dist/read/wallet.d.ts.map +1 -1
  94. package/dist/read/wallet.js +72 -53
  95. package/dist/read/wallet.js.map +1 -1
  96. package/dist/vault.d.ts +71 -15
  97. package/dist/vault.d.ts.map +1 -1
  98. package/dist/vault.js +135 -29
  99. package/dist/vault.js.map +1 -1
  100. package/package.json +10 -3
  101. package/src/client.ts +404 -69
  102. package/src/contracts/composition_royalty_pool/composition_royalty_pool.ts +15 -15
  103. package/src/contracts/miso_record/deps/sui/vec_set.ts +21 -0
  104. package/src/contracts/miso_record/pressing.ts +522 -0
  105. package/src/contracts/miso_record/record.ts +338 -0
  106. package/src/contracts/miso_record_shop/deps/std/type_name.ts +22 -0
  107. package/src/contracts/miso_record_shop/listing.ts +602 -0
  108. package/src/contracts/miso_record_shop/witness.ts +11 -0
  109. package/src/contracts/recording_royalty_pool/recording_royalty_pool.ts +14 -16
  110. package/src/contracts/vault/vault.ts +226 -21
  111. package/src/contracts.ts +5 -4
  112. package/src/deployments.ts +134 -38
  113. package/src/index.ts +2 -0
  114. package/src/mix.ts +910 -0
  115. package/src/pressing.ts +428 -423
  116. package/src/publication.ts +69 -36
  117. package/src/read/catalog.ts +49 -34
  118. package/src/read/config.ts +7 -7
  119. package/src/read/index.ts +9 -1
  120. package/src/read/internal/scalars.ts +4 -2
  121. package/src/read/internal/walrus.ts +2 -1
  122. package/src/read/receipts.ts +181 -66
  123. package/src/read/types.ts +41 -24
  124. package/src/read/wallet.ts +70 -57
  125. package/src/vault.ts +228 -41
  126. package/dist/contracts/miso_pressing/certificate.d.ts +0 -89
  127. package/dist/contracts/miso_pressing/certificate.d.ts.map +0 -1
  128. package/dist/contracts/miso_pressing/certificate.js +0 -108
  129. package/dist/contracts/miso_pressing/certificate.js.map +0 -1
  130. package/dist/contracts/miso_pressing/deps/std/type_name.d.ts.map +0 -1
  131. package/dist/contracts/miso_pressing/deps/std/type_name.js.map +0 -1
  132. package/dist/contracts/miso_pressing/listing.d.ts +0 -434
  133. package/dist/contracts/miso_pressing/listing.d.ts.map +0 -1
  134. package/dist/contracts/miso_pressing/listing.js +0 -401
  135. package/dist/contracts/miso_pressing/listing.js.map +0 -1
  136. package/dist/contracts/miso_pressing/pressing.d.ts +0 -334
  137. package/dist/contracts/miso_pressing/pressing.d.ts.map +0 -1
  138. package/dist/contracts/miso_pressing/pressing.js +0 -298
  139. package/dist/contracts/miso_pressing/pressing.js.map +0 -1
  140. package/src/contracts/miso_pressing/certificate.ts +0 -164
  141. package/src/contracts/miso_pressing/listing.ts +0 -592
  142. package/src/contracts/miso_pressing/pressing.ts +0 -399
  143. /package/dist/contracts/{miso_pressing → miso_record}/deps/std/type_name.d.ts +0 -0
  144. /package/dist/contracts/{miso_pressing → miso_record}/deps/std/type_name.js +0 -0
  145. /package/src/contracts/{miso_pressing → miso_record}/deps/std/type_name.ts +0 -0
@@ -59,6 +59,7 @@ import {
59
59
  import { setReleaseCover, setReleaseTrackCover } from "./cover.ts";
60
60
  import {
61
61
  custodyNewAdminCap,
62
+ deriveVaultAdminCapId,
62
63
  directAdminCap,
63
64
  disposeNewAdminCap,
64
65
  initializeCompositionRoyaltyPool,
@@ -79,11 +80,11 @@ import {
79
80
  derivePressingAdminCapId,
80
81
  derivePressingId,
81
82
  type ListingPrice,
82
- type PressingRunState,
83
83
  } from "./pressing.ts";
84
+ import { requireRecordSalesDeployment } from "./deployments.ts";
84
85
  import { allCreatedByType, createdByExactType, type PlatformExecResult } from "./execute.ts";
85
- import * as pressingContract from "./contracts/miso_pressing/pressing.ts";
86
- import * as listingContract from "./contracts/miso_pressing/listing.ts";
86
+ import * as pressingContract from "./contracts/miso_record/pressing.ts";
87
+ import * as listingContract from "./contracts/miso_record_shop/listing.ts";
87
88
 
88
89
  const { composition, recording, release, track, party } = protocolContracts;
89
90
 
@@ -212,7 +213,10 @@ export interface PublicationRelease {
212
213
  }
213
214
 
214
215
  export interface PublicationPressing {
215
- readonly state?: PressingRunState;
216
+ /** Positive edition number encoded as Move u16. */
217
+ readonly edition: number;
218
+ /** Immutable positive u32 ceiling, or null/omitted for an uncapped edition. */
219
+ readonly maxSupply?: number | null;
216
220
  readonly listings: {
217
221
  readonly currencyType: string;
218
222
  readonly price: ListingPrice;
@@ -264,7 +268,7 @@ function releaseCapType(p: AtomicPublicationParams): string {
264
268
  }
265
269
 
266
270
  function pressingCapType(p: AtomicPublicationParams): string {
267
- return `${p.deployment.packages.pressing}::pressing::PressingAdminCap`;
271
+ return `${requireRecordSalesDeployment(p.deployment.recordSales).recordPackageId}::pressing::PressingAdminCap`;
268
272
  }
269
273
 
270
274
  function custody(
@@ -277,6 +281,7 @@ function custody(
277
281
  return {
278
282
  kind: "vault",
279
283
  owner: selected.owner,
284
+ vaultRegistry: p.deployment.objects.vaultRegistry,
280
285
  capType,
281
286
  vaultPackageId: p.deployment.packages.vault,
282
287
  configure,
@@ -310,24 +315,27 @@ function walrusBlob(tx: Transaction, p: AtomicPublicationParams, blobId: bigint
310
315
  });
311
316
  }
312
317
 
313
- function pressingState(tx: Transaction, p: AtomicPublicationParams, state: PressingRunState) {
314
- const pkg = p.deployment.packages.pressing;
315
- if (state.kind === "scheduled") {
316
- return tx.add(pressingContract.newScheduledState({
317
- package: pkg,
318
- arguments: [BigInt(state.startTimestampMs)],
319
- }));
320
- }
321
- if (state.kind === "paused") return tx.add(pressingContract.newPausedState({ package: pkg }));
322
- return tx.add(pressingContract.newActiveState({ package: pkg }));
323
- }
324
-
325
318
  function listingPrice(tx: Transaction, p: AtomicPublicationParams, price: ListingPrice) {
326
- const pkg = p.deployment.packages.pressing;
319
+ const pkg = requireRecordSalesDeployment(p.deployment.recordSales).recordShopPackageId;
327
320
  const args = { package: pkg, arguments: [BigInt(price.amount)] as [bigint] };
328
321
  return tx.add(price.kind === "fixed"
329
- ? listingContract.newFixedPrice(args)
330
- : listingContract.newFloorPrice(args));
322
+ ? listingContract.fixed(args)
323
+ : listingContract.floor(args));
324
+ }
325
+
326
+ function publicationEdition(value: number): number {
327
+ if (!Number.isInteger(value) || value <= 0 || value > 0xffff) {
328
+ throw new RangeError("pressing.edition must be an integer from 1 to 65535");
329
+ }
330
+ return value;
331
+ }
332
+
333
+ function publicationMaxSupply(value: number | null | undefined): number | null {
334
+ if (value == null) return null;
335
+ if (!Number.isInteger(value) || value <= 0 || value > 0xffff_ffff) {
336
+ throw new RangeError("pressing.maxSupply must be a positive u32 or null");
337
+ }
338
+ return value;
331
339
  }
332
340
 
333
341
  interface PublicationShareAllocation {
@@ -410,6 +418,7 @@ function publishComposition(
410
418
  }
411
419
  custodyNewAdminCap(tx, {
412
420
  adminCap: parts.adminCap,
421
+ vaultRegistry: p.deployment.objects.vaultRegistry,
413
422
  capType: compositionCapType(p, node.shareType),
414
423
  vaultPackageId: p.deployment.packages.vault,
415
424
  owner: node.custody.owner,
@@ -479,6 +488,7 @@ function publishRecording(
479
488
  }
480
489
  custodyNewAdminCap(tx, {
481
490
  adminCap: parts.adminCap,
491
+ vaultRegistry: p.deployment.objects.vaultRegistry,
482
492
  capType: recordingCapType(p, node.shareType),
483
493
  vaultPackageId: p.deployment.packages.vault,
484
494
  owner: node.custody.owner,
@@ -542,6 +552,7 @@ function publishReleaseObject(
542
552
  }
543
553
  custodyNewAdminCap(tx, {
544
554
  adminCap,
555
+ vaultRegistry: p.deployment.objects.vaultRegistry,
545
556
  capType: releaseCapType(p),
546
557
  vaultPackageId: p.deployment.packages.vault,
547
558
  owner: node.custody.owner,
@@ -803,31 +814,51 @@ export function publishAtomicCatalog(p: AtomicPublicationParams): TxThunk {
803
814
 
804
815
  let pressingParts: { pressing: TransactionObjectArgument; adminCap: TransactionObjectArgument } | undefined;
805
816
  if (p.pressing && releaseObject && releaseAdminCap) {
817
+ const sales = requireRecordSalesDeployment(p.deployment.recordSales);
806
818
  const created = tx.add(pressingContract._new({
807
- package: p.deployment.packages.pressing,
819
+ package: sales.recordPackageId,
808
820
  arguments: [
809
821
  releaseObject,
810
822
  releaseAdminCap,
811
- pressingState(tx, p, p.pressing.state ?? { kind: "active" }),
823
+ publicationEdition(p.pressing.edition),
824
+ publicationMaxSupply(p.pressing.maxSupply),
812
825
  ],
813
826
  }));
814
827
  pressingParts = {
815
828
  pressing: requiredCommandResult(created, 0, "pressing::new"),
816
829
  adminCap: requiredCommandResult(created, 1, "pressing::new"),
817
830
  };
831
+ tx.add(pressingContract.authorizeDistributor({
832
+ package: sales.recordPackageId,
833
+ typeArguments: [`${sales.recordShopPackageId}::witness::Witness`],
834
+ arguments: [pressingParts.pressing, pressingParts.adminCap],
835
+ }));
818
836
  for (const listing of p.pressing.listings) {
819
- tx.add(listingContract._new({
820
- package: p.deployment.packages.pressing,
837
+ const createdListing = tx.add(listingContract._new({
838
+ package: sales.recordShopPackageId,
821
839
  typeArguments: [listing.currencyType],
822
840
  arguments: [
823
841
  pressingParts.pressing,
824
842
  pressingParts.adminCap,
825
843
  listingPrice(tx, p, listing.price),
826
- tx.add(listing.enabled === false
827
- ? listingContract.newDisabledState({ package: p.deployment.packages.pressing })
828
- : listingContract.newEnabledState({ package: p.deployment.packages.pressing })),
829
844
  ],
830
845
  }));
846
+ if (listing.enabled === false) {
847
+ tx.add(listingContract.setState({
848
+ package: sales.recordShopPackageId,
849
+ typeArguments: [listing.currencyType],
850
+ arguments: [
851
+ createdListing,
852
+ pressingParts.adminCap,
853
+ tx.add(listingContract.disabled({ package: sales.recordShopPackageId })),
854
+ ],
855
+ }));
856
+ }
857
+ tx.add(listingContract.share({
858
+ package: sales.recordShopPackageId,
859
+ typeArguments: [listing.currencyType],
860
+ arguments: [createdListing],
861
+ }));
831
862
  }
832
863
  }
833
864
 
@@ -858,8 +889,9 @@ export function publishAtomicCatalog(p: AtomicPublicationParams): TxThunk {
858
889
  }
859
890
 
860
891
  if (p.pressing && pressingParts) {
892
+ const sales = requireRecordSalesDeployment(p.deployment.recordSales);
861
893
  tx.add(pressingContract.share({
862
- package: p.deployment.packages.pressing,
894
+ package: sales.recordPackageId,
863
895
  arguments: [pressingParts.pressing],
864
896
  }));
865
897
  disposeNewAdminCap(tx, pressingParts.adminCap, custody(
@@ -928,14 +960,14 @@ function findByShareType(
928
960
  return matches[0]!.objectId;
929
961
  }
930
962
 
931
- function vaultsByWrappedCap(result: PlatformExecResult) {
963
+ function vaultsByCap(result: PlatformExecResult, vaultPackageId: string) {
932
964
  const out = new Map<string, { vaultId: string; vaultAdminCapId: string }>();
933
965
  for (const event of result.events) {
934
966
  if (!event.eventType.includes("::vault::VaultCreatedEvent<")) continue;
935
967
  const parsed = parseVaultCreatedEvent(event.bcs);
936
- out.set(parsed.wrapped_cap_id, {
968
+ out.set(parsed.cap_id, {
937
969
  vaultId: parsed.vault_id,
938
- vaultAdminCapId: parsed.vault_admin_cap_id,
970
+ vaultAdminCapId: deriveVaultAdminCapId(parsed.vault_id, vaultPackageId),
939
971
  });
940
972
  }
941
973
  return out;
@@ -943,7 +975,7 @@ function vaultsByWrappedCap(result: PlatformExecResult) {
943
975
 
944
976
  function authorityOut(
945
977
  result: PlatformExecResult,
946
- vaults: ReturnType<typeof vaultsByWrappedCap>,
978
+ vaults: ReturnType<typeof vaultsByCap>,
947
979
  selected: PublicationCustody,
948
980
  adminCapId: string,
949
981
  capType: string,
@@ -951,7 +983,7 @@ function authorityOut(
951
983
  ): PublicationAuthorityOut {
952
984
  if (selected.kind === "direct") return { kind: "direct", adminCapId };
953
985
  const found = vaults.get(adminCapId);
954
- if (!found) throw new Error(`No VaultCreatedEvent wrapped admin cap ${adminCapId} in ${result.digest}`);
986
+ if (!found) throw new Error(`No VaultCreatedEvent for admin cap ${adminCapId} in ${result.digest}`);
955
987
  return { kind: "vault", ...found, capType, vaultPackageId };
956
988
  }
957
989
 
@@ -960,7 +992,7 @@ export function parseAtomicPublicationResult(
960
992
  p: AtomicPublicationParams,
961
993
  result: PlatformExecResult,
962
994
  ): AtomicPublicationResult {
963
- const vaults = vaultsByWrappedCap(result);
995
+ const vaults = vaultsByCap(result, p.deployment.packages.vault);
964
996
  const createdCompositions = allCreatedByType(result, "::composition::Composition<");
965
997
  const createdRecordings = allCreatedByType(result, "::recording::Recording<");
966
998
  const createdPools = allCreatedByType(result, "::pool::RoyaltyPool<");
@@ -1032,8 +1064,9 @@ export function parseAtomicPublicationResult(
1032
1064
 
1033
1065
  let pressingOut: AtomicPublicationResult["pressing"];
1034
1066
  if (p.pressing && releaseOut) {
1035
- const id = derivePressingId(releaseOut.id, p.deployment.packages.pressing);
1036
- const adminCapId = derivePressingAdminCapId(id, p.deployment.packages.pressing);
1067
+ const sales = requireRecordSalesDeployment(p.deployment.recordSales);
1068
+ const id = derivePressingId(releaseOut.id, p.pressing.edition, sales.recordPackageId);
1069
+ const adminCapId = derivePressingAdminCapId(id, sales.recordPackageId);
1037
1070
  pressingOut = {
1038
1071
  id,
1039
1072
  adminCapId,
@@ -14,10 +14,12 @@ import {
14
14
  deriveListingId,
15
15
  getListing,
16
16
  getPressing,
17
+ getRecord,
17
18
  getSale,
18
19
  type ListingView as ContractListingView,
19
20
  type PressingView as ContractPressingView,
20
21
  } from "../pressing.ts";
22
+ import { requireRecordSalesDeployment } from "../deployments.ts";
21
23
  import {
22
24
  getReleaseCoversByIds,
23
25
  parseReleaseCoverContent,
@@ -36,12 +38,16 @@ import {
36
38
  releaseKindFieldId,
37
39
  } from "../release-extensions.ts";
38
40
  import { getRecordingMasterReferencesByIds } from "../recording-extensions.ts";
41
+ import {
42
+ getReleaseMixReferences,
43
+ walrusBlobIdFromU256,
44
+ } from "../mix.ts";
39
45
  import { getTrackCreditsByRecordingIds } from "../catalog.ts";
40
46
  import { getReleaseById, getReleasesByIds, isNotFound } from "@misonetwork/sdk";
41
47
  import type { Release } from "@misonetwork/sdk";
42
48
  import type { MisoClient } from "./client.ts";
43
49
  import { getRecordingTitles, parseReleaseObject } from "./works.ts";
44
- import { int, u64 } from "./internal/scalars.ts";
50
+ import { int } from "./internal/scalars.ts";
45
51
  import {
46
52
  quiltPatchId,
47
53
  u256ToB64Url,
@@ -122,29 +128,23 @@ function toPressingView(pressing: ContractPressingView): PressingView {
122
128
  return {
123
129
  id: pressing.id,
124
130
  releaseId: pressing.releaseId,
125
- state:
126
- pressing.state.kind === "scheduled"
127
- ? {
128
- kind: "scheduled",
129
- startTimestampMs: Number(pressing.state.startTimestampMs ?? 0n),
130
- }
131
- : pressing.state.kind === "paused"
132
- ? { kind: "paused" }
133
- : { kind: "active" },
134
- supply: u64(pressing.supply),
131
+ edition: pressing.edition,
132
+ supply: pressing.supply,
133
+ maxSupply: pressing.maxSupply,
134
+ distributors: [...pressing.distributors],
135
135
  };
136
136
  }
137
137
 
138
138
  function toListingView(listing: ContractListingView): ListingView {
139
139
  const price: Price = {
140
- kind: listing.price.kind,
141
- amount: u64(listing.price.amount),
140
+ kind: listing.pricing.kind,
141
+ amount: listing.pricing.amount,
142
142
  };
143
143
  return {
144
144
  id: listing.id,
145
145
  pressingId: listing.pressingId,
146
146
  releaseId: listing.releaseId,
147
- price,
147
+ pricing: price,
148
148
  currency: currencyInfo(listing.currencyType),
149
149
  state: listing.state,
150
150
  };
@@ -162,10 +162,11 @@ export async function getPressingView(
162
162
  client: MisoClient,
163
163
  pressingId: string,
164
164
  ): Promise<PressingView | null> {
165
+ const sales = requireRecordSalesDeployment(client.config.recordSales);
165
166
  const pressing = await getPressing(
166
167
  client.protocol,
167
168
  pressingId,
168
- client.config.protocol.pressing,
169
+ sales.recordPackageId,
169
170
  );
170
171
  return pressing ? toPressingView(pressing) : null;
171
172
  }
@@ -176,9 +177,9 @@ export async function getListingView(
176
177
  pressingId: string,
177
178
  currencyType: string,
178
179
  ): Promise<ListingView | null> {
179
- const packageId = client.config.protocol.pressing;
180
- const listingId = deriveListingId(pressingId, currencyType, packageId);
181
- const listing = await getListing(client.protocol, listingId, packageId);
180
+ const sales = requireRecordSalesDeployment(client.config.recordSales);
181
+ const listingId = deriveListingId(pressingId, currencyType, sales.recordShopPackageId);
182
+ const listing = await getListing(client.protocol, listingId, sales.recordShopPackageId);
182
183
  return listing ? toListingView(listing) : null;
183
184
  }
184
185
 
@@ -207,13 +208,15 @@ export function primaryArtistNames(credits: Credit[]): string[] {
207
208
  * Number the protocol's flat tracklist. Display grouping such as discs belongs
208
209
  * to metadata extensions and can be layered onto this projection later.
209
210
  */
210
- function toTracks(
211
+ export function toTracks(
211
212
  release: Release,
212
213
  titles: Record<string, string>,
213
214
  masterBlobIds: Partial<Record<string, string>>,
215
+ mixBlobIds: Partial<Record<number, string>> = {},
214
216
  ): TrackView[] {
215
217
  return release.tracks.map((track, index) => {
216
218
  const masterBlobId = masterBlobIds[track.recordingId];
219
+ const mixBlobId = mixBlobIds[index];
217
220
  return {
218
221
  no: `${index + 1}`,
219
222
  title: titles[track.recordingId] ?? "Untitled",
@@ -222,6 +225,7 @@ function toTracks(
222
225
  splitBps: int(track.splitBps.value),
223
226
  disc: 1,
224
227
  ...(masterBlobId ? { masterBlobId } : {}),
228
+ ...(mixBlobId ? { mixBlobId } : {}),
225
229
  };
226
230
  });
227
231
  }
@@ -369,7 +373,8 @@ export async function getReleaseDetail(
369
373
  );
370
374
 
371
375
  const recordingIds = release.tracks.map((track) => track.recordingId);
372
- const [titles, masterReferences, trackCredits] = await Promise.all([
376
+ const mixPackageId = client.config.protocol.releaseMixReference;
377
+ const [titles, masterReferences, mixReferences, trackCredits] = await Promise.all([
373
378
  getRecordingTitles(
374
379
  client.protocol,
375
380
  client.graphql,
@@ -381,6 +386,9 @@ export async function getReleaseDetail(
381
386
  recordingIds,
382
387
  client.config.protocol.recordingMasterReference,
383
388
  ).catch(() => ({})),
389
+ mixPackageId
390
+ ? getReleaseMixReferences(client.protocol, releaseId, mixPackageId).catch(() => null)
391
+ : Promise.resolve(null),
384
392
  options.include?.includes("trackCredits")
385
393
  ? getTrackCreditsForRecordingIds(client, recordingIds)
386
394
  : Promise.resolve(undefined),
@@ -389,6 +397,11 @@ export async function getReleaseDetail(
389
397
  for (const [recordingId, blobId] of Object.entries(masterReferences)) {
390
398
  if (blobId) masterBlobIds[recordingId] = u256ToB64Url(blobId);
391
399
  }
400
+ const mixBlobIds: Record<number, string> = {};
401
+ for (let index = 0; index < (mixReferences?.length ?? 0); index += 1) {
402
+ const reference = mixReferences?.[index];
403
+ if (reference) mixBlobIds[index] = walrusBlobIdFromU256(reference.blobId);
404
+ }
392
405
 
393
406
  const creditViews = credits ?? [];
394
407
  return {
@@ -403,7 +416,7 @@ export async function getReleaseDetail(
403
416
  credits: creditViews,
404
417
  primaryArtists: primaryArtistNames(creditViews),
405
418
  discCount: release.tracks.length > 0 ? 1 : 0,
406
- tracks: toTracks(release, titles, masterBlobIds),
419
+ tracks: toTracks(release, titles, masterBlobIds, mixBlobIds),
407
420
  ...(trackCredits !== undefined ? { trackCredits } : {}),
408
421
  };
409
422
  }
@@ -511,8 +524,9 @@ export async function getPressingPreview(
511
524
  title: release.title,
512
525
  subtitle: null,
513
526
  coverUrl: cover?.still.url ?? null,
514
- state: pressing.state,
527
+ edition: pressing.edition,
515
528
  supply: pressing.supply,
529
+ maxSupply: pressing.maxSupply,
516
530
  trackCount: release.tracks.length,
517
531
  };
518
532
  }
@@ -525,13 +539,17 @@ export async function getPressingPreview(
525
539
  export async function getSaleDetail(
526
540
  client: MisoClient,
527
541
  releaseId: string,
542
+ edition: number,
528
543
  currencyType: string,
529
544
  options: GetReleaseOptions = {},
530
545
  ): Promise<SaleDetail | null> {
546
+ const sales = requireRecordSalesDeployment(client.config.recordSales);
531
547
  const sale = await getSale(client.protocol, {
532
548
  releaseId,
549
+ edition,
533
550
  currencyType,
534
- misoPressingPackageId: client.config.protocol.pressing,
551
+ recordPackageId: sales.recordPackageId,
552
+ recordShopPackageId: sales.recordShopPackageId,
535
553
  });
536
554
  if (!sale.pressing || !sale.listing) return null;
537
555
  const release = await getReleaseDetail(client, sale.pressing.releaseId, options);
@@ -543,20 +561,20 @@ export async function getSaleDetail(
543
561
  /**
544
562
  * The records currently on sale.
545
563
  *
546
- * Configured by release + currency: Pressing and Listing ids are deterministic,
547
- * permanent derived addresses. There is no mutable Pressing pointer or edition
548
- * replacement in the current ABI.
564
+ * Configured by release + edition + currency: both addresses are deterministic.
549
565
  */
550
566
  export async function getDiscoverShelf(
551
567
  client: MisoClient,
552
568
  ): Promise<DiscoverItem[]> {
553
569
  const configuredSales = [...client.config.discoverSales];
570
+ const sales = requireRecordSalesDeployment(client.config.recordSales);
554
571
  const settled = await Promise.all(
555
572
  configuredSales.map(async (configured) => ({
556
573
  configured,
557
574
  result: await getSale(client.protocol, {
558
575
  ...configured,
559
- misoPressingPackageId: client.config.protocol.pressing,
576
+ recordPackageId: sales.recordPackageId,
577
+ recordShopPackageId: sales.recordShopPackageId,
560
578
  }),
561
579
  })),
562
580
  );
@@ -620,13 +638,10 @@ export async function getRecordAlbum(
620
638
  options: GetRecordAlbumOptions = {},
621
639
  ): Promise<RecordAlbum | null> {
622
640
  try {
623
- const { object } = await client.protocol.core.getObject({
624
- objectId: recordId,
625
- include: { json: true },
626
- });
627
- const json = (object?.json ?? {}) as Record<string, unknown>;
628
- const raw = json.release_id;
629
- const releaseId = typeof raw === "string" && raw ? raw : null;
641
+ const sales = requireRecordSalesDeployment(client.config.recordSales);
642
+ const record = await getRecord(client.protocol, recordId, sales.recordPackageId);
643
+ if (!record) return null;
644
+ const releaseId = record.releaseId;
630
645
  const includeRelease =
631
646
  options.include?.some(
632
647
  (part) => part === "release" || part === "trackCredits",
@@ -12,7 +12,7 @@
12
12
  // deployment is bundled for it.
13
13
 
14
14
  import type { MisoDeployment } from "@misonetwork/sdk/deployments";
15
- import { getMisoPlatformDeployment } from "../deployments.ts";
15
+ import { getMisoPlatformDeployment, type RecordSalesDeployment } from "../deployments.ts";
16
16
 
17
17
  export type Network = "testnet" | "mainnet";
18
18
 
@@ -25,10 +25,6 @@ export function networkFrom(value: string | undefined): Network {
25
25
 
26
26
  /** Package ids for the miso protocol core and the extensions the read layer touches. */
27
27
  export interface ProtocolIds {
28
- /** `miso_pressing` — permanent Pressing runs and per-currency Listings. */
29
- pressing: string;
30
- /** `miso_record` package — the exact owner/type namespace for `record::Record`. */
31
- record: string;
32
28
  /** `vault` — shared custody for protocol admin capabilities. */
33
29
  vault: string;
34
30
  /** `release_cover_art` — the release cover extension. */
@@ -37,6 +33,8 @@ export interface ProtocolIds {
37
33
  releaseKind: string;
38
34
  /** `recording_master_reference` — optional Walrus master pointers. */
39
35
  recordingMasterReference: string;
36
+ /** `release_mix_reference` — optional per-track delivery descriptor pointers. */
37
+ releaseMixReference?: string;
40
38
  /** `composition_credits` / `recording_credits` / `release_credits` extensions. */
41
39
  compositionCredits: string;
42
40
  recordingCredits: string;
@@ -57,6 +55,8 @@ export interface MisoConfig {
57
55
  /** Complete package set used by the integrated `client.miso` SDK. */
58
56
  deployment: MisoDeployment;
59
57
  protocol: ProtocolIds;
58
+ /** Final Record/Record Shop deployment, or an explicit unavailable legacy state. */
59
+ recordSales: RecordSalesDeployment;
60
60
  money: MoneyIds;
61
61
  /** Sui gRPC-web endpoint the data plane reads through. */
62
62
  grpcUrl: string;
@@ -81,6 +81,7 @@ export interface MisoConfig {
81
81
  /** One release/currency pair to resolve by Pressing and Listing derived address. */
82
82
  export interface DiscoverSale {
83
83
  releaseId: string;
84
+ edition: number;
84
85
  currencyType: string;
85
86
  }
86
87
 
@@ -95,9 +96,8 @@ export function misoConfig(network: Network, overrides: MisoConfigOverrides = {}
95
96
  const config: MisoConfig = {
96
97
  network,
97
98
  deployment: platform.protocol,
99
+ recordSales: platform.recordSales,
98
100
  protocol: {
99
- pressing: platform.packages.pressing,
100
- record: platform.packages.record,
101
101
  vault: platform.packages.vault,
102
102
  releaseCoverArt: platform.packages.releaseCoverArt,
103
103
  releaseKind: platform.packages.releaseKind,
package/src/read/index.ts CHANGED
@@ -72,6 +72,14 @@ export {
72
72
  ownsRecord,
73
73
  } from "./wallet.ts";
74
74
 
75
- export { breakdown, getPurchaseReceipt } from "./receipts.ts";
75
+ export {
76
+ breakdown,
77
+ findRecordSale,
78
+ findRecordSales,
79
+ getPurchaseReceipt,
80
+ getPurchaseReceipts,
81
+ isRecordSoldEventType,
82
+ recordSoldCurrencyType,
83
+ } from "./receipts.ts";
76
84
 
77
85
  export type * from "./types.ts";
@@ -20,8 +20,10 @@ export function u64(v: NumericLike): string {
20
20
  /** Base-unit scalar → decimal string, or `null` when absent/unparseable. */
21
21
  export function u64OrNull(v: NumericLike): string | null {
22
22
  if (v == null) return null;
23
- if (typeof v === "bigint") return v.toString();
24
- if (typeof v === "number") return Number.isFinite(v) ? BigInt(Math.trunc(v)).toString() : null;
23
+ if (typeof v === "bigint") return v >= 0n ? v.toString() : null;
24
+ if (typeof v === "number") {
25
+ return Number.isSafeInteger(v) && v >= 0 ? BigInt(v).toString() : null;
26
+ }
25
27
  const s = v.trim();
26
28
  return /^\d+$/.test(s) ? BigInt(s).toString() : null;
27
29
  }
@@ -3,6 +3,7 @@
3
3
 
4
4
  import { bcs } from "@mysten/sui/bcs";
5
5
  import { toBase64 } from "@mysten/sui/utils";
6
+ import { walrusBlobIdFromU256 } from "../../mix.ts";
6
7
 
7
8
  const u256 = bcs.u256();
8
9
 
@@ -11,7 +12,7 @@ function toBase64Url(bytes: Uint8Array): string {
11
12
  }
12
13
 
13
14
  export function u256ToB64Url(value: bigint | string): string {
14
- return toBase64Url(u256.serialize(BigInt(value)).toBytes());
15
+ return walrusBlobIdFromU256(value);
15
16
  }
16
17
 
17
18
  /** Build a blob URL with Walrus's non-strict default made explicit. */