Skip to content
Closed
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
3 changes: 2 additions & 1 deletion src/base/types.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ pub struct TokenBoundAccount {
pub owner_permissions: Permissions, // Owner's permissions
}

#[derive(Drop, Serde, starknet::Store)]
#[derive(Drop, Serde, starknet::Store, Clone)]

pub struct User {
pub id: u256,
pub username: felt252,
Expand Down
81 changes: 79 additions & 2 deletions src/chainlib/ChainLib.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ pub mod ChainLib {
Map, StorageMapReadAccess, StorageMapWriteAccess, StoragePointerReadAccess,
StoragePointerWriteAccess,
};
use starknet::{ContractAddress, get_block_timestamp, get_caller_address};
use starknet::{
ContractAddress, get_block_timestamp, get_caller_address, contract_address_const
};
use crate::interfaces::IChainLib::IChainLib;
use crate::base::types::{TokenBoundAccount, User, Role, Rank, Permissions, permission_flags};

Expand Down Expand Up @@ -49,10 +51,15 @@ pub mod ChainLib {
creators_content: Map::<ContractAddress, ContentMetadata>,
content: Map::<felt252, ContentMetadata>,
content_tags: Map::<ContentMetadata, Array<felt252>>,

next_content_id: felt252,
user_by_address: Map<ContractAddress, User>,

// Permission system storage
operator_permissions: Map::<
(u256, ContractAddress), Permissions
>, // Maps account_id and operator to permissions

}


Expand All @@ -67,10 +74,13 @@ pub mod ChainLib {
pub enum Event {
TokenBoundAccountCreated: TokenBoundAccountCreated,
UserCreated: UserCreated,
ContentRegistered: ContentRegistered,

// Permission-related events
PermissionGranted: PermissionGranted,
PermissionRevoked: PermissionRevoked,
PermissionModified: PermissionModified,

}

#[derive(Drop, starknet::Event)]
Expand All @@ -83,6 +93,14 @@ pub mod ChainLib {
pub id: u256,
}


#[derive(Drop, starknet::Event)]
pub struct ContentRegistered {
pub content_id: felt252,
pub creator: ContractAddress
}


// Permission-related events
#[derive(Drop, starknet::Event)]
pub struct PermissionGranted {
Expand All @@ -103,6 +121,7 @@ pub mod ChainLib {
pub permissions: Permissions,
}


#[abi(embed_v0)]
impl ChainLibNetImpl of IChainLib<ContractState> {
fn create_token_account(
Expand Down Expand Up @@ -180,10 +199,15 @@ pub mod ChainLib {
};

// Store the new user in the users mapping.

self.users.write(user_id, new_user);

// Also store the user in the user_by_address mapping for address-based lookups.
let user_for_address = self.users.read(user_id);
self.user_by_address.write(user_for_address.wallet_address, user_for_address);

// Increment the user ID counter for the next registration.
self.current_account_id.write(user_id + 1);
self.user_id.write(user_id + 1);

// Emit an event to notify about the new user registration.
self.emit(UserCreated { id: user_id });
Expand Down Expand Up @@ -221,6 +245,58 @@ pub mod ChainLib {
admin
}



/// @notice Registers new content in the system.
/// @dev Only users with WRITER role can register content.
/// @param self The contract state reference.
/// @param title The title of the content (cannot be empty).
/// @param description The description of the content.
/// @param content_type The type of content being registered.
/// @param category The category the content belongs to.
/// @return felt252 Returns the unique identifier of the registered content.
fn register_content(
ref self: ContractState,
title: felt252,
description: felt252,
content_type: ContentType,
category: Category
) -> felt252 {
assert!(title != 0, "Title cannot be empty");
assert!(description != 0, "Description cannot be empty");

let creator = get_caller_address();
let user = self.user_by_address.read(creator);

assert!(user.role == Role::WRITER, "Only WRITER can post content");

let content_id = self.next_content_id.read();

let content_metadata = ContentMetadata {
content_id: content_id,
title: title,
description: description,
content_type: content_type,
creator: creator,
category: category
};

self.content.write(content_id, content_metadata);
self.creators_content.write(creator, content_metadata);
self.next_content_id.write(content_id + 1);

self.emit(ContentRegistered { content_id: content_id, creator: creator });

content_id
}


fn get_content(ref self: ContractState, content_id: felt252) -> ContentMetadata {
let content_metadata = self.content.read(content_id);

assert!(content_metadata.content_id == content_id, "Content does not exist");
content_metadata

// Permission system implementation

fn get_permissions(
Expand Down Expand Up @@ -311,6 +387,7 @@ pub mod ChainLib {
self.emit(PermissionModified { account_id, permissions });

true

}
}
}
14 changes: 14 additions & 0 deletions src/interfaces/IChainLib.cairo
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use starknet::ContractAddress;
use crate::chainlib::ChainLib::ChainLib::{Category, ContentType, ContentMetadata};
use crate::base::types::{TokenBoundAccount, User, Role, Rank, Permissions};


#[starknet::interface]
pub trait IChainLib<TContractState> {
// Course Management
Expand All @@ -21,6 +23,17 @@ pub trait IChainLib<TContractState> {
fn getAdmin(self: @TContractState) -> ContractAddress;
fn is_verified(ref self: TContractState, user_id: u256) -> bool;

fn register_content(
ref self: TContractState,
title: felt252,
description: felt252,
content_type: ContentType,
category: Category
) -> felt252;

fn get_content(ref self: TContractState, content_id: felt252) -> ContentMetadata;


// Permission system
fn get_permissions(
self: @TContractState, account_id: u256, operator: ContractAddress
Expand All @@ -44,5 +57,6 @@ pub trait IChainLib<TContractState> {
fn modify_account_permissions(
ref self: TContractState, account_id: u256, permissions: Permissions
) -> bool;

}

Loading
Loading