penumbra_sdk_dex/swap/
view.rs

1use penumbra_sdk_asset::{asset::Metadata, ValueView};
2use penumbra_sdk_proto::{penumbra::core::component::dex::v1 as pb, DomainType};
3use penumbra_sdk_shielded_pool::NoteView;
4use penumbra_sdk_txhash::TransactionId;
5use serde::{Deserialize, Serialize};
6
7use crate::BatchSwapOutputData;
8
9use super::{Swap, SwapPlaintext};
10
11#[derive(Clone, Debug, Serialize, Deserialize)]
12#[serde(try_from = "pb::SwapView", into = "pb::SwapView")]
13#[allow(clippy::large_enum_variant)]
14pub enum SwapView {
15    Visible {
16        swap: Swap,
17        swap_plaintext: SwapPlaintext,
18        output_1: Option<NoteView>,
19        output_2: Option<NoteView>,
20        claim_tx: Option<TransactionId>,
21        asset_1_metadata: Option<Metadata>,
22        asset_2_metadata: Option<Metadata>,
23        batch_swap_output_data: Option<BatchSwapOutputData>,
24    },
25    Opaque {
26        swap: Swap,
27        batch_swap_output_data: Option<BatchSwapOutputData>,
28        output_1: Option<ValueView>,
29        output_2: Option<ValueView>,
30        asset_1_metadata: Option<Metadata>,
31        asset_2_metadata: Option<Metadata>,
32    },
33}
34
35impl DomainType for SwapView {
36    type Proto = pb::SwapView;
37}
38
39impl TryFrom<pb::SwapView> for SwapView {
40    type Error = anyhow::Error;
41
42    fn try_from(v: pb::SwapView) -> Result<Self, Self::Error> {
43        match v
44            .swap_view
45            .ok_or_else(|| anyhow::anyhow!("missing swap field"))?
46        {
47            pb::swap_view::SwapView::Visible(x) => Ok(SwapView::Visible {
48                swap: x
49                    .swap
50                    .ok_or_else(|| anyhow::anyhow!("missing swap field"))?
51                    .try_into()?,
52                swap_plaintext: x
53                    .swap_plaintext
54                    .ok_or_else(|| anyhow::anyhow!("missing swap plaintext field"))?
55                    .try_into()?,
56                output_1: x.output_1.map(TryInto::try_into).transpose()?,
57                output_2: x.output_2.map(TryInto::try_into).transpose()?,
58                claim_tx: x.claim_tx.map(TryInto::try_into).transpose()?,
59                asset_1_metadata: x.asset_1_metadata.map(TryInto::try_into).transpose()?,
60                asset_2_metadata: x.asset_2_metadata.map(TryInto::try_into).transpose()?,
61                batch_swap_output_data: x
62                    .batch_swap_output_data
63                    .map(TryInto::try_into)
64                    .transpose()?,
65            }),
66            pb::swap_view::SwapView::Opaque(x) => Ok(SwapView::Opaque {
67                swap: x
68                    .swap
69                    .ok_or_else(|| anyhow::anyhow!("missing swap field"))?
70                    .try_into()?,
71                batch_swap_output_data: x
72                    .batch_swap_output_data
73                    .map(TryInto::try_into)
74                    .transpose()?,
75                output_1: x.output_1_value.map(TryInto::try_into).transpose()?,
76                output_2: x.output_2_value.map(TryInto::try_into).transpose()?,
77                asset_1_metadata: x.asset_1_metadata.map(TryInto::try_into).transpose()?,
78                asset_2_metadata: x.asset_2_metadata.map(TryInto::try_into).transpose()?,
79            }),
80        }
81    }
82}
83
84impl From<SwapView> for pb::SwapView {
85    fn from(v: SwapView) -> Self {
86        use pb::swap_view as sv;
87        match v {
88            SwapView::Visible {
89                swap,
90                swap_plaintext,
91                output_1,
92                output_2,
93                claim_tx,
94                asset_1_metadata,
95                asset_2_metadata,
96                batch_swap_output_data,
97            } => Self {
98                swap_view: Some(sv::SwapView::Visible(sv::Visible {
99                    swap: Some(swap.into()),
100                    swap_plaintext: Some(swap_plaintext.into()),
101                    output_1: output_1.map(Into::into),
102                    output_2: output_2.map(Into::into),
103                    claim_tx: claim_tx.map(Into::into),
104                    asset_1_metadata: asset_1_metadata.map(Into::into),
105                    asset_2_metadata: asset_2_metadata.map(Into::into),
106                    batch_swap_output_data: batch_swap_output_data.map(Into::into),
107                })),
108            },
109            SwapView::Opaque {
110                swap,
111                batch_swap_output_data,
112                output_1,
113                output_2,
114                asset_1_metadata,
115                asset_2_metadata,
116            } => Self {
117                swap_view: Some(sv::SwapView::Opaque(sv::Opaque {
118                    swap: Some(swap.into()),
119                    batch_swap_output_data: batch_swap_output_data.map(Into::into),
120                    output_1_value: output_1.map(Into::into),
121                    output_2_value: output_2.map(Into::into),
122                    asset_1_metadata: asset_1_metadata.map(Into::into),
123                    asset_2_metadata: asset_2_metadata.map(Into::into),
124                })),
125            },
126        }
127    }
128}
129
130impl From<SwapView> for Swap {
131    fn from(v: SwapView) -> Self {
132        match v {
133            SwapView::Visible { swap, .. } => swap,
134            SwapView::Opaque { swap, .. } => swap,
135        }
136    }
137}