use amp_rs::signer::{LwkSoftwareSigner, Signer, SignerError};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
tracing_subscriber::fmt::init();
println!("๐ LwkSoftwareSigner Usage Examples");
println!("โ ๏ธ TESTNET/REGTEST ONLY - Never use with real funds!");
println!();
println!("๐ Example 1: Creating signer from existing mnemonic");
let test_mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about";
let signer1 = LwkSoftwareSigner::new(test_mnemonic)?;
println!(
"โ
Created signer from mnemonic (testnet: {})",
signer1.is_testnet()
);
println!();
println!("๐ฒ Example 2: Generating new signer with file persistence");
let (mnemonic2, signer2) = LwkSoftwareSigner::generate_new()?;
println!("โ
Generated signer with mnemonic: {}...", &mnemonic2[..50]);
println!(" Mnemonic saved to mnemonic.local.json");
println!();
println!("๐ข Example 3: Using indexed mnemonics for test isolation");
let (mnemonic_alice, alice_signer) = LwkSoftwareSigner::generate_new_indexed(0)?;
let (mnemonic_bob, bob_signer) = LwkSoftwareSigner::generate_new_indexed(1)?;
let (mnemonic_charlie, charlie_signer) = LwkSoftwareSigner::generate_new_indexed(2)?;
println!("โ
Alice (index 0): {}...", &mnemonic_alice[..30]);
println!("โ
Bob (index 1): {}...", &mnemonic_bob[..30]);
println!("โ
Charlie (index 2): {}...", &mnemonic_charlie[..30]);
println!(" All signers configured for testnet");
println!();
println!("โ Example 4: Error handling");
match LwkSoftwareSigner::new("invalid mnemonic with wrong word count") {
Ok(_) => println!("Unexpected success"),
Err(SignerError::InvalidMnemonic(msg)) => {
println!("โ
Caught invalid mnemonic error: {}", msg);
}
Err(e) => println!("Unexpected error: {}", e),
}
match signer1.sign_transaction("invalid_hex").await {
Ok(_) => println!("Unexpected success"),
Err(SignerError::HexParse(_)) => {
println!("โ
Caught hex parsing error as expected");
}
Err(e) => println!("Unexpected error: {}", e),
}
match signer1.sign_transaction("").await {
Ok(_) => println!("Unexpected success"),
Err(SignerError::InvalidTransaction(msg)) => {
println!("โ
Caught empty transaction error: {}", msg);
}
Err(e) => println!("Unexpected error: {}", e),
}
println!();
println!("๐ Example 5: Network configuration verification");
let signers = vec![
&signer1,
&signer2,
&alice_signer,
&bob_signer,
&charlie_signer,
];
for (i, signer) in signers.iter().enumerate() {
println!(" Signer {}: testnet = {}", i + 1, signer.is_testnet());
}
println!("โ
All signers correctly configured for testnet");
println!();
println!("๐ Example 6: Transaction signing attempt");
println!(" Note: This will fail because we're using mock transaction data");
let mock_tx_hex = "0200000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000";
match signer1.sign_transaction(mock_tx_hex).await {
Ok(signed_tx) => {
println!("โ
Transaction signed successfully!");
println!(" Signed TX: {}...", &signed_tx[..64]);
}
Err(SignerError::InvalidTransaction(msg)) => {
println!(
"โ Transaction signing failed (expected with mock data): {}",
msg
);
}
Err(e) => {
println!("โ Signing failed with error: {}", e);
}
}
println!();
asset_integration_example().await?;
println!();
println!("๐ฏ Summary:");
println!(" - Created signers from existing and generated mnemonics");
println!(" - Demonstrated indexed mnemonic access for test isolation");
println!(" - Showed comprehensive error handling");
println!(" - Verified testnet-only configuration");
println!(" - Attempted transaction signing with mock data");
println!(" - Demonstrated asset operation integration patterns");
println!();
println!("๐ Check mnemonic.local.json for persistent mnemonic storage");
println!("โ ๏ธ Remember: This is for TESTNET/REGTEST development only!");
Ok(())
}
#[allow(dead_code)]
async fn sign_with_trait(signer: &dyn Signer, tx_hex: &str) -> Result<String, SignerError> {
signer.sign_transaction(tx_hex).await
}
#[allow(dead_code)]
async fn multi_signer_test_scenario() -> Result<(), SignerError> {
println!("๐งช Multi-signer test scenario");
let (_, issuer_signer) = LwkSoftwareSigner::generate_new_indexed(10)?; let (_, distributor_signer) = LwkSoftwareSigner::generate_new_indexed(11)?; let (_, user_signer) = LwkSoftwareSigner::generate_new_indexed(12)?;
println!("โ
Created signers for issuer, distributor, and user roles");
println!(" Each has a unique mnemonic for test isolation");
assert!(issuer_signer.is_testnet());
assert!(distributor_signer.is_testnet());
assert!(user_signer.is_testnet());
println!("โ
All signers verified for testnet usage");
let signers: Vec<&dyn Signer> = vec![&issuer_signer, &distributor_signer, &user_signer];
println!("๐ Testing polymorphic signer usage:");
for (i, signer) in signers.iter().enumerate() {
match sign_with_trait(*signer, "invalid_hex").await {
Err(SignerError::HexParse(_)) => {
println!(" โ
Signer {} correctly rejected invalid hex", i + 1);
}
_ => println!(" โ Signer {} unexpected result", i + 1),
}
}
Ok(())
}
async fn asset_integration_example() -> Result<(), SignerError> {
println!("๐ญ Asset Integration Example");
let (_, asset_issuer) = LwkSoftwareSigner::generate_new_indexed(100)?;
let (_, asset_distributor) = LwkSoftwareSigner::generate_new_indexed(101)?;
let (_, end_user_a) = LwkSoftwareSigner::generate_new_indexed(102)?;
let (_, _end_user_b) = LwkSoftwareSigner::generate_new_indexed(103)?;
println!("โ
Created role-based signers:");
println!(" - Asset Issuer (index 100)");
println!(" - Asset Distributor (index 101)");
println!(" - End User A (index 102)");
println!(" - End User B (index 103)");
println!("๐ Simulating asset operation workflow:");
println!(" 1. Asset Issuance - Issuer creates new asset");
let mock_issuance_tx = "0200000000010001..."; match asset_issuer.sign_transaction(mock_issuance_tx).await {
Err(SignerError::InvalidTransaction(_)) => {
println!(" โ
Issuer signing attempted (mock data rejected as expected)");
}
_ => println!(" โ Unexpected result with mock data"),
}
println!(" 2. Asset Distribution - Distributor sends to users");
let mock_distribution_tx = "0200000000010002..."; match asset_distributor
.sign_transaction(mock_distribution_tx)
.await
{
Err(SignerError::InvalidTransaction(_)) => {
println!(" โ
Distributor signing attempted (mock data rejected as expected)");
}
_ => println!(" โ Unexpected result with mock data"),
}
println!(" 3. User Transfer - User A sends to User B");
let mock_transfer_tx = "0200000000010003..."; match end_user_a.sign_transaction(mock_transfer_tx).await {
Err(SignerError::InvalidTransaction(_)) => {
println!(" โ
User A signing attempted (mock data rejected as expected)");
}
_ => println!(" โ Unexpected result with mock data"),
}
println!("โ
Asset integration workflow demonstrated");
println!(" Note: Real integration would use valid transaction data from AMP API");
Ok(())
}