@misonetwork/sdk 0.3.1 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +97 -503
- package/dist/client.d.ts +6 -55
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +7 -52
- package/dist/client.js.map +1 -1
- package/dist/contracts/miso/release.d.ts +34 -31
- package/dist/contracts/miso/release.d.ts.map +1 -1
- package/dist/contracts/miso/release.js +32 -29
- package/dist/contracts/miso/release.js.map +1 -1
- package/dist/contracts/miso/track.d.ts +66 -22
- package/dist/contracts/miso/track.d.ts.map +1 -1
- package/dist/contracts/miso/track.js +65 -20
- package/dist/contracts/miso/track.js.map +1 -1
- package/dist/contracts/utils/index.d.ts +44 -0
- package/dist/contracts/utils/index.d.ts.map +1 -1
- package/dist/contracts/utils/index.js +104 -2
- package/dist/contracts/utils/index.js.map +1 -1
- package/dist/contracts.d.ts +0 -1
- package/dist/contracts.d.ts.map +1 -1
- package/dist/contracts.js +0 -1
- package/dist/contracts.js.map +1 -1
- package/dist/internal.d.ts +0 -7
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +0 -22
- package/dist/internal.js.map +1 -1
- package/dist/parsers.d.ts +1 -4
- package/dist/parsers.d.ts.map +1 -1
- package/dist/parsers.js +0 -24
- package/dist/parsers.js.map +1 -1
- package/dist/queries.d.ts +31 -5
- package/dist/queries.d.ts.map +1 -1
- package/dist/queries.js +179 -56
- package/dist/queries.js.map +1 -1
- package/dist/transactions.d.ts +10 -71
- package/dist/transactions.d.ts.map +1 -1
- package/dist/transactions.js +15 -72
- package/dist/transactions.js.map +1 -1
- package/dist/types.d.ts +3 -40
- package/dist/types.d.ts.map +1 -1
- package/dist/view.d.ts +7 -7
- package/dist/view.d.ts.map +1 -1
- package/dist/view.js +9 -9
- package/dist/view.js.map +1 -1
- package/package.json +4 -4
- package/src/client.ts +82 -89
- package/src/contracts/miso/release.ts +39 -36
- package/src/contracts/miso/track.ts +81 -23
- package/src/contracts/utils/index.ts +156 -4
- package/src/contracts.ts +0 -1
- package/src/internal.ts +0 -24
- package/src/parsers.ts +0 -35
- package/src/queries.ts +357 -83
- package/src/transactions.ts +20 -112
- package/src/types.ts +3 -53
- package/src/view.ts +13 -13
- package/dist/contracts/miso/deal.d.ts +0 -184
- package/dist/contracts/miso/deal.d.ts.map +0 -1
- package/dist/contracts/miso/deal.js +0 -184
- package/dist/contracts/miso/deal.js.map +0 -1
- package/src/contracts/miso/deal.ts +0 -257
package/README.md
CHANGED
|
@@ -1,17 +1,13 @@
|
|
|
1
1
|
# @misonetwork/sdk
|
|
2
2
|
|
|
3
|
-
TypeScript SDK for the [Miso](https://github.com/misonetwork/
|
|
3
|
+
TypeScript SDK for the [Miso](https://github.com/misonetwork/protocol) protocol
|
|
4
|
+
core on [Sui](https://sui.io). Bindings are regenerated from the local
|
|
5
|
+
`misonetwork/protocol` Move source with `bun run codegen`.
|
|
4
6
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
Helpers for the first-party **extensions** — credits, cover art, royalty pools —
|
|
10
|
-
live in [`@misofm/sdk`](https://github.com/misofm/sdk), not here. An extension is
|
|
11
|
-
opinionated business logic hung off the protocol's `&mut UID` hook (which roles
|
|
12
|
-
exist and what they are called, what a cover is, how royalties accumulate), so it
|
|
13
|
-
ships with the platform layer. The protocol package stays the open thing anyone
|
|
14
|
-
can build on without adopting Miso's opinions.
|
|
7
|
+
Miso models compositions, recordings, releases, their rights, and royalties as
|
|
8
|
+
Sui objects. This package provides core queries, PTB primitives, generated BCS
|
|
9
|
+
bindings, event parsers, and a client extension. First-party policy and
|
|
10
|
+
extension helpers live in [`@misofm/sdk`](https://github.com/misofm/sdk).
|
|
15
11
|
|
|
16
12
|
## Installation
|
|
17
13
|
|
|
@@ -19,555 +15,153 @@ can build on without adopting Miso's opinions.
|
|
|
19
15
|
bun add @misonetwork/sdk @mysten/sui
|
|
20
16
|
```
|
|
21
17
|
|
|
22
|
-
##
|
|
18
|
+
## Client extension
|
|
23
19
|
|
|
24
20
|
```ts
|
|
25
21
|
import { SuiGrpcClient } from "@mysten/sui/grpc";
|
|
26
22
|
import { miso } from "@misonetwork/sdk";
|
|
27
23
|
|
|
28
|
-
const client = new SuiGrpcClient({
|
|
24
|
+
const client = new SuiGrpcClient({
|
|
25
|
+
network: "testnet",
|
|
26
|
+
baseUrl: "https://fullnode.testnet.sui.io:443",
|
|
27
|
+
})
|
|
29
28
|
.$extend(miso({ misoPackageId: "0x..." }));
|
|
30
29
|
|
|
31
|
-
// Fetch a recording
|
|
32
30
|
const recording = await client.miso.getRecordingById("0x...");
|
|
33
|
-
console.log(recording.state); // display title comes from the parent composition
|
|
34
|
-
|
|
35
|
-
// Derive an admin cap ID (pure, no network call)
|
|
36
31
|
const adminCapId = client.miso.deriveRecordingAdminCapId("0x...");
|
|
37
32
|
```
|
|
38
33
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
```ts
|
|
44
|
-
import { SuiGrpcClient } from "@mysten/sui/grpc";
|
|
45
|
-
import { SuiGraphQLClient } from "@mysten/sui/graphql";
|
|
46
|
-
import { miso } from "@misonetwork/sdk";
|
|
47
|
-
|
|
48
|
-
const graphqlClient = new SuiGraphQLClient({
|
|
49
|
-
url: "https://sui-testnet.mystenlabs.com/graphql",
|
|
50
|
-
network: "testnet",
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
const client = new SuiGrpcClient({ network: "testnet" })
|
|
54
|
-
.$extend(miso({
|
|
55
|
-
misoPackageId: "0x...",
|
|
56
|
-
graphqlClient, // Required for generic type-based queries (getByShareType, getOwnedCompositionAdminCaps, getOwnedRecordingAdminCaps, getReleaseRegistry, getAdministeredRecordings)
|
|
57
|
-
}));
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
### API Priority
|
|
61
|
-
|
|
62
|
-
Methods use the most efficient transport available:
|
|
34
|
+
Pass a `SuiGraphQLClient` as `graphqlClient` only for generic type discovery,
|
|
35
|
+
such as `getCompositionByShareType` and `getRecordingByShareType`. ID reads and
|
|
36
|
+
owned-cap queries use the Core API.
|
|
63
37
|
|
|
64
|
-
|
|
65
|
-
|-----------|-----------|----------|
|
|
66
|
-
| **Core API** | Single-object fetch by ID, derivation | `getRecordingById`, `deriveCompositionAdminCapId` |
|
|
67
|
-
| **Core API** | Non-generic type queries | `getOwnedReleaseAdminCaps` |
|
|
68
|
-
| **GraphQL** | Generic type queries (partial type matching) | `getOwnedCompositionAdminCaps`, `getRecordingByShareType` |
|
|
38
|
+
## Data model
|
|
69
39
|
|
|
70
|
-
|
|
40
|
+
- `Composition`: the written work, with a share currency and royalty rate.
|
|
41
|
+
- `Recording`: an audio performance of a composition, with its own share currency.
|
|
42
|
+
- `Track`: a recording admin's consent to an exact target release ID and split.
|
|
43
|
+
- `Release`: a flat ordered sequence of tracks. Disc/side grouping is extension
|
|
44
|
+
presentation data, not core state.
|
|
71
45
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
- **Composition** — the underlying written work. Earns an immutable-floored `royaltyRate` from each recording. Backed by its own share currency.
|
|
76
|
-
- **Recording** — an audio performance of a composition. Backed by its own share currency. Carries no name of its own — its display title is its composition's title; richer naming lives in the metadata extension.
|
|
77
|
-
- **Release** — a flat, ordered tracklist of `Track`s (album, EP, or single), assembled from `Deal`s. Display grouping (discs/sides) lives in extensions.
|
|
78
|
-
- **Deal** — a recording admin's transferable authorization to include the recording on one exact release id.
|
|
79
|
-
|
|
80
|
-
Everything else — credits, cover art, royalty pools, masters, descriptive
|
|
81
|
-
metadata — attaches to the frozen core objects as dynamic fields through
|
|
82
|
-
extension packages (see [Extensions](#extensions)).
|
|
83
|
-
|
|
84
|
-
On publish, each entity emits a single lean pointer event carrying just its identity;
|
|
85
|
-
indexers subscribe to that pointer and fetch the immutable object by ID.
|
|
46
|
+
Core objects are built then published. Credits, cover art, royalty pools, and
|
|
47
|
+
release coordination are extension-layer concerns in `@misofm/sdk`.
|
|
86
48
|
|
|
87
49
|
## Queries
|
|
88
50
|
|
|
89
|
-
All client methods are also
|
|
90
|
-
explicitly) from the package root.
|
|
91
|
-
|
|
92
|
-
### Compositions
|
|
93
|
-
|
|
94
|
-
```ts
|
|
95
|
-
// Core API (by ID)
|
|
96
|
-
const comp = await client.miso.getCompositionById("0x...");
|
|
97
|
-
const comps = await client.miso.getCompositionsByIds(["0x...", "0x..."]);
|
|
98
|
-
const capId = client.miso.deriveCompositionAdminCapId("0x...");
|
|
99
|
-
const cap = await client.miso.getCompositionAdminCapById(capId);
|
|
100
|
-
const shareType = await client.miso.getCompositionShareType("0x...");
|
|
101
|
-
|
|
102
|
-
// GraphQL (by type or owner)
|
|
103
|
-
const comp2 = await client.miso.getCompositionByShareType("0x...::share::Share");
|
|
104
|
-
const caps = await client.miso.getOwnedCompositionAdminCaps(ownerAddress);
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
### Recordings
|
|
51
|
+
All client methods are also exported as standalone functions.
|
|
108
52
|
|
|
109
53
|
```ts
|
|
110
|
-
// Core API (by ID)
|
|
111
|
-
const rec = await client.miso.getRecordingById("0x...");
|
|
112
|
-
const recs = await client.miso.getRecordingsByIds(["0x...", "0x..."]);
|
|
113
|
-
const recCapId = client.miso.deriveRecordingAdminCapId("0x...");
|
|
114
|
-
const recCap = await client.miso.getRecordingAdminCapById(recCapId);
|
|
115
|
-
|
|
116
|
-
// A Recording is generic over two phantoms — Recording<RecordingShare, CompositionShare>.
|
|
117
|
-
const recShareType = await client.miso.getRecordingShareType("0x..."); // the recording's OWN share type
|
|
118
|
-
const [recShare, compShare] = await getRecordingShareTypes(client, "0x..."); // both, in that order
|
|
119
|
-
|
|
120
|
-
// GraphQL (by type or owner)
|
|
121
|
-
const rec2 = await client.miso.getRecordingByShareType("0x...::share::Share");
|
|
122
|
-
const recCaps = await client.miso.getOwnedRecordingAdminCaps(ownerAddress);
|
|
123
|
-
const administered = await client.miso.getAdministeredRecordings(ownerAddress);
|
|
124
|
-
```
|
|
125
|
-
|
|
126
|
-
`getRecordingShareType` returns the recording's own share type
|
|
127
|
-
(`RecordingShare`) and is bound on the client. `getRecordingShareTypes` is the
|
|
128
|
-
standalone query that returns both as `[RecordingShare, CompositionShare]` —
|
|
129
|
-
reach for it when building anything generic over the pair, which is most of the
|
|
130
|
-
protocol: `deal::new`, `track::new`, `recording::publish`, and the recording
|
|
131
|
-
credit/royalty-pool extensions all take the two phantoms in exactly that order.
|
|
132
|
-
|
|
133
|
-
### Deals
|
|
134
|
-
|
|
135
|
-
```ts
|
|
136
|
-
// Share types are read from the object's `Deal<RecordingShare, CompositionShare>` type parameters.
|
|
137
|
-
const deal = await client.miso.getDealById("0x...");
|
|
138
|
-
// { id, releaseId, trackSplitBps, recordingShareType, compositionShareType }
|
|
139
|
-
```
|
|
140
|
-
|
|
141
|
-
### Releases
|
|
142
|
-
|
|
143
|
-
```ts
|
|
144
|
-
// Core API (by ID)
|
|
145
54
|
const release = await client.miso.getReleaseById("0x...");
|
|
146
|
-
const
|
|
147
|
-
const
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
// GraphQL
|
|
152
|
-
const registryId = await client.miso.getReleaseRegistry();
|
|
153
|
-
```
|
|
154
|
-
|
|
155
|
-
### Share currencies
|
|
156
|
-
|
|
157
|
-
```ts
|
|
158
|
-
const shareType = await client.miso.getShareCurrencyType("0x..."); // Currency<T> object id → T
|
|
159
|
-
// Takes the share TYPE (which builders already thread around), not the Currency
|
|
160
|
-
// object id — so this is one call, not two.
|
|
161
|
-
const treasuryCapId = await client.miso.getShareCurrencyTreasuryCap(shareType, ownerAddress);
|
|
55
|
+
const caps = await client.miso.getOwnedReleaseAdminCaps(ownerAddress);
|
|
56
|
+
const [recordingShare, compositionShare] = await getRecordingShareTypes(
|
|
57
|
+
client,
|
|
58
|
+
"0x...",
|
|
59
|
+
);
|
|
162
60
|
```
|
|
163
61
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
Core-object getters (`getCompositionById`, `getDealById`, …) **throw** when the
|
|
167
|
-
object is missing — a miss means a broken reference. Extension readers
|
|
168
|
-
(`getCompositionCredits`, `getReleaseCover`, … — now in `@misofm/sdk`) return
|
|
169
|
-
**`null`** instead, because extension data is optional by design. The exported
|
|
170
|
-
`isNotFound(e)` helper distinguishes a missing-object error from a transport
|
|
171
|
-
failure across all Sui client transports, and `@misofm/sdk` re-exports it so
|
|
172
|
-
both packages share one not-found taxonomy:
|
|
173
|
-
|
|
174
|
-
```ts
|
|
175
|
-
import { isNotFound } from "@misonetwork/sdk";
|
|
176
|
-
|
|
177
|
-
try {
|
|
178
|
-
await client.miso.getReleaseById(id);
|
|
179
|
-
} catch (e) {
|
|
180
|
-
if (isNotFound(e)) { /* no such object */ } else throw e;
|
|
181
|
-
}
|
|
182
|
-
```
|
|
183
|
-
|
|
184
|
-
Also exported: `extractTypeParam("p::m::T<A>")` → `"A"` and
|
|
185
|
-
`extractTypeParams2("p::m::T<A, B>")` → `["A", "B"]` for reading share types
|
|
186
|
-
out of object type tags.
|
|
187
|
-
|
|
188
|
-
## Transaction Builders
|
|
189
|
-
|
|
190
|
-
This module exports five builders, in two shapes:
|
|
191
|
-
|
|
192
|
-
| Builder | Shape |
|
|
193
|
-
|---------|-------|
|
|
194
|
-
| `createComposition(tx, params)` | takes the `Transaction` first, returns `CompositionParts` |
|
|
195
|
-
| `createRecording(tx, params)` | takes the `Transaction` first, returns `RecordingParts` |
|
|
196
|
-
| `createDeal(tx, params)` | takes the `Transaction` first, returns a `TransactionObjectArgument` |
|
|
197
|
-
| `createRelease(tx, params, trackVec)` | takes the `Transaction` first, returns `ReleaseParts` |
|
|
198
|
-
| `rejectDeal(params)` | returns a `TxThunk` |
|
|
199
|
-
|
|
200
|
-
Only `rejectDeal` follows the thunk pattern — it returns a `TxThunk`
|
|
201
|
-
(`(tx: Transaction) => void | Promise<void>`) that appends commands to a
|
|
202
|
-
caller-owned `Transaction`. The four `create*` primitives take the
|
|
203
|
-
`Transaction` as their **first argument** and return their by-value results, so
|
|
204
|
-
those results can be threaded into later commands. Either way, everything
|
|
205
|
-
composes inside a single caller-owned PTB.
|
|
206
|
-
|
|
207
|
-
The client binds exactly one builder — `client.miso.tx.rejectDeal` — which
|
|
208
|
-
injects the client's `misoPackageId`. The `create*` primitives have no thunk to
|
|
209
|
-
bind, so they stay free functions: import them from the package root and pass
|
|
210
|
-
`misoPackageId` explicitly.
|
|
211
|
-
|
|
212
|
-
This SDK keeps the bare protocol primitives only. The four `create*` functions
|
|
213
|
-
each append a single `::new` and hand back its by-value results — never
|
|
214
|
-
dispersing a share supply, publishing (sharing) the object, or routing an admin
|
|
215
|
-
cap. The opinionated layers — the finish (disperse via minato, publish,
|
|
216
|
-
transfer), track assembly, cap disposition, and the share-currency lifecycle —
|
|
217
|
-
live in [`@misofm/sdk`](https://github.com/misofm/sdk) as **free functions that
|
|
218
|
-
take `misoPackageId` explicitly** (they are not bound onto any client's `tx`
|
|
219
|
-
namespace): `finalizeComposition`/`finalizeRecording`/`finalizeRelease`,
|
|
220
|
-
`publishComposition`/`publishRecording`/`publishCompositionAndRecording`,
|
|
221
|
-
`publishRelease`/`publishReleaseFromDeals`/`publishReleaseGraph`,
|
|
222
|
-
`disperseShares`, share-currency provisioning, and `executeViaExecutor`. Those
|
|
223
|
-
import the primitives from here and build on top.
|
|
224
|
-
|
|
225
|
-
Execute any thunk (from this SDK or composed with another) with `buildTx` +
|
|
226
|
-
`signAndExecute` — see [Execution](#execution-executets):
|
|
227
|
-
|
|
228
|
-
```ts
|
|
229
|
-
import { buildTx, signAndExecute } from "@misonetwork/sdk";
|
|
62
|
+
Core object getters throw for a missing object. The exported `isNotFound(error)`
|
|
63
|
+
helper distinguishes that condition from transport failures.
|
|
230
64
|
|
|
231
|
-
|
|
232
|
-
await signAndExecute(client, signer, tx);
|
|
233
|
-
```
|
|
65
|
+
## Transaction primitives
|
|
234
66
|
|
|
235
|
-
|
|
67
|
+
The core exports these synchronous builders, each operating on the caller's
|
|
68
|
+
`Transaction`:
|
|
236
69
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
`
|
|
70
|
+
| Builder | Result |
|
|
71
|
+
| --- | --- |
|
|
72
|
+
| `createComposition(tx, params)` | `CompositionParts` |
|
|
73
|
+
| `createRecording(tx, params)` | `RecordingParts` |
|
|
74
|
+
| `createTrack(tx, params)` | `TransactionObjectArgument` |
|
|
240
75
|
|
|
241
|
-
|
|
242
|
-
`
|
|
243
|
-
|
|
76
|
+
`createTrack` adds cap-gated `track::new`; it accepts either an on-chain
|
|
77
|
+
`recordingAdminCapId` or a PTB-local `recordingAdminCap` result. A `Track` has
|
|
78
|
+
`drop, store`, so leaving it unconsumed is valid. To create a release, collect
|
|
79
|
+
tracks with `tx.makeMoveVec({ type: `${misoPackageId}::track::Track`, elements })`
|
|
80
|
+
and call the extension's `release_registry::new_release` via `@misofm/sdk`.
|
|
244
81
|
|
|
245
82
|
```ts
|
|
246
|
-
import {
|
|
83
|
+
import { createTrack } from "@misonetwork/sdk";
|
|
247
84
|
|
|
248
|
-
const
|
|
85
|
+
const track = createTrack(tx, {
|
|
249
86
|
recordingId: "0x...",
|
|
250
|
-
recordingAdminCapId: "0x...",
|
|
87
|
+
recordingAdminCapId: "0x...",
|
|
251
88
|
recordingShareType: "0x...::share::Share",
|
|
252
89
|
compositionShareType: "0x...::share::Share",
|
|
253
|
-
|
|
90
|
+
targetReleaseId: "0x...",
|
|
254
91
|
trackSplitBps: 5000,
|
|
255
92
|
misoPackageId,
|
|
256
93
|
});
|
|
257
|
-
|
|
258
|
-
// (1) cross-party: send it to whoever assembles the release, to redeem later
|
|
259
|
-
tx.transferObjects([deal], releaseCreator);
|
|
260
|
-
|
|
261
|
-
// (2) same-party: spend it immediately as authorization for a track
|
|
262
|
-
// tx.add(contracts.track._new({ package: misoPackageId, typeArguments, arguments: [deal, recording] }));
|
|
263
|
-
```
|
|
264
|
-
|
|
265
|
-
`rejectDeal` is the one builder bound on the client. It destroys a deal without
|
|
266
|
-
including it in a release, and emits `DealRejectedEvent`:
|
|
267
|
-
|
|
268
|
-
```ts
|
|
269
|
-
client.miso.tx.rejectDeal({
|
|
270
|
-
dealId: "0x...",
|
|
271
|
-
recordingShareType: "0x...::share::Share",
|
|
272
|
-
compositionShareType: "0x...::share::Share",
|
|
273
|
-
});
|
|
274
|
-
```
|
|
275
|
-
|
|
276
|
-
### Releases
|
|
277
|
-
|
|
278
|
-
The end-to-end release publishers are **not** on `client.miso.tx` — they are free
|
|
279
|
-
functions in [`@misofm/sdk`](https://github.com/misofm/sdk) that take
|
|
280
|
-
`misoPackageId` explicitly:
|
|
281
|
-
|
|
282
|
-
```ts
|
|
283
|
-
import { publishRelease, publishReleaseFromDeals } from "@misofm/sdk";
|
|
284
|
-
|
|
285
|
-
// Sender holds every recording's admin cap (a deal is created inline per track).
|
|
286
|
-
await buildTx(publishRelease({ title, tracks, releaseRegistryId, releaseId, releaseNonce, adminAddress, misoPackageId }));
|
|
287
|
-
|
|
288
|
-
// Or assemble from pre-made Deals the sender already holds.
|
|
289
|
-
await buildTx(publishReleaseFromDeals({ title, deals, releaseRegistryId, releaseNonce, adminAddress, misoPackageId }));
|
|
290
94
|
```
|
|
291
95
|
|
|
292
|
-
`
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
96
|
+
`createComposition` and `createRecording` return their by-value components so
|
|
97
|
+
they can be composed in the same PTB. `recording::new` borrows its composition,
|
|
98
|
+
so a fresh composition can be passed directly into `createRecording` before it
|
|
99
|
+
is published.
|
|
296
100
|
|
|
297
|
-
|
|
298
|
-
trackVec)`, which appends `release::new` over a caller-built `vector<Track>` and
|
|
299
|
-
returns the release plus its admin cap.
|
|
101
|
+
### Release IDs
|
|
300
102
|
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
tracklist + nonce. Compute it up front via `simulateTransaction`:
|
|
103
|
+
Release IDs are derived on chain by simulation. `parentId` is a pure object ID,
|
|
104
|
+
not an object input—for example, the shared `ReleaseRegistry` owned by the
|
|
105
|
+
extension package.
|
|
305
106
|
|
|
306
107
|
```ts
|
|
307
|
-
const
|
|
308
|
-
sender: ownerAddress,
|
|
309
|
-
recordingIds: ["0x...", "0x..."],
|
|
310
|
-
splitBps: [5000, 5000],
|
|
108
|
+
const targetReleaseId = await client.miso.view.deriveTargetReleaseId({
|
|
109
|
+
sender: ownerAddress,
|
|
110
|
+
recordingIds: ["0x...", "0x..."],
|
|
111
|
+
splitBps: [5000, 5000],
|
|
311
112
|
nonce: "42",
|
|
312
|
-
|
|
113
|
+
parentId: releaseRegistryId,
|
|
313
114
|
});
|
|
314
115
|
```
|
|
315
116
|
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
caller decides what happens next.
|
|
321
|
-
|
|
322
|
-
The key move is **borrow-before-share**: `recording::new` takes the parent
|
|
323
|
-
composition by immutable reference, so you can pass a `createComposition(...)`
|
|
324
|
-
result straight into `createRecording`'s `composition` param while it is still an
|
|
325
|
-
unshared, transaction-local value. That is what lets a composition and its first
|
|
326
|
-
recording be minted in one PTB.
|
|
327
|
-
|
|
328
|
-
```ts
|
|
329
|
-
import { Transaction } from "@mysten/sui/transactions";
|
|
330
|
-
import { createComposition, createRecording } from "@misonetwork/sdk";
|
|
331
|
-
|
|
332
|
-
const tx = new Transaction();
|
|
333
|
-
|
|
334
|
-
// 1. Composition — returns { composition, adminCap, balance }.
|
|
335
|
-
const comp = createComposition(tx, {
|
|
336
|
-
title: "Song Title",
|
|
337
|
-
royaltyRateBps: 1000,
|
|
338
|
-
shareType: compositionShareType, // `${sharePkg}::share::Share`
|
|
339
|
-
shareCurrencyId: "0x...", // Currency<Share>
|
|
340
|
-
shareTreasuryCapId: "0x...", // TreasuryCap<Share>, consumed by `new`
|
|
341
|
-
misoPackageId,
|
|
342
|
-
});
|
|
343
|
-
|
|
344
|
-
// 2. Recording — borrow-before-share: hand the still-unshared composition
|
|
345
|
-
// straight in. No on-chain object id is needed for it.
|
|
346
|
-
const rec = createRecording(tx, {
|
|
347
|
-
composition: comp.composition, // or `tx.object(compositionId)` if already on chain
|
|
348
|
-
compositionShareType,
|
|
349
|
-
shareType: recordingShareType,
|
|
350
|
-
shareCurrencyId: "0x...",
|
|
351
|
-
shareTreasuryCapId: "0x...",
|
|
352
|
-
maxRoyaltyRateBps: 1000, // slippage guard — see below
|
|
353
|
-
misoPackageId,
|
|
354
|
-
});
|
|
117
|
+
Generated `contracts.release._new` is intentionally exposed because codegen
|
|
118
|
+
mirrors the ABI, but it is not PTB-callable: its final parameter is `&mut UID`.
|
|
119
|
+
Release construction therefore belongs in `@misofm/sdk`, whose
|
|
120
|
+
`release_registry::new_release` already owns that UID.
|
|
355
121
|
|
|
356
|
-
|
|
357
|
-
// — e.g. `finalizeComposition(tx, { ...comp, ... })` / `finalizeRecording(tx,
|
|
358
|
-
// { ...rec, ... })` from `@misofm/sdk`, which disperse the balances, publish
|
|
359
|
-
// the works, and route the admin caps.
|
|
360
|
-
```
|
|
122
|
+
### Generated bindings
|
|
361
123
|
|
|
362
|
-
`
|
|
363
|
-
|
|
364
|
-
|
|
124
|
+
`contracts` and `client.miso.call` expose generated `composition`, `recording`,
|
|
125
|
+
`release`, and `track` modules. Do not edit `src/contracts/`; run `bun run
|
|
126
|
+
codegen` after updating protocol source.
|
|
365
127
|
|
|
366
128
|
```ts
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
// rel.release must be consumed by `release::publish` in this same tx.
|
|
129
|
+
tx.add(client.miso.call.track._new({
|
|
130
|
+
typeArguments: [recordingShareType, compositionShareType],
|
|
131
|
+
arguments: [adminCap, tx.object(recordingId), tx.pure.id(targetReleaseId), tx.pure.u16(5000)],
|
|
132
|
+
}));
|
|
372
133
|
```
|
|
373
134
|
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
A composition's royalty rate is floored but can be **raised** by its admin. If it
|
|
377
|
-
goes up between the moment you read it and the moment your transaction lands, a
|
|
378
|
-
recording you thought owed 10% could land owing more. `CreateRecordingParams.maxRoyaltyRateBps`
|
|
379
|
-
is the guard: it is the maximum composition royalty rate (in bps) the recorder is
|
|
380
|
-
willing to grant, and `recording::new` aborts with `ERoyaltyRateAboveMax` if the
|
|
381
|
-
composition's live rate exceeds it. Pass the rate you actually observed.
|
|
382
|
-
|
|
383
|
-
It is optional, and defaults to the exported `PROTOCOL_MAX_ROYALTY_RATE_BPS`
|
|
384
|
-
(`2000`, the protocol's `MAX_ROYALTY_RATE_BPS`) — which accepts any legal rate,
|
|
385
|
-
i.e. no slippage protection. Set it explicitly whenever you are recording someone
|
|
386
|
-
else's composition.
|
|
387
|
-
|
|
388
|
-
```ts
|
|
389
|
-
import { PROTOCOL_MAX_ROYALTY_RATE_BPS } from "@misonetwork/sdk";
|
|
390
|
-
|
|
391
|
-
const comp = await client.miso.getCompositionById(compositionId);
|
|
392
|
-
createRecording(tx, { /* … */ maxRoyaltyRateBps: comp.royaltyRate.value });
|
|
393
|
-
```
|
|
394
|
-
|
|
395
|
-
#### Result shapes
|
|
396
|
-
|
|
397
|
-
```ts
|
|
398
|
-
import type {
|
|
399
|
-
CompositionParts, RecordingParts, ReleaseParts, ShareCurrencyBinding,
|
|
400
|
-
} from "@misonetwork/sdk";
|
|
401
|
-
|
|
402
|
-
// CompositionParts { composition, adminCap, balance } — balance is the creator's
|
|
403
|
-
// freshly-minted share supply
|
|
404
|
-
// RecordingParts { recording, adminCap, balance } — balance is what remains
|
|
405
|
-
// after the composition's cut
|
|
406
|
-
// ReleaseParts { release, adminCap }
|
|
407
|
-
// All fields are `TransactionObjectArgument`s, for threading onward in the PTB.
|
|
408
|
-
```
|
|
409
|
-
|
|
410
|
-
`ShareCurrencyBinding` is the trio every work-creating builder needs, extended by
|
|
411
|
-
both `CreateCompositionParams` and `CreateRecordingParams`: `shareType` (the
|
|
412
|
-
`${packageId}::share::Share` type), `shareCurrencyId` (the `Currency<Share>`
|
|
413
|
-
object), and `shareTreasuryCapId` (the `TreasuryCap<Share>`, consumed by `new`).
|
|
414
|
-
All three are passed explicitly rather than read from chain, which keeps the
|
|
415
|
-
builders synchronous — no RPC inside the transaction build.
|
|
416
|
-
|
|
417
|
-
**Lifecycle requirement.** `Composition`, `Recording`, and `Release` are all
|
|
418
|
-
`key`-only with no `drop`, so each created object MUST be consumed by its
|
|
419
|
-
`publish` in the same transaction — none can be transferred, wrapped, shared, or
|
|
420
|
-
discarded, and none can outlive its creating PTB. That is a same-**transaction**
|
|
421
|
-
requirement, not a same-**function** one: pairing a `create*` here with a
|
|
422
|
-
`finalize*` from `@misofm/sdk` on the same `tx` satisfies it. Keeping them apart
|
|
423
|
-
is what makes the intermediate value useful at all — borrowing a still-unshared
|
|
424
|
-
composition into `recording::new`, attaching a royalty pool via `uid_mut`, or
|
|
425
|
-
routing an admin cap somewhere other than a plain address (every admin cap is
|
|
426
|
-
`key, store`, hence freely routable).
|
|
427
|
-
|
|
428
|
-
Whole-graph orchestration lives in `@misofm/sdk` too: `publishReleaseGraph`
|
|
429
|
-
mints every composition and recording, attaches optional royalty pools, builds
|
|
430
|
-
the deals/tracks, and publishes the release — with the release id derived
|
|
431
|
-
on-chain — all in one PTB, importing the primitives from here.
|
|
432
|
-
|
|
433
|
-
```ts
|
|
434
|
-
import { publishReleaseGraph } from "@misofm/sdk";
|
|
435
|
-
```
|
|
436
|
-
|
|
437
|
-
## Extensions (moved to `@misofm/sdk`)
|
|
438
|
-
|
|
439
|
-
Extension helpers are no longer part of this package. As of **0.3.0**, credits,
|
|
440
|
-
cover art, and royalty pools ship from [`@misofm/sdk`](https://github.com/misofm/sdk):
|
|
441
|
-
|
|
442
|
-
| Was `@misonetwork/sdk` | Now `@misofm/sdk` |
|
|
443
|
-
|---|---|
|
|
444
|
-
| `attachCompositionCredit`, `attachRecordingCredit`, `addReleaseCredit`, `addRecordingPrimaryArtist`, `addRecordingFeaturedArtist`, `getCompositionCredits`, `getRecordingCredits`, `getReleaseCredits` | same names |
|
|
445
|
-
| `setReleaseCover`, `getReleaseCover` | same names |
|
|
446
|
-
| `attachCompositionRoyaltyPool`, `attachRecordingRoyaltyPool` | same names |
|
|
447
|
-
| `contracts.compositionCredits`, `.recordingCredits`, `.releaseCredits`, `.compositionPartyRole`, `.recordingPartyRole`, `.releasePartyRole`, `.royaltyPool`, `.royaltyPoolStake`, `.compositionRoyaltyPool`, `.recordingRoyaltyPool`, `.coverArt`, `.releaseCoverArt` | `contracts.*`, same names |
|
|
448
|
-
| types `CreditView`, `RecordingCreditsView`, `CompositionRole`, `RecordingRole`, `RecordingRoleLevel`, `RecordingLeveledRoleType`, `ReleaseRole`, `ReleaseCoverView`, `CoverImageRef` | same names |
|
|
135
|
+
## Event parsers
|
|
449
136
|
|
|
450
|
-
|
|
137
|
+
Core emits only publish/royalty events. Parse them with
|
|
138
|
+
`client.miso.parse.compositionPublishedEvent`,
|
|
139
|
+
`compositionRoyaltySetEvent`, `recordingPublishedEvent`, and
|
|
140
|
+
`releasePublishedEvent`. Track creation has no core event; pre-publish
|
|
141
|
+
observability is an extension concern.
|
|
451
142
|
|
|
452
|
-
|
|
453
|
-
-import { attachRecordingCredit, setReleaseCover } from "@misonetwork/sdk";
|
|
454
|
-
+import { attachRecordingCredit, setReleaseCover } from "@misofm/sdk";
|
|
455
|
-
```
|
|
456
|
-
|
|
457
|
-
The reasoning is the split this package exists to hold. An extension is not part
|
|
458
|
-
of what a Composition or Recording *is*; it is a choice about how to describe one
|
|
459
|
-
— which roles exist and what they are called, what counts as a cover, whether
|
|
460
|
-
royalties accumulate in a pool. The protocol offers a cap-gated `&mut UID` hook
|
|
461
|
-
and takes no position on what hangs off it. Everything that *does* take a
|
|
462
|
-
position is business logic, and business logic ships from the platform package.
|
|
463
|
-
|
|
464
|
-
Share-currency provisioning (`createShareCurrency`, `publishShareCurrencies`,
|
|
465
|
-
`initializeShareCurrencies`) moved to `@misofm/sdk` earlier for the same reason —
|
|
466
|
-
every composition and recording is backed by its own fixed-supply share currency,
|
|
467
|
-
and provisioning one is part of the opinionated publish flow, not a protocol
|
|
468
|
-
primitive.
|
|
469
|
-
|
|
470
|
-
## Execution (`execute.ts`)
|
|
471
|
-
|
|
472
|
-
Builders only append to a `Transaction`; this module submits:
|
|
473
|
-
|
|
474
|
-
```ts
|
|
475
|
-
import { buildTx, signAndExecute, execThunks, publishedPackageId, createdByType, balanceDelta } from "@misonetwork/sdk";
|
|
476
|
-
|
|
477
|
-
const result = await execThunks(client, signer, thunkA, thunkB); // build + sign + execute + wait
|
|
478
|
-
// ExecResult: { digest, changedObjects, objectTypes, balanceChanges, gasUsed }
|
|
479
|
-
|
|
480
|
-
// Object-change extractors:
|
|
481
|
-
const pkgId = publishedPackageId(result);
|
|
482
|
-
const currencyId = createdByType(result, "::coin_registry::Currency<");
|
|
483
|
-
const delta = balanceDelta(result, address, "0x2::sui::SUI");
|
|
484
|
-
```
|
|
485
|
-
|
|
486
|
-
`@misofm/sdk` builds `executeViaExecutor(executor, ...thunks)` on top of this
|
|
487
|
-
module's `buildTx`/`toExecResult` — it submits a non-idempotent PTB through a
|
|
488
|
-
`ParallelTransactionExecutor` exactly once (no auto-retry), for its batched
|
|
489
|
-
share-currency provisioning.
|
|
490
|
-
|
|
491
|
-
## Event Parsers
|
|
492
|
-
|
|
493
|
-
Miso uses a lean publish-only event model: published objects emit a single pointer event,
|
|
494
|
-
and indexers fetch the immutable object by ID. Parse the BCS-encoded events from transaction
|
|
495
|
-
results:
|
|
496
|
-
|
|
497
|
-
```ts
|
|
498
|
-
// Pointer events (carry only identities)
|
|
499
|
-
const comp = client.miso.parse.compositionPublishedEvent(bcsBytes); // { compositionId }
|
|
500
|
-
const rec = client.miso.parse.recordingPublishedEvent(bcsBytes); // { recordingId }
|
|
501
|
-
const rel = client.miso.parse.releasePublishedEvent(bcsBytes); // { releaseId }
|
|
502
|
-
|
|
503
|
-
// Non-pointer events
|
|
504
|
-
const royalty = client.miso.parse.compositionRoyaltySetEvent(bcsBytes); // { royaltyRateBps }
|
|
505
|
-
const created = client.miso.parse.dealCreatedEvent(bcsBytes); // { dealId, releaseId, trackSplitBps }
|
|
506
|
-
const accepted = client.miso.parse.dealAcceptedEvent(bcsBytes); // { dealId, releaseId }
|
|
507
|
-
const rejected = client.miso.parse.dealRejectedEvent(bcsBytes); // { dealId, releaseId }
|
|
508
|
-
```
|
|
509
|
-
|
|
510
|
-
The same functions are exported standalone as `parseCompositionPublishedEvent`, etc.
|
|
511
|
-
|
|
512
|
-
## Types
|
|
513
|
-
|
|
514
|
-
All Miso domain types are exported:
|
|
515
|
-
|
|
516
|
-
```ts
|
|
517
|
-
import type {
|
|
518
|
-
// Core entities
|
|
519
|
-
Composition, Recording, Release, Deal, Track, BPS,
|
|
520
|
-
// Admin caps
|
|
521
|
-
CompositionAdminCap, RecordingAdminCap, ReleaseAdminCap,
|
|
522
|
-
// State machines
|
|
523
|
-
CompositionState, RecordingState, ReleaseState, TrackState,
|
|
524
|
-
// Events
|
|
525
|
-
CompositionPublishedEvent, CompositionRoyaltySetEvent,
|
|
526
|
-
RecordingPublishedEvent, ReleasePublishedEvent,
|
|
527
|
-
DealCreatedEvent, DealAcceptedEvent, DealRejectedEvent,
|
|
528
|
-
// Transaction builder inputs & results (from ./transactions)
|
|
529
|
-
TxThunk, ShareCurrencyBinding,
|
|
530
|
-
CompositionParts, RecordingParts, ReleaseParts,
|
|
531
|
-
CreateCompositionParams, CreateRecordingParams, CreateDealParams,
|
|
532
|
-
CreateReleaseParams, RejectDealParams,
|
|
533
|
-
} from "@misonetwork/sdk";
|
|
534
|
-
```
|
|
535
|
-
|
|
536
|
-
The credit and cover types (`CreditView`, `RecordingCreditsView`,
|
|
537
|
-
`CompositionRole`, `RecordingRole`, `RecordingRoleLevel`,
|
|
538
|
-
`RecordingLeveledRoleType`, `ReleaseRole`, `ReleaseCoverView`, `CoverImageRef`)
|
|
539
|
-
moved to `@misofm/sdk` in 0.3.0 — see [Extensions](#extensions-moved-to-misofmsdk).
|
|
540
|
-
|
|
541
|
-
The non-type value export `PROTOCOL_MAX_ROYALTY_RATE_BPS` (`2000`) is documented
|
|
542
|
-
under [royalty-rate slippage](#royalty-rate-slippage-maxroyaltyratebps).
|
|
543
|
-
|
|
544
|
-
## Generated Bindings (`contracts`)
|
|
545
|
-
|
|
546
|
-
The codegen-generated, ABI-bound bindings (BCS structs + type-safe Move calls)
|
|
547
|
-
are exported under the `contracts` namespace — the core protocol modules
|
|
548
|
-
`composition`, `recording`, `release`, `deal`, and `track`. Bindings for the
|
|
549
|
-
extension packages are in `@misofm/sdk`'s own `contracts` namespace:
|
|
550
|
-
|
|
551
|
-
```ts
|
|
552
|
-
import { contracts } from "@misonetwork/sdk";
|
|
553
|
-
|
|
554
|
-
const parsed = contracts.composition.Composition.parse(bcsBytes);
|
|
555
|
-
tx.add(contracts.deal.reject({ package: misoPackageId, typeArguments, arguments: [dealId] }));
|
|
556
|
-
```
|
|
143
|
+
## 0.4.0 → 0.5.0 migration
|
|
557
144
|
|
|
558
|
-
|
|
559
|
-
|
|
145
|
+
| Previous API | 0.5.0 |
|
|
146
|
+
| --- | --- |
|
|
147
|
+
| `createDeal` | `createTrack`; use `targetReleaseId` rather than `releaseId` |
|
|
148
|
+
| `rejectDeal`, `getDealById`, Deal event parsers/types, `contracts.deal` | removed; offer/withdrawal policy is extension-layer |
|
|
149
|
+
| `createRelease` | removed; use `@misofm/sdk` `release_registry::new_release` |
|
|
150
|
+
| `deriveReleaseId({ releaseRegistryId })` | `deriveTargetReleaseId({ parentId })`; the parent is pure |
|
|
151
|
+
| `getReleaseRegistry`, `MisoOptions.releaseRegistryId` | removed; extension registry is a different package type |
|
|
152
|
+
| `client.miso.tx` | removed; no core thunk builders remain |
|
|
153
|
+
| deployed disc-shaped release fallback | removed; reads parse only canonical flat `Release.tracks` |
|
|
560
154
|
|
|
561
|
-
|
|
155
|
+
Update `@misofm/sdk` in the same release window: it owns release-registry
|
|
156
|
+
bindings and the callable release-construction flow.
|
|
562
157
|
|
|
563
|
-
|
|
564
|
-
functions that compute object IDs without network calls:
|
|
158
|
+
## Derived admin caps
|
|
565
159
|
|
|
566
|
-
| Function |
|
|
567
|
-
|
|
568
|
-
| `deriveCompositionAdminCapId` |
|
|
569
|
-
| `deriveRecordingAdminCapId` |
|
|
570
|
-
| `deriveReleaseAdminCapId` |
|
|
160
|
+
| Function | Parent |
|
|
161
|
+
| --- | --- |
|
|
162
|
+
| `deriveCompositionAdminCapId` | Composition |
|
|
163
|
+
| `deriveRecordingAdminCapId` | Recording |
|
|
164
|
+
| `deriveReleaseAdminCapId` | Release |
|
|
571
165
|
|
|
572
166
|
## License
|
|
573
167
|
|