@misofm/sdk 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.
- package/LICENSE +201 -0
- package/README.md +248 -0
- package/dist/catalog.d.ts +31 -0
- package/dist/catalog.d.ts.map +1 -0
- package/dist/catalog.js +45 -0
- package/dist/catalog.js.map +1 -0
- package/dist/client.d.ts +134 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +113 -0
- package/dist/client.js.map +1 -0
- package/dist/contracts/miso_pressing/certificate.d.ts +78 -0
- package/dist/contracts/miso_pressing/certificate.d.ts.map +1 -0
- package/dist/contracts/miso_pressing/certificate.js +91 -0
- package/dist/contracts/miso_pressing/certificate.js.map +1 -0
- package/dist/contracts/miso_pressing/deps/std/type_name.d.ts +18 -0
- package/dist/contracts/miso_pressing/deps/std/type_name.d.ts.map +1 -0
- package/dist/contracts/miso_pressing/deps/std/type_name.js +20 -0
- package/dist/contracts/miso_pressing/deps/std/type_name.js.map +1 -0
- package/dist/contracts/miso_pressing/listing.d.ts +449 -0
- package/dist/contracts/miso_pressing/listing.d.ts.map +1 -0
- package/dist/contracts/miso_pressing/listing.js +416 -0
- package/dist/contracts/miso_pressing/listing.js.map +1 -0
- package/dist/contracts/miso_pressing/pressing.d.ts +365 -0
- package/dist/contracts/miso_pressing/pressing.d.ts.map +1 -0
- package/dist/contracts/miso_pressing/pressing.js +335 -0
- package/dist/contracts/miso_pressing/pressing.js.map +1 -0
- package/dist/contracts/utils/index.d.ts +31 -0
- package/dist/contracts/utils/index.d.ts.map +1 -0
- package/dist/contracts/utils/index.js +162 -0
- package/dist/contracts/utils/index.js.map +1 -0
- package/dist/execute.d.ts +17 -0
- package/dist/execute.d.ts.map +1 -0
- package/dist/execute.js +21 -0
- package/dist/execute.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +27 -0
- package/dist/index.js.map +1 -0
- package/dist/pressing.d.ts +223 -0
- package/dist/pressing.d.ts.map +1 -0
- package/dist/pressing.js +280 -0
- package/dist/pressing.js.map +1 -0
- package/dist/queries.d.ts +2 -0
- package/dist/queries.d.ts.map +1 -0
- package/dist/queries.js +8 -0
- package/dist/queries.js.map +1 -0
- package/dist/release-graph.d.ts +93 -0
- package/dist/release-graph.d.ts.map +1 -0
- package/dist/release-graph.js +143 -0
- package/dist/release-graph.js.map +1 -0
- package/dist/share-template.d.ts +3 -0
- package/dist/share-template.d.ts.map +1 -0
- package/dist/share-template.js +46 -0
- package/dist/share-template.js.map +1 -0
- package/dist/share.d.ts +66 -0
- package/dist/share.d.ts.map +1 -0
- package/dist/share.js +156 -0
- package/dist/share.js.map +1 -0
- package/dist/transactions.d.ts +177 -0
- package/dist/transactions.d.ts.map +1 -0
- package/dist/transactions.js +237 -0
- package/dist/transactions.js.map +1 -0
- package/package.json +99 -0
- package/src/catalog.ts +77 -0
- package/src/client.ts +249 -0
- package/src/contracts/miso_pressing/certificate.ts +129 -0
- package/src/contracts/miso_pressing/deps/std/type_name.ts +22 -0
- package/src/contracts/miso_pressing/listing.ts +621 -0
- package/src/contracts/miso_pressing/pressing.ts +454 -0
- package/src/contracts/utils/index.ts +229 -0
- package/src/execute.ts +34 -0
- package/src/index.ts +29 -0
- package/src/pressing.ts +497 -0
- package/src/queries.ts +9 -0
- package/src/release-graph.ts +279 -0
- package/src/share-template.ts +55 -0
- package/src/share.ts +258 -0
- package/src/transactions.ts +440 -0
|
@@ -0,0 +1,440 @@
|
|
|
1
|
+
// Copyright (c) Miso Labs, Inc.
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
// Transaction builders follow the Sui SDK thunk pattern: a builder returns a
|
|
5
|
+
// `(tx: Transaction) => …` thunk that adds commands to a caller-owned
|
|
6
|
+
// `Transaction`, so a platform call composes with protocol calls and anything
|
|
7
|
+
// else in the same PTB.
|
|
8
|
+
//
|
|
9
|
+
// This module holds the OPINIONATED publish flows. `@misonetwork/sdk` does the
|
|
10
|
+
// minimum the Move semantics FORCE and returns anything a caller could
|
|
11
|
+
// legitimately route elsewhere; deciding where those values GO is the
|
|
12
|
+
// platform-layer call that lives here:
|
|
13
|
+
//
|
|
14
|
+
// - minting a work's share supply is a protocol primitive
|
|
15
|
+
// (`createComposition`/`createRecording`) — dispersing it to recipients via
|
|
16
|
+
// minato, publishing (sharing) the work, and transferring its admin cap is
|
|
17
|
+
// an opinion about economics;
|
|
18
|
+
// - minting a release is likewise a primitive (`createRelease`) — choosing a
|
|
19
|
+
// track-assembly strategy, publishing (sharing) it, and picking a recipient
|
|
20
|
+
// for its `ReleaseAdminCap` is the opinion, so `finalizeRelease` /
|
|
21
|
+
// `publishRelease` / `publishReleaseFromDeals` live here.
|
|
22
|
+
//
|
|
23
|
+
// Every `finalize*` here MUST run in the same PTB as the `create*` that produced
|
|
24
|
+
// its parts — `Composition`, `Recording`, and `Release` are all `key`-only with
|
|
25
|
+
// no `drop`, so none can outlive its creating transaction. That is a same-PTB
|
|
26
|
+
// constraint, not a same-function one, which is exactly what makes this split
|
|
27
|
+
// possible.
|
|
28
|
+
//
|
|
29
|
+
// Composes with `@misonetwork/sdk`'s calls in the same PTB (the
|
|
30
|
+
// transaction-thunk composition pattern, just crossing a package boundary now).
|
|
31
|
+
|
|
32
|
+
import { Transaction, type TransactionObjectArgument } from "@mysten/sui/transactions";
|
|
33
|
+
import {
|
|
34
|
+
contracts,
|
|
35
|
+
createComposition,
|
|
36
|
+
createRecording,
|
|
37
|
+
createRelease,
|
|
38
|
+
type CompositionParts,
|
|
39
|
+
type CreateCompositionParams,
|
|
40
|
+
type CreateRecordingParams,
|
|
41
|
+
type RecordingParts,
|
|
42
|
+
type ReleaseParts,
|
|
43
|
+
type ShareCurrencyBinding,
|
|
44
|
+
type TxThunk,
|
|
45
|
+
} from "@misonetwork/sdk";
|
|
46
|
+
|
|
47
|
+
const { deal, track, release } = contracts;
|
|
48
|
+
|
|
49
|
+
// `TxThunk` is the protocol SDK's type, re-exported so platform consumers get
|
|
50
|
+
// the same nominal shape rather than a structurally-identical twin.
|
|
51
|
+
export type { TxThunk };
|
|
52
|
+
|
|
53
|
+
// ============================================================================
|
|
54
|
+
// Share dispersal (minato)
|
|
55
|
+
// ============================================================================
|
|
56
|
+
|
|
57
|
+
export interface ShareRecipient {
|
|
58
|
+
address: string;
|
|
59
|
+
value: number;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Splits a share `Balance` across `recipients` via `minato::disperse_balance`, then
|
|
64
|
+
* destroys the emptied balance. Exposed for consumers assembling custom share
|
|
65
|
+
* distributions in their own PTBs.
|
|
66
|
+
*/
|
|
67
|
+
export function disperseShares(
|
|
68
|
+
tx: Transaction,
|
|
69
|
+
minatoPackageId: string,
|
|
70
|
+
shareType: string,
|
|
71
|
+
balance: TransactionObjectArgument,
|
|
72
|
+
recipients: ShareRecipient[],
|
|
73
|
+
) {
|
|
74
|
+
tx.moveCall({
|
|
75
|
+
target: `${minatoPackageId}::minato::disperse_balance`,
|
|
76
|
+
typeArguments: [shareType],
|
|
77
|
+
arguments: [
|
|
78
|
+
balance,
|
|
79
|
+
tx.makeMoveVec({ type: "u64", elements: recipients.map((r) => tx.pure.u64(r.value)) }),
|
|
80
|
+
tx.makeMoveVec({ type: "address", elements: recipients.map((r) => tx.pure.address(r.address)) }),
|
|
81
|
+
],
|
|
82
|
+
});
|
|
83
|
+
tx.moveCall({ target: "0x2::balance::destroy_zero", typeArguments: [shareType], arguments: [balance] });
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// ============================================================================
|
|
87
|
+
// Share currency (external share / framework)
|
|
88
|
+
// ============================================================================
|
|
89
|
+
|
|
90
|
+
export interface PackageBytecode {
|
|
91
|
+
modules: string[];
|
|
92
|
+
dependencies: string[];
|
|
93
|
+
digest: number[];
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export function publishShareCurrency(bytecode: PackageBytecode): TxThunk {
|
|
97
|
+
return (tx) => {
|
|
98
|
+
const upgradeCap = tx.publish(bytecode);
|
|
99
|
+
tx.moveCall({ target: "0x2::package::make_immutable", arguments: [upgradeCap] });
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const SUI_COIN_REGISTRY_ID = "0xc";
|
|
104
|
+
|
|
105
|
+
export interface InitializeShareCurrencyParams {
|
|
106
|
+
shareCurrencyPackageId: string;
|
|
107
|
+
name: string;
|
|
108
|
+
description: string;
|
|
109
|
+
iconUrl: string;
|
|
110
|
+
treasuryCapRecipient: string;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export function initializeShareCurrency(params: InitializeShareCurrencyParams): TxThunk {
|
|
114
|
+
const { shareCurrencyPackageId, name, description, iconUrl, treasuryCapRecipient } = params;
|
|
115
|
+
return (tx) => {
|
|
116
|
+
const treasuryCap = tx.moveCall({
|
|
117
|
+
target: `${shareCurrencyPackageId}::share::initialize`,
|
|
118
|
+
arguments: [tx.pure.string(name), tx.pure.string(description), tx.pure.string(iconUrl), tx.object(SUI_COIN_REGISTRY_ID)],
|
|
119
|
+
});
|
|
120
|
+
tx.transferObjects([treasuryCap], treasuryCapRecipient);
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// ============================================================================
|
|
125
|
+
// Composition
|
|
126
|
+
// ============================================================================
|
|
127
|
+
|
|
128
|
+
export interface FinalizeCompositionParams extends CompositionParts {
|
|
129
|
+
/** The composition's `share::Share` type. */
|
|
130
|
+
shareType: string;
|
|
131
|
+
shareRecipients: ShareRecipient[];
|
|
132
|
+
adminAddress: string;
|
|
133
|
+
misoPackageId: string;
|
|
134
|
+
minatoPackageId: string;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* The opinionated finish for a composition: disperse its share supply to
|
|
139
|
+
* `shareRecipients`, publish (share) it, and transfer its admin cap to
|
|
140
|
+
* `adminAddress`. Consumers that want different economics skip this and act on
|
|
141
|
+
* the `CompositionParts` from `@misonetwork/sdk`'s `createComposition` directly.
|
|
142
|
+
*/
|
|
143
|
+
export function finalizeComposition(tx: Transaction, params: FinalizeCompositionParams): void {
|
|
144
|
+
disperseShares(tx, params.minatoPackageId, params.shareType, params.balance, params.shareRecipients);
|
|
145
|
+
tx.add(contracts.composition.publish({ package: params.misoPackageId, typeArguments: [params.shareType], arguments: [params.composition, params.adminCap] }));
|
|
146
|
+
tx.transferObjects([params.adminCap], params.adminAddress);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
export interface PublishCompositionParams extends ShareCurrencyBinding {
|
|
150
|
+
title: string;
|
|
151
|
+
royaltyRateBps: number;
|
|
152
|
+
shareRecipients: ShareRecipient[];
|
|
153
|
+
/** Sole owner of the shares + CompositionAdminCap (the zkLogin address). */
|
|
154
|
+
adminAddress: string;
|
|
155
|
+
misoPackageId: string;
|
|
156
|
+
minatoPackageId: string;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/** Convenience: publish a composition end-to-end (createComposition → finalizeComposition). */
|
|
160
|
+
export function publishComposition(params: PublishCompositionParams): TxThunk {
|
|
161
|
+
return (tx) => {
|
|
162
|
+
const parts = createComposition(tx, {
|
|
163
|
+
shareType: params.shareType,
|
|
164
|
+
shareCurrencyId: params.shareCurrencyId,
|
|
165
|
+
shareTreasuryCapId: params.shareTreasuryCapId,
|
|
166
|
+
title: params.title,
|
|
167
|
+
royaltyRateBps: params.royaltyRateBps,
|
|
168
|
+
misoPackageId: params.misoPackageId,
|
|
169
|
+
} satisfies CreateCompositionParams);
|
|
170
|
+
finalizeComposition(tx, {
|
|
171
|
+
...parts,
|
|
172
|
+
shareType: params.shareType,
|
|
173
|
+
shareRecipients: params.shareRecipients,
|
|
174
|
+
adminAddress: params.adminAddress,
|
|
175
|
+
misoPackageId: params.misoPackageId,
|
|
176
|
+
minatoPackageId: params.minatoPackageId,
|
|
177
|
+
});
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// ============================================================================
|
|
182
|
+
// Recording
|
|
183
|
+
// ============================================================================
|
|
184
|
+
|
|
185
|
+
export interface FinalizeRecordingParams extends RecordingParts {
|
|
186
|
+
/** The recording's own `share::Share` type. */
|
|
187
|
+
recordingShareType: string;
|
|
188
|
+
/** Share type of the parent composition. */
|
|
189
|
+
compositionShareType: string;
|
|
190
|
+
shareRecipients: ShareRecipient[];
|
|
191
|
+
adminAddress: string;
|
|
192
|
+
misoPackageId: string;
|
|
193
|
+
minatoPackageId: string;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* The opinionated finish for a recording: publish (share) it, disperse its
|
|
198
|
+
* share supply, and transfer its admin cap to `adminAddress`. A recording has
|
|
199
|
+
* no embedded metadata to set — naming lives in the metadata extension.
|
|
200
|
+
*/
|
|
201
|
+
export function finalizeRecording(tx: Transaction, params: FinalizeRecordingParams): void {
|
|
202
|
+
const typeArguments: [string, string] = [params.recordingShareType, params.compositionShareType];
|
|
203
|
+
tx.add(contracts.recording.publish({ package: params.misoPackageId, typeArguments, arguments: [params.recording, params.adminCap] }));
|
|
204
|
+
disperseShares(tx, params.minatoPackageId, params.recordingShareType, params.balance, params.shareRecipients);
|
|
205
|
+
tx.transferObjects([params.adminCap], params.adminAddress);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
export interface PublishRecordingParams extends ShareCurrencyBinding {
|
|
209
|
+
/**
|
|
210
|
+
* Parent composition, referenced as an on-chain object. Read-only at
|
|
211
|
+
* `recording::new` (only its royalty rate and id are read).
|
|
212
|
+
*/
|
|
213
|
+
compositionId: string;
|
|
214
|
+
/** Share type of the parent composition (the recording's `CompositionShare` phantom). */
|
|
215
|
+
compositionShareType: string;
|
|
216
|
+
shareRecipients: ShareRecipient[];
|
|
217
|
+
adminAddress: string;
|
|
218
|
+
/** Slippage guard for `recording::new` — pass the composition rate you observed (default: protocol max). */
|
|
219
|
+
maxRoyaltyRateBps?: number;
|
|
220
|
+
misoPackageId: string;
|
|
221
|
+
minatoPackageId: string;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/** Convenience: publish a recording against an already-on-chain composition. */
|
|
225
|
+
export function publishRecording(params: PublishRecordingParams): TxThunk {
|
|
226
|
+
return (tx) => {
|
|
227
|
+
const parts = createRecording(tx, {
|
|
228
|
+
shareType: params.shareType,
|
|
229
|
+
shareCurrencyId: params.shareCurrencyId,
|
|
230
|
+
shareTreasuryCapId: params.shareTreasuryCapId,
|
|
231
|
+
compositionShareType: params.compositionShareType,
|
|
232
|
+
composition: tx.object(params.compositionId),
|
|
233
|
+
maxRoyaltyRateBps: params.maxRoyaltyRateBps,
|
|
234
|
+
misoPackageId: params.misoPackageId,
|
|
235
|
+
} satisfies CreateRecordingParams);
|
|
236
|
+
finalizeRecording(tx, {
|
|
237
|
+
...parts,
|
|
238
|
+
recordingShareType: params.shareType,
|
|
239
|
+
compositionShareType: params.compositionShareType,
|
|
240
|
+
shareRecipients: params.shareRecipients,
|
|
241
|
+
adminAddress: params.adminAddress,
|
|
242
|
+
misoPackageId: params.misoPackageId,
|
|
243
|
+
minatoPackageId: params.minatoPackageId,
|
|
244
|
+
});
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
// ============================================================================
|
|
249
|
+
// Composition + Recording (single PTB)
|
|
250
|
+
// ============================================================================
|
|
251
|
+
|
|
252
|
+
export interface PublishCompositionAndRecordingParams {
|
|
253
|
+
title: string;
|
|
254
|
+
royaltyRateBps: number;
|
|
255
|
+
/** Share-currency binding for the composition. */
|
|
256
|
+
composition: ShareCurrencyBinding & { shareRecipients: ShareRecipient[]; adminAddress: string };
|
|
257
|
+
/** Share-currency binding for the recording. */
|
|
258
|
+
recording: ShareCurrencyBinding & { shareRecipients: ShareRecipient[]; adminAddress: string };
|
|
259
|
+
misoPackageId: string;
|
|
260
|
+
minatoPackageId: string;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* Publishes a composition and its recording in a single atomic PTB.
|
|
265
|
+
*
|
|
266
|
+
* The ordering is load-bearing: `recording::new` borrows the composition by
|
|
267
|
+
* immutable reference, so it must run while the composition is still an unshared,
|
|
268
|
+
* transaction-local value — i.e. AFTER `composition::new` but BEFORE
|
|
269
|
+
* `composition::publish` (which moves the composition into `share_object`). Hence:
|
|
270
|
+
* `composition::new` → `recording::new(&comp)` → finalize composition (publish) →
|
|
271
|
+
* finalize recording (publish).
|
|
272
|
+
*/
|
|
273
|
+
export function publishCompositionAndRecording(params: PublishCompositionAndRecordingParams): TxThunk {
|
|
274
|
+
return (tx) => {
|
|
275
|
+
const comp = createComposition(tx, {
|
|
276
|
+
shareType: params.composition.shareType,
|
|
277
|
+
shareCurrencyId: params.composition.shareCurrencyId,
|
|
278
|
+
shareTreasuryCapId: params.composition.shareTreasuryCapId,
|
|
279
|
+
title: params.title,
|
|
280
|
+
royaltyRateBps: params.royaltyRateBps,
|
|
281
|
+
misoPackageId: params.misoPackageId,
|
|
282
|
+
} satisfies CreateCompositionParams);
|
|
283
|
+
|
|
284
|
+
// Borrow the still-unshared composition into recording::new before publishing it.
|
|
285
|
+
// The composition is created in this PTB with a known rate, so the slippage
|
|
286
|
+
// guard pins that exact value — front-running is structurally impossible here.
|
|
287
|
+
const rec = createRecording(tx, {
|
|
288
|
+
shareType: params.recording.shareType,
|
|
289
|
+
shareCurrencyId: params.recording.shareCurrencyId,
|
|
290
|
+
shareTreasuryCapId: params.recording.shareTreasuryCapId,
|
|
291
|
+
compositionShareType: params.composition.shareType,
|
|
292
|
+
composition: comp.composition,
|
|
293
|
+
maxRoyaltyRateBps: params.royaltyRateBps,
|
|
294
|
+
misoPackageId: params.misoPackageId,
|
|
295
|
+
} satisfies CreateRecordingParams);
|
|
296
|
+
|
|
297
|
+
finalizeComposition(tx, {
|
|
298
|
+
...comp,
|
|
299
|
+
shareType: params.composition.shareType,
|
|
300
|
+
shareRecipients: params.composition.shareRecipients,
|
|
301
|
+
adminAddress: params.composition.adminAddress,
|
|
302
|
+
misoPackageId: params.misoPackageId,
|
|
303
|
+
minatoPackageId: params.minatoPackageId,
|
|
304
|
+
});
|
|
305
|
+
|
|
306
|
+
finalizeRecording(tx, {
|
|
307
|
+
...rec,
|
|
308
|
+
recordingShareType: params.recording.shareType,
|
|
309
|
+
compositionShareType: params.composition.shareType,
|
|
310
|
+
shareRecipients: params.recording.shareRecipients,
|
|
311
|
+
adminAddress: params.recording.adminAddress,
|
|
312
|
+
misoPackageId: params.misoPackageId,
|
|
313
|
+
minatoPackageId: params.minatoPackageId,
|
|
314
|
+
});
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
// ============================================================================
|
|
319
|
+
// Release
|
|
320
|
+
// ============================================================================
|
|
321
|
+
|
|
322
|
+
export interface FinalizeReleaseParams extends ReleaseParts {
|
|
323
|
+
/** Recipient of the `ReleaseAdminCap`. */
|
|
324
|
+
adminAddress: string;
|
|
325
|
+
misoPackageId: string;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
/**
|
|
329
|
+
* The opinionated finish for a release: publish (share) it and transfer its
|
|
330
|
+
* admin cap to `adminAddress`.
|
|
331
|
+
*
|
|
332
|
+
* MUST run in the same PTB as the `createRelease` that produced these parts —
|
|
333
|
+
* `Release` is `key`-only with no `drop`, so an unpublished release cannot
|
|
334
|
+
* outlive its transaction. Splitting create from finalize is what lets a caller
|
|
335
|
+
* do something else with the cap (route it to a vault, hand it to another
|
|
336
|
+
* package, keep it for later commands) instead of a plain address transfer.
|
|
337
|
+
*/
|
|
338
|
+
export function finalizeRelease(tx: Transaction, params: FinalizeReleaseParams): void {
|
|
339
|
+
tx.add(release.publish({ package: params.misoPackageId, arguments: [params.release, params.adminCap] }));
|
|
340
|
+
tx.transferObjects([params.adminCap], tx.pure.address(params.adminAddress));
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
export interface TrackInput {
|
|
344
|
+
recordingId: string;
|
|
345
|
+
recordingAdminCapId: string;
|
|
346
|
+
/** Share type of the recording (the deal/track `RecordingShare` phantom). */
|
|
347
|
+
recordingShareType: string;
|
|
348
|
+
/** Share type of the parent composition (the deal/track `CompositionShare` phantom). */
|
|
349
|
+
compositionShareType: string;
|
|
350
|
+
splitBps: number;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
export interface PublishReleaseParams {
|
|
354
|
+
title: string;
|
|
355
|
+
/** The ordered tracklist. Display grouping (discs/sides) is extension data. */
|
|
356
|
+
tracks: TrackInput[];
|
|
357
|
+
releaseRegistryId: string;
|
|
358
|
+
releaseId: string;
|
|
359
|
+
releaseNonce: string;
|
|
360
|
+
misoPackageId: string;
|
|
361
|
+
adminAddress: string;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
function buildTrackVec(
|
|
365
|
+
tx: Transaction,
|
|
366
|
+
misoPackageId: string,
|
|
367
|
+
trackArgs: TransactionObjectArgument[],
|
|
368
|
+
) {
|
|
369
|
+
return tx.makeMoveVec({ type: `${misoPackageId}::track::Track`, elements: trackArgs });
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
/**
|
|
373
|
+
* Convenience: publish a release end-to-end, assembling its tracklist from
|
|
374
|
+
* recording admin caps held by the sender (a deal is created inline per track).
|
|
375
|
+
*/
|
|
376
|
+
export function publishRelease(params: PublishReleaseParams): TxThunk {
|
|
377
|
+
return (tx) => {
|
|
378
|
+
const { misoPackageId } = params;
|
|
379
|
+
const trackArgs = params.tracks.map((t) => {
|
|
380
|
+
const typeArguments: [string, string] = [t.recordingShareType, t.compositionShareType];
|
|
381
|
+
const dealArg = tx.add(
|
|
382
|
+
deal._new({
|
|
383
|
+
package: misoPackageId,
|
|
384
|
+
typeArguments,
|
|
385
|
+
arguments: [tx.object(t.recordingAdminCapId), tx.object(t.recordingId), tx.pure.id(params.releaseId), tx.pure.u16(t.splitBps)],
|
|
386
|
+
}),
|
|
387
|
+
);
|
|
388
|
+
return tx.add(track._new({ package: misoPackageId, typeArguments, arguments: [dealArg, tx.object(t.recordingId)] }));
|
|
389
|
+
});
|
|
390
|
+
const parts = createRelease(
|
|
391
|
+
tx,
|
|
392
|
+
{ title: params.title, nonce: params.releaseNonce, releaseRegistryId: params.releaseRegistryId, misoPackageId },
|
|
393
|
+
buildTrackVec(tx, misoPackageId, trackArgs),
|
|
394
|
+
);
|
|
395
|
+
finalizeRelease(tx, { ...parts, adminAddress: params.adminAddress, misoPackageId });
|
|
396
|
+
};
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
export interface DealInput {
|
|
400
|
+
dealId: string;
|
|
401
|
+
/** The recording the deal is for — `track::new` takes `&Recording` alongside the deal. */
|
|
402
|
+
recordingId: string;
|
|
403
|
+
/** Share type of the recording (the deal/track `RecordingShare` phantom). */
|
|
404
|
+
recordingShareType: string;
|
|
405
|
+
/** Share type of the parent composition (the deal/track `CompositionShare` phantom). */
|
|
406
|
+
compositionShareType: string;
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
export interface PublishReleaseFromDealsParams {
|
|
410
|
+
title: string;
|
|
411
|
+
/** The ordered tracklist, one pre-made deal per track. */
|
|
412
|
+
deals: DealInput[];
|
|
413
|
+
releaseRegistryId: string;
|
|
414
|
+
releaseNonce: string;
|
|
415
|
+
misoPackageId: string;
|
|
416
|
+
adminAddress: string;
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
/**
|
|
420
|
+
* Convenience: publish a release end-to-end from pre-made `Deal`s held by the
|
|
421
|
+
* sender (each deal already pins this release's id).
|
|
422
|
+
*/
|
|
423
|
+
export function publishReleaseFromDeals(params: PublishReleaseFromDealsParams): TxThunk {
|
|
424
|
+
return (tx) => {
|
|
425
|
+
const { misoPackageId } = params;
|
|
426
|
+
const trackArgs = params.deals.map((dl) =>
|
|
427
|
+
tx.add(track._new({
|
|
428
|
+
package: misoPackageId,
|
|
429
|
+
typeArguments: [dl.recordingShareType, dl.compositionShareType],
|
|
430
|
+
arguments: [tx.object(dl.dealId), tx.object(dl.recordingId)],
|
|
431
|
+
})),
|
|
432
|
+
);
|
|
433
|
+
const parts = createRelease(
|
|
434
|
+
tx,
|
|
435
|
+
{ title: params.title, nonce: params.releaseNonce, releaseRegistryId: params.releaseRegistryId, misoPackageId },
|
|
436
|
+
buildTrackVec(tx, misoPackageId, trackArgs),
|
|
437
|
+
);
|
|
438
|
+
finalizeRelease(tx, { ...parts, adminAddress: params.adminAddress, misoPackageId });
|
|
439
|
+
};
|
|
440
|
+
}
|