penumbra_sdk_community_pool/action/
community_pool_output.rs

1use anyhow::{Context, Error};
2use serde::{Deserialize, Serialize};
3use std::convert::{TryFrom, TryInto};
4
5use penumbra_sdk_asset::{Balance, Value};
6use penumbra_sdk_keys::Address;
7use penumbra_sdk_proto::{penumbra::core::component::governance::v1 as pb, DomainType};
8use penumbra_sdk_txhash::{EffectHash, EffectingData};
9
10#[derive(Clone, Debug, Serialize, Deserialize)]
11#[serde(try_from = "pb::CommunityPoolOutput", into = "pb::CommunityPoolOutput")]
12pub struct CommunityPoolOutput {
13    pub value: Value,
14    pub address: Address,
15}
16
17impl CommunityPoolOutput {
18    pub fn balance(&self) -> Balance {
19        // Outputs from the Community Pool require value
20        -Balance::from(self.value)
21    }
22}
23
24impl EffectingData for CommunityPoolOutput {
25    fn effect_hash(&self) -> EffectHash {
26        EffectHash::from_proto_effecting_data(&self.to_proto())
27    }
28}
29
30impl DomainType for CommunityPoolOutput {
31    type Proto = pb::CommunityPoolOutput;
32}
33
34impl From<CommunityPoolOutput> for pb::CommunityPoolOutput {
35    fn from(msg: CommunityPoolOutput) -> Self {
36        pb::CommunityPoolOutput {
37            value: Some(msg.value.into()),
38            address: Some(msg.address.into()),
39        }
40    }
41}
42
43impl TryFrom<pb::CommunityPoolOutput> for CommunityPoolOutput {
44    type Error = Error;
45
46    fn try_from(proto: pb::CommunityPoolOutput) -> anyhow::Result<Self, Self::Error> {
47        let value = proto
48            .value
49            .ok_or_else(|| anyhow::anyhow!("missing value"))?
50            .try_into()
51            .context("malformed value")?;
52        let address = proto
53            .address
54            .ok_or_else(|| anyhow::anyhow!("missing address"))?
55            .try_into()
56            .context("malformed address")?;
57
58        Ok(CommunityPoolOutput { value, address })
59    }
60}