| name | product-sdk-statement-store |
| description | 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.
|
Product SDK Statement Store
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.
Quick Start: Host Mode (Inside Container)
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();
Quick Start: Local Mode (Outside Container)
import { StatementStoreClient } from "@parity/product-sdk-statement-store";
const client = new StatementStoreClient({
appName: "my-app",
});
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();
StatementStoreClient Lifecycle
Create
const client = new StatementStoreClient({
appName: "my-app",
defaultTtlSeconds: 30,
});
Connect
await client.connect({ mode: "host", accountId: ["5Grw...", 42] });
await client.connect({ mode: "local", signer: { publicKey, sign } });
Publish
Returns a Result<void, StatementStoreError> — ok on accept, err carrying the reason (StatementConnectionError, StatementDataTooLargeError, or StatementSubmitError).
const result = await client.publish<MyData>(data, {
channel: "my-channel",
topic2: "room-id",
});
if (result.ok) {
} else {
console.error(result.error);
}
Subscribe
const sub = client.subscribe<MyData>(callback, { topic2: "room-id" });
sub.unsubscribe();
Destroy
client.destroy();
ChannelStore: Last-Write-Wins
import { ChannelStore } from "@parity/product-sdk-statement-store";
const channels = new ChannelStore<Presence>(client, { topic2: "doc-123" });
const result = await channels.write("presence/peer-abc", { type: "presence", timestamp: Date.now() });
if (!result.ok) console.error(result.error);
const value = channels.read("presence/peer-abc");
const all = channels.readAll();
const sub = channels.onChange((channelName, value, previous) => {
console.log(`${channelName} updated`);
});
channels.destroy();
Topics and Channels
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);
Error Handling
import {
StatementStoreError,
StatementConnectionError,
StatementDataTooLargeError,
StatementSubmitError,
} from "@parity/product-sdk-statement-store";
publish and ChannelStore.write return a Result<void, StatementStoreError> rather than throwing. On failure, result.error is one of the subclasses above; narrow on it to react to the specific cause.
Common Mistakes
- Exceeding 512-byte data limit - Use for signaling, not bulk data
- Using
PolkadotSigner instead of StatementSignerWithKey - Different interface
- Using host mode outside a container - Host API only available inside containers
- Forgetting to call
destroy() - Keeps connections open
- Not awaiting
connect() - Must connect before publish/subscribe
Reference Files