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
45 changes: 33 additions & 12 deletions creator-keys/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,13 +84,32 @@ pub mod fee {

pub mod constants {
use super::DataKey;
use soroban_sdk::Address;

pub mod storage {
use super::DataKey;
use super::{creator_key, key_balance_key, DataKey};
use soroban_sdk::Address;

pub const FEE_CONFIG: DataKey = DataKey::FeeConfig;
pub const KEY_PRICE: DataKey = DataKey::KeyPrice;
pub const TREASURY_ADDRESS: DataKey = DataKey::TreasuryAddress;
pub const ADMIN_ADDRESS: DataKey = DataKey::AdminAddress;

pub fn creator(creator: &Address) -> DataKey {
creator_key(creator)
}

pub fn key_balance(creator: &Address, holder: &Address) -> DataKey {
key_balance_key(creator, holder)
}
}

fn creator_key(creator: &Address) -> DataKey {
DataKey::Creator(creator.clone())
}

fn key_balance_key(creator: &Address, holder: &Address) -> DataKey {
DataKey::KeyBalance(creator.clone(), holder.clone())
}

pub mod creator_reads {
Expand Down Expand Up @@ -203,7 +222,7 @@ pub struct CreatorProfile {
/// Use this helper wherever repeated creator read logic is needed to keep
/// missing-creator behavior consistent across the contract.
pub fn read_creator_profile(env: &Env, creator: &Address) -> Option<CreatorProfile> {
let key = DataKey::Creator(creator.clone());
let key = constants::storage::creator(creator);
env.storage()
.persistent()
.get::<DataKey, CreatorProfile>(&key)
Expand Down Expand Up @@ -279,7 +298,7 @@ impl CreatorKeysContract {
) -> Result<(), ContractError> {
creator.require_auth();

let key = DataKey::Creator(creator.clone());
let key = constants::storage::creator(&creator);
if env.storage().persistent().has(&key) {
return Err(ContractError::AlreadyRegistered);
}
Expand Down Expand Up @@ -330,7 +349,7 @@ impl CreatorKeysContract {

let mut profile: CreatorProfile = read_registered_creator_profile(&env, &creator)?;

let balance_key = DataKey::KeyBalance(creator.clone(), buyer.clone());
let balance_key = constants::storage::key_balance(&creator, &buyer);
let current_balance: u32 = env.storage().persistent().get(&balance_key).unwrap_or(0);

if current_balance == 0 {
Expand All @@ -345,7 +364,7 @@ impl CreatorKeysContract {
.checked_add(1)
.ok_or(ContractError::Overflow)?;

let key = DataKey::Creator(creator.clone());
let key = constants::storage::creator(&creator);
env.storage().persistent().set(&key, &profile);

let new_balance = current_balance
Expand All @@ -366,7 +385,7 @@ impl CreatorKeysContract {

let mut profile: CreatorProfile = read_registered_creator_profile(&env, &creator)?;

let balance_key = DataKey::KeyBalance(creator.clone(), seller);
let balance_key = constants::storage::key_balance(&creator, &seller);
let current_balance: u32 = env.storage().persistent().get(&balance_key).unwrap_or(0);
if current_balance == 0 {
return Err(ContractError::InsufficientBalance);
Expand All @@ -387,15 +406,15 @@ impl CreatorKeysContract {
.ok_or(ContractError::Overflow)?;
}

let key = DataKey::Creator(creator);
let key = constants::storage::creator(&creator);
env.storage().persistent().set(&key, &profile);
env.storage().persistent().set(&balance_key, &new_balance);

Ok(profile.supply)
}

pub fn get_key_balance(env: Env, creator: Address, wallet: Address) -> u32 {
let key = DataKey::KeyBalance(creator, wallet);
let key = constants::storage::key_balance(&creator, &wallet);
env.storage().persistent().get(&key).unwrap_or(0)
}

Expand All @@ -408,7 +427,7 @@ impl CreatorKeysContract {
pub fn get_holder_key_count(env: Env, creator: Address, holder: Address) -> HolderKeyCountView {
let creator_exists = read_creator_profile(&env, &creator).is_some();
let key_count = if creator_exists {
let key = DataKey::KeyBalance(creator.clone(), holder.clone());
let key = constants::storage::key_balance(&creator, &holder);
env.storage().persistent().get(&key).unwrap_or(0)
} else {
0
Expand All @@ -432,7 +451,7 @@ impl CreatorKeysContract {
/// When the creator is not registered, `is_registered` is `false` and
/// default values are provided for other fields.
pub fn get_creator_details(env: Env, creator: Address) -> CreatorDetailsView {
let key = DataKey::Creator(creator.clone());
let key = constants::storage::creator(&creator);
match env
.storage()
.persistent()
Expand Down Expand Up @@ -588,7 +607,7 @@ impl CreatorKeysContract {
admin.require_auth();
env.storage()
.persistent()
.set(&DataKey::AdminAddress, &new_admin);
.set(&constants::storage::ADMIN_ADDRESS, &new_admin);
}

/// Read-only view: returns the current protocol admin address.
Expand All @@ -597,7 +616,9 @@ impl CreatorKeysContract {
/// Use this method for indexers and read-only callers that need the current
/// protocol admin address.
pub fn get_protocol_admin(env: Env) -> Option<Address> {
env.storage().persistent().get(&DataKey::AdminAddress)
env.storage()
.persistent()
.get(&constants::storage::ADMIN_ADDRESS)
}

/// Read-only view: returns the current protocol fee configuration.
Expand Down
2 changes: 1 addition & 1 deletion creator-keys/src/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ fn test_read_key_balance_returns_registered_creator_supply() {
let supply = env.as_contract(&contract_id, || {
env.storage()
.persistent()
.set(&DataKey::Creator(creator.clone()), &profile);
.set(&constants::storage::creator(&creator), &profile);

read_key_balance(&env, &creator)
});
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
{
"generators": {
"address": 3,
"nonce": 0
},
"auth": [
[],
[
[
"CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4",
{
"function": {
"contract_fn": {
"contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM",
"function_name": "set_protocol_admin",
"args": [
{
"address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4"
},
{
"address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M"
}
]
}
},
"sub_invocations": []
}
]
],
[],
[]
],
"ledger": {
"protocol_version": 22,
"sequence_number": 0,
"timestamp": 0,
"network_id": "0000000000000000000000000000000000000000000000000000000000000000",
"base_reserve": 0,
"min_persistent_entry_ttl": 4096,
"min_temp_entry_ttl": 16,
"max_entry_ttl": 6312000,
"ledger_entries": [
[
{
"contract_data": {
"contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM",
"key": {
"vec": [
{
"symbol": "AdminAddress"
}
]
},
"durability": "persistent"
}
},
[
{
"last_modified_ledger_seq": 0,
"data": {
"contract_data": {
"ext": "v0",
"contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM",
"key": {
"vec": [
{
"symbol": "AdminAddress"
}
]
},
"durability": "persistent",
"val": {
"address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M"
}
}
},
"ext": "v0"
},
4095
]
],
[
{
"contract_data": {
"contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM",
"key": "ledger_key_contract_instance",
"durability": "persistent"
}
},
[
{
"last_modified_ledger_seq": 0,
"data": {
"contract_data": {
"ext": "v0",
"contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM",
"key": "ledger_key_contract_instance",
"durability": "persistent",
"val": {
"contract_instance": {
"executable": {
"wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
"storage": null
}
}
}
},
"ext": "v0"
},
4095
]
],
[
{
"contract_data": {
"contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4",
"key": {
"ledger_key_nonce": {
"nonce": 801925984706572462
}
},
"durability": "temporary"
}
},
[
{
"last_modified_ledger_seq": 0,
"data": {
"contract_data": {
"ext": "v0",
"contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4",
"key": {
"ledger_key_nonce": {
"nonce": 801925984706572462
}
},
"durability": "temporary",
"val": "void"
}
},
"ext": "v0"
},
6311999
]
],
[
{
"contract_code": {
"hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
}
},
[
{
"last_modified_ledger_seq": 0,
"data": {
"contract_code": {
"ext": "v0",
"hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"code": ""
}
},
"ext": "v0"
},
4095
]
]
]
},
"events": []
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
{
"generators": {
"address": 1,
"nonce": 0
},
"auth": [
[],
[]
],
"ledger": {
"protocol_version": 22,
"sequence_number": 0,
"timestamp": 0,
"network_id": "0000000000000000000000000000000000000000000000000000000000000000",
"base_reserve": 0,
"min_persistent_entry_ttl": 4096,
"min_temp_entry_ttl": 16,
"max_entry_ttl": 6312000,
"ledger_entries": [
[
{
"contract_data": {
"contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM",
"key": "ledger_key_contract_instance",
"durability": "persistent"
}
},
[
{
"last_modified_ledger_seq": 0,
"data": {
"contract_data": {
"ext": "v0",
"contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM",
"key": "ledger_key_contract_instance",
"durability": "persistent",
"val": {
"contract_instance": {
"executable": {
"wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
"storage": null
}
}
}
},
"ext": "v0"
},
4095
]
],
[
{
"contract_code": {
"hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
}
},
[
{
"last_modified_ledger_seq": 0,
"data": {
"contract_code": {
"ext": "v0",
"hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"code": ""
}
},
"ext": "v0"
},
4095
]
]
]
},
"events": []
}
Loading
Loading