Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
853a9df
Extend submission result types
AndreiEres Nov 25, 2025
c6d8e87
Remove NetworkPriority (which was never used)
AndreiEres Nov 28, 2025
1cc5ae9
Add Invalid result
AndreiEres Nov 28, 2025
550d9fa
Handle encoding_too_large
AndreiEres Nov 28, 2025
b153d0f
Add rejected variant
AndreiEres Nov 28, 2025
32b198b
Update from github-actions[bot] running command 'prdoc --audience nod…
github-actions[bot] Nov 28, 2025
31a606b
Update
AndreiEres Nov 28, 2025
bc77940
Update
AndreiEres Nov 28, 2025
67d915f
Update PR doc
AndreiEres Nov 28, 2025
068364a
Fix PR doc
AndreiEres Nov 28, 2025
4b6cc03
Update substrate/client/rpc-api/src/statement/mod.rs
AndreiEres Dec 1, 2025
89c3c37
Fix assertion
AndreiEres Dec 1, 2025
a3a0a90
Don't copy types
AndreiEres Dec 2, 2025
534ec44
statement-store: api changes
alexggh Dec 2, 2025
b3d1b36
Merge remote-tracking branch 'origin/AndreiEres/sss-rpc-types' into o…
alexggh Dec 2, 2025
6ef12d3
Merge remote-tracking branch 'origin/master' into alexggh/api-consoli…
alexggh Dec 3, 2025
af1be1d
remove replacement_preference_mask
alexggh Dec 3, 2025
c394914
remove unused
alexggh Dec 3, 2025
3ad1478
remove unused
alexggh Dec 3, 2025
31d3f53
remove unused
alexggh Dec 3, 2025
03fcc46
Merge remote-tracking branch 'origin/master' into alexggh/api-consoli…
alexggh Dec 9, 2025
acf0103
address feedback
alexggh Dec 9, 2025
65cd2ec
fixup documentation
alexggh Dec 9, 2025
e97cb8f
fix documentation
alexggh Dec 9, 2025
eca03c7
remove non-api changes for now
alexggh Dec 9, 2025
f43fc81
fix typos
alexggh Dec 9, 2025
849c17f
remove original api
alexggh Dec 9, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 36 additions & 58 deletions substrate/client/rpc-api/src/statement/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,78 +19,56 @@
//! Substrate Statement Store RPC API.

use jsonrpsee::{core::RpcResult, proc_macros::rpc};
use serde::{Deserialize, Serialize};
use sp_core::Bytes;
use sp_statement_store::SubmitResult;

pub mod error;

/// Filter for subscribing to statements with different topics.
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub enum TopicFilter {
/// Matches all topics.
Any,
/// Matches only statements including all of the given topics.
/// Bytes are expected to be a 32-byte topic. Up to `4` topics can be provided.
MatchAll(Vec<Bytes>),
/// Matches statements including any of the given topics.
/// Bytes are expected to be a 32-byte topic. Up to `128` topics can be provided.
MatchAny(Vec<Bytes>),
}

/// Substrate statement RPC API
#[rpc(client, server)]
pub trait StatementApi {
/// Return all statements, SCALE-encoded.
#[method(name = "statement_dump", with_extensions)]
fn dump(&self) -> RpcResult<Vec<Bytes>>;

/// Return the data of all known statements which include all topics and have no `DecryptionKey`
/// field.
/// Subscribe to new statements that match the provided filters.
///
/// To get the statement, and not just the data, use `statement_broadcastsStatement`.
#[method(name = "statement_broadcasts")]
fn broadcasts(&self, match_all_topics: Vec<[u8; 32]>) -> RpcResult<Vec<Bytes>>;

/// Return the data of all known statements whose decryption key is identified as `dest` (this
/// will generally be the public key or a hash thereof for symmetric ciphers, or a hash of the
/// private key for symmetric ciphers).
/// # Parameters
///
/// To get the statement, and not just the data, use `statement_postedStatement`.
#[method(name = "statement_posted")]
fn posted(&self, match_all_topics: Vec<[u8; 32]>, dest: [u8; 32]) -> RpcResult<Vec<Bytes>>;

/// Return the decrypted data of all known statements whose decryption key is identified as
/// `dest`. The key must be available to the client.
/// - `topic_filter` — Which topics to match. Use `TopicFilter::Any` to match all topics,
/// `TopicFilter::MatchAll(vec)` to match statements that include all provided topics, or
/// `TopicFilter::MatchAny(vec)` to match statements that include any of the provided topics.
///
/// To get the statement, and not just the data, use `statement_postedClearStatement`.
#[method(name = "statement_postedClear")]
fn posted_clear(
&self,
match_all_topics: Vec<[u8; 32]>,
dest: [u8; 32],
) -> RpcResult<Vec<Bytes>>;

/// Return all known statements which include all topics and have no `DecryptionKey`
/// field.
/// # Returns
///
/// This returns the SCALE-encoded statements not just the data as in rpc
/// `statement_broadcasts`.
#[method(name = "statement_broadcastsStatement")]
fn broadcasts_stmt(&self, match_all_topics: Vec<[u8; 32]>) -> RpcResult<Vec<Bytes>>;

/// Return all known statements whose decryption key is identified as `dest` (this
/// will generally be the public key or a hash thereof for symmetric ciphers, or a hash of the
/// private key for symmetric ciphers).
/// Returns a stream of SCALE-encoded statements as `Bytes`.
/// When a subscription is initiated the endpoint will immediately return the matching
/// statements already in the store. Subsequent matching statements will be pushed to the client
/// as they are added to the store.
#[subscription(
name = "statement_subscribeStatement" => "statement_statement",
unsubscribe = "statement_unsubscribeStatement",
item = Bytes,
with_extensions,
)]
fn subscribe_statement(&self, topic_filter: TopicFilter);

/// Submit a SCALE-encoded statement.
///
/// This returns the SCALE-encoded statements not just the data as in rpc `statement_posted`.
#[method(name = "statement_postedStatement")]
fn posted_stmt(&self, match_all_topics: Vec<[u8; 32]>, dest: [u8; 32])
-> RpcResult<Vec<Bytes>>;

/// Return the statement and the decrypted data of all known statements whose decryption key is
/// identified as `dest`. The key must be available to the client.
/// See `Statement` definition for more details.
///
/// This returns for each statement: the SCALE-encoded statement concatenated to the decrypted
/// data. Not just the data as in rpc `statement_postedClear`.
#[method(name = "statement_postedClearStatement")]
fn posted_clear_stmt(
&self,
match_all_topics: Vec<[u8; 32]>,
dest: [u8; 32],
) -> RpcResult<Vec<Bytes>>;

/// Submit a pre-encoded statement.
/// Returns `SubmitResult` indicating success or failure reason.
#[method(name = "statement_submit")]
fn submit(&self, encoded: Bytes) -> RpcResult<SubmitResult>;

/// Remove a statement from the store.
#[method(name = "statement_remove")]
fn remove(&self, statement_hash: [u8; 32]) -> RpcResult<()>;
}
44 changes: 37 additions & 7 deletions substrate/primitives/statement-store/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,12 +177,42 @@ impl Field {
/// Statement structure.
#[derive(DecodeWithMemTracking, TypeInfo, sp_core::RuntimeDebug, Clone, PartialEq, Eq, Default)]
pub struct Statement {
/// Proof used for authorizing the statement.
proof: Option<Proof>,
/// An identifier for the key that `Data` field may be decrypted with.
#[deprecated(note = "Experimental feature, may be removed in future releases")]
decryption_key: Option<DecryptionKey>,
/// Used for identifying a distinct communication channel, only a message per channel is
/// stored.
///
/// This can be used to implement message replacement, submitting a new message with a
/// different topic/data on the same channel and a greater expiry replaces the previous one.
///
/// If the new statement data is bigger than the old one, submitting a statement with the same
/// channel does not guarantee that **ONLY** the old one will be replaced, as it might not fit
/// in the account quota. In that case, other statements from the same account with the lowest
/// expiry will be removed.
channel: Option<Channel>,
priority: Option<u32>,
/// Message expiry, used for determining which statements to keep.
///
/// The most significant 32 bits represents the expiration timestamp (in seconds since
/// UNIX epoch) after which the statement gets removed. These ensure that statements with a
/// higher expiration time have a higher priority.
/// The lower 32 bits represents an arbitrary sequence number used to order statements with the
/// same expiration time.
///
/// Higher values indicate a higher priority.
/// This is used in two cases:
/// 1) When an account exceeds its quota and some statements need to be removed. Statements
/// with the lowest `expiry` are removed first.
/// 2) When multiple statements are submitted on the same channel, the one with the highest
/// expiry replaces the one with the same channel.
expiry: u64,
/// Number of topics present.
num_topics: u8,
/// Topics, used for querying and filtering statements.
topics: [Topic; MAX_TOPICS],
/// Statement data.
data: Option<Vec<u8>>,
}

Expand Down Expand Up @@ -424,9 +454,9 @@ impl Statement {
self.channel
}

/// Get priority, if any.
pub fn priority(&self) -> Option<u32> {
self.priority
/// Get expiry.
pub fn expiry(&self) -> u64 {
self.expiry
}

/// Return encoded fields that can be signed to construct or verify a proof
Expand All @@ -444,9 +474,9 @@ impl Statement {
self.proof = Some(proof)
}

/// Set statement priority.
pub fn set_priority(&mut self, priority: u32) {
self.priority = Some(priority)
/// Set statement expiry.
pub fn set_expiry(&mut self, expiry: u64) {
self.expiry = expiry;
}

/// Set statement channel.
Expand Down
Loading