pub fn shared_store<S: LeafStore + 'static>(store: S) -> SharedStoreExpand description
Wraps a store in the handle a LeafDevice takes.
use offline_protocol_leaf::{shared_store, LeafDevice, MemoryStore};
let device = LeafDevice::open(shared_store(MemoryStore::new()), "com.example.lock")?;Examples found in repository?
examples/wasi_host_shim.rs (line 123)
112fn run() -> Result<(), String> {
113 let args: Vec<String> = std::env::args().skip(1).collect();
114 let [app_id, peer, now] = args.as_slice() else {
115 return Err(USAGE.to_string());
116 };
117 let now_unix_secs: u64 = now
118 .parse()
119 .map_err(|_| format!("now_unix_secs must be a whole number of seconds, got {now:?}"))?;
120
121 // `shared_store` rather than `Arc::new`: it is the one constructor that
122 // builds on every target the crate supports, so it is the route to copy.
123 let store = shared_store(MemoryStore::new());
124
125 // Provisioning draws from the getrandom backend the target selects. On
126 // WASI that is the runtime's `random_get`; see the header.
127 let mut device =
128 LeafDevice::open(store, app_id).map_err(|error| format!("opening the device: {error}"))?;
129 eprintln!("address {}", device.address());
130
131 let stdout = io::stdout();
132 let mut out = stdout.lock();
133
134 // Pairing starts with the device's key package. The time is supplied, not
135 // read: with `now_unix_secs` the package's validity window is real, and
136 // without it the library would stamp 1970.
137 let advertisement = device
138 .key_package_frame(peer, now_unix_secs)
139 .map_err(|error| format!("minting the key package: {error}"))?;
140 emit(&mut out, &advertisement)?;
141
142 // Steady state: frames arrive, the device verifies each, opens it if it is
143 // sealed, persists, and only then hands back what it owes in reply.
144 for (index, line) in io::stdin().lock().lines().enumerate() {
145 let line = line.map_err(|error| format!("reading standard input: {error}"))?;
146 if line.trim().is_empty() {
147 continue;
148 }
149 let inbound = Message::from_json(&line)
150 .map_err(|error| format!("line {}: not a frame: {error}", index + 1))?;
151 match device.handle(&inbound, now_unix_secs) {
152 Ok(handled) => {
153 for event in &handled.events {
154 eprintln!("event {event:?}");
155 }
156 for frame in &handled.outbound {
157 emit(&mut out, frame)?;
158 }
159 }
160 Err(error) => eprintln!("line {}: refused: {error}", index + 1),
161 }
162 }
163
164 // Answering. The persist is inside `seal`, before it returns anything, so
165 // there is no ordering here to get wrong. Without the phone's Welcome
166 // there is no session, and the crate says so rather than sealing into a
167 // group that does not exist.
168 match device.seal(peer, GREETING, now_unix_secs) {
169 Ok(frame) => emit(&mut out, &frame),
170 Err(LeafError::NoSession(_)) => {
171 eprintln!(
172 "no session with {peer}: nothing sealed. A session exists only after the \
173 phone's Welcome, and no frame on standard input carried one."
174 );
175 Ok(())
176 }
177 Err(error) => Err(format!("sealing to {peer}: {error}")),
178 }
179}