TypeScript bindings, Core API queries, event decoders, and composable PTB builders for the current Miso Move sources on Sui:
- core
miso, including its canonicalrelease::ReleaseRegistry; - all first-party
protocol-extensionspackages; - generic
royalty_poolandrouted_stakeprimitives; - Party core plus its profile, media, collection, and platform-link extensions.
The SDK does not publish packages, select gas, sign transactions, or request
faucet funds. Publishing is an operational step performed with admin-cli;
this SDK is updated only from the verified immutable admin-cli publish record.
The platform SDK consumes this package as a peer. Platform consumers therefore own one verified network SDK instance rather than accepting nested, stale protocol or Party copies through the platform package.
bun add @misonetwork/sdk @mysten/suiThe package is ESM-only and uses @mysten/sui v2 APIs.
Testnet package IDs are bundled in MISO_DEPLOYMENTS.testnet and selected by
miso() from the Sui client's network. The map is the SDK's authoritative
runtime deployment record and is updated only from a verified immutable
admin-cli publish record. Networks without a bundled manifest fail closed;
custom networks can pass an explicit complete deployment.
A manifest is complete by design:
import type { MisoDeployment } from "@misonetwork/sdk";
const deployment: MisoDeployment = {
miso: "0x…",
compositionCredits: "0x…",
recordingAdvisory: "0x…",
recordingCredits: "0x…",
recordingLanguage: "0x…",
recordingMasterReference: "0x…",
recordingPreview: "0x…",
releaseCoverArt: "0x…",
releaseCredits: "0x…",
releaseDescription: "0x…",
releaseDspLink: "0x…",
releaseGenre: "0x…",
releaseKind: "0x…",
royaltyPool: "0x…",
routedStake: "0x…",
misoParty: "0x…",
partyCta: "0x…",
partyGenre: "0x…",
partyMedia: "0x…",
partyMusic: "0x…",
partyPlatformLink: "0x…",
partyProLink: "0x…",
partyProfile: "0x…",
partyRoles: "0x…",
partySocial: "0x…",
partyTags: "0x…",
countryCode: "0x…",
languageCode: "0x…",
genre: "0x…",
};Do not substitute an address from an older source release. assertMisoDeployment
rejects partial manifests and mixed publish sets.
Use a complete manifest to make every generated package call address-safe. The
generated wrappers accept typed Move arguments and append commands to a
caller-owned Transaction; they do not execute it.
import { SuiGrpcClient } from "@mysten/sui/grpc";
import { Transaction } from "@mysten/sui/transactions";
import { miso, type MisoDeployment } from "@misonetwork/sdk";
declare const deployment: MisoDeployment;
declare const recordingId: string;
declare const recordingAdminCapId: string;
declare const recordingShareType: string;
declare const compositionShareType: string;
const client = new SuiGrpcClient({
network: "testnet",
baseUrl: "https://fullnode.testnet.sui.io:443",
}).$extend(miso({ deployment }));
const tx = new Transaction();
tx.add(
client.miso.packages.call.extensions.recordingAdvisory.unsetRating({
typeArguments: [recordingShareType, compositionShareType],
arguments: [tx.object(recordingId), tx.object(recordingAdminCapId)],
}),
);client.miso.call remains the core-only compatibility surface. Use
client.miso.packages.call for core, extension, utility, and primitive calls
bound to the full manifest. The raw codegen surface mirrors public Move
functions; the package-bound call surface excludes return-by-reference views,
because a PTB command result cannot carry a reference. Read those values through
object or dynamic-field queries instead.
The contracts namespace exposes the same unbound generated modules and BCS
codecs for advanced callers. Its @local-pkg/* names are source labels, never
deployment addresses.
Party is part of the same client and deployment boundary. It no longer needs a standalone SDK extension:
const party = await client.miso.party.getPartyById(partyId);
const profile = await client.miso.party.getProfile(partyId);
tx.add(client.miso.party.tx.setName({
partyId,
capId: partyAdminCapId,
name: "New name",
}));The @misonetwork/sdk/party subpath exports Party result types, standalone
query functions, composable transaction thunks, and extension helpers.
The hand-maintained builders cover the values that must remain inside the same PTB and make their ownership explicit:
| Builder | Result / rule |
|---|---|
createComposition, createRecording |
Return object, admin cap, and share balance by value. |
createTrack |
Returns a Track for later release assembly. |
createRelease |
Calls core release::new with the shared registry as its first object argument; returns release and cap to publish. |
publishComposition, publishRecording, publishRelease |
Consume and share an initialized core object. |
createRoyaltyStake, destroyRoyaltyStake |
Convert a Balance<Share> to/from a stake; each non-drop result must be registered, destroyed, or transferred in that PTB. |
registerRoyaltyStake, claimRoyaltyRewards |
Operate against a shared royalty pool; claimed balance must be consumed. |
sweepRoutedStake |
Permissionlessly routes accrued rewards into the parent pool. |
The generated royalty-pool call surface also exposes
client.miso.packages.call.primitives.royaltyPool.pool.sweepAndDeposit. It takes
the shared pool and AccumulatorRoot, determines the commit-settled amount on
chain, and appends a permissionless sweep without a caller-supplied u64.
Some generic functions intentionally have no standalone PTB helper: creating a
royalty pool or a routed stake requires a parent module's &mut UID. Those
operations belong in a cap-gated parent/authority Move module. Vault custody
and authority plugins are intentionally owned by @misofm/sdk; their entry
functions still compose as normal commands in a multi-command PTB.
For example, create and publish a release entirely in one transaction:
const release = createRelease(tx, {
releaseRegistryId,
title: "Release title",
tracks: [track],
nonce: 42n,
misoPackageId: deployment.miso,
});
publishRelease(tx, {
release: release.release,
adminCap: release.adminCap,
misoPackageId: deployment.miso,
});Core reads use the transport-neutral ClientWithCoreApi and BCS object content:
const release = await client.miso.getReleaseById(releaseId);
const pool = await getRoyaltyPoolById(client, poolId);
const routedStake = await getRoutedStakeById(client, routedStakeId);getExtensionField reads optional fieldless-key extension data from a core
object's UID. Supply the fresh extension package ID, module name, and generated
value codec; an absent field returns null while RPC failures still throw.
release_dsp_link is intentionally different: use getReleaseDspLink and
getTrackDspLinks, which query ReleaseLinkKey(platform) and
TrackLinksKey(platform) rather than ExtensionKey.
eventParsers decodes the raw BCS payloads for the core registry, every current
extension, royalty_pool, and routed_stake event. The legacy
camel-case helpers remain available as
parseCompositionPublishedEvent, parseRecordingPublishedEvent,
parseCompositionSharesGrantedEvent, parseReleasePublishedEvent, and
parseReleaseRegistryCreatedEvent.
The source checkout layout is expected to be:
misonetwork/
sdk/
protocol/
protocol-extensions/
royalty-pool/
routed-stake/
party/
party-extensions/
Run:
bun run codegen
bun run codegen:check
bun run typecheck
bun test
bun run buildbun run codegen creates each Move summary in a temporary directory, then
updates only src/contracts/; it does not write package_summaries/ into any
sibling source worktree. When testing an isolated SDK copy, set
MISO_SDK_CODEGEN_SOURCE_ROOT to the SDK checkout whose sibling Move sources
should be read.
miso({ misoPackageId }) and MisoProtocolDeployment remain available for a
core-only caller that supplies its own verified package address. The deprecated
MISO_PROTOCOL_DEPLOYMENTS name aliases MISO_DEPLOYMENTS.