Skip to main content

sim/runtime/
watch.rs

1//! Watch SDK facade, modeled install helper, and cookbook proof callables.
2//!
3//! The facade stays thin: it installs the shared device stream base, the worn
4//! stream library, and a small host-registered SDK lib that exposes
5//! hardware-free proofs over the landed watch contracts.
6
7use std::sync::Arc;
8
9use sim_kernel::{
10    AbiVersion, Cx, Dependency, Export, Lib, LibManifest, LibTarget, Linker, Result, Symbol,
11    Version,
12};
13
14#[cfg(feature = "cookbook")]
15mod cookbook;
16mod proof_functions;
17mod proofs;
18
19#[cfg(feature = "cookbook")]
20pub use cookbook::RECIPES;
21use proof_functions::{ProofKind, WatchProofFunction, proof_function_symbol};
22pub use proofs::{
23    DualQuorumProof, GlancePagerProof, HoldLastProof, PrivacyReaperProof, prove_dual_quorum,
24    prove_glance_pager, prove_hold_last, prove_privacy_reaper,
25};
26
27/// SDK install mode for the watch stack.
28#[derive(Clone, Copy, Debug, PartialEq, Eq)]
29pub enum WatchInstallMode {
30    /// Deterministic modeled sources only.
31    Modeled,
32    /// Include the hardware provider bridge when the feature is enabled.
33    Hardware,
34}
35
36/// Host-registered lib that exposes watch cookbook proof callables.
37pub struct WatchStackLib;
38
39impl Lib for WatchStackLib {
40    fn manifest(&self) -> LibManifest {
41        LibManifest {
42            id: watch_stack_manifest_symbol(),
43            version: Version(env!("CARGO_PKG_VERSION").to_owned()),
44            abi: AbiVersion { major: 0, minor: 1 },
45            target: LibTarget::HostRegistered,
46            requires: vec![Dependency {
47                id: sim_lib_stream_wrist::wrist_stream_manifest_symbol(),
48                minimum_version: None,
49            }],
50            capabilities: Vec::new(),
51            exports: ProofKind::ALL
52                .into_iter()
53                .map(|kind| Export::Value {
54                    symbol: proof_function_symbol(kind),
55                })
56                .collect(),
57        }
58    }
59
60    fn load(&self, cx: &mut sim_kernel::LoadCx, linker: &mut Linker<'_>) -> Result<()> {
61        for kind in ProofKind::ALL {
62            linker.value(
63                proof_function_symbol(kind),
64                cx.factory().opaque(Arc::new(WatchProofFunction { kind }))?,
65            )?;
66        }
67        Ok(())
68    }
69}
70
71/// Installs the modeled watch SDK stack into a context.
72pub fn install_watch_stack(cx: &mut Cx, mode: WatchInstallMode) -> Result<()> {
73    sim_lib_stream_wrist::install_wrist_stream_lib(cx)?;
74    if mode == WatchInstallMode::Hardware {
75        ensure_hardware_feature()?;
76    }
77    sim_lib_core::install_once(cx, &WatchStackLib)?;
78    Ok(())
79}
80
81/// Returns the manifest id for the watch SDK facade.
82pub fn watch_stack_manifest_symbol() -> Symbol {
83    Symbol::qualified("watch", "sdk")
84}
85
86/// Reads a boolean field from a proof expression.
87#[cfg(test)]
88pub(crate) fn bool_field(expr: &sim_kernel::Expr, field: &'static str) -> bool {
89    sim_value::access::field_bool(expr, field).unwrap_or(false)
90}
91
92#[cfg(feature = "watch-hardware")]
93fn ensure_hardware_feature() -> Result<()> {
94    let _provider = sim_lib_stream_wristbridge::watch_stub_provider();
95    Ok(())
96}
97
98#[cfg(not(feature = "watch-hardware"))]
99fn ensure_hardware_feature() -> Result<()> {
100    Err(sim_kernel::Error::Eval(
101        "watch hardware install requires the watch-hardware feature".to_owned(),
102    ))
103}