diff --git a/src/UserRegistry.cairo b/src/UserRegistry.cairo new file mode 100644 index 0000000..b10906c --- /dev/null +++ b/src/UserRegistry.cairo @@ -0,0 +1,76 @@ +#[starknet::contract] +mod UserRegistry { + use starknet::contract_address::ContractAddress; + use starknet::storage; + use starknet::syscalls::get_caller_address; + use core::integer::u128; + + #[derive(Drop, Copy, Serde)] + struct Profile { + id: u128, + user_address: ContractAddress, + name: felt252, + is_active: bool, + } + + #[storage] + struct Storage { + profiles: Map, + profile_by_address: Map, // Maps address to profile ID + profile_count: u128, // Tracks the total number of profiles + } + + #[event] + struct ProfileUpdated { + user: ContractAddress, + } + + #[event] + struct ProfileDeactivated { + user: ContractAddress, + } + + #[starknet::interface] + trait IUserRegistry { + fn update_profile(ref self: TContractState, name: felt252); + fn deactivate_profile(ref self: TContractState); + fn get_profile_by_id(self: @TContractState, id: u128) -> Profile; + fn get_profile_by_address(self: @TContractState, address: ContractAddress) -> Profile; + } + + #[external(v0)] + impl IUserRegistry of IUserRegistry { + fn update_profile(ref self: ContractState, name: felt252) { + let caller = get_caller_address(); + let id = self.profile_by_address.get(caller).unwrap_or_else(|| panic!("Profile not found")); + + let mut profile = self.profiles.get(id).unwrap_or_else(|| panic!("Profile not found")); + assert!(profile.user_address == caller, "Unauthorized"); + + profile.name = name; + self.profiles.insert(id, profile); + self.emit(ProfileUpdated { user: caller }); + } + + fn deactivate_profile(ref self: ContractState) { + let caller = get_caller_address(); + let id = self.profile_by_address.get(caller).unwrap_or_else(|| panic!("Profile not found")); + + let mut profile = self.profiles.get(id).unwrap_or_else(|| panic!("Profile not found")); + assert!(profile.user_address == caller, "Unauthorized"); + + profile.is_active = false; + self.profiles.insert(id, profile); + self.emit(ProfileDeactivated { user: caller }); + } + + fn get_profile_by_id(self: @ContractState, id: u128) -> Profile { + return self.profiles.get(id).unwrap_or_else(|| panic!("Profile not found")); + } + + fn get_profile_by_address(self: @ContractState, address: ContractAddress) -> Profile { + let id = self.profile_by_address.get(address).unwrap_or_else(|| panic!("Profile not found")); + return self.profiles.get(id).unwrap_or_else(|| panic!("Profile not found")); + } + } +} diff --git a/src/interfaces/IUserRegistry.cairo b/src/interfaces/IUserRegistry.cairo index 8b13789..039c6a6 100644 --- a/src/interfaces/IUserRegistry.cairo +++ b/src/interfaces/IUserRegistry.cairo @@ -1 +1,16 @@ +#[starknet::interface] +trait IUserRegistry { + /// Updates the name of the caller's profile + fn update_profile(ref self: TContractState, name: felt252); + + /// Deactivates the caller's profile without data loss + fn deactivate_profile(ref self: TContractState); + + /// Retrieves a profile by its unique ID + fn get_profile_by_id(self: @TContractState, id: u128) -> Profile; + + /// Retrieves a profile by the associated wallet address + fn get_profile_by_address(self: @TContractState, address: ContractAddress) -> Profile; +} + diff --git a/tests/test_UserRegistry.cairo b/tests/test_UserRegistry.cairo new file mode 100644 index 0000000..e69de29