Skip to content

Commit a05afa0

Browse files
committed
Rename ReceiverTypeState to ReceiveSession
It contains every possible state of a session including initialized Receiver types. Include the module `Receive` name to disambiguate the public type used in payjoin-ffi where namespacing is not yet available.
1 parent 2f3f46a commit a05afa0

File tree

6 files changed

+78
-85
lines changed

6 files changed

+78
-85
lines changed

payjoin-cli/src/app/v2/mod.rs

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ use payjoin::bitcoin::{Amount, FeeRate};
66
use payjoin::persist::OptionalTransitionOutcome;
77
use payjoin::receive::v2::{
88
process_err_res, replay_event_log as replay_receiver_event_log, Initialized, MaybeInputsOwned,
9-
MaybeInputsSeen, OutputsUnknown, PayjoinProposal, ProvisionalProposal, Receiver,
10-
ReceiverTypeState, SessionHistory, UncheckedProposal, WantsInputs, WantsOutputs,
9+
MaybeInputsSeen, OutputsUnknown, PayjoinProposal, ProvisionalProposal, ReceiveSession,
10+
Receiver, SessionHistory, UncheckedProposal, WantsInputs, WantsOutputs,
1111
};
1212
use payjoin::send::v2::{
1313
replay_event_log as replay_sender_event_log, Sender, SenderBuilder, SenderTypeState,
@@ -114,7 +114,7 @@ impl AppTrait for App {
114114
println!("Request Payjoin by sharing this Payjoin Uri:");
115115
println!("{}", pj_uri);
116116

117-
self.process_receiver_session(ReceiverTypeState::Initialized(session.clone()), &persister)
117+
self.process_receiver_session(ReceiveSession::Initialized(session.clone()), &persister)
118118
.await?;
119119
Ok(())
120120
}
@@ -282,32 +282,32 @@ impl App {
282282

283283
async fn process_receiver_session(
284284
&self,
285-
session: ReceiverTypeState,
285+
session: ReceiveSession,
286286
persister: &ReceiverPersister,
287287
) -> Result<()> {
288288
let res = {
289289
match session {
290-
ReceiverTypeState::Initialized(proposal) =>
290+
ReceiveSession::Initialized(proposal) =>
291291
self.read_from_directory(proposal, persister).await,
292-
ReceiverTypeState::UncheckedProposal(proposal) =>
292+
ReceiveSession::UncheckedProposal(proposal) =>
293293
self.check_proposal(proposal, persister).await,
294-
ReceiverTypeState::MaybeInputsOwned(proposal) =>
294+
ReceiveSession::MaybeInputsOwned(proposal) =>
295295
self.check_inputs_not_owned(proposal, persister).await,
296-
ReceiverTypeState::MaybeInputsSeen(proposal) =>
296+
ReceiveSession::MaybeInputsSeen(proposal) =>
297297
self.check_no_inputs_seen_before(proposal, persister).await,
298-
ReceiverTypeState::OutputsUnknown(proposal) =>
298+
ReceiveSession::OutputsUnknown(proposal) =>
299299
self.identify_receiver_outputs(proposal, persister).await,
300-
ReceiverTypeState::WantsOutputs(proposal) =>
300+
ReceiveSession::WantsOutputs(proposal) =>
301301
self.commit_outputs(proposal, persister).await,
302-
ReceiverTypeState::WantsInputs(proposal) =>
302+
ReceiveSession::WantsInputs(proposal) =>
303303
self.contribute_inputs(proposal, persister).await,
304-
ReceiverTypeState::ProvisionalProposal(proposal) =>
304+
ReceiveSession::ProvisionalProposal(proposal) =>
305305
self.finalize_proposal(proposal, persister).await,
306-
ReceiverTypeState::PayjoinProposal(proposal) =>
306+
ReceiveSession::PayjoinProposal(proposal) =>
307307
self.send_payjoin_proposal(proposal, persister).await,
308-
ReceiverTypeState::Uninitialized(_) =>
308+
ReceiveSession::Uninitialized(_) =>
309309
return Err(anyhow!("Uninitialized receiver session")),
310-
ReceiverTypeState::TerminalFailure =>
310+
ReceiveSession::TerminalFailure =>
311311
return Err(anyhow!("Terminal receiver session")),
312312
}
313313
};

payjoin-ffi/python/test/test_payjoin_integration_test.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ def setUpClass(cls):
6060
cls.receiver = cls.env.get_receiver()
6161
cls.sender = cls.env.get_sender()
6262

63-
async def process_receiver_proposal(self, receiver: ReceiverTypeState, recv_persister: InMemoryReceiverSessionEventLog, ohttp_relay: Url) -> Optional[ReceiverTypeState]:
63+
async def process_receiver_proposal(self, receiver: ReceiveSession, recv_persister: InMemoryReceiverSessionEventLog, ohttp_relay: Url) -> Optional[ReceiveSession]:
6464
if receiver.is_INITIALIZED():
6565
res = await self.retrieve_receiver_proposal(receiver.inner, recv_persister, ohttp_relay)
6666
if res is None:
@@ -131,7 +131,7 @@ async def process_wants_inputs(self, proposal: WantsInputs, recv_persister: InMe
131131

132132
async def process_provisional_proposal(self, proposal: ProvisionalProposal, recv_persister: InMemoryReceiverSessionEventLog):
133133
payjoin_proposal = proposal.finalize_proposal(ProcessPsbtCallback(self.receiver), 1, 10).save(recv_persister)
134-
return ReceiverTypeState.PAYJOIN_PROPOSAL(payjoin_proposal)
134+
return ReceiveSession.PAYJOIN_PROPOSAL(payjoin_proposal)
135135

136136
async def test_integration_v2_to_v2(self):
137137
try:
@@ -150,7 +150,7 @@ async def test_integration_v2_to_v2(self):
150150
recv_persister = InMemoryReceiverSessionEventLog(1)
151151
sender_persister = InMemorySenderPersister(1)
152152
session = self.create_receiver_context(receiver_address, directory, ohttp_keys, recv_persister)
153-
process_response = await self.process_receiver_proposal(ReceiverTypeState.INITIALIZED(session), recv_persister, ohttp_relay)
153+
process_response = await self.process_receiver_proposal(ReceiveSession.INITIALIZED(session), recv_persister, ohttp_relay)
154154
print(f"session: {session.to_json()}")
155155
self.assertIsNone(process_response)
156156

@@ -173,7 +173,7 @@ async def test_integration_v2_to_v2(self):
173173
# Inside the Receiver:
174174

175175
# GET fallback psbt
176-
payjoin_proposal = await self.process_receiver_proposal(ReceiverTypeState.INITIALIZED(session), recv_persister, ohttp_relay)
176+
payjoin_proposal = await self.process_receiver_proposal(ReceiveSession.INITIALIZED(session), recv_persister, ohttp_relay)
177177
self.assertIsNotNone(payjoin_proposal)
178178
self.assertEqual(payjoin_proposal.is_PAYJOIN_PROPOSAL(), True)
179179

payjoin-ffi/src/receive/mod.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,15 @@ impl From<SessionEvent> for payjoin::receive::v2::SessionEvent {
3131
fn from(event: SessionEvent) -> Self { event.0 }
3232
}
3333

34-
pub struct ReceiverTypeState(pub payjoin::receive::v2::ReceiverTypeState);
34+
pub struct ReceiveSession(pub payjoin::receive::v2::ReceiveSession);
3535

36-
impl From<payjoin::receive::v2::ReceiverTypeState> for ReceiverTypeState {
37-
fn from(value: payjoin::receive::v2::ReceiverTypeState) -> Self { Self(value) }
36+
impl From<payjoin::receive::v2::ReceiveSession> for ReceiveSession {
37+
fn from(value: payjoin::receive::v2::ReceiveSession) -> Self { Self(value) }
3838
}
3939

4040
pub fn replay_event_log<P>(
4141
persister: &P,
42-
) -> Result<(ReceiverTypeState, SessionHistory), ReceiverReplayError>
42+
) -> Result<(ReceiveSession, SessionHistory), ReceiverReplayError>
4343
where
4444
P: SessionPersister,
4545
P::SessionEvent: Into<payjoin::receive::v2::SessionEvent> + Clone,

payjoin-ffi/src/receive/uni.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ impl ReceiverSessionEvent {
3535
}
3636

3737
#[derive(Clone, uniffi::Enum)]
38-
pub enum ReceiverTypeState {
38+
pub enum ReceiveSession {
3939
Uninitialized,
4040
Initialized { inner: Arc<Initialized> },
4141
UncheckedProposal { inner: Arc<UncheckedProposal> },
@@ -49,9 +49,9 @@ pub enum ReceiverTypeState {
4949
TerminalFailure,
5050
}
5151

52-
impl From<super::ReceiverTypeState> for ReceiverTypeState {
53-
fn from(value: super::ReceiverTypeState) -> Self {
54-
use payjoin::receive::v2::ReceiverTypeState::*;
52+
impl From<super::ReceiveSession> for ReceiveSession {
53+
fn from(value: super::ReceiveSession) -> Self {
54+
use payjoin::receive::v2::ReceiveSession::*;
5555
match value.0 {
5656
Uninitialized(_) => Self::Uninitialized,
5757
Initialized(inner) =>
@@ -150,13 +150,13 @@ impl SessionHistory {
150150

151151
#[derive(uniffi::Object)]
152152
pub struct ReplayResult {
153-
state: ReceiverTypeState,
153+
state: ReceiveSession,
154154
session_history: SessionHistory,
155155
}
156156

157157
#[uniffi::export]
158158
impl ReplayResult {
159-
pub fn state(&self) -> ReceiverTypeState { self.state.clone() }
159+
pub fn state(&self) -> ReceiveSession { self.state.clone() }
160160

161161
pub fn session_history(&self) -> SessionHistory { self.session_history.clone() }
162162
}

payjoin/src/receive/v2/mod.rs

Lines changed: 37 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -83,10 +83,13 @@ fn subdir_path_from_pubkey(pubkey: &HpkePublicKey) -> ShortId {
8383
}
8484

8585
/// Represents the various states of a Payjoin receiver session during the protocol flow.
86-
/// Each variant wraps a `Receiver` with a specific state type, except for [`ReceiverTypeState::TerminalFailure`] which
87-
/// indicates the session has ended or is invalid.
86+
/// Each variant wraps a `Receiver` with a specific state type, except for [`ReceiveSession::Uninitialized`] which
87+
/// has no context yet and [`ReceiveSession::TerminalFailure`] which indicates the session has ended or is invalid.
88+
///
89+
/// This provides type erasure for the receive session state, allowing for the session to be replayed
90+
/// and the state to be updated with the next event over a uniform interface.
8891
#[derive(Debug, Clone, PartialEq)]
89-
pub enum ReceiverTypeState {
92+
pub enum ReceiveSession {
9093
Uninitialized(Receiver<UninitializedReceiver>),
9194
Initialized(Receiver<Initialized>),
9295
UncheckedProposal(Receiver<UncheckedProposal>),
@@ -100,50 +103,46 @@ pub enum ReceiverTypeState {
100103
TerminalFailure,
101104
}
102105

103-
impl ReceiverTypeState {
104-
fn process_event(self, event: SessionEvent) -> Result<ReceiverTypeState, ReplayError> {
106+
impl ReceiveSession {
107+
fn process_event(self, event: SessionEvent) -> Result<ReceiveSession, ReplayError> {
105108
match (self, event) {
106-
(ReceiverTypeState::Uninitialized(_), SessionEvent::Created(context)) =>
107-
Ok(ReceiverTypeState::Initialized(Receiver { state: Initialized { context } })),
109+
(ReceiveSession::Uninitialized(_), SessionEvent::Created(context)) =>
110+
Ok(ReceiveSession::Initialized(Receiver { state: Initialized { context } })),
108111

109112
(
110-
ReceiverTypeState::Initialized(state),
113+
ReceiveSession::Initialized(state),
111114
SessionEvent::UncheckedProposal((proposal, reply_key)),
112115
) => Ok(state.apply_unchecked_from_payload(proposal, reply_key)?),
113116

114-
(
115-
ReceiverTypeState::UncheckedProposal(state),
116-
SessionEvent::MaybeInputsOwned(inputs),
117-
) => Ok(state.apply_maybe_inputs_owned(inputs)),
117+
(ReceiveSession::UncheckedProposal(state), SessionEvent::MaybeInputsOwned(inputs)) =>
118+
Ok(state.apply_maybe_inputs_owned(inputs)),
118119

119120
(
120-
ReceiverTypeState::MaybeInputsOwned(state),
121+
ReceiveSession::MaybeInputsOwned(state),
121122
SessionEvent::MaybeInputsSeen(maybe_inputs_seen),
122123
) => Ok(state.apply_maybe_inputs_seen(maybe_inputs_seen)),
123124

124125
(
125-
ReceiverTypeState::MaybeInputsSeen(state),
126+
ReceiveSession::MaybeInputsSeen(state),
126127
SessionEvent::OutputsUnknown(outputs_unknown),
127128
) => Ok(state.apply_outputs_unknown(outputs_unknown)),
128129

129-
(
130-
ReceiverTypeState::OutputsUnknown(state),
131-
SessionEvent::WantsOutputs(wants_outputs),
132-
) => Ok(state.apply_wants_outputs(wants_outputs)),
130+
(ReceiveSession::OutputsUnknown(state), SessionEvent::WantsOutputs(wants_outputs)) =>
131+
Ok(state.apply_wants_outputs(wants_outputs)),
133132

134-
(ReceiverTypeState::WantsOutputs(state), SessionEvent::WantsInputs(wants_inputs)) =>
133+
(ReceiveSession::WantsOutputs(state), SessionEvent::WantsInputs(wants_inputs)) =>
135134
Ok(state.apply_wants_inputs(wants_inputs)),
136135

137136
(
138-
ReceiverTypeState::WantsInputs(state),
137+
ReceiveSession::WantsInputs(state),
139138
SessionEvent::ProvisionalProposal(provisional_proposal),
140139
) => Ok(state.apply_provisional_proposal(provisional_proposal)),
141140

142141
(
143-
ReceiverTypeState::ProvisionalProposal(state),
142+
ReceiveSession::ProvisionalProposal(state),
144143
SessionEvent::PayjoinProposal(payjoin_proposal),
145144
) => Ok(state.apply_payjoin_proposal(payjoin_proposal)),
146-
(_, SessionEvent::SessionInvalid(_, _)) => Ok(ReceiverTypeState::TerminalFailure),
145+
(_, SessionEvent::SessionInvalid(_, _)) => Ok(ReceiveSession::TerminalFailure),
147146
(current_state, event) => Err(InternalReplayError::InvalidStateAndEvent(
148147
Box::new(current_state),
149148
Box::new(event),
@@ -404,7 +403,7 @@ impl Receiver<Initialized> {
404403
self,
405404
event: v1::UncheckedProposal,
406405
reply_key: Option<HpkePublicKey>,
407-
) -> Result<ReceiverTypeState, InternalReplayError> {
406+
) -> Result<ReceiveSession, InternalReplayError> {
408407
if self.state.context.expiry < SystemTime::now() {
409408
// Session is expired, close the session
410409
return Err(InternalReplayError::SessionExpired(self.state.context.expiry));
@@ -417,7 +416,7 @@ impl Receiver<Initialized> {
417416
},
418417
};
419418

420-
Ok(ReceiverTypeState::UncheckedProposal(new_state))
419+
Ok(ReceiveSession::UncheckedProposal(new_state))
421420
}
422421
}
423422

@@ -485,10 +484,10 @@ impl Receiver<UncheckedProposal> {
485484
)
486485
}
487486

488-
pub(crate) fn apply_maybe_inputs_owned(self, v1: v1::MaybeInputsOwned) -> ReceiverTypeState {
487+
pub(crate) fn apply_maybe_inputs_owned(self, v1: v1::MaybeInputsOwned) -> ReceiveSession {
489488
let new_state =
490489
Receiver { state: MaybeInputsOwned { v1, context: self.state.context.clone() } };
491-
ReceiverTypeState::MaybeInputsOwned(new_state)
490+
ReceiveSession::MaybeInputsOwned(new_state)
492491
}
493492
}
494493

@@ -538,10 +537,10 @@ impl Receiver<MaybeInputsOwned> {
538537
)
539538
}
540539

541-
pub(crate) fn apply_maybe_inputs_seen(self, v1: v1::MaybeInputsSeen) -> ReceiverTypeState {
540+
pub(crate) fn apply_maybe_inputs_seen(self, v1: v1::MaybeInputsSeen) -> ReceiveSession {
542541
let new_state =
543542
Receiver { state: MaybeInputsSeen { v1, context: self.state.context.clone() } };
544-
ReceiverTypeState::MaybeInputsSeen(new_state)
543+
ReceiveSession::MaybeInputsSeen(new_state)
545544
}
546545
}
547546

@@ -584,10 +583,10 @@ impl Receiver<MaybeInputsSeen> {
584583
)
585584
}
586585

587-
pub(crate) fn apply_outputs_unknown(self, inner: v1::OutputsUnknown) -> ReceiverTypeState {
586+
pub(crate) fn apply_outputs_unknown(self, inner: v1::OutputsUnknown) -> ReceiveSession {
588587
let new_state =
589588
Receiver { state: OutputsUnknown { inner, context: self.state.context.clone() } };
590-
ReceiverTypeState::OutputsUnknown(new_state)
589+
ReceiveSession::OutputsUnknown(new_state)
591590
}
592591
}
593592

@@ -629,10 +628,10 @@ impl Receiver<OutputsUnknown> {
629628
)
630629
}
631630

632-
pub(crate) fn apply_wants_outputs(self, v1: v1::WantsOutputs) -> ReceiverTypeState {
631+
pub(crate) fn apply_wants_outputs(self, v1: v1::WantsOutputs) -> ReceiveSession {
633632
let new_state =
634633
Receiver { state: WantsOutputs { v1, context: self.state.context.clone() } };
635-
ReceiverTypeState::WantsOutputs(new_state)
634+
ReceiveSession::WantsOutputs(new_state)
636635
}
637636
}
638637

@@ -684,9 +683,9 @@ impl Receiver<WantsOutputs> {
684683
)
685684
}
686685

687-
pub(crate) fn apply_wants_inputs(self, v1: v1::WantsInputs) -> ReceiverTypeState {
686+
pub(crate) fn apply_wants_inputs(self, v1: v1::WantsInputs) -> ReceiveSession {
688687
let new_state = Receiver { state: WantsInputs { v1, context: self.state.context.clone() } };
689-
ReceiverTypeState::WantsInputs(new_state)
688+
ReceiveSession::WantsInputs(new_state)
690689
}
691690
}
692691

@@ -742,13 +741,10 @@ impl Receiver<WantsInputs> {
742741
)
743742
}
744743

745-
pub(crate) fn apply_provisional_proposal(
746-
self,
747-
v1: v1::ProvisionalProposal,
748-
) -> ReceiverTypeState {
744+
pub(crate) fn apply_provisional_proposal(self, v1: v1::ProvisionalProposal) -> ReceiveSession {
749745
let new_state =
750746
Receiver { state: ProvisionalProposal { v1, context: self.state.context.clone() } };
751-
ReceiverTypeState::ProvisionalProposal(new_state)
747+
ReceiveSession::ProvisionalProposal(new_state)
752748
}
753749
}
754750

@@ -795,10 +791,10 @@ impl Receiver<ProvisionalProposal> {
795791
)
796792
}
797793

798-
pub(crate) fn apply_payjoin_proposal(self, v1: v1::PayjoinProposal) -> ReceiverTypeState {
794+
pub(crate) fn apply_payjoin_proposal(self, v1: v1::PayjoinProposal) -> ReceiveSession {
799795
let new_state =
800796
Receiver { state: PayjoinProposal { v1, context: self.state.context.clone() } };
801-
ReceiverTypeState::PayjoinProposal(new_state)
797+
ReceiveSession::PayjoinProposal(new_state)
802798
}
803799
}
804800

0 commit comments

Comments
 (0)