@misofm/sdk 0.4.0 → 0.6.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 (53) hide show
  1. package/dist/catalog.d.ts +4 -17
  2. package/dist/catalog.d.ts.map +1 -1
  3. package/dist/catalog.js +46 -58
  4. package/dist/catalog.js.map +1 -1
  5. package/dist/cover.d.ts +10 -0
  6. package/dist/cover.d.ts.map +1 -1
  7. package/dist/cover.js +66 -19
  8. package/dist/cover.js.map +1 -1
  9. package/dist/credits.d.ts +10 -0
  10. package/dist/credits.d.ts.map +1 -1
  11. package/dist/credits.js +149 -39
  12. package/dist/credits.js.map +1 -1
  13. package/dist/drop.d.ts +7 -0
  14. package/dist/drop.d.ts.map +1 -1
  15. package/dist/drop.js +84 -34
  16. package/dist/drop.js.map +1 -1
  17. package/dist/pressing.d.ts.map +1 -1
  18. package/dist/pressing.js +59 -16
  19. package/dist/pressing.js.map +1 -1
  20. package/dist/read/artist.d.ts +1 -6
  21. package/dist/read/artist.d.ts.map +1 -1
  22. package/dist/read/artist.js +39 -22
  23. package/dist/read/artist.js.map +1 -1
  24. package/dist/read/catalog.d.ts +24 -3
  25. package/dist/read/catalog.d.ts.map +1 -1
  26. package/dist/read/catalog.js +190 -89
  27. package/dist/read/catalog.js.map +1 -1
  28. package/dist/read/index.d.ts +6 -4
  29. package/dist/read/index.d.ts.map +1 -1
  30. package/dist/read/index.js +3 -3
  31. package/dist/read/index.js.map +1 -1
  32. package/dist/read/types.d.ts +21 -1
  33. package/dist/read/types.d.ts.map +1 -1
  34. package/dist/read/wallet.d.ts +10 -1
  35. package/dist/read/wallet.d.ts.map +1 -1
  36. package/dist/read/wallet.js +28 -0
  37. package/dist/read/wallet.js.map +1 -1
  38. package/dist/read/works.d.ts +3 -2
  39. package/dist/read/works.d.ts.map +1 -1
  40. package/dist/read/works.js +158 -48
  41. package/dist/read/works.js.map +1 -1
  42. package/package.json +2 -2
  43. package/src/catalog.ts +71 -77
  44. package/src/cover.ts +107 -26
  45. package/src/credits.ts +353 -89
  46. package/src/drop.ts +150 -40
  47. package/src/pressing.ts +146 -36
  48. package/src/read/artist.ts +73 -34
  49. package/src/read/catalog.ts +324 -89
  50. package/src/read/index.ts +24 -2
  51. package/src/read/types.ts +26 -2
  52. package/src/read/wallet.ts +45 -1
  53. package/src/read/works.ts +224 -59
package/src/cover.ts CHANGED
@@ -19,7 +19,6 @@ import { bcs } from "@mysten/sui/bcs";
19
19
  import { deriveDynamicFieldID } from "@mysten/sui/utils";
20
20
  import type { TxThunk } from "./transactions.ts";
21
21
  import { OPTION_NONE, OPTION_SOME } from "./internal.ts";
22
- import { isNotFound } from "./queries.ts";
23
22
  import * as coverArt from "./contracts/cover_art/cover_art.ts";
24
23
  import * as releaseCoverArt from "./contracts/release_cover_art/release_cover_art.ts";
25
24
 
@@ -45,15 +44,27 @@ export function setReleaseCover(p: SetReleaseCoverParams): TxThunk {
45
44
  return (tx) => {
46
45
  const walrusType = `${p.oriPackageId}::walrus_data::WalrusData`;
47
46
  const blob = (id: bigint | string) =>
48
- tx.moveCall({ target: `${p.oriPackageId}::walrus_data::new_blob`, arguments: [tx.pure.u256(id)] });
47
+ tx.moveCall({
48
+ target: `${p.oriPackageId}::walrus_data::new_blob`,
49
+ arguments: [tx.pure.u256(id)],
50
+ });
49
51
 
50
52
  const still = blob(p.stillBlobId);
51
53
  const animated =
52
54
  p.animatedBlobId == null
53
55
  ? tx.moveCall({ target: OPTION_NONE, typeArguments: [walrusType] })
54
- : tx.moveCall({ target: OPTION_SOME, typeArguments: [walrusType], arguments: [blob(p.animatedBlobId)] });
55
-
56
- const cover = tx.add(coverArt._new({ package: p.coverArtPackageId, arguments: [still, animated] }));
56
+ : tx.moveCall({
57
+ target: OPTION_SOME,
58
+ typeArguments: [walrusType],
59
+ arguments: [blob(p.animatedBlobId)],
60
+ });
61
+
62
+ const cover = tx.add(
63
+ coverArt._new({
64
+ package: p.coverArtPackageId,
65
+ arguments: [still, animated],
66
+ }),
67
+ );
57
68
  tx.add(
58
69
  releaseCoverArt.setCover({
59
70
  package: p.releaseCoverArtPackageId,
@@ -72,7 +83,13 @@ export function setReleaseCover(p: SetReleaseCoverParams): TxThunk {
72
83
  */
73
84
  export type CoverImageRef =
74
85
  | { kind: "blob"; blobId: string }
75
- | { kind: "quiltPatch"; quiltId: string; version: number; startIndex: number; endIndex: number };
86
+ | {
87
+ kind: "quiltPatch";
88
+ quiltId: string;
89
+ version: number;
90
+ startIndex: number;
91
+ endIndex: number;
92
+ };
76
93
 
77
94
  /** A release's album-level cover: a still image and an optional animation. */
78
95
  export interface ReleaseCoverView {
@@ -88,17 +105,28 @@ const CoverArtField = bcs.struct("Field", {
88
105
  name: releaseCoverArt.ExtensionKey,
89
106
  value: releaseCoverArt.ReleaseCoverArt,
90
107
  });
91
- const COVER_ART_KEY_BYTES = releaseCoverArt.ExtensionKey.serialize([false]).toBytes();
108
+ const COVER_ART_KEY_BYTES = releaseCoverArt.ExtensionKey.serialize([
109
+ false,
110
+ ]).toBytes();
92
111
 
93
112
  /** A parsed `ori::WalrusData` value (a MoveEnum: `Blob` or `QuiltPatch`). */
94
113
  type ParsedWalrusData =
95
114
  | { $kind: "Blob"; Blob: [string | number | bigint, unknown] }
96
- | { $kind: "QuiltPatch"; QuiltPatch: [string | number | bigint, number, number, number] };
115
+ | {
116
+ $kind: "QuiltPatch";
117
+ QuiltPatch: [string | number | bigint, number, number, number];
118
+ };
97
119
 
98
120
  function toCoverImageRef(wd: ParsedWalrusData): CoverImageRef {
99
121
  if (wd.$kind === "Blob") return { kind: "blob", blobId: String(wd.Blob[0]) };
100
122
  const [quiltId, version, startIndex, endIndex] = wd.QuiltPatch;
101
- return { kind: "quiltPatch", quiltId: String(quiltId), version, startIndex, endIndex };
123
+ return {
124
+ kind: "quiltPatch",
125
+ quiltId: String(quiltId),
126
+ version,
127
+ startIndex,
128
+ endIndex,
129
+ };
102
130
  }
103
131
 
104
132
  /**
@@ -112,25 +140,24 @@ export async function getReleaseCover(
112
140
  releaseId: string,
113
141
  releaseCoverArtPackageId: string,
114
142
  ): Promise<ReleaseCoverView | null> {
115
- const fieldId = deriveDynamicFieldID(
116
- releaseId,
117
- `${releaseCoverArtPackageId}::release_cover_art::ExtensionKey`,
118
- COVER_ART_KEY_BYTES,
143
+ return (
144
+ (
145
+ await getReleaseCoversByIds(
146
+ client,
147
+ [releaseId],
148
+ [releaseCoverArtPackageId],
149
+ )
150
+ )[releaseId] ?? null
119
151
  );
152
+ }
120
153
 
121
- let content: Uint8Array | null;
122
- try {
123
- const { object } = await client.core.getObject({ objectId: fieldId, include: { content: true } });
124
- content = object?.content ?? null;
125
- } catch (e) {
126
- if (isNotFound(e)) return null;
127
- throw e;
128
- }
129
- if (!content) return null;
130
-
131
- const cover = CoverArtField.parse(content).value.cover as
132
- | { still: ParsedWalrusData; animated: ParsedWalrusData | null }
133
- | null;
154
+ export function parseReleaseCoverContent(
155
+ content: Uint8Array,
156
+ ): ReleaseCoverView | null {
157
+ const cover = CoverArtField.parse(content).value.cover as {
158
+ still: ParsedWalrusData;
159
+ animated: ParsedWalrusData | null;
160
+ } | null;
134
161
  if (!cover) return null;
135
162
 
136
163
  return {
@@ -138,3 +165,57 @@ export async function getReleaseCover(
138
165
  animated: cover.animated ? toCoverImageRef(cover.animated) : null,
139
166
  };
140
167
  }
168
+
169
+ /** Deterministic dynamic-field id for one release-cover package generation. */
170
+ export function releaseCoverFieldId(
171
+ releaseId: string,
172
+ releaseCoverArtPackageId: string,
173
+ ): string {
174
+ return deriveDynamicFieldID(
175
+ releaseId,
176
+ `${releaseCoverArtPackageId}::release_cover_art::ExtensionKey`,
177
+ COVER_ART_KEY_BYTES,
178
+ );
179
+ }
180
+
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.
186
+ */
187
+ export async function getReleaseCoversByIds(
188
+ client: ClientWithCoreApi,
189
+ releaseIdsInput: readonly string[],
190
+ releaseCoverArtPackageIds: readonly string[],
191
+ ): Promise<Partial<Record<string, ReleaseCoverView>>> {
192
+ 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
+ );
200
+ if (targets.length === 0) return {};
201
+
202
+ const { objects } = await client.core.getObjects({
203
+ objectIds: targets.map((target) => target.fieldId),
204
+ include: { content: true },
205
+ });
206
+ const out: Partial<Record<string, ReleaseCoverView>> = {};
207
+ const priorities = new Map<string, number>();
208
+ objects.forEach((object, index) => {
209
+ const target = targets[index];
210
+ 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
+ const cover = parseReleaseCoverContent(object.content);
215
+ if (cover) {
216
+ out[target.releaseId] = cover;
217
+ priorities.set(target.releaseId, target.priority);
218
+ }
219
+ });
220
+ return out;
221
+ }