lib

Core libraries for Radroots
git clone https://radroots.dev/git/lib.git
Log | Files | Refs | README

commit b4b63c79191d7105e5a12c68602a0e1ab176309c
parent 09b9a80de8a1793b8a7c627bd292bad8fec7abfa
Author: triesap <tyson@radroots.org>
Date:   Thu, 30 Jul 2026 13:22:34 +0000

signing: document public api contract

- define the host SPI lifecycle side effects and security boundary
- compile README and external signer examples through package tests
- record the reviewed all-feature public API baseline
- document feature behavior intended consumers and serialization rules

Diffstat:
Mcrates/signing/README.md | 163+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
Acrates/signing/examples/host_signer.rs | 51+++++++++++++++++++++++++++++++++++++++++++++++++++
Mcrates/signing/tests/package_boundary.rs | 65+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mdocs/api/README.md | 1+
Adocs/api/radroots_signing.txt | 220+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 497 insertions(+), 3 deletions(-)

diff --git a/crates/signing/README.md b/crates/signing/README.md @@ -1,6 +1,163 @@ # radroots_signing -Signing abstractions and authorization policy for Radroots. +`radroots_signing` is the protocol-neutral host SPI for authorizing and signing +frozen Radroots event drafts. It owns actor provenance, signer capabilities and +status, bounded signing requests, exact-draft receipts, progress, and normalized +secret-safe errors. -This package root is established for the Release V1 refactor. Its signer SPI -and policy surface are migrated in the subsequent signing checkpoints. +The crate is `no_std` with `alloc`. It does not own secret keys, keyrings, +network clients, NIP-46 sessions, SQL, UI prompts, or an async executor. +Concrete local Nostr signing belongs in `radroots_nostr`; remote protocol state +belongs in `radroots_nostr_connect`; applications compose those adapters in +`radroots_sdk` or their own host layer. + +The authoritative package charter is the +[`radroots_signing` section of the Release V1 specification](https://github.com/radrootslabs/lib/blob/master/docs/specs/radroots_crates_release_v1.md#8-radroots_signing). + +## Typical flow + +1. A host resolves public actor provenance and roles into an [`Actor`]. +2. Event-domain code freezes a canonical `radroots_event::EventDraft`. +3. The host combines the actor, draft, typed operation ID, deadline, and + cancellation policy into a [`SignRequest`]. Construction validates the + draft, required author role, and expected public key before a signer runs. +4. A dyn-compatible [`Signer`] implementation signs locally, delegates to a + remote device/service, or mediates explicit host interaction. +5. The implementation creates a [`SignReceipt`] from the originating request. + Receipt construction rejects any signed-event drift from the frozen draft. + +[`Actor`]: crate::Actor +[`Signer`]: crate::Signer +[`SignRequest`]: crate::SignRequest +[`SignReceipt`]: crate::SignReceipt + +```rust +use radroots_event::{EventDraft, contract::AuthorRole}; +use radroots_identity::PublicKey; +use radroots_protocol::runtime::v1::OperationId; +use radroots_signing::{ + Actor, SignRequest, + actor::ActorSource, + request::{CancellationPolicy, SignPolicy}, +}; + +let public_key = PublicKey::from_hex( + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", +) +.expect("canonical public key"); +let actor = Actor::new( + public_key, + ActorSource::ExplicitPublicKey, + [AuthorRole::Any], +) +.expect("validated actor"); +let draft = EventDraft::new( + "radroots.social.geochat.v1", + 20_000, + 1_700_000_000, + Vec::new(), + "hello from Radroots", + public_key.to_hex(), +) +.expect("frozen draft"); +let policy = SignPolicy::new( + 1_700_000_030, + CancellationPolicy::PreservePublishedRequest, +) +.expect("bounded policy"); +let request = SignRequest::new(OperationId::SyncPush, actor, draft, policy) + .expect("authorized signing request"); + +assert_eq!(request.operation_id(), OperationId::SyncPush); +``` + +The complete externally implementable SPI example is +[`examples/host_signer.rs`](examples/host_signer.rs). + +## Host SPI contract + +`Signer` is intentionally externally implementable, object-safe, `Send`, and +`Sync`. Its methods return boxed `Future + Send` values so the SPI does not +select an async runtime or require an async-trait macro. + +- `status` is observational and must not create a signing request or another + durable side effect. +- `sign` receives an owned, already-authorized request. Implementations must + honor its deadline and cancellation policy for the entire operation and must + create success only through `SignReceipt::from_signed_event`. +- Implementations must not install an executor or spawn hidden workers. The + composing host owns polling, scheduling, and process lifecycle. +- Every concrete adapter must document the exact point at which a request + becomes durable. Dropping the future before that point must leave no durable + effect; dropping it afterward does not imply rollback. +- Concrete backend failures are normalized to `radroots_signing::Error`. + Native sources may be retained with `std`, but display, debug, and versioned + protocol reports never copy source text. + +## Deadlines, cancellation, and commit points + +`SignPolicy` carries an absolute Unix deadline. A signer must reject work once +that deadline is reached; request construction does not read a clock. + +`CancellationPolicy::LocalCooperative` is for local-only work that may stop +when cancellation is observed. `PreservePublishedRequest` is for operations +that may publish a durable remote request: cancellation before publication may +stop the operation, while cancellation after publication must preserve and +report the final remote state explicitly. Cancellation never silently converts +an unknown or committed remote state into success or rollback. + +The SPI defines those rules but performs no I/O itself. Commit points belong to +the concrete adapter and must be visible in that adapter's documentation and +status/progress behavior. + +## Serialization contract + +Native `Actor` and `SignRequest` values are runtime-local and are not +serializable. `SignReceipt` can be serialized with `serde` but cannot be +deserialized without the originating request; this prevents callers from +bypassing authorization and exact-draft verification. + +The `serde` feature provides stable representations for passive policies, +capabilities, status, progress, challenges, and receipts. Versioned +cross-process error data is produced through `Error::to_report` and owned by +`radroots_protocol`. An authentication challenge URI is deliberately +host-displayable and serializable, so adapters must not embed credentials or +secret material in it. + +## Security and side effects + +- Request construction validates the current draft before role and key + authorization and never invokes a signer on failure. +- A successful receipt proves exact equality of author, timestamp, kind, tags, + content, and event ID with the frozen request draft. +- `Error` display/debug output and protocol reports are redacted. Under `std`, + a caller may explicitly inspect a preserved native error source locally. +- `AuthChallenge` debug output redacts its URI; the value accepts only bounded + control-free HTTPS URIs and remains untrusted navigation input for hosts. +- This crate forbids unsafe code and contains no secret-key type, persistence, + network transport, global state, timer, or runtime initialization. + +## Features + +| Feature | Default | Contract | +| --- | --- | --- | +| `std` | yes | Uses `std` collections and permits preserved native error sources; no runtime, I/O, or global initialization is added. | +| `serde` | yes | Adds serialization for explicitly passive public values and deserialization only where validated reconstruction is safe. | + +Features are additive. `--no-default-features` provides the `no_std + alloc` +core, and `serde` is supported independently of `std`. + +## Intended consumers + +- `radroots_nostr` implements concrete local signing. +- `radroots_nostr_connect` supplies remote protocol state without owning this + SPI's host composition. +- `radroots_sync` and `radroots_sdk` orchestrate authorized requests and + consume verified receipts. +- CLI, Studio, mobile/FFI, and service hosts resolve actor provenance, choose + adapters, display authentication challenges, and own cancellation/runtime + behavior. + +Applications that only need ordinary Radroots operations should normally use +`radroots` or `radroots_sdk`; implement this package directly when providing a +new signer adapter or advanced host composition. diff --git a/crates/signing/examples/host_signer.rs b/crates/signing/examples/host_signer.rs @@ -0,0 +1,51 @@ +use radroots_event::{EventDraft, contract::AuthorRole}; +use radroots_identity::PublicKey; +use radroots_protocol::runtime::v1::OperationId; +use radroots_signing::{ + Actor, Error, SignReceipt, SignRequest, Signer, SignerStatus, + actor::ActorSource, + error::Kind, + request::{CancellationPolicy, SignPolicy}, + signer::BoxFuture, +}; + +struct HostSigner; + +impl Signer for HostSigner { + fn status(&self) -> BoxFuture<'_, Result<SignerStatus, Error>> { + Box::pin(async { Ok(SignerStatus::unavailable()) }) + } + + fn sign(&self, _request: SignRequest) -> BoxFuture<'_, Result<SignReceipt, Error>> { + Box::pin(async { Err(Error::new(Kind::SignerUnavailable)) }) + } +} + +fn main() { + let public_key = + PublicKey::from_hex("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") + .expect("canonical public key"); + let actor = Actor::new( + public_key, + ActorSource::ExplicitPublicKey, + [AuthorRole::Any], + ) + .expect("validated actor"); + let draft = EventDraft::new( + "radroots.social.geochat.v1", + 20_000, + 1_700_000_000, + Vec::new(), + "host-composed signing", + public_key.to_hex(), + ) + .expect("frozen draft"); + let policy = SignPolicy::new(1_700_000_030, CancellationPolicy::PreservePublishedRequest) + .expect("bounded policy"); + let request = + SignRequest::new(OperationId::SyncPush, actor, draft, policy).expect("authorized request"); + + let signer: &dyn Signer = &HostSigner; + let future = signer.sign(request); + drop(future); // The composing host chooses and drives its async executor. +} diff --git a/crates/signing/tests/package_boundary.rs b/crates/signing/tests/package_boundary.rs @@ -7,6 +7,9 @@ use radroots_signing::{ }; const MANIFEST: &str = include_str!("../Cargo.toml"); +const EXAMPLE: &str = include_str!("../examples/host_signer.rs"); +const PUBLIC_API: &str = include_str!("../../../docs/api/radroots_signing.txt"); +const README: &str = include_str!("../README.md"); const ROOT: &str = include_str!("../src/lib.rs"); #[test] @@ -123,6 +126,68 @@ fn crate_root_declares_the_approved_module_skeleton() { } #[test] +fn package_documentation_and_reviewed_api_baseline_are_complete() { + for required in [ + "## Typical flow", + "## Host SPI contract", + "## Deadlines, cancellation, and commit points", + "## Serialization contract", + "## Security and side effects", + "## Features", + "## Intended consumers", + "radroots_crates_release_v1.md#8-radroots_signing", + "examples/host_signer.rs", + ] { + assert!(README.contains(required), "README is missing {required}"); + } + for required in [ + "impl Signer for HostSigner", + "fn status(&self) -> BoxFuture", + "fn sign(&self, _request: SignRequest) -> BoxFuture", + "let signer: &dyn Signer", + "drop(future)", + ] { + assert!(EXAMPLE.contains(required), "example is missing {required}"); + } + for required in [ + "pub mod radroots_signing::actor", + "pub mod radroots_signing::capability", + "pub mod radroots_signing::error", + "pub mod radroots_signing::receipt", + "pub mod radroots_signing::request", + "pub mod radroots_signing::signer", + "pub mod radroots_signing::status", + "pub trait radroots_signing::Signer", + ] { + assert!( + PUBLIC_API.contains(required), + "public API baseline is missing {required}" + ); + } +} + +#[test] +fn every_public_module_has_crate_level_documentation() { + let source_root = Path::new(env!("CARGO_MANIFEST_DIR")).join("src"); + for module in [ + "actor", + "capability", + "error", + "request", + "receipt", + "signer", + "status", + ] { + let path = source_root.join(format!("{module}.rs")); + let source = fs::read_to_string(&path).expect("read module source"); + assert!( + source.starts_with("//! "), + "public module {module} must start with module documentation" + ); + } +} + +#[test] fn production_sources_publish_only_the_approved_traits_and_no_host_stack() { let source_root = Path::new(env!("CARGO_MANIFEST_DIR")).join("src"); let mut sources = Vec::new(); diff --git a/docs/api/README.md b/docs/api/README.md @@ -37,3 +37,4 @@ expand a package beyond its charter. | `radroots_event` | [`radroots_event.txt`](radroots_event.txt) | [release V1 specification](../specs/radroots_crates_release_v1.md) | | `radroots_event_codec` | [`radroots_event_codec.txt`](radroots_event_codec.txt) | [release V1 specification](../specs/radroots_crates_release_v1.md) | | `radroots_trade` | [`radroots_trade.txt`](radroots_trade.txt) | [release V1 specification](../specs/radroots_crates_release_v1.md) | +| `radroots_signing` | [`radroots_signing.txt`](radroots_signing.txt) | [release V1 specification](../specs/radroots_crates_release_v1.md) | diff --git a/docs/api/radroots_signing.txt b/docs/api/radroots_signing.txt @@ -0,0 +1,220 @@ +pub mod radroots_signing +pub mod radroots_signing::actor +#[non_exhaustive] pub enum radroots_signing::actor::ActorSelector +pub radroots_signing::actor::ActorSelector::Account(radroots_identity::account::AccountId) +pub radroots_signing::actor::ActorSelector::DraftExpectedPublicKey +pub radroots_signing::actor::ActorSelector::PublicKey(radroots_identity::key::PublicKey) +pub radroots_signing::actor::ActorSelector::SelectedAccount +#[non_exhaustive] pub enum radroots_signing::actor::ActorSource +pub radroots_signing::actor::ActorSource::ExplicitPublicKey +pub radroots_signing::actor::ActorSource::LocalAccount(radroots_identity::account::AccountId) +pub radroots_signing::actor::ActorSource::RemoteSigner(radroots_identity::account::AccountId) +pub radroots_signing::actor::ActorSource::Service(radroots_identity::account::AccountId) +impl radroots_signing::actor::ActorSource +pub const fn radroots_signing::actor::ActorSource::account_id(self) -> core::option::Option<radroots_identity::account::AccountId> +pub struct radroots_signing::actor::Actor +impl radroots_signing::actor::Actor +pub const fn radroots_signing::actor::Actor::account_id(&self) -> core::option::Option<radroots_identity::account::AccountId> +pub fn radroots_signing::actor::Actor::from_public_key_hex<I>(&str, radroots_signing::actor::ActorSource, I) -> core::result::Result<Self, radroots_signing::error::Error> where I: core::iter::traits::collect::IntoIterator<Item = radroots_event::contract::registry_v7::AuthorRole> +pub fn radroots_signing::actor::Actor::new<I>(radroots_identity::key::PublicKey, radroots_signing::actor::ActorSource, I) -> core::result::Result<Self, radroots_signing::error::Error> where I: core::iter::traits::collect::IntoIterator<Item = radroots_event::contract::registry_v7::AuthorRole> +pub const fn radroots_signing::actor::Actor::public_key(&self) -> radroots_identity::key::PublicKey +pub const fn radroots_signing::actor::Actor::roles(&self) -> &alloc::collections::btree::set::BTreeSet<radroots_event::contract::registry_v7::AuthorRole> +pub fn radroots_signing::actor::Actor::satisfies(&self, radroots_event::contract::registry_v7::AuthorRole) -> bool +pub const fn radroots_signing::actor::Actor::source(&self) -> radroots_signing::actor::ActorSource +pub struct radroots_signing::actor::ActorResolutionRequest +impl radroots_signing::actor::ActorResolutionRequest +pub const fn radroots_signing::actor::ActorResolutionRequest::expected_public_key(&self) -> radroots_identity::key::PublicKey +pub const fn radroots_signing::actor::ActorResolutionRequest::new(radroots_signing::actor::ActorSelector, radroots_event::contract::registry_v7::AuthorRole, radroots_identity::key::PublicKey) -> Self +pub const fn radroots_signing::actor::ActorResolutionRequest::required_role(&self) -> radroots_event::contract::registry_v7::AuthorRole +pub const fn radroots_signing::actor::ActorResolutionRequest::selector(&self) -> radroots_signing::actor::ActorSelector +pub mod radroots_signing::capability +#[non_exhaustive] pub enum radroots_signing::capability::CancellationSupport +pub radroots_signing::capability::CancellationSupport::BeforeAndAfterPublication +pub radroots_signing::capability::CancellationSupport::BeforePublication +#[non_exhaustive] pub enum radroots_signing::capability::SignerKind +pub radroots_signing::capability::SignerKind::HostMediated +pub radroots_signing::capability::SignerKind::Local +pub radroots_signing::capability::SignerKind::Remote +#[non_exhaustive] pub struct radroots_signing::capability::SignerCapability +impl radroots_signing::capability::SignerCapability +pub const fn radroots_signing::capability::SignerCapability::cancellation(self) -> radroots_signing::capability::CancellationSupport +pub const fn radroots_signing::capability::SignerCapability::kind(self) -> radroots_signing::capability::SignerKind +pub const fn radroots_signing::capability::SignerCapability::may_require_authentication(self) -> bool +pub const fn radroots_signing::capability::SignerCapability::new(radroots_signing::capability::SignerKind, radroots_signing::capability::CancellationSupport, bool, bool) -> Self +pub const fn radroots_signing::capability::SignerCapability::reports_progress(self) -> bool +pub mod radroots_signing::error +#[non_exhaustive] pub enum radroots_signing::error::Kind +pub radroots_signing::error::Kind::AuthorizationDenied +pub radroots_signing::error::Kind::DeadlineExceeded +pub radroots_signing::error::Kind::InternalError +pub radroots_signing::error::Kind::InvalidArgument +pub radroots_signing::error::Kind::SignerCancelled +pub radroots_signing::error::Kind::SignerCapabilityMissing +pub radroots_signing::error::Kind::SignerOutputInvalid +pub radroots_signing::error::Kind::SignerRejected +pub radroots_signing::error::Kind::SignerTimeout +pub radroots_signing::error::Kind::SignerUnavailable +impl radroots_signing::error::Kind +pub const radroots_signing::error::Kind::ALL: &'static [Self] +pub const fn radroots_signing::error::Kind::descriptor(self) -> radroots_signing::error::Descriptor +pub struct radroots_signing::error::Descriptor +impl radroots_signing::error::Descriptor +pub const fn radroots_signing::error::Descriptor::class(self) -> radroots_protocol::error::v1::Class +pub const fn radroots_signing::error::Descriptor::code(self) -> &'static str +pub const fn radroots_signing::error::Descriptor::kind(self) -> radroots_signing::error::Kind +pub const fn radroots_signing::error::Descriptor::known_code(self) -> radroots_protocol::error::v1::KnownCode +pub const fn radroots_signing::error::Descriptor::message(self) -> &'static str +pub const fn radroots_signing::error::Descriptor::recovery_actions(self) -> &'static [radroots_protocol::error::v1::RecoveryAction] +pub const fn radroots_signing::error::Descriptor::retryable(self) -> bool +pub struct radroots_signing::error::Error +impl radroots_signing::error::Error +pub const fn radroots_signing::error::Error::class(&self) -> radroots_protocol::error::v1::Class +pub const fn radroots_signing::error::Error::code(&self) -> &'static str +pub const fn radroots_signing::error::Error::descriptor(&self) -> radroots_signing::error::Descriptor +pub const fn radroots_signing::error::Error::kind(&self) -> radroots_signing::error::Kind +pub const fn radroots_signing::error::Error::new(radroots_signing::error::Kind) -> Self +pub const fn radroots_signing::error::Error::recovery_actions(&self) -> &'static [radroots_protocol::error::v1::RecoveryAction] +pub const fn radroots_signing::error::Error::retryable(&self) -> bool +pub fn radroots_signing::error::Error::to_report(&self, core::option::Option<radroots_protocol::runtime::v1::OperationId>) -> radroots_protocol::error::v1::ErrorReport +pub fn radroots_signing::error::Error::with_source<E>(radroots_signing::error::Kind, E) -> Self where E: core::error::Error + core::marker::Send + core::marker::Sync + 'static +impl core::convert::From<&radroots_signing::error::Error> for radroots_protocol::error::v1::ErrorReport +pub fn radroots_protocol::error::v1::ErrorReport::from(&radroots_signing::error::Error) -> Self +impl core::error::Error for radroots_signing::error::Error +pub fn radroots_signing::error::Error::source(&self) -> core::option::Option<&(dyn core::error::Error + 'static)> +impl core::fmt::Debug for radroots_signing::error::Error +pub fn radroots_signing::error::Error::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result +impl core::fmt::Display for radroots_signing::error::Error +pub fn radroots_signing::error::Error::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result +pub const radroots_signing::error::CATALOG: &[radroots_signing::error::Descriptor] +pub mod radroots_signing::receipt +#[non_exhaustive] pub struct radroots_signing::receipt::SignReceipt +impl radroots_signing::receipt::SignReceipt +pub const fn radroots_signing::receipt::SignReceipt::completed_at_unix(&self) -> u64 +pub fn radroots_signing::receipt::SignReceipt::from_signed_event(&radroots_signing::request::SignRequest, radroots_event::draft::SignedEvent, u64) -> core::result::Result<Self, radroots_signing::error::Error> +pub const fn radroots_signing::receipt::SignReceipt::operation_id(&self) -> radroots_protocol::runtime::v1::OperationId +pub const fn radroots_signing::receipt::SignReceipt::signed_event(&self) -> &radroots_event::draft::SignedEvent +impl core::fmt::Debug for radroots_signing::receipt::SignReceipt +pub fn radroots_signing::receipt::SignReceipt::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result +pub mod radroots_signing::request +#[non_exhaustive] pub enum radroots_signing::request::CancellationPolicy +pub radroots_signing::request::CancellationPolicy::LocalCooperative +pub radroots_signing::request::CancellationPolicy::PreservePublishedRequest +#[non_exhaustive] pub struct radroots_signing::request::SignPolicy +impl radroots_signing::request::SignPolicy +pub const fn radroots_signing::request::SignPolicy::cancellation(self) -> radroots_signing::request::CancellationPolicy +pub const fn radroots_signing::request::SignPolicy::deadline_unix(self) -> u64 +pub const fn radroots_signing::request::SignPolicy::new(u64, radroots_signing::request::CancellationPolicy) -> core::result::Result<Self, radroots_signing::error::Error> +pub struct radroots_signing::request::SignRequest +impl radroots_signing::request::SignRequest +pub const fn radroots_signing::request::SignRequest::actor(&self) -> &radroots_signing::actor::Actor +pub const fn radroots_signing::request::SignRequest::draft(&self) -> &radroots_event::draft::EventDraft +pub fn radroots_signing::request::SignRequest::new(radroots_protocol::runtime::v1::OperationId, radroots_signing::actor::Actor, radroots_event::draft::EventDraft, radroots_signing::request::SignPolicy) -> core::result::Result<Self, radroots_signing::error::Error> +pub const fn radroots_signing::request::SignRequest::operation_id(&self) -> radroots_protocol::runtime::v1::OperationId +pub const fn radroots_signing::request::SignRequest::policy(&self) -> radroots_signing::request::SignPolicy +pub fn radroots_signing::request::SignRequest::report_progress(&self, &radroots_signing::status::SignProgress) +pub fn radroots_signing::request::SignRequest::with_progress_observer(self, alloc::sync::Arc<dyn radroots_signing::request::ProgressObserver>) -> Self +impl core::fmt::Debug for radroots_signing::request::SignRequest +pub fn radroots_signing::request::SignRequest::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result +pub trait radroots_signing::request::ProgressObserver: core::marker::Send + core::marker::Sync +pub fn radroots_signing::request::ProgressObserver::on_progress(&self, &radroots_signing::status::SignProgress) +pub mod radroots_signing::signer +pub trait radroots_signing::signer::Signer: core::marker::Send + core::marker::Sync +pub fn radroots_signing::signer::Signer::sign(&self, radroots_signing::request::SignRequest) -> radroots_signing::signer::BoxFuture<'_, core::result::Result<radroots_signing::receipt::SignReceipt, radroots_signing::error::Error>> +pub fn radroots_signing::signer::Signer::status(&self) -> radroots_signing::signer::BoxFuture<'_, core::result::Result<radroots_signing::status::SignerStatus, radroots_signing::error::Error>> +pub type radroots_signing::signer::BoxFuture<'a, T> = core::pin::Pin<alloc::boxed::Box<(dyn core::future::future::Future<Output = T> + core::marker::Send + 'a)>> +pub mod radroots_signing::status +#[non_exhaustive] pub enum radroots_signing::status::SignProgressStage +pub radroots_signing::status::SignProgressStage::AwaitingAuthentication +pub radroots_signing::status::SignProgressStage::AwaitingSignature +pub radroots_signing::status::SignProgressStage::Complete +pub radroots_signing::status::SignProgressStage::Queued +pub radroots_signing::status::SignProgressStage::RequestPublished +pub radroots_signing::status::SignProgressStage::Validating +pub radroots_signing::status::SignProgressStage::VerifyingOutput +#[non_exhaustive] pub enum radroots_signing::status::SignerAvailability +pub radroots_signing::status::SignerAvailability::AwaitingAuthentication +pub radroots_signing::status::SignerAvailability::Busy +pub radroots_signing::status::SignerAvailability::Ready +pub radroots_signing::status::SignerAvailability::Unavailable +#[non_exhaustive] pub struct radroots_signing::status::AuthChallenge +impl radroots_signing::status::AuthChallenge +pub const fn radroots_signing::status::AuthChallenge::expires_at_unix(&self) -> core::option::Option<u64> +pub fn radroots_signing::status::AuthChallenge::new(impl core::convert::Into<alloc::string::String>, u64, core::option::Option<u64>) -> core::result::Result<Self, radroots_signing::error::Error> +pub const fn radroots_signing::status::AuthChallenge::required_at_unix(&self) -> u64 +pub fn radroots_signing::status::AuthChallenge::uri(&self) -> &str +impl core::fmt::Debug for radroots_signing::status::AuthChallenge +pub fn radroots_signing::status::AuthChallenge::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result +impl<'de> serde_core::de::Deserialize<'de> for radroots_signing::status::AuthChallenge +pub fn radroots_signing::status::AuthChallenge::deserialize<D>(D) -> core::result::Result<Self, <D as serde_core::de::Deserializer>::Error> where D: serde_core::de::Deserializer<'de> +#[non_exhaustive] pub struct radroots_signing::status::SignProgress +impl radroots_signing::status::SignProgress +pub const fn radroots_signing::status::SignProgress::authentication(radroots_signing::status::AuthChallenge) -> Self +pub const fn radroots_signing::status::SignProgress::challenge(&self) -> core::option::Option<&radroots_signing::status::AuthChallenge> +pub const fn radroots_signing::status::SignProgress::stage(radroots_signing::status::SignProgressStage) -> core::result::Result<Self, radroots_signing::error::Error> +pub const fn radroots_signing::status::SignProgress::stage_value(&self) -> radroots_signing::status::SignProgressStage +impl<'de> serde_core::de::Deserialize<'de> for radroots_signing::status::SignProgress +pub fn radroots_signing::status::SignProgress::deserialize<D>(D) -> core::result::Result<Self, <D as serde_core::de::Deserializer>::Error> where D: serde_core::de::Deserializer<'de> +#[non_exhaustive] pub struct radroots_signing::status::SignerStatus +impl radroots_signing::status::SignerStatus +pub const fn radroots_signing::status::SignerStatus::availability(&self) -> radroots_signing::status::SignerAvailability +pub fn radroots_signing::status::SignerStatus::capabilities(&self) -> &[radroots_signing::capability::SignerCapability] +pub fn radroots_signing::status::SignerStatus::new(radroots_signing::status::SignerAvailability, alloc::vec::Vec<radroots_signing::capability::SignerCapability>, core::option::Option<radroots_signing::status::SignProgress>) -> Self +pub const fn radroots_signing::status::SignerStatus::progress(&self) -> core::option::Option<&radroots_signing::status::SignProgress> +pub const fn radroots_signing::status::SignerStatus::unavailable() -> Self +pub struct radroots_signing::Actor +impl radroots_signing::actor::Actor +pub const fn radroots_signing::actor::Actor::account_id(&self) -> core::option::Option<radroots_identity::account::AccountId> +pub fn radroots_signing::actor::Actor::from_public_key_hex<I>(&str, radroots_signing::actor::ActorSource, I) -> core::result::Result<Self, radroots_signing::error::Error> where I: core::iter::traits::collect::IntoIterator<Item = radroots_event::contract::registry_v7::AuthorRole> +pub fn radroots_signing::actor::Actor::new<I>(radroots_identity::key::PublicKey, radroots_signing::actor::ActorSource, I) -> core::result::Result<Self, radroots_signing::error::Error> where I: core::iter::traits::collect::IntoIterator<Item = radroots_event::contract::registry_v7::AuthorRole> +pub const fn radroots_signing::actor::Actor::public_key(&self) -> radroots_identity::key::PublicKey +pub const fn radroots_signing::actor::Actor::roles(&self) -> &alloc::collections::btree::set::BTreeSet<radroots_event::contract::registry_v7::AuthorRole> +pub fn radroots_signing::actor::Actor::satisfies(&self, radroots_event::contract::registry_v7::AuthorRole) -> bool +pub const fn radroots_signing::actor::Actor::source(&self) -> radroots_signing::actor::ActorSource +pub struct radroots_signing::Error +impl radroots_signing::error::Error +pub const fn radroots_signing::error::Error::class(&self) -> radroots_protocol::error::v1::Class +pub const fn radroots_signing::error::Error::code(&self) -> &'static str +pub const fn radroots_signing::error::Error::descriptor(&self) -> radroots_signing::error::Descriptor +pub const fn radroots_signing::error::Error::kind(&self) -> radroots_signing::error::Kind +pub const fn radroots_signing::error::Error::new(radroots_signing::error::Kind) -> Self +pub const fn radroots_signing::error::Error::recovery_actions(&self) -> &'static [radroots_protocol::error::v1::RecoveryAction] +pub const fn radroots_signing::error::Error::retryable(&self) -> bool +pub fn radroots_signing::error::Error::to_report(&self, core::option::Option<radroots_protocol::runtime::v1::OperationId>) -> radroots_protocol::error::v1::ErrorReport +pub fn radroots_signing::error::Error::with_source<E>(radroots_signing::error::Kind, E) -> Self where E: core::error::Error + core::marker::Send + core::marker::Sync + 'static +impl core::convert::From<&radroots_signing::error::Error> for radroots_protocol::error::v1::ErrorReport +pub fn radroots_protocol::error::v1::ErrorReport::from(&radroots_signing::error::Error) -> Self +impl core::error::Error for radroots_signing::error::Error +pub fn radroots_signing::error::Error::source(&self) -> core::option::Option<&(dyn core::error::Error + 'static)> +impl core::fmt::Debug for radroots_signing::error::Error +pub fn radroots_signing::error::Error::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result +impl core::fmt::Display for radroots_signing::error::Error +pub fn radroots_signing::error::Error::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result +#[non_exhaustive] pub struct radroots_signing::SignReceipt +impl radroots_signing::receipt::SignReceipt +pub const fn radroots_signing::receipt::SignReceipt::completed_at_unix(&self) -> u64 +pub fn radroots_signing::receipt::SignReceipt::from_signed_event(&radroots_signing::request::SignRequest, radroots_event::draft::SignedEvent, u64) -> core::result::Result<Self, radroots_signing::error::Error> +pub const fn radroots_signing::receipt::SignReceipt::operation_id(&self) -> radroots_protocol::runtime::v1::OperationId +pub const fn radroots_signing::receipt::SignReceipt::signed_event(&self) -> &radroots_event::draft::SignedEvent +impl core::fmt::Debug for radroots_signing::receipt::SignReceipt +pub fn radroots_signing::receipt::SignReceipt::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result +pub struct radroots_signing::SignRequest +impl radroots_signing::request::SignRequest +pub const fn radroots_signing::request::SignRequest::actor(&self) -> &radroots_signing::actor::Actor +pub const fn radroots_signing::request::SignRequest::draft(&self) -> &radroots_event::draft::EventDraft +pub fn radroots_signing::request::SignRequest::new(radroots_protocol::runtime::v1::OperationId, radroots_signing::actor::Actor, radroots_event::draft::EventDraft, radroots_signing::request::SignPolicy) -> core::result::Result<Self, radroots_signing::error::Error> +pub const fn radroots_signing::request::SignRequest::operation_id(&self) -> radroots_protocol::runtime::v1::OperationId +pub const fn radroots_signing::request::SignRequest::policy(&self) -> radroots_signing::request::SignPolicy +pub fn radroots_signing::request::SignRequest::report_progress(&self, &radroots_signing::status::SignProgress) +pub fn radroots_signing::request::SignRequest::with_progress_observer(self, alloc::sync::Arc<dyn radroots_signing::request::ProgressObserver>) -> Self +impl core::fmt::Debug for radroots_signing::request::SignRequest +pub fn radroots_signing::request::SignRequest::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result +#[non_exhaustive] pub struct radroots_signing::SignerStatus +impl radroots_signing::status::SignerStatus +pub const fn radroots_signing::status::SignerStatus::availability(&self) -> radroots_signing::status::SignerAvailability +pub fn radroots_signing::status::SignerStatus::capabilities(&self) -> &[radroots_signing::capability::SignerCapability] +pub fn radroots_signing::status::SignerStatus::new(radroots_signing::status::SignerAvailability, alloc::vec::Vec<radroots_signing::capability::SignerCapability>, core::option::Option<radroots_signing::status::SignProgress>) -> Self +pub const fn radroots_signing::status::SignerStatus::progress(&self) -> core::option::Option<&radroots_signing::status::SignProgress> +pub const fn radroots_signing::status::SignerStatus::unavailable() -> Self +pub trait radroots_signing::Signer: core::marker::Send + core::marker::Sync +pub fn radroots_signing::Signer::sign(&self, radroots_signing::request::SignRequest) -> radroots_signing::signer::BoxFuture<'_, core::result::Result<radroots_signing::receipt::SignReceipt, radroots_signing::error::Error>> +pub fn radroots_signing::Signer::status(&self) -> radroots_signing::signer::BoxFuture<'_, core::result::Result<radroots_signing::status::SignerStatus, radroots_signing::error::Error>>