stellar_base/crypto/
public_key.rs1use std::convert::TryInto;
2
3use crate::crypto::strkey;
4use crate::error::{Error, Result};
5use crate::xdr;
6
7#[derive(Debug, Clone, Copy, PartialEq, Eq)]
9pub struct PublicKey(pub [u8; 32]);
10
11impl PublicKey {
12 pub fn from_account_id(account_id: &str) -> Result<PublicKey> {
14 let bytes = strkey::decode_account_id(account_id)?;
15 Self::from_slice(&bytes)
16 }
17
18 pub fn from_slice(data: &[u8]) -> Result<PublicKey> {
20 Ok(PublicKey(
22 data.try_into().map_err(|_| Error::InvalidPublicKey)?,
23 ))
24 }
25
26 pub fn account_id(&self) -> String {
27 strkey::encode_account_id(&self.0)
28 }
29
30 pub fn into_muxed_account(self, id: u64) -> MuxedAccount {
31 let inner = MuxedEd25519PublicKey { key: self, id };
32 MuxedAccount::MuxedEd25519(inner)
33 }
34
35 pub fn to_muxed_account(&self, id: u64) -> MuxedAccount {
36 (*self).into_muxed_account(id)
37 }
38
39 pub fn to_xdr_uint256(&self) -> Result<xdr::Uint256> {
40 Ok(xdr::Uint256(self.0))
41 }
42
43 pub fn to_xdr_public_key(&self) -> Result<xdr::PublicKey> {
44 let uint256 = self.to_xdr_uint256()?;
45 Ok(xdr::PublicKey::PublicKeyTypeEd25519(uint256))
46 }
47
48 pub fn to_xdr_account_id(&self) -> Result<xdr::AccountId> {
49 let public_key = self.to_xdr_public_key()?;
50 Ok(xdr::AccountId(public_key))
51 }
52
53 pub fn from_xdr_public_key(x: &xdr::PublicKey) -> Result<PublicKey> {
54 match x {
55 xdr::PublicKey::PublicKeyTypeEd25519(inner) => Self::from_slice(&inner.0),
56 }
57 }
58
59 pub fn from_xdr_account_id(x: &xdr::AccountId) -> Result<PublicKey> {
60 Self::from_xdr_public_key(&x.0)
61 }
62
63 pub fn as_bytes(&self) -> &[u8] {
64 &self.0
65 }
66
67 pub fn to_xdr(&self) -> Result<xdr::MuxedAccount> {
68 let uint256 = self.to_xdr_uint256()?;
69 Ok(xdr::MuxedAccount::Ed25519(uint256))
70 }
71}
72
73#[derive(Debug, Clone, PartialEq, Eq)]
75pub struct MuxedEd25519PublicKey {
76 key: PublicKey,
77 id: u64,
78}
79
80#[derive(Debug, Clone, PartialEq, Eq)]
81pub enum MuxedAccount {
82 Ed25519(PublicKey),
83 MuxedEd25519(MuxedEd25519PublicKey),
84}
85
86impl MuxedEd25519PublicKey {
87 pub fn new(key: PublicKey, id: u64) -> MuxedEd25519PublicKey {
88 MuxedEd25519PublicKey { key, id }
89 }
90
91 pub fn from_account_id(account_id: &str) -> Result<MuxedEd25519PublicKey> {
92 let (bytes, id) = strkey::decode_muxed_account(account_id)?;
93 Self::from_slice(&bytes, id)
94 }
95
96 pub fn from_slice(data: &[u8], id: u64) -> Result<MuxedEd25519PublicKey> {
98 let key = PublicKey::from_slice(data)?;
99 Ok(MuxedEd25519PublicKey { key, id })
100 }
101
102 pub fn public_key(&self) -> &PublicKey {
104 &self.key
105 }
106
107 pub fn account_id(&self) -> String {
108 strkey::encode_muxed_account(self.key.as_bytes(), self.id)
109 }
110
111 pub fn to_xdr(&self) -> Result<xdr::MuxedAccount> {
112 let uint256 = self.key.to_xdr_uint256()?;
113 let muxed = xdr::MuxedAccountMed25519 {
114 id: self.id,
115 ed25519: uint256,
116 };
117 Ok(xdr::MuxedAccount::MuxedEd25519(muxed))
118 }
119}
120
121impl MuxedAccount {
122 pub fn account_id(&self) -> String {
123 match self {
124 MuxedAccount::Ed25519(pk) => pk.account_id(),
125 MuxedAccount::MuxedEd25519(mx) => mx.account_id(),
126 }
127 }
128
129 pub fn to_xdr(&self) -> Result<xdr::MuxedAccount> {
130 match self {
131 MuxedAccount::Ed25519(pk) => pk.to_xdr(),
132 MuxedAccount::MuxedEd25519(mx) => mx.to_xdr(),
133 }
134 }
135
136 pub fn from_xdr(x: &xdr::MuxedAccount) -> Result<MuxedAccount> {
137 match x {
138 xdr::MuxedAccount::Ed25519(buf) => {
139 let inner = PublicKey::from_slice(&buf.0)?;
140 Ok(MuxedAccount::Ed25519(inner))
141 }
142 xdr::MuxedAccount::MuxedEd25519(mx) => {
143 let inner = MuxedEd25519PublicKey::from_slice(&mx.ed25519.0, mx.id)?;
144 Ok(MuxedAccount::MuxedEd25519(inner))
145 }
146 }
147 }
148}
149
150impl From<PublicKey> for MuxedAccount {
151 fn from(pk: PublicKey) -> Self {
152 MuxedAccount::Ed25519(pk)
153 }
154}
155
156impl From<MuxedEd25519PublicKey> for MuxedAccount {
157 fn from(muxed: MuxedEd25519PublicKey) -> Self {
158 MuxedAccount::MuxedEd25519(muxed)
159 }
160}
161
162impl std::str::FromStr for PublicKey {
163 type Err = crate::error::Error;
164
165 fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
166 let pk = PublicKey::from_account_id(s)?;
167 Ok(pk)
168 }
169}
170
171impl std::fmt::Display for PublicKey {
172 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
173 write!(f, "{}", self.account_id())
174 }
175}