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
19 changes: 19 additions & 0 deletions contracts/assetsup/src/branch.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
use soroban_sdk::{Address, BytesN, String, contracttype};

#[contracttype]
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum DataKey {
Branch(BytesN<32>),
AssetList(BytesN<32>),
}

#[contracttype]
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Branch {
pub id: BytesN<32>,
pub name: String,
pub location: String,
pub admin: Address,
}

// Note: Contract methods implemented in lib.rs
2 changes: 2 additions & 0 deletions contracts/assetsup/src/errors.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// Re-export from the main error module for backward compatibility
// This file is kept for compatibility but the main error handling is in error.rs
105 changes: 104 additions & 1 deletion contracts/assetsup/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
#![no_std]

use crate::error::{Error, handle_error};
use soroban_sdk::{Address, BytesN, Env, contract, contractimpl, contracttype};
use soroban_sdk::{Address, BytesN, Env, String, Vec, contract, contractimpl, contracttype};

pub(crate) mod asset;
pub(crate) mod branch;
pub(crate) mod error;
pub(crate) mod errors;
pub(crate) mod types;

pub use types::*;
Expand Down Expand Up @@ -67,6 +69,107 @@ impl AssetUpContract {
}
}

// Branch functions
pub fn create_branch(
env: Env,
id: BytesN<32>,
name: String,
location: String,
admin: Address,
) -> Result<(), Error> {
// Enforce admin-only access for branch creation
let contract_admin = Self::get_admin(env.clone())?;
contract_admin.require_auth();

if name.is_empty() {
panic!("Branch name cannot be empty");
}

let key = branch::DataKey::Branch(id.clone());
let store = env.storage().persistent();
if store.has(&key) {
return Err(Error::BranchAlreadyExists);
}

let branch = branch::Branch {
id: id.clone(),
name,
location,
admin,
};

store.set(&key, &branch);

// Initialize empty asset list for this branch
let asset_list_key = branch::DataKey::AssetList(id);
let empty_asset_list: Vec<BytesN<32>> = Vec::new(&env);
store.set(&asset_list_key, &empty_asset_list);

Ok(())
}

pub fn add_asset_to_branch(
env: Env,
branch_id: BytesN<32>,
asset_id: BytesN<32>,
) -> Result<(), Error> {
// Verify branch exists
let branch_key = branch::DataKey::Branch(branch_id.clone());
let store = env.storage().persistent();
if !store.has(&branch_key) {
return Err(Error::BranchNotFound);
}

// Verify asset exists
let asset_key = asset::DataKey::Asset(asset_id.clone());
if !store.has(&asset_key) {
return Err(Error::AssetNotFound);
}

// Get current asset list
let asset_list_key = branch::DataKey::AssetList(branch_id);
let mut asset_list: Vec<BytesN<32>> =
store.get(&asset_list_key).unwrap_or_else(|| Vec::new(&env));

// Check if asset is already in the list
for existing_asset_id in asset_list.iter() {
if existing_asset_id == asset_id {
return Ok(()); // Asset already linked, no error
}
}

// Add asset to the list
asset_list.push_back(asset_id);
store.set(&asset_list_key, &asset_list);

Ok(())
}

pub fn get_branch_assets(env: Env, branch_id: BytesN<32>) -> Result<Vec<BytesN<32>>, Error> {
// Verify branch exists
let branch_key = branch::DataKey::Branch(branch_id.clone());
let store = env.storage().persistent();
if !store.has(&branch_key) {
return Err(Error::BranchNotFound);
}

// Get asset list
let asset_list_key = branch::DataKey::AssetList(branch_id);
match store.get(&asset_list_key) {
Some(asset_list) => Ok(asset_list),
None => Ok(Vec::new(&env)), // Return empty list if no assets
}
}

pub fn get_branch(env: Env, branch_id: BytesN<32>) -> Result<branch::Branch, Error> {
let key = branch::DataKey::Branch(branch_id);
let store = env.storage().persistent();
match store.get::<_, branch::Branch>(&key) {
Some(branch) => Ok(branch),
None => Err(Error::BranchNotFound),
}
}

/// Tokenize an existing asset by attaching a Stellar token ID.
///
/// Access: Only the contract admin (set during `initialize`) can call this.
Expand Down
Loading