@misonetwork/sdk 0.6.0 → 0.7.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.
- package/README.md +18 -3
- package/dist/client.d.ts +4 -7
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +0 -2
- package/dist/client.js.map +1 -1
- package/dist/contracts/miso/composition.d.ts +16 -38
- package/dist/contracts/miso/composition.d.ts.map +1 -1
- package/dist/contracts/miso/composition.js +16 -37
- package/dist/contracts/miso/composition.js.map +1 -1
- package/dist/contracts/miso/recording.d.ts +43 -18
- package/dist/contracts/miso/recording.d.ts.map +1 -1
- package/dist/contracts/miso/recording.js +45 -19
- package/dist/contracts/miso/recording.js.map +1 -1
- package/dist/contracts/miso/release.d.ts +2 -0
- package/dist/contracts/miso/release.d.ts.map +1 -1
- package/dist/contracts/miso/track.d.ts +39 -8
- package/dist/contracts/miso/track.d.ts.map +1 -1
- package/dist/contracts/miso/track.js +42 -8
- package/dist/contracts/miso/track.js.map +1 -1
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +2 -0
- package/dist/internal.js.map +1 -1
- package/dist/parsers.d.ts +1 -2
- package/dist/parsers.d.ts.map +1 -1
- package/dist/parsers.js +1 -5
- package/dist/parsers.js.map +1 -1
- package/dist/transactions.d.ts +0 -9
- package/dist/transactions.d.ts.map +1 -1
- package/dist/transactions.js +1 -3
- package/dist/transactions.js.map +1 -1
- package/dist/types.d.ts +17 -8
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/client.ts +0 -2
- package/src/contracts/miso/composition.ts +16 -53
- package/src/contracts/miso/recording.ts +59 -22
- package/src/contracts/miso/track.ts +51 -8
- package/src/internal.ts +2 -0
- package/src/parsers.ts +1 -10
- package/src/transactions.ts +1 -11
- package/src/types.ts +17 -9
|
@@ -45,14 +45,15 @@
|
|
|
45
45
|
* the one trust assumption that never expires: integrators should model the cap
|
|
46
46
|
* holder as able to mutate or delete any extension data, forever.
|
|
47
47
|
*
|
|
48
|
-
* The recording carries its parent composition's identity
|
|
49
|
-
* `CompositionShare` phantom type parameter
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
48
|
+
* The recording carries its parent composition's identity two ways. The
|
|
49
|
+
* `CompositionShare` phantom type parameter is the durable identity (a share
|
|
50
|
+
* currency is published independently of miso and survives a fresh republish,
|
|
51
|
+
* whereas an object ID does not) and makes the recording↔composition lineage
|
|
52
|
+
* compile-time enforced wherever the two meet. The embedded `composition_id` is
|
|
53
|
+
* the address-level handle: Move cannot chase a type (or an ID) to an object, so
|
|
54
|
+
* on-chain consumers holding only `&Recording` — or a bare `Track` — could not
|
|
55
|
+
* otherwise reach the composition at all. Both are set at creation and immutable,
|
|
56
|
+
* so they cannot diverge.
|
|
56
57
|
*
|
|
57
58
|
* A recording is its own freshly-created object (`object::new`), not a derived
|
|
58
59
|
* child of its composition: `recording::new` takes a read-only `&Composition`
|
|
@@ -76,7 +77,15 @@ export const Recording = new MoveStruct({ name: `${$moduleName}::Recording<phant
|
|
|
76
77
|
/** Unique identifier for this recording. */
|
|
77
78
|
id: bcs.Address,
|
|
78
79
|
/** Current lifecycle state. */
|
|
79
|
-
state: RecordingState
|
|
80
|
+
state: RecordingState,
|
|
81
|
+
/**
|
|
82
|
+
* Object ID of the parent composition. The address-level counterpart of the
|
|
83
|
+
* `CompositionShare` phantom, set from the `&Composition` passed to `new` (the
|
|
84
|
+
* shared phantom proves the pairing). An identity handle — not a revenue routing
|
|
85
|
+
* target: the composition is paid through its recording-share ownership, settled
|
|
86
|
+
* at creation.
|
|
87
|
+
*/
|
|
88
|
+
composition_id: bcs.Address
|
|
80
89
|
} });
|
|
81
90
|
export const RecordingAdminCap = new MoveStruct({ name: `${$moduleName}::RecordingAdminCap<phantom RecordingShare>`, fields: {
|
|
82
91
|
/** Unique identifier for this capability. */
|
|
@@ -99,15 +108,13 @@ export interface NewArguments {
|
|
|
99
108
|
composition: RawTransactionArgument<string>;
|
|
100
109
|
shareCurrency: RawTransactionArgument<string>;
|
|
101
110
|
shareTreasuryCap: RawTransactionArgument<string>;
|
|
102
|
-
maxRoyaltyRateBps: RawTransactionArgument<number>;
|
|
103
111
|
}
|
|
104
112
|
export interface NewOptions {
|
|
105
113
|
package?: string;
|
|
106
114
|
arguments: NewArguments | [
|
|
107
115
|
composition: RawTransactionArgument<string>,
|
|
108
116
|
shareCurrency: RawTransactionArgument<string>,
|
|
109
|
-
shareTreasuryCap: RawTransactionArgument<string
|
|
110
|
-
maxRoyaltyRateBps: RawTransactionArgument<number>
|
|
117
|
+
shareTreasuryCap: RawTransactionArgument<string>
|
|
111
118
|
];
|
|
112
119
|
typeArguments: [
|
|
113
120
|
string,
|
|
@@ -126,13 +133,11 @@ export interface NewOptions {
|
|
|
126
133
|
* composition owner then does with the shares (hold, stake, sell) is outside the
|
|
127
134
|
* protocol's scope.
|
|
128
135
|
*
|
|
129
|
-
*
|
|
130
|
-
*
|
|
131
|
-
*
|
|
132
|
-
*
|
|
133
|
-
*
|
|
134
|
-
* will grant (pass the rate they observed, or `2000` to accept up to the protocol
|
|
135
|
-
* maximum).
|
|
136
|
+
* The composition's royalty rate is immutable, so the rate a recorder's client
|
|
137
|
+
* displayed is exactly the rate applied here — no slippage protection is needed or
|
|
138
|
+
* possible. Whether that rate is acceptable is the recorder's decision to make
|
|
139
|
+
* before calling; per-deal deviations settle as voluntary share transfers after
|
|
140
|
+
* creation.
|
|
136
141
|
*
|
|
137
142
|
* The composition need not be `Published`: within the composition's own creating
|
|
138
143
|
* transaction its creator can already mint recordings against it. Third parties
|
|
@@ -153,10 +158,9 @@ export function _new(options: NewOptions) {
|
|
|
153
158
|
const argumentsTypes = [
|
|
154
159
|
null,
|
|
155
160
|
null,
|
|
156
|
-
null
|
|
157
|
-
'u16'
|
|
161
|
+
null
|
|
158
162
|
] satisfies (string | null)[];
|
|
159
|
-
const parameterNames = ["composition", "shareCurrency", "shareTreasuryCap"
|
|
163
|
+
const parameterNames = ["composition", "shareCurrency", "shareTreasuryCap"];
|
|
160
164
|
return (tx: Transaction) => tx.moveCall({
|
|
161
165
|
package: packageAddress,
|
|
162
166
|
module: 'recording',
|
|
@@ -203,6 +207,39 @@ export function publish(options: PublishOptions) {
|
|
|
203
207
|
typeArguments: options.typeArguments
|
|
204
208
|
});
|
|
205
209
|
}
|
|
210
|
+
export interface CompositionIdArguments {
|
|
211
|
+
self: RawTransactionArgument<string>;
|
|
212
|
+
}
|
|
213
|
+
export interface CompositionIdOptions {
|
|
214
|
+
package?: string;
|
|
215
|
+
arguments: CompositionIdArguments | [
|
|
216
|
+
self: RawTransactionArgument<string>
|
|
217
|
+
];
|
|
218
|
+
typeArguments: [
|
|
219
|
+
string,
|
|
220
|
+
string
|
|
221
|
+
];
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Returns the object ID of the parent composition. An identity/membership handle
|
|
225
|
+
* (the address-level counterpart of the `CompositionShare` phantom) — not a
|
|
226
|
+
* revenue routing target: the composition is paid via its recording-share
|
|
227
|
+
* ownership.
|
|
228
|
+
*/
|
|
229
|
+
export function compositionId(options: CompositionIdOptions) {
|
|
230
|
+
const packageAddress = options.package ?? '@local-pkg/miso';
|
|
231
|
+
const argumentsTypes = [
|
|
232
|
+
null
|
|
233
|
+
] satisfies (string | null)[];
|
|
234
|
+
const parameterNames = ["self"];
|
|
235
|
+
return (tx: Transaction) => tx.moveCall({
|
|
236
|
+
package: packageAddress,
|
|
237
|
+
module: 'recording',
|
|
238
|
+
function: 'composition_id',
|
|
239
|
+
arguments: normalizeMoveArguments(options.arguments, argumentsTypes, parameterNames),
|
|
240
|
+
typeArguments: options.typeArguments
|
|
241
|
+
});
|
|
242
|
+
}
|
|
206
243
|
export interface IdArguments {
|
|
207
244
|
self: RawTransactionArgument<string>;
|
|
208
245
|
}
|
|
@@ -12,6 +12,10 @@
|
|
|
12
12
|
* - `recording_id` — the routing target for the track's revenue, and the handle
|
|
13
13
|
* through which all other metadata (title, cover art, and the
|
|
14
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.
|
|
15
19
|
* - `split_bps` — this track's share of the release's revenue; genuinely
|
|
16
20
|
* release-specific and not derivable from the recording.
|
|
17
21
|
* - `state` — the assign-once lifecycle that carries (then sheds) the recording
|
|
@@ -19,8 +23,9 @@
|
|
|
19
23
|
*
|
|
20
24
|
* `Track` is intentionally monomorphic: a `Release` holds a `vector<Track>` of
|
|
21
25
|
* tracks from many different recordings/compositions, so it cannot be generic over
|
|
22
|
-
* their share types. It stores no title, cover art, or share-type —
|
|
23
|
-
* from the recording via `recording_id
|
|
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.
|
|
24
29
|
*/
|
|
25
30
|
|
|
26
31
|
import { MoveEnum, MoveStruct, normalizeMoveArguments, type RawTransactionArgument } from '../utils/index.js';
|
|
@@ -48,6 +53,14 @@ export const TrackState = new MoveEnum({ name: `${$moduleName}::TrackState`, fie
|
|
|
48
53
|
export const Track = new MoveStruct({ name: `${$moduleName}::Track`, fields: {
|
|
49
54
|
/** Current state of the track. */
|
|
50
55
|
state: TrackState,
|
|
56
|
+
/**
|
|
57
|
+
* ID of the composition underlying this track's recording. An identity and
|
|
58
|
+
* membership handle — NOT a revenue routing target: the composition is paid
|
|
59
|
+
* through its recording-share ownership (settled at `recording::new`), so a track
|
|
60
|
+
* routes its full split to the recording. Immutable and safe to denormalize: the
|
|
61
|
+
* recording↔composition pairing is fixed at recording creation.
|
|
62
|
+
*/
|
|
63
|
+
composition_id: bcs.Address,
|
|
51
64
|
/**
|
|
52
65
|
* ID of the recording on this track. The routing target for the track's revenue;
|
|
53
66
|
* also the handle a consumer uses to fetch the recording (whose type carries the
|
|
@@ -89,9 +102,10 @@ export interface NewOptions {
|
|
|
89
102
|
* would be unable to distinguish pending from dead. Pre-publish observability is
|
|
90
103
|
* the responsibility of whatever wraps the track (see below).
|
|
91
104
|
*
|
|
92
|
-
* The composition is
|
|
93
|
-
*
|
|
94
|
-
*
|
|
105
|
+
* The recording↔composition pairing is compile-time enforced by the recording's
|
|
106
|
+
* `CompositionShare` phantom, and its address-level counterpart is embedded on the
|
|
107
|
+
* recording at creation — so the composition id is copied from the `&Recording`
|
|
108
|
+
* argument with no `Composition` argument and no runtime check needed.
|
|
95
109
|
*
|
|
96
110
|
* ### What creating a track consents to
|
|
97
111
|
*
|
|
@@ -115,9 +129,10 @@ export interface NewOptions {
|
|
|
115
129
|
* encodes — visible in its type, not in core.
|
|
116
130
|
*
|
|
117
131
|
* `recording` compile-time-binds the `RecordingShare`/`CompositionShare` phantom
|
|
118
|
-
* pairing, and is read for its id
|
|
119
|
-
*
|
|
120
|
-
*
|
|
132
|
+
* pairing, and is read for its own id and its embedded composition id: the
|
|
133
|
+
* monomorphic `Track` must store both _addresses_ — the recording's for revenue
|
|
134
|
+
* routing, the composition's for graph reachability — and an address cannot come
|
|
135
|
+
* from a phantom.
|
|
121
136
|
*/
|
|
122
137
|
export function _new(options: NewOptions) {
|
|
123
138
|
const packageAddress = options.package ?? '@local-pkg/miso';
|
|
@@ -159,6 +174,34 @@ export function recordingId(options: RecordingIdOptions) {
|
|
|
159
174
|
arguments: normalizeMoveArguments(options.arguments, argumentsTypes, parameterNames),
|
|
160
175
|
});
|
|
161
176
|
}
|
|
177
|
+
export interface CompositionIdArguments {
|
|
178
|
+
self: TransactionArgument;
|
|
179
|
+
}
|
|
180
|
+
export interface CompositionIdOptions {
|
|
181
|
+
package?: string;
|
|
182
|
+
arguments: CompositionIdArguments | [
|
|
183
|
+
self: TransactionArgument
|
|
184
|
+
];
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Returns the ID of the composition underlying this track's recording. An
|
|
188
|
+
* identity/membership handle (e.g. "is this composition on this release?") — not a
|
|
189
|
+
* revenue routing target: the composition is paid via its recording-share
|
|
190
|
+
* ownership, and a track routes its full split to the recording.
|
|
191
|
+
*/
|
|
192
|
+
export function compositionId(options: CompositionIdOptions) {
|
|
193
|
+
const packageAddress = options.package ?? '@local-pkg/miso';
|
|
194
|
+
const argumentsTypes = [
|
|
195
|
+
null
|
|
196
|
+
] satisfies (string | null)[];
|
|
197
|
+
const parameterNames = ["self"];
|
|
198
|
+
return (tx: Transaction) => tx.moveCall({
|
|
199
|
+
package: packageAddress,
|
|
200
|
+
module: 'track',
|
|
201
|
+
function: 'composition_id',
|
|
202
|
+
arguments: normalizeMoveArguments(options.arguments, argumentsTypes, parameterNames),
|
|
203
|
+
});
|
|
204
|
+
}
|
|
162
205
|
export interface SplitBpsArguments {
|
|
163
206
|
self: TransactionArgument;
|
|
164
207
|
}
|
package/src/internal.ts
CHANGED
|
@@ -59,12 +59,14 @@ export function mapRecording(id: string, d: Parsed): Recording {
|
|
|
59
59
|
return {
|
|
60
60
|
id,
|
|
61
61
|
state: mapState(d.state),
|
|
62
|
+
compositionId: d.composition_id,
|
|
62
63
|
};
|
|
63
64
|
}
|
|
64
65
|
|
|
65
66
|
export function mapTrack(d: Parsed): Track {
|
|
66
67
|
return {
|
|
67
68
|
state: (d.state?.$kind ?? "Unassigned") as TrackState,
|
|
69
|
+
compositionId: d.composition_id,
|
|
68
70
|
recordingId: d.recording_id,
|
|
69
71
|
splitBps: mapBps(d.split_bps),
|
|
70
72
|
};
|
package/src/parsers.ts
CHANGED
|
@@ -5,15 +5,11 @@
|
|
|
5
5
|
// they track the on-chain ABI automatically); these functions parse raw event
|
|
6
6
|
// bytes and map them to the public camelCase event types.
|
|
7
7
|
|
|
8
|
-
import {
|
|
9
|
-
CompositionPublishedEvent as CompositionPublishedEventBcs,
|
|
10
|
-
CompositionRoyaltySetEvent as CompositionRoyaltySetEventBcs,
|
|
11
|
-
} from "./contracts/miso/composition.ts";
|
|
8
|
+
import { CompositionPublishedEvent as CompositionPublishedEventBcs } from "./contracts/miso/composition.ts";
|
|
12
9
|
import { RecordingPublishedEvent as RecordingPublishedEventBcs } from "./contracts/miso/recording.ts";
|
|
13
10
|
import { ReleasePublishedEvent as ReleasePublishedEventBcs } from "./contracts/miso/release.ts";
|
|
14
11
|
import type {
|
|
15
12
|
CompositionPublishedEvent,
|
|
16
|
-
CompositionRoyaltySetEvent,
|
|
17
13
|
RecordingPublishedEvent,
|
|
18
14
|
ReleasePublishedEvent,
|
|
19
15
|
} from "./types.ts";
|
|
@@ -25,11 +21,6 @@ export function parseCompositionPublishedEvent(bytes: Uint8Array): CompositionPu
|
|
|
25
21
|
return { compositionId: e.composition_id };
|
|
26
22
|
}
|
|
27
23
|
|
|
28
|
-
export function parseCompositionRoyaltySetEvent(bytes: Uint8Array): CompositionRoyaltySetEvent {
|
|
29
|
-
const e = CompositionRoyaltySetEventBcs.parse(bytes);
|
|
30
|
-
return { royaltyRateBps: e.royalty_rate_bps };
|
|
31
|
-
}
|
|
32
|
-
|
|
33
24
|
// === Recording ===
|
|
34
25
|
|
|
35
26
|
export function parseRecordingPublishedEvent(bytes: Uint8Array): RecordingPublishedEvent {
|
package/src/transactions.ts
CHANGED
|
@@ -110,9 +110,6 @@ export interface RecordingParts {
|
|
|
110
110
|
balance: TransactionObjectArgument;
|
|
111
111
|
}
|
|
112
112
|
|
|
113
|
-
/** The protocol's maximum composition royalty rate (`MAX_ROYALTY_RATE_BPS`). */
|
|
114
|
-
export const PROTOCOL_MAX_ROYALTY_RATE_BPS = 2000;
|
|
115
|
-
|
|
116
113
|
export interface CreateRecordingParams extends ShareCurrencyBinding {
|
|
117
114
|
/** Share type of the parent composition (the recording's `CompositionShare` phantom). */
|
|
118
115
|
compositionShareType: string;
|
|
@@ -122,13 +119,6 @@ export interface CreateRecordingParams extends ShareCurrencyBinding {
|
|
|
122
119
|
* unshared, transaction-local `createComposition(...).composition` result.
|
|
123
120
|
*/
|
|
124
121
|
composition: TransactionObjectArgument;
|
|
125
|
-
/**
|
|
126
|
-
* Slippage guard: the maximum composition royalty rate (bps) the recorder will
|
|
127
|
-
* grant — `recording::new` aborts if the composition's live rate exceeds it.
|
|
128
|
-
* Pass the rate you observed. Defaults to the protocol maximum (2000), which
|
|
129
|
-
* accepts any legal rate.
|
|
130
|
-
*/
|
|
131
|
-
maxRoyaltyRateBps?: number;
|
|
132
122
|
misoPackageId: string;
|
|
133
123
|
}
|
|
134
124
|
|
|
@@ -144,7 +134,7 @@ export function createRecording(tx: Transaction, params: CreateRecordingParams):
|
|
|
144
134
|
recording._new({
|
|
145
135
|
package: params.misoPackageId,
|
|
146
136
|
typeArguments: [params.shareType, params.compositionShareType],
|
|
147
|
-
arguments: [params.composition, tx.object(params.shareCurrencyId), tx.object(params.shareTreasuryCapId)
|
|
137
|
+
arguments: [params.composition, tx.object(params.shareCurrencyId), tx.object(params.shareTreasuryCapId)],
|
|
148
138
|
}),
|
|
149
139
|
);
|
|
150
140
|
return { recording: result[0]!, adminCap: result[1]!, balance: result[2]! };
|
package/src/types.ts
CHANGED
|
@@ -35,7 +35,10 @@ export interface Composition {
|
|
|
35
35
|
state: CompositionState;
|
|
36
36
|
/** Primary title of the composition. */
|
|
37
37
|
title: string;
|
|
38
|
-
/**
|
|
38
|
+
/**
|
|
39
|
+
* Royalty rate this composition earns from each recording's revenue (basis
|
|
40
|
+
* points, 0-10000). Immutable for the composition's lifetime.
|
|
41
|
+
*/
|
|
39
42
|
royaltyRate: BPS;
|
|
40
43
|
}
|
|
41
44
|
|
|
@@ -48,14 +51,6 @@ export interface CompositionPublishedEvent {
|
|
|
48
51
|
compositionId: string;
|
|
49
52
|
}
|
|
50
53
|
|
|
51
|
-
/**
|
|
52
|
-
* Emitted when a composition's royalty rate is set or changed. The composition
|
|
53
|
-
* is identified by the event's `CompositionShare` phantom type, not a field.
|
|
54
|
-
*/
|
|
55
|
-
export interface CompositionRoyaltySetEvent {
|
|
56
|
-
royaltyRateBps: number;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
54
|
/**
|
|
60
55
|
* Admin cap for a Composition, derived deterministically from the Composition object ID.
|
|
61
56
|
*
|
|
@@ -96,6 +91,12 @@ export interface Recording {
|
|
|
96
91
|
id: string;
|
|
97
92
|
/** Current lifecycle state. */
|
|
98
93
|
state: RecordingState;
|
|
94
|
+
/**
|
|
95
|
+
* Object ID of the parent composition. An identity/membership handle — not a
|
|
96
|
+
* revenue routing target: the composition is paid via its recording-share
|
|
97
|
+
* ownership, settled at recording creation. Immutable.
|
|
98
|
+
*/
|
|
99
|
+
compositionId: string;
|
|
99
100
|
}
|
|
100
101
|
|
|
101
102
|
/**
|
|
@@ -135,6 +136,13 @@ export type TrackState = "Unassigned" | "Assigned";
|
|
|
135
136
|
export interface Track {
|
|
136
137
|
/** Current state of the track (Unassigned until the release claims it, then Assigned). */
|
|
137
138
|
state: TrackState;
|
|
139
|
+
/**
|
|
140
|
+
* ID of the composition underlying this track's recording. An identity/
|
|
141
|
+
* membership handle — not a revenue routing target: the composition is paid
|
|
142
|
+
* via its recording-share ownership, and a track routes its full split to the
|
|
143
|
+
* recording.
|
|
144
|
+
*/
|
|
145
|
+
compositionId: string;
|
|
138
146
|
/** ID of the recording on this track. */
|
|
139
147
|
recordingId: string;
|
|
140
148
|
/** Revenue split for this track within the release (in basis points). */
|