substrate_stellar_sdk/xdr/impls/
muxed_account.rs1use sp_std::vec::Vec;
2
3use crate::{
4 types::{MuxedAccount, MuxedAccountMed25519, Uint64},
5 utils::key_encoding::{
6 decode_stellar_key, encode_stellar_key, ED25519_PUBLIC_KEY_VERSION_BYTE, MED25519_PUBLIC_KEY_BYTE_LENGTH,
7 MED25519_PUBLIC_KEY_VERSION_BYTE,
8 },
9 AccountId, IntoAccountId, PublicKey, StellarSdkError, XdrCodec,
10};
11
12use core::convert::{AsRef, TryInto};
13
14impl MuxedAccount {
15 pub fn from_account_id<T: IntoAccountId>(account_id: T) -> Result<Self, StellarSdkError> {
16 account_id.into_account_id().map(|account_id| {
17 let account_id = match account_id {
18 PublicKey::PublicKeyTypeEd25519(account_id) => account_id,
19 };
20 MuxedAccount::KeyTypeEd25519(account_id)
21 })
22 }
23
24 pub fn from_muxed_account_id<T: IntoAccountId>(
25 account_id: T,
26 sub_account_id: u64,
27 ) -> Result<Self, StellarSdkError> {
28 account_id.into_account_id().map(|account_id| {
29 let account_id = match account_id {
30 PublicKey::PublicKeyTypeEd25519(account_id) => account_id,
31 };
32 MuxedAccount::KeyTypeMuxedEd25519(MuxedAccountMed25519 { id: sub_account_id, ed25519: account_id })
33 })
34 }
35
36 pub fn from_encoding<T: AsRef<[u8]>>(encoded_key: T) -> Result<Self, StellarSdkError> {
37 let encoded_key = encoded_key.as_ref();
38
39 match decode_stellar_key::<_, MED25519_PUBLIC_KEY_BYTE_LENGTH>(encoded_key, MED25519_PUBLIC_KEY_VERSION_BYTE) {
40 Ok(raw_bytes) => Ok(MuxedAccount::KeyTypeMuxedEd25519(MuxedAccountMed25519 {
41 id: Uint64::from_xdr(&raw_bytes[MED25519_PUBLIC_KEY_BYTE_LENGTH - 8..]).unwrap(),
42 ed25519: raw_bytes[..MED25519_PUBLIC_KEY_BYTE_LENGTH - 8].try_into().unwrap(),
43 })),
44 Err(_) => PublicKey::from_encoding(encoded_key)
45 .map(|public_key| MuxedAccount::KeyTypeEd25519(public_key.into_binary())),
46 }
47 }
48
49 pub fn to_encoding(&self) -> Vec<u8> {
51 match self {
52 MuxedAccount::KeyTypeEd25519(raw_bytes) => encode_stellar_key(raw_bytes, ED25519_PUBLIC_KEY_VERSION_BYTE),
53 MuxedAccount::KeyTypeMuxedEd25519(MuxedAccountMed25519 { id, ed25519 }) => {
54 let mut raw_bytes = [0u8; MED25519_PUBLIC_KEY_BYTE_LENGTH];
55 raw_bytes[..MED25519_PUBLIC_KEY_BYTE_LENGTH - 8].copy_from_slice(ed25519);
56 raw_bytes[MED25519_PUBLIC_KEY_BYTE_LENGTH - 8..].copy_from_slice(id.to_xdr().as_slice());
57 encode_stellar_key(&raw_bytes, MED25519_PUBLIC_KEY_VERSION_BYTE)
58 },
59 _ => unreachable!("Invalid muxed account type"),
60 }
61 }
62}
63
64pub trait IntoMuxedAccountId {
68 fn into_muxed_account_id(self) -> Result<MuxedAccount, StellarSdkError>;
69}
70
71impl IntoMuxedAccountId for AccountId {
72 fn into_muxed_account_id(self) -> Result<MuxedAccount, StellarSdkError> {
73 Ok(MuxedAccount::KeyTypeEd25519(self.into_binary()))
74 }
75}
76
77impl IntoMuxedAccountId for MuxedAccount {
78 fn into_muxed_account_id(self) -> Result<MuxedAccount, StellarSdkError> {
79 Ok(self)
80 }
81}
82
83impl<T: AsRef<[u8]>> IntoMuxedAccountId for T {
84 fn into_muxed_account_id(self) -> Result<MuxedAccount, StellarSdkError> {
85 MuxedAccount::from_encoding(self)
86 }
87}