use blvm_protocol::address::{AddressError, BitcoinAddress, Network};
fn create_p2wpkh_program() -> Vec<u8> {
vec![0x75; 20]
}
fn create_p2wsh_program() -> Vec<u8> {
vec![0x75; 32]
}
fn create_p2tr_program() -> Vec<u8> {
vec![0x75; 32]
}
#[test]
fn test_bech32_mainnet_p2wpkh_encoding() {
let program = create_p2wpkh_program();
let addr = BitcoinAddress::new(Network::Mainnet, 0, program).unwrap();
let encoded = addr.encode().unwrap();
assert!(encoded.starts_with("bc1"));
assert_eq!(addr.witness_version, 0);
assert_eq!(addr.witness_program.len(), 20);
assert_eq!(addr.network, Network::Mainnet);
assert_eq!(addr.address_type(), "P2WPKH");
}
#[test]
fn test_bech32m_mainnet_p2tr_encoding() {
let program = create_p2tr_program();
let addr = BitcoinAddress::new(Network::Mainnet, 1, program).unwrap();
let encoded = addr.encode().unwrap();
assert!(encoded.starts_with("bc1p"));
assert_eq!(addr.witness_version, 1);
assert_eq!(addr.witness_program.len(), 32);
assert_eq!(addr.network, Network::Mainnet);
assert_eq!(addr.address_type(), "P2TR");
assert!(addr.is_taproot());
}
#[test]
fn test_bech32_testnet_encoding() {
let program = create_p2wpkh_program();
let addr = BitcoinAddress::new(Network::Testnet, 0, program).unwrap();
let encoded = addr.encode().unwrap();
assert!(encoded.starts_with("tb1"));
assert_eq!(addr.network, Network::Testnet);
}
#[test]
fn test_bech32_regtest_encoding() {
let program = create_p2wpkh_program();
let addr = BitcoinAddress::new(Network::Regtest, 0, program).unwrap();
let encoded = addr.encode().unwrap();
assert!(encoded.starts_with("bcrt1"));
assert_eq!(addr.network, Network::Regtest);
}
#[test]
fn test_bech32_mainnet_p2wsh_encoding() {
let program = create_p2wsh_program();
let addr = BitcoinAddress::new(Network::Mainnet, 0, program).unwrap();
let encoded = addr.encode().unwrap();
assert!(encoded.starts_with("bc1"));
assert_eq!(addr.witness_version, 0);
assert_eq!(addr.witness_program.len(), 32);
assert_eq!(addr.address_type(), "P2WSH");
}
#[test]
fn test_bech32_decoding_valid_address() {
let program = create_p2wpkh_program();
let addr1 = BitcoinAddress::new(Network::Mainnet, 0, program.clone()).unwrap();
let encoded = addr1.encode().unwrap();
let addr2 = BitcoinAddress::decode(&encoded).unwrap();
assert_eq!(addr2.network, Network::Mainnet);
assert_eq!(addr2.witness_version, 0);
assert_eq!(addr2.witness_program, program);
assert_eq!(addr2.address_type(), "P2WPKH");
}
#[test]
fn test_bech32m_decoding_valid_address() {
let program = create_p2tr_program();
let addr1 = BitcoinAddress::new(Network::Mainnet, 1, program.clone()).unwrap();
let encoded = addr1.encode().unwrap();
let addr2 = BitcoinAddress::decode(&encoded).unwrap();
assert_eq!(addr2.network, Network::Mainnet);
assert_eq!(addr2.witness_version, 1);
assert_eq!(addr2.witness_program, program);
assert!(addr2.is_taproot());
}
#[test]
fn test_address_roundtrip_encoding() {
let program = create_p2wpkh_program();
let addr1 = BitcoinAddress::new(Network::Mainnet, 0, program.clone()).unwrap();
let addr_str = addr1.encode().unwrap();
let addr2 = BitcoinAddress::decode(&addr_str).unwrap();
assert_eq!(addr1.network, addr2.network);
assert_eq!(addr1.witness_version, addr2.witness_version);
assert_eq!(addr1.witness_program, addr2.witness_program);
}
#[test]
fn test_address_roundtrip_taproot() {
let program = create_p2tr_program();
let addr1 = BitcoinAddress::new(Network::Mainnet, 1, program.clone()).unwrap();
let addr_str = addr1.encode().unwrap();
let addr2 = BitcoinAddress::decode(&addr_str).unwrap();
assert_eq!(addr1.network, addr2.network);
assert_eq!(addr1.witness_version, addr2.witness_version);
assert_eq!(addr1.witness_program, addr2.witness_program);
assert!(addr2.is_taproot());
}
#[test]
fn test_bech32_decoding_invalid_hrp() {
let invalid_addr = "invalid1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4";
let result = BitcoinAddress::decode(invalid_addr);
assert!(result.is_err());
match result {
Err(AddressError::InvalidHRP) | Err(AddressError::InvalidEncoding) => {}
Err(e) => panic!("Unexpected error: {:?}", e),
Ok(_) => panic!("Should have failed"),
}
}
#[test]
fn test_invalid_witness_version() {
let program = create_p2wpkh_program();
let result = BitcoinAddress::new(Network::Mainnet, 17, program);
assert!(matches!(result, Err(AddressError::InvalidWitnessVersion)));
}
#[test]
fn test_invalid_witness_length_p2wpkh() {
let program = vec![0x75; 19]; let result = BitcoinAddress::new(Network::Mainnet, 0, program);
assert!(matches!(result, Err(AddressError::InvalidWitnessLength)));
}
#[test]
fn test_invalid_witness_length_p2wsh() {
let program = vec![0x75; 31]; let result = BitcoinAddress::new(Network::Mainnet, 0, program);
assert!(matches!(result, Err(AddressError::InvalidWitnessLength)));
}
#[test]
fn test_invalid_witness_length_taproot() {
let program = vec![0x75; 20]; let result = BitcoinAddress::new(Network::Mainnet, 1, program);
assert!(matches!(result, Err(AddressError::InvalidWitnessLength)));
}
#[test]
fn test_address_network_mismatch() {
let program = create_p2wpkh_program();
let mainnet_addr = BitcoinAddress::new(Network::Mainnet, 0, program.clone()).unwrap();
let testnet_addr = BitcoinAddress::new(Network::Testnet, 0, program).unwrap();
let mainnet_encoded = mainnet_addr.encode().unwrap();
let testnet_encoded = testnet_addr.encode().unwrap();
assert_ne!(mainnet_encoded, testnet_encoded);
assert!(mainnet_encoded.starts_with("bc1"));
assert!(testnet_encoded.starts_with("tb1"));
}
#[test]
fn test_is_segwit_p2wpkh() {
let program = create_p2wpkh_program();
let addr = BitcoinAddress::new(Network::Mainnet, 0, program).unwrap();
assert!(addr.is_segwit());
assert!(!addr.is_taproot());
}
#[test]
fn test_is_segwit_p2wsh() {
let program = create_p2wsh_program();
let addr = BitcoinAddress::new(Network::Mainnet, 0, program).unwrap();
assert!(addr.is_segwit());
assert!(!addr.is_taproot());
}
#[test]
fn test_is_taproot() {
let program = create_p2tr_program();
let addr = BitcoinAddress::new(Network::Mainnet, 1, program).unwrap();
assert!(addr.is_taproot());
assert!(!addr.is_segwit());
}
#[test]
fn test_address_type_detection() {
let p2wpkh = BitcoinAddress::new(Network::Mainnet, 0, create_p2wpkh_program()).unwrap();
assert_eq!(p2wpkh.address_type(), "P2WPKH");
let p2wsh = BitcoinAddress::new(Network::Mainnet, 0, create_p2wsh_program()).unwrap();
assert_eq!(p2wsh.address_type(), "P2WSH");
let p2tr = BitcoinAddress::new(Network::Mainnet, 1, create_p2tr_program()).unwrap();
assert_eq!(p2tr.address_type(), "P2TR");
}
#[test]
fn test_network_hrp_values() {
assert_eq!(Network::Mainnet.hrp(), "bc");
assert_eq!(Network::Testnet.hrp(), "tb");
assert_eq!(Network::Regtest.hrp(), "bcrt");
}
#[test]
fn test_all_networks_p2wpkh() {
let program = create_p2wpkh_program();
let mainnet = BitcoinAddress::new(Network::Mainnet, 0, program.clone()).unwrap();
let testnet = BitcoinAddress::new(Network::Testnet, 0, program.clone()).unwrap();
let regtest = BitcoinAddress::new(Network::Regtest, 0, program).unwrap();
assert!(mainnet.encode().unwrap().starts_with("bc1"));
assert!(testnet.encode().unwrap().starts_with("tb1"));
assert!(regtest.encode().unwrap().starts_with("bcrt1"));
}
#[test]
fn test_all_networks_p2tr() {
let program = create_p2tr_program();
let mainnet = BitcoinAddress::new(Network::Mainnet, 1, program.clone()).unwrap();
let testnet = BitcoinAddress::new(Network::Testnet, 1, program.clone()).unwrap();
let regtest = BitcoinAddress::new(Network::Regtest, 1, program).unwrap();
assert!(mainnet.encode().unwrap().starts_with("bc1p"));
assert!(testnet.encode().unwrap().starts_with("tb1p"));
assert!(regtest.encode().unwrap().starts_with("bcrt1p"));
}