stellar_base/operations/
claim_claimable_balance.rs

1use crate::claim::ClaimableBalanceId;
2use crate::crypto::MuxedAccount;
3use crate::error::{Error, Result};
4use crate::operations::Operation;
5use crate::xdr;
6
7#[derive(Debug, Clone, PartialEq, Eq)]
8pub struct ClaimClaimableBalanceOperation {
9    source_account: Option<MuxedAccount>,
10    balance_id: ClaimableBalanceId,
11}
12
13#[derive(Debug, Default)]
14pub struct ClaimClaimableBalanceOperationBuilder {
15    source_account: Option<MuxedAccount>,
16    balance_id: Option<ClaimableBalanceId>,
17}
18
19impl ClaimClaimableBalanceOperation {
20    /// Retrieves the operation source account.
21    pub fn source_account(&self) -> &Option<MuxedAccount> {
22        &self.source_account
23    }
24
25    /// Retrieves a reference to the operation source account.
26    pub fn source_account_mut(&mut self) -> &mut Option<MuxedAccount> {
27        &mut self.source_account
28    }
29
30    /// Retrieves a reference to the claimable balance id.
31    pub fn balance_id(&self) -> &ClaimableBalanceId {
32        &self.balance_id
33    }
34
35    /// Retrieves a mutable reference to the claimable balance id.
36    pub fn balance_id_mut(&mut self) -> &mut ClaimableBalanceId {
37        &mut self.balance_id
38    }
39
40    /// Returns tho xdr operation body.
41    pub fn to_xdr_operation_body(&self) -> Result<xdr::OperationBody> {
42        let balance_id = self.balance_id.to_xdr();
43        let inner = xdr::ClaimClaimableBalanceOp { balance_id };
44        Ok(xdr::OperationBody::ClaimClaimableBalance(inner))
45    }
46
47    /// Creates from the xdr operation body.
48    pub fn from_xdr_operation_body(
49        source_account: Option<MuxedAccount>,
50        x: &xdr::ClaimClaimableBalanceOp,
51    ) -> Result<ClaimClaimableBalanceOperation> {
52        let balance_id = ClaimableBalanceId::from_xdr(&x.balance_id)?;
53        Ok(ClaimClaimableBalanceOperation {
54            source_account,
55            balance_id,
56        })
57    }
58}
59
60impl ClaimClaimableBalanceOperationBuilder {
61    pub fn new() -> ClaimClaimableBalanceOperationBuilder {
62        Default::default()
63    }
64
65    pub fn with_source_account<S>(mut self, source: S) -> ClaimClaimableBalanceOperationBuilder
66    where
67        S: Into<MuxedAccount>,
68    {
69        self.source_account = Some(source.into());
70        self
71    }
72
73    pub fn with_claimable_balance_id(
74        mut self,
75        balance_id: ClaimableBalanceId,
76    ) -> ClaimClaimableBalanceOperationBuilder {
77        self.balance_id = Some(balance_id);
78        self
79    }
80
81    pub fn build(self) -> Result<Operation> {
82        let balance_id = self.balance_id.ok_or_else(|| {
83            Error::InvalidOperation("missing claim claimable balance id".to_string())
84        })?;
85
86        Ok(Operation::ClaimClaimableBalance(
87            ClaimClaimableBalanceOperation {
88                source_account: self.source_account,
89                balance_id,
90            },
91        ))
92    }
93}
94
95#[cfg(test)]
96mod tests {
97    use crate::claim::ClaimableBalanceId;
98
99    use crate::network::Network;
100    use crate::operations::tests::*;
101    use crate::operations::Operation;
102    use crate::transaction::{Transaction, TransactionEnvelope, MIN_BASE_FEE};
103    use crate::xdr::{XDRDeserialize, XDRSerialize};
104
105    #[test]
106    fn test_claim_claimable_balance() {
107        let kp = keypair0();
108
109        let balance_id = ClaimableBalanceId::new(vec![7; 32]).unwrap();
110
111        let op = Operation::new_claim_claimable_balance()
112            .with_claimable_balance_id(balance_id)
113            .build()
114            .unwrap();
115
116        let mut tx = Transaction::builder(kp.public_key(), 3556091187167235, MIN_BASE_FEE)
117            .add_operation(op)
118            .into_transaction()
119            .unwrap();
120        tx.sign(kp.as_ref(), &Network::new_test()).unwrap();
121        let envelope = tx.to_envelope();
122        let xdr = envelope.xdr_base64().unwrap();
123        let expected = "AAAAAgAAAADg3G3hclysZlFitS+s5zWyiiJD5B0STWy5LXCj6i5yxQAAAGQADKI/AAAAAwAAAAAAAAAAAAAAAQAAAAAAAAAPAAAAAAcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHAAAAAAAAAAHqLnLFAAAAQH9SMMxYh28+t9WP0xrJWUZH/i7mk9jG1Qzjvnh2I2Hx/M8OTOqr0511hvBuHI+ETJiAEMUoFw8zb16fXHjQoQQ=";
124        assert_eq!(expected, xdr);
125        let back = TransactionEnvelope::from_xdr_base64(&xdr).unwrap();
126        assert_eq!(envelope, back);
127    }
128
129    #[test]
130    fn test_claim_claimable_balance_with_source_account() {
131        let kp = keypair0();
132
133        let balance_id = ClaimableBalanceId::new(vec![7; 32]).unwrap();
134
135        let op = Operation::new_claim_claimable_balance()
136            .with_source_account(kp.public_key())
137            .with_claimable_balance_id(balance_id)
138            .build()
139            .unwrap();
140
141        let mut tx = Transaction::builder(kp.public_key(), 3556091187167235, MIN_BASE_FEE)
142            .add_operation(op)
143            .into_transaction()
144            .unwrap();
145        tx.sign(kp.as_ref(), &Network::new_test()).unwrap();
146        let envelope = tx.to_envelope();
147        let xdr = envelope.xdr_base64().unwrap();
148        let expected = "AAAAAgAAAADg3G3hclysZlFitS+s5zWyiiJD5B0STWy5LXCj6i5yxQAAAGQADKI/AAAAAwAAAAAAAAAAAAAAAQAAAAEAAAAA4Nxt4XJcrGZRYrUvrOc1sooiQ+QdEk1suS1wo+oucsUAAAAPAAAAAAcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHAAAAAAAAAAHqLnLFAAAAQD80Q+16BK4ZzJzNGaesezr0cPxsyOvgVVlANU1g91tfM6/NkzLXkB1QI2F4xkXIbp5qbSJ/OfrGRxmsdwWo2g0=";
149        assert_eq!(expected, xdr);
150        let back = TransactionEnvelope::from_xdr_base64(&xdr).unwrap();
151        assert_eq!(envelope, back);
152    }
153}