105 lines
3.1 KiB
Python
105 lines
3.1 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Bootstrap script to generate tests/vectors.json.
|
|
Run this ONCE (online allowed if needed, though this logic is offline)
|
|
to freeze the expected outputs of the current pyhdwallet implementation.
|
|
"""
|
|
import sys
|
|
import json
|
|
import os
|
|
from pathlib import Path
|
|
|
|
# Add src to path so we can import pyhdwallet
|
|
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), "../src")))
|
|
|
|
import pyhdwallet
|
|
from bip_utils import Bip39SeedGenerator
|
|
|
|
def main():
|
|
print("Bootstrapping test vectors...")
|
|
vectors = {}
|
|
|
|
# 1. PGP Fingerprint Vector
|
|
recipient_path = Path(__file__).parent / "data" / "recipient.asc"
|
|
if not recipient_path.exists():
|
|
print(f"Error: {recipient_path} not found. Please create it first.")
|
|
sys.exit(1)
|
|
|
|
with open(recipient_path, "r", encoding="utf-8") as f:
|
|
armored = f.read()
|
|
|
|
# Calculate expected fingerprint using current code logic
|
|
expected_fpr = pyhdwallet.pgp_fingerprint(armored)
|
|
|
|
vectors["pgp"] = {
|
|
"recipient_file": "recipient.asc",
|
|
"expected_fingerprint": expected_fpr
|
|
}
|
|
print(f"PGP: Pinned fingerprint {expected_fpr}")
|
|
|
|
# 2. BIP39 & Derivation Vectors
|
|
mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about"
|
|
|
|
vectors["bip39"] = []
|
|
|
|
# Case A: No Passphrase
|
|
seed_bytes = Bip39SeedGenerator(mnemonic).Generate("")
|
|
seed_hex = seed_bytes.hex()
|
|
|
|
# Generate addresses for all supported chains/profiles
|
|
chains = ["ethereum", "bitcoin", "solana"]
|
|
# Fixed profile names to use underscores instead of hyphens
|
|
sol_profiles = ["phantom_bip44change", "phantom_bip44", "solana_bip39_first32"]
|
|
|
|
derived_data = {}
|
|
|
|
# Run derivation for each sol profile logic
|
|
for profile in sol_profiles:
|
|
res = pyhdwallet.derive_all(
|
|
seed_bytes,
|
|
chains,
|
|
count=5,
|
|
sol_profile=profile,
|
|
export_private=False
|
|
)
|
|
derived_data[profile] = res["addresses"]
|
|
|
|
vectors["bip39"].append({
|
|
"mnemonic": mnemonic,
|
|
"passphrase": "",
|
|
"expected_seed_hex": seed_hex,
|
|
"derived_addresses": derived_data
|
|
})
|
|
|
|
# Case B: With Passphrase (Regression test)
|
|
passphrase = "TREZOR"
|
|
seed_bytes_p = Bip39SeedGenerator(mnemonic).Generate(passphrase)
|
|
seed_hex_p = seed_bytes_p.hex()
|
|
|
|
res_p = pyhdwallet.derive_all(
|
|
seed_bytes_p,
|
|
chains,
|
|
count=1,
|
|
sol_profile="phantom_bip44change",
|
|
export_private=False
|
|
)
|
|
|
|
vectors["bip39"].append({
|
|
"mnemonic": mnemonic,
|
|
"passphrase": passphrase,
|
|
"expected_seed_hex": seed_hex_p,
|
|
"derived_addresses": {"phantom_bip44change": res_p["addresses"]}
|
|
})
|
|
|
|
print("Derivation: Generated vectors for empty and non-empty passphrases.")
|
|
|
|
# 3. Save
|
|
out_path = Path(__file__).parent / "vectors.json"
|
|
with open(out_path, "w", encoding="utf-8") as f:
|
|
json.dump(vectors, f, indent=2)
|
|
|
|
print(f"Success! Vectors written to {out_path}")
|
|
|
|
if __name__ == "__main__":
|
|
main()
|