|
1 | 1 | #![no_std] |
2 | 2 |
|
3 | 3 | use crate::error::{Error, handle_error}; |
4 | | -use soroban_sdk::{Address, BytesN, Env, contract, contractimpl, contracttype}; |
| 4 | +use soroban_sdk::{Address, BytesN, Env, String, Vec, contract, contractimpl, contracttype}; |
5 | 5 |
|
6 | 6 | pub(crate) mod asset; |
| 7 | +pub(crate) mod branch; |
7 | 8 | pub(crate) mod error; |
| 9 | +pub(crate) mod errors; |
8 | 10 | pub(crate) mod types; |
9 | 11 |
|
10 | 12 | pub use types::*; |
@@ -67,6 +69,107 @@ impl AssetUpContract { |
67 | 69 | } |
68 | 70 | } |
69 | 71 |
|
| 72 | + // Branch functions |
| 73 | + pub fn create_branch( |
| 74 | + env: Env, |
| 75 | + id: BytesN<32>, |
| 76 | + name: String, |
| 77 | + location: String, |
| 78 | + admin: Address, |
| 79 | + ) -> Result<(), Error> { |
| 80 | + // Enforce admin-only access for branch creation |
| 81 | + let contract_admin = Self::get_admin(env.clone())?; |
| 82 | + contract_admin.require_auth(); |
| 83 | + |
| 84 | + if name.is_empty() { |
| 85 | + panic!("Branch name cannot be empty"); |
| 86 | + } |
| 87 | + |
| 88 | + let key = branch::DataKey::Branch(id.clone()); |
| 89 | + let store = env.storage().persistent(); |
| 90 | + if store.has(&key) { |
| 91 | + return Err(Error::BranchAlreadyExists); |
| 92 | + } |
| 93 | + |
| 94 | + let branch = branch::Branch { |
| 95 | + id: id.clone(), |
| 96 | + name, |
| 97 | + location, |
| 98 | + admin, |
| 99 | + }; |
| 100 | + |
| 101 | + store.set(&key, &branch); |
| 102 | + |
| 103 | + // Initialize empty asset list for this branch |
| 104 | + let asset_list_key = branch::DataKey::AssetList(id); |
| 105 | + let empty_asset_list: Vec<BytesN<32>> = Vec::new(&env); |
| 106 | + store.set(&asset_list_key, &empty_asset_list); |
| 107 | + |
| 108 | + Ok(()) |
| 109 | + } |
| 110 | + |
| 111 | + pub fn add_asset_to_branch( |
| 112 | + env: Env, |
| 113 | + branch_id: BytesN<32>, |
| 114 | + asset_id: BytesN<32>, |
| 115 | + ) -> Result<(), Error> { |
| 116 | + // Verify branch exists |
| 117 | + let branch_key = branch::DataKey::Branch(branch_id.clone()); |
| 118 | + let store = env.storage().persistent(); |
| 119 | + if !store.has(&branch_key) { |
| 120 | + return Err(Error::BranchNotFound); |
| 121 | + } |
| 122 | + |
| 123 | + // Verify asset exists |
| 124 | + let asset_key = asset::DataKey::Asset(asset_id.clone()); |
| 125 | + if !store.has(&asset_key) { |
| 126 | + return Err(Error::AssetNotFound); |
| 127 | + } |
| 128 | + |
| 129 | + // Get current asset list |
| 130 | + let asset_list_key = branch::DataKey::AssetList(branch_id); |
| 131 | + let mut asset_list: Vec<BytesN<32>> = |
| 132 | + store.get(&asset_list_key).unwrap_or_else(|| Vec::new(&env)); |
| 133 | + |
| 134 | + // Check if asset is already in the list |
| 135 | + for existing_asset_id in asset_list.iter() { |
| 136 | + if existing_asset_id == asset_id { |
| 137 | + return Ok(()); // Asset already linked, no error |
| 138 | + } |
| 139 | + } |
| 140 | + |
| 141 | + // Add asset to the list |
| 142 | + asset_list.push_back(asset_id); |
| 143 | + store.set(&asset_list_key, &asset_list); |
| 144 | + |
| 145 | + Ok(()) |
| 146 | + } |
| 147 | + |
| 148 | + pub fn get_branch_assets(env: Env, branch_id: BytesN<32>) -> Result<Vec<BytesN<32>>, Error> { |
| 149 | + // Verify branch exists |
| 150 | + let branch_key = branch::DataKey::Branch(branch_id.clone()); |
| 151 | + let store = env.storage().persistent(); |
| 152 | + if !store.has(&branch_key) { |
| 153 | + return Err(Error::BranchNotFound); |
| 154 | + } |
| 155 | + |
| 156 | + // Get asset list |
| 157 | + let asset_list_key = branch::DataKey::AssetList(branch_id); |
| 158 | + match store.get(&asset_list_key) { |
| 159 | + Some(asset_list) => Ok(asset_list), |
| 160 | + None => Ok(Vec::new(&env)), // Return empty list if no assets |
| 161 | + } |
| 162 | + } |
| 163 | + |
| 164 | + pub fn get_branch(env: Env, branch_id: BytesN<32>) -> Result<branch::Branch, Error> { |
| 165 | + let key = branch::DataKey::Branch(branch_id); |
| 166 | + let store = env.storage().persistent(); |
| 167 | + match store.get::<_, branch::Branch>(&key) { |
| 168 | + Some(branch) => Ok(branch), |
| 169 | + None => Err(Error::BranchNotFound), |
| 170 | + } |
| 171 | + } |
| 172 | + |
70 | 173 | /// Tokenize an existing asset by attaching a Stellar token ID. |
71 | 174 | /// |
72 | 175 | /// Access: Only the contract admin (set during `initialize`) can call this. |
|
0 commit comments