@misofm/musicos 0.1.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 (103) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +75 -0
  3. package/dist/client.d.ts +309 -0
  4. package/dist/client.d.ts.map +1 -0
  5. package/dist/client.js +216 -0
  6. package/dist/client.js.map +1 -0
  7. package/dist/contracts/musicos/composition.d.ts +195 -0
  8. package/dist/contracts/musicos/composition.d.ts.map +1 -0
  9. package/dist/contracts/musicos/composition.js +195 -0
  10. package/dist/contracts/musicos/composition.js.map +1 -0
  11. package/dist/contracts/musicos/deps/bps/bps.d.ts +17 -0
  12. package/dist/contracts/musicos/deps/bps/bps.d.ts.map +1 -0
  13. package/dist/contracts/musicos/deps/bps/bps.js +19 -0
  14. package/dist/contracts/musicos/deps/bps/bps.js.map +1 -0
  15. package/dist/contracts/musicos/recording.d.ts +238 -0
  16. package/dist/contracts/musicos/recording.d.ts.map +1 -0
  17. package/dist/contracts/musicos/recording.js +232 -0
  18. package/dist/contracts/musicos/recording.js.map +1 -0
  19. package/dist/contracts/musicos/release.d.ts +298 -0
  20. package/dist/contracts/musicos/release.d.ts.map +1 -0
  21. package/dist/contracts/musicos/release.js +298 -0
  22. package/dist/contracts/musicos/release.js.map +1 -0
  23. package/dist/contracts/musicos/track.d.ts +193 -0
  24. package/dist/contracts/musicos/track.d.ts.map +1 -0
  25. package/dist/contracts/musicos/track.js +197 -0
  26. package/dist/contracts/musicos/track.js.map +1 -0
  27. package/dist/contracts/utils/index.d.ts +104 -0
  28. package/dist/contracts/utils/index.d.ts.map +1 -0
  29. package/dist/contracts/utils/index.js +272 -0
  30. package/dist/contracts/utils/index.js.map +1 -0
  31. package/dist/contracts.d.ts +9 -0
  32. package/dist/contracts.d.ts.map +1 -0
  33. package/dist/contracts.js +14 -0
  34. package/dist/contracts.js.map +1 -0
  35. package/dist/deployments.d.ts +60 -0
  36. package/dist/deployments.d.ts.map +1 -0
  37. package/dist/deployments.js +109 -0
  38. package/dist/deployments.js.map +1 -0
  39. package/dist/events.d.ts +16 -0
  40. package/dist/events.d.ts.map +1 -0
  41. package/dist/events.js +25 -0
  42. package/dist/events.js.map +1 -0
  43. package/dist/execute.d.ts +49 -0
  44. package/dist/execute.d.ts.map +1 -0
  45. package/dist/execute.js +110 -0
  46. package/dist/execute.js.map +1 -0
  47. package/dist/index.d.ts +13 -0
  48. package/dist/index.d.ts.map +1 -0
  49. package/dist/index.js +20 -0
  50. package/dist/index.js.map +1 -0
  51. package/dist/internal.d.ts +17 -0
  52. package/dist/internal.d.ts.map +1 -0
  53. package/dist/internal.js +46 -0
  54. package/dist/internal.js.map +1 -0
  55. package/dist/numeric.d.ts +5 -0
  56. package/dist/numeric.d.ts.map +1 -0
  57. package/dist/numeric.js +21 -0
  58. package/dist/numeric.js.map +1 -0
  59. package/dist/packages.d.ts +67 -0
  60. package/dist/packages.d.ts.map +1 -0
  61. package/dist/packages.js +85 -0
  62. package/dist/packages.js.map +1 -0
  63. package/dist/parsers.d.ts +9 -0
  64. package/dist/parsers.d.ts.map +1 -0
  65. package/dist/parsers.js +40 -0
  66. package/dist/parsers.js.map +1 -0
  67. package/dist/queries.d.ts +178 -0
  68. package/dist/queries.d.ts.map +1 -0
  69. package/dist/queries.js +611 -0
  70. package/dist/queries.js.map +1 -0
  71. package/dist/transactions.d.ts +136 -0
  72. package/dist/transactions.d.ts.map +1 -0
  73. package/dist/transactions.js +145 -0
  74. package/dist/transactions.js.map +1 -0
  75. package/dist/types.d.ts +194 -0
  76. package/dist/types.d.ts.map +1 -0
  77. package/dist/types.js +4 -0
  78. package/dist/types.js.map +1 -0
  79. package/dist/view.d.ts +22 -0
  80. package/dist/view.d.ts.map +1 -0
  81. package/dist/view.js +42 -0
  82. package/dist/view.js.map +1 -0
  83. package/package.json +119 -0
  84. package/src/client.ts +341 -0
  85. package/src/contracts/musicos/composition.ts +280 -0
  86. package/src/contracts/musicos/deps/bps/bps.ts +22 -0
  87. package/src/contracts/musicos/recording.ts +308 -0
  88. package/src/contracts/musicos/release.ts +409 -0
  89. package/src/contracts/musicos/track.ts +255 -0
  90. package/src/contracts/utils/index.ts +428 -0
  91. package/src/contracts.ts +29 -0
  92. package/src/deployments.ts +166 -0
  93. package/src/events.ts +30 -0
  94. package/src/execute.ts +137 -0
  95. package/src/index.ts +21 -0
  96. package/src/internal.ts +78 -0
  97. package/src/numeric.ts +25 -0
  98. package/src/packages.ts +117 -0
  99. package/src/parsers.ts +66 -0
  100. package/src/queries.ts +928 -0
  101. package/src/transactions.ts +305 -0
  102. package/src/types.ts +222 -0
  103. package/src/view.ts +65 -0
@@ -0,0 +1,409 @@
1
+ /**************************************************************
2
+ * THIS FILE IS GENERATED AND SHOULD NOT BE MANUALLY MODIFIED *
3
+ **************************************************************/
4
+
5
+
6
+ /**
7
+ * Represents a music release in musicos. A release is an ordered tracklist with
8
+ * per-track revenue distribution configuration. Cover art lives in the `cover_art`
9
+ * extension, not in core.
10
+ *
11
+ * The tracklist is deliberately FLAT — a `vector<Track>` with no disc structure.
12
+ * Grouping a sequence into discs, vinyl sides, acts, or movements is a property of
13
+ * a distribution medium, not of the release: it has more than one correct
14
+ * rendering, which makes it presentation, and presentation lives in the metadata
15
+ * extension. A consequence worth stating: the stored tracklist and the digest
16
+ * pre-image have the same shape, so what signers consented to is exactly what is
17
+ * stored — nothing structural is chosen after consent except the title.
18
+ *
19
+ * ### Key Features:
20
+ *
21
+ * - Ordered flat tracklist (grouping is presentation, in the metadata extension)
22
+ * - Configurable per-track revenue splits
23
+ * - State machine: Initialized -> Published
24
+ *
25
+ * Attribution (credits, primary/featured artists) is intentionally NOT part of
26
+ * core: it is display-oriented, varies across platforms, and is never read by the
27
+ * economics. It lives in a first-party credits extension attached via `uid_mut`,
28
+ * so core takes no dependency on an identity package and core publish enforces no
29
+ * attribution.
30
+ *
31
+ * The same rule governs naming. Core stores what a thing _is_ — identity and
32
+ * everything the economics read; extensions describe it. The release's `title` is
33
+ * the one embedded name: it is constitutive (naming the package is part of
34
+ * creating it) and freezing it at publish is a buyer-facing guarantee. Edition
35
+ * naming ("Deluxe Edition"), disc titles, localized titles, and DSP-shaped slots
36
+ * all have more than one correct rendering — presentation — and live in the
37
+ * metadata extension.
38
+ *
39
+ * ### Consent scope
40
+ *
41
+ * The release digest — and therefore the derived release id every `Track` commits
42
+ * to at creation — binds the economics and membership of the release: the ordered
43
+ * list of `(recording, split)` pairs and the creator's nonce. It deliberately
44
+ * binds nothing else. The title — the one embedded field outside the digest — and
45
+ * everything in the extension layer (artwork, credits, display grouping) are
46
+ * chosen by the release creator, before or after tracks are created, and are
47
+ * trusted and publicly attributable rather than cryptographically committed. See
48
+ * `track::new` for the signer-side statement of this boundary.
49
+ *
50
+ * The derived id commits to the canonical registry's UID and the digest, not the
51
+ * digest alone — so targeting an id also consents to that namespace's liveness. If
52
+ * that parent were deleted, or its `&mut UID` became permanently unreachable, the
53
+ * release could never exist and every track or offer targeting it would be
54
+ * stranded — the same blast-radius class as a release that simply never publishes.
55
+ * `ReleaseRegistry` is therefore created and shared exactly once at package
56
+ * initialization, and exposes neither a constructor, deletion path, nor mutable
57
+ * UID accessor.
58
+ *
59
+ * ### Lifecycle and trust model
60
+ *
61
+ * A release is `key`-only with no `drop`: a fresh `Initialized` object cannot be
62
+ * transferred, wrapped, publicly shared, or discarded, and its only by-value
63
+ * consumer is `publish`. Create-and-publish is therefore atomic by construction —
64
+ * an `Initialized` release cannot outlive its creating transaction, and every
65
+ * release that exists on-chain is `Published` and shared. There is deliberately no
66
+ * keep function; assembling tracks, discs, and the release must fit one
67
+ * transaction.
68
+ *
69
+ * `uid_mut` works in any lifecycle state and is permanent root over ALL dynamic
70
+ * fields on the object — including fields attached by other extensions. "Immutable
71
+ * after publish" covers the embedded fields only; extension-layer data stays
72
+ * admin-mutable in perpetuity. This is the designed extension surface, and it is
73
+ * the one trust assumption that never expires: integrators should model the cap
74
+ * holder as able to mutate or delete any extension data, forever.
75
+ */
76
+
77
+ import { MoveEnum, MoveStruct, MoveTuple, normalizeMoveArguments, type RawTransactionArgument } from '../utils/index.ts';
78
+ import { bcs } from '@mysten/sui/bcs';
79
+ import type {} from "@mysten/bcs";
80
+ import { type Transaction, type TransactionArgument } from '@mysten/sui/transactions';
81
+ import * as track from './track.ts';
82
+ const $moduleName = '@local-pkg/musicos::release';
83
+ /** Lifecycle state of a release. */
84
+ export const ReleaseState = new MoveEnum({ name: `${$moduleName}::ReleaseState`, fields: {
85
+ /** Release is initialized but not yet published. */
86
+ Initialized: null,
87
+ /** Release is published and immutable. Includes publication timestamp. */
88
+ Published: bcs.u64()
89
+ } });
90
+ export const Release = new MoveStruct({ name: `${$moduleName}::Release`, fields: {
91
+ /** Unique identifier for this release. */
92
+ id: bcs.Address,
93
+ /** Current lifecycle state. */
94
+ state: ReleaseState,
95
+ /** Title of the release. */
96
+ title: bcs.string(),
97
+ /**
98
+ * The ordered tracklist. Same shape as the digest pre-image every track's creator
99
+ * consented to; display grouping lives in the metadata extension.
100
+ */
101
+ tracks: bcs.vector(track.Track)
102
+ } });
103
+ export const ReleaseRegistry = new MoveStruct({ name: `${$moduleName}::ReleaseRegistry`, fields: {
104
+ id: bcs.Address
105
+ } });
106
+ export const ReleaseKey = new MoveTuple({ name: `${$moduleName}::ReleaseKey`, fields: [bcs.vector(bcs.u8())] });
107
+ export const ReleaseAdminCap = new MoveStruct({ name: `${$moduleName}::ReleaseAdminCap`, fields: {
108
+ /** Unique identifier for this capability. */
109
+ id: bcs.Address,
110
+ /** ID of the release this capability controls. */
111
+ release_id: bcs.Address
112
+ } });
113
+ export const ReleaseAdminCapKey = new MoveTuple({ name: `${$moduleName}::ReleaseAdminCapKey`, fields: [bcs.bool()] });
114
+ export const ReleasePublishedEvent = new MoveStruct({ name: `${$moduleName}::ReleasePublishedEvent`, fields: {
115
+ release_id: bcs.Address
116
+ } });
117
+ export const ReleaseRegistryCreatedEvent = new MoveStruct({ name: `${$moduleName}::ReleaseRegistryCreatedEvent`, fields: {
118
+ registry_id: bcs.Address,
119
+ created_by: bcs.Address
120
+ } });
121
+ export interface NewArguments {
122
+ self: RawTransactionArgument<string>;
123
+ title: RawTransactionArgument<string>;
124
+ tracks: TransactionArgument;
125
+ nonce: RawTransactionArgument<number | bigint>;
126
+ }
127
+ export interface NewOptions {
128
+ package?: string;
129
+ arguments: NewArguments | [
130
+ self: RawTransactionArgument<string>,
131
+ title: RawTransactionArgument<string>,
132
+ tracks: TransactionArgument,
133
+ nonce: RawTransactionArgument<number | bigint>
134
+ ];
135
+ }
136
+ /**
137
+ * Assembles a release under the canonical registry namespace. This is
138
+ * permissionless: consent is carried by the supplied tracks, each of which was
139
+ * created for the exact derived release id. Returns the release and admin
140
+ * capability by value so the caller can compose `publish` and custody in the same
141
+ * PTB.
142
+ */
143
+ export function _new(options: NewOptions) {
144
+ const packageAddress = options.package ?? '@local-pkg/musicos';
145
+ const argumentsTypes = [
146
+ null,
147
+ '0x1::string::String',
148
+ 'vector<null>',
149
+ 'u256'
150
+ ] satisfies (string | null)[];
151
+ const parameterNames = ["self", "title", "tracks", "nonce"];
152
+ return (tx: Transaction) => tx.moveCall({
153
+ package: packageAddress,
154
+ module: 'release',
155
+ function: 'new',
156
+ arguments: normalizeMoveArguments(options.arguments, argumentsTypes, parameterNames),
157
+ });
158
+ }
159
+ export interface DeriveTargetReleaseIdArguments {
160
+ self: RawTransactionArgument<string>;
161
+ recordingIds: RawTransactionArgument<Array<string>>;
162
+ trackSplitValues: RawTransactionArgument<Array<number | bigint>>;
163
+ nonce: RawTransactionArgument<number | bigint>;
164
+ }
165
+ export interface DeriveTargetReleaseIdOptions {
166
+ package?: string;
167
+ arguments: DeriveTargetReleaseIdArguments | [
168
+ self: RawTransactionArgument<string>,
169
+ recordingIds: RawTransactionArgument<Array<string>>,
170
+ trackSplitValues: RawTransactionArgument<Array<number | bigint>>,
171
+ nonce: RawTransactionArgument<number | bigint>
172
+ ];
173
+ }
174
+ /**
175
+ * Derives the release id that `new` would claim under this registry, without
176
+ * creating a release. This immutable shared-object access remains parallelizable
177
+ * for clients preparing tracks.
178
+ */
179
+ export function deriveTargetReleaseId(options: DeriveTargetReleaseIdOptions) {
180
+ const packageAddress = options.package ?? '@local-pkg/musicos';
181
+ const argumentsTypes = [
182
+ null,
183
+ 'vector<0x2::object::ID>',
184
+ 'vector<u64>',
185
+ 'u256'
186
+ ] satisfies (string | null)[];
187
+ const parameterNames = ["self", "recordingIds", "trackSplitValues", "nonce"];
188
+ return (tx: Transaction) => tx.moveCall({
189
+ package: packageAddress,
190
+ module: 'release',
191
+ function: 'derive_target_release_id',
192
+ arguments: normalizeMoveArguments(options.arguments, argumentsTypes, parameterNames),
193
+ });
194
+ }
195
+ export interface ReleaseRegistryIdArguments {
196
+ self: RawTransactionArgument<string>;
197
+ }
198
+ export interface ReleaseRegistryIdOptions {
199
+ package?: string;
200
+ arguments: ReleaseRegistryIdArguments | [
201
+ self: RawTransactionArgument<string>
202
+ ];
203
+ }
204
+ /**
205
+ * Returns the canonical registry's object ID, which is the derivation parent
206
+ * committed to by `new` and `derive_target_release_id`. Exported as the
207
+ * `ReleaseRegistry.id()` method to avoid colliding with the existing
208
+ * `release::id(&Release)` ABI function.
209
+ */
210
+ export function releaseRegistryId(options: ReleaseRegistryIdOptions) {
211
+ const packageAddress = options.package ?? '@local-pkg/musicos';
212
+ const argumentsTypes = [
213
+ null
214
+ ] satisfies (string | null)[];
215
+ const parameterNames = ["self"];
216
+ return (tx: Transaction) => tx.moveCall({
217
+ package: packageAddress,
218
+ module: 'release',
219
+ function: 'release_registry_id',
220
+ arguments: normalizeMoveArguments(options.arguments, argumentsTypes, parameterNames),
221
+ });
222
+ }
223
+ export interface PublishArguments {
224
+ self: RawTransactionArgument<string>;
225
+ cap: RawTransactionArgument<string>;
226
+ }
227
+ export interface PublishOptions {
228
+ package?: string;
229
+ arguments: PublishArguments | [
230
+ self: RawTransactionArgument<string>,
231
+ cap: RawTransactionArgument<string>
232
+ ];
233
+ }
234
+ /**
235
+ * Publishes the release, making it immutable. Track splits must be set and sum to
236
+ * 100% before publishing. Required State: Initialized
237
+ *
238
+ * Note: core enforces no attribution requirement — credits live in the credits
239
+ * extension and may be attached before or after publish via `uid_mut`.
240
+ */
241
+ export function publish(options: PublishOptions) {
242
+ const packageAddress = options.package ?? '@local-pkg/musicos';
243
+ const argumentsTypes = [
244
+ null,
245
+ null,
246
+ '0x2::clock::Clock'
247
+ ] satisfies (string | null)[];
248
+ const parameterNames = ["self", "cap"];
249
+ return (tx: Transaction) => tx.moveCall({
250
+ package: packageAddress,
251
+ module: 'release',
252
+ function: 'publish',
253
+ arguments: normalizeMoveArguments(options.arguments, argumentsTypes, parameterNames),
254
+ });
255
+ }
256
+ export interface AuthorizeArguments {
257
+ self: RawTransactionArgument<string>;
258
+ cap: RawTransactionArgument<string>;
259
+ }
260
+ export interface AuthorizeOptions {
261
+ package?: string;
262
+ arguments: AuthorizeArguments | [
263
+ self: RawTransactionArgument<string>,
264
+ cap: RawTransactionArgument<string>
265
+ ];
266
+ }
267
+ /** Verifies that the admin capability matches this release. */
268
+ export function authorize(options: AuthorizeOptions) {
269
+ const packageAddress = options.package ?? '@local-pkg/musicos';
270
+ const argumentsTypes = [
271
+ null,
272
+ null
273
+ ] satisfies (string | null)[];
274
+ const parameterNames = ["self", "cap"];
275
+ return (tx: Transaction) => tx.moveCall({
276
+ package: packageAddress,
277
+ module: 'release',
278
+ function: 'authorize',
279
+ arguments: normalizeMoveArguments(options.arguments, argumentsTypes, parameterNames),
280
+ });
281
+ }
282
+ export interface TitleArguments {
283
+ self: RawTransactionArgument<string>;
284
+ }
285
+ export interface TitleOptions {
286
+ package?: string;
287
+ arguments: TitleArguments | [
288
+ self: RawTransactionArgument<string>
289
+ ];
290
+ }
291
+ /** Returns the release title. */
292
+ export function title(options: TitleOptions) {
293
+ const packageAddress = options.package ?? '@local-pkg/musicos';
294
+ const argumentsTypes = [
295
+ null
296
+ ] satisfies (string | null)[];
297
+ const parameterNames = ["self"];
298
+ return (tx: Transaction) => tx.moveCall({
299
+ package: packageAddress,
300
+ module: 'release',
301
+ function: 'title',
302
+ arguments: normalizeMoveArguments(options.arguments, argumentsTypes, parameterNames),
303
+ });
304
+ }
305
+ export interface TracksArguments {
306
+ self: RawTransactionArgument<string>;
307
+ }
308
+ export interface TracksOptions {
309
+ package?: string;
310
+ arguments: TracksArguments | [
311
+ self: RawTransactionArgument<string>
312
+ ];
313
+ }
314
+ /**
315
+ * Returns a reference to the ordered tracklist. The single tracklist accessor —
316
+ * consumers derive length, membership, and per-track data from it
317
+ * (`tracks().length()`, `tracks().any!(..)`, indexing).
318
+ */
319
+ export function tracks(options: TracksOptions) {
320
+ const packageAddress = options.package ?? '@local-pkg/musicos';
321
+ const argumentsTypes = [
322
+ null
323
+ ] satisfies (string | null)[];
324
+ const parameterNames = ["self"];
325
+ return (tx: Transaction) => tx.moveCall({
326
+ package: packageAddress,
327
+ module: 'release',
328
+ function: 'tracks',
329
+ arguments: normalizeMoveArguments(options.arguments, argumentsTypes, parameterNames),
330
+ });
331
+ }
332
+ export interface ReleaseAdminCapReleaseIdArguments {
333
+ cap: RawTransactionArgument<string>;
334
+ }
335
+ export interface ReleaseAdminCapReleaseIdOptions {
336
+ package?: string;
337
+ arguments: ReleaseAdminCapReleaseIdArguments | [
338
+ cap: RawTransactionArgument<string>
339
+ ];
340
+ }
341
+ /** Returns the release ID associated with the admin capability. */
342
+ export function releaseAdminCapReleaseId(options: ReleaseAdminCapReleaseIdOptions) {
343
+ const packageAddress = options.package ?? '@local-pkg/musicos';
344
+ const argumentsTypes = [
345
+ null
346
+ ] satisfies (string | null)[];
347
+ const parameterNames = ["cap"];
348
+ return (tx: Transaction) => tx.moveCall({
349
+ package: packageAddress,
350
+ module: 'release',
351
+ function: 'release_admin_cap_release_id',
352
+ arguments: normalizeMoveArguments(options.arguments, argumentsTypes, parameterNames),
353
+ });
354
+ }
355
+ export interface UidArguments {
356
+ self: RawTransactionArgument<string>;
357
+ }
358
+ export interface UidOptions {
359
+ package?: string;
360
+ arguments: UidArguments | [
361
+ self: RawTransactionArgument<string>
362
+ ];
363
+ }
364
+ /** Returns a reference to the release's UID for reading dynamic fields. */
365
+ export function uid(options: UidOptions) {
366
+ const packageAddress = options.package ?? '@local-pkg/musicos';
367
+ const argumentsTypes = [
368
+ null
369
+ ] satisfies (string | null)[];
370
+ const parameterNames = ["self"];
371
+ return (tx: Transaction) => tx.moveCall({
372
+ package: packageAddress,
373
+ module: 'release',
374
+ function: 'uid',
375
+ arguments: normalizeMoveArguments(options.arguments, argumentsTypes, parameterNames),
376
+ });
377
+ }
378
+ export interface UidMutArguments {
379
+ self: RawTransactionArgument<string>;
380
+ cap: RawTransactionArgument<string>;
381
+ }
382
+ export interface UidMutOptions {
383
+ package?: string;
384
+ arguments: UidMutArguments | [
385
+ self: RawTransactionArgument<string>,
386
+ cap: RawTransactionArgument<string>
387
+ ];
388
+ }
389
+ /**
390
+ * Returns a mutable reference to the release's UID. Requires the admin capability.
391
+ * Works in any lifecycle state — dynamic fields are the extension surface (e.g.
392
+ * credits) and stay admin-mutable after publish; only the embedded fields are
393
+ * frozen. The reference is root over every dynamic field on the object, including
394
+ * fields attached by other extensions.
395
+ */
396
+ export function uidMut(options: UidMutOptions) {
397
+ const packageAddress = options.package ?? '@local-pkg/musicos';
398
+ const argumentsTypes = [
399
+ null,
400
+ null
401
+ ] satisfies (string | null)[];
402
+ const parameterNames = ["self", "cap"];
403
+ return (tx: Transaction) => tx.moveCall({
404
+ package: packageAddress,
405
+ module: 'release',
406
+ function: 'uid_mut',
407
+ arguments: normalizeMoveArguments(options.arguments, argumentsTypes, parameterNames),
408
+ });
409
+ }
@@ -0,0 +1,255 @@
1
+ /**************************************************************
2
+ * THIS FILE IS GENERATED AND SHOULD NOT BE MANUALLY MODIFIED *
3
+ **************************************************************/
4
+
5
+
6
+ /**
7
+ * Represents a track on a release, linking a recording to its position in the
8
+ * tracklist.
9
+ *
10
+ * A `Track` is the minimal positioned (recording, revenue-share) pair:
11
+ *
12
+ * - `recording_id` — the routing target for the track's revenue, and the handle
13
+ * through which all other metadata (title, cover art, and the
14
+ * recording/composition share-type identities) is reached.
15
+ * - `composition_id` — the identity of the recording's underlying work, so the
16
+ * composition–recording–release graph is walkable on-chain from the release
17
+ * alone. Move cannot chase an ID to an object, so this edge is unreachable in a
18
+ * track loop unless embedded here.
19
+ * - `split_bps` — this track's share of the release's revenue; genuinely
20
+ * release-specific and not derivable from the recording.
21
+ * - `state` — the assign-once lifecycle that carries (then sheds) the recording
22
+ * admin's target release commitment, made at creation; see `TrackState`.
23
+ *
24
+ * `Track` is intentionally monomorphic: a `Release` holds a `vector<Track>` of
25
+ * tracks from many different recordings/compositions, so it cannot be generic over
26
+ * their share types. It stores no title, cover art, or share-type — those are
27
+ * consumed off-chain and derived from the recording via `recording_id`; a `Track`
28
+ * embeds exactly the facts on-chain consumers cannot reach any other way.
29
+ */
30
+
31
+ import { MoveEnum, MoveStruct, normalizeMoveArguments, type RawTransactionArgument } from '../utils/index.ts';
32
+ import { bcs } from '@mysten/sui/bcs';
33
+ import type {} from "@mysten/bcs";
34
+ import { type Transaction, type TransactionArgument } from '@mysten/sui/transactions';
35
+ import * as bps from './deps/bps/bps.ts';
36
+ const $moduleName = '@local-pkg/musicos::track';
37
+ /**
38
+ * Lifecycle state of a track within a release. A track is born `Unassigned`,
39
+ * carrying the target release id the consent committed to at creation (the release
40
+ * id is a digest of the whole tracklist, so this is the recording owner's consent
41
+ * to the exact release configuration). At publish the release verifies the match
42
+ * and transitions the track to `Assigned`, which carries no id — shedding the
43
+ * 32-byte commitment once it has served its purpose.
44
+ */
45
+ export const TrackState = new MoveEnum({ name: `${$moduleName}::TrackState`, fields: {
46
+ /**
47
+ * Track has been created but not yet assigned to a release. Carries the target
48
+ * release id the consent committed to at creation.
49
+ */
50
+ Unassigned: bcs.Address,
51
+ /** Track has been assigned to its target release. */
52
+ Assigned: null
53
+ } });
54
+ export const Track = new MoveStruct({ name: `${$moduleName}::Track`, fields: {
55
+ /** Current state of the track. */
56
+ state: TrackState,
57
+ /**
58
+ * ID of the composition underlying this track's recording. An identity and
59
+ * membership handle — NOT a revenue routing target: the composition is paid
60
+ * through its recording-share ownership (settled at `recording::new`), so a track
61
+ * routes its full split to the recording. Immutable and safe to denormalize: the
62
+ * recording↔composition pairing is fixed at recording creation.
63
+ */
64
+ composition_id: bcs.Address,
65
+ /**
66
+ * ID of the recording on this track. The routing target for the track's revenue;
67
+ * also the handle a consumer uses to fetch the recording (whose type carries the
68
+ * recording and composition share-type identities).
69
+ */
70
+ recording_id: bcs.Address,
71
+ /**
72
+ * This track's share of the release's revenue, in basis points. All tracks in a
73
+ * release sum to 100%. The composition's cut is settled as recording-share
74
+ * ownership at recording creation, so it is not split out here — a track routes
75
+ * its full share to the recording.
76
+ */
77
+ split_bps: bps.BPS
78
+ } });
79
+ export interface NewArguments {
80
+ _: RawTransactionArgument<string>;
81
+ recording: RawTransactionArgument<string>;
82
+ targetReleaseId: RawTransactionArgument<string>;
83
+ trackSplitBpsValue: RawTransactionArgument<number>;
84
+ }
85
+ export interface NewOptions {
86
+ package?: string;
87
+ arguments: NewArguments | [
88
+ _: RawTransactionArgument<string>,
89
+ recording: RawTransactionArgument<string>,
90
+ targetReleaseId: RawTransactionArgument<string>,
91
+ trackSplitBpsValue: RawTransactionArgument<number>
92
+ ];
93
+ typeArguments: [
94
+ string,
95
+ string
96
+ ];
97
+ }
98
+ /**
99
+ * Creates a new track: the recording admin's consent to that recording's inclusion
100
+ * in a specific future release with an agreed split. Requires the recording admin
101
+ * capability. No event: a `Track` has `drop` and is not an object, so a creation
102
+ * event could announce a consent that is then silently discarded, and indexers
103
+ * would be unable to distinguish pending from dead. Pre-publish observability is
104
+ * the responsibility of whatever wraps the track (see below).
105
+ *
106
+ * The recording↔composition pairing is compile-time enforced by the recording's
107
+ * `CompositionShare` phantom, and its address-level counterpart is embedded on the
108
+ * recording at creation — so the composition id is copied from the `&Recording`
109
+ * argument with no `Composition` argument and no runtime check needed.
110
+ *
111
+ * ### What creating a track consents to
112
+ *
113
+ * `target_release_id` is derived from the release digest, so targeting it consents
114
+ * to that release's exact economics and membership: the ordered list of
115
+ * `(recording, split)` pairs and the creator's nonce, nothing more. The release's
116
+ * title, artwork, credits, and display grouping are chosen by the release creator
117
+ * — before or after this track is created — and are not bound by the digest.
118
+ * Presentation is trusted and publicly attributable, not cryptographically
119
+ * committed.
120
+ *
121
+ * The recording need not be `Published`: its admin can create tracks inside the
122
+ * recording's own creating transaction (an `Initialized` recording cannot escape
123
+ * that transaction, so across transactions tracks always reference `Published`,
124
+ * shared recordings).
125
+ *
126
+ * A `Track` has `store`, not `key`: it carries no identity of its own, so it may
127
+ * be exercised synchronously in the same transaction that creates it, or handed to
128
+ * an offer extension that wraps it in a real object with its own identity.
129
+ * Withdrawal, expiry, and rejection are then whatever that wrapping extension
130
+ * encodes — visible in its type, not in core.
131
+ *
132
+ * `recording` compile-time-binds the `RecordingShare`/`CompositionShare` phantom
133
+ * pairing, and is read for its own id and its embedded composition id: the
134
+ * monomorphic `Track` must store both _addresses_ — the recording's for revenue
135
+ * routing, the composition's for graph reachability — and an address cannot come
136
+ * from a phantom.
137
+ */
138
+ export function _new(options: NewOptions) {
139
+ const packageAddress = options.package ?? '@local-pkg/musicos';
140
+ const argumentsTypes = [
141
+ null,
142
+ null,
143
+ '0x2::object::ID',
144
+ 'u16'
145
+ ] satisfies (string | null)[];
146
+ const parameterNames = ["_", "recording", "targetReleaseId", "trackSplitBpsValue"];
147
+ return (tx: Transaction) => tx.moveCall({
148
+ package: packageAddress,
149
+ module: 'track',
150
+ function: 'new',
151
+ arguments: normalizeMoveArguments(options.arguments, argumentsTypes, parameterNames),
152
+ typeArguments: options.typeArguments
153
+ });
154
+ }
155
+ export interface RecordingIdArguments {
156
+ self: TransactionArgument;
157
+ }
158
+ export interface RecordingIdOptions {
159
+ package?: string;
160
+ arguments: RecordingIdArguments | [
161
+ self: TransactionArgument
162
+ ];
163
+ }
164
+ /** Returns the ID of the recording. */
165
+ export function recordingId(options: RecordingIdOptions) {
166
+ const packageAddress = options.package ?? '@local-pkg/musicos';
167
+ const argumentsTypes = [
168
+ null
169
+ ] satisfies (string | null)[];
170
+ const parameterNames = ["self"];
171
+ return (tx: Transaction) => tx.moveCall({
172
+ package: packageAddress,
173
+ module: 'track',
174
+ function: 'recording_id',
175
+ arguments: normalizeMoveArguments(options.arguments, argumentsTypes, parameterNames),
176
+ });
177
+ }
178
+ export interface CompositionIdArguments {
179
+ self: TransactionArgument;
180
+ }
181
+ export interface CompositionIdOptions {
182
+ package?: string;
183
+ arguments: CompositionIdArguments | [
184
+ self: TransactionArgument
185
+ ];
186
+ }
187
+ /**
188
+ * Returns the ID of the composition underlying this track's recording. An
189
+ * identity/membership handle (e.g. "is this composition on this release?") — not a
190
+ * revenue routing target: the composition is paid via its recording-share
191
+ * ownership, and a track routes its full split to the recording.
192
+ */
193
+ export function compositionId(options: CompositionIdOptions) {
194
+ const packageAddress = options.package ?? '@local-pkg/musicos';
195
+ const argumentsTypes = [
196
+ null
197
+ ] satisfies (string | null)[];
198
+ const parameterNames = ["self"];
199
+ return (tx: Transaction) => tx.moveCall({
200
+ package: packageAddress,
201
+ module: 'track',
202
+ function: 'composition_id',
203
+ arguments: normalizeMoveArguments(options.arguments, argumentsTypes, parameterNames),
204
+ });
205
+ }
206
+ export interface SplitBpsArguments {
207
+ self: TransactionArgument;
208
+ }
209
+ export interface SplitBpsOptions {
210
+ package?: string;
211
+ arguments: SplitBpsArguments | [
212
+ self: TransactionArgument
213
+ ];
214
+ }
215
+ /** Returns this track's share of the release's revenue (in basis points). */
216
+ export function splitBps(options: SplitBpsOptions) {
217
+ const packageAddress = options.package ?? '@local-pkg/musicos';
218
+ const argumentsTypes = [
219
+ null
220
+ ] satisfies (string | null)[];
221
+ const parameterNames = ["self"];
222
+ return (tx: Transaction) => tx.moveCall({
223
+ package: packageAddress,
224
+ module: 'track',
225
+ function: 'split_bps',
226
+ arguments: normalizeMoveArguments(options.arguments, argumentsTypes, parameterNames),
227
+ });
228
+ }
229
+ export interface TargetReleaseIdArguments {
230
+ self: TransactionArgument;
231
+ }
232
+ export interface TargetReleaseIdOptions {
233
+ package?: string;
234
+ arguments: TargetReleaseIdArguments | [
235
+ self: TransactionArgument
236
+ ];
237
+ }
238
+ /**
239
+ * Returns the target release id this track's creator consented to. Aborts if the
240
+ * track is `Assigned`: an assigned track only exists inside a published release,
241
+ * so its release is the object you fetched it from.
242
+ */
243
+ export function targetReleaseId(options: TargetReleaseIdOptions) {
244
+ const packageAddress = options.package ?? '@local-pkg/musicos';
245
+ const argumentsTypes = [
246
+ null
247
+ ] satisfies (string | null)[];
248
+ const parameterNames = ["self"];
249
+ return (tx: Transaction) => tx.moveCall({
250
+ package: packageAddress,
251
+ module: 'track',
252
+ function: 'target_release_id',
253
+ arguments: normalizeMoveArguments(options.arguments, argumentsTypes, parameterNames),
254
+ });
255
+ }