wallet_adapter_common/
utils.rs1use std::{borrow::Cow, time::SystemTime};
2
3use ed25519_dalek::{Signature, Verifier, VerifyingKey};
4
5use crate::{WalletUtilsError, WalletUtilsResult};
6
7pub type PublicKeyBytes = [u8; 32];
9
10pub type SignatureBytes = [u8; 64];
12
13pub struct WalletCommonUtils;
15
16impl WalletCommonUtils {
17 pub fn public_key_rand() -> [u8; 32] {
19 Self::rand_32bytes()
20 }
21
22 pub fn rand_32bytes() -> [u8; 32] {
24 use getrandom::SysRng;
25
26 use rand_chacha::ChaCha12Rng;
27 use rand_core::{Rng, SeedableRng};
28
29 let mut rng = ChaCha12Rng::try_from_rng(&mut SysRng).unwrap();
30 let mut buffer = [0u8; 32];
31
32 rng.fill_bytes(&mut buffer);
33
34 buffer
35 }
36
37 pub fn public_key(public_key_bytes: &[u8; 32]) -> WalletUtilsResult<VerifyingKey> {
39 VerifyingKey::from_bytes(public_key_bytes)
40 .or(Err(WalletUtilsError::InvalidEd25519PublicKeyBytes))
41 }
42
43 pub fn signature(signature_bytes: &[u8; 64]) -> Signature {
45 Signature::from_bytes(signature_bytes)
46 }
47
48 pub fn to32byte_array(bytes: &[u8]) -> WalletUtilsResult<[u8; 32]> {
51 bytes
52 .try_into()
53 .or(Err(WalletUtilsError::Expected32ByteLength))
54 }
55
56 pub fn to64byte_array(bytes: &[u8]) -> WalletUtilsResult<[u8; 64]> {
59 bytes
60 .try_into()
61 .or(Err(WalletUtilsError::Expected64ByteLength))
62 }
63
64 pub fn verify_signature(
66 public_key: VerifyingKey,
67 message: &[u8],
68 signature: Signature,
69 ) -> WalletUtilsResult<()> {
70 public_key
71 .verify(message, &signature)
72 .or(Err(WalletUtilsError::InvalidSignature))
73 }
74
75 pub fn verify(
77 public_key_bytes: &[u8; 32],
78 message_bytes: &[u8],
79 signature_bytes: &[u8; 64],
80 ) -> WalletUtilsResult<()> {
81 let public_key = Self::public_key(public_key_bytes)?;
82 let signature = Self::signature(signature_bytes);
83
84 public_key
85 .verify(message_bytes, &signature)
86 .or(Err(WalletUtilsError::InvalidSignature))
87 }
88
89 pub fn address(public_key: VerifyingKey) -> String {
91 bs58::encode(public_key.as_ref()).into_string()
92 }
93
94 pub fn base58_signature(signature: Signature) -> String {
96 bs58::encode(signature.to_bytes()).into_string()
97 }
98
99 pub fn shorten_base58<'a>(base58_str: &'a str) -> WalletUtilsResult<Cow<'a, str>> {
104 if base58_str.len() < 8 {
105 return Err(WalletUtilsError::InvalidBase58Address);
106 }
107
108 let first_part = &base58_str[..4];
109 let last_part = &base58_str[base58_str.len() - 4..];
110
111 Ok(Cow::Borrowed(first_part) + "..." + last_part)
112 }
113
114 pub fn custom_shorten_base58<'a>(
118 base58_str: &'a str,
119 take: usize,
120 ) -> WalletUtilsResult<Cow<'a, str>> {
121 if base58_str.len() < take + take {
122 return Err(WalletUtilsError::InvalidBase58Address);
123 }
124
125 let first_part = &base58_str[..take];
126 let last_part = &base58_str[base58_str.len() - take..];
127
128 Ok(Cow::Borrowed(first_part) + "..." + last_part)
129 }
130
131 pub fn custom_shorten_address_rl<'a>(
135 base58_address: &'a str,
136 left: usize,
137 right: usize,
138 ) -> WalletUtilsResult<Cow<'a, str>> {
139 if base58_address.len() < left + right {
140 return Err(WalletUtilsError::InvalidBase58Address);
141 }
142
143 let first_part = &base58_address[..left];
144 let last_part = &base58_address[base58_address.len() - right..];
145
146 Ok(Cow::Borrowed(first_part) + "..." + last_part)
147 }
148
149 pub fn to_iso860(system_time: SystemTime) -> humantime::Rfc3339Timestamp {
152 humantime::format_rfc3339_millis(system_time)
153 }
154}