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