@misofm/sdk 0.15.4 → 0.15.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/README.md +12 -2
  2. package/dist/client.d.ts +7 -7
  3. package/dist/client.d.ts.map +1 -1
  4. package/dist/client.js +15 -15
  5. package/dist/client.js.map +1 -1
  6. package/dist/contracts/composition_royalty_pool/composition_royalty_pool.d.ts +29 -3
  7. package/dist/contracts/composition_royalty_pool/composition_royalty_pool.d.ts.map +1 -1
  8. package/dist/contracts/composition_royalty_pool/composition_royalty_pool.js +26 -2
  9. package/dist/contracts/composition_royalty_pool/composition_royalty_pool.js.map +1 -1
  10. package/dist/contracts/recording_royalty_pool/recording_royalty_pool.d.ts +30 -3
  11. package/dist/contracts/recording_royalty_pool/recording_royalty_pool.d.ts.map +1 -1
  12. package/dist/contracts/recording_royalty_pool/recording_royalty_pool.js +26 -2
  13. package/dist/contracts/recording_royalty_pool/recording_royalty_pool.js.map +1 -1
  14. package/dist/deployments.d.ts +12 -12
  15. package/dist/deployments.d.ts.map +1 -1
  16. package/dist/deployments.js +6 -6
  17. package/dist/deployments.js.map +1 -1
  18. package/dist/publication.d.ts +4 -0
  19. package/dist/publication.d.ts.map +1 -1
  20. package/dist/publication.js +88 -19
  21. package/dist/publication.js.map +1 -1
  22. package/dist/transactions.d.ts +37 -0
  23. package/dist/transactions.d.ts.map +1 -1
  24. package/dist/transactions.js +65 -3
  25. package/dist/transactions.js.map +1 -1
  26. package/dist/vault.d.ts +6 -0
  27. package/dist/vault.d.ts.map +1 -1
  28. package/dist/vault.js +22 -0
  29. package/dist/vault.js.map +1 -1
  30. package/package.json +2 -2
  31. package/src/client.ts +26 -26
  32. package/src/contracts/composition_royalty_pool/composition_royalty_pool.ts +44 -3
  33. package/src/contracts/recording_royalty_pool/recording_royalty_pool.ts +45 -3
  34. package/src/deployments.ts +11 -11
  35. package/src/publication.ts +122 -18
  36. package/src/transactions.ts +111 -3
  37. package/src/vault.ts +34 -0
@@ -6,10 +6,13 @@
6
6
  *
7
7
  * Share packages and their registered Currency objects must already exist. This
8
8
  * builder then creates every declared Party, Composition, Recording, Track,
9
- * Release, extension, Vault plugin, Pressing, and Listing in one PTB. Fresh raw
10
- * protocol capabilities never leave the transaction: data extensions use them
11
- * directly, Vault-only plugins are configured while each new Vault is still
12
- * owned, and only the selected direct cap or VaultAdminCap is delivered.
9
+ * Release, extension, Vault plugin, Pressing, and Listing in one PTB. Share
10
+ * allocation is explicit: callers may preserve raw address balances or create
11
+ * holder Stakes, register them before a fresh pool is shared, and transfer the
12
+ * registered objects. Fresh raw protocol capabilities never leave the
13
+ * transaction: data extensions use them directly, Vault-only plugins are
14
+ * configured while each new Vault is still owned, and only the selected direct
15
+ * cap or VaultAdminCap is delivered.
13
16
  */
14
17
 
15
18
  import { Transaction, type TransactionObjectArgument } from "@mysten/sui/transactions";
@@ -22,7 +25,14 @@ import {
22
25
  import { derivePartyAdminCapId } from "@misonetwork/sdk/party";
23
26
  import type { MisoPlatformDeployment } from "./deployments.ts";
24
27
  import type { TxThunk } from "./transactions.ts";
25
- import { disperseShares, requiredCommandResult, type ShareRecipient } from "./transactions.ts";
28
+ import {
29
+ createShareStakes,
30
+ disperseShares,
31
+ registerShareStake,
32
+ requiredCommandResult,
33
+ shareRoyaltyPool,
34
+ type ShareRecipient,
35
+ } from "./transactions.ts";
26
36
  import {
27
37
  addRecordingPrimaryArtist,
28
38
  addReleaseCredit,
@@ -59,6 +69,8 @@ import {
59
69
  installRecordingRoyaltyPoolPlugin,
60
70
  installReleaseRevenueDistributorPlugin,
61
71
  invokeWithAdminCap,
72
+ newCompositionRoyaltyPool,
73
+ newRecordingRoyaltyPool,
62
74
  parseVaultCreatedEvent,
63
75
  type AdminCapAuthority,
64
76
  type AdminCapCustody,
@@ -121,6 +133,8 @@ export interface PublicationComposition {
121
133
  readonly title: string;
122
134
  readonly royaltyRateBps: number;
123
135
  readonly shareRecipients: ShareRecipient[];
136
+ /** Defaults to raw address balances for SDK compatibility; the CLI selects `stake`. */
137
+ readonly shareDistribution?: "balance" | "stake";
124
138
  readonly custody: PublicationCustody;
125
139
  readonly credits?: PublicationCompositionCredit[];
126
140
  readonly royaltyPool?: { readonly currencyType: string };
@@ -142,6 +156,8 @@ export type PublicationRecording = PublicationRecordingParent & {
142
156
  readonly shareTreasuryCapId: string;
143
157
  readonly compositionShareType: string;
144
158
  readonly shareRecipients: ShareRecipient[];
159
+ /** Defaults to raw address balances for SDK compatibility; the CLI selects `stake`. */
160
+ readonly shareDistribution?: "balance" | "stake";
145
161
  readonly custody: PublicationCustody;
146
162
  readonly credits?: PublicationRecordingCredit[];
147
163
  readonly royaltyPool?: { readonly currencyType: string };
@@ -314,13 +330,73 @@ function listingPrice(tx: Transaction, p: AtomicPublicationParams, price: Listin
314
330
  : listingContract.newFloorPrice(args));
315
331
  }
316
332
 
333
+ interface PublicationShareAllocation {
334
+ readonly shareType: string;
335
+ readonly shareRecipients: ShareRecipient[];
336
+ readonly shareDistribution?: "balance" | "stake";
337
+ }
338
+
339
+ function allocatePublicationShares(
340
+ tx: Transaction,
341
+ p: AtomicPublicationParams,
342
+ node: PublicationShareAllocation,
343
+ balance: TransactionObjectArgument,
344
+ ): TransactionObjectArgument[] {
345
+ if (node.shareDistribution !== "stake") {
346
+ disperseShares(tx, p.deployment.packages.minato, node.shareType, balance, node.shareRecipients);
347
+ return [];
348
+ }
349
+ return createShareStakes(tx, {
350
+ balance,
351
+ shareType: node.shareType,
352
+ recipients: node.shareRecipients,
353
+ royaltyPoolPackageId: p.deployment.packages.royaltyPool,
354
+ });
355
+ }
356
+
357
+ function registerPublicationStakes(
358
+ tx: Transaction,
359
+ p: AtomicPublicationParams,
360
+ node: PublicationShareAllocation,
361
+ stakes: readonly TransactionObjectArgument[],
362
+ pool: TransactionObjectArgument,
363
+ currencyType: string,
364
+ ): void {
365
+ for (const stake of stakes) {
366
+ registerShareStake(tx, {
367
+ stake,
368
+ pool,
369
+ shareType: node.shareType,
370
+ currencyType,
371
+ royaltyPoolPackageId: p.deployment.packages.royaltyPool,
372
+ });
373
+ }
374
+ }
375
+
376
+ function transferPublicationStakes(
377
+ tx: Transaction,
378
+ node: PublicationShareAllocation,
379
+ stakes: readonly TransactionObjectArgument[],
380
+ ): void {
381
+ if (node.shareDistribution !== "stake") {
382
+ if (stakes.length !== 0) throw new Error("balance distribution unexpectedly created stakes");
383
+ return;
384
+ }
385
+ if (stakes.length !== node.shareRecipients.length) {
386
+ throw new Error("publication stake count does not match share recipient count");
387
+ }
388
+ stakes.forEach((stake, index) => {
389
+ tx.transferObjects([stake], tx.pure.address(node.shareRecipients[index]!.address));
390
+ });
391
+ }
392
+
317
393
  function publishComposition(
318
394
  tx: Transaction,
319
395
  p: AtomicPublicationParams,
320
396
  node: PublicationComposition,
321
397
  parts: WorkParts,
322
398
  ): void {
323
- disperseShares(tx, p.deployment.packages.minato, node.shareType, parts.balance, node.shareRecipients);
399
+ const stakes = allocatePublicationShares(tx, p, node, parts.balance);
324
400
  const typeArguments: [string] = [node.shareType];
325
401
  if (node.custody.kind === "direct") {
326
402
  tx.add(composition.publish({
@@ -329,6 +405,7 @@ function publishComposition(
329
405
  arguments: [parts.work, parts.adminCap],
330
406
  }));
331
407
  disposeNewAdminCap(tx, parts.adminCap, custody(p, node.custody, compositionCapType(p, node.shareType)));
408
+ transferPublicationStakes(tx, node, stakes);
332
409
  return;
333
410
  }
334
411
  custodyNewAdminCap(tx, {
@@ -340,19 +417,31 @@ function publishComposition(
340
417
  if (node.royaltyPool) {
341
418
  installCompositionRoyaltyPoolPlugin(tx, {
342
419
  vault, vaultAdminCap, compositionShareType: node.shareType,
343
- pluginPackageId: p.deployment.packages.compositionRoyaltyPoolPlugin,
420
+ pluginPackageId: p.deployment.packages.vaultCompositionRoyaltyPoolPlugin,
344
421
  });
345
- initializeCompositionRoyaltyPool(tx, {
422
+ const poolParams = {
346
423
  vault, vaultAdminCap, composition: parts.work,
347
424
  compositionShareType: node.shareType,
348
425
  currencyType: node.royaltyPool.currencyType,
349
- pluginPackageId: p.deployment.packages.compositionRoyaltyPoolPlugin,
350
- });
426
+ pluginPackageId: p.deployment.packages.vaultCompositionRoyaltyPoolPlugin,
427
+ };
428
+ if (stakes.length > 0) {
429
+ const pool = newCompositionRoyaltyPool(tx, poolParams);
430
+ registerPublicationStakes(tx, p, node, stakes, pool, node.royaltyPool.currencyType);
431
+ shareRoyaltyPool(tx, {
432
+ pool,
433
+ shareType: node.shareType,
434
+ currencyType: node.royaltyPool.currencyType,
435
+ royaltyPoolPackageId: p.deployment.packages.royaltyPool,
436
+ });
437
+ } else {
438
+ initializeCompositionRoyaltyPool(tx, poolParams);
439
+ }
351
440
  }
352
441
  if (node.routedStake) {
353
442
  installCompositionRoutedStakePlugin(tx, {
354
443
  vault, vaultAdminCap, compositionShareType: node.shareType,
355
- pluginPackageId: p.deployment.packages.compositionRoutedStakePlugin,
444
+ pluginPackageId: p.deployment.packages.vaultCompositionRoutedStakePlugin,
356
445
  });
357
446
  }
358
447
  invokeWithAdminCap(tx, {
@@ -367,6 +456,7 @@ function publishComposition(
367
456
  });
368
457
  },
369
458
  });
459
+ transferPublicationStakes(tx, node, stakes);
370
460
  }
371
461
 
372
462
  function publishRecording(
@@ -376,7 +466,7 @@ function publishRecording(
376
466
  parts: WorkParts,
377
467
  ): void {
378
468
  const typeArguments: [string, string] = [node.shareType, node.compositionShareType];
379
- disperseShares(tx, p.deployment.packages.minato, node.shareType, parts.balance, node.shareRecipients);
469
+ const stakes = allocatePublicationShares(tx, p, node, parts.balance);
380
470
  if (node.custody.kind === "direct") {
381
471
  tx.add(recording.publish({
382
472
  package: p.deployment.protocol.miso,
@@ -384,6 +474,7 @@ function publishRecording(
384
474
  arguments: [parts.work, parts.adminCap],
385
475
  }));
386
476
  disposeNewAdminCap(tx, parts.adminCap, custody(p, node.custody, recordingCapType(p, node.shareType)));
477
+ transferPublicationStakes(tx, node, stakes);
387
478
  return;
388
479
  }
389
480
  custodyNewAdminCap(tx, {
@@ -397,15 +488,27 @@ function publishRecording(
397
488
  vault, vaultAdminCap,
398
489
  recordingShareType: node.shareType,
399
490
  compositionShareType: node.compositionShareType,
400
- pluginPackageId: p.deployment.packages.recordingRoyaltyPoolPlugin,
491
+ pluginPackageId: p.deployment.packages.vaultRecordingRoyaltyPoolPlugin,
401
492
  });
402
- initializeRecordingRoyaltyPool(tx, {
493
+ const poolParams = {
403
494
  vault, vaultAdminCap, recording: parts.work,
404
495
  recordingShareType: node.shareType,
405
496
  compositionShareType: node.compositionShareType,
406
497
  currencyType: node.royaltyPool.currencyType,
407
- pluginPackageId: p.deployment.packages.recordingRoyaltyPoolPlugin,
408
- });
498
+ pluginPackageId: p.deployment.packages.vaultRecordingRoyaltyPoolPlugin,
499
+ };
500
+ if (stakes.length > 0) {
501
+ const pool = newRecordingRoyaltyPool(tx, poolParams);
502
+ registerPublicationStakes(tx, p, node, stakes, pool, node.royaltyPool.currencyType);
503
+ shareRoyaltyPool(tx, {
504
+ pool,
505
+ shareType: node.shareType,
506
+ currencyType: node.royaltyPool.currencyType,
507
+ royaltyPoolPackageId: p.deployment.packages.royaltyPool,
508
+ });
509
+ } else {
510
+ initializeRecordingRoyaltyPool(tx, poolParams);
511
+ }
409
512
  }
410
513
  invokeWithAdminCap(tx, {
411
514
  kind: "vault", vault, vaultAdminCap,
@@ -419,6 +522,7 @@ function publishRecording(
419
522
  });
420
523
  },
421
524
  });
525
+ transferPublicationStakes(tx, node, stakes);
422
526
  }
423
527
 
424
528
  function publishReleaseObject(
@@ -445,7 +549,7 @@ function publishReleaseObject(
445
549
  if (node.revenueDistribution) {
446
550
  installReleaseRevenueDistributorPlugin(tx, {
447
551
  vault, vaultAdminCap,
448
- pluginPackageId: p.deployment.packages.releaseRevenueDistributorPlugin,
552
+ pluginPackageId: p.deployment.packages.vaultReleaseRevenueDistributorPlugin,
449
553
  });
450
554
  }
451
555
  invokeWithAdminCap(tx, {
@@ -747,7 +851,7 @@ export function publishAtomicCatalog(p: AtomicPublicationParams): TxThunk {
747
851
  node.custody.kind === "vault" && node.installWallet !== false
748
852
  ? (vault, vaultAdminCap) => installPartyWalletPlugin(tx, {
749
853
  vault, vaultAdminCap,
750
- pluginPackageId: p.deployment.packages.partyWalletPlugin,
854
+ pluginPackageId: p.deployment.packages.vaultPartyWalletPlugin,
751
855
  })
752
856
  : undefined,
753
857
  ));
@@ -12,9 +12,9 @@
12
12
  // platform-layer call that lives here:
13
13
  //
14
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;
15
+ // (`createComposition`/`createRecording`) — allocating it to raw address
16
+ // balances or composable Stake objects, publishing (sharing) the work, and
17
+ // transferring its admin cap is an opinion about economics;
18
18
  // - minting a release is a platform primitive: core's `release::new` takes an
19
19
  // unconstructible PTB `&mut UID`, so core `release::new(registry, …)` is the
20
20
  // canonical client path. Choosing a track-assembly strategy, publishing
@@ -43,6 +43,8 @@ import {
43
43
  type TxThunk,
44
44
  } from "@misonetwork/sdk";
45
45
  import { asU64, directAdminCap, disposeNewAdminCap, invokeWithAdminCap, type AdminCapAuthority, type AdminCapCustody, type U64Input } from "./vault.ts";
46
+ import * as royaltyPool from "./contracts/royalty_pool/pool.ts";
47
+ import * as royaltyPoolStake from "./contracts/royalty_pool/stake.ts";
46
48
 
47
49
  const { track, release } = contracts;
48
50
 
@@ -96,6 +98,112 @@ export interface ShareRecipient {
96
98
  value: U64Input;
97
99
  }
98
100
 
101
+ export interface CreateShareStakeParams {
102
+ readonly balance: TransactionObjectArgument;
103
+ readonly shareType: string;
104
+ readonly value: U64Input;
105
+ readonly royaltyPoolPackageId: string;
106
+ }
107
+
108
+ /** Split shares from a Balance and return a fresh, unregistered Stake object. */
109
+ export function createShareStake(
110
+ tx: Transaction,
111
+ params: CreateShareStakeParams,
112
+ ): TransactionObjectArgument {
113
+ const value = asU64("share stake value", params.value);
114
+ if (value === 0n) throw new Error("share stake value must be greater than zero");
115
+ const stakeBalance = tx.moveCall({
116
+ target: "0x2::balance::split",
117
+ typeArguments: [params.shareType],
118
+ arguments: [params.balance, tx.pure.u64(value)],
119
+ });
120
+ return tx.add(
121
+ royaltyPoolStake._new({
122
+ package: params.royaltyPoolPackageId,
123
+ typeArguments: [params.shareType],
124
+ arguments: [stakeBalance],
125
+ }),
126
+ );
127
+ }
128
+
129
+ export interface RegisterShareStakeParams {
130
+ readonly stake: TransactionObjectArgument;
131
+ readonly pool: TransactionObjectArgument;
132
+ readonly shareType: string;
133
+ readonly currencyType: string;
134
+ readonly royaltyPoolPackageId: string;
135
+ }
136
+
137
+ /** Register an existing Stake with one RoyaltyPool. */
138
+ export function registerShareStake(
139
+ tx: Transaction,
140
+ params: RegisterShareStakeParams,
141
+ ): void {
142
+ tx.add(
143
+ royaltyPool.registerStake({
144
+ package: params.royaltyPoolPackageId,
145
+ typeArguments: [params.shareType, params.currencyType],
146
+ arguments: [params.pool, params.stake],
147
+ }),
148
+ );
149
+ }
150
+
151
+ export interface CreateShareStakesParams {
152
+ readonly balance: TransactionObjectArgument;
153
+ readonly shareType: string;
154
+ readonly recipients: readonly ShareRecipient[];
155
+ readonly royaltyPoolPackageId: string;
156
+ }
157
+
158
+ /**
159
+ * Convert an entire share Balance into one unregistered Stake per recipient.
160
+ * The emptied Balance is destroyed, so recipient values must consume it exactly.
161
+ * Returned stakes remain caller-controlled for optional registration and transfer.
162
+ */
163
+ export function createShareStakes(
164
+ tx: Transaction,
165
+ params: CreateShareStakesParams,
166
+ ): TransactionObjectArgument[] {
167
+ if (params.recipients.length === 0) {
168
+ throw new Error("share stake recipients must not be empty");
169
+ }
170
+ const values = params.recipients.map((recipient) => {
171
+ const value = asU64("share stake value", recipient.value);
172
+ if (value === 0n) throw new Error("share stake value must be greater than zero");
173
+ return value;
174
+ });
175
+ const stakes = params.recipients.map((recipient, index) => createShareStake(tx, {
176
+ balance: params.balance,
177
+ shareType: params.shareType,
178
+ value: values[index]!,
179
+ royaltyPoolPackageId: params.royaltyPoolPackageId,
180
+ }));
181
+ tx.moveCall({
182
+ target: "0x2::balance::destroy_zero",
183
+ typeArguments: [params.shareType],
184
+ arguments: [params.balance],
185
+ });
186
+ return stakes;
187
+ }
188
+
189
+ export interface ShareRoyaltyPoolParams {
190
+ readonly pool: TransactionObjectArgument;
191
+ readonly shareType: string;
192
+ readonly currencyType: string;
193
+ readonly royaltyPoolPackageId: string;
194
+ }
195
+
196
+ /** Consume an unshared RoyaltyPool and make it globally accessible. */
197
+ export function shareRoyaltyPool(tx: Transaction, params: ShareRoyaltyPoolParams): void {
198
+ tx.add(
199
+ royaltyPool.share({
200
+ package: params.royaltyPoolPackageId,
201
+ typeArguments: [params.shareType, params.currencyType],
202
+ arguments: [params.pool],
203
+ }),
204
+ );
205
+ }
206
+
99
207
  /**
100
208
  * Splits a share `Balance` across `recipients` via `minato::disperse_balance`, then
101
209
  * destroys the emptied balance. Exposed for consumers assembling custom share
package/src/vault.ts CHANGED
@@ -267,6 +267,21 @@ export interface InitializeCompositionRoyaltyPoolParams
267
267
  readonly currencyType: string;
268
268
  }
269
269
 
270
+ /** Create the canonical pool without sharing it so callers can configure fresh stakes first. */
271
+ export function newCompositionRoyaltyPool(
272
+ tx: Transaction,
273
+ params: InitializeCompositionRoyaltyPoolParams,
274
+ ): TransactionObjectArgument {
275
+ return tx.add(
276
+ compositionRoyaltyPool.newPool({
277
+ package: params.pluginPackageId,
278
+ typeArguments: [params.compositionShareType, params.currencyType],
279
+ arguments: [params.vault, params.composition, params.vaultAdminCap],
280
+ }),
281
+ );
282
+ }
283
+
284
+ /** Create and immediately share the canonical Composition royalty pool. */
270
285
  export function initializeCompositionRoyaltyPool(
271
286
  tx: Transaction,
272
287
  params: InitializeCompositionRoyaltyPoolParams,
@@ -470,6 +485,25 @@ export interface InitializeRecordingRoyaltyPoolParams
470
485
  readonly currencyType: string;
471
486
  }
472
487
 
488
+ /** Create the canonical pool without sharing it so callers can configure fresh stakes first. */
489
+ export function newRecordingRoyaltyPool(
490
+ tx: Transaction,
491
+ params: InitializeRecordingRoyaltyPoolParams,
492
+ ): TransactionObjectArgument {
493
+ return tx.add(
494
+ recordingRoyaltyPool.newPool({
495
+ package: params.pluginPackageId,
496
+ typeArguments: [
497
+ params.recordingShareType,
498
+ params.compositionShareType,
499
+ params.currencyType,
500
+ ],
501
+ arguments: [params.vault, params.recording, params.vaultAdminCap],
502
+ }),
503
+ );
504
+ }
505
+
506
+ /** Create and immediately share the canonical Recording royalty pool. */
473
507
  export function initializeRecordingRoyaltyPool(
474
508
  tx: Transaction,
475
509
  params: InitializeRecordingRoyaltyPoolParams,