use soroban_fork::ForkConfig;
use soroban_sdk::{Address, IntoVal, String as SorobanString, Symbol, Val};
const USDC_SAC: &str = "CCW67TSZV3SSS2HXMBQ5JFGCKJNXKZM7UQUWUZPUTHXSTZLEO7SJMI75";
fn mainnet_rpc() -> String {
std::env::var("MAINNET_RPC_URL")
.unwrap_or_else(|_| "https://soroban-rpc.mainnet.stellar.gateway.fm".to_string())
}
fn addr(env: &soroban_sdk::Env, id: &str) -> Address {
Address::from_string(&SorobanString::from_str(env, id))
}
#[test]
#[ignore = "requires live Stellar mainnet RPC (opt-in via `cargo test -- --ignored`)"]
fn auth_tree_is_empty_before_any_invocation() {
let env = ForkConfig::new(mainnet_rpc()).build().expect("fork setup");
env.mock_all_auths();
let tree = env.auth_tree();
assert!(
tree.is_empty(),
"expected empty tree before any invoke, got {} payloads",
tree.payload_count()
);
assert_eq!(tree.invocation_count(), 0);
let rendered = tree.to_string();
assert!(
rendered.starts_with("[AUTH] (empty"),
"empty tree should render the explanatory placeholder; got:\n{rendered}"
);
}
#[test]
#[ignore = "requires live Stellar mainnet RPC (opt-in via `cargo test -- --ignored`)"]
fn transfer_records_alice_auth_payload() {
let env = ForkConfig::new(mainnet_rpc()).build().expect("fork setup");
env.mock_all_auths();
let usdc = addr(&env, USDC_SAC);
let accounts = env.test_accounts();
assert!(
accounts.len() >= 2,
"this test requires at least 2 pre-funded test accounts"
);
let alice_strkey = accounts[0].account_strkey();
let bob_strkey = accounts[1].account_strkey();
let alice = addr(&env, &alice_strkey);
let bob = addr(&env, &bob_strkey);
const HUNDRED_USDC: i128 = 100 * 10_000_000;
env.deal_token(&usdc, &alice, HUNDRED_USDC);
let amount: i128 = 25 * 10_000_000;
let mut args = soroban_sdk::Vec::new(&env);
let alice_val: Val = alice.into_val(&*env);
let bob_val: Val = bob.into_val(&*env);
let amount_val: Val = amount.into_val(&*env);
args.push_back(alice_val);
args.push_back(bob_val);
args.push_back(amount_val);
env.invoke_contract::<()>(&usdc, &Symbol::new(&env, "transfer"), args);
let tree = env.auth_tree();
assert!(
!tree.is_empty(),
"transfer should have produced at least one auth payload"
);
assert_eq!(
tree.payload_count(),
1,
"expected exactly 1 payload for a single transfer; got tree:\n{tree}"
);
assert_eq!(
tree.invocation_count(),
1,
"expected exactly 1 invocation node; got tree:\n{tree}"
);
let rendered = tree.to_string();
assert!(
rendered.contains("transfer("),
"rendered tree should name the transfer call:\n{rendered}"
);
let alice_prefix = &alice_strkey[..4];
let alice_suffix = &alice_strkey[alice_strkey.len() - 4..];
assert!(
rendered.contains(alice_prefix) && rendered.contains(alice_suffix),
"rendered tree should mention Alice's address ({alice_strkey}):\n{rendered}"
);
eprintln!("--- captured auth tree ---");
env.print_auth_tree();
eprintln!("--- end ---");
}