worgl_client/lib.rs
1//! Talks to a [Worgl](worgl) server over HTTP.
2//!
3//! Two layers:
4//!
5//! - [`Client`] makes one typed call per route of `worgl-server`: mint info
6//! and keys, verify, transfer, burn, mint, and the mint admin's rotate,
7//! pause and resume, and the two routes of a playground faucet. Errors
8//! keep the mint's stable code, such as `spent` or `frozen`, in
9//! [`Error::code`].
10//! - [`Purse`] puts a [`worgl_sdk::Holder`] on top: it reads mint info by
11//! itself, submits transfers at the random times the holder gives them,
12//! retries what failed on the way, and saves the holder to a [`Store`]
13//! after every change, before anything that depends on it is handed out.
14//!
15//! The privacy rules come from the holder: a fresh key for every note, one
16//! note per transfer, and transfers of one payment, refreshes and resends
17//! spread out in time.
18//!
19//! # A payment
20//!
21//! ```no_run
22//! # async fn run(mint: worgl::PublicKey) -> Result<(), worgl_client::Error> {
23//! use worgl_client::{Client, Purse};
24//! use worgl_sdk::Spacing;
25//!
26//! let client = Client::new("https://mint.example.com")?;
27//! let alice = Purse::open(client.clone(), "alice.json")?;
28//! let bob = Purse::open(client, "bob.json")?;
29//!
30//! // Bob asks for 5 and sends the request to Alice.
31//! let request = bob.request(&mint, 5).await?;
32//! // Alice answers with signed transfers and sends them to Bob.
33//! let payment = alice.pay(&request, Spacing::default()).await?;
34//! // Bob checks them, submits each at its time and keeps the notes.
35//! let received = bob.receive(&request, &payment).await?;
36//! assert_eq!(received.value, 5);
37//! // Bob sends Alice the rest of the answers, her change, and she keeps it.
38//! alice.accept(&received.theirs).await?;
39//! # Ok(())
40//! # }
41//! ```
42//!
43//! Without the change from Bob, Alice would [`settle`](Purse::settle):
44//! resend her transfers, which the mint answers with the same notes while
45//! it keeps its answers. If Bob had not submitted the payment, her resend
46//! carries it out. She cannot tell, so she keeps his notes from every
47//! answer for him (see [`Holder::payments`](worgl_sdk::Holder::payments))
48//! until she hands them over ([`Purse::forget_owed`]) or
49//! [prunes](Purse::prune) them once they expire. A transfer the mint
50//! refuses for good is dropped or cancelled ([`Refused::outcome`]).
51//!
52//! Either side may submit a payment. When the payer does, with
53//! [`Purse::submit`], it hands the payee's notes from the answers,
54//! [`Submitted::theirs`], to the payee, who takes them in with
55//! [`Purse::accept`], and then stops keeping them with
56//! [`Purse::forget_owed`].
57//!
58//! Requests run on Tokio. TLS is rustls with the platform's certificate
59//! roots.
60
61mod client;
62mod error;
63mod purse;
64mod store;
65
66pub use client::{Client, FaucetInfo, Info, Verified};
67pub use error::{Error, Refusal};
68pub use purse::{MAX_DELAY_SECS, Outcome, Purse, Refused, Retry, Submitted};
69pub use store::{FileLock, FileStore, Locked, MemoryStore, Store};