@misofm/sdk 0.8.1 → 0.10.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.
Files changed (279) hide show
  1. package/README.md +88 -56
  2. package/dist/client.d.ts +126 -18
  3. package/dist/client.d.ts.map +1 -1
  4. package/dist/client.js +210 -44
  5. package/dist/client.js.map +1 -1
  6. package/dist/contracts/composition_routed_stake/composition_routed_stake.d.ts +205 -0
  7. package/dist/contracts/composition_routed_stake/composition_routed_stake.d.ts.map +1 -0
  8. package/dist/contracts/composition_routed_stake/composition_routed_stake.js +184 -0
  9. package/dist/contracts/composition_routed_stake/composition_routed_stake.js.map +1 -0
  10. package/dist/contracts/composition_routed_stake/witness.d.ts +7 -0
  11. package/dist/contracts/composition_routed_stake/witness.d.ts.map +1 -0
  12. package/dist/contracts/composition_routed_stake/witness.js +9 -0
  13. package/dist/contracts/composition_routed_stake/witness.js.map +1 -0
  14. package/dist/contracts/composition_royalty_pool/composition_royalty_pool.d.ts +89 -28
  15. package/dist/contracts/composition_royalty_pool/composition_royalty_pool.d.ts.map +1 -1
  16. package/dist/contracts/composition_royalty_pool/composition_royalty_pool.js +84 -23
  17. package/dist/contracts/composition_royalty_pool/composition_royalty_pool.js.map +1 -1
  18. package/dist/contracts/composition_royalty_pool/witness.d.ts +6 -0
  19. package/dist/contracts/composition_royalty_pool/witness.d.ts.map +1 -0
  20. package/dist/contracts/composition_royalty_pool/witness.js +8 -0
  21. package/dist/contracts/composition_royalty_pool/witness.js.map +1 -0
  22. package/dist/contracts/genre/genre.d.ts +96 -0
  23. package/dist/contracts/genre/genre.d.ts.map +1 -0
  24. package/dist/contracts/genre/genre.js +107 -0
  25. package/dist/contracts/genre/genre.js.map +1 -0
  26. package/dist/contracts/recording_advisory/recording_advisory.d.ts +194 -0
  27. package/dist/contracts/recording_advisory/recording_advisory.d.ts.map +1 -0
  28. package/dist/contracts/recording_advisory/recording_advisory.js +204 -0
  29. package/dist/contracts/recording_advisory/recording_advisory.js.map +1 -0
  30. package/dist/contracts/recording_language/deps/language_code/language_code.d.ts +6 -0
  31. package/dist/contracts/recording_language/deps/language_code/language_code.d.ts.map +1 -0
  32. package/dist/contracts/recording_language/deps/language_code/language_code.js +8 -0
  33. package/dist/contracts/recording_language/deps/language_code/language_code.js.map +1 -0
  34. package/dist/contracts/recording_language/recording_language.d.ts +152 -0
  35. package/dist/contracts/recording_language/recording_language.d.ts.map +1 -0
  36. package/dist/contracts/recording_language/recording_language.js +149 -0
  37. package/dist/contracts/recording_language/recording_language.js.map +1 -0
  38. package/dist/contracts/recording_master_reference/deps/ori/walrus_data.d.ts +52 -0
  39. package/dist/contracts/recording_master_reference/deps/ori/walrus_data.d.ts.map +1 -0
  40. package/dist/contracts/recording_master_reference/deps/ori/walrus_data.js +37 -0
  41. package/dist/contracts/recording_master_reference/deps/ori/walrus_data.js.map +1 -0
  42. package/dist/contracts/recording_master_reference/recording_master_reference.d.ts +131 -0
  43. package/dist/contracts/recording_master_reference/recording_master_reference.d.ts.map +1 -0
  44. package/dist/contracts/recording_master_reference/recording_master_reference.js +121 -0
  45. package/dist/contracts/recording_master_reference/recording_master_reference.js.map +1 -0
  46. package/dist/contracts/recording_preview/deps/ori/walrus_data.d.ts +52 -0
  47. package/dist/contracts/recording_preview/deps/ori/walrus_data.d.ts.map +1 -0
  48. package/dist/contracts/recording_preview/deps/ori/walrus_data.js +37 -0
  49. package/dist/contracts/recording_preview/deps/ori/walrus_data.js.map +1 -0
  50. package/dist/contracts/recording_preview/recording_preview.d.ts +104 -0
  51. package/dist/contracts/recording_preview/recording_preview.d.ts.map +1 -0
  52. package/dist/contracts/recording_preview/recording_preview.js +94 -0
  53. package/dist/contracts/recording_preview/recording_preview.js.map +1 -0
  54. package/dist/contracts/recording_royalty_pool/recording_royalty_pool.d.ts +90 -28
  55. package/dist/contracts/recording_royalty_pool/recording_royalty_pool.d.ts.map +1 -1
  56. package/dist/contracts/recording_royalty_pool/recording_royalty_pool.js +84 -23
  57. package/dist/contracts/recording_royalty_pool/recording_royalty_pool.js.map +1 -1
  58. package/dist/contracts/recording_royalty_pool/witness.d.ts +6 -0
  59. package/dist/contracts/recording_royalty_pool/witness.d.ts.map +1 -0
  60. package/dist/contracts/recording_royalty_pool/witness.js +8 -0
  61. package/dist/contracts/recording_royalty_pool/witness.js.map +1 -0
  62. package/dist/contracts/release_description/release_description.d.ts +112 -0
  63. package/dist/contracts/release_description/release_description.d.ts.map +1 -0
  64. package/dist/contracts/release_description/release_description.js +123 -0
  65. package/dist/contracts/release_description/release_description.js.map +1 -0
  66. package/dist/contracts/release_dsp_link/release_dsp_link.d.ts +644 -0
  67. package/dist/contracts/release_dsp_link/release_dsp_link.d.ts.map +1 -0
  68. package/dist/contracts/release_dsp_link/release_dsp_link.js +556 -0
  69. package/dist/contracts/release_dsp_link/release_dsp_link.js.map +1 -0
  70. package/dist/contracts/release_genre/deps/per_track/per_track.d.ts +33 -0
  71. package/dist/contracts/release_genre/deps/per_track/per_track.d.ts.map +1 -0
  72. package/dist/contracts/release_genre/deps/per_track/per_track.js +32 -0
  73. package/dist/contracts/release_genre/deps/per_track/per_track.js.map +1 -0
  74. package/dist/contracts/release_genre/release_genre.d.ts +193 -0
  75. package/dist/contracts/release_genre/release_genre.d.ts.map +1 -0
  76. package/dist/contracts/release_genre/release_genre.js +207 -0
  77. package/dist/contracts/release_genre/release_genre.js.map +1 -0
  78. package/dist/contracts/release_kind/release_kind.d.ts +98 -0
  79. package/dist/contracts/release_kind/release_kind.d.ts.map +1 -0
  80. package/dist/contracts/release_kind/release_kind.js +109 -0
  81. package/dist/contracts/release_kind/release_kind.js.map +1 -0
  82. package/dist/contracts/release_revenue_distributor/release_revenue_distributor.d.ts +106 -0
  83. package/dist/contracts/release_revenue_distributor/release_revenue_distributor.d.ts.map +1 -0
  84. package/dist/contracts/release_revenue_distributor/release_revenue_distributor.js +113 -0
  85. package/dist/contracts/release_revenue_distributor/release_revenue_distributor.js.map +1 -0
  86. package/dist/contracts/release_revenue_distributor/witness.d.ts +7 -0
  87. package/dist/contracts/release_revenue_distributor/witness.d.ts.map +1 -0
  88. package/dist/contracts/release_revenue_distributor/witness.js +9 -0
  89. package/dist/contracts/release_revenue_distributor/witness.js.map +1 -0
  90. package/dist/contracts/release_snapshot_bundle/deps/ori/walrus_data.d.ts +52 -0
  91. package/dist/contracts/release_snapshot_bundle/deps/ori/walrus_data.d.ts.map +1 -0
  92. package/dist/contracts/release_snapshot_bundle/deps/ori/walrus_data.js +37 -0
  93. package/dist/contracts/release_snapshot_bundle/deps/ori/walrus_data.js.map +1 -0
  94. package/dist/contracts/release_snapshot_bundle/release_snapshot_bundle.d.ts +91 -0
  95. package/dist/contracts/release_snapshot_bundle/release_snapshot_bundle.d.ts.map +1 -0
  96. package/dist/contracts/release_snapshot_bundle/release_snapshot_bundle.js +91 -0
  97. package/dist/contracts/release_snapshot_bundle/release_snapshot_bundle.js.map +1 -0
  98. package/dist/contracts/routed_stake/deps/royalty_pool/stake.d.ts +54 -0
  99. package/dist/contracts/routed_stake/deps/royalty_pool/stake.d.ts.map +1 -0
  100. package/dist/contracts/routed_stake/deps/royalty_pool/stake.js +37 -0
  101. package/dist/contracts/routed_stake/deps/royalty_pool/stake.js.map +1 -0
  102. package/dist/contracts/routed_stake/deps/std/type_name.d.ts +18 -0
  103. package/dist/contracts/routed_stake/deps/std/type_name.d.ts.map +1 -0
  104. package/dist/contracts/routed_stake/deps/std/type_name.js +20 -0
  105. package/dist/contracts/routed_stake/deps/std/type_name.js.map +1 -0
  106. package/dist/contracts/routed_stake/deps/sui/balance.d.ts +13 -0
  107. package/dist/contracts/routed_stake/deps/sui/balance.d.ts.map +1 -0
  108. package/dist/contracts/routed_stake/deps/sui/balance.js +15 -0
  109. package/dist/contracts/routed_stake/deps/sui/balance.js.map +1 -0
  110. package/dist/contracts/routed_stake/deps/sui/vec_map.d.ts +37 -0
  111. package/dist/contracts/routed_stake/deps/sui/vec_map.d.ts.map +1 -0
  112. package/dist/contracts/routed_stake/deps/sui/vec_map.js +28 -0
  113. package/dist/contracts/routed_stake/deps/sui/vec_map.js.map +1 -0
  114. package/dist/contracts/routed_stake/routed_stake.d.ts +356 -0
  115. package/dist/contracts/routed_stake/routed_stake.d.ts.map +1 -0
  116. package/dist/contracts/routed_stake/routed_stake.js +311 -0
  117. package/dist/contracts/routed_stake/routed_stake.js.map +1 -0
  118. package/dist/contracts/royalty_pool/pool.d.ts +27 -17
  119. package/dist/contracts/royalty_pool/pool.d.ts.map +1 -1
  120. package/dist/contracts/royalty_pool/pool.js +26 -17
  121. package/dist/contracts/royalty_pool/pool.js.map +1 -1
  122. package/dist/contracts/vault/deps/sui/bag.d.ts +35 -0
  123. package/dist/contracts/vault/deps/sui/bag.d.ts.map +1 -0
  124. package/dist/contracts/vault/deps/sui/bag.js +37 -0
  125. package/dist/contracts/vault/deps/sui/bag.js.map +1 -0
  126. package/dist/contracts/vault/deps/sui/borrow.d.ts +20 -0
  127. package/dist/contracts/vault/deps/sui/borrow.d.ts.map +1 -0
  128. package/dist/contracts/vault/deps/sui/borrow.js +21 -0
  129. package/dist/contracts/vault/deps/sui/borrow.js.map +1 -0
  130. package/dist/contracts/vault/vault.d.ts +276 -0
  131. package/dist/contracts/vault/vault.d.ts.map +1 -0
  132. package/dist/contracts/vault/vault.js +274 -0
  133. package/dist/contracts/vault/vault.js.map +1 -0
  134. package/dist/contracts.d.ts +14 -2
  135. package/dist/contracts.d.ts.map +1 -1
  136. package/dist/contracts.js +16 -7
  137. package/dist/contracts.js.map +1 -1
  138. package/dist/cover.d.ts +17 -3
  139. package/dist/cover.d.ts.map +1 -1
  140. package/dist/cover.js +43 -20
  141. package/dist/cover.js.map +1 -1
  142. package/dist/credits.d.ts +31 -12
  143. package/dist/credits.d.ts.map +1 -1
  144. package/dist/credits.js +41 -25
  145. package/dist/credits.js.map +1 -1
  146. package/dist/deployments.d.ts +31 -57
  147. package/dist/deployments.d.ts.map +1 -1
  148. package/dist/deployments.js +5 -53
  149. package/dist/deployments.js.map +1 -1
  150. package/dist/index.d.ts +4 -2
  151. package/dist/index.d.ts.map +1 -1
  152. package/dist/index.js +6 -5
  153. package/dist/index.js.map +1 -1
  154. package/dist/pressing.d.ts +8 -7
  155. package/dist/pressing.d.ts.map +1 -1
  156. package/dist/pressing.js +91 -32
  157. package/dist/pressing.js.map +1 -1
  158. package/dist/read/artist.js +3 -3
  159. package/dist/read/artist.js.map +1 -1
  160. package/dist/read/catalog.d.ts +14 -9
  161. package/dist/read/catalog.d.ts.map +1 -1
  162. package/dist/read/catalog.js +72 -37
  163. package/dist/read/catalog.js.map +1 -1
  164. package/dist/read/client.d.ts +4 -2
  165. package/dist/read/client.d.ts.map +1 -1
  166. package/dist/read/client.js +15 -4
  167. package/dist/read/client.js.map +1 -1
  168. package/dist/read/config.d.ts +14 -11
  169. package/dist/read/config.d.ts.map +1 -1
  170. package/dist/read/config.js +10 -37
  171. package/dist/read/config.js.map +1 -1
  172. package/dist/read/index.d.ts +2 -2
  173. package/dist/read/index.d.ts.map +1 -1
  174. package/dist/read/index.js +1 -1
  175. package/dist/read/index.js.map +1 -1
  176. package/dist/read/receipts.d.ts +24 -7
  177. package/dist/read/receipts.d.ts.map +1 -1
  178. package/dist/read/receipts.js +78 -25
  179. package/dist/read/receipts.js.map +1 -1
  180. package/dist/read/types.d.ts +45 -25
  181. package/dist/read/types.d.ts.map +1 -1
  182. package/dist/read/types.js +2 -2
  183. package/dist/read/types.js.map +1 -1
  184. package/dist/read/works.d.ts.map +1 -1
  185. package/dist/read/works.js +6 -1
  186. package/dist/read/works.js.map +1 -1
  187. package/dist/recording-extensions.d.ts +37 -0
  188. package/dist/recording-extensions.d.ts.map +1 -0
  189. package/dist/recording-extensions.js +61 -0
  190. package/dist/recording-extensions.js.map +1 -0
  191. package/dist/release-extensions.d.ts +92 -0
  192. package/dist/release-extensions.d.ts.map +1 -0
  193. package/dist/release-extensions.js +175 -0
  194. package/dist/release-extensions.js.map +1 -0
  195. package/dist/release-graph.d.ts +17 -32
  196. package/dist/release-graph.d.ts.map +1 -1
  197. package/dist/release-graph.js +57 -57
  198. package/dist/release-graph.js.map +1 -1
  199. package/dist/transactions.d.ts +43 -26
  200. package/dist/transactions.d.ts.map +1 -1
  201. package/dist/transactions.js +50 -31
  202. package/dist/transactions.js.map +1 -1
  203. package/dist/vault.d.ts +268 -0
  204. package/dist/vault.d.ts.map +1 -0
  205. package/dist/vault.js +389 -0
  206. package/dist/vault.js.map +1 -0
  207. package/package.json +21 -11
  208. package/src/client.ts +428 -61
  209. package/src/contracts/composition_routed_stake/composition_routed_stake.ts +346 -0
  210. package/src/contracts/composition_routed_stake/witness.ts +11 -0
  211. package/src/contracts/composition_royalty_pool/composition_royalty_pool.ts +151 -35
  212. package/src/contracts/composition_royalty_pool/witness.ts +7 -0
  213. package/src/contracts/genre/genre.ts +151 -0
  214. package/src/contracts/recording_advisory/recording_advisory.ts +315 -0
  215. package/src/contracts/recording_language/deps/language_code/language_code.ts +7 -0
  216. package/src/contracts/recording_language/recording_language.ts +237 -0
  217. package/src/contracts/recording_master_reference/deps/ori/walrus_data.ts +36 -0
  218. package/src/contracts/recording_master_reference/recording_master_reference.ts +181 -0
  219. package/src/contracts/recording_preview/deps/ori/walrus_data.ts +36 -0
  220. package/src/contracts/recording_preview/recording_preview.ts +154 -0
  221. package/src/contracts/recording_royalty_pool/recording_royalty_pool.ts +152 -35
  222. package/src/contracts/recording_royalty_pool/witness.ts +7 -0
  223. package/src/contracts/release_description/release_description.ts +167 -0
  224. package/src/contracts/release_dsp_link/release_dsp_link.ts +813 -0
  225. package/src/contracts/release_genre/deps/per_track/per_track.ts +36 -0
  226. package/src/contracts/release_genre/release_genre.ts +314 -0
  227. package/src/contracts/release_kind/release_kind.ts +153 -0
  228. package/src/contracts/release_revenue_distributor/release_revenue_distributor.ts +178 -0
  229. package/src/contracts/release_revenue_distributor/witness.ts +11 -0
  230. package/src/contracts/release_snapshot_bundle/deps/ori/walrus_data.ts +36 -0
  231. package/src/contracts/release_snapshot_bundle/release_snapshot_bundle.ts +124 -0
  232. package/src/contracts/routed_stake/deps/royalty_pool/stake.ts +39 -0
  233. package/src/contracts/routed_stake/deps/std/type_name.ts +22 -0
  234. package/src/contracts/routed_stake/deps/sui/balance.ts +17 -0
  235. package/src/contracts/routed_stake/deps/sui/vec_map.ts +33 -0
  236. package/src/contracts/routed_stake/routed_stake.ts +508 -0
  237. package/src/contracts/royalty_pool/pool.ts +34 -24
  238. package/src/contracts/vault/deps/sui/bag.ts +39 -0
  239. package/src/contracts/vault/deps/sui/borrow.ts +25 -0
  240. package/src/contracts/vault/vault.ts +454 -0
  241. package/src/contracts.ts +17 -9
  242. package/src/cover.ts +62 -37
  243. package/src/credits.ts +64 -51
  244. package/src/deployments.ts +36 -97
  245. package/src/index.ts +11 -5
  246. package/src/pressing.ts +135 -39
  247. package/src/read/artist.ts +3 -3
  248. package/src/read/catalog.ts +100 -44
  249. package/src/read/client.ts +20 -4
  250. package/src/read/config.ts +23 -49
  251. package/src/read/index.ts +3 -1
  252. package/src/read/receipts.ts +103 -26
  253. package/src/read/types.ts +46 -27
  254. package/src/read/works.ts +6 -1
  255. package/src/recording-extensions.ts +102 -0
  256. package/src/release-extensions.ts +286 -0
  257. package/src/release-graph.ts +70 -96
  258. package/src/transactions.ts +81 -59
  259. package/src/vault.ts +777 -0
  260. package/dist/contracts/miso_drop/drop.d.ts +0 -550
  261. package/dist/contracts/miso_drop/drop.d.ts.map +0 -1
  262. package/dist/contracts/miso_drop/drop.js +0 -523
  263. package/dist/contracts/miso_drop/drop.js.map +0 -1
  264. package/dist/contracts/release_registry/release_registry.d.ts +0 -114
  265. package/dist/contracts/release_registry/release_registry.d.ts.map +0 -1
  266. package/dist/contracts/release_registry/release_registry.js +0 -119
  267. package/dist/contracts/release_registry/release_registry.js.map +0 -1
  268. package/dist/drop.d.ts +0 -127
  269. package/dist/drop.d.ts.map +0 -1
  270. package/dist/drop.js +0 -202
  271. package/dist/drop.js.map +0 -1
  272. package/dist/extensions/royalty-pool.d.ts +0 -32
  273. package/dist/extensions/royalty-pool.d.ts.map +0 -1
  274. package/dist/extensions/royalty-pool.js +0 -33
  275. package/dist/extensions/royalty-pool.js.map +0 -1
  276. package/src/contracts/miso_drop/drop.ts +0 -798
  277. package/src/contracts/release_registry/release_registry.ts +0 -160
  278. package/src/drop.ts +0 -376
  279. package/src/extensions/royalty-pool.ts +0 -90
@@ -0,0 +1,286 @@
1
+ // Copyright (c) Miso Labs, Inc.
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ // First-party metadata attached to a protocol Release. The JSON/CLI release
5
+ // intent aggregates these concerns, but every value is written by its own
6
+ // independently deployed extension package.
7
+
8
+ import { deriveDynamicFieldID } from "@mysten/sui/utils";
9
+ import type {
10
+ Transaction,
11
+ TransactionArgument,
12
+ } from "@mysten/sui/transactions";
13
+ import type { TxThunk } from "./transactions.ts";
14
+ import * as genre from "./contracts/genre/genre.ts";
15
+ import * as releaseDescription from "./contracts/release_description/release_description.ts";
16
+ import * as releaseDspLink from "./contracts/release_dsp_link/release_dsp_link.ts";
17
+ import * as releaseGenre from "./contracts/release_genre/release_genre.ts";
18
+ import * as releaseKind from "./contracts/release_kind/release_kind.ts";
19
+ import * as releaseSnapshotBundle from "./contracts/release_snapshot_bundle/release_snapshot_bundle.ts";
20
+ import { asU64, directAdminCap, invokeWithAdminCap, type AdminCapAuthority, type U64Input } from "./vault.ts";
21
+
22
+ type ReleaseAuthorityInput =
23
+ | { readonly authority: AdminCapAuthority; readonly releaseAdminCapId?: never }
24
+ | { readonly authority?: never; readonly releaseAdminCapId: string };
25
+ interface ReleaseExtensionTargetBase {
26
+ releaseId: string;
27
+ }
28
+ export type ReleaseExtensionTarget = ReleaseExtensionTargetBase & ReleaseAuthorityInput;
29
+ function authority(p: ReleaseExtensionTarget): AdminCapAuthority {
30
+ if (p.authority !== undefined) return p.authority;
31
+ if (p.releaseAdminCapId !== undefined) return directAdminCap(p.releaseAdminCapId);
32
+ throw new Error("release authority is required");
33
+ }
34
+
35
+ export type SetReleaseKindParams = ReleaseExtensionTarget & {
36
+ kind: string;
37
+ releaseKindPackageId: string;
38
+ };
39
+
40
+ /** Attach the release's self-declared kind (for example "EP" or "Mixtape"). */
41
+ export function setReleaseKind(p: SetReleaseKindParams): TxThunk {
42
+ const bytes = new TextEncoder().encode(p.kind).length;
43
+ if (bytes === 0) throw new Error("setReleaseKind: kind must not be empty");
44
+ if (bytes > 32) {
45
+ throw new Error(
46
+ `setReleaseKind: kind must be at most 32 UTF-8 bytes (got ${bytes})`,
47
+ );
48
+ }
49
+ return (tx) => {
50
+ invokeWithAdminCap(tx, authority(p), {
51
+ target: `${p.releaseKindPackageId}::release_kind::set_kind`,
52
+ arguments: [tx.object(p.releaseId), tx.pure.string(p.kind)],
53
+ adminCapIndex: 1,
54
+ });
55
+ };
56
+ }
57
+
58
+ export type SetReleaseDescriptionParams = ReleaseExtensionTarget & {
59
+ description: string;
60
+ releaseDescriptionPackageId: string;
61
+ };
62
+
63
+ /** Attach the release's editorial description. */
64
+ export function setReleaseDescription(p: SetReleaseDescriptionParams): TxThunk {
65
+ const bytes = new TextEncoder().encode(p.description).length;
66
+ if (bytes === 0) {
67
+ throw new Error("setReleaseDescription: description must not be empty");
68
+ }
69
+ if (bytes > 8192) {
70
+ throw new Error(
71
+ `setReleaseDescription: description must be at most 8192 UTF-8 bytes (got ${bytes})`,
72
+ );
73
+ }
74
+ return (tx) => {
75
+ invokeWithAdminCap(tx, authority(p), {
76
+ target: `${p.releaseDescriptionPackageId}::release_description::set_description`,
77
+ arguments: [tx.object(p.releaseId), tx.pure.string(p.description)],
78
+ adminCapIndex: 1,
79
+ });
80
+ };
81
+ }
82
+
83
+ const GENRE_NAME_RE = /^[A-Z]+(?:_[A-Z]+)*$/;
84
+
85
+ /** Validate the canonical on-chain genre vocabulary spelling. */
86
+ export function assertCanonicalGenreName(name: string): void {
87
+ const bytes = new TextEncoder().encode(name).length;
88
+ if (bytes === 0 || bytes > 64 || !GENRE_NAME_RE.test(name)) {
89
+ throw new Error(
90
+ `Genre name must be 1-64 bytes of uppercase A-Z and underscores; got ${JSON.stringify(name)}`,
91
+ );
92
+ }
93
+ }
94
+
95
+ /** Derive the immutable Genre object id for a canonical vocabulary name. */
96
+ export function deriveGenreId(
97
+ genreRegistryId: string,
98
+ genrePackageId: string,
99
+ canonicalName: string,
100
+ ): string {
101
+ assertCanonicalGenreName(canonicalName);
102
+ return deriveDynamicFieldID(
103
+ genreRegistryId,
104
+ `${genrePackageId}::genre::GenreKey`,
105
+ genre.GenreKey.serialize([canonicalName]).toBytes(),
106
+ );
107
+ }
108
+
109
+ export interface TrackGenreAssignment {
110
+ trackIndex: U64Input;
111
+ genreId: string;
112
+ }
113
+
114
+ export type SetReleaseGenresParams = ReleaseExtensionTarget & {
115
+ primaryGenreId: string;
116
+ secondaryGenreIds?: readonly string[];
117
+ trackPrimaryGenres?: readonly TrackGenreAssignment[];
118
+ releaseGenrePackageId: string;
119
+ };
120
+
121
+ /** Attach primary/secondary release genres and optional per-track overrides. */
122
+ export function setReleaseGenres(p: SetReleaseGenresParams): TxThunk {
123
+ return (tx) => {
124
+ invokeWithAdminCap(tx, authority(p), {
125
+ target: `${p.releaseGenrePackageId}::release_genre::set_primary_genre`,
126
+ arguments: [tx.object(p.releaseId), tx.object(p.primaryGenreId)],
127
+ adminCapIndex: 1,
128
+ });
129
+ for (const genreId of p.secondaryGenreIds ?? []) {
130
+ invokeWithAdminCap(tx, authority(p), {
131
+ target: `${p.releaseGenrePackageId}::release_genre::add_secondary_genre`,
132
+ arguments: [tx.object(p.releaseId), tx.object(genreId)],
133
+ adminCapIndex: 1,
134
+ });
135
+ }
136
+ for (const assignment of p.trackPrimaryGenres ?? []) {
137
+ invokeWithAdminCap(tx, authority(p), {
138
+ target: `${p.releaseGenrePackageId}::release_genre::set_track_primary_genre`,
139
+ arguments: [
140
+ tx.object(p.releaseId),
141
+ tx.pure.u64(asU64("trackIndex", assignment.trackIndex)),
142
+ tx.object(assignment.genreId),
143
+ ],
144
+ adminCapIndex: 1,
145
+ });
146
+ }
147
+ };
148
+ }
149
+
150
+ export type DspLink =
151
+ | { platform: "Spotify"; id: string }
152
+ | {
153
+ platform: "AppleMusic";
154
+ storefront: string;
155
+ albumId: string;
156
+ trackId?: string;
157
+ }
158
+ | { platform: "AmazonMusic"; albumId: string; trackId?: string }
159
+ | { platform: "Bandcamp"; subdomain: string; slug: string }
160
+ | { platform: "Deezer"; id: string }
161
+ | { platform: "SoundCloud"; user: string; slug: string }
162
+ | { platform: "Tidal"; id: string }
163
+ | { platform: "YouTubeMusic"; id: string };
164
+
165
+ function buildDspLink(
166
+ tx: Transaction,
167
+ packageId: string,
168
+ link: DspLink,
169
+ ): TransactionArgument {
170
+ switch (link.platform) {
171
+ case "Spotify":
172
+ return tx.add(
173
+ releaseDspLink.newSpotify({ package: packageId, arguments: [link.id] }),
174
+ );
175
+ case "AppleMusic":
176
+ return tx.add(
177
+ link.trackId === undefined
178
+ ? releaseDspLink.newAppleMusicAlbum({
179
+ package: packageId,
180
+ arguments: [link.storefront, link.albumId],
181
+ })
182
+ : releaseDspLink.newAppleMusicTrack({
183
+ package: packageId,
184
+ arguments: [link.storefront, link.albumId, link.trackId],
185
+ }),
186
+ );
187
+ case "AmazonMusic":
188
+ return tx.add(
189
+ link.trackId === undefined
190
+ ? releaseDspLink.newAmazonMusicAlbum({
191
+ package: packageId,
192
+ arguments: [link.albumId],
193
+ })
194
+ : releaseDspLink.newAmazonMusicTrack({
195
+ package: packageId,
196
+ arguments: [link.albumId, link.trackId],
197
+ }),
198
+ );
199
+ case "Bandcamp":
200
+ return tx.add(
201
+ releaseDspLink.newBandcamp({
202
+ package: packageId,
203
+ arguments: [link.subdomain, link.slug],
204
+ }),
205
+ );
206
+ case "Deezer":
207
+ return tx.add(
208
+ releaseDspLink.newDeezer({ package: packageId, arguments: [link.id] }),
209
+ );
210
+ case "SoundCloud":
211
+ return tx.add(
212
+ releaseDspLink.newSoundcloud({
213
+ package: packageId,
214
+ arguments: [link.user, link.slug],
215
+ }),
216
+ );
217
+ case "Tidal":
218
+ return tx.add(
219
+ releaseDspLink.newTidal({ package: packageId, arguments: [link.id] }),
220
+ );
221
+ case "YouTubeMusic":
222
+ return tx.add(
223
+ releaseDspLink.newYoutubeMusic({
224
+ package: packageId,
225
+ arguments: [link.id],
226
+ }),
227
+ );
228
+ }
229
+ }
230
+
231
+ export interface TrackDspLink {
232
+ trackIndex: U64Input;
233
+ link: DspLink;
234
+ }
235
+
236
+ export type SetReleaseDspLinksParams = ReleaseExtensionTarget & {
237
+ releaseLinks?: readonly DspLink[];
238
+ trackLinks?: readonly TrackDspLink[];
239
+ releaseDspLinkPackageId: string;
240
+ };
241
+
242
+ /** Attach release-level and per-track DSP links. */
243
+ export function setReleaseDspLinks(p: SetReleaseDspLinksParams): TxThunk {
244
+ return (tx) => {
245
+ for (const link of p.releaseLinks ?? []) {
246
+ const value = buildDspLink(tx, p.releaseDspLinkPackageId, link);
247
+ invokeWithAdminCap(tx, authority(p), {
248
+ target: `${p.releaseDspLinkPackageId}::release_dsp_link::set_release_link`,
249
+ arguments: [tx.object(p.releaseId), value],
250
+ adminCapIndex: 1,
251
+ });
252
+ }
253
+ for (const item of p.trackLinks ?? []) {
254
+ const value = buildDspLink(tx, p.releaseDspLinkPackageId, item.link);
255
+ invokeWithAdminCap(tx, authority(p), {
256
+ target: `${p.releaseDspLinkPackageId}::release_dsp_link::set_track_link`,
257
+ arguments: [tx.object(p.releaseId), tx.pure.u64(asU64("trackIndex", item.trackIndex)), value],
258
+ adminCapIndex: 1,
259
+ });
260
+ }
261
+ };
262
+ }
263
+
264
+ export type SetReleaseSnapshotBundleParams = ReleaseExtensionTarget & {
265
+ /** Plaintext outer Walrus quilt blob id, as the on-chain u256 value. */
266
+ blobId: bigint | string;
267
+ releaseSnapshotBundlePackageId: string;
268
+ oriPackageId: string;
269
+ };
270
+
271
+ /** Attach the write-once release snapshot-bundle pointer. */
272
+ export function setReleaseSnapshotBundle(
273
+ p: SetReleaseSnapshotBundleParams,
274
+ ): TxThunk {
275
+ return (tx) => {
276
+ const bundle = tx.moveCall({
277
+ target: `${p.oriPackageId}::walrus_data::new_blob`,
278
+ arguments: [tx.pure.u256(p.blobId)],
279
+ });
280
+ invokeWithAdminCap(tx, authority(p), {
281
+ target: `${p.releaseSnapshotBundlePackageId}::release_snapshot_bundle::set_snapshot_bundle`,
282
+ arguments: [tx.object(p.releaseId), bundle],
283
+ adminCapIndex: 1,
284
+ });
285
+ };
286
+ }
@@ -2,15 +2,15 @@
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
 
4
4
  // Single-PTB publisher for a whole release graph: creates every composition and
5
- // recording, optionally attaches royalty pools, derives the release id ON-CHAIN
5
+ // recording, derives the release id ON-CHAIN
6
6
  // (so recordings need not be shared first), builds the tracks/release,
7
7
  // then shares everything and transfers the admin caps — all in ONE transaction.
8
8
  //
9
9
  // Share currencies must already be published + initialized (their Currency objects
10
10
  // shared on-chain); their ids/types are passed in. Ordering is load-bearing:
11
- // 1. composition::new → recording::new(&comp) (borrow-before-share) + pool attach
11
+ // 1. composition::new → recording::new(&comp) (borrow-before-share)
12
12
  // 2. release::derive_target_release_id(<recording::id results>) →
13
- // track::new(cap, &rec, derivedId, split) → release_registry::new_release
13
+ // track::new(cap, &rec, derivedId, split) → release::new(registry, …)
14
14
  // 3. publish (share) comps + recs + release, disperse supply, transfer caps
15
15
  // Steps 1–2 borrow the works; step 3 consumes them into share_object.
16
16
  //
@@ -19,59 +19,40 @@
19
19
  //
20
20
  // This is the whole-graph orchestration half of the opinionated publish flow —
21
21
  // it composes `@misonetwork/sdk`'s bare `composition`/`recording`/`track`/
22
- // `release` call bindings and this package's `release_registry` binding with its
23
- // own `disperseShares`/`finalizeRelease` and royalty-pool extension helpers, into
24
- // one PTB.
22
+ // `release` core call bindings with its
23
+ // own `disperseShares`/`finalizeRelease` helpers into one PTB. Royalty pools are
24
+ // installed later through an admin-cap Vault plugin; the retired raw-cap helper
25
+ // is intentionally not used here.
25
26
 
26
27
  import { Transaction, type TransactionObjectArgument } from "@mysten/sui/transactions";
27
- import { contracts, PROTOCOL_MAX_ROYALTY_RATE_BPS } from "@misonetwork/sdk";
28
- import { attachCompositionRoyaltyPool, attachRecordingRoyaltyPool } from "./extensions/royalty-pool.ts";
29
- import { disperseShares, finalizeRelease, type ShareRecipient } from "./transactions.ts";
30
- import * as releaseRegistry from "./contracts/release_registry/release_registry.ts";
31
-
32
- const { composition, recording, track, release } = contracts;
33
-
34
- /** A royalty pool to attach to a work, in the same PTB. */
35
- export interface RoyaltyPoolNode {
36
- currency: string;
37
- /** `composition_royalty_pool` / `recording_royalty_pool` package id. */
38
- extensionPackageId: string;
39
- /** Base `royalty_pool` lib package id. */
40
- royaltyPoolPackageId: string;
41
- }
28
+ import { contracts } from "@misonetwork/sdk";
29
+ import { custodyOf, disperseShares, finalizeRelease, recordingAuthorityOf, requiredCommandResult, type AdminCustodyInput, type RecordingAuthorityInput, type ShareRecipient } from "./transactions.ts";
30
+ import { disposeNewAdminCap, invokeWithAdminCap } from "./vault.ts";
31
+
32
+ const { composition, recording, track } = contracts;
42
33
 
43
- export interface CompositionNode {
34
+ interface CompositionNodeBase {
44
35
  shareType: string;
45
36
  shareCurrencyId: string;
46
37
  shareTreasuryCapId: string;
47
38
  title: string;
48
39
  royaltyRateBps: number;
49
40
  shareRecipients: ShareRecipient[];
50
- /** Recipient of the CompositionAdminCap (the owner). */
51
- adminAddress: string;
52
- royaltyPool?: RoyaltyPoolNode;
53
41
  }
42
+ export type CompositionNode = CompositionNodeBase & AdminCustodyInput;
54
43
 
55
- export interface RecordingNode {
44
+ interface RecordingNodeBase {
56
45
  shareType: string;
57
46
  shareCurrencyId: string;
58
47
  shareTreasuryCapId: string;
59
48
  /** The parent composition's share type. */
60
49
  compositionShareType: string;
61
- /** Index into `compositions[]` if the parent is created in THIS PTB… */
62
- parentCompositionIndex?: number;
63
- /** …or the on-chain composition object id if the parent already exists. */
64
- parentCompositionId?: string;
65
50
  shareRecipients: ShareRecipient[];
66
- adminAddress: string;
67
- /**
68
- * Slippage guard for `recording::new` against an EXISTING on-chain parent —
69
- * pass the composition rate you observed (default: protocol max). Ignored for
70
- * parents created in this PTB, whose exact known rate is pinned automatically.
71
- */
72
- maxRoyaltyRateBps?: number;
73
- royaltyPool?: RoyaltyPoolNode;
74
51
  }
52
+ type RecordingParent =
53
+ | { readonly parentCompositionIndex: number; readonly parentCompositionId?: never }
54
+ | { readonly parentCompositionIndex?: never; readonly parentCompositionId: string };
55
+ export type RecordingNode = RecordingNodeBase & RecordingParent & AdminCustodyInput;
75
56
 
76
57
  /** A track whose recording is created in THIS PTB. */
77
58
  export interface FreshTrackNode {
@@ -84,27 +65,33 @@ export interface FreshTrackNode {
84
65
  * A track over an EXISTING recording, authorized by its admin cap held by the
85
66
  * sender. This can coexist with recordings created in this PTB.
86
67
  */
87
- export interface CapTrackNode {
68
+ interface CapTrackNodeBase {
88
69
  recordingId: string;
89
- recordingAdminCapId: string;
90
70
  recordingShareType: string;
91
71
  compositionShareType: string;
92
72
  splitBps: number;
93
73
  }
74
+ export type CapTrackNode = CapTrackNodeBase & RecordingAuthorityInput;
94
75
 
95
76
  export type TrackNode = FreshTrackNode | CapTrackNode;
96
77
 
97
78
  const isFresh = (t: TrackNode): t is FreshTrackNode => "recordingIndex" in t;
98
79
 
99
- export interface ReleaseNode {
80
+ function requiredAt<T>(items: readonly T[], index: number, description: string): T {
81
+ const item = items[index];
82
+ if (item === undefined) throw new Error(`${description} index ${index} is out of range`);
83
+ return item;
84
+ }
85
+
86
+ interface ReleaseNodeBase {
100
87
  title: string;
101
88
  /** u256 nonce as a decimal string (deterministic release id). */
102
89
  nonce: string;
103
- adminAddress: string;
104
90
  releaseRegistryId: string;
105
91
  /** The ordered tracklist. Display grouping (discs/sides) is extension data. */
106
92
  tracks: TrackNode[];
107
93
  }
94
+ export type ReleaseNode = ReleaseNodeBase & AdminCustodyInput;
108
95
 
109
96
  export interface PublishReleaseGraphParams {
110
97
  compositions: CompositionNode[];
@@ -112,8 +99,6 @@ export interface PublishReleaseGraphParams {
112
99
  release?: ReleaseNode;
113
100
  misoPackageId: string;
114
101
  minatoPackageId: string;
115
- /** `release_registry` extension package, distinct from its shared object id. */
116
- releaseRegistryPackageId: string;
117
102
  }
118
103
 
119
104
  interface Parts {
@@ -124,7 +109,7 @@ interface Parts {
124
109
 
125
110
  /** Builds the entire graph in a single transaction (see file header for ordering). */
126
111
  export function publishReleaseGraph(params: PublishReleaseGraphParams): (tx: Transaction) => void {
127
- const { misoPackageId: pkg, minatoPackageId, releaseRegistryPackageId } = params;
112
+ const { misoPackageId: pkg, minatoPackageId } = params;
128
113
  return (tx) => {
129
114
  // ── 1) Create every composition, then every recording (borrow-before-share) ──
130
115
  const comps: Parts[] = params.compositions.map((c) => {
@@ -135,50 +120,32 @@ export function publishReleaseGraph(params: PublishReleaseGraphParams): (tx: Tra
135
120
  arguments: [tx.pure.string(c.title), tx.pure.u16(c.royaltyRateBps), tx.object(c.shareCurrencyId), tx.object(c.shareTreasuryCapId)],
136
121
  }),
137
122
  );
138
- const parts: Parts = { work: r[0]!, adminCap: r[1]!, balance: r[2]! };
139
- if (c.royaltyPool) {
140
- attachCompositionRoyaltyPool(tx, {
141
- composition: parts.work,
142
- adminCap: parts.adminCap,
143
- compositionShareType: c.shareType,
144
- currency: c.royaltyPool.currency,
145
- compositionRoyaltyPoolPackageId: c.royaltyPool.extensionPackageId,
146
- royaltyPoolPackageId: c.royaltyPool.royaltyPoolPackageId,
147
- });
148
- }
123
+ const parts: Parts = {
124
+ work: requiredCommandResult(r, 0, "composition::_new"),
125
+ adminCap: requiredCommandResult(r, 1, "composition::_new"),
126
+ balance: requiredCommandResult(r, 2, "composition::_new"),
127
+ };
149
128
  return parts;
150
129
  });
151
130
 
152
131
  const recTypeArgs = (i: number): [string, string] => {
153
- const n = params.recordings[i]!;
132
+ const n = requiredAt(params.recordings, i, "recording");
154
133
  return [n.shareType, n.compositionShareType];
155
134
  };
156
135
 
157
136
  const recs: Parts[] = params.recordings.map((rec, i) => {
158
- const parent = rec.parentCompositionIndex !== undefined ? comps[rec.parentCompositionIndex]!.work : tx.object(rec.parentCompositionId!);
159
- // Slippage guard: a parent created in this PTB has a known rate — pin it
160
- // exactly. An existing parent uses the caller's observed rate (or accepts
161
- // up to the protocol max).
162
- const maxRoyaltyRateBps =
163
- rec.parentCompositionIndex !== undefined
164
- ? params.compositions[rec.parentCompositionIndex]!.royaltyRateBps
165
- : (rec.maxRoyaltyRateBps ?? PROTOCOL_MAX_ROYALTY_RATE_BPS);
137
+ const parent = rec.parentCompositionIndex !== undefined
138
+ ? requiredAt(comps, rec.parentCompositionIndex, "parent composition").work
139
+ : tx.object(rec.parentCompositionId);
166
140
  const typeArgs = recTypeArgs(i);
167
141
  const r = tx.add(
168
- recording._new({ package: pkg, typeArguments: typeArgs, arguments: [parent, tx.object(rec.shareCurrencyId), tx.object(rec.shareTreasuryCapId), tx.pure.u16(maxRoyaltyRateBps)] }),
142
+ recording._new({ package: pkg, typeArguments: typeArgs, arguments: [parent, tx.object(rec.shareCurrencyId), tx.object(rec.shareTreasuryCapId)] }),
169
143
  );
170
- const parts: Parts = { work: r[0]!, adminCap: r[1]!, balance: r[2]! };
171
- if (rec.royaltyPool) {
172
- attachRecordingRoyaltyPool(tx, {
173
- recording: parts.work,
174
- adminCap: parts.adminCap,
175
- recordingShareType: rec.shareType,
176
- compositionShareType: rec.compositionShareType,
177
- currency: rec.royaltyPool.currency,
178
- recordingRoyaltyPoolPackageId: rec.royaltyPool.extensionPackageId,
179
- royaltyPoolPackageId: rec.royaltyPool.royaltyPoolPackageId,
180
- });
181
- }
144
+ const parts: Parts = {
145
+ work: requiredCommandResult(r, 0, "recording::_new"),
146
+ adminCap: requiredCommandResult(r, 1, "recording::_new"),
147
+ balance: requiredCommandResult(r, 2, "recording::_new"),
148
+ };
182
149
  return parts;
183
150
  });
184
151
 
@@ -190,50 +157,57 @@ export function publishReleaseGraph(params: PublishReleaseGraphParams): (tx: Tra
190
157
  type: "0x2::object::ID",
191
158
  elements: ordered.map((t) =>
192
159
  isFresh(t)
193
- ? tx.add(recording.id({ package: pkg, typeArguments: recTypeArgs(t.recordingIndex), arguments: [recs[t.recordingIndex]!.work] }))
160
+ ? tx.add(recording.id({ package: pkg, typeArguments: recTypeArgs(t.recordingIndex), arguments: [requiredAt(recs, t.recordingIndex, "fresh recording").work] }))
194
161
  : tx.pure.id(t.recordingId),
195
162
  ),
196
163
  });
197
164
  const splitVec = tx.makeMoveVec({ type: "u64", elements: ordered.map((t) => tx.pure.u64(t.splitBps)) });
198
165
  // This returns an ID value (not an object); pass the result straight to
199
166
  // `track::new` so every track consents to this exact release target.
200
- const releaseId = tx.add(
201
- release.deriveTargetReleaseId({ package: pkg, arguments: [idVec, splitVec, tx.pure.u256(BigInt(rel.nonce)), tx.pure.id(rel.releaseRegistryId)] }),
202
- );
167
+ const releaseId = tx.moveCall({
168
+ target: `${pkg}::release::derive_target_release_id`,
169
+ arguments: [tx.object(rel.releaseRegistryId), idVec, splitVec, tx.pure.u256(BigInt(rel.nonce))],
170
+ });
203
171
 
204
172
  const trackArgs = ordered.map((t) => {
205
173
  if (isFresh(t)) {
206
174
  const typeArgs = recTypeArgs(t.recordingIndex);
207
- const parts = recs[t.recordingIndex]!;
175
+ const parts = requiredAt(recs, t.recordingIndex, "fresh recording");
208
176
  return tx.add(track._new({ package: pkg, typeArguments: typeArgs, arguments: [parts.adminCap, parts.work, releaseId, tx.pure.u16(t.splitBps)] }));
209
177
  }
210
178
  const typeArgs: [string, string] = [t.recordingShareType, t.compositionShareType];
211
179
  const rec = tx.object(t.recordingId);
212
- return tx.add(track._new({ package: pkg, typeArguments: typeArgs, arguments: [tx.object(t.recordingAdminCapId), rec, releaseId, tx.pure.u16(t.splitBps)] }));
180
+ return invokeWithAdminCap(tx, recordingAuthorityOf(t), {
181
+ target: `${pkg}::track::new`,
182
+ typeArguments: typeArgs,
183
+ arguments: [rec, releaseId, tx.pure.u16(t.splitBps)],
184
+ adminCapIndex: 0,
185
+ });
213
186
  });
214
187
  const trackVec = tx.makeMoveVec({ type: `${pkg}::track::Track`, elements: trackArgs });
215
- const created = tx.add(
216
- releaseRegistry.newRelease({
217
- package: releaseRegistryPackageId,
218
- arguments: [tx.object(rel.releaseRegistryId), tx.pure.string(rel.title), trackVec, tx.pure.u256(BigInt(rel.nonce))],
219
- }),
220
- );
221
- const releaseParts = { release: created[0]!, adminCap: created[1]! };
222
- finalizeRelease(tx, { ...releaseParts, adminAddress: rel.adminAddress, misoPackageId: pkg });
188
+ const created = tx.moveCall({
189
+ target: `${pkg}::release::new`,
190
+ arguments: [tx.object(rel.releaseRegistryId), tx.pure.string(rel.title), trackVec, tx.pure.u256(BigInt(rel.nonce))],
191
+ });
192
+ const releaseParts = {
193
+ release: requiredCommandResult(created, 0, "release::new"),
194
+ adminCap: requiredCommandResult(created, 1, "release::new"),
195
+ };
196
+ finalizeRelease(tx, { ...releaseParts, adminCustody: custodyOf(rel), misoPackageId: pkg });
223
197
  }
224
198
 
225
199
  // ── 3) Share every work, disperse its supply, transfer admin caps ──
226
200
  params.compositions.forEach((c, i) => {
227
- const parts = comps[i]!;
201
+ const parts = requiredAt(comps, i, "composition");
228
202
  disperseShares(tx, minatoPackageId, c.shareType, parts.balance, c.shareRecipients);
229
203
  tx.add(composition.publish({ package: pkg, typeArguments: [c.shareType], arguments: [parts.work, parts.adminCap] }));
230
- tx.transferObjects([parts.adminCap], c.adminAddress);
204
+ disposeNewAdminCap(tx, parts.adminCap, custodyOf(c));
231
205
  });
232
206
  params.recordings.forEach((rec, i) => {
233
- const parts = recs[i]!;
207
+ const parts = requiredAt(recs, i, "recording");
234
208
  tx.add(recording.publish({ package: pkg, typeArguments: recTypeArgs(i), arguments: [parts.work, parts.adminCap] }));
235
209
  disperseShares(tx, minatoPackageId, rec.shareType, parts.balance, rec.shareRecipients);
236
- tx.transferObjects([parts.adminCap], rec.adminAddress);
210
+ disposeNewAdminCap(tx, parts.adminCap, custodyOf(rec));
237
211
  });
238
212
  };
239
213
  }