From d98ccf3479f2fc28cc98729ae09f9768fb5a3c63 Mon Sep 17 00:00:00 2001 From: The Daniel Date: Tue, 30 Jun 2026 23:02:12 -0400 Subject: [PATCH 1/2] fix: use standard Liquid wallet derivation Switch the wallet descriptor from the old master-xpub m/* form to LWK's standard BIP84 Liquid singlesig descriptor so the same seed restores in Apogee and Blockstream-compatible wallets. Add a regression test for the canonical mainnet and testnet/regtest descriptor shape. --- .gitignore | 4 +++ src-tauri/crates/deadcat-sdk/src/sdk.rs | 39 +++++++++++++++++++++---- 2 files changed, 38 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index fe0fdf9b..2d956a8e 100644 --- a/.gitignore +++ b/.gitignore @@ -26,3 +26,7 @@ dist-ssr # But keep SDK implementation docs !src-tauri/crates/deadcat-sdk/docs/ + +# Local agent notes +docs/WALLET_DERIVATION_PATH.md +docs/memory-management.md diff --git a/src-tauri/crates/deadcat-sdk/src/sdk.rs b/src-tauri/crates/deadcat-sdk/src/sdk.rs index fc37e7b3..1cac4172 100644 --- a/src-tauri/crates/deadcat-sdk/src/sdk.rs +++ b/src-tauri/crates/deadcat-sdk/src/sdk.rs @@ -428,11 +428,9 @@ impl DeadcatSdk { let signer = SwSigner::new(mnemonic, network.is_mainnet()) .map_err(|e| Error::Signer(e.to_string()))?; - let slip77_key = signer - .slip77_master_blinding_key() - .map_err(|e| Error::Signer(e.to_string()))?; - let xpub = signer.xpub(); - let descriptor_str = format!("ct(slip77({}),elwpkh({}/*))", slip77_key, xpub); + let descriptor_str = signer + .wpkh_slip77_descriptor() + .map_err(|e| Error::Descriptor(e.to_string()))?; let descriptor: WolletDescriptor = descriptor_str .parse() .map_err(|e: lwk_wollet::Error| Error::Descriptor(e.to_string()))?; @@ -4896,6 +4894,37 @@ mod tests { (sdk, temp_dir) } + #[test] + fn wallet_descriptor_uses_standard_bip84_liquid_singlesig_path() { + let mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about"; + + let mainnet_dir = tempfile::tempdir().unwrap(); + let mainnet = DeadcatSdk::new( + mnemonic, + Network::Liquid, + "tcp://127.0.0.1:1", + mainnet_dir.path(), + ) + .unwrap(); + assert_eq!( + mainnet.wollet.wollet_descriptor().to_string(), + "ct(slip77(9c8e4f05c7711a98c838be228bcb84924d4570ca53f35fa1c793e58841d47023),elwpkh([73c5da0a/84'/1776'/0']xpub6CRFzUgHFDaiDAQFNX7VeV9JNPDRabq6NYSpzVZ8zW8ANUCiDdenkb1gBoEZuXNZb3wPc1SVcDXgD2ww5UBtTb8s8ArAbTkoRQ8qn34KgcY/<0;1>/*))#87kykuta" + ); + + let regtest_dir = tempfile::tempdir().unwrap(); + let regtest = DeadcatSdk::new( + mnemonic, + Network::LiquidRegtest, + "tcp://127.0.0.1:1", + regtest_dir.path(), + ) + .unwrap(); + assert_eq!( + regtest.wollet.wollet_descriptor().to_string(), + "ct(slip77(9c8e4f05c7711a98c838be228bcb84924d4570ca53f35fa1c793e58841d47023),elwpkh([73c5da0a/84'/1'/0']tpubDC8msFGeGuwnKG9Upg7DM2b4DaRqg3CUZa5g8v2SRQ6K4NSkxUgd7HsL2XVWbVm39yBA4LAxysQAm397zwQSQoQgewGiYZqrA9DsP4zbQ1M/<0;1>/*))#2e4n992d" + ); + } + fn maker_pubkey_for_index(sdk: &DeadcatSdk, order_index: u32) -> [u8; 32] { let keypair = sdk.derive_maker_keypair(order_index).unwrap(); let (maker_xonly, _parity) = keypair.x_only_public_key(); From 99db6d1b43a1ea9961f3ae6fd8566d700b4d91bb Mon Sep 17 00:00:00 2001 From: The Daniel Date: Tue, 30 Jun 2026 23:23:32 -0400 Subject: [PATCH 2/2] docs: remove local docs ignore entries --- .gitignore | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.gitignore b/.gitignore index 2d956a8e..fe0fdf9b 100644 --- a/.gitignore +++ b/.gitignore @@ -26,7 +26,3 @@ dist-ssr # But keep SDK implementation docs !src-tauri/crates/deadcat-sdk/docs/ - -# Local agent notes -docs/WALLET_DERIVATION_PATH.md -docs/memory-management.md