@misonetwork/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.
- package/README.md +101 -503
- package/dist/client.d.ts +21 -59
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +26 -58
- package/dist/client.js.map +1 -1
- package/dist/contracts/miso/release.d.ts +34 -31
- package/dist/contracts/miso/release.d.ts.map +1 -1
- package/dist/contracts/miso/release.js +32 -29
- package/dist/contracts/miso/release.js.map +1 -1
- package/dist/contracts/miso/track.d.ts +66 -22
- package/dist/contracts/miso/track.d.ts.map +1 -1
- package/dist/contracts/miso/track.js +65 -20
- package/dist/contracts/miso/track.js.map +1 -1
- package/dist/contracts/utils/index.d.ts +44 -0
- package/dist/contracts/utils/index.d.ts.map +1 -1
- package/dist/contracts/utils/index.js +104 -2
- package/dist/contracts/utils/index.js.map +1 -1
- package/dist/contracts.d.ts +0 -1
- package/dist/contracts.d.ts.map +1 -1
- package/dist/contracts.js +0 -1
- package/dist/contracts.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 +0 -7
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +0 -22
- package/dist/internal.js.map +1 -1
- package/dist/parsers.d.ts +1 -4
- package/dist/parsers.d.ts.map +1 -1
- package/dist/parsers.js +0 -24
- package/dist/parsers.js.map +1 -1
- package/dist/queries.d.ts +2 -5
- package/dist/queries.d.ts.map +1 -1
- package/dist/queries.js +8 -45
- package/dist/queries.js.map +1 -1
- package/dist/transactions.d.ts +10 -71
- package/dist/transactions.d.ts.map +1 -1
- package/dist/transactions.js +15 -72
- package/dist/transactions.js.map +1 -1
- package/dist/types.d.ts +3 -40
- package/dist/types.d.ts.map +1 -1
- package/dist/view.d.ts +7 -7
- package/dist/view.d.ts.map +1 -1
- package/dist/view.js +9 -9
- package/dist/view.js.map +1 -1
- package/package.json +8 -4
- package/src/client.ts +47 -86
- package/src/contracts/miso/release.ts +39 -36
- package/src/contracts/miso/track.ts +81 -23
- package/src/contracts/utils/index.ts +156 -4
- package/src/contracts.ts +0 -1
- package/src/deployments.ts +42 -0
- package/src/index.ts +1 -0
- package/src/internal.ts +0 -24
- package/src/parsers.ts +0 -35
- package/src/queries.ts +11 -59
- package/src/transactions.ts +20 -112
- package/src/types.ts +3 -53
- package/src/view.ts +13 -13
- package/dist/contracts/miso/deal.d.ts +0 -184
- package/dist/contracts/miso/deal.d.ts.map +0 -1
- package/dist/contracts/miso/deal.js +0 -184
- package/dist/contracts/miso/deal.js.map +0 -1
- package/src/contracts/miso/deal.ts +0 -257
package/src/client.ts
CHANGED
|
@@ -6,15 +6,16 @@ import type {
|
|
|
6
6
|
SuiClientRegistration,
|
|
7
7
|
} from "@mysten/sui/client";
|
|
8
8
|
import type { SuiGraphQLClient } from "@mysten/sui/graphql";
|
|
9
|
-
import
|
|
9
|
+
import {
|
|
10
|
+
getMisoProtocolDeployment,
|
|
11
|
+
type MisoProtocolDeployment,
|
|
12
|
+
} from "./deployments.ts";
|
|
10
13
|
import * as parsers from "./parsers.ts";
|
|
11
14
|
import * as queries from "./queries.ts";
|
|
12
|
-
import * as transactions from "./transactions.ts";
|
|
13
15
|
import * as view from "./view.ts";
|
|
14
16
|
import type {
|
|
15
17
|
Composition,
|
|
16
18
|
CompositionAdminCap,
|
|
17
|
-
Deal,
|
|
18
19
|
Recording,
|
|
19
20
|
RecordingAdminCap,
|
|
20
21
|
Release,
|
|
@@ -25,46 +26,27 @@ import type {
|
|
|
25
26
|
import * as composition from "./contracts/miso/composition.ts";
|
|
26
27
|
import * as recording from "./contracts/miso/recording.ts";
|
|
27
28
|
import * as release from "./contracts/miso/release.ts";
|
|
28
|
-
import * as deal from "./contracts/miso/deal.ts";
|
|
29
29
|
import * as track from "./contracts/miso/track.ts";
|
|
30
30
|
|
|
31
31
|
export interface MisoOptions<Name extends string = "miso"> {
|
|
32
32
|
/** Name for the client extension. Defaults to "miso". */
|
|
33
33
|
name?: Name;
|
|
34
|
-
/** The Miso package ID. Required for type-based queries and derivation. */
|
|
35
|
-
misoPackageId: string;
|
|
36
34
|
/**
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
* Created once in `release::init` and shared, so it is FIXED for the lifetime
|
|
40
|
-
* of a published package — deployment config, not runtime state. Supply it
|
|
41
|
-
* (alongside `misoPackageId`, from the same deployment manifest) and
|
|
42
|
-
* `getReleaseRegistry()` needs no network call at all. Omit it and the SDK
|
|
43
|
-
* falls back to a GraphQL scan, which is why this is worth configuring.
|
|
35
|
+
* Complete custom deployment. Omit for bundled Mainnet/Testnet addresses,
|
|
36
|
+
* selected from the Sui client's `network`.
|
|
44
37
|
*/
|
|
45
|
-
|
|
38
|
+
deployment?: MisoProtocolDeployment;
|
|
39
|
+
/** @deprecated Use `deployment`. Retained for compatibility with pre-0.4 callers. */
|
|
40
|
+
misoPackageId?: string;
|
|
46
41
|
/**
|
|
47
42
|
* Optional GraphQL client, required ONLY for the global type-discovery reads
|
|
48
43
|
* the Core API cannot express: `getCompositionByShareType`,
|
|
49
|
-
* `getRecordingByShareType
|
|
50
|
-
* `releaseRegistryId` is not configured. Everything else — including every
|
|
44
|
+
* `getRecordingByShareType`. Everything else — including every
|
|
51
45
|
* `getOwned*AdminCaps` — goes over the Core API.
|
|
52
46
|
*/
|
|
53
47
|
graphqlClient?: SuiGraphQLClient;
|
|
54
48
|
}
|
|
55
49
|
|
|
56
|
-
/**
|
|
57
|
-
* Wraps a builder so the client's `misoPackageId` is injected, dropping it from
|
|
58
|
-
* the caller's params. Explicit call-sites (the free functions in
|
|
59
|
-
* `./transactions`) remain available for full control.
|
|
60
|
-
*/
|
|
61
|
-
function bindPackages<P extends { misoPackageId: string }>(
|
|
62
|
-
fn: (params: P) => TxThunk,
|
|
63
|
-
misoPackageId: string,
|
|
64
|
-
): (params: Omit<P, "misoPackageId">) => TxThunk {
|
|
65
|
-
return (params) => fn({ misoPackageId, ...params } as unknown as P);
|
|
66
|
-
}
|
|
67
|
-
|
|
68
50
|
/** Defaults `options.package` to `pkg` for every call-function in a generated module. */
|
|
69
51
|
function bindModulePackage<M extends object>(mod: M, pkg: string): M {
|
|
70
52
|
const out: Record<string, unknown> = {};
|
|
@@ -84,31 +66,53 @@ function bindModulePackage<M extends object>(mod: M, pkg: string): M {
|
|
|
84
66
|
* @example
|
|
85
67
|
* ```ts
|
|
86
68
|
* const client = new SuiGrpcClient({ network: 'testnet' })
|
|
87
|
-
* .$extend(miso(
|
|
69
|
+
* .$extend(miso());
|
|
88
70
|
* const composition = await client.miso.getCompositionById('0x...');
|
|
89
71
|
* ```
|
|
90
72
|
*/
|
|
91
73
|
export function miso<const Name extends string = "miso">(
|
|
92
|
-
options: MisoOptions<Name
|
|
93
|
-
): SuiClientRegistration<ClientWithCoreApi, Name,
|
|
74
|
+
options: MisoOptions<Name> = {},
|
|
75
|
+
): SuiClientRegistration<ClientWithCoreApi, Name, MisoProtocolClient> {
|
|
94
76
|
const name = (options.name ?? "miso") as Name;
|
|
95
77
|
return {
|
|
96
78
|
name,
|
|
97
|
-
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
|
+
},
|
|
98
90
|
};
|
|
99
91
|
}
|
|
100
92
|
|
|
101
|
-
export
|
|
93
|
+
export interface MisoProtocolClientOptions {
|
|
94
|
+
deployment: MisoProtocolDeployment;
|
|
95
|
+
graphqlClient?: SuiGraphQLClient;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export class MisoProtocolClient {
|
|
102
99
|
#client: ClientWithCoreApi;
|
|
103
100
|
#graphqlClient?: SuiGraphQLClient;
|
|
104
|
-
#
|
|
105
|
-
#releaseRegistryId?: string;
|
|
101
|
+
#deployment: MisoProtocolDeployment;
|
|
106
102
|
|
|
107
|
-
constructor(client: ClientWithCoreApi, options:
|
|
103
|
+
constructor(client: ClientWithCoreApi, options: MisoProtocolClientOptions) {
|
|
108
104
|
this.#client = client;
|
|
109
105
|
this.#graphqlClient = options.graphqlClient;
|
|
110
|
-
this.#
|
|
111
|
-
|
|
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;
|
|
112
116
|
}
|
|
113
117
|
|
|
114
118
|
// === Composition ===
|
|
@@ -202,12 +206,6 @@ export class MisoClient {
|
|
|
202
206
|
return queries.deriveRecordingAdminCapId(recordingId, this.#misoPackageId);
|
|
203
207
|
}
|
|
204
208
|
|
|
205
|
-
// === Deal ===
|
|
206
|
-
|
|
207
|
-
async getDealById(dealId: string): Promise<Deal> {
|
|
208
|
-
return queries.getDealById(this.#client, dealId);
|
|
209
|
-
}
|
|
210
|
-
|
|
211
209
|
// === Release ===
|
|
212
210
|
|
|
213
211
|
async getReleaseById(releaseId: string): Promise<Release> {
|
|
@@ -229,23 +227,6 @@ export class MisoClient {
|
|
|
229
227
|
this.#misoPackageId,
|
|
230
228
|
);
|
|
231
229
|
}
|
|
232
|
-
/**
|
|
233
|
-
* The deployment's `ReleaseRegistry` object ID.
|
|
234
|
-
*
|
|
235
|
-
* Returns the configured `releaseRegistryId` with no network call. Only when
|
|
236
|
-
* it was not configured does this fall back to a GraphQL scan — a one-time
|
|
237
|
-
* bootstrap for a fresh deployment whose id you have not recorded yet. Prefer
|
|
238
|
-
* configuring it: the registry is created once in `release::init` and never
|
|
239
|
-
* changes, so scanning for it on every call is pure overhead.
|
|
240
|
-
*/
|
|
241
|
-
async getReleaseRegistry(): Promise<string> {
|
|
242
|
-
if (this.#releaseRegistryId) return this.#releaseRegistryId;
|
|
243
|
-
return queries.getReleaseRegistry(
|
|
244
|
-
this.#requireGraphQL(),
|
|
245
|
-
this.#misoPackageId,
|
|
246
|
-
);
|
|
247
|
-
}
|
|
248
|
-
|
|
249
230
|
// === Share Currency ===
|
|
250
231
|
|
|
251
232
|
async getShareCurrencyType(shareCurrencyId: string): Promise<string> {
|
|
@@ -263,29 +244,14 @@ export class MisoClient {
|
|
|
263
244
|
return queries.getShareCurrencyTreasuryCap(this.#client, shareType, owner);
|
|
264
245
|
}
|
|
265
246
|
|
|
266
|
-
// === Transaction builders (thunks) ===
|
|
267
|
-
|
|
268
|
-
// Only the `(params) => TxThunk` builders bind here. The primitives that take
|
|
269
|
-
// a `Transaction` directly and return values (`createComposition`,
|
|
270
|
-
// `createRecording`, `createRelease`, `createDeal`) are free functions by
|
|
271
|
-
// design — they thread results into a caller-owned PTB, so there is nothing
|
|
272
|
-
// to bind. Import them from the package root and pass `misoPackageId`
|
|
273
|
-
// explicitly.
|
|
274
|
-
get tx() {
|
|
275
|
-
const miso = this.#misoPackageId;
|
|
276
|
-
return {
|
|
277
|
-
rejectDeal: bindPackages(transactions.rejectDeal, miso),
|
|
278
|
-
};
|
|
279
|
-
}
|
|
280
|
-
|
|
281
247
|
// === Simulate-based reads (view) ===
|
|
282
248
|
|
|
283
249
|
get view() {
|
|
284
250
|
const client = this.#client;
|
|
285
251
|
const misoPackageId = this.#misoPackageId;
|
|
286
252
|
return {
|
|
287
|
-
|
|
288
|
-
view.
|
|
253
|
+
deriveTargetReleaseId: (params: view.DeriveTargetReleaseIdParams) =>
|
|
254
|
+
view.deriveTargetReleaseId(client, misoPackageId, params),
|
|
289
255
|
};
|
|
290
256
|
}
|
|
291
257
|
|
|
@@ -297,7 +263,6 @@ export class MisoClient {
|
|
|
297
263
|
composition: bindModulePackage(composition, pkg),
|
|
298
264
|
recording: bindModulePackage(recording, pkg),
|
|
299
265
|
release: bindModulePackage(release, pkg),
|
|
300
|
-
deal: bindModulePackage(deal, pkg),
|
|
301
266
|
track: bindModulePackage(track, pkg),
|
|
302
267
|
};
|
|
303
268
|
}
|
|
@@ -309,15 +274,11 @@ export class MisoClient {
|
|
|
309
274
|
Composition: composition.Composition,
|
|
310
275
|
Recording: recording.Recording,
|
|
311
276
|
Release: release.Release,
|
|
312
|
-
Deal: deal.Deal,
|
|
313
277
|
Track: track.Track,
|
|
314
278
|
CompositionPublishedEvent: composition.CompositionPublishedEvent,
|
|
315
279
|
CompositionRoyaltySetEvent: composition.CompositionRoyaltySetEvent,
|
|
316
280
|
RecordingPublishedEvent: recording.RecordingPublishedEvent,
|
|
317
281
|
ReleasePublishedEvent: release.ReleasePublishedEvent,
|
|
318
|
-
DealCreatedEvent: deal.DealCreatedEvent,
|
|
319
|
-
DealAcceptedEvent: deal.DealAcceptedEvent,
|
|
320
|
-
DealRejectedEvent: deal.DealRejectedEvent,
|
|
321
282
|
};
|
|
322
283
|
}
|
|
323
284
|
|
|
@@ -329,9 +290,6 @@ export class MisoClient {
|
|
|
329
290
|
compositionRoyaltySetEvent: parsers.parseCompositionRoyaltySetEvent,
|
|
330
291
|
recordingPublishedEvent: parsers.parseRecordingPublishedEvent,
|
|
331
292
|
releasePublishedEvent: parsers.parseReleasePublishedEvent,
|
|
332
|
-
dealCreatedEvent: parsers.parseDealCreatedEvent,
|
|
333
|
-
dealAcceptedEvent: parsers.parseDealAcceptedEvent,
|
|
334
|
-
dealRejectedEvent: parsers.parseDealRejectedEvent,
|
|
335
293
|
};
|
|
336
294
|
}
|
|
337
295
|
|
|
@@ -344,3 +302,6 @@ export class MisoClient {
|
|
|
344
302
|
return this.#graphqlClient;
|
|
345
303
|
}
|
|
346
304
|
}
|
|
305
|
+
|
|
306
|
+
/** @deprecated Prefer the layer-specific `MisoProtocolClient` name. */
|
|
307
|
+
export { MisoProtocolClient as MisoClient };
|
|
@@ -38,14 +38,22 @@
|
|
|
38
38
|
*
|
|
39
39
|
* ### Consent scope
|
|
40
40
|
*
|
|
41
|
-
* The release digest — and therefore the derived release id every `
|
|
42
|
-
* to — binds the economics and membership of the release: the ordered
|
|
43
|
-
* `(recording, split)` pairs and the creator's nonce. It deliberately
|
|
44
|
-
* nothing else. The title — the one embedded field outside the digest — and
|
|
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
45
|
* everything in the extension layer (artwork, credits, display grouping) are
|
|
46
|
-
* chosen by the release creator, before or after
|
|
47
|
-
* and publicly attributable rather than cryptographically committed. See
|
|
48
|
-
* `
|
|
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 a `(parent, digest)` pair, not the digest alone — so
|
|
51
|
+
* targeting an id also consents to that namespace's liveness. If the parent object
|
|
52
|
+
* is deleted, or its `&mut UID` becomes permanently unreachable, the release can
|
|
53
|
+
* never exist and every track or offer targeting it is stranded — the same
|
|
54
|
+
* blast-radius class as a release that simply never publishes. A coordinator meant
|
|
55
|
+
* to serve as the default parent namespace should therefore be shared and
|
|
56
|
+
* undeletable.
|
|
49
57
|
*
|
|
50
58
|
* ### Lifecycle and trust model
|
|
51
59
|
*
|
|
@@ -65,12 +73,11 @@
|
|
|
65
73
|
* holder as able to mutate or delete any extension data, forever.
|
|
66
74
|
*/
|
|
67
75
|
|
|
68
|
-
import {
|
|
76
|
+
import { MoveEnum, MoveStruct, MoveTuple, normalizeMoveArguments, type RawTransactionArgument } from '../utils/index.js';
|
|
69
77
|
import { bcs } from '@mysten/sui/bcs';
|
|
70
78
|
import { type Transaction, type TransactionArgument } from '@mysten/sui/transactions';
|
|
71
79
|
import * as track from './track.js';
|
|
72
80
|
const $moduleName = '@local-pkg/miso::release';
|
|
73
|
-
export const RELEASE = new MoveTuple({ name: `${$moduleName}::RELEASE`, fields: [bcs.bool()] });
|
|
74
81
|
/** Lifecycle state of a release. */
|
|
75
82
|
export const ReleaseState = new MoveEnum({ name: `${$moduleName}::ReleaseState`, fields: {
|
|
76
83
|
/** Release is initialized but not yet published. */
|
|
@@ -86,15 +93,12 @@ export const Release = new MoveStruct({ name: `${$moduleName}::Release`, fields:
|
|
|
86
93
|
/** Title of the release. */
|
|
87
94
|
title: bcs.string(),
|
|
88
95
|
/**
|
|
89
|
-
* The ordered tracklist. Same shape as the digest pre-image every
|
|
90
|
-
* to; display grouping lives in the metadata extension.
|
|
96
|
+
* The ordered tracklist. Same shape as the digest pre-image every track's creator
|
|
97
|
+
* consented to; display grouping lives in the metadata extension.
|
|
91
98
|
*/
|
|
92
99
|
tracks: bcs.vector(track.Track)
|
|
93
100
|
} });
|
|
94
101
|
export const ReleaseKey = new MoveTuple({ name: `${$moduleName}::ReleaseKey`, fields: [bcs.vector(bcs.u8())] });
|
|
95
|
-
export const ReleaseRegistry = new MoveStruct({ name: `${$moduleName}::ReleaseRegistry`, fields: {
|
|
96
|
-
id: bcs.Address
|
|
97
|
-
} });
|
|
98
102
|
export const ReleaseAdminCap = new MoveStruct({ name: `${$moduleName}::ReleaseAdminCap`, fields: {
|
|
99
103
|
/** Unique identifier for this capability. */
|
|
100
104
|
id: bcs.Address,
|
|
@@ -102,10 +106,6 @@ export const ReleaseAdminCap = new MoveStruct({ name: `${$moduleName}::ReleaseAd
|
|
|
102
106
|
release_id: bcs.Address
|
|
103
107
|
} });
|
|
104
108
|
export const ReleaseAdminCapKey = new MoveTuple({ name: `${$moduleName}::ReleaseAdminCapKey`, fields: [bcs.bool()] });
|
|
105
|
-
export const ReleaseRegistryCreatedEvent = new MoveStruct({ name: `${$moduleName}::ReleaseRegistryCreatedEvent`, fields: {
|
|
106
|
-
registry_id: bcs.Address,
|
|
107
|
-
created_by: bcs.Address
|
|
108
|
-
} });
|
|
109
109
|
export const ReleasePublishedEvent = new MoveStruct({ name: `${$moduleName}::ReleasePublishedEvent`, fields: {
|
|
110
110
|
release_id: bcs.Address
|
|
111
111
|
} });
|
|
@@ -113,7 +113,7 @@ export interface NewArguments {
|
|
|
113
113
|
title: RawTransactionArgument<string>;
|
|
114
114
|
tracks: TransactionArgument;
|
|
115
115
|
nonce: RawTransactionArgument<number | bigint>;
|
|
116
|
-
|
|
116
|
+
parent: RawTransactionArgument<string>;
|
|
117
117
|
}
|
|
118
118
|
export interface NewOptions {
|
|
119
119
|
package?: string;
|
|
@@ -121,12 +121,15 @@ export interface NewOptions {
|
|
|
121
121
|
title: RawTransactionArgument<string>,
|
|
122
122
|
tracks: TransactionArgument,
|
|
123
123
|
nonce: RawTransactionArgument<number | bigint>,
|
|
124
|
-
|
|
124
|
+
parent: RawTransactionArgument<string>
|
|
125
125
|
];
|
|
126
126
|
}
|
|
127
127
|
/**
|
|
128
|
-
* Creates a new release with the given configuration.
|
|
129
|
-
*
|
|
128
|
+
* Creates a new release with the given configuration. Claims the release's UID as
|
|
129
|
+
* a derived child of `parent`, keyed by the release digest (see the module doc's
|
|
130
|
+
* "Consent scope" section) — so contention is per-parent, and which object serves
|
|
131
|
+
* as parent is entirely the caller's choice. Returns the release and admin
|
|
132
|
+
* capability.
|
|
130
133
|
*/
|
|
131
134
|
export function _new(options: NewOptions) {
|
|
132
135
|
const packageAddress = options.package ?? '@local-pkg/miso';
|
|
@@ -134,9 +137,9 @@ export function _new(options: NewOptions) {
|
|
|
134
137
|
'0x1::string::String',
|
|
135
138
|
'vector<null>',
|
|
136
139
|
'u256',
|
|
137
|
-
|
|
140
|
+
'0x2::object::ID'
|
|
138
141
|
] satisfies (string | null)[];
|
|
139
|
-
const parameterNames = ["title", "tracks", "nonce", "
|
|
142
|
+
const parameterNames = ["title", "tracks", "nonce", "parent"];
|
|
140
143
|
return (tx: Transaction) => tx.moveCall({
|
|
141
144
|
package: packageAddress,
|
|
142
145
|
module: 'release',
|
|
@@ -203,39 +206,39 @@ export function authorize(options: AuthorizeOptions) {
|
|
|
203
206
|
arguments: normalizeMoveArguments(options.arguments, argumentsTypes, parameterNames),
|
|
204
207
|
});
|
|
205
208
|
}
|
|
206
|
-
export interface
|
|
209
|
+
export interface DeriveTargetReleaseIdArguments {
|
|
207
210
|
recordingIds: RawTransactionArgument<Array<string>>;
|
|
208
211
|
trackSplitValues: RawTransactionArgument<Array<number | bigint>>;
|
|
209
212
|
nonce: RawTransactionArgument<number | bigint>;
|
|
210
|
-
|
|
213
|
+
parent: RawTransactionArgument<string>;
|
|
211
214
|
}
|
|
212
|
-
export interface
|
|
215
|
+
export interface DeriveTargetReleaseIdOptions {
|
|
213
216
|
package?: string;
|
|
214
|
-
arguments:
|
|
217
|
+
arguments: DeriveTargetReleaseIdArguments | [
|
|
215
218
|
recordingIds: RawTransactionArgument<Array<string>>,
|
|
216
219
|
trackSplitValues: RawTransactionArgument<Array<number | bigint>>,
|
|
217
220
|
nonce: RawTransactionArgument<number | bigint>,
|
|
218
|
-
|
|
221
|
+
parent: RawTransactionArgument<string>
|
|
219
222
|
];
|
|
220
223
|
}
|
|
221
224
|
/**
|
|
222
|
-
* Derives the release ID that `new()` would produce for the given inputs
|
|
223
|
-
* creating the object. This is the on-chain equivalent of the
|
|
224
|
-
* `deriveReleaseId()` function.
|
|
225
|
+
* Derives the target release ID that `new()` would produce for the given inputs
|
|
226
|
+
* and parent, without creating the object. This is the on-chain equivalent of the
|
|
227
|
+
* client-side `deriveReleaseId()` function.
|
|
225
228
|
*/
|
|
226
|
-
export function
|
|
229
|
+
export function deriveTargetReleaseId(options: DeriveTargetReleaseIdOptions) {
|
|
227
230
|
const packageAddress = options.package ?? '@local-pkg/miso';
|
|
228
231
|
const argumentsTypes = [
|
|
229
232
|
'vector<0x2::object::ID>',
|
|
230
233
|
'vector<u64>',
|
|
231
234
|
'u256',
|
|
232
|
-
|
|
235
|
+
'0x2::object::ID'
|
|
233
236
|
] satisfies (string | null)[];
|
|
234
|
-
const parameterNames = ["recordingIds", "trackSplitValues", "nonce", "
|
|
237
|
+
const parameterNames = ["recordingIds", "trackSplitValues", "nonce", "parent"];
|
|
235
238
|
return (tx: Transaction) => tx.moveCall({
|
|
236
239
|
package: packageAddress,
|
|
237
240
|
module: 'release',
|
|
238
|
-
function: '
|
|
241
|
+
function: 'derive_target_release_id',
|
|
239
242
|
arguments: normalizeMoveArguments(options.arguments, argumentsTypes, parameterNames),
|
|
240
243
|
});
|
|
241
244
|
}
|
|
@@ -14,8 +14,8 @@
|
|
|
14
14
|
* recording/composition share-type identities) is reached.
|
|
15
15
|
* - `split_bps` — this track's share of the release's revenue; genuinely
|
|
16
16
|
* release-specific and not derivable from the recording.
|
|
17
|
-
* - `state` — the assign-once lifecycle that carries (then sheds)
|
|
18
|
-
* target release commitment; see `TrackState`.
|
|
17
|
+
* - `state` — the assign-once lifecycle that carries (then sheds) the recording
|
|
18
|
+
* admin's target release commitment, made at creation; see `TrackState`.
|
|
19
19
|
*
|
|
20
20
|
* `Track` is intentionally monomorphic: a `Release` holds a `vector<Track>` of
|
|
21
21
|
* tracks from many different recordings/compositions, so it cannot be generic over
|
|
@@ -30,16 +30,16 @@ import * as bps from './deps/bps/bps.js';
|
|
|
30
30
|
const $moduleName = '@local-pkg/miso::track';
|
|
31
31
|
/**
|
|
32
32
|
* Lifecycle state of a track within a release. A track is born `Unassigned`,
|
|
33
|
-
* carrying the target
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
33
|
+
* carrying the target release id the consent committed to at creation (the release
|
|
34
|
+
* id is a digest of the whole tracklist, so this is the recording owner's consent
|
|
35
|
+
* to the exact release configuration). At publish the release verifies the match
|
|
36
|
+
* and transitions the track to `Assigned`, which carries no id — shedding the
|
|
37
|
+
* 32-byte commitment once it has served its purpose.
|
|
38
38
|
*/
|
|
39
39
|
export const TrackState = new MoveEnum({ name: `${$moduleName}::TrackState`, fields: {
|
|
40
40
|
/**
|
|
41
41
|
* Track has been created but not yet assigned to a release. Carries the target
|
|
42
|
-
* release id the
|
|
42
|
+
* release id the consent committed to at creation.
|
|
43
43
|
*/
|
|
44
44
|
Unassigned: bcs.Address,
|
|
45
45
|
/** Track has been assigned to its target release. */
|
|
@@ -63,14 +63,18 @@ export const Track = new MoveStruct({ name: `${$moduleName}::Track`, fields: {
|
|
|
63
63
|
split_bps: bps.BPS
|
|
64
64
|
} });
|
|
65
65
|
export interface NewArguments {
|
|
66
|
-
|
|
66
|
+
_: RawTransactionArgument<string>;
|
|
67
67
|
recording: RawTransactionArgument<string>;
|
|
68
|
+
targetReleaseId: RawTransactionArgument<string>;
|
|
69
|
+
trackSplitBpsValue: RawTransactionArgument<number>;
|
|
68
70
|
}
|
|
69
71
|
export interface NewOptions {
|
|
70
72
|
package?: string;
|
|
71
73
|
arguments: NewArguments | [
|
|
72
|
-
|
|
73
|
-
recording: RawTransactionArgument<string
|
|
74
|
+
_: RawTransactionArgument<string>,
|
|
75
|
+
recording: RawTransactionArgument<string>,
|
|
76
|
+
targetReleaseId: RawTransactionArgument<string>,
|
|
77
|
+
trackSplitBpsValue: RawTransactionArgument<number>
|
|
74
78
|
];
|
|
75
79
|
typeArguments: [
|
|
76
80
|
string,
|
|
@@ -78,25 +82,52 @@ export interface NewOptions {
|
|
|
78
82
|
];
|
|
79
83
|
}
|
|
80
84
|
/**
|
|
81
|
-
* Creates a new track
|
|
82
|
-
*
|
|
83
|
-
*
|
|
85
|
+
* Creates a new track: the recording admin's consent to that recording's inclusion
|
|
86
|
+
* in a specific future release with an agreed split. Requires the recording admin
|
|
87
|
+
* capability. No event: a `Track` has `drop` and is not an object, so a creation
|
|
88
|
+
* event could announce a consent that is then silently discarded, and indexers
|
|
89
|
+
* would be unable to distinguish pending from dead. Pre-publish observability is
|
|
90
|
+
* the responsibility of whatever wraps the track (see below).
|
|
84
91
|
*
|
|
85
|
-
* The
|
|
86
|
-
*
|
|
87
|
-
* `
|
|
88
|
-
*
|
|
89
|
-
*
|
|
90
|
-
*
|
|
91
|
-
*
|
|
92
|
+
* The composition is identified by the recording's `CompositionShare` phantom, so
|
|
93
|
+
* the recording↔composition pairing is compile-time enforced — there is no
|
|
94
|
+
* `Composition` argument and no runtime ID check.
|
|
95
|
+
*
|
|
96
|
+
* ### What creating a track consents to
|
|
97
|
+
*
|
|
98
|
+
* `target_release_id` is derived from the release digest, so targeting it consents
|
|
99
|
+
* to that release's exact economics and membership: the ordered list of
|
|
100
|
+
* `(recording, split)` pairs and the creator's nonce, nothing more. The release's
|
|
101
|
+
* title, artwork, credits, and display grouping are chosen by the release creator
|
|
102
|
+
* — before or after this track is created — and are not bound by the digest.
|
|
103
|
+
* Presentation is trusted and publicly attributable, not cryptographically
|
|
104
|
+
* committed.
|
|
105
|
+
*
|
|
106
|
+
* The recording need not be `Published`: its admin can create tracks inside the
|
|
107
|
+
* recording's own creating transaction (an `Initialized` recording cannot escape
|
|
108
|
+
* that transaction, so across transactions tracks always reference `Published`,
|
|
109
|
+
* shared recordings).
|
|
110
|
+
*
|
|
111
|
+
* A `Track` has `store`, not `key`: it carries no identity of its own, so it may
|
|
112
|
+
* be exercised synchronously in the same transaction that creates it, or handed to
|
|
113
|
+
* an offer extension that wraps it in a real object with its own identity.
|
|
114
|
+
* Withdrawal, expiry, and rejection are then whatever that wrapping extension
|
|
115
|
+
* encodes — visible in its type, not in core.
|
|
116
|
+
*
|
|
117
|
+
* `recording` compile-time-binds the `RecordingShare`/`CompositionShare` phantom
|
|
118
|
+
* pairing, and is read for its id: the monomorphic `Track` must store the
|
|
119
|
+
* recording's _address_ for revenue routing, and an address cannot come from a
|
|
120
|
+
* phantom.
|
|
92
121
|
*/
|
|
93
122
|
export function _new(options: NewOptions) {
|
|
94
123
|
const packageAddress = options.package ?? '@local-pkg/miso';
|
|
95
124
|
const argumentsTypes = [
|
|
96
125
|
null,
|
|
97
|
-
null
|
|
126
|
+
null,
|
|
127
|
+
'0x2::object::ID',
|
|
128
|
+
'u16'
|
|
98
129
|
] satisfies (string | null)[];
|
|
99
|
-
const parameterNames = ["
|
|
130
|
+
const parameterNames = ["_", "recording", "targetReleaseId", "trackSplitBpsValue"];
|
|
100
131
|
return (tx: Transaction) => tx.moveCall({
|
|
101
132
|
package: packageAddress,
|
|
102
133
|
module: 'track',
|
|
@@ -150,4 +181,31 @@ export function splitBps(options: SplitBpsOptions) {
|
|
|
150
181
|
function: 'split_bps',
|
|
151
182
|
arguments: normalizeMoveArguments(options.arguments, argumentsTypes, parameterNames),
|
|
152
183
|
});
|
|
184
|
+
}
|
|
185
|
+
export interface TargetReleaseIdArguments {
|
|
186
|
+
self: TransactionArgument;
|
|
187
|
+
}
|
|
188
|
+
export interface TargetReleaseIdOptions {
|
|
189
|
+
package?: string;
|
|
190
|
+
arguments: TargetReleaseIdArguments | [
|
|
191
|
+
self: TransactionArgument
|
|
192
|
+
];
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Returns the target release id this track's creator consented to. Aborts if the
|
|
196
|
+
* track is `Assigned`: an assigned track only exists inside a published release,
|
|
197
|
+
* so its release is the object you fetched it from.
|
|
198
|
+
*/
|
|
199
|
+
export function targetReleaseId(options: TargetReleaseIdOptions) {
|
|
200
|
+
const packageAddress = options.package ?? '@local-pkg/miso';
|
|
201
|
+
const argumentsTypes = [
|
|
202
|
+
null
|
|
203
|
+
] satisfies (string | null)[];
|
|
204
|
+
const parameterNames = ["self"];
|
|
205
|
+
return (tx: Transaction) => tx.moveCall({
|
|
206
|
+
package: packageAddress,
|
|
207
|
+
module: 'track',
|
|
208
|
+
function: 'target_release_id',
|
|
209
|
+
arguments: normalizeMoveArguments(options.arguments, argumentsTypes, parameterNames),
|
|
210
|
+
});
|
|
153
211
|
}
|