gabriel / muse public
feat BREAKING auth+mpay task/issue-22-final #1 / 1
gabriel · 154 days ago · Apr 15, 2026 · Diff

feat(auth+mpay): muse auth show/migrate --to-hd + MPay AVAX dual-signature

Phase 1 completion: - muse auth show: display full HD identity (derived paths, mnemonic word count, AVAX C-Chain address). JSON: hub/handle/type/key_source/fingerprint/hd_path/ derived_paths/avax_c_chain_address. Mnemonic never printed. - muse auth migrate --to-hd: re-key JBOK → BIP39 HD identity. Generates fresh mnemonic, derives new Ed25519 key via SLIP-0010, overwrites PEM + identity.toml. Requires --force (destructive). Preserves handle/type/caps/provisioned_by. Prints re-register reminder since fingerprint changes.

Phase 3 completion: - PaymentClaim: split into _PaymentClaimRequired (total=True) + optional AVAX dual-sig fields (payer_avax_address, recipient_avax_address, eth_sig). - build_payment_claim: new avax_private_key + recipient_avax_address kwargs. When avax_private_key supplied: EIP-191 personal_sign over the same MPAY canonical message; payer_avax_address derived from secp256k1 public key. eth_sig stored as 130-char lowercase hex (65 bytes, v=27|28). On-chain verifiable via ecrecover on Avalanche C-Chain.

Also: fix run_issue_comment_list _hub_api params bug (bake QS into path string).

Tests: 50 tests across 8 tiers (unit, integration, e2e, stress, data-integrity, performance, security, docstrings) for all new functionality.

sha256:9ad51a9457477957dfdc7ac8ebc1cec647a5ce892431292f98796186bb1a9060 sha
+107 ~6 symbols
sha256:6f31020a6358f5dd1f0282bee5ea7ac04a8039c15d57f970f8af3e637b1a2bcb snapshot
+107
symbols added
~6
symbols modified
0
dead code introduced
Semantic Changes 113 symbols
~ tests/test_auth_show_migrate.py .py 60 symbols added
+ FAKE_FINGERPRINT variable variable FAKE_FINGERPRINT L42–42
+ FAKE_HANDLE variable variable FAKE_HANDLE L43–43
+ FAKE_HD_PATH variable variable FAKE_HD_PATH L41–41
+ FAKE_MNEMONIC variable variable FAKE_MNEMONIC L37–40
+ HOSTNAME variable variable HOSTNAME L36–36
+ HUB variable variable HUB L35–35
+ TestDataIntegrity class class TestDataIntegrity L550–621
+ test_migrate_invalid_strength_exits_1 method method test_migrate_invalid_strength_exits_1 L580–597
+ test_migrate_stores_12_word_mnemonic method method test_migrate_stores_12_word_mnemonic L553–578
+ test_show_mnemonic_word_count_matches_24_words method method test_show_mnemonic_word_count_matches_24_words L599–621
+ TestDocstrings class class TestDocstrings L768–781
+ test_run_migrate_docstring method method test_run_migrate_docstring L775–777
+ test_run_show_docstring method method test_run_show_docstring L771–773
+ test_show_identity_detail_docstring method method test_show_identity_detail_docstring L779–781
+ TestMigrateCLI class class TestMigrateCLI L282–423
+ _mk_fake_pem method method _mk_fake_pem L285–289
+ test_migrate_no_identity_exits_1 method method test_migrate_no_identity_exits_1 L348–364
+ test_migrate_rejects_already_hd method method test_migrate_rejects_already_hd L329–346
+ test_migrate_requires_force method method test_migrate_requires_force L310–327
+ test_migrate_requires_to_hd_flag method method test_migrate_requires_to_hd_flag L291–308
+ test_migrate_success_json method method test_migrate_success_json L366–394
+ test_migrate_writes_hd_to_toml method method test_migrate_writes_hd_to_toml L396–423
+ TestPerformance class class TestPerformance L629–672
+ test_migrate_latency method method test_migrate_latency L648–672
+ test_show_hd_latency method method test_show_hd_latency L632–646
+ TestSecurity class class TestSecurity L680–760
+ test_migrate_already_hd_guard method method test_migrate_already_hd_guard L739–760
+ test_migrate_no_force_exits_safely method method test_migrate_no_force_exits_safely L716–737
+ test_show_json_has_no_mnemonic_key method method test_show_json_has_no_mnemonic_key L701–714
+ test_show_never_prints_mnemonic method method test_show_never_prints_mnemonic L683–699
+ TestShowCLI class class TestShowCLI L229–279
+ test_show_hd_json method method test_show_hd_json L249–265
+ test_show_jbok_json method method test_show_jbok_json L232–247
+ test_show_no_identity_exits_1 method method test_show_no_identity_exits_1 L267–279
+ TestShowIdentityDetail class class TestShowIdentityDetail L113–221
+ test_hd_derived_paths_format method method test_hd_derived_paths_format L188–206
+ test_hd_entry_has_avax_address method method test_hd_entry_has_avax_address L166–186
+ test_hd_entry_json_has_paths method method test_hd_entry_json_has_paths L139–164
+ test_jbok_entry_json method method test_jbok_entry_json L116–137
+ test_jbok_stderr_human_readable method method test_jbok_stderr_human_readable L208–221
+ TestShowMigrateE2E class class TestShowMigrateE2E L431–492
+ test_migrate_preserves_handle method method test_migrate_preserves_handle L469–492
+ test_migrate_then_show_roundtrip method method test_migrate_then_show_roundtrip L434–467
+ TestStress class class TestStress L500–542
+ test_distinct_mnemonics method method test_distinct_mnemonics L503–542
+ _patch_home function function _patch_home L51–64
+ _write_hd_identity function function _write_hd_identity L90–105
+ _write_jbok_identity function function _write_jbok_identity L75–87
+ _write_toml_section function function _write_toml_section L67–72
+ CliRunner import import CliRunner L29–29
+ MagicMock import import MagicMock L26–26
+ annotations import import annotations L20–20
+ json import import json L22–22
+ kp_mod import import kp_mod L31–31
+ patch import import patch L26–26
+ pathlib import import pathlib L23–23
+ pytest import import pytest L28–28
+ time import import time L24–24
+ tomllib import import tomllib L25–25
+ runner variable variable runner L33–33
~ tests/test_msign_dual_sig.py .py 40 symbols added
+ BIP39_MNEMONIC variable variable BIP39_MNEMONIC L40–43
+ TestDataIntegrity class class TestDataIntegrity L310–336
+ test_canonical_message_format method method test_canonical_message_format L313–322
+ test_dual_sig_uses_same_canonical_message method method test_dual_sig_uses_same_canonical_message L324–336
+ TestDocstrings class class TestDocstrings L410–419
+ test_build_payment_claim_docstring method method test_build_payment_claim_docstring L413–415
+ test_payment_claim_docstring method method test_payment_claim_docstring L417–419
+ TestDualSigRoundTrip class class TestDualSigRoundTrip L161–224
+ test_deterministic_given_fixed_ts method method test_deterministic_given_fixed_ts L211–224
+ test_ed25519_sig_still_valid method method test_ed25519_sig_still_valid L191–209
+ test_eth_sig_is_65_bytes_hex method method test_eth_sig_is_65_bytes_hex L175–189
+ test_payer_address_matches_derived method method test_payer_address_matches_derived L164–173
+ TestEip191Verification class class TestEip191Verification L232–279
+ test_eip191_verify_accepts_eth_sig method method test_eip191_verify_accepts_eth_sig L235–247
+ test_eip191_verify_rejects_tampered_message method method test_eip191_verify_rejects_tampered_message L267–279
+ test_eip191_verify_rejects_wrong_address method method test_eip191_verify_rejects_wrong_address L249–265
+ TestPaymentClaimShape class class TestPaymentClaimShape L82–153
+ test_avax_fields_absent_without_key method method test_avax_fields_absent_without_key L103–113
+ test_avax_fields_present_with_key method method test_avax_fields_present_with_key L115–126
+ test_recipient_avax_address_stored method method test_recipient_avax_address_stored L128–139
+ test_recipient_without_payer_key method method test_recipient_without_payer_key L141–153
+ test_required_fields_present_without_avax method method test_required_fields_present_without_avax L85–101
+ TestPerformance class class TestPerformance L344–358
+ test_claim_latency method method test_claim_latency L347–358
+ TestSecurity class class TestSecurity L366–402
+ test_ed25519_domain_separation method method test_ed25519_domain_separation L393–402
+ test_no_avax_fields_by_default method method test_no_avax_fields_by_default L369–377
+ test_no_private_key_in_claim method method test_no_private_key_in_claim L379–391
+ TestStress class class TestStress L287–302
+ test_50_claims method method test_50_claims L290–302
+ avax_address function function avax_address L72–74
+ avax_key function function avax_key L53–55
+ ed25519_signing function function ed25519_signing L59–68
+ MagicMock import import MagicMock L31–31
+ annotations import import annotations L26–26
+ base64 import import base64 L28–28
+ hashlib import import hashlib L29–29
+ pytest import import pytest L33–33
+ time import import time L30–30
+ seed function function seed L47–49
~ muse/cli/commands/auth.py .py 5 symbols added, 1 symbol modified
+ _MigrateJson class class _MigrateJson L166–176
+ _ShowJson class class _ShowJson L152–163
+ _show_identity_detail function function _show_identity_detail L1216–1301
+ run_migrate function function run_migrate L1367–1539
+ run_show function function run_show L1304–1362
~ muse/core/msign.py .py 2 symbols added, 4 symbols modified
+ _PaymentClaimRequired class class _PaymentClaimRequired L91–102
+ Any import import Any L59–59
← Older Oldest on task/issue-22-final
All commits
Newer → Latest on task/issue-22-final

0 comments

No comments yet. Be the first to start the discussion.

To add a comment, use the Muse CLI: muse hub commit comment sha256:9ad51a9457477957dfdc7ac8ebc1cec647a5ce892431292f98796186bb1a9060 --body "your comment"