npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@misofm/partyos

v0.8.0

Published

A sui-effect extension for the PartyOS object model (Party identity, admin caps, and group membership) on Sui.

Readme

@misofm/partyos

A sui-effect extension for the PartyOS object model on Sui: the Party object, its PartyAdminCap, and consent-based group membership.

@misofm/partyos is the object model. Everything Miso offers on top of it is platform.

A Party's profile, media, roles, tags, genres, CTAs, platform links, and wallet are extensions someone chose to offer, so they ship from @misofm/platform, which depends on this package. Which Move package generates into which SDK is decided by sui-codegen.config.ts in the misofm/sdks repo.

Install

bun add @misofm/partyos @unconfirmed/sui-effect effect @mysten/sui @mysten/bcs

Peer dependencies: @unconfirmed/sui-effect@>=0.3.0 <0.4.0, effect@>=4.0.3 <4.1, @mysten/sui@^2.29.0, @mysten/bcs@^2.1.1.

Use

Promise consumers: client.$extend

partyos() registers client.partyos, built once from the client's own transport (one connection, one chain-identifier check shared with everything else on the client). Every rejection is the same tagged error instance an Effect caller would have caught, so a Promise consumer can still switch on _tag:

import { SuiGrpcClient } from "@mysten/sui/grpc";
import { Transaction } from "@mysten/sui/transactions";
import { partyos, PartyNotFound } from "@misofm/partyos";
import { ObjectId } from "@unconfirmed/sui-effect";

const client = new SuiGrpcClient({ network: "testnet", baseUrl }).$extend(partyos());

try {
  const party = await client.partyos.getPartyById(ObjectId.make("0x..."));
  const groups = await client.partyos.getMemberships(party.id);
} catch (error) {
  if (error instanceof PartyNotFound) {
    // error.partyId
  }
  throw error;
}

// Recipe fragments are synchronous even on the Promise face (`warm` builds
// the runtime inside `register`, so `tx` is real immediately).
const tx = new Transaction();
client.partyos.tx.createIndividualParty({ name: "Ada", recipient: "0x..." })(tx);

await client.partyos.dispose();

Effect consumers: the service directly

import { Effect, Layer } from "effect";
import { Sui, SuiCore } from "@unconfirmed/sui-effect";
import { Partyos } from "@misofm/partyos";

const program = Effect.gen(function* () {
  const partyos = yield* Partyos;
  const party = yield* partyos.getPartyById(partyId);
  const groups = yield* partyos.getMemberships(party.id);
  return { party, groups };
}).pipe(
  Effect.catchTag("partyos/PartyNotFound", (error) => Effect.succeed({ party: null, groups: [], missing: error })),
);

await Effect.runPromise(
  program.pipe(
    Effect.provide(Partyos.layer()), // or `.layerConfig` / `.layerTest()`
    Effect.provide(Sui.layerNoDeps),
    Effect.provide(SuiCore.layerFromClient(client)),
  ),
);

Every member's requirement channel is empty (R = never once you have a Partyos): the layer captures Sui once and provides it to every member internally.

PTB fragments

partyos.tx.* (or the free functions in ./transactions, each taking partyPackageId explicitly) are Recipes — (tx: Transaction) => void — so a consumer composes PartyOS's commands with other extensions' fragments into one transaction and submits once:

import { Transaction } from "@mysten/sui/transactions";

const tx = new Transaction();
client.partyos.tx.setName({ partyId, capId, name: "New name" })(tx);
someOtherExtension.claim(...)(tx);

Free functions

derivePartyAdminCapId and partyType (in ./queries) are pure and synchronous — no Sui required — and stay exported for callers that only need them:

import { derivePartyAdminCapId } from "@misofm/partyos/queries";

const capId = derivePartyAdminCapId(partyId, packageId);

Event decoding

Use the pure decoders from @misofm/partyos/events after routing an event to its known on-chain type:

import { partyEventParsers } from "@misofm/partyos/events";

const rawEventBcs: Uint8Array = getRawEventBytes();
const event = partyEventParsers.core.partyCreated(rawEventBcs);
// event.kind is 0 (individual) or 1 (group)
// event.created_at_ms and event.created_epoch are decimal strings

partyEventParsers targets the v1 PartyOS event ABI and preserves generated snake_case fields. partyCreated is emitted when share makes the newly created party public, so its snapshot contains the final state at the atomic share transaction's execution epoch, along with the transaction sender as creator. Its canonical events are partyCreated, partyNameSet, partyGroupInviteCreated, partyGroupMembershipAccepted, partyGroupInviteDeclined, partyGroupInviteRevoked, partyGroupMembershipLeft, and partyGroupMembershipRemoved. u64 values are decimal strings, and removed_since_epoch is string | null, preserving the difference between an absent value and epoch "0". The registry does not discover an event type or verify its deployment; callers choose the matching codec after routing. Generated codecs, including the event codecs, remain available from contracts.party.

Errors

| Member | Fails with | |---|---| | getPartyById | PartyNotFound (missing or deleted), DecodeError (not a Party of this deployment), TransportError | | getPartiesByIds | TransportError (per-item failures — PartyNotFound, DecodeError, ObjectUnavailable — come back as a Result per distinct id) | | getMemberships / getPendingInvites / getPendingMemberships | DecodeError, TransportError | | isMember | TransportError | | Partyos.layer / layerConfig | PartyosDeploymentError (an explicit manifest did not validate, or this release bundles no deployment for the client's network), ConfigError (layerConfig only) |

Every error is a Schema.TaggedError declaring outcome: "applied" | "not_applied" | "unknown" (sui-effect's SuiError.outcome and Script.exitCode read it). Recover with Effect.catchTag("partyos/PartyNotFound", ...) (the tag is prefixed with the package name, per docs/extensions.md §2) — never an isNotFound(error) predicate. ./errors also exports PartyReadError and PartyBatchItemError, the two union aliases above.

Deployment manifest

PARTYOS_DEPLOYMENTS bundles the verified testnet deployment: a single key, partyos. Pass partyos({ deployment, chainId }) for another network — chainId is required outside mainnet/testnet because partyos() registers warm (see "Promise consumers" above): without it, client.$extend(partyos({ deployment })) throws a plain Error (from sui-effect's warm registration) synchronously, from inside $extend itself, rather than rejecting the first call. A manifest with any other shape is rejected before a Move target is constructed (assertPartyDeployment/normalizePartyDeployment throw synchronously; validatePartyDeployment is the Effect-returning counterpart, now failing with PartyosDeploymentError, for callers composing a config-loading pipeline out of Effects). Partyos.layerConfig reads PARTYOS_PACKAGE_ID from the environment; unset, it falls back to the bundled manifest for the client's network.

Move upgrades. PartyDeployment carries an optional typeOrigin, the package the party module's types were first published in — what appears inside pkg::party::Party, pkg::party::MembershipKey, and every other type name this package compares against. It defaults to partyos (the package tx targets for moveCalls) and that default is correct until partyos is upgraded: an upgrade gives the package a new id for calls and leaves every type name pointing at the one it was first published under. Set typeOrigin explicitly once that happens, so getPartyById, the membership reads and every dynamic-field tag comparison keep checking the type that actually exists on chain, instead of failing every read with DecodeError the moment partyos no longer matches the id baked into the original publish.

Testing

@misofm/partyos/testing ships PARTYOS_TEST_DEPLOYMENT, fakeParty(...) (a Party object with real BCS content), and fakeMembershipField(...) (a MembershipKey / PendingInviteKey / PendingMembershipKey dynamic-field entry) for building a FakeScript against @unconfirmed/sui-effect/testing's harness — layerExtensionTest(Partyos.layerTest(), script) — with no network. See tests/Partyos.test.ts in this repo.

Migrating from PartyosClient

PartyosClient, PartyProtocolClient and bindModulePackage are removed — they held either a rebuilt Sui.layerNoDeps per call or a Layer.orDieed NetworkMismatch, so a compatibility shim would have been dishonest about its own failure modes as well as pointless: platform's own call sites are adapted in its conversion (misofm/sdks#35), not by a shim here. Only two source-compatible aliases remain, both @deprecated: TxThunk (Recipe, in ./transactions) and PartyNotFoundError (PartyNotFound, in ./errors) — the latter's runtime _tag is the new "partyos/PartyNotFound", not the string "PartyNotFoundError" a predecessor caller may have matched on.

Subpaths

@misofm/partyos (everything), /client (Partyos, partyos), /deployments, /errors, /events, /queries, /testing, /transactions, /types, /contracts (curated bindings), /contracts/* (raw generated modules).