Skip to content

Commit 59d4319

Browse files
authored
Merge pull request #323 from gelluisaac/Feat
Implement Branch Contract
2 parents 355f379 + b5cef06 commit 59d4319

15 files changed

+4901
-1
lines changed

contracts/assetsup/src/branch.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
use soroban_sdk::{Address, BytesN, String, contracttype};
2+
3+
#[contracttype]
4+
#[derive(Clone, Debug, Eq, PartialEq)]
5+
pub enum DataKey {
6+
Branch(BytesN<32>),
7+
AssetList(BytesN<32>),
8+
}
9+
10+
#[contracttype]
11+
#[derive(Clone, Debug, Eq, PartialEq)]
12+
pub struct Branch {
13+
pub id: BytesN<32>,
14+
pub name: String,
15+
pub location: String,
16+
pub admin: Address,
17+
}
18+
19+
// Note: Contract methods implemented in lib.rs

contracts/assetsup/src/errors.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
// Re-export from the main error module for backward compatibility
2+
// This file is kept for compatibility but the main error handling is in error.rs

contracts/assetsup/src/lib.rs

Lines changed: 104 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
#![no_std]
22

33
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};
55

66
pub(crate) mod asset;
7+
pub(crate) mod branch;
78
pub(crate) mod error;
9+
pub(crate) mod errors;
810
pub(crate) mod types;
911

1012
pub use types::*;
@@ -67,6 +69,107 @@ impl AssetUpContract {
6769
}
6870
}
6971

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+
70173
/// Tokenize an existing asset by attaching a Stellar token ID.
71174
///
72175
/// Access: Only the contract admin (set during `initialize`) can call this.

0 commit comments

Comments
 (0)