Skip to main content

Purse

Struct Purse 

Source
pub struct Purse<S: Store = FileStore> { /* private fields */ }
Expand description

A Holder connected to a server and a Store: it reads mint info itself, submits transfers at their scheduled times, retries what failed on the way, and saves after every change.

Nothing that depends on a change leaves the purse before the change is saved: a payment request’s keys are saved before the request is returned, and the spent notes and change keys of a payment before the payment is. If a save fails, the change is undone and the call fails.

Methods take &self, so one purse can be shared between tasks; a refresh waiting for its schedule does not block payments. The holder is locked only while it changes, never across a request.

Several processes can share one store too. Before each change the purse takes the store’s lock and reads the holder saved there, makes the change to that, and saves before letting go, so a note another process took in meanwhile is kept, not saved over. Reads such as holder show the holder as this purse last read or saved it.

Implementations§

Source§

impl Purse<FileStore>

Source

pub fn open(client: Client, path: impl Into<PathBuf>) -> Result<Self, Error>

A purse saved in the file at path, created on the first save if it does not exist yet.

Source§

impl<S: Store> Purse<S>

Source

pub fn new(client: Client, holder: Holder, store: S) -> Self

A purse holding holder, talking to client and saving to store.

Source

pub fn with_retry(self, retry: Retry) -> Self

Sets how failed transfers are retried.

Source

pub fn client(&self) -> &Client

The client requests go through.

Source

pub fn store(&self) -> &S

The store saves go to.

Source

pub fn holder(&self) -> Holder

A copy of the holder as it is now.

Source

pub async fn balance(&self, mint: &PublicKey) -> Result<Balance, Error>

Value held at mint, by what it can do now, from the mint’s info.

Source

pub async fn request( &self, mint: &PublicKey, amount: u64, ) -> Result<PaymentRequest, Error>

Asks for amount from mint: a payment request with a fresh key per note, saved before it is returned. Send it to the payer.

Source

pub async fn request_at_most( &self, mint: &PublicKey, amount: u64, largest: u64, ) -> Result<PaymentRequest, Error>

Like request, in notes of at most largest, for a payer whose notes are small.

Source

pub async fn take_from_faucet( &self, faucet: &Client, ) -> Result<(PublicKey, u128), Error>

Asks a playground faucet for a note and keeps it. The faucet’s mint must be on this purse’s server; the faucet may share its URL. The note goes to a fresh key, saved before the faucet is asked, as for any payment request. Returns the faucet’s mint and the value kept.

Source

pub fn withdraw(&self, request: &PaymentRequest) -> Result<(), Error>

Stops expecting the notes of a request that will not be paid.

Source

pub async fn pay( &self, request: &PaymentRequest, spacing: Spacing, ) -> Result<Payment, Error>

Answers a payment request, after reading the mint’s info. The notes spent, the keys for the change and the payment itself (see Holder::payments) are saved before the payment is returned. Send it to the payee, who submits it and can hand back the change for accept; or settle later to take it in. A request for a note the mint would not make, or to a key this purse has paid already, is refused before anything is signed (see Holder::pay).

Source

pub fn cancel(&self, request: &TransferRequest) -> Result<bool, Error>

Takes back the note of an outgoing transfer the mint never applied, keeping the keys of its change in case it did, and saves (see Holder::cancel). Returns whether the transfer was outgoing.

A payee that holds the transfer can still submit it: if the mint applies it, or already had, the payee’s notes and the note taken back claim the same value, and the mint refuses whichever is spent second.

Source

pub fn forget(&self, request: &TransferRequest) -> Result<bool, Error>

Drops an outgoing transfer whose note is gone, keeping the keys of its change so that change handed over later is still taken in, and saves (see Holder::forget). Returns whether the transfer was outgoing.

Source

pub fn forget_owed(&self, notes: &[Note]) -> Result<u128, Error>

Stops keeping notes owed to payees, once they are handed over, and saves (see Holder::forget_owed). The notes of a payment are in Holder::payments: write them where the payee gets them, then forget them. Returns the value it stopped keeping.

Source

pub async fn receive( &self, request: &PaymentRequest, payment: &Payment, ) -> Result<Submitted, Error>

Takes a payment for request: checks that it pays what was asked, then submits each transfer at its time and takes in the notes. Returns once the last transfer is answered or refused. The payer chose the times; wrap the call in a timeout to bound the wait. Hand Submitted::theirs, the payer’s change, back to the payer.

Source

pub async fn accept(&self, notes: &[Note]) -> Result<u128, Error>

Takes in notes the counterparty handed over from the mint’s answers, after checking each one’s signature against its mint’s keys, and settles the outgoing transfers they answer (see Holder::take_answers). Notes for keys this purse never handed out are ignored. A note whose layer the mint has dropped no longer verifies and fails the call. Returns the value taken in.

The signatures show that the mint issued the notes, not that it applied the transfers they settle: a counterparty could pay the same keys from notes of its own (see Holder::take_answers).

Source

pub async fn settle(&self, spacing: Spacing) -> Result<Submitted, Error>

Resends the transfers this purse made and has not seen answered, at random gaps of spacing, and takes in their change. Call it once a payee has had time to submit a payment, or after a restart. Planned refreshes still waiting for their time are resent too. The answer to a payment’s transfer keeps the payee’s notes for it, in case the payee has not submitted the payment and the resend carried it out (see MadePayment::owed), and a transfer refused for good is dropped or cancelled (see Refused::outcome).

The mint answers a resent transfer with the same notes only while it keeps its answer, and at the latest until the notes it issued expire (see Error codes). After that, a transfer already applied is refused as spent or expired, with Refused::at_stake set, and its change can only come from the counterparty, for accept. refresh resends the transfers whose chance the next rotation ends.

Source

pub async fn plan_refresh( &self, mint: &PublicKey, ) -> Result<Vec<ScheduledTransfer>, Error>

Plans the refresh of mint’s notes that die at the next rotation, after reading its info, and saves the plan. The outgoing transfers to resend before that rotation join it (see Holder::due_resends); if the save fails, only the refreshes are undone. Submit the transfers at their times with submit.

The times are planned by the server’s clock, from the Date of its info answer (Client::view_and_time), so this machine’s clock, slow or fast, moves none of them past the rotation. When the answer has no Date, they are planned by this machine’s clock instead. Once the rotation’s time has come and the mint has not made it yet, they are all due at once.

Source

pub async fn refresh(&self, mint: &PublicKey) -> Result<Submitted, Error>

Refreshes mint’s notes that die at the next rotation and resends the outgoing transfers that must land before it: plans the transfers with plan_refresh and submits each at its random time before the rotation. Returns once the last one is done, which may be most of a rotation period away; run it in a task of its own.

Source

pub async fn prune(&self, mint: &PublicKey) -> Result<u128, Error>

Drops mint’s notes whose layer was dropped, after reading its info, and returns the value lost. It also stops waiting for unconfirmed change that would sit in a dropped layer, and stops keeping notes owed to payees once their layer is dropped (see Holder::prune). The info alone decides, not this machine’s clock: a note goes, with its key, only once the mint has dropped its layer.

Source

pub async fn submit( &self, transfers: &[ScheduledTransfer], ) -> Result<Submitted, Error>

Submits each transfer at its time, counted from now, retrying failures on the way, and records each answer: the transfer stops being outgoing and the notes for this purse are taken in, and the payee’s notes are kept for it when the transfer is part of a payment this purse made (see Holder::settle). A payer that submits its own payment hands them to the payee from Submitted::theirs, then calls forget_owed with them, as worgl submit does.

A refused transfer does not stop the others; it is listed in Submitted::refused. One this purse made that the mint refused for good is dropped or cancelled (Refused::outcome); the rest stay outgoing. To confirm a policy refusal, the purse reads the mint’s info again. The call fails only if a save does.

Trait Implementations§

Source§

impl<S: Debug + Store> Debug for Purse<S>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<S = FileStore> !Freeze for Purse<S>

§

impl<S = FileStore> !RefUnwindSafe for Purse<S>

§

impl<S = FileStore> !UnwindSafe for Purse<S>

§

impl<S> Send for Purse<S>

§

impl<S> Sync for Purse<S>

§

impl<S> Unpin for Purse<S>
where S: Unpin,

§

impl<S> UnsafeUnpin for Purse<S>
where S: UnsafeUnpin,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

§

impl<T> PolicyExt for T
where T: ?Sized,

§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns [Action::Follow] only if self and other return Action::Follow. Read more
§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns [Action::Follow] if either self or other returns Action::Follow. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more