@misofm/sdk 0.15.2 → 0.15.4

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 (60) hide show
  1. package/README.md +11 -0
  2. package/dist/client.d.ts +4 -4
  3. package/dist/client.js +4 -4
  4. package/dist/client.js.map +1 -1
  5. package/dist/contracts/composition_royalty_pool/composition_royalty_pool.d.ts +11 -8
  6. package/dist/contracts/composition_royalty_pool/composition_royalty_pool.d.ts.map +1 -1
  7. package/dist/contracts/composition_royalty_pool/composition_royalty_pool.js +9 -6
  8. package/dist/contracts/composition_royalty_pool/composition_royalty_pool.js.map +1 -1
  9. package/dist/contracts/miso_pressing/certificate.d.ts +1 -1
  10. package/dist/contracts/miso_pressing/certificate.d.ts.map +1 -1
  11. package/dist/contracts/miso_pressing/certificate.js +1 -1
  12. package/dist/contracts/miso_pressing/certificate.js.map +1 -1
  13. package/dist/contracts/miso_pressing/listing.d.ts +5 -5
  14. package/dist/contracts/miso_pressing/listing.js +5 -5
  15. package/dist/contracts/miso_pressing/pressing.d.ts +10 -10
  16. package/dist/contracts/miso_pressing/pressing.js +7 -7
  17. package/dist/contracts/party_wallet/party_wallet.d.ts +42 -17
  18. package/dist/contracts/party_wallet/party_wallet.d.ts.map +1 -1
  19. package/dist/contracts/party_wallet/party_wallet.js +40 -15
  20. package/dist/contracts/party_wallet/party_wallet.js.map +1 -1
  21. package/dist/contracts/recording_royalty_pool/recording_royalty_pool.d.ts +13 -8
  22. package/dist/contracts/recording_royalty_pool/recording_royalty_pool.d.ts.map +1 -1
  23. package/dist/contracts/recording_royalty_pool/recording_royalty_pool.js +11 -6
  24. package/dist/contracts/recording_royalty_pool/recording_royalty_pool.js.map +1 -1
  25. package/dist/contracts/royalty_pool/pool.d.ts +14 -10
  26. package/dist/contracts/royalty_pool/pool.d.ts.map +1 -1
  27. package/dist/contracts/royalty_pool/pool.js +12 -8
  28. package/dist/contracts/royalty_pool/pool.js.map +1 -1
  29. package/dist/read/catalog.d.ts +2 -1
  30. package/dist/read/catalog.d.ts.map +1 -1
  31. package/dist/read/catalog.js +17 -1
  32. package/dist/read/catalog.js.map +1 -1
  33. package/dist/read/config.d.ts +2 -0
  34. package/dist/read/config.d.ts.map +1 -1
  35. package/dist/read/config.js +1 -0
  36. package/dist/read/config.js.map +1 -1
  37. package/dist/read/types.d.ts +2 -0
  38. package/dist/read/types.d.ts.map +1 -1
  39. package/dist/release-extensions.d.ts +7 -0
  40. package/dist/release-extensions.d.ts.map +1 -1
  41. package/dist/release-extensions.js +29 -4
  42. package/dist/release-extensions.js.map +1 -1
  43. package/dist/vault.d.ts +27 -10
  44. package/dist/vault.d.ts.map +1 -1
  45. package/dist/vault.js +53 -7
  46. package/dist/vault.js.map +1 -1
  47. package/package.json +1 -1
  48. package/src/client.ts +4 -4
  49. package/src/contracts/composition_royalty_pool/composition_royalty_pool.ts +14 -11
  50. package/src/contracts/miso_pressing/certificate.ts +1 -1
  51. package/src/contracts/miso_pressing/listing.ts +5 -5
  52. package/src/contracts/miso_pressing/pressing.ts +7 -7
  53. package/src/contracts/party_wallet/party_wallet.ts +63 -24
  54. package/src/contracts/recording_royalty_pool/recording_royalty_pool.ts +16 -11
  55. package/src/contracts/royalty_pool/pool.ts +17 -13
  56. package/src/read/catalog.ts +25 -3
  57. package/src/read/config.ts +3 -0
  58. package/src/read/types.ts +2 -0
  59. package/src/release-extensions.ts +44 -1
  60. package/src/vault.ts +95 -14
@@ -38,9 +38,9 @@
38
38
  * Nothing here is ever destroyed, sealed, or wound down — deleting a pressing
39
39
  * would strand its whole derived subtree, so there is no destructor at all. The
40
40
  * run's lifecycle is `Scheduled → Active → Paused → Active`: it opens itself at
41
- * its scheduled start (no artist transaction, and nobody can buy early), then the
42
- * artist stops and starts it at will. The first transition is real, not computed —
43
- * the first sale past the start rewrites `Scheduled` to `Active` inside
41
+ * its drop moment (no artist transaction, and nobody can buy early), and after
42
+ * that the artist stops and starts it at will. The first transition is real, not
43
+ * computed — the first sale past the start rewrites `Scheduled` to `Active` inside
44
44
  * `mint_next`, which is why `Scheduled` only ever describes a run still waiting.
45
45
  * Below it, each listing's `Enabled | Disabled` governs one currency. A run that
46
46
  * is paused or not yet open sells in no currency, whatever the listings say.
@@ -73,8 +73,8 @@ export const PressingKey = new MoveTuple({ name: `${$moduleName}::PressingKey`,
73
73
  export const PressingAdminCapKey = new MoveTuple({ name: `${$moduleName}::PressingAdminCapKey`, fields: [bcs.bool()] });
74
74
  /**
75
75
  * Whether the run sells, over every currency at once. The lifecycle runs
76
- * `Scheduled → Active → Paused → Active`: a pressing opens itself at its scheduled
77
- * start, then the artist stops and starts it at will.
76
+ * `Scheduled → Active → Paused → Active`: a pressing opens itself at its drop
77
+ * moment, then the artist stops and starts it at will.
78
78
  */
79
79
  export const PressingState = new MoveEnum({ name: `${$moduleName}::PressingState`, fields: {
80
80
  /**
@@ -85,7 +85,7 @@ export const PressingState = new MoveEnum({ name: `${$moduleName}::PressingState
85
85
  * `Active` (in `mint_next`, before any sales logic), so a run reads `Scheduled`
86
86
  * only while it is still waiting. Between the start and that first sale the run
87
87
  * already sells — `is_selling` answers against the clock — so nobody has to go
88
- * first for the Pressing to be open.
88
+ * first for the drop to be open.
89
89
  *
90
90
  * Consequence worth knowing: once the transition fires the start time is gone from
91
91
  * the object. `PressingOpenedEvent` and `PressingStateChangedEvent` carry it, so
@@ -190,7 +190,7 @@ export interface NewOptions {
190
190
  ];
191
191
  }
192
192
  /**
193
- * Open a release's pressing in `state` — `Scheduled` for a future start, `Active`
193
+ * Open a release's pressing in `state` — `Scheduled` for a drop moment, `Active`
194
194
  * to sell immediately, `Paused` to set it up quietly. Returns it unshared, so the
195
195
  * same transaction can list it (`listing::new`) before `share` puts it on chain,
196
196
  * plus the cap that governs it from here on. Neither value has `drop`, so neither
@@ -8,11 +8,12 @@
8
8
  *
9
9
  * Anyone may address objects or funds to a Party ID. This plugin is the bounded
10
10
  * withdrawal door: it temporarily leases the matching `PartyAdminCap`, uses it
11
- * only to reach that Party's UID, returns it to the Vault, and then transfers the
12
- * withdrawn object or coin to the recipient selected by the Vault administrator.
11
+ * only to reach that Party's UID, and returns it to the Vault. Object withdrawals
12
+ * transfer to the recipient selected by the Vault administrator; monetary
13
+ * withdrawals return a composable `Balance` for the caller's PTB to consume.
13
14
  *
14
15
  * Installation alone never makes withdrawals permissionless. Every production
15
- * withdrawal is an `entry fun` requiring the matching `VaultAdminCap`, and no
16
+ * withdrawal is a `public fun` requiring the matching `VaultAdminCap`, and no
16
17
  * endpoint returns the leased capability, its borrow receipt, or a privileged
17
18
  * reference. The Party itself stores no plugin data.
18
19
  */
@@ -182,7 +183,6 @@ export interface ReceiveCoinsArguments {
182
183
  party: RawTransactionArgument<string>;
183
184
  vaultAdminCap: RawTransactionArgument<string>;
184
185
  coins: TransactionArgument;
185
- recipient: RawTransactionArgument<string>;
186
186
  }
187
187
  export interface ReceiveCoinsOptions {
188
188
  package?: string;
@@ -190,16 +190,15 @@ export interface ReceiveCoinsOptions {
190
190
  vault: RawTransactionArgument<string>,
191
191
  party: RawTransactionArgument<string>,
192
192
  vaultAdminCap: RawTransactionArgument<string>,
193
- coins: TransactionArgument,
194
- recipient: RawTransactionArgument<string>
193
+ coins: TransactionArgument
195
194
  ];
196
195
  typeArguments: [
197
196
  string
198
197
  ];
199
198
  }
200
199
  /**
201
- * Receive coin objects of one currency, merge them, and transfer the resulting
202
- * Coin to `recipient`.
200
+ * Receive coin objects of one currency, merge them, and return their combined
201
+ * Balance for the caller's PTB to consume.
203
202
  *
204
203
  * Aborts with `ENothingToReceive` if `coins` is empty. It also aborts if the Vault
205
204
  * administrator, plugin installation, Party capability, or a receiving ticket is
@@ -211,10 +210,9 @@ export function receiveCoins(options: ReceiveCoinsOptions) {
211
210
  null,
212
211
  null,
213
212
  null,
214
- 'vector<null>',
215
- 'address'
213
+ 'vector<null>'
216
214
  ] satisfies (string | null)[];
217
- const parameterNames = ["vault", "party", "vaultAdminCap", "coins", "recipient"];
215
+ const parameterNames = ["vault", "party", "vaultAdminCap", "coins"];
218
216
  return (tx: Transaction) => tx.moveCall({
219
217
  package: packageAddress,
220
218
  module: 'party_wallet',
@@ -223,48 +221,89 @@ export function receiveCoins(options: ReceiveCoinsOptions) {
223
221
  typeArguments: options.typeArguments
224
222
  });
225
223
  }
226
- export interface RedeemCoinArguments {
224
+ export interface RedeemBalanceArguments {
227
225
  vault: RawTransactionArgument<string>;
228
226
  party: RawTransactionArgument<string>;
229
227
  vaultAdminCap: RawTransactionArgument<string>;
230
228
  value: RawTransactionArgument<number | bigint>;
231
- recipient: RawTransactionArgument<string>;
232
229
  }
233
- export interface RedeemCoinOptions {
230
+ export interface RedeemBalanceOptions {
234
231
  package?: string;
235
- arguments: RedeemCoinArguments | [
232
+ arguments: RedeemBalanceArguments | [
236
233
  vault: RawTransactionArgument<string>,
237
234
  party: RawTransactionArgument<string>,
238
235
  vaultAdminCap: RawTransactionArgument<string>,
239
- value: RawTransactionArgument<number | bigint>,
240
- recipient: RawTransactionArgument<string>
236
+ value: RawTransactionArgument<number | bigint>
241
237
  ];
242
238
  typeArguments: [
243
239
  string
244
240
  ];
245
241
  }
246
242
  /**
247
- * Redeem `value` from the Party's accumulator balance, create a Coin, and transfer
248
- * it to `recipient`.
243
+ * Redeem `value` from the Party's accumulator and return a Balance for the
244
+ * caller's PTB to consume.
249
245
  *
250
246
  * Aborts if the Vault administrator is wrong, the plugin is not installed, the
251
247
  * Vault contains another Party's cap, `value` is zero, or the accumulator cannot
252
248
  * cover the requested amount.
253
249
  */
254
- export function redeemCoin(options: RedeemCoinOptions) {
250
+ export function redeemBalance(options: RedeemBalanceOptions) {
255
251
  const packageAddress = options.package ?? '@local-pkg/party_wallet';
256
252
  const argumentsTypes = [
257
253
  null,
258
254
  null,
259
255
  null,
260
- 'u64',
261
- 'address'
256
+ 'u64'
257
+ ] satisfies (string | null)[];
258
+ const parameterNames = ["vault", "party", "vaultAdminCap", "value"];
259
+ return (tx: Transaction) => tx.moveCall({
260
+ package: packageAddress,
261
+ module: 'party_wallet',
262
+ function: 'redeem_balance',
263
+ arguments: normalizeMoveArguments(options.arguments, argumentsTypes, parameterNames),
264
+ typeArguments: options.typeArguments
265
+ });
266
+ }
267
+ export interface SweepBalanceArguments {
268
+ vault: RawTransactionArgument<string>;
269
+ party: RawTransactionArgument<string>;
270
+ root: RawTransactionArgument<string>;
271
+ vaultAdminCap: RawTransactionArgument<string>;
272
+ }
273
+ export interface SweepBalanceOptions {
274
+ package?: string;
275
+ arguments: SweepBalanceArguments | [
276
+ vault: RawTransactionArgument<string>,
277
+ party: RawTransactionArgument<string>,
278
+ root: RawTransactionArgument<string>,
279
+ vaultAdminCap: RawTransactionArgument<string>
280
+ ];
281
+ typeArguments: [
282
+ string
283
+ ];
284
+ }
285
+ /**
286
+ * Redeem the settled `Currency` amount reported for the Party address and return a
287
+ * Balance for the caller's PTB to consume.
288
+ *
289
+ * Funds sent during the current consensus commit are not yet settled and remain
290
+ * available for a later sweep. Aborts with `ENoSettledFunds` when the settled
291
+ * amount is zero. The framework caps the reported amount at `u64::MAX`; any excess
292
+ * remains for a later sweep.
293
+ */
294
+ export function sweepBalance(options: SweepBalanceOptions) {
295
+ const packageAddress = options.package ?? '@local-pkg/party_wallet';
296
+ const argumentsTypes = [
297
+ null,
298
+ null,
299
+ null,
300
+ null
262
301
  ] satisfies (string | null)[];
263
- const parameterNames = ["vault", "party", "vaultAdminCap", "value", "recipient"];
302
+ const parameterNames = ["vault", "party", "root", "vaultAdminCap"];
264
303
  return (tx: Transaction) => tx.moveCall({
265
304
  package: packageAddress,
266
305
  module: 'party_wallet',
267
- function: 'redeem_coin',
306
+ function: 'sweep_balance',
268
307
  arguments: normalizeMoveArguments(options.arguments, argumentsTypes, parameterNames),
269
308
  typeArguments: options.typeArguments
270
309
  });
@@ -157,19 +157,19 @@ export function receiveAndDeposit(options: ReceiveAndDepositOptions) {
157
157
  typeArguments: options.typeArguments
158
158
  });
159
159
  }
160
- export interface RedeemAndDepositArguments {
160
+ export interface SweepAndDepositArguments {
161
161
  vault: RawTransactionArgument<string>;
162
162
  recording: RawTransactionArgument<string>;
163
163
  pool: RawTransactionArgument<string>;
164
- value: RawTransactionArgument<number | bigint>;
164
+ root: RawTransactionArgument<string>;
165
165
  }
166
- export interface RedeemAndDepositOptions {
166
+ export interface SweepAndDepositOptions {
167
167
  package?: string;
168
- arguments: RedeemAndDepositArguments | [
168
+ arguments: SweepAndDepositArguments | [
169
169
  vault: RawTransactionArgument<string>,
170
170
  recording: RawTransactionArgument<string>,
171
171
  pool: RawTransactionArgument<string>,
172
- value: RawTransactionArgument<number | bigint>
172
+ root: RawTransactionArgument<string>
173
173
  ];
174
174
  typeArguments: [
175
175
  string,
@@ -178,22 +178,27 @@ export interface RedeemAndDepositOptions {
178
178
  ];
179
179
  }
180
180
  /**
181
- * Redeem funds accumulated at the Recording address and deposit them into its
182
- * canonical pool. Anyone may crank this after installation.
181
+ * Redeem the settled `Currency` amount reported for the Recording address and
182
+ * deposit it into the canonical pool. Anyone may crank this after installation.
183
+ *
184
+ * Funds sent during the current consensus commit are not yet settled and remain
185
+ * available for a later sweep. Aborts with `ENoSettledFunds` when the settled
186
+ * amount is zero. The framework caps the reported amount at `u64::MAX`; any excess
187
+ * remains for a later sweep.
183
188
  */
184
- export function redeemAndDeposit(options: RedeemAndDepositOptions) {
189
+ export function sweepAndDeposit(options: SweepAndDepositOptions) {
185
190
  const packageAddress = options.package ?? '@local-pkg/recording_royalty_pool';
186
191
  const argumentsTypes = [
187
192
  null,
188
193
  null,
189
194
  null,
190
- 'u64'
195
+ null
191
196
  ] satisfies (string | null)[];
192
- const parameterNames = ["vault", "recording", "pool", "value"];
197
+ const parameterNames = ["vault", "recording", "pool", "root"];
193
198
  return (tx: Transaction) => tx.moveCall({
194
199
  package: packageAddress,
195
200
  module: 'recording_royalty_pool',
196
- function: 'redeem_and_deposit',
201
+ function: 'sweep_and_deposit',
197
202
  arguments: normalizeMoveArguments(options.arguments, argumentsTypes, parameterNames),
198
203
  typeArguments: options.typeArguments
199
204
  });
@@ -29,7 +29,7 @@
29
29
  * track's split there). The address is a pure function of
30
30
  * `(parent_id, Share, Currency)`, so senders need the pool neither shared nor
31
31
  * even created yet; a later `new` claims exactly that ID — and can only be the
32
- * correctly-typed, shared pool. `receive_and_deposit` and `redeem_and_deposit`
32
+ * correctly-typed, shared pool. `receive_and_deposit` and `sweep_and_deposit`
33
33
  * fold such funds into the accumulator, permissionlessly: anyone can complete
34
34
  * the delivery. Both run through `deposit`, which aborts while no shares are
35
35
  * staked — and the pool has no other withdrawal path — so funds at the pool's
@@ -236,15 +236,15 @@ export function receiveAndDeposit(options: ReceiveAndDepositOptions) {
236
236
  typeArguments: options.typeArguments
237
237
  });
238
238
  }
239
- export interface RedeemAndDepositArguments {
239
+ export interface SweepAndDepositArguments {
240
240
  self: RawTransactionArgument<string>;
241
- value: RawTransactionArgument<number | bigint>;
241
+ root: RawTransactionArgument<string>;
242
242
  }
243
- export interface RedeemAndDepositOptions {
243
+ export interface SweepAndDepositOptions {
244
244
  package?: string;
245
- arguments: RedeemAndDepositArguments | [
245
+ arguments: SweepAndDepositArguments | [
246
246
  self: RawTransactionArgument<string>,
247
- value: RawTransactionArgument<number | bigint>
247
+ root: RawTransactionArgument<string>
248
248
  ];
249
249
  typeArguments: [
250
250
  string,
@@ -252,21 +252,25 @@ export interface RedeemAndDepositOptions {
252
252
  ];
253
253
  }
254
254
  /**
255
- * Redeem `value` base units from the pool's funds-accumulator and fold them into
256
- * the accumulator. Recovery path for funds delivered via Sui's `send_funds`
257
- * mechanism rather than via the canonical extension path.
255
+ * Redeem the pool's funds settled at the start of the current consensus commit and
256
+ * fold them into the royalty accumulator. Recovery path for funds delivered via
257
+ * Sui's `send_funds` mechanism rather than via the canonical extension path.
258
+ *
259
+ * The framework returns at most `u64::MAX` per call. Any excess, along with funds
260
+ * sent later in the current commit, remains for a subsequent sweep. Aborts with
261
+ * `ENoSettledFunds` when no positive amount is currently eligible.
258
262
  */
259
- export function redeemAndDeposit(options: RedeemAndDepositOptions) {
263
+ export function sweepAndDeposit(options: SweepAndDepositOptions) {
260
264
  const packageAddress = options.package ?? '@local-pkg/royalty_pool';
261
265
  const argumentsTypes = [
262
266
  null,
263
- 'u64'
267
+ null
264
268
  ] satisfies (string | null)[];
265
- const parameterNames = ["self", "value"];
269
+ const parameterNames = ["self", "root"];
266
270
  return (tx: Transaction) => tx.moveCall({
267
271
  package: packageAddress,
268
272
  module: 'pool',
269
- function: 'redeem_and_deposit',
273
+ function: 'sweep_and_deposit',
270
274
  arguments: normalizeMoveArguments(options.arguments, argumentsTypes, parameterNames),
271
275
  typeArguments: options.typeArguments
272
276
  });
@@ -31,6 +31,10 @@ import {
31
31
  releaseCreditsFieldId,
32
32
  type CreditView,
33
33
  } from "../credits.ts";
34
+ import {
35
+ parseReleaseKindContent,
36
+ releaseKindFieldId,
37
+ } from "../release-extensions.ts";
34
38
  import { getTrackCreditsByRecordingIds } from "../catalog.ts";
35
39
  import { getReleaseById, getReleasesByIds, isNotFound } from "@misonetwork/sdk";
36
40
  import type { Release } from "@misonetwork/sdk";
@@ -229,12 +233,13 @@ export async function readReleaseCover(
229
233
  return toCover(client.config.walrusAggregatorUrl, covers[releaseId] ?? null);
230
234
  }
231
235
 
232
- export type ReleaseResourceInclude = "cover" | "credits";
236
+ export type ReleaseResourceInclude = "cover" | "credits" | "kind";
233
237
 
234
238
  export interface ReleaseResources {
235
239
  release: Release;
236
240
  cover?: Cover | null;
237
241
  credits?: Credit[];
242
+ kind?: string | null;
238
243
  }
239
244
 
240
245
  /**
@@ -249,16 +254,21 @@ export async function getReleaseResources(
249
254
  ): Promise<ReleaseResources> {
250
255
  const wantsCover = include.includes("cover");
251
256
  const wantsCredits = include.includes("credits");
257
+ const wantsKind = include.includes("kind");
252
258
  const coverFieldIds = wantsCover
253
259
  ? [releaseCoverFieldId(releaseId, client.config.protocol.releaseCoverArt)]
254
260
  : [];
255
261
  const creditsFieldId = wantsCredits
256
262
  ? releaseCreditsFieldId(releaseId, client.config.protocol.releaseCredits)
257
263
  : null;
264
+ const kindFieldId = wantsKind
265
+ ? releaseKindFieldId(releaseId, client.config.protocol.releaseKind)
266
+ : null;
258
267
  const objectIds = [
259
268
  releaseId,
260
269
  ...coverFieldIds,
261
270
  ...(creditsFieldId ? [creditsFieldId] : []),
271
+ ...(kindFieldId ? [kindFieldId] : []),
262
272
  ];
263
273
  const { objects } = await client.protocol.core.getObjects({
264
274
  objectIds,
@@ -303,10 +313,21 @@ export async function getReleaseResources(
303
313
  }
304
314
  credits = toCredits(view);
305
315
  }
316
+ let kind: string | null | undefined;
317
+ if (wantsKind) {
318
+ const object = objects[
319
+ 1 + coverFieldIds.length + (creditsFieldId ? 1 : 0)
320
+ ];
321
+ kind =
322
+ object && !(object instanceof Error) && object.content
323
+ ? parseReleaseKindContent(object.content)
324
+ : null;
325
+ }
306
326
  return {
307
327
  release,
308
328
  ...(wantsCover ? { cover: cover ?? null } : {}),
309
329
  ...(wantsCredits ? { credits: credits ?? [] } : {}),
330
+ ...(wantsKind ? { kind: kind ?? null } : {}),
310
331
  };
311
332
  }
312
333
 
@@ -332,10 +353,10 @@ export async function getReleaseDetail(
332
353
  releaseId: string,
333
354
  options: GetReleaseOptions = {},
334
355
  ): Promise<ReleaseDetail> {
335
- const { release, cover, credits } = await getReleaseResources(
356
+ const { release, cover, credits, kind } = await getReleaseResources(
336
357
  client,
337
358
  releaseId,
338
- ["cover", "credits"],
359
+ ["cover", "credits", "kind"],
339
360
  );
340
361
 
341
362
  const recordingIds = release.tracks.map((track) => track.recordingId);
@@ -356,6 +377,7 @@ export async function getReleaseDetail(
356
377
  id: release.id,
357
378
  title: release.title,
358
379
  subtitle: null,
380
+ kind: kind ?? null,
359
381
  state: toWorkState(release.state),
360
382
  publishedAtMs:
361
383
  release.state.type === "Published" ? release.state.timestampMs : null,
@@ -33,6 +33,8 @@ export interface ProtocolIds {
33
33
  vault: string;
34
34
  /** `release_cover_art` — the release cover extension. */
35
35
  releaseCoverArt: string;
36
+ /** `release_kind` — the Release's optional self-declared kind. */
37
+ releaseKind: string;
36
38
  /** `composition_credits` / `recording_credits` / `release_credits` extensions. */
37
39
  compositionCredits: string;
38
40
  recordingCredits: string;
@@ -96,6 +98,7 @@ export function misoConfig(network: Network, overrides: MisoConfigOverrides = {}
96
98
  record: platform.packages.record,
97
99
  vault: platform.packages.vault,
98
100
  releaseCoverArt: platform.packages.releaseCoverArt,
101
+ releaseKind: platform.packages.releaseKind,
99
102
  compositionCredits: platform.packages.compositionCredits,
100
103
  recordingCredits: platform.packages.recordingCredits,
101
104
  releaseCredits: platform.packages.releaseCredits,
package/src/read/types.ts CHANGED
@@ -82,6 +82,8 @@ export interface ReleaseDetail {
82
82
  id: string;
83
83
  title: string;
84
84
  subtitle: string | null;
85
+ /** Self-declared `release_kind`, or null when no extension is attached. */
86
+ kind: string | null;
85
87
  state: WorkState;
86
88
  /** Publish time (ms), or null while unpublished. */
87
89
  publishedAtMs: number | null;
@@ -5,7 +5,9 @@
5
5
  // intent aggregates these concerns, but every value is written by its own
6
6
  // independently deployed extension package.
7
7
 
8
- import { deriveObjectID } from "@mysten/sui/utils";
8
+ import type { ClientWithCoreApi } from "@mysten/sui/client";
9
+ import { bcs } from "@mysten/sui/bcs";
10
+ import { deriveDynamicFieldID, deriveObjectID } from "@mysten/sui/utils";
9
11
  import type {
10
12
  Transaction,
11
13
  TransactionArgument,
@@ -59,6 +61,47 @@ export function setReleaseKind(p: SetReleaseKindParams): TxThunk {
59
61
  };
60
62
  }
61
63
 
64
+ const ReleaseKindField = bcs.struct("Field", {
65
+ id: bcs.Address,
66
+ name: releaseKind.ExtensionKey,
67
+ value: bcs.string(),
68
+ });
69
+ const RELEASE_KIND_KEY_BYTES = releaseKind.ExtensionKey.serialize([
70
+ false,
71
+ ]).toBytes();
72
+
73
+ /** Deterministic dynamic-field id for a Release's optional self-declared kind. */
74
+ export function releaseKindFieldId(
75
+ releaseId: string,
76
+ releaseKindPackageId: string,
77
+ ): string {
78
+ return deriveDynamicFieldID(
79
+ releaseId,
80
+ `${releaseKindPackageId}::release_kind::ExtensionKey`,
81
+ RELEASE_KIND_KEY_BYTES,
82
+ );
83
+ }
84
+
85
+ /** Parse the dynamic field storing `Option<String>` as its present string. */
86
+ export function parseReleaseKindContent(content: Uint8Array): string {
87
+ return ReleaseKindField.parse(content).value;
88
+ }
89
+
90
+ /** Read a Release's self-declared kind, or `null` when the extension is absent. */
91
+ export async function getReleaseKind(
92
+ client: ClientWithCoreApi,
93
+ releaseId: string,
94
+ releaseKindPackageId: string,
95
+ ): Promise<string | null> {
96
+ const { objects } = await client.core.getObjects({
97
+ objectIds: [releaseKindFieldId(releaseId, releaseKindPackageId)],
98
+ include: { content: true },
99
+ });
100
+ const object = objects[0];
101
+ if (!object || object instanceof Error || !object.content) return null;
102
+ return parseReleaseKindContent(object.content);
103
+ }
104
+
62
105
  export type SetReleaseDescriptionParams = ReleaseExtensionTarget & {
63
106
  description: string;
64
107
  releaseDescriptionPackageId: string;
package/src/vault.ts CHANGED
@@ -284,6 +284,7 @@ export interface CompositionRoyaltyPoolCrankParams {
284
284
  readonly vault: TransactionObjectArgument;
285
285
  readonly composition: TransactionObjectArgument;
286
286
  readonly pool: TransactionObjectArgument;
287
+ readonly accumulatorRoot: TransactionObjectArgument;
287
288
  readonly compositionShareType: string;
288
289
  readonly currencyType: string;
289
290
  readonly pluginPackageId: string;
@@ -307,16 +308,16 @@ export function asU64(name: string, value: U64Input): bigint {
307
308
  return parsed;
308
309
  }
309
310
 
310
- /** Permissionless crank: redeem address funds into the canonical pool. */
311
- export function redeemCompositionRoyaltyPool(
311
+ /** Permissionless crank: sweep settled address funds into the canonical pool. */
312
+ export function sweepCompositionRoyaltyPool(
312
313
  tx: Transaction,
313
- params: CompositionRoyaltyPoolCrankParams & { readonly value: U64Input },
314
+ params: CompositionRoyaltyPoolCrankParams,
314
315
  ): void {
315
316
  tx.add(
316
- compositionRoyaltyPool.redeemAndDeposit({
317
+ compositionRoyaltyPool.sweepAndDeposit({
317
318
  package: params.pluginPackageId,
318
319
  typeArguments: [params.compositionShareType, params.currencyType],
319
- arguments: [params.vault, params.composition, params.pool, asU64("value", params.value)],
320
+ arguments: [params.vault, params.composition, params.pool, params.accumulatorRoot],
320
321
  }),
321
322
  );
322
323
  }
@@ -361,14 +362,16 @@ export function installRecordingRoyaltyPoolPlugin(
361
362
  );
362
363
  }
363
364
 
365
+ export interface PartyWalletPluginParams {
366
+ readonly vault: TransactionObjectArgument;
367
+ readonly vaultAdminCap: TransactionObjectArgument;
368
+ readonly pluginPackageId: string;
369
+ }
370
+
364
371
  /** Install the Party wallet plugin; its canonical witness stays internal. */
365
372
  export function installPartyWalletPlugin(
366
373
  tx: Transaction,
367
- params: {
368
- readonly vault: TransactionObjectArgument;
369
- readonly vaultAdminCap: TransactionObjectArgument;
370
- readonly pluginPackageId: string;
371
- },
374
+ params: PartyWalletPluginParams,
372
375
  ): void {
373
376
  tx.add(
374
377
  partyWallet.install({
@@ -378,6 +381,82 @@ export function installPartyWalletPlugin(
378
381
  );
379
382
  }
380
383
 
384
+ export function uninstallPartyWalletPlugin(
385
+ tx: Transaction,
386
+ params: PartyWalletPluginParams,
387
+ ): void {
388
+ tx.add(
389
+ partyWallet.uninstall({
390
+ package: params.pluginPackageId,
391
+ arguments: [params.vault, params.vaultAdminCap],
392
+ }),
393
+ );
394
+ }
395
+
396
+ export interface PartyWalletFundsParams extends PartyWalletPluginParams {
397
+ readonly party: TransactionObjectArgument;
398
+ readonly currencyType: string;
399
+ }
400
+
401
+ /** Receive selected Party-owned coins and return their merged Balance. */
402
+ export function receivePartyWalletBalance(
403
+ tx: Transaction,
404
+ params: PartyWalletFundsParams & { readonly coins: readonly ReceivingObjectRef[] },
405
+ ): TransactionArgument {
406
+ return tx.add(
407
+ partyWallet.receiveCoins({
408
+ package: params.pluginPackageId,
409
+ typeArguments: [params.currencyType],
410
+ arguments: [
411
+ params.vault,
412
+ params.party,
413
+ params.vaultAdminCap,
414
+ receivingCoins(tx, params.currencyType, params.coins),
415
+ ],
416
+ }),
417
+ );
418
+ }
419
+
420
+ /** Redeem an exact Party accumulator amount and return its Balance. */
421
+ export function redeemPartyWalletBalance(
422
+ tx: Transaction,
423
+ params: PartyWalletFundsParams & { readonly value: U64Input },
424
+ ): TransactionArgument {
425
+ return tx.add(
426
+ partyWallet.redeemBalance({
427
+ package: params.pluginPackageId,
428
+ typeArguments: [params.currencyType],
429
+ arguments: [
430
+ params.vault,
431
+ params.party,
432
+ params.vaultAdminCap,
433
+ asU64("value", params.value),
434
+ ],
435
+ }),
436
+ );
437
+ }
438
+
439
+ /** Sweep the Party's currently settled accumulator funds and return its Balance. */
440
+ export function sweepPartyWalletBalance(
441
+ tx: Transaction,
442
+ params: PartyWalletFundsParams & {
443
+ readonly accumulatorRoot: TransactionObjectArgument;
444
+ },
445
+ ): TransactionArgument {
446
+ return tx.add(
447
+ partyWallet.sweepBalance({
448
+ package: params.pluginPackageId,
449
+ typeArguments: [params.currencyType],
450
+ arguments: [
451
+ params.vault,
452
+ params.party,
453
+ params.accumulatorRoot,
454
+ params.vaultAdminCap,
455
+ ],
456
+ }),
457
+ );
458
+ }
459
+
381
460
  export function uninstallRecordingRoyaltyPoolPlugin(
382
461
  tx: Transaction,
383
462
  params: RecordingRoyaltyPoolPluginParams,
@@ -412,25 +491,27 @@ export interface RecordingRoyaltyPoolCrankParams {
412
491
  readonly vault: TransactionObjectArgument;
413
492
  readonly recording: TransactionObjectArgument;
414
493
  readonly pool: TransactionObjectArgument;
494
+ readonly accumulatorRoot: TransactionObjectArgument;
415
495
  readonly recordingShareType: string;
416
496
  readonly compositionShareType: string;
417
497
  readonly currencyType: string;
418
498
  readonly pluginPackageId: string;
419
499
  }
420
500
 
421
- export function redeemRecordingRoyaltyPool(
501
+ /** Permissionless crank: sweep settled address funds into the canonical pool. */
502
+ export function sweepRecordingRoyaltyPool(
422
503
  tx: Transaction,
423
- params: RecordingRoyaltyPoolCrankParams & { readonly value: U64Input },
504
+ params: RecordingRoyaltyPoolCrankParams,
424
505
  ): void {
425
506
  tx.add(
426
- recordingRoyaltyPool.redeemAndDeposit({
507
+ recordingRoyaltyPool.sweepAndDeposit({
427
508
  package: params.pluginPackageId,
428
509
  typeArguments: [
429
510
  params.recordingShareType,
430
511
  params.compositionShareType,
431
512
  params.currencyType,
432
513
  ],
433
- arguments: [params.vault, params.recording, params.pool, asU64("value", params.value)],
514
+ arguments: [params.vault, params.recording, params.pool, params.accumulatorRoot],
434
515
  }),
435
516
  );
436
517
  }