@misonetwork/sdk 0.5.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 +23 -4
- package/dist/client.d.ts +24 -13
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +25 -8
- 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/deployments.d.ts +21 -0
- package/dist/deployments.d.ts.map +1 -0
- package/dist/deployments.js +17 -0
- package/dist/deployments.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.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 +5 -1
- package/src/client.ts +46 -12
- 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/deployments.ts +42 -0
- package/src/index.ts +1 -0
- package/src/internal.ts +2 -0
- package/src/parsers.ts +1 -10
- package/src/transactions.ts +1 -11
- package/src/types.ts +17 -9
package/dist/types.d.ts
CHANGED
|
@@ -25,7 +25,10 @@ export interface Composition {
|
|
|
25
25
|
state: CompositionState;
|
|
26
26
|
/** Primary title of the composition. */
|
|
27
27
|
title: string;
|
|
28
|
-
/**
|
|
28
|
+
/**
|
|
29
|
+
* Royalty rate this composition earns from each recording's revenue (basis
|
|
30
|
+
* points, 0-10000). Immutable for the composition's lifetime.
|
|
31
|
+
*/
|
|
29
32
|
royaltyRate: BPS;
|
|
30
33
|
}
|
|
31
34
|
/**
|
|
@@ -36,13 +39,6 @@ export interface Composition {
|
|
|
36
39
|
export interface CompositionPublishedEvent {
|
|
37
40
|
compositionId: string;
|
|
38
41
|
}
|
|
39
|
-
/**
|
|
40
|
-
* Emitted when a composition's royalty rate is set or changed. The composition
|
|
41
|
-
* is identified by the event's `CompositionShare` phantom type, not a field.
|
|
42
|
-
*/
|
|
43
|
-
export interface CompositionRoyaltySetEvent {
|
|
44
|
-
royaltyRateBps: number;
|
|
45
|
-
}
|
|
46
42
|
/**
|
|
47
43
|
* Admin cap for a Composition, derived deterministically from the Composition object ID.
|
|
48
44
|
*
|
|
@@ -80,6 +76,12 @@ export interface Recording {
|
|
|
80
76
|
id: string;
|
|
81
77
|
/** Current lifecycle state. */
|
|
82
78
|
state: RecordingState;
|
|
79
|
+
/**
|
|
80
|
+
* Object ID of the parent composition. An identity/membership handle — not a
|
|
81
|
+
* revenue routing target: the composition is paid via its recording-share
|
|
82
|
+
* ownership, settled at recording creation. Immutable.
|
|
83
|
+
*/
|
|
84
|
+
compositionId: string;
|
|
83
85
|
}
|
|
84
86
|
/**
|
|
85
87
|
* Emitted once when a recording is published. A pure pointer carrying only the
|
|
@@ -112,6 +114,13 @@ export type TrackState = "Unassigned" | "Assigned";
|
|
|
112
114
|
export interface Track {
|
|
113
115
|
/** Current state of the track (Unassigned until the release claims it, then Assigned). */
|
|
114
116
|
state: TrackState;
|
|
117
|
+
/**
|
|
118
|
+
* ID of the composition underlying this track's recording. An identity/
|
|
119
|
+
* membership handle — not a revenue routing target: the composition is paid
|
|
120
|
+
* via its recording-share ownership, and a track routes its full split to the
|
|
121
|
+
* recording.
|
|
122
|
+
*/
|
|
123
|
+
compositionId: string;
|
|
115
124
|
/** ID of the recording on this track. */
|
|
116
125
|
recordingId: string;
|
|
117
126
|
/** Revenue split for this track within the release (in basis points). */
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAOA,wDAAwD;AACxD,MAAM,WAAW,GAAG;IAClB,KAAK,EAAE,MAAM,CAAC;CACf;AAMD,wCAAwC;AACxC,MAAM,MAAM,gBAAgB,GACxB;IAAE,IAAI,EAAE,aAAa,CAAA;CAAE,GACvB;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAAC;AAE/C;;;;;;;;GAQG;AACH,MAAM,WAAW,WAAW;IAC1B,8CAA8C;IAC9C,EAAE,EAAE,MAAM,CAAC;IACX,+BAA+B;IAC/B,KAAK,EAAE,gBAAgB,CAAC;IACxB,wCAAwC;IACxC,KAAK,EAAE,MAAM,CAAC;IACd
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAOA,wDAAwD;AACxD,MAAM,WAAW,GAAG;IAClB,KAAK,EAAE,MAAM,CAAC;CACf;AAMD,wCAAwC;AACxC,MAAM,MAAM,gBAAgB,GACxB;IAAE,IAAI,EAAE,aAAa,CAAA;CAAE,GACvB;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAAC;AAE/C;;;;;;;;GAQG;AACH,MAAM,WAAW,WAAW;IAC1B,8CAA8C;IAC9C,EAAE,EAAE,MAAM,CAAC;IACX,+BAA+B;IAC/B,KAAK,EAAE,gBAAgB,CAAC;IACxB,wCAAwC;IACxC,KAAK,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,WAAW,EAAE,GAAG,CAAC;CAClB;AAED;;;;GAIG;AACH,MAAM,WAAW,yBAAyB;IACxC,aAAa,EAAE,MAAM,CAAC;CACvB;AAED;;;;;GAKG;AACH,MAAM,WAAW,mBAAmB;IAClC,sCAAsC;IACtC,EAAE,EAAE,MAAM,CAAC;IACX,8DAA8D;IAC9D,SAAS,EAAE,MAAM,CAAC;CACnB;AAMD,sCAAsC;AACtC,MAAM,MAAM,cAAc,GACtB;IAAE,IAAI,EAAE,aAAa,CAAA;CAAE,GACvB;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAAC;AAE/C;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,SAAS;IACxB,4CAA4C;IAC5C,EAAE,EAAE,MAAM,CAAC;IACX,+BAA+B;IAC/B,KAAK,EAAE,cAAc,CAAC;IACtB;;;;OAIG;IACH,aAAa,EAAE,MAAM,CAAC;CACvB;AAED;;;;GAIG;AACH,MAAM,WAAW,uBAAuB;IACtC,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;;;;GAKG;AACH,MAAM,WAAW,iBAAiB;IAChC,sCAAsC;IACtC,EAAE,EAAE,MAAM,CAAC;IACX,4DAA4D;IAC5D,SAAS,EAAE,MAAM,CAAC;CACnB;AAKD,+CAA+C;AAC/C,MAAM,MAAM,UAAU,GAAG,YAAY,GAAG,UAAU,CAAC;AAEnD;;;;;GAKG;AACH,MAAM,WAAW,KAAK;IACpB,0FAA0F;IAC1F,KAAK,EAAE,UAAU,CAAC;IAClB;;;;;OAKG;IACH,aAAa,EAAE,MAAM,CAAC;IACtB,yCAAyC;IACzC,WAAW,EAAE,MAAM,CAAC;IACpB,yEAAyE;IACzE,QAAQ,EAAE,GAAG,CAAC;CACf;AAMD,oCAAoC;AACpC,MAAM,MAAM,YAAY,GACpB;IAAE,IAAI,EAAE,aAAa,CAAA;CAAE,GACvB;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAAC;AAE/C;;;;;;;;;GASG;AACH,MAAM,WAAW,OAAO;IACtB,0CAA0C;IAC1C,EAAE,EAAE,MAAM,CAAC;IACX,+BAA+B;IAC/B,KAAK,EAAE,YAAY,CAAC;IACpB,4BAA4B;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,6BAA6B;IAC7B,MAAM,EAAE,KAAK,EAAE,CAAC;CACjB;AAED;;;;GAIG;AACH,MAAM,WAAW,qBAAqB;IACpC,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;GAKG;AACH,MAAM,WAAW,eAAe;IAC9B,sCAAsC;IACtC,EAAE,EAAE,MAAM,CAAC;IACX,yDAAyD;IACzD,SAAS,EAAE,MAAM,CAAC;CACnB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@misonetwork/sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"description": "Typed query helpers and transaction builders for the Miso protocol core on Sui.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -44,6 +44,10 @@
|
|
|
44
44
|
"types": "./dist/client.d.ts",
|
|
45
45
|
"default": "./dist/client.js"
|
|
46
46
|
},
|
|
47
|
+
"./deployments": {
|
|
48
|
+
"types": "./dist/deployments.d.ts",
|
|
49
|
+
"default": "./dist/deployments.js"
|
|
50
|
+
},
|
|
47
51
|
"./queries": {
|
|
48
52
|
"types": "./dist/queries.d.ts",
|
|
49
53
|
"default": "./dist/queries.js"
|
package/src/client.ts
CHANGED
|
@@ -6,6 +6,10 @@ import type {
|
|
|
6
6
|
SuiClientRegistration,
|
|
7
7
|
} from "@mysten/sui/client";
|
|
8
8
|
import type { SuiGraphQLClient } from "@mysten/sui/graphql";
|
|
9
|
+
import {
|
|
10
|
+
getMisoProtocolDeployment,
|
|
11
|
+
type MisoProtocolDeployment,
|
|
12
|
+
} from "./deployments.ts";
|
|
9
13
|
import * as parsers from "./parsers.ts";
|
|
10
14
|
import * as queries from "./queries.ts";
|
|
11
15
|
import * as view from "./view.ts";
|
|
@@ -27,8 +31,13 @@ import * as track from "./contracts/miso/track.ts";
|
|
|
27
31
|
export interface MisoOptions<Name extends string = "miso"> {
|
|
28
32
|
/** Name for the client extension. Defaults to "miso". */
|
|
29
33
|
name?: Name;
|
|
30
|
-
/**
|
|
31
|
-
|
|
34
|
+
/**
|
|
35
|
+
* Complete custom deployment. Omit for bundled Mainnet/Testnet addresses,
|
|
36
|
+
* selected from the Sui client's `network`.
|
|
37
|
+
*/
|
|
38
|
+
deployment?: MisoProtocolDeployment;
|
|
39
|
+
/** @deprecated Use `deployment`. Retained for compatibility with pre-0.4 callers. */
|
|
40
|
+
misoPackageId?: string;
|
|
32
41
|
/**
|
|
33
42
|
* Optional GraphQL client, required ONLY for the global type-discovery reads
|
|
34
43
|
* the Core API cannot express: `getCompositionByShareType`,
|
|
@@ -57,29 +66,53 @@ function bindModulePackage<M extends object>(mod: M, pkg: string): M {
|
|
|
57
66
|
* @example
|
|
58
67
|
* ```ts
|
|
59
68
|
* const client = new SuiGrpcClient({ network: 'testnet' })
|
|
60
|
-
* .$extend(miso(
|
|
69
|
+
* .$extend(miso());
|
|
61
70
|
* const composition = await client.miso.getCompositionById('0x...');
|
|
62
71
|
* ```
|
|
63
72
|
*/
|
|
64
73
|
export function miso<const Name extends string = "miso">(
|
|
65
|
-
options: MisoOptions<Name
|
|
66
|
-
): SuiClientRegistration<ClientWithCoreApi, Name,
|
|
74
|
+
options: MisoOptions<Name> = {},
|
|
75
|
+
): SuiClientRegistration<ClientWithCoreApi, Name, MisoProtocolClient> {
|
|
67
76
|
const name = (options.name ?? "miso") as Name;
|
|
68
77
|
return {
|
|
69
78
|
name,
|
|
70
|
-
register: (client) =>
|
|
79
|
+
register: (client) => {
|
|
80
|
+
const deployment =
|
|
81
|
+
options.deployment ??
|
|
82
|
+
(options.misoPackageId
|
|
83
|
+
? { packageId: options.misoPackageId }
|
|
84
|
+
: getMisoProtocolDeployment(client.network));
|
|
85
|
+
return new MisoProtocolClient(client, {
|
|
86
|
+
deployment,
|
|
87
|
+
graphqlClient: options.graphqlClient,
|
|
88
|
+
});
|
|
89
|
+
},
|
|
71
90
|
};
|
|
72
91
|
}
|
|
73
92
|
|
|
74
|
-
export
|
|
93
|
+
export interface MisoProtocolClientOptions {
|
|
94
|
+
deployment: MisoProtocolDeployment;
|
|
95
|
+
graphqlClient?: SuiGraphQLClient;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export class MisoProtocolClient {
|
|
75
99
|
#client: ClientWithCoreApi;
|
|
76
100
|
#graphqlClient?: SuiGraphQLClient;
|
|
77
|
-
#
|
|
101
|
+
#deployment: MisoProtocolDeployment;
|
|
78
102
|
|
|
79
|
-
constructor(client: ClientWithCoreApi, options:
|
|
103
|
+
constructor(client: ClientWithCoreApi, options: MisoProtocolClientOptions) {
|
|
80
104
|
this.#client = client;
|
|
81
105
|
this.#graphqlClient = options.graphqlClient;
|
|
82
|
-
this.#
|
|
106
|
+
this.#deployment = options.deployment;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/** The exact deployment selected for this client. */
|
|
110
|
+
get deployment(): MisoProtocolDeployment {
|
|
111
|
+
return this.#deployment;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
get #misoPackageId(): string {
|
|
115
|
+
return this.#deployment.packageId;
|
|
83
116
|
}
|
|
84
117
|
|
|
85
118
|
// === Composition ===
|
|
@@ -243,7 +276,6 @@ export class MisoClient {
|
|
|
243
276
|
Release: release.Release,
|
|
244
277
|
Track: track.Track,
|
|
245
278
|
CompositionPublishedEvent: composition.CompositionPublishedEvent,
|
|
246
|
-
CompositionRoyaltySetEvent: composition.CompositionRoyaltySetEvent,
|
|
247
279
|
RecordingPublishedEvent: recording.RecordingPublishedEvent,
|
|
248
280
|
ReleasePublishedEvent: release.ReleasePublishedEvent,
|
|
249
281
|
};
|
|
@@ -254,7 +286,6 @@ export class MisoClient {
|
|
|
254
286
|
get parse() {
|
|
255
287
|
return {
|
|
256
288
|
compositionPublishedEvent: parsers.parseCompositionPublishedEvent,
|
|
257
|
-
compositionRoyaltySetEvent: parsers.parseCompositionRoyaltySetEvent,
|
|
258
289
|
recordingPublishedEvent: parsers.parseRecordingPublishedEvent,
|
|
259
290
|
releasePublishedEvent: parsers.parseReleasePublishedEvent,
|
|
260
291
|
};
|
|
@@ -269,3 +300,6 @@ export class MisoClient {
|
|
|
269
300
|
return this.#graphqlClient;
|
|
270
301
|
}
|
|
271
302
|
}
|
|
303
|
+
|
|
304
|
+
/** @deprecated Prefer the layer-specific `MisoProtocolClient` name. */
|
|
305
|
+
export { MisoProtocolClient as MisoClient };
|
|
@@ -67,12 +67,6 @@ export const CompositionAdminCapKey = new MoveTuple({ name: `${$moduleName}::Com
|
|
|
67
67
|
export const CompositionPublishedEvent = new MoveStruct({ name: `${$moduleName}::CompositionPublishedEvent<phantom CompositionShare>`, fields: {
|
|
68
68
|
composition_id: bcs.Address
|
|
69
69
|
} });
|
|
70
|
-
export const CompositionRoyaltySetEvent = new MoveStruct({ name: `${$moduleName}::CompositionRoyaltySetEvent<phantom CompositionShare>`, fields: {
|
|
71
|
-
composition_id: bcs.Address,
|
|
72
|
-
previous_royalty_rate_bps: bcs.u16(),
|
|
73
|
-
royalty_rate_bps: bcs.u16(),
|
|
74
|
-
changed_by: bcs.Address
|
|
75
|
-
} });
|
|
76
70
|
export interface NewArguments {
|
|
77
71
|
title: RawTransactionArgument<string>;
|
|
78
72
|
royaltyRateBps: RawTransactionArgument<number>;
|
|
@@ -92,10 +86,17 @@ export interface NewOptions {
|
|
|
92
86
|
];
|
|
93
87
|
}
|
|
94
88
|
/**
|
|
95
|
-
* Creates a new composition with the given title and royalty rate.
|
|
96
|
-
*
|
|
97
|
-
*
|
|
98
|
-
*
|
|
89
|
+
* Creates a new composition with the given title and royalty rate.
|
|
90
|
+
*
|
|
91
|
+
* The rate is set once, here, and is immutable for the composition's lifetime: it
|
|
92
|
+
* is a permanent standing offer that recorders and share buyers can price against
|
|
93
|
+
* without trusting the admin. The protocol imposes no opinion on it beyond the
|
|
94
|
+
* arithmetic bound of 100% (10000 bps, enforced by `bps::new`). There is no floor
|
|
95
|
+
* — 0% is permitted (e.g. a generative recording with no authored composition) —
|
|
96
|
+
* and no protocol ceiling: an uncompetitive rate simply attracts no recordings.
|
|
97
|
+
* What rate is reasonable is a client-side concern; per-deal deviations settle as
|
|
98
|
+
* voluntary share transfers after recording creation. Initializes share tokens
|
|
99
|
+
* (10M supply, 6 decimals) and returns:
|
|
99
100
|
*
|
|
100
101
|
* - The composition object
|
|
101
102
|
* - Admin capability for the owner
|
|
@@ -155,48 +156,6 @@ export function publish(options: PublishOptions) {
|
|
|
155
156
|
typeArguments: options.typeArguments
|
|
156
157
|
});
|
|
157
158
|
}
|
|
158
|
-
export interface SetRoyaltyRateArguments {
|
|
159
|
-
self: RawTransactionArgument<string>;
|
|
160
|
-
_: RawTransactionArgument<string>;
|
|
161
|
-
royaltyRateBps: RawTransactionArgument<number>;
|
|
162
|
-
}
|
|
163
|
-
export interface SetRoyaltyRateOptions {
|
|
164
|
-
package?: string;
|
|
165
|
-
arguments: SetRoyaltyRateArguments | [
|
|
166
|
-
self: RawTransactionArgument<string>,
|
|
167
|
-
_: RawTransactionArgument<string>,
|
|
168
|
-
royaltyRateBps: RawTransactionArgument<number>
|
|
169
|
-
];
|
|
170
|
-
typeArguments: [
|
|
171
|
-
string
|
|
172
|
-
];
|
|
173
|
-
}
|
|
174
|
-
/**
|
|
175
|
-
* Sets the royalty rate this composition earns from each recording. Must not
|
|
176
|
-
* exceed `MAX_ROYALTY_RATE_BPS` (there is no floor; 0% is allowed). The rate can
|
|
177
|
-
* be changed in any lifecycle state, including after publishing, and takes effect
|
|
178
|
-
* immediately. There is deliberately no rate-change cooldown: a change cannot
|
|
179
|
-
* surprise anyone, because each recording snapshots the rate when it is created
|
|
180
|
-
* (existing recordings keep the rate they captured) and `recording::new`'s
|
|
181
|
-
* `max_royalty_rate_bps` slippage guard means no future recorder can be charged a
|
|
182
|
-
* rate they did not consent to.
|
|
183
|
-
*/
|
|
184
|
-
export function setRoyaltyRate(options: SetRoyaltyRateOptions) {
|
|
185
|
-
const packageAddress = options.package ?? '@local-pkg/miso';
|
|
186
|
-
const argumentsTypes = [
|
|
187
|
-
null,
|
|
188
|
-
null,
|
|
189
|
-
'u16'
|
|
190
|
-
] satisfies (string | null)[];
|
|
191
|
-
const parameterNames = ["self", "_", "royaltyRateBps"];
|
|
192
|
-
return (tx: Transaction) => tx.moveCall({
|
|
193
|
-
package: packageAddress,
|
|
194
|
-
module: 'composition',
|
|
195
|
-
function: 'set_royalty_rate',
|
|
196
|
-
arguments: normalizeMoveArguments(options.arguments, argumentsTypes, parameterNames),
|
|
197
|
-
typeArguments: options.typeArguments
|
|
198
|
-
});
|
|
199
|
-
}
|
|
200
159
|
export interface IdArguments {
|
|
201
160
|
self: RawTransactionArgument<string>;
|
|
202
161
|
}
|
|
@@ -263,7 +222,11 @@ export interface RoyaltyRateOptions {
|
|
|
263
222
|
string
|
|
264
223
|
];
|
|
265
224
|
}
|
|
266
|
-
/**
|
|
225
|
+
/**
|
|
226
|
+
* Returns the royalty rate this composition earns from each recording. Immutable
|
|
227
|
+
* for the composition's lifetime — the value read here is, by construction, the
|
|
228
|
+
* value `recording::new` will apply.
|
|
229
|
+
*/
|
|
267
230
|
export function royaltyRate(options: RoyaltyRateOptions) {
|
|
268
231
|
const packageAddress = options.package ?? '@local-pkg/miso';
|
|
269
232
|
const argumentsTypes = [
|
|
@@ -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
|
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
// Copyright (c) Miso Labs, Inc.
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
/** Sui networks with a protocol deployment bundled into this SDK release. */
|
|
5
|
+
export type MisoNetwork = "mainnet" | "testnet";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* On-chain identity for one Miso protocol deployment.
|
|
9
|
+
*
|
|
10
|
+
* Package deployments are immutable. A new publish is represented by a new SDK
|
|
11
|
+
* release with updated values here, keeping the ABI bindings and addresses in
|
|
12
|
+
* the same versioned artifact.
|
|
13
|
+
*/
|
|
14
|
+
export interface MisoProtocolDeployment {
|
|
15
|
+
/** The published `miso` package used for calls, types, and derivation. */
|
|
16
|
+
readonly packageId: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export const MISO_PROTOCOL_DEPLOYMENTS = {
|
|
20
|
+
testnet: {
|
|
21
|
+
packageId:
|
|
22
|
+
"0x974d453e82b09ac90d29cf65d981d3cf3cabe1e5ca9c6348f42860226ef9b5c4",
|
|
23
|
+
},
|
|
24
|
+
} as const satisfies Partial<Record<MisoNetwork, MisoProtocolDeployment>>;
|
|
25
|
+
|
|
26
|
+
/** Resolve a bundled deployment, failing closed for devnet/localnet/custom names. */
|
|
27
|
+
export function getMisoProtocolDeployment(
|
|
28
|
+
network: string,
|
|
29
|
+
): MisoProtocolDeployment {
|
|
30
|
+
const deployment = (
|
|
31
|
+
MISO_PROTOCOL_DEPLOYMENTS as Partial<
|
|
32
|
+
Record<string, MisoProtocolDeployment>
|
|
33
|
+
>
|
|
34
|
+
)[network];
|
|
35
|
+
if (!deployment) {
|
|
36
|
+
throw new Error(
|
|
37
|
+
`@misonetwork/sdk: no bundled Miso protocol deployment for network "${network}". ` +
|
|
38
|
+
"Pass an explicit deployment to miso() for custom networks.",
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
return deployment;
|
|
42
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -11,6 +11,7 @@ export * from "./queries.ts";
|
|
|
11
11
|
export * from "./parsers.ts";
|
|
12
12
|
export * from "./view.ts";
|
|
13
13
|
export * from "./client.ts";
|
|
14
|
+
export * from "./deployments.ts";
|
|
14
15
|
|
|
15
16
|
// Generated, ABI-bound bindings (BCS structs + type-safe Move calls).
|
|
16
17
|
export * as contracts from "./contracts.ts";
|
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]! };
|