Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 8 additions & 7 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ soroban-sdk = "28.0.0"
stellar-access = "0.8.0"
stellar-macros = "0.8.0"
stellar-tokens = "0.8.0"
stellar-registry = "0.1.0"
stellar-registry = "0.1.4"
stellar-xdr = "28.0.0"

[profile.release]
Expand Down
1 change: 1 addition & 0 deletions contracts/guess-the-number/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,4 @@ stellar-registry = { workspace = true }
[dev-dependencies]
stellar-xdr = { workspace = true, features = ["serde"] }
soroban-sdk = { workspace = true, features = ["testutils"] }
stellar-registry = { workspace = true, features = ["testutils"] }
4 changes: 1 addition & 3 deletions contracts/guess-the-number/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,7 @@ impl GuessTheNumber {
let admin = Self::admin(env).expect("admin not set");
// Only the admin can reset the game and authorize spending their XLM.
admin.require_auth();
// Ensure the XLM contract exists on the network. Unit tests create
// their own asset in test setup, outside contract invocations.
#[cfg(not(test))]
// Ensure the XLM contract exists on the network.
xlm::register(env);
// Seed the pot with 1 XLM from the admin for players to win.
xlm::token_client(env).transfer(
Expand Down
9 changes: 5 additions & 4 deletions contracts/guess-the-number/src/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use soroban_sdk::{
testutils::{Address as _, MockAuth, MockAuthInvoke},
token::{StellarAssetClient, TokenClient},
};
use stellar_registry::testutils::register_import;

fn init_test<'a>(env: &'a Env) -> (Address, StellarAssetClient<'a>, GuessTheNumberClient<'a>) {
let admin = Address::generate(env);
Expand All @@ -16,9 +17,9 @@ fn init_test<'a>(env: &'a Env) -> (Address, StellarAssetClient<'a>, GuessTheNumb
env.mock_all_auths();
let contract_id = env.register(GuessTheNumber, (&admin,));
let client = GuessTheNumberClient::new(env, &contract_id);
// Create the asset outside contract invocations, after the game exists.
let asset = xlm::register(env, &admin, &contract_id);
let sac = StellarAssetClient::new(env, &asset.address());
// Put a mintable test asset at the address `import_asset!("xlm")` resolves to.
let asset = register_import!(env, xlm);
let sac = StellarAssetClient::new(env, &asset);
// Mint a starting balance for the admin. On testnet, use Friendbot instead.
sac.mint(&admin, &xlm::to_stroops(10_000));
// Clear setup's auth mocks so each test chooses what to authorize.
Expand Down Expand Up @@ -188,7 +189,7 @@ fn reset_without_funds_does_not_change_round() {
// Authorize reset and its nested transfer, rather than mocking every caller.
fn set_caller(client: &GuessTheNumberClient, caller: &Address) {
let env = &client.env;
let asset = env.as_contract(&client.address, || xlm::contract_id(env));
let asset = xlm::contract_id(env);
env.mock_auths(&[MockAuth {
address: caller,
invoke: &MockAuthInvoke {
Expand Down
40 changes: 1 addition & 39 deletions contracts/guess-the-number/src/xlm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,12 @@ pub const fn to_stroops(num: u64) -> i128 {
(num as i128) * ONE_XLM
}

#[cfg(not(test))]
// Resolve the real network's XLM contract; tests use a separate asset below.
// Resolve the network's XLM contract; tests put a test asset at the same address.
stellar_registry::import_asset!("xlm");

#[cfg(test)]
pub use test_asset::*;
#[cfg(not(test))]
pub use xlm::*;

/// Ensure the native XLM asset contract exists before funding a round.
#[cfg(not(test))]
pub fn register(env: &soroban_sdk::Env) {
if token_client(env)
.try_balance(&env.current_contract_address())
Expand All @@ -24,36 +19,3 @@ pub fn register(env: &soroban_sdk::Env) {
env.deployer().with_stellar_asset([0u8; 4]).deploy();
}
}

#[cfg(test)]
mod test_asset {
const XLM_KEY: &soroban_sdk::Symbol = &soroban_sdk::symbol_short!("XLM");

pub fn contract_id(env: &soroban_sdk::Env) -> soroban_sdk::Address {
env.storage()
.instance()
.get::<_, soroban_sdk::Address>(XLM_KEY)
.expect("XLM contract not initialized. Please deploy the XLM contract first.")
}

pub fn register(
env: &soroban_sdk::Env,
admin: &soroban_sdk::Address,
game: &soroban_sdk::Address,
) -> soroban_sdk::testutils::StellarAssetContract {
// SDK test generators must run outside contract invocations.
// This is a mintable test asset, not native XLM.
let sac = env.register_stellar_asset_contract_v2(admin.clone());
// Run the storage write in the game's context so its token client can
// find this asset when called from inside a contract method.
env.as_contract(game, || {
env.storage().instance().set(XLM_KEY, &sac.address());
});
sac
}

/// Create a client for the test asset stored in the game's instance.
pub fn token_client<'a>(env: &soroban_sdk::Env) -> soroban_sdk::token::TokenClient<'a> {
soroban_sdk::token::TokenClient::new(env, &contract_id(env))
}
}
Loading