Skip to main content

thruput_signing/
strkey.rs

1//! Text encodings shared by native clients. `StrKeys` encode type and checksum, not network.
2//! Contract addresses, public keys and private seeds are deliberately separate operations.
3
4use thruput_xdr::types::ContractAddress;
5use zeroize::Zeroizing;
6
7/// Invalid encoding, checksum, length or `StrKey` type. Never includes the supplied text.
8#[derive(Debug, Clone, Copy, PartialEq, Eq, thiserror::Error)]
9pub enum Error {
10    /// Expected a contract address, never an Ed25519 public key.
11    #[error("contract address must be a Z StrKey or base58 encoding of exactly 32 bytes")]
12    ContractAddress,
13    /// Expected an Ed25519 public key, never a contract address.
14    #[error("Ed25519 public key must be a G StrKey or base58 encoding of exactly 32 bytes")]
15    PublicKey,
16    /// Expected the 32-byte private seed, not a stored 64-byte keypair.
17    #[error("expected an S StrKey or base58 encoding of a 32-byte Ed25519 seed")]
18    SecretSeed,
19}
20
21/// Parse a checksummed Z `StrKey` or base58 address of exactly 32 bytes.
22pub fn parse_contract_address(value: &str) -> Result<ContractAddress, Error> {
23    thruput_encoding::parse_address(value)
24        .map(Into::into)
25        .map_err(|_| Error::ContractAddress)
26}
27
28/// Encode the same contract address bytes as a Z `StrKey`; no address derivation is performed.
29pub fn format_contract_address(address: &ContractAddress) -> String {
30    let mut bytes = [0; 32];
31    bytes.copy_from_slice(address.as_ref());
32    thruput_encoding::address_strkey(&bytes)
33}
34
35/// Parse a G `StrKey` or base58 public key. Does not derive an account address.
36pub fn parse_public_key(value: &str) -> Result<[u8; 32], Error> {
37    thruput_encoding::parse_public_key(value).map_err(|_| Error::PublicKey)
38}
39
40/// Encode raw Ed25519 public key bytes as a G `StrKey`, not a wallet address.
41pub fn format_public_key(key: &[u8; 32]) -> String {
42    thruput_encoding::public_key_strkey(key)
43}
44
45/// Parse an S `StrKey` or base58 seed of exactly 32 bytes. Secret buffers are zeroed on drop.
46/// The caller must also protect and clear the input string it owns.
47pub fn parse_secret_seed(value: &str) -> Result<Zeroizing<[u8; 32]>, Error> {
48    thruput_encoding::parse_secret_seed(value).map_err(|_| Error::SecretSeed)
49}
50
51/// Explicitly export a private seed as an S `StrKey`. The returned buffer is zeroed on drop.
52pub fn format_secret_seed(seed: &[u8; 32]) -> Zeroizing<String> {
53    thruput_encoding::secret_seed_strkey(seed)
54}