penumbra_sdk_shielded_pool/
event.rs

1use anyhow::{anyhow, Context};
2use penumbra_sdk_asset::Value;
3use penumbra_sdk_keys::Address;
4use penumbra_sdk_proto::{core::component::shielded_pool::v1 as pb, DomainType};
5use penumbra_sdk_sct::Nullifier;
6use prost::Name as _;
7
8use crate::note::StateCommitment;
9
10// // These are sort of like the proto/domain type From impls, because
11// // we don't have separate domain types for the events (yet, possibly ever).
12// Narrator: we did in fact need the separate domain types.
13
14#[derive(Clone, Debug)]
15pub struct EventSpend {
16    pub nullifier: Nullifier,
17}
18
19impl TryFrom<pb::EventSpend> for EventSpend {
20    type Error = anyhow::Error;
21
22    fn try_from(value: pb::EventSpend) -> Result<Self, Self::Error> {
23        fn inner(value: pb::EventSpend) -> anyhow::Result<EventSpend> {
24            Ok(EventSpend {
25                nullifier: value
26                    .nullifier
27                    .ok_or(anyhow!("missing `nullifier`"))?
28                    .try_into()?,
29            })
30        }
31        inner(value).context(format!("parsing {}", pb::EventSpend::NAME))
32    }
33}
34
35impl From<EventSpend> for pb::EventSpend {
36    fn from(value: EventSpend) -> Self {
37        Self {
38            nullifier: Some(value.nullifier.into()),
39        }
40    }
41}
42
43impl DomainType for EventSpend {
44    type Proto = pb::EventSpend;
45}
46
47#[derive(Clone, Debug)]
48pub struct EventOutput {
49    pub note_commitment: StateCommitment,
50}
51
52impl TryFrom<pb::EventOutput> for EventOutput {
53    type Error = anyhow::Error;
54
55    fn try_from(value: pb::EventOutput) -> Result<Self, Self::Error> {
56        fn inner(value: pb::EventOutput) -> anyhow::Result<EventOutput> {
57            Ok(EventOutput {
58                note_commitment: value
59                    .note_commitment
60                    .ok_or(anyhow!("missing `note_commitment`"))?
61                    .try_into()?,
62            })
63        }
64        inner(value).context(format!("parsing {}", pb::EventOutput::NAME))
65    }
66}
67
68impl From<EventOutput> for pb::EventOutput {
69    fn from(value: EventOutput) -> Self {
70        Self {
71            note_commitment: Some(value.note_commitment.into()),
72        }
73    }
74}
75
76impl DomainType for EventOutput {
77    type Proto = pb::EventOutput;
78}
79
80#[derive(Clone, Debug)]
81pub struct FungibleTokenTransferPacketMetadata {
82    pub channel: String,
83    pub sequence: u64,
84}
85
86impl TryFrom<pb::FungibleTokenTransferPacketMetadata> for FungibleTokenTransferPacketMetadata {
87    type Error = anyhow::Error;
88
89    fn try_from(value: pb::FungibleTokenTransferPacketMetadata) -> Result<Self, Self::Error> {
90        fn inner(
91            value: pb::FungibleTokenTransferPacketMetadata,
92        ) -> anyhow::Result<FungibleTokenTransferPacketMetadata> {
93            Ok(FungibleTokenTransferPacketMetadata {
94                channel: value.channel,
95                sequence: value.sequence,
96            })
97        }
98        inner(value).context(format!(
99            "parsing {}",
100            pb::FungibleTokenTransferPacketMetadata::NAME
101        ))
102    }
103}
104
105impl From<FungibleTokenTransferPacketMetadata> for pb::FungibleTokenTransferPacketMetadata {
106    fn from(value: FungibleTokenTransferPacketMetadata) -> Self {
107        Self {
108            channel: value.channel,
109            sequence: value.sequence,
110        }
111    }
112}
113
114impl DomainType for FungibleTokenTransferPacketMetadata {
115    type Proto = pb::FungibleTokenTransferPacketMetadata;
116}
117
118#[derive(Clone, Debug)]
119pub struct EventOutboundFungibleTokenTransfer {
120    pub value: Value,
121    pub sender: Address,
122    pub receiver: String,
123    pub meta: FungibleTokenTransferPacketMetadata,
124}
125
126impl TryFrom<pb::EventOutboundFungibleTokenTransfer> for EventOutboundFungibleTokenTransfer {
127    type Error = anyhow::Error;
128
129    fn try_from(value: pb::EventOutboundFungibleTokenTransfer) -> Result<Self, Self::Error> {
130        fn inner(
131            value: pb::EventOutboundFungibleTokenTransfer,
132        ) -> anyhow::Result<EventOutboundFungibleTokenTransfer> {
133            Ok(EventOutboundFungibleTokenTransfer {
134                value: value.value.ok_or(anyhow!("missing `value`"))?.try_into()?,
135                sender: value
136                    .sender
137                    .ok_or(anyhow!("missing `sender`"))?
138                    .try_into()?,
139                receiver: value.receiver,
140                meta: value.meta.ok_or(anyhow!("missing `meta`"))?.try_into()?,
141            })
142        }
143        inner(value).context(format!(
144            "parsing {}",
145            pb::EventOutboundFungibleTokenTransfer::NAME
146        ))
147    }
148}
149
150impl From<EventOutboundFungibleTokenTransfer> for pb::EventOutboundFungibleTokenTransfer {
151    fn from(value: EventOutboundFungibleTokenTransfer) -> Self {
152        Self {
153            value: Some(value.value.into()),
154            sender: Some(value.sender.into()),
155            receiver: value.receiver,
156            meta: Some(value.meta.into()),
157        }
158    }
159}
160
161impl DomainType for EventOutboundFungibleTokenTransfer {
162    type Proto = pb::EventOutboundFungibleTokenTransfer;
163}
164
165#[derive(Clone, Copy, Debug)]
166#[repr(i32)]
167pub enum FungibleTokenRefundReason {
168    Unspecified = 0,
169    Timeout = 1,
170    Error = 2,
171}
172
173#[derive(Clone, Debug)]
174pub struct EventOutboundFungibleTokenRefund {
175    pub value: Value,
176    pub sender: Address,
177    pub receiver: String,
178    pub reason: FungibleTokenRefundReason,
179    pub meta: FungibleTokenTransferPacketMetadata,
180}
181
182impl TryFrom<pb::EventOutboundFungibleTokenRefund> for EventOutboundFungibleTokenRefund {
183    type Error = anyhow::Error;
184
185    fn try_from(value: pb::EventOutboundFungibleTokenRefund) -> Result<Self, Self::Error> {
186        fn inner(
187            value: pb::EventOutboundFungibleTokenRefund,
188        ) -> anyhow::Result<EventOutboundFungibleTokenRefund> {
189            use pb::event_outbound_fungible_token_refund::Reason;
190            let reason = match value.reason() {
191                Reason::Timeout => FungibleTokenRefundReason::Timeout,
192                Reason::Error => FungibleTokenRefundReason::Error,
193                Reason::Unspecified => FungibleTokenRefundReason::Unspecified,
194            };
195            Ok(EventOutboundFungibleTokenRefund {
196                value: value.value.ok_or(anyhow!("missing `value`"))?.try_into()?,
197                sender: value
198                    .sender
199                    .ok_or(anyhow!("missing `sender`"))?
200                    .try_into()?,
201                receiver: value.receiver,
202                reason,
203                meta: value.meta.ok_or(anyhow!("missing `meta`"))?.try_into()?,
204            })
205        }
206        inner(value).context(format!(
207            "parsing {}",
208            pb::EventOutboundFungibleTokenRefund::NAME
209        ))
210    }
211}
212
213impl From<EventOutboundFungibleTokenRefund> for pb::EventOutboundFungibleTokenRefund {
214    fn from(value: EventOutboundFungibleTokenRefund) -> Self {
215        Self {
216            value: Some(value.value.into()),
217            sender: Some(value.sender.into()),
218            receiver: value.receiver,
219            reason: value.reason as i32,
220            meta: Some(value.meta.into()),
221        }
222    }
223}
224
225impl DomainType for EventOutboundFungibleTokenRefund {
226    type Proto = pb::EventOutboundFungibleTokenRefund;
227}
228
229#[derive(Clone, Debug)]
230pub struct EventInboundFungibleTokenTransfer {
231    pub value: Value,
232    pub sender: String,
233    pub receiver: Address,
234    pub meta: FungibleTokenTransferPacketMetadata,
235}
236
237impl TryFrom<pb::EventInboundFungibleTokenTransfer> for EventInboundFungibleTokenTransfer {
238    type Error = anyhow::Error;
239
240    fn try_from(value: pb::EventInboundFungibleTokenTransfer) -> Result<Self, Self::Error> {
241        fn inner(
242            value: pb::EventInboundFungibleTokenTransfer,
243        ) -> anyhow::Result<EventInboundFungibleTokenTransfer> {
244            Ok(EventInboundFungibleTokenTransfer {
245                value: value.value.ok_or(anyhow!("missing `value`"))?.try_into()?,
246                sender: value.sender,
247                receiver: value
248                    .receiver
249                    .ok_or(anyhow!("missing `receiver`"))?
250                    .try_into()?,
251                meta: value.meta.ok_or(anyhow!("missing `meta`"))?.try_into()?,
252            })
253        }
254        inner(value).context(format!(
255            "parsing {}",
256            pb::EventInboundFungibleTokenTransfer::NAME
257        ))
258    }
259}
260
261impl From<EventInboundFungibleTokenTransfer> for pb::EventInboundFungibleTokenTransfer {
262    fn from(value: EventInboundFungibleTokenTransfer) -> Self {
263        Self {
264            value: Some(value.value.into()),
265            sender: value.sender,
266            receiver: Some(value.receiver.into()),
267            meta: Some(value.meta.into()),
268        }
269    }
270}
271
272impl DomainType for EventInboundFungibleTokenTransfer {
273    type Proto = pb::EventInboundFungibleTokenTransfer;
274}