Skip to content
Merged
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
36 changes: 36 additions & 0 deletions creator-keys/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,18 @@ pub mod fee {
}
}

/// Stable, non-optional view of the protocol fee configuration.
///
/// Returned by [`CreatorKeysContract::get_protocol_fee_view`] for indexer-friendly consumption.
/// When `is_configured` is `false`, both bps fields are `0` and no fee config has been stored.
#[derive(Clone)]
#[contracttype]
pub struct ProtocolFeeView {
pub creator_bps: u32,
pub protocol_bps: u32,
pub is_configured: bool,
}

#[derive(Clone)]
#[contracttype]
pub enum DataKey {
Expand Down Expand Up @@ -164,6 +176,30 @@ impl CreatorKeysContract {
env.storage().persistent().get(&DataKey::FeeConfig)
}

/// Read-only view: returns the current protocol fee configuration.
///
/// Returns a stable [`ProtocolFeeView`] regardless of whether a fee config has been set.
/// When no config is stored, `is_configured` is `false` and both bps fields are `0`.
/// Use this method for indexers and read-only callers that need a non-optional result.
pub fn get_protocol_fee_view(env: Env) -> ProtocolFeeView {
match env
.storage()
.persistent()
.get::<DataKey, fee::FeeConfig>(&DataKey::FeeConfig)
{
Some(config) => ProtocolFeeView {
creator_bps: config.creator_bps,
protocol_bps: config.protocol_bps,
is_configured: true,
},
None => ProtocolFeeView {
creator_bps: 0,
protocol_bps: 0,
is_configured: false,
},
}
}

pub fn compute_fees_for_payment(env: Env, total: i128) -> (i128, i128) {
let config: fee::FeeConfig = env
.storage()
Expand Down
71 changes: 71 additions & 0 deletions creator-keys/tests/fee_config_view.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
//! Tests for the get_protocol_fee_view read-only method (#19).

use creator_keys::{CreatorKeysContract, CreatorKeysContractClient};
use soroban_sdk::{testutils::Address as _, Env};

#[test]
fn test_get_protocol_fee_view_unconfigured_returns_defaults() {
let env = Env::default();
let contract_id = env.register(CreatorKeysContract, ());
let client = CreatorKeysContractClient::new(&env, &contract_id);

let view = client.get_protocol_fee_view();
assert!(!view.is_configured);
assert_eq!(view.creator_bps, 0);
assert_eq!(view.protocol_bps, 0);
}

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

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

client.set_fee_config(&admin, &9000u32, &1000u32);

let view = client.get_protocol_fee_view();
assert!(view.is_configured);
assert_eq!(view.creator_bps, 9000);
assert_eq!(view.protocol_bps, 1000);
}

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

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

client.set_fee_config(&admin, &8000u32, &2000u32);

let v1 = client.get_protocol_fee_view();
let v2 = client.get_protocol_fee_view();

assert_eq!(v1.creator_bps, v2.creator_bps);
assert_eq!(v1.protocol_bps, v2.protocol_bps);
assert_eq!(v1.is_configured, v2.is_configured);
}

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

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

client.set_fee_config(&admin, &9000u32, &1000u32);
let v1 = client.get_protocol_fee_view();
assert_eq!(v1.protocol_bps, 1000);

client.set_fee_config(&admin, &8000u32, &2000u32);
let v2 = client.get_protocol_fee_view();
assert_eq!(v2.protocol_bps, 2000);
assert_eq!(v2.creator_bps, 8000);
}
Loading