@misofm/platform 0.0.0 → 0.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +686 -3
- package/dist/auth.d.ts +73 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +193 -0
- package/dist/auth.js.map +1 -0
- package/dist/catalog.d.ts +48 -0
- package/dist/catalog.d.ts.map +1 -0
- package/dist/catalog.js +92 -0
- package/dist/catalog.js.map +1 -0
- package/dist/client.d.ts +462 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +788 -0
- package/dist/client.js.map +1 -0
- package/dist/contracts.d.ts +34 -0
- package/dist/contracts.d.ts.map +1 -0
- package/dist/contracts.js +49 -0
- package/dist/contracts.js.map +1 -0
- package/dist/cover.d.ts +69 -0
- package/dist/cover.d.ts.map +1 -0
- package/dist/cover.js +132 -0
- package/dist/cover.js.map +1 -0
- package/dist/credits.d.ts +200 -0
- package/dist/credits.d.ts.map +1 -0
- package/dist/credits.js +465 -0
- package/dist/credits.js.map +1 -0
- package/dist/deployments.d.ts +224 -0
- package/dist/deployments.d.ts.map +1 -0
- package/dist/deployments.js +177 -0
- package/dist/deployments.js.map +1 -0
- package/dist/execute.d.ts +30 -0
- package/dist/execute.d.ts.map +1 -0
- package/dist/execute.js +31 -0
- package/dist/execute.js.map +1 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +52 -0
- package/dist/index.js.map +1 -0
- package/dist/internal.d.ts +13 -0
- package/dist/internal.d.ts.map +1 -0
- package/dist/internal.js +41 -0
- package/dist/internal.js.map +1 -0
- package/dist/mix.d.ts +144 -0
- package/dist/mix.d.ts.map +1 -0
- package/dist/mix.js +656 -0
- package/dist/mix.js.map +1 -0
- package/dist/pressing.d.ts +137 -0
- package/dist/pressing.d.ts.map +1 -0
- package/dist/pressing.js +390 -0
- package/dist/pressing.js.map +1 -0
- package/dist/publication.d.ts +216 -0
- package/dist/publication.d.ts.map +1 -0
- package/dist/publication.js +872 -0
- package/dist/publication.js.map +1 -0
- package/dist/queries.d.ts +2 -0
- package/dist/queries.d.ts.map +1 -0
- package/dist/queries.js +8 -0
- package/dist/queries.js.map +1 -0
- package/dist/read/artist.d.ts +18 -0
- package/dist/read/artist.d.ts.map +1 -0
- package/dist/read/artist.js +86 -0
- package/dist/read/artist.js.map +1 -0
- package/dist/read/catalog.d.ts +93 -0
- package/dist/read/catalog.d.ts.map +1 -0
- package/dist/read/catalog.js +441 -0
- package/dist/read/catalog.js.map +1 -0
- package/dist/read/client.d.ts +37 -0
- package/dist/read/client.d.ts.map +1 -0
- package/dist/read/client.js +50 -0
- package/dist/read/client.js.map +1 -0
- package/dist/read/config.d.ts +68 -0
- package/dist/read/config.d.ts.map +1 -0
- package/dist/read/config.js +63 -0
- package/dist/read/config.js.map +1 -0
- package/dist/read/genres.d.ts +7 -0
- package/dist/read/genres.d.ts.map +1 -0
- package/dist/read/genres.js +38 -0
- package/dist/read/genres.js.map +1 -0
- package/dist/read/index.d.ts +14 -0
- package/dist/read/index.d.ts.map +1 -0
- package/dist/read/index.js +23 -0
- package/dist/read/index.js.map +1 -0
- package/dist/read/internal/scalars.d.ts +23 -0
- package/dist/read/internal/scalars.d.ts.map +1 -0
- package/dist/read/internal/scalars.js +57 -0
- package/dist/read/internal/scalars.js.map +1 -0
- package/dist/read/internal/walrus.d.ts +6 -0
- package/dist/read/internal/walrus.d.ts.map +1 -0
- package/dist/read/internal/walrus.js +29 -0
- package/dist/read/internal/walrus.js.map +1 -0
- package/dist/read/receipts.d.ts +41 -0
- package/dist/read/receipts.d.ts.map +1 -0
- package/dist/read/receipts.js +398 -0
- package/dist/read/receipts.js.map +1 -0
- package/dist/read/types.d.ts +328 -0
- package/dist/read/types.d.ts.map +1 -0
- package/dist/read/types.js +21 -0
- package/dist/read/types.js.map +1 -0
- package/dist/read/wallet.d.ts +74 -0
- package/dist/read/wallet.d.ts.map +1 -0
- package/dist/read/wallet.js +578 -0
- package/dist/read/wallet.js.map +1 -0
- package/dist/read/works.d.ts +29 -0
- package/dist/read/works.d.ts.map +1 -0
- package/dist/read/works.js +191 -0
- package/dist/read/works.js.map +1 -0
- package/dist/recording-extensions.d.ts +62 -0
- package/dist/recording-extensions.d.ts.map +1 -0
- package/dist/recording-extensions.js +159 -0
- package/dist/recording-extensions.js.map +1 -0
- package/dist/release-extensions.d.ts +93 -0
- package/dist/release-extensions.d.ts.map +1 -0
- package/dist/release-extensions.js +190 -0
- package/dist/release-extensions.js.map +1 -0
- package/dist/release-graph.d.ts +65 -0
- package/dist/release-graph.d.ts.map +1 -0
- package/dist/release-graph.js +136 -0
- package/dist/release-graph.js.map +1 -0
- package/dist/share-template.d.ts +3 -0
- package/dist/share-template.d.ts.map +1 -0
- package/dist/share-template.js +46 -0
- package/dist/share-template.js.map +1 -0
- package/dist/share.d.ts +67 -0
- package/dist/share.d.ts.map +1 -0
- package/dist/share.js +157 -0
- package/dist/share.js.map +1 -0
- package/dist/transactions.d.ts +216 -0
- package/dist/transactions.d.ts.map +1 -0
- package/dist/transactions.js +314 -0
- package/dist/transactions.js.map +1 -0
- package/dist/vault.d.ts +364 -0
- package/dist/vault.d.ts.map +1 -0
- package/dist/vault.js +507 -0
- package/dist/vault.js.map +1 -0
- package/package.json +145 -5
- package/src/auth.ts +275 -0
- package/src/catalog.ts +189 -0
- package/src/client.ts +1320 -0
- package/src/contracts.ts +54 -0
- package/src/cover.ts +240 -0
- package/src/credits.ts +906 -0
- package/src/deployments.ts +357 -0
- package/src/execute.ts +52 -0
- package/src/index.ts +69 -0
- package/src/internal.ts +46 -0
- package/src/mix.ts +910 -0
- package/src/pressing.ts +705 -0
- package/src/publication.ts +1214 -0
- package/src/queries.ts +9 -0
- package/src/read/artist.ts +118 -0
- package/src/read/catalog.ts +668 -0
- package/src/read/client.ts +87 -0
- package/src/read/config.ts +138 -0
- package/src/read/genres.ts +37 -0
- package/src/read/index.ts +85 -0
- package/src/read/internal/scalars.ts +59 -0
- package/src/read/internal/walrus.ts +42 -0
- package/src/read/receipts.ts +476 -0
- package/src/read/types.ts +415 -0
- package/src/read/wallet.ts +687 -0
- package/src/read/works.ts +297 -0
- package/src/recording-extensions.ts +256 -0
- package/src/release-extensions.ts +311 -0
- package/src/release-graph.ts +219 -0
- package/src/share-template.ts +55 -0
- package/src/share.ts +261 -0
- package/src/transactions.ts +542 -0
- package/src/vault.ts +1009 -0
package/README.md
CHANGED
|
@@ -1,6 +1,689 @@
|
|
|
1
1
|
# @misofm/platform
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
The complete client SDK for the **Miso platform layer** on Sui: composed catalog,
|
|
4
|
+
artist, wallet, and receipt reads; the record production line and sale of copies;
|
|
5
|
+
and fail-closed Vault custody, raw Actions, and safe crank plugins built on `@misofm/protocol`'s
|
|
6
|
+
protocol and data-extension primitives.
|
|
5
7
|
|
|
6
|
-
|
|
8
|
+
## The split
|
|
9
|
+
|
|
10
|
+
Miso ships two SDK packages, and the package name tells you which promise you are
|
|
11
|
+
holding:
|
|
12
|
+
|
|
13
|
+
| Package | Layer | Owns |
|
|
14
|
+
| -------------------- | ------------ | -------------------------------------------------------------------------------------------------------------------------------------- |
|
|
15
|
+
| `@misofm/protocol` | **Protocol** | Composition, Recording, Release, Party identity; metadata/data extensions; utilities; generic royalty-pool and routed-stake primitives |
|
|
16
|
+
| `@misofm/platform` | **Platform** | Pressing, Listing, Record, and an explicitly deployed Vault/Action/plugin compatibility set |
|
|
17
|
+
|
|
18
|
+
A release is protocol. Pressing a record off that release and selling it is
|
|
19
|
+
platform. So is deciding _what to do_ with a freshly-minted work's share
|
|
20
|
+
supply — the protocol only knows how to mint one. Keeping the boundary at the
|
|
21
|
+
package line is what stops the open protocol from quietly growing a
|
|
22
|
+
storefront (or an opinion about tokenomics).
|
|
23
|
+
|
|
24
|
+
Extensions add data to a work. Raw Actions accept an admin cap and remain
|
|
25
|
+
composable with either direct authority or a scoped Vault borrow. Three safe,
|
|
26
|
+
permissionless crank plugins borrow through their own witness: a shared
|
|
27
|
+
`Vault<AdminCap>` custodies the raw cap, while its owner holds a
|
|
28
|
+
`VaultAdminCap<AdminCap>`. A plugin borrows the cap and must return the exact
|
|
29
|
+
object in the same PTB. The SDK supports both vault authorities and legacy
|
|
30
|
+
address-owned admin caps explicitly; it never silently treats a legacy cap as a
|
|
31
|
+
vaulted one. New Vault IDs are derived from the shared `VaultRegistry`, the raw
|
|
32
|
+
cap ID, and its type; each VaultAdminCap ID is then derived from its Vault.
|
|
33
|
+
|
|
34
|
+
This package depends on `@misofm/protocol` directly and imports its bare
|
|
35
|
+
`createComposition`/`createRecording` primitives, composing them with its own
|
|
36
|
+
minato-dispersal and share-currency logic in the same PTB — the
|
|
37
|
+
transaction-thunk composition pattern from the
|
|
38
|
+
[Sui SDK building guide](https://sdk.mystenlabs.com/sui/sdk-building), just
|
|
39
|
+
crossing a package boundary.
|
|
40
|
+
|
|
41
|
+
```sh
|
|
42
|
+
bun add @misofm/platform@^0.18.0
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
`@misofm/protocol` resolves transitively through that dependency, so
|
|
46
|
+
applications get exactly one protocol SDK and one compatible deployment map
|
|
47
|
+
without installing it themselves. Registration takes a recursively frozen
|
|
48
|
+
snapshot of custom deployment/config records without freezing the caller's
|
|
49
|
+
original objects, so later caller mutation cannot retarget an existing client.
|
|
50
|
+
|
|
51
|
+
### Canonical Record-gated sessions
|
|
52
|
+
|
|
53
|
+
`@misofm/platform/mix` defines the complete protected-playback wire contract. A
|
|
54
|
+
Record resolves its immutable Release track to a Recording, then derives that
|
|
55
|
+
Recording's `recording_engine_session::ExtensionKey` dynamic field directly.
|
|
56
|
+
The field names one plaintext Walrus `miso.engine-session/1` document containing
|
|
57
|
+
the encrypted stem blob IDs and one Seal-wrapped 32-byte session key. No event
|
|
58
|
+
scan, indexer-maintained relationship, or second encrypted manifest is needed.
|
|
59
|
+
|
|
60
|
+
The same entry point exposes exact identity encoding, strict canonical-session
|
|
61
|
+
parsing, Seal-envelope inspection, and explicit attach/replace/unset PTB
|
|
62
|
+
builders. The bundled Testnet deployment pins the Record, policy, gate, and
|
|
63
|
+
engine-session identities together at `recordSales.recordPackageId`,
|
|
64
|
+
`packages.recordSealPolicy`, `objects.recordGate`, and
|
|
65
|
+
`packages.recordingEngineSession`.
|
|
66
|
+
|
|
67
|
+
## The model
|
|
68
|
+
|
|
69
|
+
A release may have one `Pressing` per positive `u16` edition. Each Pressing owns its
|
|
70
|
+
independent `u32` Record-number sequence, current supply, optional immutable `u32`
|
|
71
|
+
maximum supply, and authorized distributor witness types.
|
|
72
|
+
|
|
73
|
+
Selling in a currency is a `Listing<Currency>`, one per currency, permanent, edited in
|
|
74
|
+
place rather than replaced. The Listing's enabled/disabled state is the sale switch;
|
|
75
|
+
the Pressing has no schedule state.
|
|
76
|
+
|
|
77
|
+
**Everything is address math.** The pressing's UID derives off its release's, each
|
|
78
|
+
listing's off the pressing's. The protocol's canonical `ReleaseRegistry` creates the
|
|
79
|
+
release; there is no _pressing_ registry or mutable lookup pointer to follow, so
|
|
80
|
+
"where is it" is answered offline. A Pressing derives from `(release, edition)`, a
|
|
81
|
+
Record from `(pressing, number)`, and a `Listing<Currency>` from its Pressing under
|
|
82
|
+
the separate immutable Record Shop package. There are no Record Registry or Settings
|
|
83
|
+
singletons.
|
|
84
|
+
|
|
85
|
+
## Usage
|
|
86
|
+
|
|
87
|
+
Register the client extension on any client implementing Sui's Core API
|
|
88
|
+
([SDK building guidelines](https://sdk.mystenlabs.com/sui/sdk-building)):
|
|
89
|
+
|
|
90
|
+
```ts
|
|
91
|
+
import { SuiGrpcClient } from "@mysten/sui/grpc";
|
|
92
|
+
import { Transaction } from "@mysten/sui/transactions";
|
|
93
|
+
import { miso } from "@misofm/platform";
|
|
94
|
+
|
|
95
|
+
const client = new SuiGrpcClient({ network: "testnet", baseUrl }).$extend(
|
|
96
|
+
miso({ deployment: verifiedDeployment }),
|
|
97
|
+
);
|
|
98
|
+
|
|
99
|
+
// One memoized Core API read proves this endpoint is the deployment's exact
|
|
100
|
+
// ledger before any synchronous client-bound builder can be used.
|
|
101
|
+
await client.miso.ready();
|
|
102
|
+
|
|
103
|
+
// The permissionless protocol SDK is part of the same facade.
|
|
104
|
+
const release = await client.miso.protocol.getReleaseById(releaseId);
|
|
105
|
+
const party = await client.miso.party.getPartyById(partyId);
|
|
106
|
+
|
|
107
|
+
// Read: run + one currency's offer, one round trip, no registry lookup.
|
|
108
|
+
const { pressing, listing } = await client.miso.getSale({
|
|
109
|
+
releaseId,
|
|
110
|
+
edition,
|
|
111
|
+
currencyType: USD_COIN_TYPE,
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
// Write: a thunk, so it composes with protocol calls in the same PTB.
|
|
115
|
+
const tx = new Transaction();
|
|
116
|
+
tx.add(
|
|
117
|
+
client.miso.tx.purchaseRecord({
|
|
118
|
+
releaseId,
|
|
119
|
+
edition,
|
|
120
|
+
currencyType: USD_COIN_TYPE,
|
|
121
|
+
paymentAmount: listing.pricing.amount,
|
|
122
|
+
expectedPricing: listing.pricing,
|
|
123
|
+
recipient: buyer,
|
|
124
|
+
}),
|
|
125
|
+
);
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
The bundled Testnet deployment includes both verified immutable package IDs.
|
|
129
|
+
Custom deployments can still mark sales unavailable explicitly; sales builders
|
|
130
|
+
and readers fail closed whenever either package is unavailable.
|
|
131
|
+
|
|
132
|
+
Holding the ids yourself? The bare APIs take `recordPackageId` and/or
|
|
133
|
+
`recordShopPackageId` explicitly:
|
|
134
|
+
|
|
135
|
+
```ts
|
|
136
|
+
import { purchaseRecord, getSale } from "@misofm/platform/pressing";
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
Verified package and singleton IDs are bundled in
|
|
140
|
+
`MISO_PLATFORM_DEPLOYMENTS.testnet`. Calling `miso()` selects that verified map
|
|
141
|
+
from the Sui client's network. Unbundled and custom networks still fail closed
|
|
142
|
+
unless the caller passes one complete deployment through `miso({ deployment })`.
|
|
143
|
+
|
|
144
|
+
### High-level platform reads
|
|
145
|
+
|
|
146
|
+
`@misofm/platform/read` turns protocol, pressing, Party, credits, cover, and wallet
|
|
147
|
+
objects into the JSON-safe views a client actually renders. It works in browsers,
|
|
148
|
+
Workers, and servers. Miso's HTTP API is a thin validated and cached transport over
|
|
149
|
+
this same surface, not a separate domain implementation.
|
|
150
|
+
|
|
151
|
+
```ts
|
|
152
|
+
import {
|
|
153
|
+
createMisoClient,
|
|
154
|
+
getDiscoverShelf,
|
|
155
|
+
getReleaseDetail,
|
|
156
|
+
getOwnedRecords,
|
|
157
|
+
} from "@misofm/platform/read";
|
|
158
|
+
|
|
159
|
+
const miso = createMisoClient({ config: verifiedReadConfig });
|
|
160
|
+
|
|
161
|
+
const discover = await getDiscoverShelf(miso);
|
|
162
|
+
const release = await getReleaseDetail(miso, releaseId);
|
|
163
|
+
const library = await getOwnedRecords(miso, walletAddress);
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
The package root also exposes the same functions under the `read` namespace:
|
|
167
|
+
|
|
168
|
+
```ts
|
|
169
|
+
import { read } from "@misofm/platform";
|
|
170
|
+
|
|
171
|
+
const miso = read.createMisoClient({ config: verifiedReadConfig });
|
|
172
|
+
const artist = await read.getArtistProfile(miso, partyId);
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
### Authenticated platform mutations
|
|
176
|
+
|
|
177
|
+
`@misofm/platform/auth` implements Miso's Enoki + Sui personal-message authorization
|
|
178
|
+
protocol without owning session state or private credentials. It asks the API
|
|
179
|
+
for a short-lived, method/path-bound challenge, validates the response, signs
|
|
180
|
+
the exact bytes with the caller's Sui signer, and sends the authenticated
|
|
181
|
+
mutation.
|
|
182
|
+
|
|
183
|
+
```ts
|
|
184
|
+
import { authenticatedFetch } from "@misofm/platform/auth";
|
|
185
|
+
|
|
186
|
+
await authenticatedFetch(
|
|
187
|
+
"https://api.testnet.miso.fm/platform/usernames/alice",
|
|
188
|
+
{
|
|
189
|
+
method: "PUT",
|
|
190
|
+
body: JSON.stringify({}),
|
|
191
|
+
headers: { "Content-Type": "application/json" },
|
|
192
|
+
auth: {
|
|
193
|
+
token: enokiOidcToken,
|
|
194
|
+
address: suiAddress,
|
|
195
|
+
signer: await enokiFlow.getKeypair({ network: "testnet" }),
|
|
196
|
+
network: "testnet",
|
|
197
|
+
},
|
|
198
|
+
},
|
|
199
|
+
);
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
The SDK is only a client and shared wire contract. The API remains the security
|
|
203
|
+
boundary: it verifies Enoki membership, challenge freshness, the recovered Sui
|
|
204
|
+
address, and the exact authorized route on every protected request.
|
|
205
|
+
|
|
206
|
+
### Payment
|
|
207
|
+
|
|
208
|
+
`listing::purchase` takes a bare `Balance<Currency>`, and `purchaseRecord` sources it with
|
|
209
|
+
`tx.balance()` — which draws from the buyer's **address balance** first and falls back
|
|
210
|
+
to coin objects only if it must. When the address balance covers the price, that is a
|
|
211
|
+
single `balance::redeem_funds` and **no coin object is minted, touched, or destroyed**,
|
|
212
|
+
leaving the sale free of owned-object contention.
|
|
213
|
+
|
|
214
|
+
Never hand-pick coin objects for a payment. That road shows a buyer their $1,000 and
|
|
215
|
+
then refuses to spend a cent of it, because a coin listing cannot see money that lives
|
|
216
|
+
in the address balance.
|
|
217
|
+
|
|
218
|
+
Purchases always set `useGasCoin: false`: the gas coin may belong to a sponsor. Buyers
|
|
219
|
+
also pass the exact expected `Fixed` or `Floor` pricing variant and value, protecting
|
|
220
|
+
them from stale pricing-mode changes as well as amount changes.
|
|
221
|
+
|
|
222
|
+
### Vault fund settlement
|
|
223
|
+
|
|
224
|
+
`settleAndDistributeReleaseRevenue` invokes the fixed release plugin with the
|
|
225
|
+
framework `AccumulatorRoot` (`0xacc`); the plugin redeems the whole settled
|
|
226
|
+
snapshot and exposes no amount argument. `settleCompositionRoyaltyPool` and
|
|
227
|
+
`settleRecordingRoyaltyPool` read `balance::settled_funds_value` and pass that
|
|
228
|
+
command result directly to their exact-value plugin calls. The lower-level raw
|
|
229
|
+
Action `redeemAndDistributeReleaseRevenue` and the plugin helpers
|
|
230
|
+
`redeemAndDepositCompositionRoyaltyPool`, and
|
|
231
|
+
`redeemAndDepositRecordingRoyaltyPool` remain available when an earlier PTB
|
|
232
|
+
command already produced the exact value.
|
|
233
|
+
|
|
234
|
+
Party-wallet monetary builders are similarly composable:
|
|
235
|
+
`receivePartyWalletBalance`, `redeemPartyWalletBalance`, and
|
|
236
|
+
`settlePartyWalletBalance` return the PTB `Balance<Currency>` result. Pass that
|
|
237
|
+
result directly to another Move call, or convert it with `coin::from_balance`
|
|
238
|
+
only when an owned Coin is required. Every returned Balance must be consumed in
|
|
239
|
+
the same PTB.
|
|
240
|
+
|
|
241
|
+
## Publishing (`transactions.ts`, `share.ts`, `release-graph.ts`)
|
|
242
|
+
|
|
243
|
+
`@misofm/protocol`'s `createComposition`/`createRecording` mint a work and hand
|
|
244
|
+
back its by-value parts (the object, its admin cap, its freshly-minted share
|
|
245
|
+
`Balance`) without dispersing, sharing, or transferring anything. This package
|
|
246
|
+
supplies the opinionated finish on top:
|
|
247
|
+
|
|
248
|
+
```ts
|
|
249
|
+
import { miso } from "@misofm/platform";
|
|
250
|
+
|
|
251
|
+
const client = new SuiGrpcClient({ network: "testnet", baseUrl }).$extend(
|
|
252
|
+
miso({ deployment: verifiedDeployment }),
|
|
253
|
+
);
|
|
254
|
+
|
|
255
|
+
// Mints the composition's share supply, disperses it to shareRecipients as
|
|
256
|
+
// address balances, publishes (shares) the composition, and transfers the
|
|
257
|
+
// CompositionAdminCap to adminAddress — createComposition → finalizeComposition
|
|
258
|
+
// in one PTB.
|
|
259
|
+
const thunk = client.miso.tx.publishComposition({
|
|
260
|
+
title: "Song Title",
|
|
261
|
+
royaltyRateBps: 1000,
|
|
262
|
+
shareType: "0x...::share::Share",
|
|
263
|
+
shareCurrencyId: "0x...",
|
|
264
|
+
shareTreasuryCapId: "0x...",
|
|
265
|
+
shareRecipients: [{ address: ownerAddress, value: 10_000_000_000_000 }],
|
|
266
|
+
adminAddress: ownerAddress,
|
|
267
|
+
});
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
`client.miso.tx.publishRecording` and `publishCompositionAndRecording`
|
|
271
|
+
follow the same shape (the latter atomically, borrow-before-share, in one PTB —
|
|
272
|
+
see `@misofm/protocol`'s README for why the ordering is load-bearing).
|
|
273
|
+
The protocol, immutable Record and Record Shop packages, minato, and core
|
|
274
|
+
`ReleaseRegistry` address all come from the deployment selected by the Sui
|
|
275
|
+
client's network. Record sales have no Record Registry or Settings singleton.
|
|
276
|
+
The deprecated `misoPlatform()` constructor still accepts those values manually
|
|
277
|
+
for compatibility with existing integrations. It must also receive the exact
|
|
278
|
+
`network` and `chainIdentifier`; call `await client.misoPlatform.ready()` before
|
|
279
|
+
accessing its client-bound protocol or platform surfaces.
|
|
280
|
+
|
|
281
|
+
For custom PTBs, the bare primitives (`disperseShares`, `finalizeComposition`,
|
|
282
|
+
`finalizeRecording`) and the whole-graph orchestrator are exported standalone:
|
|
283
|
+
|
|
284
|
+
```ts
|
|
285
|
+
import { publishReleaseGraph } from "@misofm/platform";
|
|
286
|
+
|
|
287
|
+
// Every composition and recording, optional royalty pools, tracks, and
|
|
288
|
+
// the release — with the release id derived ON-CHAIN — in one atomic PTB.
|
|
289
|
+
const thunk = publishReleaseGraph({
|
|
290
|
+
compositions: [
|
|
291
|
+
{
|
|
292
|
+
shareType,
|
|
293
|
+
shareCurrencyId,
|
|
294
|
+
shareTreasuryCapId,
|
|
295
|
+
title: "Song",
|
|
296
|
+
royaltyRateBps: 1000,
|
|
297
|
+
shareRecipients,
|
|
298
|
+
adminAddress,
|
|
299
|
+
},
|
|
300
|
+
],
|
|
301
|
+
recordings: [
|
|
302
|
+
{
|
|
303
|
+
shareType,
|
|
304
|
+
shareCurrencyId,
|
|
305
|
+
shareTreasuryCapId,
|
|
306
|
+
compositionShareType,
|
|
307
|
+
parentCompositionIndex: 0,
|
|
308
|
+
shareRecipients,
|
|
309
|
+
adminAddress,
|
|
310
|
+
},
|
|
311
|
+
],
|
|
312
|
+
release: {
|
|
313
|
+
title: "Album",
|
|
314
|
+
nonce: "42",
|
|
315
|
+
adminAddress,
|
|
316
|
+
releaseRegistryId: "0x...",
|
|
317
|
+
tracks: [{ recordingIndex: 0, splitBps: 10000 }],
|
|
318
|
+
},
|
|
319
|
+
misoPackageId: "0x...",
|
|
320
|
+
minatoPackageId: "0x...",
|
|
321
|
+
});
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
### Atomic catalog publication (`publication.ts`)
|
|
325
|
+
|
|
326
|
+
`publishAtomicCatalog` owns the semantic publication transaction. Given
|
|
327
|
+
pre-initialized share currencies, it creates every new Party, Composition,
|
|
328
|
+
Recording, Track, and Release; applies all declared data extensions; composes
|
|
329
|
+
raw-cap Actions through direct custody or a scoped Vault borrow; installs only
|
|
330
|
+
the permissionless royalty/revenue crank plugins; opens the Pressing and
|
|
331
|
+
Listings; shares the new objects; and delivers only the selected direct admin
|
|
332
|
+
cap or VaultAdminCap. The
|
|
333
|
+
entire catalog stage is one PTB, so none of it can land partially.
|
|
334
|
+
|
|
335
|
+
Share allocation is explicit at the SDK boundary. Omitting
|
|
336
|
+
`shareDistribution` preserves the existing `"balance"` behavior. Setting it to
|
|
337
|
+
`"stake"` converts the minted `Balance<Share>` into one address-owned
|
|
338
|
+
`Stake<Share>` per `shareRecipients` entry. When the work also declares a
|
|
339
|
+
`royaltyPool`, the builder creates the pool unshared, registers each fresh
|
|
340
|
+
stake, shares the pool, and then transfers the registered stakes. The lower
|
|
341
|
+
level `createShareStake`, `createShareStakes`, `registerShareStake`,
|
|
342
|
+
`newCompositionRoyaltyPool`, `newRecordingRoyaltyPool`, and
|
|
343
|
+
`shareRoyaltyPool` builders expose each step separately for custom PTBs.
|
|
344
|
+
|
|
345
|
+
For a fresh Recording whose parent Composition owns a protocol royalty cut,
|
|
346
|
+
`recordings[].routedStake` redeems that exact cut into a derived
|
|
347
|
+
`RoutedStake`, registers it with the Recording's royalty pool, and shares it
|
|
348
|
+
for permissionless sweeping. The Recording and parent Composition must both
|
|
349
|
+
declare royalty pools in the same currency, and the parent must use Vault
|
|
350
|
+
custody:
|
|
351
|
+
|
|
352
|
+
```ts
|
|
353
|
+
recordings: [{
|
|
354
|
+
// ...fresh parent, share currency, custody, and royaltyPool...
|
|
355
|
+
routedStake: true,
|
|
356
|
+
}]
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
The SDK derives the exact `composition_routed_stake::create_stake` value from
|
|
360
|
+
the protocol's fixed share supply and the fresh parent's `royaltyRateBps`; it
|
|
361
|
+
does not permit zero or partial routing. Both works must use `"stake"` share
|
|
362
|
+
distribution so the Recording pool has its complete supply registered and the
|
|
363
|
+
parent destination pool is operable from the first sweep. Atomic publication
|
|
364
|
+
supports rates from 1 to 9999 BPS because it always allocates a non-zero
|
|
365
|
+
Recording creator remainder; lower-level routed-stake builders remain
|
|
366
|
+
available for the Move layer's 100% composition-cut case.
|
|
367
|
+
|
|
368
|
+
```ts
|
|
369
|
+
import {
|
|
370
|
+
assertAtomicPublicationBounds,
|
|
371
|
+
parseAtomicPublicationResult,
|
|
372
|
+
publishAtomicCatalog,
|
|
373
|
+
} from "@misofm/platform/publication";
|
|
374
|
+
|
|
375
|
+
const publication = {
|
|
376
|
+
deployment,
|
|
377
|
+
parties,
|
|
378
|
+
compositions, // includes initialized share Currency + TreasuryCap ids
|
|
379
|
+
recordings,
|
|
380
|
+
release,
|
|
381
|
+
pressing,
|
|
382
|
+
};
|
|
383
|
+
|
|
384
|
+
// Pure local assembly: fail before publishing any share package if the final
|
|
385
|
+
// PTB exceeds the SDK's command/input safety limits or has an invalid graph.
|
|
386
|
+
assertAtomicPublicationBounds(publication);
|
|
387
|
+
|
|
388
|
+
const executed = await client.miso.executeViaExecutor(
|
|
389
|
+
executor,
|
|
390
|
+
publishAtomicCatalog(publication),
|
|
391
|
+
);
|
|
392
|
+
const result = parseAtomicPublicationResult(publication, executed);
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
Fresh raw PartyAdminCap, CompositionAdminCap, RecordingAdminCap, and
|
|
396
|
+
ReleaseAdminCap values never leave the PTB when Vault custody is selected.
|
|
397
|
+
Only the Composition royalty-pool, Recording royalty-pool, and Release revenue
|
|
398
|
+
plugins are installable, while each new Vault is still owned. Party-wallet and
|
|
399
|
+
Composition routed-stake operations remain raw Actions. Atomic publication
|
|
400
|
+
consumes the returned routed stake by registering and sharing it; lower-level
|
|
401
|
+
callers retain explicit control over those lifecycle steps. Plugin witness
|
|
402
|
+
construction remains inside the SDK bindings.
|
|
403
|
+
|
|
404
|
+
Share packages necessarily precede this stage: publish at most five per PTB,
|
|
405
|
+
then initialize their currencies, then submit the atomic catalog PTB. The two
|
|
406
|
+
share helpers below accept a parallel-compatible executor, allowing package
|
|
407
|
+
batches to queue concurrently while a hardware signer serializes approvals.
|
|
408
|
+
|
|
409
|
+
### Share Currency Provisioning (`share.ts`)
|
|
410
|
+
|
|
411
|
+
Every composition and recording is backed by its own fixed-supply share
|
|
412
|
+
currency: an independently published `share` package (bytecode template
|
|
413
|
+
embedded as `SHARE_TEMPLATE`, initializer patched via `patchInitializer`).
|
|
414
|
+
Publish and initialize are necessarily two transactions:
|
|
415
|
+
|
|
416
|
+
```ts
|
|
417
|
+
// Sequential (one currency, two txs):
|
|
418
|
+
const currency = await client.miso.createShareCurrency(signer, {
|
|
419
|
+
name: "Song Shares",
|
|
420
|
+
description: "…",
|
|
421
|
+
});
|
|
422
|
+
// → { packageId, currencyId, shareType, treasuryCapId, gasUsed }
|
|
423
|
+
|
|
424
|
+
// Batched (many currencies, via a ParallelTransactionExecutor):
|
|
425
|
+
import { publishShareCurrencies, initializeShareCurrencies } from "@misofm/platform";
|
|
426
|
+
const { packageIds } = await publishShareCurrencies(
|
|
427
|
+
executor,
|
|
428
|
+
initializerAddress,
|
|
429
|
+
10,
|
|
430
|
+
);
|
|
431
|
+
const { currencies } = await initializeShareCurrencies(
|
|
432
|
+
executor,
|
|
433
|
+
signerAddress,
|
|
434
|
+
packageIds,
|
|
435
|
+
(pkg) => ({
|
|
436
|
+
name: "…",
|
|
437
|
+
description: "…",
|
|
438
|
+
}),
|
|
439
|
+
);
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
`executeViaExecutor(executor, ...thunks)` (`execute.ts`) submits a
|
|
443
|
+
non-idempotent PTB through a `ParallelTransactionExecutor` exactly once (no
|
|
444
|
+
auto-retry) — it's what the batched provisioning above builds on, layered over
|
|
445
|
+
`@misofm/protocol`'s transport-agnostic `buildTx`/`toExecResult`.
|
|
446
|
+
|
|
447
|
+
## Extensions
|
|
448
|
+
|
|
449
|
+
An extension attaches data to a protocol work through that work's cap-gated
|
|
450
|
+
`uid_mut` hook. The work stays a protocol object; the opinion hanging off it is
|
|
451
|
+
ours.
|
|
452
|
+
|
|
453
|
+
### Credits (`credits.ts`)
|
|
454
|
+
|
|
455
|
+
Contributor credits pair a party with a display name and one or more
|
|
456
|
+
domain-specific roles, attached to a work as a dynamic field and gated by the
|
|
457
|
+
work's admin cap. Three role vocabularies:
|
|
458
|
+
|
|
459
|
+
- **Composition** (writing, 1–5 roles, no level): `Adapter`, `Arranger`, `Composer`, `Lyricist`, `Songwriter`, `Translator`, or `{ type: "Custom", name }`.
|
|
460
|
+
- **Recording** (production/performance, 1–10 roles): 28 leveled roles (`Producer`, `Vocalist`, `Engineer`, …) each with an optional seniority `level` (`Lead`, `Featured`, `Executive`, …), plus `{ type: "Instrumentalist", instrument, level? }`, `{ type: "Custom", name, level? }`, and the unleveled `ArtistsAndRepertoire` / `Copyist`.
|
|
461
|
+
- **Release** (top-line billing, exactly one role): `"Primary"` or `"Featured"`.
|
|
462
|
+
|
|
463
|
+
Writers validate client-side, mirroring the Move aborts: display name
|
|
464
|
+
non-empty and ≤200 UTF-8 bytes; role counts within the caps above; no
|
|
465
|
+
duplicate roles.
|
|
466
|
+
|
|
467
|
+
```ts
|
|
468
|
+
import {
|
|
469
|
+
attachCompositionCredit,
|
|
470
|
+
attachRecordingCredit,
|
|
471
|
+
addReleaseCredit,
|
|
472
|
+
addRecordingPrimaryArtist,
|
|
473
|
+
addRecordingFeaturedArtist,
|
|
474
|
+
getCompositionCredits,
|
|
475
|
+
getRecordingCredits,
|
|
476
|
+
getReleaseCredits,
|
|
477
|
+
} from "@misofm/platform";
|
|
478
|
+
|
|
479
|
+
const thunk = attachRecordingCredit({
|
|
480
|
+
recordingId: "0x...",
|
|
481
|
+
recordingAdminCapId: "0x...",
|
|
482
|
+
partyId: "0x...",
|
|
483
|
+
displayName: "Jane Doe",
|
|
484
|
+
roles: [
|
|
485
|
+
{ type: "Vocalist", level: "Lead" },
|
|
486
|
+
{ type: "Instrumentalist", instrument: "Guitar" },
|
|
487
|
+
],
|
|
488
|
+
recordingShareType: "0x...::share::Share",
|
|
489
|
+
compositionShareType: "0x...::share::Share",
|
|
490
|
+
recordingCreditsPackageId: "0x...",
|
|
491
|
+
misoCreditPackageId: "0x...",
|
|
492
|
+
});
|
|
493
|
+
|
|
494
|
+
// Designate an already-credited party (same params minus displayName/roles/misoCreditPackageId):
|
|
495
|
+
addRecordingPrimaryArtist({
|
|
496
|
+
recordingId,
|
|
497
|
+
recordingAdminCapId,
|
|
498
|
+
partyId,
|
|
499
|
+
recordingShareType,
|
|
500
|
+
compositionShareType,
|
|
501
|
+
recordingCreditsPackageId,
|
|
502
|
+
});
|
|
503
|
+
|
|
504
|
+
// Reads return null when no credits field is attached.
|
|
505
|
+
const credits = await getCompositionCredits(
|
|
506
|
+
client,
|
|
507
|
+
compositionId,
|
|
508
|
+
compositionCreditsPackageId,
|
|
509
|
+
);
|
|
510
|
+
// CreditView[]: { partyId, displayName, roles: string[] } — e.g. "Producer (Lead)", "Instrumentalist: Guitar"
|
|
511
|
+
const rc = await getRecordingCredits(
|
|
512
|
+
client,
|
|
513
|
+
recordingId,
|
|
514
|
+
recordingCreditsPackageId,
|
|
515
|
+
);
|
|
516
|
+
// { credits: CreditView[], primaryArtistIds: string[], featuredArtistIds: string[] }
|
|
517
|
+
```
|
|
518
|
+
|
|
519
|
+
`attachCompositionCredit` takes `compositionId`/`compositionAdminCapId`/`compositionShareType`/`compositionCreditsPackageId`;
|
|
520
|
+
`addReleaseCredit` takes `releaseId`/`releaseAdminCapId` and a single `role`.
|
|
521
|
+
|
|
522
|
+
A recording is `Recording<RecordingShare, CompositionShare>` — the recording's
|
|
523
|
+
OWN share type comes first, its parent composition's second. The recording
|
|
524
|
+
writers take both as separate named params for that reason; passing them in the
|
|
525
|
+
wrong order still typechecks (both are `string`) and resolves to the wrong
|
|
526
|
+
on-chain type.
|
|
527
|
+
|
|
528
|
+
### Cover art (`cover.ts`)
|
|
529
|
+
|
|
530
|
+
A release's cover is a Walrus blob referenced on-chain via `ori::WalrusData`,
|
|
531
|
+
attached under the `release_cover_art` extension:
|
|
532
|
+
|
|
533
|
+
```ts
|
|
534
|
+
import { setReleaseCover, getReleaseCover } from "@misofm/platform";
|
|
535
|
+
|
|
536
|
+
const thunk = setReleaseCover({
|
|
537
|
+
releaseId: "0x...",
|
|
538
|
+
releaseAdminCapId: "0x...",
|
|
539
|
+
stillBlobId: "987654321", // Walrus blob id as u256 (decimal string or bigint)
|
|
540
|
+
animatedBlobId: null, // optional animated cover
|
|
541
|
+
coverArtPackageId: "0x...",
|
|
542
|
+
releaseCoverArtPackageId: "0x...",
|
|
543
|
+
oriPackageId: "0x...",
|
|
544
|
+
});
|
|
545
|
+
|
|
546
|
+
const cover = await getReleaseCover(
|
|
547
|
+
client,
|
|
548
|
+
releaseId,
|
|
549
|
+
releaseCoverArtPackageId,
|
|
550
|
+
);
|
|
551
|
+
// ReleaseCoverView | null: { still, animated } as normalized Walrus refs
|
|
552
|
+
// ({ kind: "blob", blobId } | { kind: "quiltPatch", quiltId, version, startIndex, endIndex })
|
|
553
|
+
```
|
|
554
|
+
|
|
555
|
+
### Vault operations (`vault.ts`)
|
|
556
|
+
|
|
557
|
+
`vault.ts` contains composable PTB builders for custody and plugin flows:
|
|
558
|
+
`invokeWithAdminCap` safely sequences `borrow_as_admin → Move call → put_back`, and
|
|
559
|
+
`custodyNewAdminCap` shares the Vault while transferring only its owner-held
|
|
560
|
+
`VaultAdminCap` through the Vault module. `deriveVaultId` and
|
|
561
|
+
`deriveVaultAdminCapId` discover both canonical object IDs without an RPC lookup.
|
|
562
|
+
`withdrawVaultCapability` and `restoreVaultCapability` operate on the permanent
|
|
563
|
+
Vault shell; withdrawal requires every plugin to have been removed. Plugin
|
|
564
|
+
installers construct their witnesses inside their Move package; callers supply no
|
|
565
|
+
witness.
|
|
566
|
+
|
|
567
|
+
It also builds Composition/Recording royalty-pool initialization and cranks,
|
|
568
|
+
fixed Release settlement plus raw-admin amount composition, Party wallet
|
|
569
|
+
Actions, and the full Composition routed-stake Action lifecycle. Receive flows
|
|
570
|
+
take exact object references and construct the required
|
|
571
|
+
`vector<Receiving<Coin<Currency>>>` in the PTB.
|
|
572
|
+
|
|
573
|
+
The bundled Testnet deployment sets `operations.status` to `"available"` with
|
|
574
|
+
one canonical Vault package and registry, five distinct raw Action packages,
|
|
575
|
+
and three distinct suffixed plugin packages. Zero-config Testnet clients expose
|
|
576
|
+
that complete verified surface after `await client.miso.ready()`. Custom
|
|
577
|
+
deployments remain fail-closed unless they provide the same atomic identity set.
|
|
578
|
+
Structural validation checks canonical, pairwise-distinct IDs; callers remain
|
|
579
|
+
responsible for the provenance and compatibility of arbitrary custom IDs. The
|
|
580
|
+
bundled map is recursively frozen from one verified immutable admin export.
|
|
581
|
+
|
|
582
|
+
### Migrating from 0.16
|
|
583
|
+
|
|
584
|
+
Version 0.17 is a breaking deployment-safety release. Replace flat Vault,
|
|
585
|
+
Action, and plugin package fields with the discriminated `operations` union.
|
|
586
|
+
After client
|
|
587
|
+
registration, call `await client.miso.ready()` before using synchronous
|
|
588
|
+
`client.miso.tx`, `ids`, `call`, `vault`, or `party` surfaces. Platform reads
|
|
589
|
+
and SDK execution helpers await the same memoized readiness check themselves.
|
|
590
|
+
Standalone builders remain pure for offline composition, so their caller is
|
|
591
|
+
responsible for completing this exact-chain validation lifecycle before
|
|
592
|
+
execution.
|
|
593
|
+
|
|
594
|
+
The Release revenue plugin crank is now fixed: call
|
|
595
|
+
`redeemAllAndDistribute(vault, release, accumulatorRoot)` with no amount. The
|
|
596
|
+
explicit-amount `redeemAndDistribute` Action remains available only for raw
|
|
597
|
+
admin-cap composition.
|
|
598
|
+
|
|
599
|
+
### Extension types
|
|
600
|
+
|
|
601
|
+
```ts
|
|
602
|
+
import type {
|
|
603
|
+
CreditView,
|
|
604
|
+
RecordingCreditsView,
|
|
605
|
+
CompositionRole,
|
|
606
|
+
RecordingRole,
|
|
607
|
+
RecordingRoleLevel,
|
|
608
|
+
RecordingLeveledRoleType,
|
|
609
|
+
ReleaseRole,
|
|
610
|
+
ReleaseCoverView,
|
|
611
|
+
CoverImageRef,
|
|
612
|
+
} from "@misofm/platform";
|
|
613
|
+
```
|
|
614
|
+
|
|
615
|
+
`RecordingLeveledRoleType` is the union of the 28 recording role base names that
|
|
616
|
+
carry an optional `RecordingRoleLevel` (`Producer`, `Vocalist`, `Engineer`,
|
|
617
|
+
`Conductor`, …) — the leveled arm of `RecordingRole`. The other arms
|
|
618
|
+
(`Instrumentalist`, `Custom`, and the unleveled `ArtistsAndRepertoire` /
|
|
619
|
+
`Copyist`) are spelled out separately in `RecordingRole`.
|
|
620
|
+
|
|
621
|
+
## Layout
|
|
622
|
+
|
|
623
|
+
```
|
|
624
|
+
src/
|
|
625
|
+
deployments.ts fail-closed deployment schema and future address injection point
|
|
626
|
+
client.ts the full client.miso facade; protocol and Party live at client.miso.protocol / .party
|
|
627
|
+
pressing.ts facade: builders, readers, and the id derivations
|
|
628
|
+
queries.ts shared read plumbing (isNotFound, re-exported from @misofm/protocol)
|
|
629
|
+
transactions.ts the TxThunk contract + the opinionated publish flow (disperse/finalize/publish*)
|
|
630
|
+
release-graph.ts whole release graph in one PTB (publishReleaseGraph)
|
|
631
|
+
share.ts share-currency provisioning (createShareCurrency, batched variants)
|
|
632
|
+
share-template.ts embedded `share` package bytecode
|
|
633
|
+
credits.ts EXTENSION: contributor credits + the three role vocabularies
|
|
634
|
+
cover.ts EXTENSION: release cover art (Walrus blob via ori)
|
|
635
|
+
read/ high-level catalog, artist, wallet, and receipt views
|
|
636
|
+
vault.ts Vault authority, plugin, event, and receiving-coin builders
|
|
637
|
+
execute.ts executeViaExecutor, layered on @misofm/protocol's buildTx/toExecResult
|
|
638
|
+
internal.ts private helpers (the 0x1::option moveCall targets) — NOT exported
|
|
639
|
+
contracts.ts barrel re-exporting the generated bindings as `contracts`
|
|
640
|
+
contracts/ GENERATED — do not edit by hand
|
|
641
|
+
```
|
|
642
|
+
|
|
643
|
+
## Codegen
|
|
644
|
+
|
|
645
|
+
Bindings are generated from the live Move source, so the typed layer cannot drift from
|
|
646
|
+
the on-chain ABI:
|
|
647
|
+
|
|
648
|
+
```sh
|
|
649
|
+
bun run codegen # reads sui-codegen.config.ts → src/contracts/
|
|
650
|
+
```
|
|
651
|
+
|
|
652
|
+
`sui-codegen.config.ts` lists `miso_record`, `miso_record_shop`, data
|
|
653
|
+
extensions, generic `royalty_pool`/`routed_stake`, and the `vault` plus all
|
|
654
|
+
vault-plugin packages. The protocol CORE (`miso` —
|
|
655
|
+
composition/recording/release/track) generates into
|
|
656
|
+
`@misofm/protocol` instead, which this package depends on for those bindings —
|
|
657
|
+
adding the core here to save an import is how the split this package exists to
|
|
658
|
+
enforce gets undone.
|
|
659
|
+
|
|
660
|
+
Paths resolve against sibling checkouts, so regenerating requires
|
|
661
|
+
`~/Documents/GitHub/misofm/{sdk, record, record-shop, vault, vault-plugins}` and
|
|
662
|
+
`~/Documents/GitHub/misonetwork/{party-actions, protocol, protocol-actions,
|
|
663
|
+
protocol-extensions, royalty-pool, routed-stake, share, cover-art, genre}`.
|
|
664
|
+
|
|
665
|
+
For an isolated checkout, copy those source trees and set
|
|
666
|
+
`MISO_SDK_CODEGEN_SOURCE_ROOT` to their common parent. The codegen config reads
|
|
667
|
+
only from that copy, avoiding writes to a developer's live source tree.
|
|
668
|
+
|
|
669
|
+
## Dependency on `@misofm/protocol`
|
|
670
|
+
|
|
671
|
+
`@misofm/protocol` is a regular runtime dependency of this package (a workspace
|
|
672
|
+
dependency in this monorepo, resolved to a published version range on publish),
|
|
673
|
+
not a peer. This package imports its primitives, deployment configuration,
|
|
674
|
+
protocol client, and Party client directly, then exposes them at
|
|
675
|
+
`client.miso.protocol` and `client.miso.party` only after
|
|
676
|
+
`await client.miso.ready()` validates the exact ledger. Direct protocol reads,
|
|
677
|
+
generated calls, package bindings, and nested Party APIs cannot be obtained
|
|
678
|
+
before that gate.
|
|
679
|
+
|
|
680
|
+
`@mysten/sui` itself stays a peer dependency here, so an application resolves
|
|
681
|
+
exactly one Sui SDK across both packages regardless of which protocol version
|
|
682
|
+
`@misofm/platform` pins.
|
|
683
|
+
|
|
684
|
+
```bash
|
|
685
|
+
bun add @misofm/platform
|
|
686
|
+
```
|
|
687
|
+
|
|
688
|
+
`@misofm/protocol` resolves automatically as a transitive dependency; there is
|
|
689
|
+
no separate install step and no peer version for consumers to reconcile.
|