"""ADR-015 key loader: refuses non-founder phrases before touching the node, derives the key the node's own way, and never puts it on a command line.""" import importlib.util import os import sys import pytest _dir = os.path.join(os.path.dirname(__file__), "..", "tools", "vault") sys.path.insert(0, _dir) _spec = importlib.util.spec_from_file_location("load_founder_key", os.path.join(_dir, "load_founder_key.py")) lfk = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(lfk) import wallet # noqa: E402 PHRASE = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about" ADDR = wallet.derive_from_seed_phrase(PHRASE)["address"] SAMPLE_VERSION = 0xB0 class FakeNode: def __init__(self, log, wallet_name=None): self.log, self.wallet = log, wallet_name def __call__(self, method, *params, stdin=None, ok_fail=False): self.log.append((self.wallet, method, params, stdin)) if method == "listwallets": return [] if method == "loadwallet": return None if method == "createwallet": return {"name": params[0]} if method == "getnewaddress": return "moon1qprobe" if method == "dumpprivkey": return lfk.to_wif("11" * 32, SAMPLE_VERSION) if method == "importprivkey": return "" if method == "getaddressinfo": return {"ismine": params[0] == ADDR} if method == "getbalances": return {"mine": {"trusted": 100, "immature": 0}} raise AssertionError(method) def run(monkeypatch, phrase, founders): monkeypatch.setattr(lfk, "FOUNDER_ADDRESSES", founders) log = [] answers = iter([phrase, ""]) rc = lfk.main(["--cli", "moonbite-cli"], ask=lambda prompt: next(answers), make_cli=lambda cmd, w=None: FakeNode(log, w)) return rc, log def test_wif_roundtrip_uses_the_nodes_version_byte(): wif = lfk.to_wif("01" * 32, SAMPLE_VERSION) assert lfk.wif_version(wif) == SAMPLE_VERSION def test_non_founder_phrase_never_touches_the_node(monkeypatch): with pytest.raises(SystemExit, match="not a founder address"): run(monkeypatch, PHRASE, ["moon1qsomeoneelse"]) def test_founder_phrase_imports_over_stdin_and_verifies(monkeypatch): rc, log = run(monkeypatch, PHRASE, [ADDR]) assert rc == 0 imports = [e for e in log if e[1] == "importprivkey"] assert len(imports) == 1 wallet_name, _, params, stdin = imports[0] assert wallet_name == lfk.WALLET and params == () # nothing on the command line wif = stdin.splitlines()[0] assert lfk.wif_version(wif) == SAMPLE_VERSION # the imported key is the phrase's key raw = lfk.b58decode(wif) assert raw[1:33].hex() == wallet.derive_from_seed_phrase(PHRASE)["private_key"] assert any(e[1] == "getaddressinfo" for e in log)