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<S: Store> Purse<S>
impl<S: Store> Purse<S>
Sourcepub fn new(client: Client, holder: Holder, store: S) -> Self
pub fn new(client: Client, holder: Holder, store: S) -> Self
A purse holding holder, talking to client and saving to store.
Sourcepub fn with_retry(self, retry: Retry) -> Self
pub fn with_retry(self, retry: Retry) -> Self
Sets how failed transfers are retried.
Sourcepub async fn balance(&self, mint: &PublicKey) -> Result<Balance, Error>
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.
Sourcepub async fn request(
&self,
mint: &PublicKey,
amount: u64,
) -> Result<PaymentRequest, Error>
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.
Sourcepub async fn request_at_most(
&self,
mint: &PublicKey,
amount: u64,
largest: u64,
) -> Result<PaymentRequest, Error>
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.
Sourcepub async fn take_from_faucet(
&self,
faucet: &Client,
) -> Result<(PublicKey, u128), Error>
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.
Sourcepub fn withdraw(&self, request: &PaymentRequest) -> Result<(), Error>
pub fn withdraw(&self, request: &PaymentRequest) -> Result<(), Error>
Stops expecting the notes of a request that will not be paid.
Sourcepub async fn pay(
&self,
request: &PaymentRequest,
spacing: Spacing,
) -> Result<Payment, Error>
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).
Sourcepub fn cancel(&self, request: &TransferRequest) -> Result<bool, Error>
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.
Sourcepub fn forget(&self, request: &TransferRequest) -> Result<bool, Error>
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.
Sourcepub fn forget_owed(&self, notes: &[Note]) -> Result<u128, Error>
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.
Sourcepub async fn receive(
&self,
request: &PaymentRequest,
payment: &Payment,
) -> Result<Submitted, Error>
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.
Sourcepub async fn accept(&self, notes: &[Note]) -> Result<u128, Error>
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).
Sourcepub async fn settle(&self, spacing: Spacing) -> Result<Submitted, Error>
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.
Sourcepub async fn plan_refresh(
&self,
mint: &PublicKey,
) -> Result<Vec<ScheduledTransfer>, Error>
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.
Sourcepub async fn refresh(&self, mint: &PublicKey) -> Result<Submitted, Error>
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.
Sourcepub async fn prune(&self, mint: &PublicKey) -> Result<u128, Error>
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.
Sourcepub async fn submit(
&self,
transfers: &[ScheduledTransfer],
) -> Result<Submitted, Error>
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.