penumbra_sdk_dex/lp/
action.rs1use serde::{Deserialize, Serialize};
2
3use penumbra_sdk_asset::{balance, Balance, Value};
4use penumbra_sdk_proto::{penumbra::core::component::dex::v1 as pb, DomainType};
5use penumbra_sdk_txhash::{EffectHash, EffectingData};
6
7use super::{position, position::Position, LpNft};
8
9#[derive(Debug, Clone, Serialize, Deserialize)]
14#[serde(try_from = "pb::PositionOpen", into = "pb::PositionOpen")]
15pub struct PositionOpen {
16 pub position: Position,
21}
22
23impl EffectingData for PositionOpen {
24 fn effect_hash(&self) -> EffectHash {
25 EffectHash::from_proto_effecting_data(&self.to_proto())
28 }
29}
30
31impl PositionOpen {
32 pub fn balance(&self) -> Balance {
34 let opened_position_nft = Value {
35 amount: 1u64.into(),
36 asset_id: LpNft::new(self.position.id(), position::State::Opened).asset_id(),
37 };
38
39 let reserves = self.position.reserves.balance(&self.position.phi.pair);
40
41 Balance::from(opened_position_nft) - reserves
43 }
44}
45
46#[derive(Debug, Clone, Serialize, Deserialize)]
56#[serde(try_from = "pb::PositionClose", into = "pb::PositionClose")]
57pub struct PositionClose {
58 pub position_id: position::Id,
59}
60
61impl EffectingData for PositionClose {
62 fn effect_hash(&self) -> EffectHash {
63 EffectHash::from_proto_effecting_data(&self.to_proto())
64 }
65}
66
67impl PositionClose {
68 pub fn balance(&self) -> Balance {
70 let opened_position_nft = Value {
71 amount: 1u64.into(),
72 asset_id: LpNft::new(self.position_id, position::State::Opened).asset_id(),
73 };
74
75 let closed_position_nft = Value {
76 amount: 1u64.into(),
77 asset_id: LpNft::new(self.position_id, position::State::Closed).asset_id(),
78 };
79
80 Balance::from(closed_position_nft) - opened_position_nft
82 }
83}
84
85#[derive(Debug, Clone, Serialize, Deserialize)]
91#[serde(try_from = "pb::PositionWithdraw", into = "pb::PositionWithdraw")]
92pub struct PositionWithdraw {
93 pub position_id: position::Id,
94 pub reserves_commitment: balance::Commitment,
98 pub sequence: u64,
100}
101
102impl EffectingData for PositionWithdraw {
103 fn effect_hash(&self) -> EffectHash {
104 EffectHash::from_proto_effecting_data(&self.to_proto())
105 }
106}
107
108impl DomainType for PositionOpen {
109 type Proto = pb::PositionOpen;
110}
111
112impl From<PositionOpen> for pb::PositionOpen {
113 fn from(value: PositionOpen) -> Self {
114 Self {
115 position: Some(value.position.into()),
116 }
117 }
118}
119
120impl TryFrom<pb::PositionOpen> for PositionOpen {
121 type Error = anyhow::Error;
122
123 fn try_from(value: pb::PositionOpen) -> Result<Self, Self::Error> {
124 Ok(Self {
125 position: value
126 .position
127 .ok_or_else(|| anyhow::anyhow!("missing position"))?
128 .try_into()?,
129 })
130 }
131}
132
133impl DomainType for PositionClose {
134 type Proto = pb::PositionClose;
135}
136
137impl From<PositionClose> for pb::PositionClose {
138 fn from(value: PositionClose) -> Self {
139 Self {
140 position_id: Some(value.position_id.into()),
141 }
142 }
143}
144
145impl TryFrom<pb::PositionClose> for PositionClose {
146 type Error = anyhow::Error;
147
148 fn try_from(value: pb::PositionClose) -> Result<Self, Self::Error> {
149 Ok(Self {
150 position_id: value
151 .position_id
152 .ok_or_else(|| anyhow::anyhow!("missing position_id"))?
153 .try_into()?,
154 })
155 }
156}
157
158impl DomainType for PositionWithdraw {
159 type Proto = pb::PositionWithdraw;
160}
161
162impl From<PositionWithdraw> for pb::PositionWithdraw {
163 fn from(value: PositionWithdraw) -> Self {
164 Self {
165 position_id: Some(value.position_id.into()),
166 reserves_commitment: Some(value.reserves_commitment.into()),
167 sequence: value.sequence,
168 }
169 }
170}
171
172impl TryFrom<pb::PositionWithdraw> for PositionWithdraw {
173 type Error = anyhow::Error;
174
175 fn try_from(value: pb::PositionWithdraw) -> Result<Self, Self::Error> {
176 Ok(Self {
177 position_id: value
178 .position_id
179 .ok_or_else(|| anyhow::anyhow!("missing position_id"))?
180 .try_into()?,
181 reserves_commitment: value
182 .reserves_commitment
183 .ok_or_else(|| anyhow::anyhow!("missing balance_commitment"))?
184 .try_into()?,
185 sequence: value.sequence,
186 })
187 }
188}