@misofm/sdk 0.6.0 → 0.8.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 (84) hide show
  1. package/README.md +37 -29
  2. package/dist/client.d.ts +46 -6
  3. package/dist/client.d.ts.map +1 -1
  4. package/dist/client.js +97 -6
  5. package/dist/client.js.map +1 -1
  6. package/dist/contracts/release_registry/release_registry.d.ts +114 -0
  7. package/dist/contracts/release_registry/release_registry.d.ts.map +1 -0
  8. package/dist/contracts/release_registry/release_registry.js +119 -0
  9. package/dist/contracts/release_registry/release_registry.js.map +1 -0
  10. package/dist/contracts/royalty_pool/pool.d.ts +28 -2
  11. package/dist/contracts/royalty_pool/pool.d.ts.map +1 -1
  12. package/dist/contracts/royalty_pool/pool.js +28 -2
  13. package/dist/contracts/royalty_pool/pool.js.map +1 -1
  14. package/dist/contracts/utils/index.d.ts +44 -0
  15. package/dist/contracts/utils/index.d.ts.map +1 -1
  16. package/dist/contracts/utils/index.js +104 -2
  17. package/dist/contracts/utils/index.js.map +1 -1
  18. package/dist/contracts.d.ts +1 -0
  19. package/dist/contracts.d.ts.map +1 -1
  20. package/dist/contracts.js +4 -1
  21. package/dist/contracts.js.map +1 -1
  22. package/dist/cover.d.ts +3 -6
  23. package/dist/cover.d.ts.map +1 -1
  24. package/dist/cover.js +7 -16
  25. package/dist/cover.js.map +1 -1
  26. package/dist/credits.d.ts.map +1 -1
  27. package/dist/credits.js +17 -43
  28. package/dist/credits.js.map +1 -1
  29. package/dist/deployments.d.ts +95 -0
  30. package/dist/deployments.d.ts.map +1 -0
  31. package/dist/deployments.js +64 -0
  32. package/dist/deployments.js.map +1 -0
  33. package/dist/index.d.ts +3 -2
  34. package/dist/index.d.ts.map +1 -1
  35. package/dist/index.js +5 -2
  36. package/dist/index.js.map +1 -1
  37. package/dist/read/catalog.d.ts +2 -12
  38. package/dist/read/catalog.d.ts.map +1 -1
  39. package/dist/read/catalog.js +9 -24
  40. package/dist/read/catalog.js.map +1 -1
  41. package/dist/read/config.d.ts +7 -9
  42. package/dist/read/config.d.ts.map +1 -1
  43. package/dist/read/config.js +24 -38
  44. package/dist/read/config.js.map +1 -1
  45. package/dist/read/index.d.ts +1 -1
  46. package/dist/read/index.d.ts.map +1 -1
  47. package/dist/read/index.js +1 -1
  48. package/dist/read/index.js.map +1 -1
  49. package/dist/read/types.d.ts +1 -1
  50. package/dist/read/types.d.ts.map +1 -1
  51. package/dist/read/wallet.d.ts +3 -7
  52. package/dist/read/wallet.d.ts.map +1 -1
  53. package/dist/read/wallet.js +11 -38
  54. package/dist/read/wallet.js.map +1 -1
  55. package/dist/read/works.d.ts +2 -5
  56. package/dist/read/works.d.ts.map +1 -1
  57. package/dist/read/works.js +7 -37
  58. package/dist/read/works.js.map +1 -1
  59. package/dist/release-graph.d.ts +6 -19
  60. package/dist/release-graph.d.ts.map +1 -1
  61. package/dist/release-graph.js +29 -43
  62. package/dist/release-graph.js.map +1 -1
  63. package/dist/transactions.d.ts +12 -28
  64. package/dist/transactions.d.ts.map +1 -1
  65. package/dist/transactions.js +23 -28
  66. package/dist/transactions.js.map +1 -1
  67. package/package.json +8 -4
  68. package/src/client.ts +152 -10
  69. package/src/contracts/release_registry/release_registry.ts +160 -0
  70. package/src/contracts/royalty_pool/pool.ts +28 -2
  71. package/src/contracts/utils/index.ts +156 -4
  72. package/src/contracts.ts +5 -1
  73. package/src/cover.ts +8 -19
  74. package/src/credits.ts +23 -63
  75. package/src/deployments.ts +148 -0
  76. package/src/index.ts +6 -3
  77. package/src/read/catalog.ts +9 -29
  78. package/src/read/config.ts +29 -46
  79. package/src/read/index.ts +0 -1
  80. package/src/read/types.ts +1 -1
  81. package/src/read/wallet.ts +11 -37
  82. package/src/read/works.ts +5 -42
  83. package/src/release-graph.ts +40 -75
  84. package/src/transactions.ts +33 -62
package/src/cover.ts CHANGED
@@ -145,7 +145,7 @@ export async function getReleaseCover(
145
145
  await getReleaseCoversByIds(
146
146
  client,
147
147
  [releaseId],
148
- [releaseCoverArtPackageId],
148
+ releaseCoverArtPackageId,
149
149
  )
150
150
  )[releaseId] ?? null
151
151
  );
@@ -166,7 +166,7 @@ export function parseReleaseCoverContent(
166
166
  };
167
167
  }
168
168
 
169
- /** Deterministic dynamic-field id for one release-cover package generation. */
169
+ /** Deterministic dynamic-field id for the configured release-cover package. */
170
170
  export function releaseCoverFieldId(
171
171
  releaseId: string,
172
172
  releaseCoverArtPackageId: string,
@@ -179,24 +179,18 @@ export function releaseCoverFieldId(
179
179
  }
180
180
 
181
181
  /**
182
- * Read covers for many releases and package generations in one Core request.
183
- *
184
- * Package IDs are ordered newest to oldest. If both fields exist, the newest
185
- * wins; legacy fallbacks add bytes to the same bulk request, not serial probes.
182
+ * Read covers for many releases from the configured package in one Core request.
186
183
  */
187
184
  export async function getReleaseCoversByIds(
188
185
  client: ClientWithCoreApi,
189
186
  releaseIdsInput: readonly string[],
190
- releaseCoverArtPackageIds: readonly string[],
187
+ releaseCoverArtPackageId: string,
191
188
  ): Promise<Partial<Record<string, ReleaseCoverView>>> {
192
189
  const releaseIds = [...new Set(releaseIdsInput)];
193
- const targets = releaseIds.flatMap((releaseId) =>
194
- releaseCoverArtPackageIds.map((packageId, priority) => ({
195
- releaseId,
196
- priority,
197
- fieldId: releaseCoverFieldId(releaseId, packageId),
198
- })),
199
- );
190
+ const targets = releaseIds.map((releaseId) => ({
191
+ releaseId,
192
+ fieldId: releaseCoverFieldId(releaseId, releaseCoverArtPackageId),
193
+ }));
200
194
  if (targets.length === 0) return {};
201
195
 
202
196
  const { objects } = await client.core.getObjects({
@@ -204,17 +198,12 @@ export async function getReleaseCoversByIds(
204
198
  include: { content: true },
205
199
  });
206
200
  const out: Partial<Record<string, ReleaseCoverView>> = {};
207
- const priorities = new Map<string, number>();
208
201
  objects.forEach((object, index) => {
209
202
  const target = targets[index];
210
203
  if (!target || object instanceof Error || !object.content) return;
211
- const currentPriority = priorities.get(target.releaseId);
212
- if (currentPriority !== undefined && currentPriority <= target.priority)
213
- return;
214
204
  const cover = parseReleaseCoverContent(object.content);
215
205
  if (cover) {
216
206
  out[target.releaseId] = cover;
217
- priorities.set(target.releaseId, target.priority);
218
207
  }
219
208
  });
220
209
  return out;
package/src/credits.ts CHANGED
@@ -605,9 +605,7 @@ const RELEASE_CREDITS_KEY_BYTES = releaseCredits.ExtensionKey.serialize([
605
605
 
606
606
  type CreditFieldKind =
607
607
  | "composition"
608
- | "compositionLegacy"
609
608
  | "recording"
610
- | "recordingLegacy"
611
609
  | "release";
612
610
 
613
611
  interface CreditFieldTarget {
@@ -616,13 +614,7 @@ interface CreditFieldTarget {
616
614
  fieldId: string;
617
615
  }
618
616
 
619
- /**
620
- * Fetch many derived credit fields through one Core bulk request.
621
- *
622
- * Composition and recording extensions have one legacy key spelling. Both IDs
623
- * ride in the same request, so fallback compatibility does not add a sequential
624
- * round trip when the current key is absent.
625
- */
617
+ /** Fetch many derived credit fields through one Core bulk request. */
626
618
  async function fetchCreditFields(
627
619
  client: ClientWithCoreApi,
628
620
  targets: readonly CreditFieldTarget[],
@@ -645,52 +637,30 @@ function compositionCreditTargets(
645
637
  compositionIds: readonly string[],
646
638
  packageId: string,
647
639
  ): CreditFieldTarget[] {
648
- return compositionIds.flatMap((workId) => [
649
- {
650
- workId,
651
- kind: "composition" as const,
652
- fieldId: deriveDynamicFieldID(
653
- workId,
654
- `${packageId}::composition_credits::ExtensionKey`,
655
- COMPOSITION_CREDITS_KEY_BYTES,
656
- ),
657
- },
658
- {
640
+ return compositionIds.map((workId) => ({
641
+ workId,
642
+ kind: "composition" as const,
643
+ fieldId: deriveDynamicFieldID(
659
644
  workId,
660
- kind: "compositionLegacy" as const,
661
- fieldId: deriveDynamicFieldID(
662
- workId,
663
- `${packageId}::composition_credits::CompositionCreditsKey`,
664
- COMPOSITION_CREDITS_KEY_BYTES,
665
- ),
666
- },
667
- ]);
645
+ `${packageId}::composition_credits::ExtensionKey`,
646
+ COMPOSITION_CREDITS_KEY_BYTES,
647
+ ),
648
+ }));
668
649
  }
669
650
 
670
651
  function recordingCreditTargets(
671
652
  recordingIds: readonly string[],
672
653
  packageId: string,
673
654
  ): CreditFieldTarget[] {
674
- return recordingIds.flatMap((workId) => [
675
- {
676
- workId,
677
- kind: "recording" as const,
678
- fieldId: deriveDynamicFieldID(
679
- workId,
680
- `${packageId}::recording_credits::ExtensionKey`,
681
- RECORDING_CREDITS_KEY_BYTES,
682
- ),
683
- },
684
- {
655
+ return recordingIds.map((workId) => ({
656
+ workId,
657
+ kind: "recording" as const,
658
+ fieldId: deriveDynamicFieldID(
685
659
  workId,
686
- kind: "recordingLegacy" as const,
687
- fieldId: deriveDynamicFieldID(
688
- workId,
689
- `${packageId}::recording_credits::RecordingCreditsKey`,
690
- RECORDING_CREDITS_KEY_BYTES,
691
- ),
692
- },
693
- ]);
660
+ `${packageId}::recording_credits::ExtensionKey`,
661
+ RECORDING_CREDITS_KEY_BYTES,
662
+ ),
663
+ }));
694
664
  }
695
665
 
696
666
  function releaseCreditTargets(
@@ -825,15 +795,10 @@ export async function getCompositionCreditsByIds(
825
795
  );
826
796
  const contents = await fetchCreditFields(client, targets);
827
797
  const out: Partial<Record<string, CreditView[]>> = {};
828
- for (const compositionId of compositionIds) {
829
- const candidates = targets.filter(
830
- (target) => target.workId === compositionId,
831
- );
832
- const content = candidates
833
- .map((target) => contents.get(target.fieldId))
834
- .find((value): value is Uint8Array => value !== undefined);
798
+ for (const target of targets) {
799
+ const content = contents.get(target.fieldId);
835
800
  if (content) {
836
- out[compositionId] = creditViews(
801
+ out[target.workId] = creditViews(
837
802
  CompositionCreditsField.parse(content).value.credits,
838
803
  compositionRoleLabel,
839
804
  );
@@ -875,16 +840,11 @@ export async function getRecordingCreditsByIds(
875
840
  );
876
841
  const contents = await fetchCreditFields(client, targets);
877
842
  const out: Partial<Record<string, RecordingCreditsView>> = {};
878
- for (const recordingId of recordingIds) {
879
- const candidates = targets.filter(
880
- (target) => target.workId === recordingId,
881
- );
882
- const content = candidates
883
- .map((target) => contents.get(target.fieldId))
884
- .find((value): value is Uint8Array => value !== undefined);
843
+ for (const target of targets) {
844
+ const content = contents.get(target.fieldId);
885
845
  if (!content) continue;
886
846
  const value = RecordingCreditsField.parse(content).value;
887
- out[recordingId] = {
847
+ out[target.workId] = {
888
848
  credits: creditViews(value.credits, recordingRoleLabel),
889
849
  primaryArtistIds: value.primary_artist_ids.contents,
890
850
  featuredArtistIds: value.featured_artist_ids.contents,
@@ -0,0 +1,148 @@
1
+ // Copyright (c) Miso Labs, Inc.
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import {
5
+ MISO_PROTOCOL_DEPLOYMENTS,
6
+ type MisoNetwork,
7
+ type MisoProtocolDeployment,
8
+ } from "@misonetwork/sdk/deployments";
9
+
10
+ /** Complete on-chain identity used by the Miso platform SDK on one network. */
11
+ export interface MisoPlatformDeployment {
12
+ /** The protocol deployment this platform deployment was built against. */
13
+ readonly protocol: MisoProtocolDeployment;
14
+ readonly packages: {
15
+ readonly pressing: string;
16
+ readonly record: string;
17
+ readonly releaseRegistry: string;
18
+ readonly minato: string;
19
+ readonly drop: string;
20
+ readonly credit: string;
21
+ readonly compositionCredits: string;
22
+ readonly recordingCredits: string;
23
+ readonly releaseCredits: string;
24
+ readonly releaseCoverArt: string;
25
+ };
26
+ readonly objects: {
27
+ readonly recordSettings: string;
28
+ readonly releaseRegistry: string;
29
+ };
30
+ /** PartyOS packages used by the composed artist and wallet reads. */
31
+ readonly party: {
32
+ readonly partyPackageId: string;
33
+ readonly partyProfilePackageId: string;
34
+ readonly countryCodePackageId: string;
35
+ readonly languageCodePackageId: string;
36
+ readonly partyMediaPackageId: string;
37
+ readonly partyRolesPackageId: string;
38
+ readonly partyTagsPackageId: string;
39
+ readonly partyGenrePackageId: string;
40
+ readonly partyCtaPackageId: string;
41
+ readonly partyPlatformLinkPackageId: string;
42
+ readonly partySocialPackageId: string;
43
+ readonly partyMusicPackageId: string;
44
+ readonly partyProLinkPackageId: string;
45
+ readonly partyFeaturedDropPackageId: string;
46
+ readonly genrePackageId: string;
47
+ };
48
+ readonly legacy: {
49
+ readonly releaseCoverArtPackages: readonly string[];
50
+ };
51
+ }
52
+
53
+ /**
54
+ * Platform deployments bundled with this SDK release.
55
+ *
56
+ * Mainnet is intentionally absent until the complete platform stack is live.
57
+ * Mainnet is intentionally unavailable until this ABI is deployed there.
58
+ */
59
+ export const MISO_PLATFORM_DEPLOYMENTS = {
60
+ testnet: {
61
+ protocol: MISO_PROTOCOL_DEPLOYMENTS.testnet,
62
+ packages: {
63
+ pressing:
64
+ "0xd0913b584d87a3891a8013c58644e3896f438fd948e819a69db256b47314974e",
65
+ record:
66
+ "0x97e2772d81528c69e21b6681f6702f90deae2a6b079e19da1df53f9f4fdd3271",
67
+ releaseRegistry:
68
+ "0x683b2feb784a815171d2976418345bd41c046e159dcf7a16890c766f69fd7808",
69
+ minato:
70
+ "0x8466e9864c1d947888e73b0e349b035bc22805579eef18f132966f56c8efe1d2",
71
+ drop:
72
+ "0xfc2b51f068dee9d5482d39fa017164f6a8c3601cabb59084a518de5f609ef1c7",
73
+ credit:
74
+ "0x0121926470393cc93b89b5b6d5067737a8bc0c1c545fb96c4447569174116174",
75
+ compositionCredits:
76
+ "0xfa2f62db28f2eb42c8c1a6533097fb2095649efab05c0527be1874b9be6cdc73",
77
+ recordingCredits:
78
+ "0xc794252bd90efb4cc224107f9dd0a56d4f4f5623783628b6af286f6535dd4c1e",
79
+ releaseCredits:
80
+ "0x42e2dbf6098d18782911460ecf79b338af2f1b654ef7ba99c6e7344fd4bf3f94",
81
+ releaseCoverArt:
82
+ "0x831a612920343696de7e8f0603ff4c0b21c43ca3de478feb96d230e263cd11d4",
83
+ },
84
+ objects: {
85
+ recordSettings:
86
+ "0x6a005dad071562d421ad7a9d368289f5c9f0408ca495cd466a1f774d65a21fa7",
87
+ releaseRegistry:
88
+ "0x5941b8690916e762a7583363906496d64a6ea3e6cedb078c90e23e7c671544f2",
89
+ },
90
+ party: {
91
+ partyPackageId:
92
+ "0x09a812d46c3aa3978703c8e5a7409ba67b9ba2dfdb91154e48ebdd9d2415da0c",
93
+ partyProfilePackageId:
94
+ "0xce89d3f993dfebc0b697388598c3b01e9db7b73fa2e8df18ed22608cf7ac5aee",
95
+ countryCodePackageId:
96
+ "0x6c3a53f228ccd089825d0fb5ee1f0465a4b7a438bc1b1735b4e2f01df8d056e9",
97
+ languageCodePackageId:
98
+ "0xa18b786807cfc45488691f93aa647800b77cf9993e420d110afd7024c5b15948",
99
+ partyMediaPackageId:
100
+ "0x7db56ef37692f84c1cfb0e0b26bde35ac9f1bc0bcd91ac5d24b3f8b4d1821349",
101
+ partyRolesPackageId:
102
+ "0x41a442a2c39368af2181e73ea5b90e2e0b4f89de09050c121a6e7d79e7c84415",
103
+ partyTagsPackageId:
104
+ "0xa4c7f6b05bb9b612ea7640974c150ce31ad7927ea82d3f9f4673acac7deef0da",
105
+ partyGenrePackageId:
106
+ "0x6ce063438be6cf44ccf5f17bf8892c9e0cef4e2344442aeb44412beead74d3a8",
107
+ partyCtaPackageId:
108
+ "0x85a312210d9ddbae535e0f933032c8a56aa3f0fe1d6c3430d4fa538765008da3",
109
+ partyPlatformLinkPackageId:
110
+ "0x46d9f3e05d2065a926b010fe833baf61e5c250c233d512a260cbe746b02c56af",
111
+ partySocialPackageId:
112
+ "0x438e767ce8f5699f12be1704a12ff69c28045ca241f890ca8a978d55e09f6541",
113
+ partyMusicPackageId:
114
+ "0x89add347dfa779aa77e21b1853a37f2054dbecfce29799b61463d9900877b7b1",
115
+ partyProLinkPackageId:
116
+ "0xe5e8a0d02b43037abb7e6ddb4b742c6197aadf2dc19910957bba98307bef4103",
117
+ partyFeaturedDropPackageId:
118
+ "0x1a7b926686565a6cc82a9e0630839dc1f75c9bf4fafc0ba789a05af2c3c269f0",
119
+ genrePackageId:
120
+ "0xcbbce10e8b0781d458e88ce99d08e0c85f1e674c5b7ec975383d74f87a1d76b1",
121
+ },
122
+ legacy: {
123
+ releaseCoverArtPackages: [
124
+ "0x25c3c87ef4823d62d80dd8bda714ef4976df0f04453997646659a6cebadd655b",
125
+ "0x1ee2cae0da7595d7973c310c912434ef531589b468cc57839296810c1385f7f6",
126
+ "0x7d4a205a68f8e768a408c9f4c45a4d4076722c5edeba9068c0ac058f554e964e",
127
+ ],
128
+ },
129
+ },
130
+ } as const satisfies Partial<Record<MisoNetwork, MisoPlatformDeployment>>;
131
+
132
+ /** Resolve a bundled platform deployment, failing closed when it is unavailable. */
133
+ export function getMisoPlatformDeployment(
134
+ network: string,
135
+ ): MisoPlatformDeployment {
136
+ const deployment = (
137
+ MISO_PLATFORM_DEPLOYMENTS as Partial<
138
+ Record<string, MisoPlatformDeployment>
139
+ >
140
+ )[network];
141
+ if (!deployment) {
142
+ throw new Error(
143
+ `@misofm/sdk: no bundled Miso platform deployment for network "${network}". ` +
144
+ "Pass an explicit deployment to miso() for custom networks.",
145
+ );
146
+ }
147
+ return deployment;
148
+ }
package/src/index.ts CHANGED
@@ -14,7 +14,9 @@
14
14
  //
15
15
  // A release is protocol. Pressing a record off it and selling that record is
16
16
  // platform. Keeping the split at the package boundary is what stops the protocol
17
- // from quietly growing a storefront.
17
+ // from quietly growing a storefront. Core's `release::new` is the sole practical
18
+ // exception: it needs `&mut UID`, which cannot cross a PTB command boundary, so
19
+ // the platform's `release_registry` extension owns the PTB-callable minting path.
18
20
  //
19
21
  // Extensions live on this side of the line for the same reason. An extension is
20
22
  // not part of what a Composition or Recording IS — it is a choice Miso makes
@@ -25,8 +27,9 @@
25
27
 
26
28
  // The recommended entry point is the client extension (see ./client.ts); the bare
27
29
  // builders and readers stay exported for callers that hold ids themselves.
28
- export { misoPlatform, MisoPlatformClient } from "./client.ts";
29
- export type { MisoPlatformConfig } from "./client.ts";
30
+ export { miso, misoPlatform, MisoClient, MisoPlatformClient } from "./client.ts";
31
+ export type { MisoOptions, MisoPlatformConfig } from "./client.ts";
32
+ export * from "./deployments.ts";
30
33
  export * from "./pressing.ts";
31
34
  export * from "./transactions.ts";
32
35
  export * from "./execute.ts";
@@ -161,24 +161,16 @@ function toTracks(
161
161
 
162
162
  // ── Cover ────────────────────────────────────────────────────────────────────
163
163
 
164
- /**
165
- * A release's cover, trying the current `release_cover_art` package and then each
166
- * legacy one in turn.
167
- *
168
- * Covers set before the cover_art package split live under a different
169
- * `CoverArtKey` TYPE (different package address), so a current-package read
170
- * simply misses them rather than failing. Ported verbatim from miso-app's
171
- * `lib/pressing.ts:readReleaseCover`.
172
- */
164
+ /** A release's cover from the configured `release_cover_art` package. */
173
165
  export async function readReleaseCover(
174
166
  client: MisoClient,
175
167
  releaseId: string,
176
168
  ): Promise<Cover | null> {
177
- const { releaseCoverArt, legacyReleaseCoverArt } = client.config.protocol;
169
+ const { releaseCoverArt } = client.config.protocol;
178
170
  const covers = await getReleaseCoversByIds(
179
171
  client.protocol,
180
172
  [releaseId],
181
- [releaseCoverArt, ...legacyReleaseCoverArt],
173
+ releaseCoverArt,
182
174
  ).catch(() => ({}) as Partial<Record<string, ReleaseCoverView>>);
183
175
  return toCover(client.config.walrusAggregatorUrl, covers[releaseId] ?? null);
184
176
  }
@@ -203,15 +195,9 @@ export async function getReleaseResources(
203
195
  ): Promise<ReleaseResources> {
204
196
  const wantsCover = include.includes("cover");
205
197
  const wantsCredits = include.includes("credits");
206
- const coverPackages = wantsCover
207
- ? [
208
- client.config.protocol.releaseCoverArt,
209
- ...client.config.protocol.legacyReleaseCoverArt,
210
- ]
198
+ const coverFieldIds = wantsCover
199
+ ? [releaseCoverFieldId(releaseId, client.config.protocol.releaseCoverArt)]
211
200
  : [];
212
- const coverFieldIds = coverPackages.map((packageId) =>
213
- releaseCoverFieldId(releaseId, packageId),
214
- );
215
201
  const creditsFieldId = wantsCredits
216
202
  ? releaseCreditsFieldId(releaseId, client.config.protocol.releaseCredits)
217
203
  : null;
@@ -222,7 +208,7 @@ export async function getReleaseResources(
222
208
  ];
223
209
  const { objects } = await client.protocol.core.getObjects({
224
210
  objectIds,
225
- include: { content: true, json: true },
211
+ include: { content: true },
226
212
  });
227
213
  const releaseObject = objects[0];
228
214
  if (!releaseObject) throw new Error(`Release not found: ${releaseId}`);
@@ -232,7 +218,6 @@ export async function getReleaseResources(
232
218
  const release = parseReleaseObject(
233
219
  releaseObject.objectId,
234
220
  releaseObject.content,
235
- releaseObject.json,
236
221
  );
237
222
 
238
223
  let cover: Cover | null | undefined;
@@ -440,10 +425,7 @@ export async function getDiscoverShelf(
440
425
 
441
426
  const [releases, coverViews, credits] = await Promise.all([
442
427
  getReleasesByIds(client.protocol, releaseIds),
443
- getReleaseCoversByIds(client.protocol, releaseIds, [
444
- client.config.protocol.releaseCoverArt,
445
- ...client.config.protocol.legacyReleaseCoverArt,
446
- ]).catch(() => ({}) as Partial<Record<string, ReleaseCoverView>>),
428
+ getReleaseCoversByIds(client.protocol, releaseIds, client.config.protocol.releaseCoverArt).catch(() => ({}) as Partial<Record<string, ReleaseCoverView>>),
447
429
  getReleaseCreditsByIds(
448
430
  client.protocol,
449
431
  releaseIds,
@@ -476,9 +458,7 @@ export async function getDiscoverShelf(
476
458
  // ── Record → release ─────────────────────────────────────────────────────────
477
459
 
478
460
  /**
479
- * A record's parent release. Both live `Record` struct layouts expose it — card
480
- * checkout's `{ release_id, number }` and the SDK view's
481
- * `{ release_id, edition, variant }` — so we probe both spellings.
461
+ * A record's parent release. Fresh `Record` objects expose `release_id`.
482
462
  *
483
463
  * This answer is IMMUTABLE for the life of the record, which is what lets the
484
464
  * endpoint in front of it cache for a year.
@@ -500,7 +480,7 @@ export async function getRecordAlbum(
500
480
  include: { json: true },
501
481
  });
502
482
  const json = (object?.json ?? {}) as Record<string, unknown>;
503
- const raw = json.release_id ?? json.releaseId;
483
+ const raw = json.release_id;
504
484
  const releaseId = typeof raw === "string" && raw ? raw : null;
505
485
  const includeRelease =
506
486
  options.include?.some(
@@ -7,15 +7,18 @@
7
7
  // `lib/money.ts`, `lib/drops.ts`) lives here instead, so a redeploy is a change
8
8
  // in ONE file that every surface picks up.
9
9
  //
10
- // Testnet values are the deployed ones (verified against chain 2026-08-09).
11
- // Mainnet is deliberately EMPTY: `misoConfig("mainnet")` throws rather than
12
- // silently reading testnet ids on a mainnet deployment.
10
+ // Testnet values are baked from the verified 2026-08-19 deployment. Mainnet is
11
+ // deliberately unavailable until this ABI is deployed there.
12
+
13
+ import { MISO_PLATFORM_DEPLOYMENTS } from "../deployments.ts";
13
14
 
14
15
  export type Network = "testnet" | "mainnet";
15
16
 
16
- /** Anything but "mainnet" including unset is testnet. Mirrors miso-api's `networkFromEnv`. */
17
+ /** Missing defaults to Testnet for local development; invalid values fail closed. */
17
18
  export function networkFrom(value: string | undefined): Network {
18
- return value === "mainnet" ? "mainnet" : "testnet";
19
+ if (value === undefined || value === "testnet") return "testnet";
20
+ if (value === "mainnet") return "mainnet";
21
+ throw new Error(`@misofm/sdk/read: unsupported network "${value}".`);
19
22
  }
20
23
 
21
24
  /** Package ids for the miso protocol core and the extensions the read layer touches. */
@@ -24,17 +27,15 @@ export interface ProtocolIds {
24
27
  miso: string;
25
28
  /** `miso_drop` — `drop::buy` and the `Drop` objects the pressing pages read. */
26
29
  drop: string;
30
+ /** `miso_record` package — the exact owner/type namespace for `record::Record`. */
31
+ record: string;
27
32
  /** `miso_record` shared `Settings` object — the mint witness authorizer. */
28
33
  recordSettings: string;
29
- /** `release_cover_art` the release cover extension currently written to. */
34
+ /** Release coordinator package and its shared derivation-parent object. */
35
+ releaseRegistry: string;
36
+ releaseRegistryId: string;
37
+ /** `release_cover_art` — the release cover extension. */
30
38
  releaseCoverArt: string;
31
- /**
32
- * Cover-art packages from before the `cover_art` package split. A cover set
33
- * under one of these is invisible to a current-package read, so cover reads
34
- * fall back through this list in order. Drop an entry once every cover it
35
- * holds has been re-set under `releaseCoverArt`.
36
- */
37
- legacyReleaseCoverArt: readonly string[];
38
39
  /** `composition_credits` / `recording_credits` / `release_credits` extensions. */
39
40
  compositionCredits: string;
40
41
  recordingCredits: string;
@@ -97,33 +98,19 @@ export interface MisoConfig {
97
98
  const TESTNET: MisoConfig = {
98
99
  network: "testnet",
99
100
  protocol: {
100
- miso: "0x648c9dfba8c800ebd5e608599551f51e1a157942e29d59a1c35e14c44367acf0",
101
- drop: "0xfc2b51f068dee9d5482d39fa017164f6a8c3601cabb59084a518de5f609ef1c7",
102
- recordSettings: "0xadf53b5be0d9eea43712b0c73d0ce55d1fb990ba06e35e12a9a371b2dfe3fd35",
103
- releaseCoverArt: "0x1ee2cae0da7595d7973c310c912434ef531589b468cc57839296810c1385f7f6",
104
- legacyReleaseCoverArt: ["0x7d4a205a68f8e768a408c9f4c45a4d4076722c5edeba9068c0ac058f554e964e"],
105
- compositionCredits: "0x25ba72b5737cac577ca8c92d0f1962efbe5d688a1088cfdc580740605086b366",
106
- recordingCredits: "0xd272b1960e5fae15ae2a5425b910a96619727c85acd0c0095b6089531fdb32a9",
107
- releaseCredits: "0xed764634b9c9a6af04e3c7f60f657c8e2129baf9b43fb9aee6f3523a423228e4",
108
- credit: "0x96c82da135bbd534850ca0a2445fdd2531dd4e0947ffa14645a2eb6636d83646",
109
- },
110
- party: {
111
- partyPackageId: "0xd1c0253f837c57bd0a572673a28374e32c118059356e0c9db26784897175197e",
112
- partyProfilePackageId: "0x6f8841bb252d3ba0f59f9027546be7a0e0a59d84757214df216eb14ef8a9719e",
113
- countryCodePackageId: "0x6c3a53f228ccd089825d0fb5ee1f0465a4b7a438bc1b1735b4e2f01df8d056e9",
114
- languageCodePackageId: "0xa18b786807cfc45488691f93aa647800b77cf9993e420d110afd7024c5b15948",
115
- partyMediaPackageId: "0xc04dbdc05076f642fa8dc79257de9d45ee71fc8fee4a4fe1c05c6bb27e8982ee",
116
- partyRolesPackageId: "0x18e6d59fe3a6496bd42273fd97e6e4b0ae7d3a8a876a6bbe4f6ae1b6057a6f38",
117
- partyTagsPackageId: "0x5a5ed50aac1146b34490949ab33fd29dc2ba13ddf1b8f90b4797e67e1301609d",
118
- partyGenrePackageId: "0x2d489291ce41392ae887e2e048f752a9bd6bea9f540b2c3d2356e36f0e624e29",
119
- partyCtaPackageId: "0xbf4b04afa5b9c87b7385c6a1f116165a6e3f9bed3e16ea064fed7be4da14db7f",
120
- partyPlatformLinkPackageId: "0x2bf95053493e640e3641abef2a9d6080ac563da62a5ca8e878e6d3459fdf27c8",
121
- partySocialPackageId: "0x24bdc5f4cdf68d5cbd6f2b4b791f8b0311060a7fac7e54c10d3a101aa7d6b56d",
122
- partyMusicPackageId: "0x40d8c48aa7cd8ade4ccfc7eb68de958403b08a897589934c191993b25961c453",
123
- partyProLinkPackageId: "0xe2f0160eeac627378538b82209c2cd58b6a73827dae46f5f92368a6c7e84ee8d",
124
- partyFeaturedDropPackageId: "0x5205a9f88702ed2dadd95e4d0096c691a40c96d8bb05d77127f1a62a6eb72cf7",
125
- genrePackageId: "0x7ee69a2f1440152ecdacad997364fb28fe1fc140fd720e4c6d37ad78e29a376d",
101
+ miso: MISO_PLATFORM_DEPLOYMENTS.testnet.protocol.packageId,
102
+ drop: MISO_PLATFORM_DEPLOYMENTS.testnet.packages.drop,
103
+ record: MISO_PLATFORM_DEPLOYMENTS.testnet.packages.record,
104
+ recordSettings: MISO_PLATFORM_DEPLOYMENTS.testnet.objects.recordSettings,
105
+ releaseRegistry: MISO_PLATFORM_DEPLOYMENTS.testnet.packages.releaseRegistry,
106
+ releaseRegistryId: MISO_PLATFORM_DEPLOYMENTS.testnet.objects.releaseRegistry,
107
+ releaseCoverArt: MISO_PLATFORM_DEPLOYMENTS.testnet.packages.releaseCoverArt,
108
+ compositionCredits: MISO_PLATFORM_DEPLOYMENTS.testnet.packages.compositionCredits,
109
+ recordingCredits: MISO_PLATFORM_DEPLOYMENTS.testnet.packages.recordingCredits,
110
+ releaseCredits: MISO_PLATFORM_DEPLOYMENTS.testnet.packages.releaseCredits,
111
+ credit: MISO_PLATFORM_DEPLOYMENTS.testnet.packages.credit,
126
112
  },
113
+ party: MISO_PLATFORM_DEPLOYMENTS.testnet.party,
127
114
  money: {
128
115
  usdCoinType: "0x77774cb7b8cb5622b4ef2658101bf5f1e965418297fe874b683df8f760b6e749::fakeusd::FakeUsd",
129
116
  usdDecimals: 6,
@@ -132,12 +119,8 @@ const TESTNET: MisoConfig = {
132
119
  graphqlUrl: "https://graphql.testnet.sui.io/graphql",
133
120
  walrusAggregatorUrl: "https://aggregator.walrus-testnet.walrus.space",
134
121
  apiBaseUrl: "https://api.testnet.miso.fm",
135
- discoverReleaseIds: [
136
- // AMIANGELIKA — BLCK SUN
137
- "0xa16e7ef7af5104690117321c749995db1164db668a5559cf6a0706b26141c327",
138
- // Gateway Girl — Between the Doors
139
- "0x7144600de3bb037f23b9371a2bcd5c0d84a80abc381a9d03b00ff7e03f412623",
140
- ],
122
+ // Content from the retired deployment is intentionally not carried forward.
123
+ discoverReleaseIds: [],
141
124
  };
142
125
 
143
126
  /** Fields a deployment may override without forking the whole config (endpoints, shelf). */
@@ -152,7 +135,7 @@ export type MisoConfigOverrides = Partial<
152
135
  export function misoConfig(network: Network, overrides: MisoConfigOverrides = {}): MisoConfig {
153
136
  if (network === "mainnet") {
154
137
  throw new Error(
155
- "@misofm/sdk/read: no mainnet configuration yet. Deploy the Move packages, then fill in the mainnet block in src/read/config.ts.",
138
+ `@misofm/sdk/read: no bundled Miso platform deployment for network "${network}".`,
156
139
  );
157
140
  }
158
141
  return { ...TESTNET, ...stripUndefined(overrides) };
package/src/read/index.ts CHANGED
@@ -59,7 +59,6 @@ export type { ArtistInclude, GetArtistOptions } from "./artist.ts";
59
59
  export { resolveGenreNames } from "./genres.ts";
60
60
 
61
61
  export {
62
- RECORD_TYPE_SUFFIX,
63
62
  getBalance,
64
63
  getOwnedParties,
65
64
  getPendingMemberships,
package/src/read/types.ts CHANGED
@@ -270,7 +270,7 @@ export interface PartySummary {
270
270
  export interface OwnedRecord {
271
271
  /** Canonical object id — the `recordId` route param. */
272
272
  id: string;
273
- /** Full on-chain type, e.g. `0xfc2b51…::record::Record`. */
273
+ /** Full on-chain type, e.g. `<miso_record>::record::Record`. */
274
274
  type: string;
275
275
  releaseId: string | null;
276
276
  /** Copy / edition number, when the struct exposes one. */