use crate::crypto::ed25519::public_from_seed;
use crate::crypto::secp256k1::SecpPrivateKey;
use crate::pubkey::PubKey;
use crate::script::Script;
use crate::{parse_bitcoin_based_address, parse_evm_address, parse_massa_address};
fn arr32(s: &str) -> [u8; 32] {
let v = hex::decode(s).unwrap();
let mut a = [0u8; 32];
a.copy_from_slice(&v);
a
}
fn secp_script() -> Script {
let sk = SecpPrivateKey::from_bytes(&arr32(
"eb696a065ef48a2192da5b28b694f87544b30fae8327c4510137a922f32c6dcf",
))
.unwrap();
Script::new(sk.public_key())
}
#[test]
fn addresses_generate_and_roundtrip() {
let s = secp_script();
let cases: &[(&str, &str, &str)] = &[
(
"eth",
"ethereum",
"0x2AeB8ADD8337360E088B7D9ce4e857b9BE60f3a7",
),
("p2pkh", "bitcoin", "1C2yfT2NNAPPHBqXQxxBPvguht2whJWRSi"),
(
"p2pkh",
"bitcoincash",
"bitcoincash:qpusjxtjrpkyf843mmfzk78yp5qfhhcq3yv38ma5lm",
),
("p2pkh", "litecoin", "LWFvvfLCSpdSXzXgb6wUfwkfv6QDipAzJc"),
(
"p2pkh",
"electraproto",
"PKd9pRRDR5saG2WHm3Gi4pfBKdCpm1YfY3",
),
(
"p2sh:p2pkh",
"litecoin",
"MNBNbudWqRT5MhorGVnpk7DDuMX5XCxKnR",
),
(
"p2wpkh",
"bitcoin",
"bc1q0yy3juscd3zfavw76g4h3eqdqzda7qyf58rj4m",
),
(
"p2wpkh",
"litecoin",
"ltc1q0yy3juscd3zfavw76g4h3eqdqzda7qyfsmekdt",
),
(
"p2wpkh",
"electraproto",
"ep1q0yy3juscd3zfavw76g4h3eqdqzda7qyf4r3klt",
),
(
"p2wsh:p2wpkh",
"bitcoin",
"bc1qwg7r0yn6t7ctfaplxuwvlu2yk8q6fd3xsvr3lkq5ud4ylsecczzqgq9ste",
),
];
for (fmt, net, want) in cases {
let sout = s.out(fmt).unwrap_or_else(|e| panic!("generate {fmt}: {e}"));
let addr = sout
.address(&[net])
.unwrap_or_else(|e| panic!("addr {fmt}: {e}"));
assert_eq!(&addr, want, "format {fmt} net {net}");
let out = if want.starts_with("0x") {
parse_evm_address(want).unwrap()
} else if *net != "electraproto" {
parse_bitcoin_based_address("auto", want).unwrap()
} else {
parse_bitcoin_based_address(net, want).unwrap()
};
assert_eq!(out.script, sout.script, "script mismatch for {want}");
}
}
#[test]
fn taproot_parse_roundtrip() {
let a = "bc1pgf6m46mr8c55veujxg3qvqxfektwmmpfrt5mhwtvwrzeacmm7xaqdndj5l";
let addr = parse_bitcoin_based_address("bitcoin", a).unwrap();
let b = addr.address(&[]).unwrap();
assert_eq!(b, a);
}
#[test]
fn massa_address() {
let seed = arr32("20a1c9d559159085c82ae54e35f332a2d54aab952dd5832c42d06fb0548d5f88");
let pk = public_from_seed(&seed);
let s = Script::new(PubKey::Ed25519(pk));
let sout = s.out("massa").unwrap();
let addr = sout.address(&["massa"]).unwrap();
assert_eq!(addr, "AU16f3K8uWS8cSJaXb7oDzKUZRqt7392eFPtq2bBBop9PVbyXkMs");
let out = parse_massa_address(&addr).unwrap();
assert_eq!(out.script, sout.script);
}
#[test]
fn evm_lowercase_and_checksum() {
let checksummed = "0x2AeB8ADD8337360E088B7D9ce4e857b9BE60f3a7";
assert!(parse_evm_address(checksummed).is_ok());
assert!(parse_evm_address(&checksummed.to_lowercase()).is_ok());
let bad = "0x2aEb8ADD8337360E088B7D9ce4e857b9BE60f3a7";
assert!(parse_evm_address(bad).is_err());
}