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 rand_chacha::ChaCha20Rng;
25 use rand_core::{RngCore, SeedableRng};
26
27 let mut rng = ChaCha20Rng::from_os_rng();
28
29 let mut buffer = [0u8; 32];
30
31 rng.fill_bytes(&mut buffer);
32
33 buffer
34 }
35
36 pub fn public_key(public_key_bytes: &[u8; 32]) -> WalletUtilsResult<VerifyingKey> {
38 VerifyingKey::from_bytes(public_key_bytes)
39 .or(Err(WalletUtilsError::InvalidEd25519PublicKeyBytes))
40 }
41
42 pub fn signature(signature_bytes: &[u8; 64]) -> Signature {
44 Signature::from_bytes(signature_bytes)
45 }
46
47 pub fn to32byte_array(bytes: &[u8]) -> WalletUtilsResult<[u8; 32]> {
50 bytes
51 .try_into()
52 .or(Err(WalletUtilsError::Expected32ByteLength))
53 }
54
55 pub fn to64byte_array(bytes: &[u8]) -> WalletUtilsResult<[u8; 64]> {
58 bytes
59 .try_into()
60 .or(Err(WalletUtilsError::Expected64ByteLength))
61 }
62
63 pub fn verify_signature(
65 public_key: VerifyingKey,
66 message: &[u8],
67 signature: Signature,
68 ) -> WalletUtilsResult<()> {
69 public_key
70 .verify(message, &signature)
71 .or(Err(WalletUtilsError::InvalidSignature))
72 }
73
74 pub fn verify(
76 public_key_bytes: &[u8; 32],
77 message_bytes: &[u8],
78 signature_bytes: &[u8; 64],
79 ) -> WalletUtilsResult<()> {
80 let public_key = Self::public_key(public_key_bytes)?;
81 let signature = Self::signature(signature_bytes);
82
83 public_key
84 .verify(message_bytes, &signature)
85 .or(Err(WalletUtilsError::InvalidSignature))
86 }
87
88 pub fn address(public_key: VerifyingKey) -> String {
90 bs58::encode(public_key.as_ref()).into_string()
91 }
92
93 pub fn base58_signature(signature: Signature) -> String {
95 bs58::encode(signature.to_bytes()).into_string()
96 }
97
98 pub fn shorten_base58<'a>(base58_str: &'a str) -> WalletUtilsResult<Cow<'a, str>> {
103 if base58_str.len() < 8 {
104 return Err(WalletUtilsError::InvalidBase58Address);
105 }
106
107 let first_part = &base58_str[..4];
108 let last_part = &base58_str[base58_str.len() - 4..];
109
110 Ok(Cow::Borrowed(first_part) + "..." + last_part)
111 }
112
113 pub fn custom_shorten_base58<'a>(
117 base58_str: &'a str,
118 take: usize,
119 ) -> WalletUtilsResult<Cow<'a, str>> {
120 if base58_str.len() < take + take {
121 return Err(WalletUtilsError::InvalidBase58Address);
122 }
123
124 let first_part = &base58_str[..take];
125 let last_part = &base58_str[base58_str.len() - take..];
126
127 Ok(Cow::Borrowed(first_part) + "..." + last_part)
128 }
129
130 pub fn custom_shorten_address_rl<'a>(
134 base58_address: &'a str,
135 left: usize,
136 right: usize,
137 ) -> WalletUtilsResult<Cow<'a, str>> {
138 if base58_address.len() < left + right {
139 return Err(WalletUtilsError::InvalidBase58Address);
140 }
141
142 let first_part = &base58_address[..left];
143 let last_part = &base58_address[base58_address.len() - right..];
144
145 Ok(Cow::Borrowed(first_part) + "..." + last_part)
146 }
147
148 pub fn to_iso860(system_time: SystemTime) -> humantime::Rfc3339Timestamp {
151 humantime::format_rfc3339_millis(system_time)
152 }
153}