diff --git a/Cargo.lock b/Cargo.lock index ee03d0c..75debb8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -155,6 +155,20 @@ version = "1.0.99" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b0674a1ddeecb70197781e945de4b3b8ffb61fa939a5597bcf48503737663100" +[[package]] +name = "aquamarine" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21cc1548309245035eb18aa7f0967da6bc65587005170c56e6ef2788a4cf3f4e" +dependencies = [ + "include_dir", + "itertools 0.10.5", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 2.0.106", +] + [[package]] name = "argon2" version = "0.5.3" @@ -862,6 +876,15 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" +[[package]] +name = "cfg-expr" +version = "0.15.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d067ad48b8650848b989a59a86c6c36a995d02d2bf778d45c3c5d57bc2718f02" +dependencies = [ + "smallvec", +] + [[package]] name = "cfg-if" version = "1.0.3" @@ -989,6 +1012,26 @@ version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" +[[package]] +name = "const-random" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87e00182fe74b066627d63b85fd550ac2998d4b0bd86bfed477a0ae4c7c71359" +dependencies = [ + "const-random-macro", +] + +[[package]] +name = "const-random-macro" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e" +dependencies = [ + "getrandom 0.2.16", + "once_cell", + "tiny-keccak", +] + [[package]] name = "const_format" version = "0.2.34" @@ -1635,6 +1678,93 @@ dependencies = [ "serde", ] +[[package]] +name = "frame-support" +version = "41.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00861648586bca196780b311ca1f345752ee5d971fa1a027f3213955bc493434" +dependencies = [ + "aquamarine", + "array-bytes", + "binary-merkle-tree", + "bitflags 1.3.2", + "docify", + "environmental", + "frame-metadata", + "frame-support-procedural", + "impl-trait-for-tuples", + "k256", + "log", + "macro_magic", + "parity-scale-codec", + "paste", + "scale-info", + "serde", + "serde_json", + "sp-api", + "sp-arithmetic", + "sp-core", + "sp-crypto-hashing-proc-macro", + "sp-debug-derive", + "sp-genesis-builder", + "sp-inherents", + "sp-io", + "sp-metadata-ir", + "sp-runtime", + "sp-staking", + "sp-state-machine", + "sp-std", + "sp-tracing", + "sp-trie", + "sp-weights", + "tt-call", +] + +[[package]] +name = "frame-support-procedural" +version = "34.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aeeec31716c2eeecf21535814faf293dfc7120351c249d1f6f4dea0e520c155b" +dependencies = [ + "Inflector", + "cfg-expr", + "derive-syn-parse", + "docify", + "expander", + "frame-support-procedural-tools", + "itertools 0.11.0", + "macro_magic", + "proc-macro-warning", + "proc-macro2", + "quote", + "sp-crypto-hashing", + "syn 2.0.106", +] + +[[package]] +name = "frame-support-procedural-tools" +version = "13.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81a088fd6fda5f53ff0c17fc7551ce8bd0ead14ba742228443c8196296a7369b" +dependencies = [ + "frame-support-procedural-tools-derive", + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.106", +] + +[[package]] +name = "frame-support-procedural-tools-derive" +version = "12.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed971c6435503a099bdac99fe4c5bea08981709e5b5a0a8535a1856f48561191" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", +] + [[package]] name = "fs-err" version = "2.11.0" @@ -2289,6 +2419,25 @@ dependencies = [ "syn 2.0.106", ] +[[package]] +name = "include_dir" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "923d117408f1e49d914f1a379a309cffe4f18c05cf4e3d12e613a15fc81bd0dd" +dependencies = [ + "include_dir_macros", +] + +[[package]] +name = "include_dir_macros" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cab85a7ed0bd5f0e76d93846e0147172bed2e2d3f859bcc33a8d9699cad1a75" +dependencies = [ + "proc-macro2", + "quote", +] + [[package]] name = "indexmap" version = "2.11.1" @@ -2680,6 +2829,54 @@ dependencies = [ "hashbrown 0.15.5", ] +[[package]] +name = "macro_magic" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc33f9f0351468d26fbc53d9ce00a096c8522ecb42f19b50f34f2c422f76d21d" +dependencies = [ + "macro_magic_core", + "macro_magic_macros", + "quote", + "syn 2.0.106", +] + +[[package]] +name = "macro_magic_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1687dc887e42f352865a393acae7cf79d98fab6351cde1f58e9e057da89bf150" +dependencies = [ + "const-random", + "derive-syn-parse", + "macro_magic_core_macros", + "proc-macro2", + "quote", + "syn 2.0.106", +] + +[[package]] +name = "macro_magic_core_macros" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b02abfe41815b5bd98dbd4260173db2c116dda171dc0fe7838cb206333b83308" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", +] + +[[package]] +name = "macro_magic_macros" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73ea28ee64b88876bf45277ed9a5817c1817df061a74f2b988971a12570e5869" +dependencies = [ + "macro_magic_core", + "quote", + "syn 2.0.106", +] + [[package]] name = "matchers" version = "0.2.0" @@ -3055,6 +3252,12 @@ dependencies = [ "syn 2.0.106", ] +[[package]] +name = "parity-wasm" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1ad0aff30c1da14b1254fcb2af73e1fa9a28670e584a626f53a369d0e157304" + [[package]] name = "parking" version = "2.2.1" @@ -3310,6 +3513,30 @@ dependencies = [ "toml_edit", ] +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + [[package]] name = "proc-macro-error-attr2" version = "2.0.0" @@ -3332,6 +3559,17 @@ dependencies = [ "syn 2.0.106", ] +[[package]] +name = "proc-macro-warning" +version = "1.84.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75eea531cfcd120e0851a3f8aed42c4841f78c889eefafd96339c72677ae42c3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", +] + [[package]] name = "proc-macro2" version = "1.0.101" @@ -3493,6 +3731,7 @@ dependencies = [ "clap", "colored", "dirs", + "frame-support", "hex", "jsonrpsee", "parity-scale-codec", @@ -4411,6 +4650,44 @@ dependencies = [ "sha1", ] +[[package]] +name = "sp-api" +version = "37.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ee297c1304c6b069784dda4147ef5f478f7aef75b94e0838a38c29de792f1df" +dependencies = [ + "docify", + "hash-db", + "log", + "parity-scale-codec", + "scale-info", + "sp-api-proc-macro", + "sp-core", + "sp-externalities", + "sp-metadata-ir", + "sp-runtime", + "sp-runtime-interface", + "sp-state-machine", + "sp-trie", + "sp-version", + "thiserror 1.0.69", +] + +[[package]] +name = "sp-api-proc-macro" +version = "23.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74a14a276fde5d6e5a0668494e3dd42739b346a7ac7b6348c74f9c9142f4474a" +dependencies = [ + "Inflector", + "blake2", + "expander", + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.106", +] + [[package]] name = "sp-application-crypto" version = "41.0.0" @@ -4502,6 +4779,17 @@ dependencies = [ "twox-hash 1.6.3", ] +[[package]] +name = "sp-crypto-hashing-proc-macro" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b85d0f1f1e44bd8617eb2a48203ee854981229e3e79e6f468c7175d5fd37489b" +dependencies = [ + "quote", + "sp-crypto-hashing", + "syn 2.0.106", +] + [[package]] name = "sp-debug-derive" version = "14.0.0" @@ -4524,6 +4812,33 @@ dependencies = [ "sp-storage", ] +[[package]] +name = "sp-genesis-builder" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d731c7b601124756432cd9f5b5da55f6bc55b52c7a334b6df340b769d7103383" +dependencies = [ + "parity-scale-codec", + "scale-info", + "serde_json", + "sp-api", + "sp-runtime", +] + +[[package]] +name = "sp-inherents" +version = "37.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1371275d805f905c407a9eef8447bc0a3d383dbd9277adba2a6264c6fe7daac" +dependencies = [ + "async-trait", + "impl-trait-for-tuples", + "parity-scale-codec", + "scale-info", + "sp-runtime", + "thiserror 1.0.69", +] + [[package]] name = "sp-io" version = "41.0.1" @@ -4563,6 +4878,17 @@ dependencies = [ "sp-externalities", ] +[[package]] +name = "sp-metadata-ir" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2319040b39b9614c35c7faaf548172f4d9a3b44b6992bbae534b096d5cdb4f79" +dependencies = [ + "frame-metadata", + "parity-scale-codec", + "scale-info", +] + [[package]] name = "sp-panic-handler" version = "13.0.2" @@ -4637,6 +4963,20 @@ dependencies = [ "syn 2.0.106", ] +[[package]] +name = "sp-staking" +version = "39.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bca7ccd7d7e478e9f8e933850f025a1c7f409a2b70157d30e5f51675427af022" +dependencies = [ + "impl-trait-for-tuples", + "parity-scale-codec", + "scale-info", + "serde", + "sp-core", + "sp-runtime", +] + [[package]] name = "sp-state-machine" version = "0.46.0" @@ -4715,6 +5055,37 @@ dependencies = [ "trie-root", ] +[[package]] +name = "sp-version" +version = "40.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98fd599db91c11c32e4df4c85b22b6396f28284889a583db9151ff59599dd1cb" +dependencies = [ + "impl-serde", + "parity-scale-codec", + "parity-wasm", + "scale-info", + "serde", + "sp-crypto-hashing-proc-macro", + "sp-runtime", + "sp-std", + "sp-version-proc-macro", + "thiserror 1.0.69", +] + +[[package]] +name = "sp-version-proc-macro" +version = "15.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54cabc8279e835cd9c608d70cb00e693bddec94fe8478e9f3104dad1da5f93ca" +dependencies = [ + "parity-scale-codec", + "proc-macro-warning", + "proc-macro2", + "quote", + "syn 2.0.106", +] + [[package]] name = "sp-wasm-interface" version = "22.0.0" @@ -5446,6 +5817,12 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" +[[package]] +name = "tt-call" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4f195fd851901624eee5a58c4bb2b4f06399148fcd0ed336e6f1cb60a9881df" + [[package]] name = "tuplex" version = "0.1.2" diff --git a/Cargo.toml b/Cargo.toml index bcd74ba..64dd71d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -62,6 +62,7 @@ codec = { package = "parity-scale-codec", version = "3.7", features = [ ] } sp-core = { version = "37.0.0" } sp-runtime = { version = "42.0.0" } +frame-support = { version = "41.0.0" } subxt = "0.43.0" jsonrpsee = { version = "0.24", features = ["client"] } diff --git a/src/cli/address_format.rs b/src/cli/address_format.rs index adaab9b..08ee1e2 100644 --- a/src/cli/address_format.rs +++ b/src/cli/address_format.rs @@ -1,9 +1,15 @@ /// Address formatting utilities for consistent SS58 encoding /// /// This module provides unified functions for formatting addresses in the Quantus -/// SS58 format (version 189). Since the default SS58 version is set to 189 in main.rs, -/// most conversions can use the simpler to_ss58check() method. -use sp_core::crypto::Ss58Codec; +/// SS58 format (version 189). +use sp_core::crypto::{Ss58AddressFormat, Ss58Codec}; + +/// Returns the Quantus SS58 address format (version 189) +/// This is the standard address format for Quantus Network, producing addresses with 'qz' prefix +#[inline] +pub fn quantus_ss58_format() -> Ss58AddressFormat { + Ss58AddressFormat::custom(189) +} /// Trait for converting AccountId32 to Quantus SS58 format pub trait QuantusSS58 { @@ -12,7 +18,7 @@ pub trait QuantusSS58 { impl QuantusSS58 for sp_core::crypto::AccountId32 { fn to_quantus_ss58(&self) -> String { - self.to_ss58check() + self.to_ss58check_with_version(quantus_ss58_format()) } } @@ -20,6 +26,6 @@ impl QuantusSS58 for subxt::ext::subxt_core::utils::AccountId32 { fn to_quantus_ss58(&self) -> String { let bytes: [u8; 32] = *self.as_ref(); let sp_account_id = sp_core::crypto::AccountId32::from(bytes); - sp_account_id.to_ss58check() + sp_account_id.to_ss58check_with_version(quantus_ss58_format()) } } diff --git a/src/cli/treasury.rs b/src/cli/treasury.rs index 4577025..bde75a9 100644 --- a/src/cli/treasury.rs +++ b/src/cli/treasury.rs @@ -2,6 +2,7 @@ use crate::{chain::quantus_subxt, cli::common::submit_transaction, log_print, log_success}; use clap::Subcommand; use colored::Colorize; +use frame_support::sp_runtime::traits::AccountIdConversion; /// Treasury management commands #[derive(Subcommand, Debug)] @@ -158,12 +159,13 @@ async fn get_treasury_balance( log_print!("💰 Treasury Balance"); log_print!(""); - // Get Treasury account ID - // PalletId("py/trsry") converts to account using "modl" prefix - let mut full_data = [0u8; 32]; - full_data[0..4].copy_from_slice(b"modl"); - full_data[4..12].copy_from_slice(b"py/trsry"); - let treasury_account = subxt::utils::AccountId32(full_data); + // Get Treasury account ID using the same method as runtime + let treasury_pallet_id = frame_support::PalletId(*b"py/trsry"); + let treasury_account_raw: sp_runtime::AccountId32 = + treasury_pallet_id.into_account_truncating(); + + // Convert to subxt's AccountId32 + let treasury_account = subxt::utils::AccountId32(*treasury_account_raw.as_ref()); // Query balance let addr = quantus_subxt::api::storage().system().account(treasury_account.clone()); @@ -185,7 +187,11 @@ async fn get_treasury_balance( log_print!("💰 Free Balance: {}", formatted_free_balance); log_print!("💰 Reserved: {}", formatted_reserved_balance); - log_print!("📍 Treasury Account: {}", treasury_account.to_string().bright_yellow()); + + // Display address in Quantus format (uses default SS58 version 189 set in main.rs) + use crate::cli::address_format::QuantusSS58; + let treasury_address = treasury_account_raw.to_quantus_ss58(); + log_print!("📍 Treasury Account: {}", treasury_address.bright_yellow()); Ok(()) } @@ -475,10 +481,11 @@ async fn list_spends( if let Some(spend_status) = storage_at.fetch(&spend_addr).await? { log_print!("💰 Spend #{}", spend_index.to_string().bright_yellow().bold()); log_print!(" Amount: {} (raw)", spend_status.amount.to_string().bright_green()); - log_print!( - " Beneficiary: {}", - format!("{:?}", spend_status.beneficiary).bright_cyan() - ); + + // Format beneficiary address in Quantus SS58 format + use crate::cli::address_format::QuantusSS58; + let beneficiary_str = spend_status.beneficiary.to_quantus_ss58(); + log_print!(" Beneficiary: {}", beneficiary_str.bright_cyan()); log_print!(" Valid From: Block #{}", spend_status.valid_from); log_print!(" Expires At: Block #{}", spend_status.expire_at); log_print!( diff --git a/src/wallet/keystore.rs b/src/wallet/keystore.rs index 16af6d3..aeed76b 100644 --- a/src/wallet/keystore.rs +++ b/src/wallet/keystore.rs @@ -7,8 +7,10 @@ use crate::error::{Result, WalletError}; use qp_rusty_crystals_dilithium::ml_dsa_87::{Keypair, PublicKey, SecretKey}; use serde::{Deserialize, Serialize}; +#[cfg(test)] +use sp_core::crypto::Ss58AddressFormat; use sp_core::{ - crypto::{AccountId32, Ss58AddressFormat, Ss58Codec}, + crypto::{AccountId32, Ss58Codec}, ByteArray, }; // Quantum-safe encryption imports @@ -78,8 +80,9 @@ impl QuantumKeyPair { } pub fn to_account_id_ss58check(&self) -> String { + use crate::cli::address_format::quantus_ss58_format; let account = self.to_account_id_32(); - account.to_ss58check_with_version(Ss58AddressFormat::custom(189)) + account.to_ss58check_with_version(quantus_ss58_format()) } /// Convert to subxt Signer for use @@ -354,14 +357,18 @@ mod tests { ); // Verify consistency between methods + use crate::cli::address_format::quantus_ss58_format; assert_eq!( - account_id.to_ss58check(), + account_id.to_ss58check_with_version(quantus_ss58_format()), ss58_address, "Address methods should be consistent for {name}" ); // Verify it matches the direct DilithiumPair method - let expected_address = resonance_pair.public().into_account().to_ss58check(); + let expected_address = resonance_pair + .public() + .into_account() + .to_ss58check_with_version(quantus_ss58_format()); assert_eq!( ss58_address, expected_address, "Address should match DilithiumPair method for {name}" @@ -373,10 +380,20 @@ mod tests { fn test_ss58_to_account_id_conversion() { sp_core::crypto::set_default_ss58_version(sp_core::crypto::Ss58AddressFormat::custom(189)); // Test with known addresses + use crate::cli::address_format::quantus_ss58_format; let test_cases = vec![ - crystal_alice().public().into_account().to_ss58check(), - dilithium_bob().public().into_account().to_ss58check(), - crystal_charlie().public().into_account().to_ss58check(), + crystal_alice() + .public() + .into_account() + .to_ss58check_with_version(quantus_ss58_format()), + dilithium_bob() + .public() + .into_account() + .to_ss58check_with_version(quantus_ss58_format()), + crystal_charlie() + .public() + .into_account() + .to_ss58check_with_version(quantus_ss58_format()), ]; for ss58_address in test_cases { @@ -389,7 +406,8 @@ mod tests { // Convert back to SS58 and verify round-trip let account_id = AccountId32::from_slice(&account_bytes).expect("Should create valid AccountId32"); - let round_trip_address = account_id.to_ss58check(); + let round_trip_address = + account_id.to_ss58check_with_version(Ss58AddressFormat::custom(189)); assert_eq!( ss58_address, round_trip_address, "Round-trip conversion should preserve address" @@ -414,7 +432,10 @@ mod tests { // All should generate the same address let addr1 = quantum_from_dilithium.to_account_id_ss58check(); let addr2 = quantum_from_resonance.to_account_id_ss58check(); - let addr3 = resonance_from_quantum.public().into_account().to_ss58check(); + let addr3 = resonance_from_quantum + .public() + .into_account() + .to_ss58check_with_version(Ss58AddressFormat::custom(189)); assert_eq!(addr1, addr2, "Addresses should be consistent across conversion paths"); assert_eq!(addr2, addr3, "Address should match direct DilithiumPair calculation"); @@ -501,7 +522,10 @@ mod tests { Ok(address) => { println!("✅ Address generation successful: {address}"); // Verify it matches the expected address - let expected = alice_pair.public().into_account().to_ss58check(); + let expected = alice_pair + .public() + .into_account() + .to_ss58check_with_version(Ss58AddressFormat::custom(189)); assert_eq!(address, expected, "Stored wallet should generate correct address"); }, Err(_) => { @@ -559,7 +583,10 @@ mod tests { Ok(address) => { println!("✅ Encrypted wallet address generation successful: {address}"); // Verify it matches the expected address - let expected = alice_pair.public().into_account().to_ss58check(); + let expected = alice_pair + .public() + .into_account() + .to_ss58check_with_version(Ss58AddressFormat::custom(189)); assert_eq!(address, expected, "Decrypted wallet should generate correct address"); }, Err(_) => { @@ -617,7 +644,10 @@ mod tests { Ok(address) => { println!("✅ Send command flow works: {address}"); // If this passes, the bug is fixed - let expected = alice_pair.public().into_account().to_ss58check(); + let expected = alice_pair + .public() + .into_account() + .to_ss58check_with_version(Ss58AddressFormat::custom(189)); assert_eq!(address, expected, "Loaded wallet should generate correct address"); }, Err(_) => { diff --git a/src/wallet/mod.rs b/src/wallet/mod.rs index f421314..f92ec96 100644 --- a/src/wallet/mod.rs +++ b/src/wallet/mod.rs @@ -13,7 +13,6 @@ pub use keystore::{Keystore, QuantumKeyPair, WalletData}; use qp_rusty_crystals_hdwallet::{generate_mnemonic, HDLattice}; use rand::{rng, RngCore}; use serde::{Deserialize, Serialize}; -use sp_core::crypto::Ss58Codec; use sp_runtime::traits::IdentifyAccount; /// Default derivation path for Quantus wallets: m/44'/189189'/0'/0/0 @@ -124,7 +123,13 @@ impl WalletManager { let quantum_keypair = QuantumKeyPair::from_resonance_pair(&resonance_pair); - println!("🔑 Resonance pair: {:?}", resonance_pair.public().into_account().to_ss58check()); + // Format addresses with SS58 version 189 (Quantus format) + use sp_core::crypto::Ss58Codec; + let resonance_addr = resonance_pair + .public() + .into_account() + .to_ss58check_with_version(sp_core::crypto::Ss58AddressFormat::custom(189)); + println!("🔑 Resonance pair: {:?}", resonance_addr); println!("🔑 Quantum keypair: {:?}", quantum_keypair.to_account_id_ss58check()); // Create wallet data