Skip to Content
API Reference@parity/product-sdk-statement-storeOverview

@parity/product-sdk-statement-store

Publish/subscribe over the Polkadot Statement Store.

StatementStoreClient submits signed statements and subscribes to topics via the Host API’s native binary protocol — the SDK runs only inside a host container (Polkadot Browser / Desktop). ChannelStore layers a channel abstraction on top for apps that want stable, two-party message streams instead of raw topics.

npm install @parity/product-sdk-statement-store

Exports

Classes

NameSummary
ChannelStoreHigher-level abstraction providing last-write-wins channel semantics
StatementConnectionErrorFailed to connect to the statement store transport.
StatementDataTooLargeErrorThe statement data payload exceeds the maximum allowed size.
StatementEncodingErrorA SCALE encoding or decoding operation failed.
StatementStoreClientHigh-level client for the Polkadot Statement Store.
StatementStoreErrorBase class for all statement store errors.
StatementSubmitErrorThe statement store node rejected a submitted statement.
StatementSubscriptionErrorFailed to set up or maintain a statement subscription.

Functions

NameSummary
createChannel()Create a 32-byte channel hash from a human-readable channel name.
createTopic()Create a 32-byte topic hash from a human-readable string.
createTransport()Create a statement store transport.
decodeData()Decode a JSON-serialized data payload from statement bytes.
encodeData()Encode a value as a JSON-serialized data payload for a statement.
fromHex()Convert a hex string (with or without 0x prefix) to bytes.
serializeTopicFilter()Serialize a TopicFilter into the JSON-RPC format expected by statement store nodes.
toHex()Convert bytes to a hex string with 0x prefix.
topicsEqual()Compare two topic or channel hashes for byte equality.
topicToHex()Convert a topic or channel hash to a hex string (with 0x prefix).

Interfaces

NameSummary
PublishOptionsOptions for publishing a single statement.
ReceivedStatementA received statement with typed data and metadata.
StatementSignerWithKeyAn Sr25519 signer with its associated public key.
StatementStoreConfigConfiguration for StatementStoreClient.
StatementTransportLow-level transport interface for statement store communication.
UnsubscribableHandle returned by subscription methods. Call unsubscribe() to stop receiving events.

Type Aliases

NameSummary
ChannelHashA 32-byte blake2b-256 hash used as a statement channel identifier.
ConnectionCredentialsCredentials for connecting to the statement store.
Proof
SdkTopicFilterFilter for subscribing to statements with different topics.
SignedStatement
Statement
StatementSignerA function that signs a message with an Sr25519 key.
SubmitResult
TopicFilterFilter for statement subscriptions and queries.
TopicHashA 32-byte blake2b-256 hash used as a statement topic.
UnsignedStatement

Variables

NameSummary
DEFAULT_TTL_SECONDSDefault time-to-live for published statements in seconds.
MAX_STATEMENT_SIZEMaximum size of a single statement’s data payload in bytes.
MAX_USER_TOTALMaximum total storage per user in bytes.

Classes

class ChannelStore

Higher-level abstraction providing last-write-wins channel semantics over the statement store.

Each channel name maps to a single value. When a new value is written to a channel, it replaces the previous one if its timestamp is newer. This is ideal for presence announcements, signaling, and ephemeral state.

Examples

interface Presence { type: "presence"; peerId: string; timestamp: number; } const channels = new ChannelStore<Presence>(client, { topic2: "doc-123" }); // Write presence await channels.write("presence/peer-abc", { type: "presence", peerId: "abc", timestamp: Date.now(), }); // Read all presences for (const [name, value] of channels.readAll()) { console.log(`${name}: ${value.peerId}`); } // React to changes channels.onChange((name, value, previous) => { console.log(`Channel ${name} updated`); }); channels.destroy();

Constructors

constructor
new ChannelStore(client: StatementStoreClient, options?: { topic2?: string }): ChannelStore<T>
Parameters
  • client: The connected StatementStoreClient to use.
  • options: Optional secondary topic for scoping channels.

Accessors

size
accessornumber

Get the number of channels currently tracked.

Methods

destroy

Destroy the channel store and clean up subscriptions.

Does not destroy the underlying client.

destroy(): void
onChange

Subscribe to channel value changes.

The callback is invoked whenever a channel value is updated (either from the network or from a local write).

onChange(callback: (channelName: string, value: T, previous: T | undefined) => void): Unsubscribable
Parameters
  • callback: Called with the channel key (hex hash for network-received, hex hash for local writes), new value, and previous value.
Returns

A handle to unsubscribe.

read

Read the latest value for a channel by its human-readable name.

Looks up the channel hash from the name, then retrieves the value. Also checks the hash directly for values received from the network before any local write established the name mapping.

read(channelName: string): T | undefined
Parameters
  • channelName: The channel name (e.g., “presence/peer-abc”).
Returns

The latest value, or undefined if no value has been received.

readAll

Read all channel values as a read-only map.

Keys are hex-encoded channel hashes. Use read for lookup by human-readable name.

readAll(): ReadonlyMap<string, T>
Returns

A map of channel hash to latest value.

write

Write a value to a named channel.

If the value doesn’t include a timestamp, one is added automatically using Date.now(). The value is published to the statement store with the channel name as the statement channel.

write(channelName: string, value: T): Promise<boolean>
Parameters
  • channelName: The channel name (e.g., “presence/peer-abc”).
  • value: The value to write.
Returns

true if the statement was accepted by the network.

class StatementConnectionError

Failed to connect to the statement store transport.

Thrown when the WebSocket connection cannot be established or the chain-client’s bulletin chain is not connected.

Extends: StatementStoreError

Constructors

constructor
new StatementConnectionError(message: string, options?: ErrorOptions): StatementConnectionError

class StatementDataTooLargeError

The statement data payload exceeds the maximum allowed size.

The statement store protocol limits individual statement data to MAX_STATEMENT_SIZE bytes (512 bytes).

Extends: StatementStoreError

Constructors

constructor
new StatementDataTooLargeError(actualSize: number, maxSize: number = MAX_STATEMENT_SIZE): StatementDataTooLargeError

Properties

actualSize
propertyreadonlynumber

The actual size of the data in bytes.

maxSize
propertyreadonlynumber

The maximum allowed size in bytes.

class StatementEncodingError

A SCALE encoding or decoding operation failed.

Thrown when statement bytes cannot be parsed (corrupt data, unknown field tags) or when encoding produces invalid output.

Extends: StatementStoreError

Constructors

constructor
new StatementEncodingError(message: string, options?: ErrorOptions): StatementEncodingError

class StatementStoreClient

High-level client for the Polkadot Statement Store.

Provides a simple publish/subscribe API over the ephemeral statement store, handling topic management and signing through the host API.

The SDK is designed to run exclusively inside a host container.

Examples

import { StatementStoreClient } from "@parity/product-sdk-statement-store"; // Inside a container (host mode) const client = new StatementStoreClient({ appName: "my-app" }); await client.connect({ mode: "host", accountId: ["5Grw...", 42] }); // Publish await client.publish({ type: "presence", peerId: "abc" }, { channel: "presence/abc", topic2: "room-123", }); // Subscribe client.subscribe<{ type: string }>(statement => { console.log(statement.data.type); }); // Cleanup client.destroy();

Constructors

constructor
new StatementStoreClient(config: StatementStoreConfig): StatementStoreClient

Methods

connect

Connect to the statement store and start receiving statements.

Overload 1
connect(credentials: ConnectionCredentials): Promise<void>

Connect to the statement store and start receiving statements.

Parameters
  • credentials: Connection credentials (host accountId or local signer).
Throws
  • If the transport cannot be established.
Overload 2
connect(signer: StatementSignerWithKey): Promise<void>
destroy

Destroy the client, unsubscribing and closing the transport.

Safe to call multiple times. After destruction, the client cannot be reused.

destroy(): void
getPublicKeyHex

Get the signer’s public key as a hex string (with 0x prefix).

getPublicKeyHex(): string
Returns

The hex-encoded public key, or empty string if not connected or in host mode.

isConnected

Whether the client is connected and ready to publish/subscribe.

isConnected(): boolean
publish

Publish typed data to the statement store.

publish(data: T, options?: PublishOptions): Promise<boolean>
Parameters
  • data: The value to publish (must be JSON-serializable, max 512 bytes).
  • options: Optional channel, topic2, TTL, and decryption key overrides.
Returns

true if accepted, false if rejected or errored.

Throws
  • If not connected.
  • If the encoded data exceeds 512 bytes.
subscribe

Subscribe to incoming statements on this application’s topic.

subscribe(callback: (statement: ReceivedStatement<T>) => void, options?: { topic2?: string }): Unsubscribable
Parameters
  • callback: Called for each new statement.
  • options: Optional secondary topic filter.
Returns

A handle to unsubscribe.

class StatementStoreError

Base class for all statement store errors.

Use instanceof StatementStoreError to catch any error originating from the statement store package.

Extends: Error

Constructors

constructor
new StatementStoreError(message: string, options?: ErrorOptions): StatementStoreError

class StatementSubmitError

The statement store node rejected a submitted statement.

Carries the raw RPC response detail for programmatic inspection.

Extends: StatementStoreError

Constructors

constructor
new StatementSubmitError(detail: unknown): StatementSubmitError

Properties

detail
propertyreadonlyunknown

The raw response from the RPC call.

class StatementSubscriptionError

Failed to set up or maintain a statement subscription.

This is a non-fatal error — the client falls back to polling when subscriptions are unavailable.

Extends: StatementStoreError

Constructors

constructor
new StatementSubscriptionError(message: string, options?: ErrorOptions): StatementSubscriptionError

Functions

createChannel()

Create a 32-byte channel hash from a human-readable channel name.

Channels enable last-write-wins semantics: for a given channel, only the most recent statement (by timestamp) is retained.

createChannel(name: string): ChannelHash

Parameters

  • name: A human-readable channel name (e.g., “presence/peer-abc”).

Returns

A branded 32-byte channel hash.

Examples

const channel = createChannel("presence/peer-abc123");

createTopic()

Create a 32-byte topic hash from a human-readable string.

Uses blake2b-256 to hash the UTF-8 encoded string into a deterministic 32-byte topic identifier. Statements are tagged with topics so subscribers can filter efficiently on the network.

createTopic(name: string): TopicHash

Parameters

  • name: A human-readable topic name (e.g., “ss-webrtc”, “my-app”).

Returns

A branded 32-byte topic hash.

Examples

const topic = createTopic("ss-webrtc"); // Use in subscriptions and publish options

createTransport()

Create a statement store transport.

Uses the Host API via @parity/product-sdk-host — the container’s native statement store protocol (binary, not JSON-RPC). This is the only supported path.

createTransport(): Promise<StatementTransport>

Throws

  • If the host statement store is unavailable.

decodeData()

Decode a JSON-serialized data payload from statement bytes.

decodeData(bytes: Uint8Array): T

Parameters

  • bytes: UTF-8 encoded JSON bytes.

Returns

The parsed value.

Throws

  • If the bytes are not valid UTF-8 or valid JSON.

encodeData()

Encode a value as a JSON-serialized data payload for a statement.

Serializes the value as JSON and encodes to UTF-8 bytes. Throws StatementDataTooLargeError if the result exceeds MAX_STATEMENT_SIZE bytes.

encodeData(value: T): Uint8Array

Parameters

  • value: The value to serialize.

Returns

UTF-8 encoded JSON bytes.

Throws

  • If the encoded data exceeds 512 bytes.

fromHex()

Convert a hex string (with or without 0x prefix) to bytes.

fromHex(hex: string): Uint8Array

serializeTopicFilter()

Serialize a TopicFilter into the JSON-RPC format expected by statement store nodes.

  • "any" is passed through as the string "any".
  • { matchAll: [...] } becomes { matchAll: ["0x...", ...] } with hex-encoded topics.
  • { matchAny: [...] } becomes { matchAny: ["0x...", ...] } with hex-encoded topics.
serializeTopicFilter(filter: TopicFilter): TopicFilter

Parameters

  • filter: The topic filter to serialize.

Returns

A JSON-RPC compatible filter value.

toHex()

Convert bytes to a hex string with 0x prefix.

toHex(bytes: Uint8Array): string

topicsEqual()

Compare two topic or channel hashes for byte equality.

topicsEqual(a: Uint8Array, b: Uint8Array): boolean

Parameters

  • a: First hash.
  • b: Second hash.

Returns

True if the hashes are identical.

topicToHex()

Convert a topic or channel hash to a hex string (with 0x prefix).

topicToHex(hash: Uint8Array): string

Parameters

  • hash: A 32-byte topic or channel hash.

Returns

Hex string with “0x” prefix.

Interfaces

interface PublishOptions

Options for publishing a single statement.

Properties

channel
propertyoptionalstring

Channel name for last-write-wins semantics.

When provided, the statement is tagged with blake2b(channel). For a given channel, only the most recent statement is kept.

decryptionKey
propertyoptionalUint8Array<ArrayBufferLike>

Decryption key hint (32 bytes).

Used by the statement_posted RPC method to filter statements. Typically set to the blake2b hash of the room or document ID.

topic2
propertyoptionalstring

Secondary topic for additional filtering.

Hashed with blake2b and set as topic2. Useful for scoping statements to a specific room, document, or context.

ttlSeconds
propertyoptionalnumber

Time-to-live in seconds. Overrides StatementStoreConfig.defaultTtlSeconds.

interface ReceivedStatement

A received statement with typed data and metadata.

Properties

channelHex
propertyoptionalstring

Channel hex, if present.

data
propertyT

Parsed data payload.

expiry
propertyoptionalbigint

Combined expiry value (upper 32 bits = timestamp, lower 32 bits = sequence).

raw
propertyStatement

The full statement from the transport for advanced inspection.

signerHex
propertyoptionalstring

Signer’s public key hex (from proof), if present.

topics
propertystring[]

Topics array (hex strings).

interface StatementSignerWithKey

An Sr25519 signer with its associated public key.

Used by StatementStoreClient.connect to sign published statements when running outside a container (local mode).

Properties

publicKey
propertyUint8Array

32-byte Sr25519 public key.

sign
propertyStatementSigner

Signing function.

interface StatementStoreConfig

Configuration for StatementStoreClient.

The client uses the Host API’s native statement store protocol. The SDK is designed to run exclusively inside a host container.

Properties

appName
propertystring

Application namespace used as the primary topic (topic1).

All statements published by this client are tagged with blake2b(appName). Subscribers filter on this topic to receive only relevant statements.

defaultTtlSeconds
propertyoptionalnumber

Default time-to-live for published statements in seconds.

Statements automatically expire after this duration. Can be overridden per-publish via PublishOptions.ttlSeconds.

transport
propertyoptionalStatementTransport

Provide a custom transport instead of auto-detection.

When set, the client uses this transport directly. Useful for testing or advanced BYOD setups.

interface StatementTransport

Low-level transport interface for statement store communication.

Uses HostTransport — the Host API’s native binary protocol.

Most consumers should use StatementStoreClient instead of this interface directly.

Methods

destroy

Destroy the transport and release all resources.

destroy(): void
query

Query existing statements from the store.

Note: The host API subscription replays initial state, so this may not be needed.

query(filter: TopicFilter): Promise<Partial<{ channel: SizedHex<32>; data: Uint8Array; decryptionKey: SizedHex<32>; expiry: bigint; proof: Proof; topics: SizedHex<32>[] }>[]>
signAndSubmit

Sign and submit a statement.

  • Host mode: delegates to the host API’s createProof then submit.
  • Local mode: signs locally using getStatementSigner from sdk-statement, then submits.
signAndSubmit(statement: Statement, credentials: ConnectionCredentials): Promise<void>
Parameters
  • statement: The unsigned statement to sign and submit.
  • credentials: Signing credentials (host accountId or local signer).
subscribe

Subscribe to statements matching a topic filter.

subscribe(filter: TopicFilter, onStatements: (statements: Partial<{ channel: SizedHex<32>; data: Uint8Array; decryptionKey: SizedHex<32>; expiry: bigint; proof: Proof; topics: SizedHex<32>[] }>[]) => void, onError: (error: Error) => void): Unsubscribable
Parameters
  • filter: sdk-statement topic filter.
  • onStatements: Called with batches of received statements.
  • onError: Called when the subscription encounters an error.
Returns

A handle to unsubscribe.

interface Unsubscribable

Handle returned by subscription methods. Call unsubscribe() to stop receiving events.

Properties

unsubscribe
property() => void

Type Aliases

type ChannelHash

A 32-byte blake2b-256 hash used as a statement channel identifier.

Channels enable last-write-wins semantics: for a given channel, only the most recent statement (by timestamp) is kept. Create one with createChannel.

type ChannelHash = Uint8Array & { readonly __brand: "ChannelHash" }

type ConnectionCredentials

Credentials for connecting to the statement store.

  • Host mode: Inside a container, proof creation is delegated to the host API. The accountId is a [ss58Address, chainPrefix] tuple from product-sdk.
  • Local mode: Outside a container, statements are signed locally using the provided Sr25519 signer.
type ConnectionCredentials = { accountId: [string, number]; mode: "host" } | { mode: "local"; signer: StatementSignerWithKey }

type Proof

type Proof = Enum<{ ecdsa: { signature: SizedHex<65>; signer: SizedHex<33> }; ed25519: { signature: SizedHex<64>; signer: SizedHex<32> }; onChain: { blockHash: SizedHex<32>; event: bigint; who: SizedHex<32> }; sr25519: { signature: SizedHex<64>; signer: SizedHex<32> } }>

type SdkTopicFilter

Filter for subscribing to statements with different topics.

type SdkTopicFilter = "any" | { matchAll: SizedHex<32>[] } | { matchAny: SizedHex<32>[] }

type SignedStatement

type SignedStatement = UnsignedStatement & { proof: Proof }

type Statement

type Statement = Partial<{ channel: SizedHex<32>; data: Uint8Array; decryptionKey: SizedHex<32>; expiry: bigint; proof: Proof; topics: SizedHex<32>[] }>

type StatementSigner

A function that signs a message with an Sr25519 key.

Takes the signature material bytes and returns a 64-byte Sr25519 signature. May be synchronous or asynchronous (e.g., when signing via a hardware wallet).

type StatementSigner = (message: Uint8Array) => Uint8Array | Promise<Uint8Array>

type SubmitResult

type SubmitResult = SubmitNew | SubmitKnown | SubmitKnownExpired | SubmitRejected | SubmitInvalid | SubmitInternalError

type TopicFilter

Filter for statement subscriptions and queries.

  • "any" — matches all statements (no filtering).
  • { matchAll: [...] } — matches statements that have all listed topics.
  • { matchAny: [...] } — matches statements that have any listed topic.
type TopicFilter = "any" | { matchAll: TopicHash[] } | { matchAny: TopicHash[] }

type TopicHash

A 32-byte blake2b-256 hash used as a statement topic.

Topics allow subscribers to filter statements efficiently on the network. Create one with createTopic.

type TopicHash = Uint8Array & { readonly __brand: "TopicHash" }

type UnsignedStatement

type UnsignedStatement = Omit<Statement, "proof">

Variables

DEFAULT_TTL_SECONDS

Default time-to-live for published statements in seconds.

let DEFAULT_TTL_SECONDS: 30 = 30

MAX_STATEMENT_SIZE

Maximum size of a single statement’s data payload in bytes.

let MAX_STATEMENT_SIZE: 512 = 512

MAX_USER_TOTAL

Maximum total storage per user in bytes.

let MAX_USER_TOTAL: 1024 = 1024
Last updated on