Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce persistence as a first class abstraction in payjoin crate #477

Open
nothingmuch opened this issue Jan 14, 2025 · 0 comments
Open

Comments

@nothingmuch
Copy link
Collaborator

nothingmuch commented Jan 14, 2025

The payjoin crate provides pure functions and a state machine for handling payjoins, but does not actually send OHTTP requests, or manipulate any wallet data.

The payjoin-cli crate demonstrates how to integrate this (specifically with bitcoin core's RPC api). Due to the async nature of v2 payjoins, the state machine is persisted by payjoin-cli (which includes resume command).

Unfortunately this leaks implementation details and domain knowledge: although the payjoin crate defines the state machine, wallet integrations need to know what to serialize, and when & how it is appropriate to do so.

If instead the payjoin crate defined a trait (or two, or four, for separating {v1,v2} x {sender, receiver}) for the abstract serialization, which defines what data is stored and under what key, but not the details of how, along with a contract for this trait (namely that once an impl returns from a storage operation, the data is assumed to be in durable storage, and that writes are atomic and consistent), integrations would only be burdened with correctly implementing the storage primitives, without needing to understand how and when to use them with respect to the payjoin state machines.

It's not clear to me if the arguments and return values of the methods of this trait(s) should be serializable value types defined by the payjoin crate, or just serde based trait bounds. Having concrete types would ensure that any changes to what is serialized can be dealt with, using semver breaking changes when it is appropriate to do so, so seems safer, but potentially an increase integrator burden. Using trait bounds would require the payjoin crate to explicitly handle the moral equivalent of database migrations in its types, i.e. whatever type is used to deserialize should be able to handle serialized representations of all past versions of that type, which seems a bit risky but would simplify the API.

See also #336

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: No status
Development

No branches or pull requests

1 participant