use aptos_sdk::{
Aptos, AptosConfig,
account::Ed25519Account,
transaction::{
EntryFunction, InputEntryFunctionData, TransactionPayload, functions, move_none, move_some,
move_string,
},
types::{MoveModuleId, TypeTag},
};
#[tokio::main]
async fn main() -> anyhow::Result<()> {
println!("=== Entry Function Transaction Examples ===\n");
let aptos = Aptos::new(AptosConfig::testnet())?;
println!("Connected to testnet (chain_id: {})", aptos.chain_id());
let sender = aptos.create_funded_account(100_000_000).await?;
let recipient = Ed25519Account::generate();
println!("Sender: {}", sender.address());
println!("Recipient: {}", recipient.address());
println!("\n--- Part 1: InputEntryFunctionData Builder (Recommended) ---");
let payload1 = InputEntryFunctionData::new("0x1::aptos_account::transfer")
.arg(recipient.address())
.arg(1_000_000u64) .build()?;
println!("Simple transfer payload built:");
println!(" Function: 0x1::aptos_account::transfer");
println!(" Arguments: [recipient, amount]");
let result = aptos.sign_submit_and_wait(&sender, payload1, None).await?;
let success = result
.data
.get("success")
.and_then(|v| v.as_bool())
.unwrap_or(false);
println!(" Transaction success: {}", success);
println!("\n--- Part 2: Entry Functions with Type Arguments ---");
let payload2 = InputEntryFunctionData::new("0x1::coin::transfer")
.type_arg("0x1::aptos_coin::AptosCoin") .arg(recipient.address())
.arg(500_000u64)
.build()?;
println!("Generic coin transfer:");
println!(" Function: 0x1::coin::transfer<0x1::aptos_coin::AptosCoin>");
println!(" Type arg parsed from string");
let result = aptos.sign_submit_and_wait(&sender, payload2, None).await?;
let success = result
.data
.get("success")
.and_then(|v| v.as_bool())
.unwrap_or(false);
println!(" Transaction success: {}", success);
println!("\n--- Part 3: Convenience Helper Methods ---");
let payload3 = InputEntryFunctionData::transfer_apt(recipient.address(), 250_000)?;
println!("InputEntryFunctionData::transfer_apt() - Quick APT transfer");
let result = aptos.sign_submit_and_wait(&sender, payload3, None).await?;
println!(
" Transaction success: {}",
result
.data
.get("success")
.and_then(|v| v.as_bool())
.unwrap_or(false)
);
let payload4 = InputEntryFunctionData::transfer_coin(
"0x1::aptos_coin::AptosCoin",
recipient.address(),
100_000,
)?;
println!("InputEntryFunctionData::transfer_coin() - Generic coin transfer");
let result = aptos.sign_submit_and_wait(&sender, payload4, None).await?;
println!(
" Transaction success: {}",
result
.data
.get("success")
.and_then(|v| v.as_bool())
.unwrap_or(false)
);
println!("\n--- Part 4: Using EntryFunction Directly ---");
let entry_fn = EntryFunction::new(
MoveModuleId::from_str_strict("0x1::aptos_account")?,
"transfer",
vec![], vec![
aptos_bcs::to_bytes(&recipient.address())?,
aptos_bcs::to_bytes(&100_000u64)?,
],
);
let payload5 = TransactionPayload::EntryFunction(entry_fn);
println!("EntryFunction::new() - Manual construction");
println!(" Requires manual BCS encoding of arguments");
let result = aptos.sign_submit_and_wait(&sender, payload5, None).await?;
println!(
" Transaction success: {}",
result
.data
.get("success")
.and_then(|v| v.as_bool())
.unwrap_or(false)
);
println!("\n--- Part 5: Using Function ID Constants ---");
println!("Available function constants:");
println!(
" functions::APT_TRANSFER = \"{}\"",
functions::APT_TRANSFER
);
println!(
" functions::COIN_TRANSFER = \"{}\"",
functions::COIN_TRANSFER
);
println!(
" functions::CREATE_ACCOUNT = \"{}\"",
functions::CREATE_ACCOUNT
);
println!(
" functions::REGISTER_COIN = \"{}\"",
functions::REGISTER_COIN
);
println!(
" functions::PUBLISH_PACKAGE = \"{}\"",
functions::PUBLISH_PACKAGE
);
println!("\nAvailable type constants:");
println!(" aptos_sdk::transaction::types::APT_COIN = \"0x1::aptos_coin::AptosCoin\"");
let payload6 = InputEntryFunctionData::new(functions::APT_TRANSFER)
.arg(recipient.address())
.arg(50_000u64)
.build()?;
let result = aptos.sign_submit_and_wait(&sender, payload6, None).await?;
println!("\nUsing functions::APT_TRANSFER constant:");
println!(
" Transaction success: {}",
result
.data
.get("success")
.and_then(|v| v.as_bool())
.unwrap_or(false)
);
println!("\n--- Part 6: Complex Argument Types ---");
println!("Argument encoding helpers:");
let name = move_string("MyToken");
println!(" move_string(\"MyToken\") -> String arg for Move");
let addresses = vec![recipient.address()];
let amounts = vec![1000u64, 2000u64, 3000u64];
println!(" move_vec(&[...]) -> Vector arg for Move");
let _some_value = move_some(42u64);
let _none_value: Vec<u8> = move_none();
println!(" move_some(42u64) -> Option::Some(42)");
println!(" move_none() -> Option::None");
println!("\nExample complex payload (not submitted):");
let _complex_payload = InputEntryFunctionData::new("0x1::example::complex_function")
.arg(42u8) .arg(1000u64) .arg(true) .arg(name) .arg(addresses) .arg(amounts) .build();
println!(" Built payload with: u8, u64, bool, String, vector<address>, vector<u64>");
println!("\n--- Part 7: TypeTag Construction Methods ---");
let type_tag1 = TypeTag::from_str_strict("0x1::aptos_coin::AptosCoin")?;
println!("TypeTag::from_str_strict(\"0x1::aptos_coin::AptosCoin\")");
let type_tag2 = TypeTag::aptos_coin();
println!("TypeTag::aptos_coin() - convenience method");
assert_eq!(type_tag1, type_tag2);
println!("Both produce the same TypeTag");
let payload7 = InputEntryFunctionData::new("0x1::coin::transfer")
.type_arg_typed(TypeTag::aptos_coin()) .arg(recipient.address())
.arg(25_000u64)
.build()?;
let result = aptos.sign_submit_and_wait(&sender, payload7, None).await?;
println!("\nUsing type_arg_typed():");
println!(
" Transaction success: {}",
result
.data
.get("success")
.and_then(|v| v.as_bool())
.unwrap_or(false)
);
println!("\n--- Part 8: Building from Module Parts ---");
let module = MoveModuleId::from_str_strict("0x1::aptos_account")?;
let payload8 = InputEntryFunctionData::from_parts(module, "transfer")
.arg(recipient.address())
.arg(10_000u64)
.build()?;
println!("InputEntryFunctionData::from_parts():");
println!(" Useful when module ID is already parsed");
let result = aptos.sign_submit_and_wait(&sender, payload8, None).await?;
println!(
" Transaction success: {}",
result
.data
.get("success")
.and_then(|v| v.as_bool())
.unwrap_or(false)
);
println!("\n--- Part 9: Building Entry Function Only ---");
let entry_fn = InputEntryFunctionData::new("0x1::aptos_account::transfer")
.arg(recipient.address())
.arg(5_000u64)
.build_entry_function()?;
println!("build_entry_function() returns EntryFunction directly:");
println!(
" Module: {}::{}",
entry_fn.module.address, entry_fn.module.name
);
println!(" Function: {}", entry_fn.function);
println!(" Args count: {}", entry_fn.args.len());
let payload9 = TransactionPayload::EntryFunction(entry_fn);
let result = aptos.sign_submit_and_wait(&sender, payload9, None).await?;
println!(
" Transaction success: {}",
result
.data
.get("success")
.and_then(|v| v.as_bool())
.unwrap_or(false)
);
println!("\n--- Part 10: Error Handling ---");
let result = InputEntryFunctionData::new("invalid_function")
.arg(42u64)
.build();
println!("Invalid function ID: {}", result.is_err());
if let Err(e) = result {
println!(" Error: {}", e);
}
let result = InputEntryFunctionData::new("0x1::coin::transfer")
.type_arg("not::a::valid::type")
.arg(recipient.address())
.arg(1000u64)
.build();
println!("Invalid type arg: {}", result.is_err());
println!("\n=== Summary ===");
println!("Best practices for entry function transactions:");
println!(" 1. Use InputEntryFunctionData builder for most cases");
println!(" 2. Use helper methods (transfer_apt, transfer_coin) for common ops");
println!(" 3. Use function constants (functions::APT_TRANSFER) for clarity");
println!(" 4. Use type_arg() for string types, type_arg_typed() for TypeTag");
println!(" 5. Use move_vec(), move_some(), move_none() for complex types");
let sender_balance = aptos.get_balance(sender.address()).await?;
let recipient_balance = aptos.get_balance(recipient.address()).await?;
println!("\nFinal balances:");
println!(" Sender: {} APT", sender_balance as f64 / 100_000_000.0);
println!(
" Recipient: {} APT",
recipient_balance as f64 / 100_000_000.0
);
println!("\n=== Entry Function Examples Completed ===");
Ok(())
}