1use crate::asset::TrustLineAsset;
2use crate::claim::ClaimableBalanceId;
3use crate::crypto::{MuxedAccount, PublicKey, SignerKey};
4use crate::error::{Error, Result};
5use crate::ledger::LedgerKey;
6use crate::liquidity_pool::LiquidityPoolId;
7use crate::operations::Operation;
8use crate::xdr;
9
10#[derive(Debug, Clone, PartialEq, Eq)]
11pub enum RevokeSponsorshipOperation {
12 LedgerEntry(RevokeSponsorshipLedgerEntry),
13 Signer(RevokeSponsorshipSigner),
14}
15
16#[derive(Debug, Clone, PartialEq, Eq)]
17pub struct RevokeSponsorshipLedgerEntry {
18 source_account: Option<MuxedAccount>,
19 ledger_key: LedgerKey,
20}
21
22#[derive(Debug, Clone, PartialEq, Eq)]
23pub struct RevokeSponsorshipSigner {
24 source_account: Option<MuxedAccount>,
25 account_id: PublicKey,
26 signer_key: SignerKey,
27}
28
29#[derive(Debug, Default)]
30pub struct RevokeSponsorshipOperationBuilder {
31 source_account: Option<MuxedAccount>,
32 value: Option<RevokeSponsorshipValue>,
33}
34
35#[derive(Debug)]
36pub enum RevokeSponsorshipValue {
37 LedgerEntry(LedgerKey),
38 Signer(PublicKey, SignerKey),
39}
40
41impl RevokeSponsorshipOperation {
42 pub fn source_account(&self) -> &Option<MuxedAccount> {
44 match *self {
45 RevokeSponsorshipOperation::LedgerEntry(ref le) => le.source_account(),
46 RevokeSponsorshipOperation::Signer(ref s) => s.source_account(),
47 }
48 }
49
50 pub fn source_account_mut(&mut self) -> &mut Option<MuxedAccount> {
52 match *self {
53 RevokeSponsorshipOperation::LedgerEntry(ref mut le) => le.source_account_mut(),
54 RevokeSponsorshipOperation::Signer(ref mut s) => s.source_account_mut(),
55 }
56 }
57
58 pub fn as_ledger_entry(&self) -> Option<&RevokeSponsorshipLedgerEntry> {
60 match *self {
61 RevokeSponsorshipOperation::LedgerEntry(ref inner) => Some(inner),
62 _ => None,
63 }
64 }
65
66 pub fn as_ledger_entry_mut(&mut self) -> Option<&mut RevokeSponsorshipLedgerEntry> {
68 match *self {
69 RevokeSponsorshipOperation::LedgerEntry(ref mut inner) => Some(inner),
70 _ => None,
71 }
72 }
73
74 pub fn is_ledger_entry(&self) -> bool {
76 self.as_ledger_entry().is_some()
77 }
78
79 pub fn as_signer(&self) -> Option<&RevokeSponsorshipSigner> {
81 match *self {
82 RevokeSponsorshipOperation::Signer(ref inner) => Some(inner),
83 _ => None,
84 }
85 }
86
87 pub fn as_signer_mut(&mut self) -> Option<&mut RevokeSponsorshipSigner> {
89 match *self {
90 RevokeSponsorshipOperation::Signer(ref mut inner) => Some(inner),
91 _ => None,
92 }
93 }
94
95 pub fn is_signer(&self) -> bool {
97 self.as_signer().is_some()
98 }
99
100 pub fn to_xdr_operation_body(&self) -> Result<xdr::OperationBody> {
102 let inner = match *self {
103 RevokeSponsorshipOperation::LedgerEntry(ref le) => {
104 let ledger_key = le.ledger_key.to_xdr()?;
105 xdr::RevokeSponsorshipOp::LedgerEntry(ledger_key)
106 }
107 RevokeSponsorshipOperation::Signer(ref s) => {
108 let account_id = s.account_id.to_xdr_account_id()?;
109 let signer_key = s.signer_key.to_xdr()?;
110 let inner = xdr::RevokeSponsorshipOpSigner {
111 account_id,
112 signer_key,
113 };
114 xdr::RevokeSponsorshipOp::Signer(inner)
115 }
116 };
117 Ok(xdr::OperationBody::RevokeSponsorship(inner))
118 }
119
120 pub fn from_xdr_operation_body(
122 source_account: Option<MuxedAccount>,
123 x: &xdr::RevokeSponsorshipOp,
124 ) -> Result<RevokeSponsorshipOperation> {
125 match x {
126 xdr::RevokeSponsorshipOp::LedgerEntry(ref le) => {
127 let ledger_key = LedgerKey::from_xdr(le)?;
128 let inner = RevokeSponsorshipLedgerEntry {
129 source_account,
130 ledger_key,
131 };
132 Ok(RevokeSponsorshipOperation::LedgerEntry(inner))
133 }
134 xdr::RevokeSponsorshipOp::Signer(ref s) => {
135 let account_id = PublicKey::from_xdr_account_id(&s.account_id)?;
136 let signer_key = SignerKey::from_xdr(&s.signer_key)?;
137 let inner = RevokeSponsorshipSigner {
138 source_account,
139 account_id,
140 signer_key,
141 };
142 Ok(RevokeSponsorshipOperation::Signer(inner))
143 }
144 }
145 }
146}
147
148impl RevokeSponsorshipLedgerEntry {
149 pub fn source_account(&self) -> &Option<MuxedAccount> {
151 &self.source_account
152 }
153
154 pub fn source_account_mut(&mut self) -> &mut Option<MuxedAccount> {
156 &mut self.source_account
157 }
158}
159
160impl RevokeSponsorshipSigner {
161 pub fn source_account(&self) -> &Option<MuxedAccount> {
163 &self.source_account
164 }
165
166 pub fn source_account_mut(&mut self) -> &mut Option<MuxedAccount> {
168 &mut self.source_account
169 }
170}
171
172impl LedgerKey {
173 pub fn to_xdr(&self) -> Result<xdr::LedgerKey> {
175 match *self {
176 LedgerKey::Account(ref account_id) => {
177 let account_id = account_id.to_xdr_account_id()?;
178 let inner = xdr::LedgerKeyAccount { account_id };
179 Ok(xdr::LedgerKey::Account(inner))
180 }
181 LedgerKey::Trustline(ref account_id, ref asset) => {
182 let account_id = account_id.to_xdr_account_id()?;
183 let asset = asset.to_xdr()?;
184 let inner = xdr::LedgerKeyTrustLine { account_id, asset };
185 Ok(xdr::LedgerKey::Trustline(inner))
186 }
187 LedgerKey::Offer(ref seller_id, ref offer_id) => {
188 let seller_id = seller_id.to_xdr_account_id()?;
189 let inner = xdr::LedgerKeyOffer {
190 seller_id,
191 offer_id: *offer_id,
192 };
193 Ok(xdr::LedgerKey::Offer(inner))
194 }
195 LedgerKey::Data(ref account_id, ref data_name) => {
196 let account_id = account_id.to_xdr_account_id()?;
197 let data_name = data_name
198 .as_bytes()
199 .to_vec()
200 .try_into()
201 .map_err(|_| Error::XdrError)?;
202 let inner = xdr::LedgerKeyData {
203 account_id,
204 data_name,
205 };
206 Ok(xdr::LedgerKey::Data(inner))
207 }
208 LedgerKey::ClaimableBalance(ref balance_id) => {
209 let balance_id = balance_id.to_xdr();
210 let inner = xdr::LedgerKeyClaimableBalance { balance_id };
211 Ok(xdr::LedgerKey::ClaimableBalance(inner))
212 }
213 LedgerKey::LiquidityPool(ref liquidity_pool_id) => {
214 let liquidity_pool_id = liquidity_pool_id.to_xdr();
215 let inner = xdr::LedgerKeyLiquidityPool { liquidity_pool_id };
216 Ok(xdr::LedgerKey::LiquidityPool(inner))
217 }
218 LedgerKey::ContractData(ref contract_data) => {
219 Ok(xdr::LedgerKey::ContractData(contract_data.clone()))
220 }
221 LedgerKey::ContractCode(ref contract_code) => {
222 Ok(xdr::LedgerKey::ContractCode(contract_code.clone()))
223 }
224 LedgerKey::ConfigSetting(ref config_setting) => {
225 Ok(xdr::LedgerKey::ConfigSetting(config_setting.clone()))
226 }
227 LedgerKey::Ttl(ref ttl) => Ok(xdr::LedgerKey::Ttl(ttl.clone())),
228 }
229 }
230
231 pub fn from_xdr(x: &xdr::LedgerKey) -> Result<LedgerKey> {
233 match x {
234 xdr::LedgerKey::Account(ref account) => {
235 let account_id = PublicKey::from_xdr_account_id(&account.account_id)?;
236 Ok(LedgerKey::Account(account_id))
237 }
238 xdr::LedgerKey::Trustline(ref trustline) => {
239 let account_id = PublicKey::from_xdr_account_id(&trustline.account_id)?;
240 let asset = TrustLineAsset::from_xdr(&trustline.asset)?;
241 Ok(LedgerKey::Trustline(account_id, asset))
242 }
243 xdr::LedgerKey::Offer(ref offer) => {
244 let seller_id = PublicKey::from_xdr_account_id(&offer.seller_id)?;
245 let offer_id = offer.offer_id;
246 Ok(LedgerKey::Offer(seller_id, offer_id))
247 }
248 xdr::LedgerKey::Data(ref data) => {
249 let account_id = PublicKey::from_xdr_account_id(&data.account_id)?;
250 let data_name = data.data_name.to_string();
251 Ok(LedgerKey::Data(account_id, data_name))
252 }
253 xdr::LedgerKey::ClaimableBalance(ref claimable_balance) => {
254 let balance_id = ClaimableBalanceId::from_xdr(&claimable_balance.balance_id)?;
255 Ok(LedgerKey::ClaimableBalance(balance_id))
256 }
257 xdr::LedgerKey::LiquidityPool(ref liquidity_pool) => {
258 let liquidity_pool_id =
259 LiquidityPoolId::from_xdr(&liquidity_pool.liquidity_pool_id)?;
260 Ok(LedgerKey::LiquidityPool(liquidity_pool_id))
261 }
262 xdr::LedgerKey::ContractData(ref contract_data) => {
263 Ok(LedgerKey::ContractData(contract_data.to_owned()))
264 }
265 xdr::LedgerKey::ContractCode(ref contract_code) => {
266 Ok(LedgerKey::ContractCode(contract_code.to_owned()))
267 }
268 xdr::LedgerKey::ConfigSetting(ref config_setting) => {
269 Ok(LedgerKey::ConfigSetting(config_setting.to_owned()))
270 }
271 xdr::LedgerKey::Ttl(ref ttl) => Ok(LedgerKey::Ttl(ttl.to_owned())),
272 }
273 }
274}
275
276impl RevokeSponsorshipOperationBuilder {
277 pub fn new() -> RevokeSponsorshipOperationBuilder {
278 Default::default()
279 }
280
281 pub fn with_source_account<S>(mut self, source: S) -> RevokeSponsorshipOperationBuilder
282 where
283 S: Into<MuxedAccount>,
284 {
285 self.source_account = Some(source.into());
286 self
287 }
288
289 pub fn with_ledger_key(mut self, ledger_key: LedgerKey) -> RevokeSponsorshipOperationBuilder {
290 self.value = Some(RevokeSponsorshipValue::LedgerEntry(ledger_key));
291 self
292 }
293
294 pub fn with_signer(
295 mut self,
296 account_id: PublicKey,
297 signer_key: SignerKey,
298 ) -> RevokeSponsorshipOperationBuilder {
299 self.value = Some(RevokeSponsorshipValue::Signer(account_id, signer_key));
300 self
301 }
302
303 pub fn build(self) -> Result<Operation> {
304 match self.value {
305 None => Err(Error::InvalidOperation(
306 "missing revoke sponsorship operation ledger key or signer".to_string(),
307 )),
308 Some(RevokeSponsorshipValue::LedgerEntry(ledger_key)) => {
309 let ledger_entry = RevokeSponsorshipLedgerEntry {
310 source_account: self.source_account,
311 ledger_key,
312 };
313 let inner = RevokeSponsorshipOperation::LedgerEntry(ledger_entry);
314 Ok(Operation::RevokeSponsorship(inner))
315 }
316 Some(RevokeSponsorshipValue::Signer(account_id, signer_key)) => {
317 let signer = RevokeSponsorshipSigner {
318 source_account: self.source_account,
319 account_id,
320 signer_key,
321 };
322 let inner = RevokeSponsorshipOperation::Signer(signer);
323 Ok(Operation::RevokeSponsorship(inner))
324 }
325 }
326 }
327}
328
329#[cfg(test)]
330mod tests {
331 use crate::asset::TrustLineAsset;
332 use crate::claim::ClaimableBalanceId;
333 use crate::crypto::SignerKey;
334 use crate::ledger::LedgerKey;
335 use crate::network::Network;
336 use crate::operations::tests::*;
337 use crate::operations::Operation;
338 use crate::transaction::{Transaction, TransactionEnvelope, MIN_BASE_FEE};
339 use crate::xdr::{XDRDeserialize, XDRSerialize};
340
341 #[test]
342 fn test_revoke_sponsorship_ledger_key_account() {
343 let kp = keypair0();
344 let kp1 = keypair1();
345
346 let op = Operation::new_revoke_sponsorship()
347 .with_ledger_key(LedgerKey::Account(kp1.public_key()))
348 .build()
349 .unwrap();
350 let mut tx = Transaction::builder(kp.public_key(), 3556091187167235, MIN_BASE_FEE)
351 .add_operation(op)
352 .into_transaction()
353 .unwrap();
354 tx.sign(kp.as_ref(), &Network::new_test()).unwrap();
355 let envelope = tx.to_envelope();
356 let xdr = envelope.xdr_base64().unwrap();
357 let expected = "AAAAAgAAAADg3G3hclysZlFitS+s5zWyiiJD5B0STWy5LXCj6i5yxQAAAGQADKI/AAAAAwAAAAAAAAAAAAAAAQAAAAAAAAASAAAAAAAAAAAAAAAAJcrx2g/Hbs/ohF5CVFG7B5JJSJR+OqDKzDGK7dKHZH4AAAAAAAAAAeoucsUAAABAlhwbGG2OC+ym0bD7G0GsGnbLInIVKzfLdhCl6AsyioseAydDXCVOB2A8Ywv4XfT0nC4BY26UdPBuLWG3cALmAg==";
358 assert_eq!(expected, xdr);
359 let back = TransactionEnvelope::from_xdr_base64(&xdr).unwrap();
360 assert_eq!(envelope, back);
361 }
362
363 #[test]
364 fn test_revoke_sponsorship_ledger_key_trustline() {
365 let kp = keypair0();
366 let kp1 = keypair1();
367 let kp2 = keypair2();
368
369 let abcd = TrustLineAsset::new_credit("ABCD", kp2.public_key()).unwrap();
370
371 let op = Operation::new_revoke_sponsorship()
372 .with_ledger_key(LedgerKey::Trustline(kp1.public_key(), abcd))
373 .build()
374 .unwrap();
375 let mut tx = Transaction::builder(kp.public_key(), 3556091187167235, MIN_BASE_FEE)
376 .add_operation(op)
377 .into_transaction()
378 .unwrap();
379 tx.sign(kp.as_ref(), &Network::new_test()).unwrap();
380 let envelope = tx.to_envelope();
381 let xdr = envelope.xdr_base64().unwrap();
382 let expected = "AAAAAgAAAADg3G3hclysZlFitS+s5zWyiiJD5B0STWy5LXCj6i5yxQAAAGQADKI/AAAAAwAAAAAAAAAAAAAAAQAAAAAAAAASAAAAAAAAAAEAAAAAJcrx2g/Hbs/ohF5CVFG7B5JJSJR+OqDKzDGK7dKHZH4AAAABQUJDRAAAAAB+Ecs01jX14asC1KAsPdWlpGbYCM2PEgFZCD3NLhVZmAAAAAAAAAAB6i5yxQAAAEA+1KnFKV7vhXjLxRJ+/aWfusVTrV3Az+Iscd13uKG0g6Pi41uTC5nsU07GeC2Os2bwz7r8XlNtxlkwHF89DCcG";
383 assert_eq!(expected, xdr);
384 let back = TransactionEnvelope::from_xdr_base64(&xdr).unwrap();
385 assert_eq!(envelope, back);
386 }
387
388 #[test]
389 fn test_revoke_sponsorship_ledger_key_offer() {
390 let kp = keypair0();
391 let kp1 = keypair1();
392
393 let op = Operation::new_revoke_sponsorship()
394 .with_ledger_key(LedgerKey::Offer(kp1.public_key(), 123))
395 .build()
396 .unwrap();
397 let mut tx = Transaction::builder(kp.public_key(), 3556091187167235, MIN_BASE_FEE)
398 .add_operation(op)
399 .into_transaction()
400 .unwrap();
401 tx.sign(kp.as_ref(), &Network::new_test()).unwrap();
402 let envelope = tx.to_envelope();
403 let xdr = envelope.xdr_base64().unwrap();
404 let expected = "AAAAAgAAAADg3G3hclysZlFitS+s5zWyiiJD5B0STWy5LXCj6i5yxQAAAGQADKI/AAAAAwAAAAAAAAAAAAAAAQAAAAAAAAASAAAAAAAAAAIAAAAAJcrx2g/Hbs/ohF5CVFG7B5JJSJR+OqDKzDGK7dKHZH4AAAAAAAAAewAAAAAAAAAB6i5yxQAAAECBX+hYvz4LN3DoBmTTabB7aZGCjUqps1DZaMm9jLBsHgIUrfmoVNx2e0a6t1o0nvAKpatd3SCZFWIY0W6TnAYJ";
405 assert_eq!(expected, xdr);
406 let back = TransactionEnvelope::from_xdr_base64(&xdr).unwrap();
407 assert_eq!(envelope, back);
408 }
409
410 #[test]
411 fn test_revoke_sponsorship_ledger_key_data() {
412 let kp = keypair0();
413 let kp1 = keypair1();
414
415 let op = Operation::new_revoke_sponsorship()
416 .with_ledger_key(LedgerKey::Data(kp1.public_key(), "Test_Data".to_string()))
417 .build()
418 .unwrap();
419 let mut tx = Transaction::builder(kp.public_key(), 3556091187167235, MIN_BASE_FEE)
420 .add_operation(op)
421 .into_transaction()
422 .unwrap();
423 tx.sign(kp.as_ref(), &Network::new_test()).unwrap();
424 let envelope = tx.to_envelope();
425 let xdr = envelope.xdr_base64().unwrap();
426 let expected = "AAAAAgAAAADg3G3hclysZlFitS+s5zWyiiJD5B0STWy5LXCj6i5yxQAAAGQADKI/AAAAAwAAAAAAAAAAAAAAAQAAAAAAAAASAAAAAAAAAAMAAAAAJcrx2g/Hbs/ohF5CVFG7B5JJSJR+OqDKzDGK7dKHZH4AAAAJVGVzdF9EYXRhAAAAAAAAAAAAAAHqLnLFAAAAQIEt621z4bNoQ9RXuT+bUktPySCRYocLfde5SKO2/94r4K8GBZhVzKBez80hNxfljncOuG4ZkzQ+mWaCGBjnpgE=";
427 assert_eq!(expected, xdr);
428 let back = TransactionEnvelope::from_xdr_base64(&xdr).unwrap();
429 assert_eq!(envelope, back);
430 }
431
432 #[test]
433 fn test_revoke_sponsorship_ledger_key_balance_id() {
434 let kp = keypair0();
435
436 let balance_id = ClaimableBalanceId::new(vec![7; 32]).unwrap();
437
438 let op = Operation::new_revoke_sponsorship()
439 .with_ledger_key(LedgerKey::ClaimableBalance(balance_id))
440 .build()
441 .unwrap();
442 let mut tx = Transaction::builder(kp.public_key(), 3556091187167235, MIN_BASE_FEE)
443 .add_operation(op)
444 .into_transaction()
445 .unwrap();
446 tx.sign(kp.as_ref(), &Network::new_test()).unwrap();
447 let envelope = tx.to_envelope();
448 let xdr = envelope.xdr_base64().unwrap();
449 let expected = "AAAAAgAAAADg3G3hclysZlFitS+s5zWyiiJD5B0STWy5LXCj6i5yxQAAAGQADKI/AAAAAwAAAAAAAAAAAAAAAQAAAAAAAAASAAAAAAAAAAQAAAAABwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcAAAAAAAAAAeoucsUAAABAAofz60qpHGLrsNmcT9fgAnUOywCE5xDW8OMYpusgis1zODTg3fmsbFmUGB32DrGn+aeVtrLkVVjIY8vey3cVDQ==";
450 assert_eq!(expected, xdr);
451 let back = TransactionEnvelope::from_xdr_base64(&xdr).unwrap();
452 assert_eq!(envelope, back);
453 }
454
455 #[test]
456 fn test_revoke_sponsorship_ledger_key_account_with_source_account() {
457 let kp = keypair0();
458 let kp1 = keypair1();
459
460 let op = Operation::new_revoke_sponsorship()
461 .with_ledger_key(LedgerKey::Account(kp1.public_key()))
462 .with_source_account(kp1.public_key())
463 .build()
464 .unwrap();
465 let mut tx = Transaction::builder(kp.public_key(), 3556091187167235, MIN_BASE_FEE)
466 .add_operation(op)
467 .into_transaction()
468 .unwrap();
469 tx.sign(kp.as_ref(), &Network::new_test()).unwrap();
470 let envelope = tx.to_envelope();
471 let xdr = envelope.xdr_base64().unwrap();
472 let expected = "AAAAAgAAAADg3G3hclysZlFitS+s5zWyiiJD5B0STWy5LXCj6i5yxQAAAGQADKI/AAAAAwAAAAAAAAAAAAAAAQAAAAEAAAAAJcrx2g/Hbs/ohF5CVFG7B5JJSJR+OqDKzDGK7dKHZH4AAAASAAAAAAAAAAAAAAAAJcrx2g/Hbs/ohF5CVFG7B5JJSJR+OqDKzDGK7dKHZH4AAAAAAAAAAeoucsUAAABA0Fd2Pp3NfMLTFGXbb6oks4IiwWQLqzQ71DFgVjv98Cle113hcH2toNlNEF7iT1D+262C4ajIhdAReZBubwTHCg==";
473 assert_eq!(expected, xdr);
474 let back = TransactionEnvelope::from_xdr_base64(&xdr).unwrap();
475 assert_eq!(envelope, back);
476 }
477
478 #[test]
479 fn test_revoke_sponsorship_ledger_key_signer_key() {
480 let kp = keypair0();
481 let kp1 = keypair1();
482
483 let signer_key = SignerKey::new_from_public_key(kp1.public_key());
484
485 let op = Operation::new_revoke_sponsorship()
486 .with_signer(kp1.public_key(), signer_key)
487 .build()
488 .unwrap();
489 let mut tx = Transaction::builder(kp.public_key(), 3556091187167235, MIN_BASE_FEE)
490 .add_operation(op)
491 .into_transaction()
492 .unwrap();
493 tx.sign(kp.as_ref(), &Network::new_test()).unwrap();
494 let envelope = tx.to_envelope();
495 let xdr = envelope.xdr_base64().unwrap();
496 let expected = "AAAAAgAAAADg3G3hclysZlFitS+s5zWyiiJD5B0STWy5LXCj6i5yxQAAAGQADKI/AAAAAwAAAAAAAAAAAAAAAQAAAAAAAAASAAAAAQAAAAAlyvHaD8duz+iEXkJUUbsHkklIlH46oMrMMYrt0odkfgAAAAAlyvHaD8duz+iEXkJUUbsHkklIlH46oMrMMYrt0odkfgAAAAAAAAAB6i5yxQAAAECkJuiFk6qWll/g4XtiknA2GktvVLIsQuxSs2SC2NvzrzxF0WSxZjOaKdDqeZ/AfkzgajS6mCo7s9e7sg9DcF8P";
497 assert_eq!(expected, xdr);
498 let back = TransactionEnvelope::from_xdr_base64(&xdr).unwrap();
499 assert_eq!(envelope, back);
500 }
501
502 #[test]
503 fn test_revoke_sponsorship_ledger_key_signer_key_with_source_account() {
504 let kp = keypair0();
505 let kp1 = keypair1();
506
507 let signer_key = SignerKey::new_from_public_key(kp1.public_key());
508
509 let op = Operation::new_revoke_sponsorship()
510 .with_signer(kp1.public_key(), signer_key)
511 .with_source_account(kp1.public_key())
512 .build()
513 .unwrap();
514 let mut tx = Transaction::builder(kp.public_key(), 3556091187167235, MIN_BASE_FEE)
515 .add_operation(op)
516 .into_transaction()
517 .unwrap();
518 tx.sign(kp.as_ref(), &Network::new_test()).unwrap();
519 let envelope = tx.to_envelope();
520 let xdr = envelope.xdr_base64().unwrap();
521 let expected = "AAAAAgAAAADg3G3hclysZlFitS+s5zWyiiJD5B0STWy5LXCj6i5yxQAAAGQADKI/AAAAAwAAAAAAAAAAAAAAAQAAAAEAAAAAJcrx2g/Hbs/ohF5CVFG7B5JJSJR+OqDKzDGK7dKHZH4AAAASAAAAAQAAAAAlyvHaD8duz+iEXkJUUbsHkklIlH46oMrMMYrt0odkfgAAAAAlyvHaD8duz+iEXkJUUbsHkklIlH46oMrMMYrt0odkfgAAAAAAAAAB6i5yxQAAAECe7rfndyOX8KE0jYOH5hH8oTYFF06UOEeQWvtLdxP9s0a/V8kTDclsyPpfCiC4dcNV5CPVifcolty05Qap2TUN";
522 assert_eq!(expected, xdr);
523 let back = TransactionEnvelope::from_xdr_base64(&xdr).unwrap();
524 assert_eq!(envelope, back);
525 }
526}