test: add offline integrity test suite with frozen vectors
This commit is contained in:
104
tests/bootstrap_vectors.py
Normal file
104
tests/bootstrap_vectors.py
Normal file
@@ -0,0 +1,104 @@
|
||||
#!/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()
|
||||
136
tests/test_vectors.py
Normal file
136
tests/test_vectors.py
Normal file
@@ -0,0 +1,136 @@
|
||||
import sys
|
||||
import os
|
||||
import json
|
||||
import pytest
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
# Add src to path at the very top
|
||||
TEST_DIR = Path(__file__).parent
|
||||
SRC_DIR = TEST_DIR.parent / "src"
|
||||
sys.path.insert(0, str(SRC_DIR))
|
||||
|
||||
import pyhdwallet
|
||||
from bip_utils import Bip39SeedGenerator
|
||||
|
||||
DATA_DIR = TEST_DIR / "data"
|
||||
VECTORS_FILE = TEST_DIR / "vectors.json"
|
||||
|
||||
@pytest.fixture
|
||||
def vectors():
|
||||
if not VECTORS_FILE.exists():
|
||||
pytest.fail("tests/vectors.json missing. Run tests/bootstrap_vectors.py first.")
|
||||
with open(VECTORS_FILE, "r") as f:
|
||||
return json.load(f)
|
||||
|
||||
@pytest.fixture
|
||||
def recipient_key_content():
|
||||
path = DATA_DIR / "recipient.asc"
|
||||
if not path.exists():
|
||||
pytest.fail("tests/data/recipient.asc missing.")
|
||||
with open(path, "r", encoding="utf-8") as f:
|
||||
return f.read()
|
||||
|
||||
def test_pgp_fingerprint_calculation(vectors, recipient_key_content):
|
||||
"""
|
||||
Verifies that pgp_fingerprint computes the expected fingerprint
|
||||
for the stored recipient key.
|
||||
"""
|
||||
expected = vectors["pgp"]["expected_fingerprint"]
|
||||
actual = pyhdwallet.pgp_fingerprint(recipient_key_content)
|
||||
assert actual == expected, "Fingerprint calculation logic has changed!"
|
||||
|
||||
def test_pgp_require_fingerprint_match(vectors):
|
||||
"""
|
||||
Verifies the safety check require_fingerprint_match enforces exact matches.
|
||||
"""
|
||||
expected = vectors["pgp"]["expected_fingerprint"]
|
||||
|
||||
# Should not raise
|
||||
pyhdwallet.require_fingerprint_match(expected, expected, "test")
|
||||
|
||||
# Should raise on mismatch
|
||||
wrong = expected.replace("A", "B") if "A" in expected else expected.replace("0", "1")
|
||||
with pytest.raises(ValueError, match="test: PGP fingerprint mismatch"):
|
||||
pyhdwallet.require_fingerprint_match(wrong, expected, "test")
|
||||
|
||||
def test_bip39_seed_derivation(vectors):
|
||||
"""
|
||||
Verifies that mnemonics convert to seeds exactly as they did at bootstrap time.
|
||||
"""
|
||||
for case in vectors["bip39"]:
|
||||
mnemonic = case["mnemonic"]
|
||||
passphrase = case["passphrase"]
|
||||
expected_hex = case["expected_seed_hex"]
|
||||
|
||||
# Verify internal Bip39SeedGenerator usage matches expected hex
|
||||
actual_bytes = Bip39SeedGenerator(mnemonic).Generate(passphrase)
|
||||
assert actual_bytes.hex() == expected_hex
|
||||
|
||||
def test_address_derivation_integrity(vectors):
|
||||
"""
|
||||
Verifies derive_all produces the exact same addresses for supported chains.
|
||||
"""
|
||||
for case in vectors["bip39"]:
|
||||
seed_hex = case["expected_seed_hex"]
|
||||
seed_bytes = bytes.fromhex(seed_hex)
|
||||
|
||||
for profile, expected_addresses in case["derived_addresses"].items():
|
||||
# Infer count from ethereum addresses in the expected data
|
||||
# (Ethereum always generates `count` addresses, unlike Solana which depends on profile)
|
||||
count = len(expected_addresses.get("ethereum", []))
|
||||
|
||||
result = pyhdwallet.derive_all(
|
||||
seed_bytes,
|
||||
chains=["ethereum", "bitcoin", "solana"],
|
||||
count=count,
|
||||
sol_profile=profile,
|
||||
export_private=False
|
||||
)
|
||||
assert result["addresses"] == expected_addresses, f"Mismatch for profile {profile}"
|
||||
|
||||
def test_cli_recover_smoke(tmp_path, vectors):
|
||||
"""
|
||||
Runs the CLI in a subprocess to verify end-to-end wiring
|
||||
without network (recover mode).
|
||||
"""
|
||||
vector = vectors["bip39"][0]
|
||||
mnemonic = vector["mnemonic"]
|
||||
expected_fp = vectors["pgp"]["expected_fingerprint"]
|
||||
recipient_file = DATA_DIR / "recipient.asc"
|
||||
|
||||
# 1. Successful Recovery
|
||||
cmd = [
|
||||
sys.executable, "src/pyhdwallet.py", "recover",
|
||||
"--mnemonic-stdin",
|
||||
"--pgp-pubkey-file", str(recipient_file),
|
||||
"--expected-fingerprint", expected_fp,
|
||||
"--file",
|
||||
"--wallet-location", str(tmp_path),
|
||||
"--off-screen",
|
||||
"--zip-password-mode", "auto"
|
||||
]
|
||||
|
||||
result = subprocess.run(
|
||||
cmd,
|
||||
input=mnemonic.encode("utf-8"),
|
||||
capture_output=True
|
||||
)
|
||||
|
||||
assert result.returncode == 0, f"CLI failed: {result.stderr.decode()}"
|
||||
zips = list(tmp_path.glob("*.zip"))
|
||||
assert len(zips) == 1, "Expected exactly one zip file output"
|
||||
|
||||
# 2. Failed Recovery (Wrong Fingerprint)
|
||||
wrong_fp = expected_fp.replace("A", "B")
|
||||
cmd_fail = list(cmd)
|
||||
cmd_fail[cmd_fail.index(expected_fp)] = wrong_fp
|
||||
|
||||
result_fail = subprocess.run(
|
||||
cmd_fail,
|
||||
input=mnemonic.encode("utf-8"),
|
||||
capture_output=True
|
||||
)
|
||||
|
||||
assert result_fail.returncode != 0
|
||||
assert b"fingerprint mismatch" in result_fail.stderr or b"fingerprint mismatch" in result_fail.stdout
|
||||
482
tests/vectors.json
Normal file
482
tests/vectors.json
Normal file
@@ -0,0 +1,482 @@
|
||||
{
|
||||
"pgp": {
|
||||
"recipient_file": "recipient.asc",
|
||||
"expected_fingerprint": "A27B96F2B169B5491013D2DA892B822C14A9AA18"
|
||||
},
|
||||
"bip39": [
|
||||
{
|
||||
"mnemonic": "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about",
|
||||
"passphrase": "",
|
||||
"expected_seed_hex": "5eb00bbddcf069084889a8ab9155568165f5c453ccb85e70811aaed6f6da5fc19a5ac40b389cd370d086206dec8aa6c43daea6690f20ad3d8d48b2d2ce9e38e4",
|
||||
"derived_addresses": {
|
||||
"phantom_bip44change": {
|
||||
"ethereum": [
|
||||
{
|
||||
"index": 0,
|
||||
"path": "m/44'/60'/0'/0/0",
|
||||
"address": "0x9858EfFD232B4033E47d90003D41EC34EcaEda94"
|
||||
},
|
||||
{
|
||||
"index": 1,
|
||||
"path": "m/44'/60'/0'/0/1",
|
||||
"address": "0x6Fac4D18c912343BF86fa7049364Dd4E424Ab9C0"
|
||||
},
|
||||
{
|
||||
"index": 2,
|
||||
"path": "m/44'/60'/0'/0/2",
|
||||
"address": "0xb6716976A3ebe8D39aCEB04372f22Ff8e6802D7A"
|
||||
},
|
||||
{
|
||||
"index": 3,
|
||||
"path": "m/44'/60'/0'/0/3",
|
||||
"address": "0xF3f50213C1d2e255e4B2bAD430F8A38EEF8D718E"
|
||||
},
|
||||
{
|
||||
"index": 4,
|
||||
"path": "m/44'/60'/0'/0/4",
|
||||
"address": "0x51cA8ff9f1C0a99f88E86B8112eA3237F55374cA"
|
||||
}
|
||||
],
|
||||
"solana": [
|
||||
{
|
||||
"index": 0,
|
||||
"path": "m/44'/501'/0'/0'",
|
||||
"address": "HAgk14JpMQLgt6rVgv7cBQFJWFto5Dqxi472uT3DKpqk"
|
||||
},
|
||||
{
|
||||
"index": 1,
|
||||
"path": "m/44'/501'/1'/0'",
|
||||
"address": "Hh8QwFUA6MtVu1qAoq12ucvFHNwCcVTV7hpWjeY1Hztb"
|
||||
},
|
||||
{
|
||||
"index": 2,
|
||||
"path": "m/44'/501'/2'/0'",
|
||||
"address": "7WktogJEd2wQ9eH2oWusmcoFTgeYi6rS632UviTBJ2jm"
|
||||
},
|
||||
{
|
||||
"index": 3,
|
||||
"path": "m/44'/501'/3'/0'",
|
||||
"address": "3YqEpfo3c818GhvbQ1UmVY1nJxw16vtu4JB9peJXT94k"
|
||||
},
|
||||
{
|
||||
"index": 4,
|
||||
"path": "m/44'/501'/4'/0'",
|
||||
"address": "6nod592sTfEWD3VSVPdQndLMVBCNmMc6ngt7MyGBK21j"
|
||||
}
|
||||
],
|
||||
"bitcoin": [
|
||||
{
|
||||
"index": 0,
|
||||
"path": "m/84'/0'/0'/0/0",
|
||||
"address_type": "native_segwit",
|
||||
"address": "bc1qcr8te4kr609gcawutmrza0j4xv80jy8z306fyu"
|
||||
},
|
||||
{
|
||||
"index": 0,
|
||||
"path": "m/49'/0'/0'/0/0",
|
||||
"address_type": "segwit",
|
||||
"address": "37VucYSaXLCAsxYyAPfbSi9eh4iEcbShgf"
|
||||
},
|
||||
{
|
||||
"index": 0,
|
||||
"path": "m/44'/0'/0'/0/0",
|
||||
"address_type": "legacy",
|
||||
"address": "1LqBGSKuX5yYUonjxT5qGfpUsXKYYWeabA"
|
||||
},
|
||||
{
|
||||
"index": 1,
|
||||
"path": "m/84'/0'/0'/0/1",
|
||||
"address_type": "native_segwit",
|
||||
"address": "bc1qnjg0jd8228aq7egyzacy8cys3knf9xvrerkf9g"
|
||||
},
|
||||
{
|
||||
"index": 1,
|
||||
"path": "m/49'/0'/0'/0/1",
|
||||
"address_type": "segwit",
|
||||
"address": "3LtMnn87fqUeHBUG414p9CWwnoV6E2pNKS"
|
||||
},
|
||||
{
|
||||
"index": 1,
|
||||
"path": "m/44'/0'/0'/0/1",
|
||||
"address_type": "legacy",
|
||||
"address": "1Ak8PffB2meyfYnbXZR9EGfLfFZVpzJvQP"
|
||||
},
|
||||
{
|
||||
"index": 2,
|
||||
"path": "m/84'/0'/0'/0/2",
|
||||
"address_type": "native_segwit",
|
||||
"address": "bc1qp59yckz4ae5c4efgw2s5wfyvrz0ala7rgvuz8z"
|
||||
},
|
||||
{
|
||||
"index": 2,
|
||||
"path": "m/49'/0'/0'/0/2",
|
||||
"address_type": "segwit",
|
||||
"address": "3B4cvWGR8X6Xs8nvTxVUoMJV77E4f7oaia"
|
||||
},
|
||||
{
|
||||
"index": 2,
|
||||
"path": "m/44'/0'/0'/0/2",
|
||||
"address_type": "legacy",
|
||||
"address": "1MNF5RSaabFwcbtJirJwKnDytsXXEsVsNb"
|
||||
},
|
||||
{
|
||||
"index": 3,
|
||||
"path": "m/84'/0'/0'/0/3",
|
||||
"address_type": "native_segwit",
|
||||
"address": "bc1qgl5vlg0zdl7yvprgxj9fevsc6q6x5dmcyk3cn3"
|
||||
},
|
||||
{
|
||||
"index": 3,
|
||||
"path": "m/49'/0'/0'/0/3",
|
||||
"address_type": "segwit",
|
||||
"address": "38CahkVftQneLonbWtfWxiiaT2fdnzsEAN"
|
||||
},
|
||||
{
|
||||
"index": 3,
|
||||
"path": "m/44'/0'/0'/0/3",
|
||||
"address_type": "legacy",
|
||||
"address": "1MVGa13XFvvpKGZdX389iU8b3qwtmAyrsJ"
|
||||
},
|
||||
{
|
||||
"index": 4,
|
||||
"path": "m/84'/0'/0'/0/4",
|
||||
"address_type": "native_segwit",
|
||||
"address": "bc1qm97vqzgj934vnaq9s53ynkyf9dgr05rargr04n"
|
||||
},
|
||||
{
|
||||
"index": 4,
|
||||
"path": "m/49'/0'/0'/0/4",
|
||||
"address_type": "segwit",
|
||||
"address": "37mbeJptxfQC6SNNLJ9a8efCY4BwBh5Kak"
|
||||
},
|
||||
{
|
||||
"index": 4,
|
||||
"path": "m/44'/0'/0'/0/4",
|
||||
"address_type": "legacy",
|
||||
"address": "1Gka4JdwhLxRwXaC6oLNH4YuEogeeSwqW7"
|
||||
}
|
||||
]
|
||||
},
|
||||
"phantom_bip44": {
|
||||
"ethereum": [
|
||||
{
|
||||
"index": 0,
|
||||
"path": "m/44'/60'/0'/0/0",
|
||||
"address": "0x9858EfFD232B4033E47d90003D41EC34EcaEda94"
|
||||
},
|
||||
{
|
||||
"index": 1,
|
||||
"path": "m/44'/60'/0'/0/1",
|
||||
"address": "0x6Fac4D18c912343BF86fa7049364Dd4E424Ab9C0"
|
||||
},
|
||||
{
|
||||
"index": 2,
|
||||
"path": "m/44'/60'/0'/0/2",
|
||||
"address": "0xb6716976A3ebe8D39aCEB04372f22Ff8e6802D7A"
|
||||
},
|
||||
{
|
||||
"index": 3,
|
||||
"path": "m/44'/60'/0'/0/3",
|
||||
"address": "0xF3f50213C1d2e255e4B2bAD430F8A38EEF8D718E"
|
||||
},
|
||||
{
|
||||
"index": 4,
|
||||
"path": "m/44'/60'/0'/0/4",
|
||||
"address": "0x51cA8ff9f1C0a99f88E86B8112eA3237F55374cA"
|
||||
}
|
||||
],
|
||||
"solana": [
|
||||
{
|
||||
"index": 0,
|
||||
"path": "m/44'/501'/0'",
|
||||
"address": "GjJyeC1r2RgkuoCWMyPYkCWSGSGLcz266EaAkLA27AhL"
|
||||
},
|
||||
{
|
||||
"index": 1,
|
||||
"path": "m/44'/501'/1'",
|
||||
"address": "ANf3TEKFL6jPWjzkndo4CbnNdUNkBk4KHPggJs2nu8Xi"
|
||||
},
|
||||
{
|
||||
"index": 2,
|
||||
"path": "m/44'/501'/2'",
|
||||
"address": "Ag74i82rUZBTgMGLacCA1ZLnotvAca8CLscXcrG6Nwem"
|
||||
},
|
||||
{
|
||||
"index": 3,
|
||||
"path": "m/44'/501'/3'",
|
||||
"address": "weCFpgyyyrzum6nA8XdmJXjDGDTXmG5P2DdgHv59hgQ"
|
||||
},
|
||||
{
|
||||
"index": 4,
|
||||
"path": "m/44'/501'/4'",
|
||||
"address": "4w6V162fV7HJQNma7vZvxjunqmkie8hM2x1DqaFQqxqL"
|
||||
}
|
||||
],
|
||||
"bitcoin": [
|
||||
{
|
||||
"index": 0,
|
||||
"path": "m/84'/0'/0'/0/0",
|
||||
"address_type": "native_segwit",
|
||||
"address": "bc1qcr8te4kr609gcawutmrza0j4xv80jy8z306fyu"
|
||||
},
|
||||
{
|
||||
"index": 0,
|
||||
"path": "m/49'/0'/0'/0/0",
|
||||
"address_type": "segwit",
|
||||
"address": "37VucYSaXLCAsxYyAPfbSi9eh4iEcbShgf"
|
||||
},
|
||||
{
|
||||
"index": 0,
|
||||
"path": "m/44'/0'/0'/0/0",
|
||||
"address_type": "legacy",
|
||||
"address": "1LqBGSKuX5yYUonjxT5qGfpUsXKYYWeabA"
|
||||
},
|
||||
{
|
||||
"index": 1,
|
||||
"path": "m/84'/0'/0'/0/1",
|
||||
"address_type": "native_segwit",
|
||||
"address": "bc1qnjg0jd8228aq7egyzacy8cys3knf9xvrerkf9g"
|
||||
},
|
||||
{
|
||||
"index": 1,
|
||||
"path": "m/49'/0'/0'/0/1",
|
||||
"address_type": "segwit",
|
||||
"address": "3LtMnn87fqUeHBUG414p9CWwnoV6E2pNKS"
|
||||
},
|
||||
{
|
||||
"index": 1,
|
||||
"path": "m/44'/0'/0'/0/1",
|
||||
"address_type": "legacy",
|
||||
"address": "1Ak8PffB2meyfYnbXZR9EGfLfFZVpzJvQP"
|
||||
},
|
||||
{
|
||||
"index": 2,
|
||||
"path": "m/84'/0'/0'/0/2",
|
||||
"address_type": "native_segwit",
|
||||
"address": "bc1qp59yckz4ae5c4efgw2s5wfyvrz0ala7rgvuz8z"
|
||||
},
|
||||
{
|
||||
"index": 2,
|
||||
"path": "m/49'/0'/0'/0/2",
|
||||
"address_type": "segwit",
|
||||
"address": "3B4cvWGR8X6Xs8nvTxVUoMJV77E4f7oaia"
|
||||
},
|
||||
{
|
||||
"index": 2,
|
||||
"path": "m/44'/0'/0'/0/2",
|
||||
"address_type": "legacy",
|
||||
"address": "1MNF5RSaabFwcbtJirJwKnDytsXXEsVsNb"
|
||||
},
|
||||
{
|
||||
"index": 3,
|
||||
"path": "m/84'/0'/0'/0/3",
|
||||
"address_type": "native_segwit",
|
||||
"address": "bc1qgl5vlg0zdl7yvprgxj9fevsc6q6x5dmcyk3cn3"
|
||||
},
|
||||
{
|
||||
"index": 3,
|
||||
"path": "m/49'/0'/0'/0/3",
|
||||
"address_type": "segwit",
|
||||
"address": "38CahkVftQneLonbWtfWxiiaT2fdnzsEAN"
|
||||
},
|
||||
{
|
||||
"index": 3,
|
||||
"path": "m/44'/0'/0'/0/3",
|
||||
"address_type": "legacy",
|
||||
"address": "1MVGa13XFvvpKGZdX389iU8b3qwtmAyrsJ"
|
||||
},
|
||||
{
|
||||
"index": 4,
|
||||
"path": "m/84'/0'/0'/0/4",
|
||||
"address_type": "native_segwit",
|
||||
"address": "bc1qm97vqzgj934vnaq9s53ynkyf9dgr05rargr04n"
|
||||
},
|
||||
{
|
||||
"index": 4,
|
||||
"path": "m/49'/0'/0'/0/4",
|
||||
"address_type": "segwit",
|
||||
"address": "37mbeJptxfQC6SNNLJ9a8efCY4BwBh5Kak"
|
||||
},
|
||||
{
|
||||
"index": 4,
|
||||
"path": "m/44'/0'/0'/0/4",
|
||||
"address_type": "legacy",
|
||||
"address": "1Gka4JdwhLxRwXaC6oLNH4YuEogeeSwqW7"
|
||||
}
|
||||
]
|
||||
},
|
||||
"solana_bip39_first32": {
|
||||
"ethereum": [
|
||||
{
|
||||
"index": 0,
|
||||
"path": "m/44'/60'/0'/0/0",
|
||||
"address": "0x9858EfFD232B4033E47d90003D41EC34EcaEda94"
|
||||
},
|
||||
{
|
||||
"index": 1,
|
||||
"path": "m/44'/60'/0'/0/1",
|
||||
"address": "0x6Fac4D18c912343BF86fa7049364Dd4E424Ab9C0"
|
||||
},
|
||||
{
|
||||
"index": 2,
|
||||
"path": "m/44'/60'/0'/0/2",
|
||||
"address": "0xb6716976A3ebe8D39aCEB04372f22Ff8e6802D7A"
|
||||
},
|
||||
{
|
||||
"index": 3,
|
||||
"path": "m/44'/60'/0'/0/3",
|
||||
"address": "0xF3f50213C1d2e255e4B2bAD430F8A38EEF8D718E"
|
||||
},
|
||||
{
|
||||
"index": 4,
|
||||
"path": "m/44'/60'/0'/0/4",
|
||||
"address": "0x51cA8ff9f1C0a99f88E86B8112eA3237F55374cA"
|
||||
}
|
||||
],
|
||||
"solana": [
|
||||
{
|
||||
"index": 0,
|
||||
"path": "BIP39 seed[0:32]",
|
||||
"address": "EHqmfkN89RJ7Y33CXM6uCzhVeuywHoJXZZLszBHHZy7o"
|
||||
}
|
||||
],
|
||||
"bitcoin": [
|
||||
{
|
||||
"index": 0,
|
||||
"path": "m/84'/0'/0'/0/0",
|
||||
"address_type": "native_segwit",
|
||||
"address": "bc1qcr8te4kr609gcawutmrza0j4xv80jy8z306fyu"
|
||||
},
|
||||
{
|
||||
"index": 0,
|
||||
"path": "m/49'/0'/0'/0/0",
|
||||
"address_type": "segwit",
|
||||
"address": "37VucYSaXLCAsxYyAPfbSi9eh4iEcbShgf"
|
||||
},
|
||||
{
|
||||
"index": 0,
|
||||
"path": "m/44'/0'/0'/0/0",
|
||||
"address_type": "legacy",
|
||||
"address": "1LqBGSKuX5yYUonjxT5qGfpUsXKYYWeabA"
|
||||
},
|
||||
{
|
||||
"index": 1,
|
||||
"path": "m/84'/0'/0'/0/1",
|
||||
"address_type": "native_segwit",
|
||||
"address": "bc1qnjg0jd8228aq7egyzacy8cys3knf9xvrerkf9g"
|
||||
},
|
||||
{
|
||||
"index": 1,
|
||||
"path": "m/49'/0'/0'/0/1",
|
||||
"address_type": "segwit",
|
||||
"address": "3LtMnn87fqUeHBUG414p9CWwnoV6E2pNKS"
|
||||
},
|
||||
{
|
||||
"index": 1,
|
||||
"path": "m/44'/0'/0'/0/1",
|
||||
"address_type": "legacy",
|
||||
"address": "1Ak8PffB2meyfYnbXZR9EGfLfFZVpzJvQP"
|
||||
},
|
||||
{
|
||||
"index": 2,
|
||||
"path": "m/84'/0'/0'/0/2",
|
||||
"address_type": "native_segwit",
|
||||
"address": "bc1qp59yckz4ae5c4efgw2s5wfyvrz0ala7rgvuz8z"
|
||||
},
|
||||
{
|
||||
"index": 2,
|
||||
"path": "m/49'/0'/0'/0/2",
|
||||
"address_type": "segwit",
|
||||
"address": "3B4cvWGR8X6Xs8nvTxVUoMJV77E4f7oaia"
|
||||
},
|
||||
{
|
||||
"index": 2,
|
||||
"path": "m/44'/0'/0'/0/2",
|
||||
"address_type": "legacy",
|
||||
"address": "1MNF5RSaabFwcbtJirJwKnDytsXXEsVsNb"
|
||||
},
|
||||
{
|
||||
"index": 3,
|
||||
"path": "m/84'/0'/0'/0/3",
|
||||
"address_type": "native_segwit",
|
||||
"address": "bc1qgl5vlg0zdl7yvprgxj9fevsc6q6x5dmcyk3cn3"
|
||||
},
|
||||
{
|
||||
"index": 3,
|
||||
"path": "m/49'/0'/0'/0/3",
|
||||
"address_type": "segwit",
|
||||
"address": "38CahkVftQneLonbWtfWxiiaT2fdnzsEAN"
|
||||
},
|
||||
{
|
||||
"index": 3,
|
||||
"path": "m/44'/0'/0'/0/3",
|
||||
"address_type": "legacy",
|
||||
"address": "1MVGa13XFvvpKGZdX389iU8b3qwtmAyrsJ"
|
||||
},
|
||||
{
|
||||
"index": 4,
|
||||
"path": "m/84'/0'/0'/0/4",
|
||||
"address_type": "native_segwit",
|
||||
"address": "bc1qm97vqzgj934vnaq9s53ynkyf9dgr05rargr04n"
|
||||
},
|
||||
{
|
||||
"index": 4,
|
||||
"path": "m/49'/0'/0'/0/4",
|
||||
"address_type": "segwit",
|
||||
"address": "37mbeJptxfQC6SNNLJ9a8efCY4BwBh5Kak"
|
||||
},
|
||||
{
|
||||
"index": 4,
|
||||
"path": "m/44'/0'/0'/0/4",
|
||||
"address_type": "legacy",
|
||||
"address": "1Gka4JdwhLxRwXaC6oLNH4YuEogeeSwqW7"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"mnemonic": "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about",
|
||||
"passphrase": "TREZOR",
|
||||
"expected_seed_hex": "c55257c360c07c72029aebc1b53c05ed0362ada38ead3e3e9efa3708e53495531f09a6987599d18264c1e1c92f2cf141630c7a3c4ab7c81b2f001698e7463b04",
|
||||
"derived_addresses": {
|
||||
"phantom_bip44change": {
|
||||
"ethereum": [
|
||||
{
|
||||
"index": 0,
|
||||
"path": "m/44'/60'/0'/0/0",
|
||||
"address": "0x9c32F71D4DB8Fb9e1A58B0a80dF79935e7256FA6"
|
||||
}
|
||||
],
|
||||
"solana": [
|
||||
{
|
||||
"index": 0,
|
||||
"path": "m/44'/501'/0'/0'",
|
||||
"address": "7zSmbu6gKkb6HB7UDPtHYjwCWuBHU1D4TpNZFm4sndQe"
|
||||
}
|
||||
],
|
||||
"bitcoin": [
|
||||
{
|
||||
"index": 0,
|
||||
"path": "m/84'/0'/0'/0/0",
|
||||
"address_type": "native_segwit",
|
||||
"address": "bc1qv5rmq0kt9yz3pm36wvzct7p3x6mtgehjul0feu"
|
||||
},
|
||||
{
|
||||
"index": 0,
|
||||
"path": "m/49'/0'/0'/0/0",
|
||||
"address_type": "segwit",
|
||||
"address": "3Aho3kS7vgVWKTpRHjcqBoPXiCujiSuTaZ"
|
||||
},
|
||||
{
|
||||
"index": 0,
|
||||
"path": "m/44'/0'/0'/0/0",
|
||||
"address_type": "legacy",
|
||||
"address": "1PEha8dk5Me5J1rZWpgqSt5F4BroTBLS5y"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user