use bech32::{self, Bech32m, Hrp};
use hex::decode as hex_to_bytes;
use spark_address::{
Network, SparkAddressData, SparkAddressError, decode_spark_address, encode_spark_address,
};
const PUBKEY: &str = "0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798";
const TAG: u8 = 0x0a;
#[test]
fn unknown_prefix() {
let key_bytes = hex_to_bytes(PUBKEY).unwrap();
let mut proto = Vec::with_capacity(2 + key_bytes.len());
proto.push(TAG);
proto.push(key_bytes.len() as u8);
proto.extend_from_slice(&key_bytes);
let hrp = Hrp::parse("xx").unwrap();
let addr = bech32::encode::<Bech32m>(hrp, &proto).unwrap();
match decode_spark_address(&addr) {
Err(SparkAddressError::UnknownPrefix(_)) => {}
other => panic!("expected UnknownPrefix, got {:?}", other),
}
}
#[test]
fn bad_proto_tag() {
let data = SparkAddressData {
identity_public_key: PUBKEY.into(),
network: Network::Mainnet,
};
let good_addr = encode_spark_address(&data).unwrap();
let (hrp, mut proto) = bech32::decode(&good_addr).unwrap();
proto[0] ^= 0x01;
let broken_addr = bech32::encode::<Bech32m>(hrp, &proto).unwrap();
match decode_spark_address(&broken_addr) {
Err(SparkAddressError::BadProto) => {}
other => panic!("expected BadProto, got {:?}", other),
}
}
#[test]
fn wrong_key_length_encode() {
let short_key = "03".to_string() + &"00".repeat(31); let data = SparkAddressData {
identity_public_key: short_key,
network: Network::Mainnet,
};
match encode_spark_address(&data) {
Err(SparkAddressError::WrongKeyLength(32)) => {}
other => panic!("expected WrongKeyLength(32), got {:?}", other),
}
}
#[test]
fn wrong_key_length_decode() {
let key_bytes = vec![0u8; 32];
let mut proto = Vec::with_capacity(2 + key_bytes.len());
proto.push(TAG);
proto.push(key_bytes.len() as u8);
proto.extend_from_slice(&key_bytes);
let hrp = Hrp::parse("sp").unwrap();
let addr = bech32::encode::<Bech32m>(hrp, &proto).unwrap();
match decode_spark_address(&addr) {
Err(SparkAddressError::WrongKeyLength(32)) => {}
other => panic!("expected WrongKeyLength(32), got {:?}", other),
}
}
#[test]
fn mixed_case_address() {
let data = SparkAddressData {
identity_public_key: PUBKEY.into(),
network: Network::Mainnet,
};
let good_addr = encode_spark_address(&data).unwrap();
let mut chars: Vec<char> = good_addr.chars().collect();
chars[0] = chars[0].to_ascii_uppercase();
let bad_addr: String = chars.into_iter().collect();
match decode_spark_address(&bad_addr) {
Err(SparkAddressError::MixedCase) => {}
other => panic!("expected MixedCase, got {:?}", other),
}
}
#[test]
fn checksum_error() {
let data = SparkAddressData {
identity_public_key: PUBKEY.into(),
network: Network::Mainnet,
};
let mut addr = encode_spark_address(&data).unwrap();
let last = addr.pop().unwrap();
let replacement = if last != 'q' { 'q' } else { 'p' }; addr.push(replacement);
match decode_spark_address(&addr) {
Err(SparkAddressError::InvalidBech32(_)) => {}
other => panic!("expected InvalidBech32, got {:?}", other),
}
}