use aptos_sdk::{aptos_contract, types::AccountAddress};
aptos_contract! {
name: CoinModule,
abi: r#"{
"address": "0x1",
"name": "coin",
"exposed_functions": [
{
"name": "transfer",
"visibility": "public",
"is_entry": true,
"is_view": false,
"generic_type_params": [{"constraints": []}],
"params": ["&signer", "address", "u64"],
"return": []
},
{
"name": "balance",
"visibility": "public",
"is_entry": false,
"is_view": true,
"generic_type_params": [{"constraints": []}],
"params": ["address"],
"return": ["u64"]
}
],
"structs": []
}"#,
source: r#"
module 0x1::coin {
/// Transfer coins from sender to recipient.
public entry fun transfer<CoinType>(
sender: &signer,
to: address,
amount: u64,
) { }
/// Get the balance of an account.
#[view]
public fun balance<CoinType>(owner: address): u64 { 0 }
}
"#
}
aptos_contract! {
name: MyToken,
abi: r#"{
"address": "0xcafe",
"name": "my_token",
"exposed_functions": [
{
"name": "mint",
"visibility": "public",
"is_entry": true,
"is_view": false,
"generic_type_params": [],
"params": ["&signer", "address", "u64"],
"return": []
},
{
"name": "burn",
"visibility": "public",
"is_entry": true,
"is_view": false,
"generic_type_params": [],
"params": ["&signer", "u64"],
"return": []
},
{
"name": "total_supply",
"visibility": "public",
"is_entry": false,
"is_view": true,
"generic_type_params": [],
"params": [],
"return": ["u64"]
},
{
"name": "balance_of",
"visibility": "public",
"is_entry": false,
"is_view": true,
"generic_type_params": [],
"params": ["address"],
"return": ["u64"]
}
],
"structs": [
{
"name": "TokenInfo",
"is_native": false,
"abilities": ["key"],
"generic_type_params": [],
"fields": [
{"name": "name", "type": "0x1::string::String"},
{"name": "symbol", "type": "0x1::string::String"},
{"name": "decimals", "type": "u8"},
{"name": "total_supply", "type": "u64"}
]
}
]
}"#,
source: r#"
module 0xcafe::my_token {
/// Mint new tokens to a recipient.
public entry fun mint(
admin: &signer,
recipient: address,
amount: u64,
) { }
/// Burn tokens from sender's account.
public entry fun burn(
account: &signer,
amount: u64,
) { }
/// Get the total supply of tokens.
#[view]
public fun total_supply(): u64 { 0 }
/// Get the balance of an address.
#[view]
public fun balance_of(owner: address): u64 { 0 }
}
"#
}
#[tokio::main]
async fn main() -> anyhow::Result<()> {
println!("=== Type-Safe Contract Bindings Example ===\n");
let coin_module = CoinModule::new(); let my_token = MyToken::new();
let _custom_deployment = MyToken::with_address("0xabcd1234");
println!("CoinModule constants:");
println!(" Default Address: {}", CoinModule::DEFAULT_ADDRESS);
println!(" Effective Address: {}", coin_module.address());
println!(" Module: {}", CoinModule::MODULE);
println!("\nMyToken constants:");
println!(" Default Address: {}", MyToken::DEFAULT_ADDRESS);
println!(" Effective Address: {}", my_token.address());
println!(" Module: {}", MyToken::MODULE);
let recipient = AccountAddress::from_hex("0x1234")?;
let amount = 1_000_000u64;
let transfer_payload = coin_module.transfer(
recipient, amount, vec![], )?;
println!("\nGenerated transfer payload: {:?}", transfer_payload);
let mint_payload = my_token.mint(
recipient, 500_000, )?;
println!("Generated mint payload: {:?}", mint_payload);
let burn_payload = my_token.burn(
100_000, )?;
println!("Generated burn payload: {:?}", burn_payload);
println!("\n--- View Function Demo (requires network) ---");
println!("To call view functions, you need an Aptos client:");
println!();
println!(" let aptos = Aptos::new(AptosConfig::testnet())?;");
println!(" let coin = CoinModule::new();");
println!(" let balance = coin.view_balance(&aptos, owner, type_args).await?;");
println!(" let supply = my_token.view_total_supply(&aptos).await?;");
println!("\n--- Generated Struct: TokenInfo ---");
let token_info = TokenInfo {
name: "My Token".to_string(),
symbol: "MTK".to_string(),
decimals: 8,
total_supply: 1_000_000_000,
};
println!("TokenInfo: {:?}", token_info);
println!("\n=== Benefits of Type-Safe Bindings ===");
println!("1. Compile-time type checking for arguments");
println!("2. IDE autocomplete and documentation");
println!("3. Meaningful parameter names from Move source");
println!("4. No runtime ABI parsing overhead");
println!("5. Generated structs for Move types");
Ok(())
}