From product-sdk
Use when publishing or subscribing to ephemeral messages on the Polkadot Statement Store. Covers StatementStoreClient lifecycle, two connection modes (host and local), topic/channel creation, ChannelStore last-write-wins semantics, data size limits, and StatementTransport BYOD.
How this skill is triggered — by the user, by Claude, or both
Slash command
/product-sdk:product-sdk-statement-storeThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
The Statement Store is a pub/sub messaging system built on top of the Polkadot Bulletin Chain. It lets peers publish small, signed, ephemeral statements tagged with topics and optional channels.
The Statement Store is a pub/sub messaging system built on top of the Polkadot Bulletin Chain. It lets peers publish small, signed, ephemeral statements tagged with topics and optional channels.
Package: @parity/product-sdk-statement-store
DATA SIZE LIMIT: MAX_STATEMENT_SIZE = 512 bytes. The JSON-serialized payload must not exceed 512 bytes after UTF-8 encoding.
TWO CONNECTION MODES. Use
{ mode: "host", accountId }inside containers or{ mode: "local", signer }outside containers.
import { StatementStoreClient } from "@parity/product-sdk-statement-store";
const client = new StatementStoreClient({ appName: "my-app" });
await client.connect({ mode: "host", accountId: ["5Grw...", 42] });
const sub = client.subscribe<{ type: string }>(statement => {
console.log(statement.data.type);
});
await client.publish({ type: "presence" }, { channel: "room-42" });
sub.unsubscribe();
client.destroy();
import { StatementStoreClient } from "@parity/product-sdk-statement-store";
const client = new StatementStoreClient({
appName: "my-app",
endpoint: "wss://paseo-bulletin-next-rpc.polkadot.io",
});
await client.connect({
mode: "local",
signer: { publicKey: myPublicKey, sign: (msg) => sr25519Sign(msg, mySecretKey) },
});
const sub = client.subscribe<{ type: string }>(statement => {
console.log(statement.data.type);
});
await client.publish({ type: "presence" });
sub.unsubscribe();
client.destroy();
const client = new StatementStoreClient({
appName: "my-app", // required: hashed as topic1
endpoint: "wss://...", // optional: fallback WebSocket URL
pollIntervalMs: 10_000, // optional: polling interval
defaultTtlSeconds: 30, // optional: statement TTL
});
// Host mode
await client.connect({ mode: "host", accountId: ["5Grw...", 42] });
// Local mode
await client.connect({ mode: "local", signer: { publicKey, sign } });
const accepted = await client.publish<MyData>(data, {
channel: "my-channel",
topic2: "room-id",
});
const sub = client.subscribe<MyData>(callback, { topic2: "room-id" });
sub.unsubscribe();
client.destroy();
import { ChannelStore } from "@parity/product-sdk-statement-store";
const channels = new ChannelStore<Presence>(client, { topic2: "doc-123" });
await channels.write("presence/peer-abc", { type: "presence", timestamp: Date.now() });
const value = channels.read("presence/peer-abc");
const all = channels.readAll();
const sub = channels.onChange((channelName, value, previous) => {
console.log(`${channelName} updated`);
});
channels.destroy();
import { createTopic, createChannel, topicToHex } from "@parity/product-sdk-statement-store";
const topic = createTopic("my-room");
const channel = createChannel("presence/peer-abc");
const hex = topicToHex(topic);
import {
StatementStoreError,
StatementConnectionError,
StatementDataTooLargeError,
} from "@parity/product-sdk-statement-store";
PolkadotSigner instead of StatementSignerWithKey - Different interfacedestroy() - Keeps connections openconnect() - Must connect before publish/subscribeCreates, edits, and optimizes skills for Claude Code, including drafting, evaluating with test prompts, iterating on performance, and improving skill descriptions for better triggering accuracy.
npx claudepluginhub paritytech/product-sdk --plugin product-sdk