use amp_rs::signer::LwkSoftwareSigner;
use amp_rs::ElementsRpc;
use chrono;
use dotenvy;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
tracing_subscriber::fmt::init();
println!("🔧 Descriptor-based Elements Wallet Setup Example");
println!("================================================");
dotenvy::dotenv().ok();
let elements_rpc = match ElementsRpc::from_env() {
Ok(rpc) => {
println!("✅ Elements RPC client created from environment variables");
rpc
}
Err(e) => {
println!("❌ Failed to create Elements RPC client: {}", e);
println!("\nPlease set the following environment variables:");
println!(" ELEMENTS_RPC_URL=http://localhost:18884");
println!(" ELEMENTS_RPC_USER=your_rpc_user");
println!(" ELEMENTS_RPC_PASSWORD=your_rpc_password");
return Err(e.into());
}
};
match elements_rpc.get_network_info().await {
Ok(info) => {
println!("✅ Connected to Elements node");
println!(" Version: {}", info.version);
println!(" Connections: {}", info.connections);
}
Err(e) => {
println!("❌ Failed to connect to Elements node: {}", e);
println!(" Please ensure your Elements node is running and accessible");
return Err(e.into());
}
}
println!("\n🔐 Generating Mnemonic and Signer");
println!("=================================");
let (mnemonic, signer) = LwkSoftwareSigner::generate_new()?;
println!("✅ Generated new mnemonic and signer");
println!(" Mnemonic: {}", mnemonic);
println!(" Testnet: {}", signer.is_testnet());
let treasury_address = signer.derive_address(Some(0))?;
println!(" Treasury address (index 0): {}", treasury_address);
println!("\n📝 Generating Descriptors");
println!("========================");
let descriptor = signer.get_wpkh_slip77_descriptor()?;
println!("✅ Generated WPkH Slip77 descriptor");
println!(" Descriptor: {}", descriptor);
assert!(descriptor.contains("ct(") || descriptor.contains("wpkh("));
assert!(descriptor.contains("<0;1>/*") || descriptor.contains("/0/*"));
println!("✅ Descriptor validated - correct format for Liquid confidential transactions");
println!("\n🏦 Setting Up Elements Wallet");
println!("============================");
let wallet_name = format!("descriptor_example_{}", chrono::Utc::now().timestamp());
println!(" Wallet name: {}", wallet_name);
let wallet_result = async {
elements_rpc.create_descriptor_wallet(&wallet_name).await?;
elements_rpc
.import_descriptor(&wallet_name, &descriptor)
.await
}
.await;
match wallet_result {
Ok(()) => {
println!("✅ Successfully set up descriptor wallet");
println!(" The wallet can now:");
println!(" - Detect transactions to mnemonic-derived addresses");
println!(" - Access blinding keys for confidential transactions");
println!(" - Scan the blockchain for relevant UTXOs");
}
Err(e) => {
println!("❌ Failed to set up descriptor wallet: {}", e);
println!("\n🔧 Manual Setup Instructions");
println!("============================");
println!("If automatic setup failed, you can manually set up the wallet:");
println!();
println!("1. Create descriptor wallet:");
println!(" elements-cli createwallet \"{}\" true", wallet_name);
println!();
println!("2. Import descriptor:");
println!(
" elements-cli -rpcwallet={} importdescriptors '[",
wallet_name
);
println!(" {{");
println!(" \"desc\": \"{}\",", descriptor);
println!(" \"timestamp\": \"now\",");
println!(" \"active\": true,");
println!(" \"internal\": false");
println!(" }}");
println!(" ]'");
println!();
println!("3. Verify import:");
println!(" elements-cli -rpcwallet={} listdescriptors", wallet_name);
return Err(e.into());
}
}
println!("\n🎯 Example Complete");
println!("==================");
println!("✅ Mnemonic generated: {}", mnemonic);
println!("✅ Descriptors created with Slip77 blinding support");
println!("✅ Elements wallet configured: {}", wallet_name);
println!();
println!("The wallet is now ready to:");
println!(" - Receive funds to mnemonic-derived addresses");
println!(" - See confidential transactions with proper blinding keys");
println!(" - Support the asset distribution workflow");
println!();
println!("💡 Next steps:");
println!(" - Send test funds to: {}", treasury_address);
println!(
" - Check wallet balance: elements-cli -rpcwallet={} getbalance",
wallet_name
);
println!(
" - List UTXOs: elements-cli -rpcwallet={} listunspent",
wallet_name
);
Ok(())
}