Skip to content
Closed
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
90 changes: 87 additions & 3 deletions creator-keys/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ pub enum DataKey {
TreasuryAddress,
}

/// On-chain profile stored under `DataKey::Creator`.
#[derive(Clone)]
#[contracttype]
pub struct CreatorProfile {
Expand Down Expand Up @@ -122,6 +123,10 @@ impl CreatorKeysContract {

#[contractimpl]
impl CreatorKeysContract {
/// Register a new creator on-chain.
///
/// Emits a `("register", creator)` event with a [`CreatorRegistered`]
/// data payload for downstream indexing.
pub fn register_creator(env: Env, creator: Address, handle: String) {
creator.require_auth();

Expand All @@ -131,13 +136,22 @@ impl CreatorKeysContract {
}

let profile = CreatorProfile {
creator,
handle,
creator: creator.clone(),
handle: handle.clone(),
supply: 0,
};

env.storage().persistent().set(&key, &profile);
env.events().publish((symbol_short!("register"),), key);

env.events().publish(
(symbol_short!("register"), creator.clone()),
CreatorRegistered {
creator,
handle,
supply: 0,
ledger: env.ledger().sequence(),
},
);
}

pub fn buy_key(env: Env, creator: Address, buyer: Address, payment: i128) -> u32 {
Expand Down Expand Up @@ -333,3 +347,73 @@ mod tests {
}
}
}

#[cfg(test)]
mod tests {
use super::*;
use soroban_sdk::{testutils::Events, vec, Env, IntoVal, String};

#[test]
fn test_register_emits_rich_event() {
let env = Env::default();
env.mock_all_auths();

let contract_id = env.register(CreatorKeysContract, ());
let client = CreatorKeysContractClient::new(&env, &contract_id);

let creator = Address::generate(&env);
let handle = String::from_str(&env, "alice");

client.register_creator(&creator, &handle);

let events = env.events().all();

// Find our register event among all published events.
let register_events: soroban_sdk::Vec<_> = events
.iter()
.filter(|(_, topics, _)| {
let expected_topics = (symbol_short!("register"), creator.clone()).into_val(&env);
*topics == expected_topics
})
.collect(&env);

assert_eq!(
register_events.len(),
1,
"expected exactly one register event"
);
}

#[test]
fn test_register_event_fields() {
let env = Env::default();
env.mock_all_auths();

let contract_id = env.register(CreatorKeysContract, ());
let client = CreatorKeysContractClient::new(&env, &contract_id);

let creator = Address::generate(&env);
let handle = String::from_str(&env, "bob");

client.register_creator(&creator, &handle);

let events = env.events().all();

// Extract the data payload from the register event.
let (_, _, data) = events
.iter()
.find(|(_, topics, _)| {
let expected_topics = (symbol_short!("register"), creator.clone()).into_val(&env);
*topics == expected_topics
})
.expect("register event not found");

let registered: CreatorRegistered = data.into_val(&env);

assert_eq!(registered.creator, creator);
assert_eq!(registered.handle, handle);
assert_eq!(registered.supply, 0);
// Ledger sequence is set by the test env; just verify it is present.
assert!(registered.ledger >= 0);
}
}
Loading