Skip to content

Commit

Permalink
solving error storage
Browse files Browse the repository at this point in the history
  • Loading branch information
PavitraAgarwal21 committed Oct 3, 2024
1 parent 26c1a15 commit a7d88f3
Show file tree
Hide file tree
Showing 10 changed files with 462 additions and 3 deletions.
4 changes: 4 additions & 0 deletions src/base/constants/errors.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,8 @@ pub mod Errors {
pub const SELF_FOLLOWING: felt252 = 'Karst: self follow is forbidden';
pub const ALREADY_REACTED: felt252 = 'Karst: already react to post!';
pub const TOKEN_DOES_NOT_EXIST: felt252 = 'Karst: token_id does not exist!';
pub const NOT_CHANNEL_OWNER: felt252 = 'Channel: not channel owner ';
pub const NOT_CHANNEL_MODERATOR: felt252 = 'Channel: not channel moderator';
pub const NOT_CHANNEL_MEMBER: felt252 = 'Channel: not channel member';
pub const BANNED_FROM_CHANNEL: felt252 = 'Channel: banned from channel';
}
32 changes: 32 additions & 0 deletions src/base/constants/types.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -157,3 +157,35 @@ pub struct QuoteParams {
pub reference_pub_type: PublicationType
}



// /**
// * @notice A struct containing the parameters which define channel
// *
// * @param channel_id unquie id to each channel
// * @param channel_owner primary owner of channel , who create channel
// * @param channel_metadata_uri contain channel metadata
// * @param channel_nft_address contain channel token gated nfts
// * @param channel_total_members total number of member in the channel
// * @param channel_censorship cencorship of channel
// * @param channel_premium_status
// */
#[derive(Drop, Serde, Clone, starknet::Store)]
pub struct channelParams {
channel_id: u256,
channel_owner: ContractAddress,
channel_metadata_uri: ByteArray,
channel_nft_address: ContractAddress,
channel_total_members: u256,
channel_censorship: bool,
}


#[derive(Drop, Serde, Clone, starknet::Store)]
pub struct channelMember {
profile: ContractAddress,
channel_id: u256,
total_publications: u256,
channel_token_id: u256,
ban_status: bool,
}
1 change: 1 addition & 0 deletions src/channel.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
mod channel ;
348 changes: 348 additions & 0 deletions src/channel/channel.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,348 @@
//TODO make the channel as the componet
#[starknet::component]
mod ChannelComponent {
use core::clone::Clone;
use core::starknet::{ContractAddress, get_caller_address, get_block_timestamp};
use karst::interfaces::IChannel::IChannel;
use karst::base::{
constants::errors::Errors::{
NOT_CHANNEL_OWNER, NOT_CHANNEL_MODERATOR, NOT_CHANNEL_MEMBER, BANNED_FROM_CHANNEL
},
constants::types::{channelParams, channelMember}
};
#[storage]
struct Storage {
channels: LegacyMap<u256, channelParams>,
channel_counter: u256,
channel_members: LegacyMap<ContractAddress, channelMember>,
channel_moderators: LegacyMap<(u256, ContractAddress), bool>,
}

#[derive(Drop, starknet::Event)]
pub struct ChannelCreated {
channel_id: u256,
channel_owner: ContractAddress,
channel_nft_address: ContractAddress,
block_timestamp: u64,
}

#[derive(Drop, starknet::Event)]
pub struct JoinedChannel {
channel_id: u256,
transaction_executor: ContractAddress,
token_id: u256,
block_timestamp: u64,
}

#[derive(Drop, starknet::Event)]
pub struct LeftChannel {
channel_id: u256,
transaction_executor: ContractAddress,
token_id: u256,
block_timestamp: u64,
}
// this should also contain the IChannel & IChannelNFT implmentation , waht is the self what d.
#[derive(Drop, starknet::Event)]
pub struct ChannelModAdded {
channel_id: u256,
transaction_executor: ContractAddress,
mod_address: ContractAddress,
block_timestamp: u64,
}

#[derive(Drop, starknet::Event)]
pub struct ChannelModRemoved {
channel_id: u256,
transaction_executor: ContractAddress,
mod_address: ContractAddress,
block_timestamp: u64,
}

#[derive(Drop, starknet::Event)]
pub struct ChannelBanStatusUpdated {
channel_id: u256,
transaction_executor: ContractAddress,
profile: ContractAddress,
block_timestamp: u64,
}

#[event]
#[derive(Drop, starknet::Event)]
enum Event {
ChannelCreated: ChannelCreated,
JoinedChannel: JoinedChannel,
LeftChannel: LeftChannel,
ChannelModAdded: ChannelModAdded,
ChannelModRemoved: ChannelModRemoved,
ChannelBanStatusUpdated: ChannelBanStatusUpdated,
}


// mnaking the constructor to store the onwer , who can set the moderators

#[embeddable_as(KarstChannel)]
impl ChannelImpl<
TContractState, +HasComponent<TContractState>, +Drop<TContractState>>
of IChannel<ComponentState<TContractState>> {
///@notice Create a new channel
///@param channel_params: The parameters of the channel
fn create_channel(ref self: ComponentState<TContractState>, channel_params: channelParams) -> u256 {

let channel_id : u256 = self.channel_counter.read() ;
let new_channel = channelParams {
channel_id: channel_id ,
channel_owner: channel_params.channel_owner,
channel_metadata_uri: channel_params.channel_metadata_uri,
channel_nft_address: channel_params.channel_nft_address,
channel_total_members: 0,
channel_censorship: channel_params.channel_censorship,
};
// increment
self.channels.write(channel_id , new_channel.clone());
self.channel_counter.write(channel_id + 1 );
self
.emit(
ChannelCreated {
channel_id: new_channel.channel_id,
channel_owner: new_channel.channel_owner,
channel_nft_address: new_channel.channel_nft_address,
block_timestamp: get_block_timestamp(),
}
);
channel_id
}


///TODO : Add the minting of the NFT
/// @notice Join the channel
/// @param channel_id: The id of the channel
fn join_channel(ref self: ComponentState<TContractState>, channel_id: u256) {
// check that i prioor not baned
let channel_member: channelMember = self.channel_members.read(get_caller_address());
assert(channel_member.ban_status, BANNED_FROM_CHANNEL);

let mut new_channel: channelParams = self.channels.read(channel_id);
new_channel.channel_total_members += 1;
self.channels.write(channel_id, new_channel);

// calculate the total channel member add +1 is the new member id

self
.channel_members
.write(
get_caller_address(),
channelMember {
profile: get_caller_address(),
channel_id: channel_id,
total_publications: 0,
channel_token_id: 0, //TODO impl token gating self.get_user_token_id(get_caller_address()),
ban_status: false,
}
);
// self.mint_nft(get_caller_address());
self
.emit(
JoinedChannel {
channel_id: channel_id,
transaction_executor: get_caller_address(),
token_id: 0, // dummy value
// token_id: self.last_minted_id.read() + 1,
block_timestamp: get_block_timestamp(),
}
)
}


/// @notice Leave the channel
/// @param channel_id: The id of the channel
/// @dev The user must be a member of the channel
fn leave_channel(ref self: ComponentState<TContractState>, channel_id: u256) {
let channel_member: channelParams = self.channels.read(channel_id);
assert(channel_member.channel_owner == get_caller_address(), NOT_CHANNEL_OWNER);

//TODO Delete the mapping at the caller address
// self.channel_members.write(get_caller_address , None );
//TODO : burn the NFT
self
.emit(
LeftChannel {
channel_id: channel_id,
transaction_executor: get_caller_address(),
token_id: 0, //TODO impl token gating self.get_user_token_id(get_caller_address()),
block_timestamp: get_block_timestamp(),
}
)
}


/// @notice Set the metadata URI of the channel
/// @param channel_id: The id of the channel
/// @param metadata_uri: The new metadata URI
/// @dev Only the owner of the channel can set the metadata URI
fn set_channel_metadata_uri(
ref self: ComponentState<TContractState>, channel_id: u256, metadata_uri: ByteArray
) {
let channel_member: channelParams = self.channels.read(channel_id);
assert(
channel_member.channel_owner == get_caller_address()
|| self.channel_moderators.read((channel_id, get_caller_address())),
NOT_CHANNEL_MODERATOR
);
let mut new_channel: channelParams = self.channels.read(channel_id);
new_channel.channel_metadata_uri = metadata_uri;
self.channels.write(channel_id, new_channel);
}


/// @notice Add a moderator to the channel
/// @param channel_id: The id of the channel
/// @param moderator: The address of the moderator
/// dev only primary moderator/owner can add the moderators
fn add_channel_mods(
ref self: ComponentState<TContractState>, channel_id: u256, moderator: ContractAddress
) {
let channel_member: channelParams = self.channels.read(channel_id);
assert(channel_member.channel_owner == get_caller_address(), NOT_CHANNEL_OWNER);

self.channel_moderators.write((channel_id, moderator), true);
self
.emit(
ChannelModAdded {
channel_id: channel_id,
transaction_executor: get_caller_address(),
mod_address: moderator,
block_timestamp: get_block_timestamp(),
}
)
}


/// @notice Remove a moderator from the channel
/// @param channel_id: The id of the channel
/// @param moderator: The address of the moderator
/// dev only primary moderator/owner can remove the moderators
fn remove_channel_mods(
ref self: ComponentState<TContractState>, channel_id: u256, moderator: ContractAddress
) {
let channel_member: channelParams = self.channels.read(channel_id);
assert(channel_member.channel_owner == get_caller_address(), NOT_CHANNEL_OWNER);

self.channel_moderators.write((channel_id, moderator), false);

self
.emit(
ChannelModRemoved {
channel_id: channel_id,
transaction_executor: get_caller_address(),
mod_address: moderator,
block_timestamp: get_block_timestamp(),
}
)
}


/// @notice Set the censorship status of the channel
/// @param channel_id: The id of the channel
fn set_channel_censorship_status(
ref self: ComponentState<TContractState>, channel_id: u256, censorship_status: bool
) {
let channel_member: channelParams = self.channels.read(channel_id);
assert(channel_member.channel_owner == get_caller_address(), NOT_CHANNEL_OWNER);
let mut new_channel: channelParams = self.channels.read(channel_id);
new_channel.channel_censorship = censorship_status;
self.channels.write(channel_id, new_channel);
}


///@notice Set the ban status of a profile in the channel
/// @param channel_id: The id of the channel
/// @param profile: The address of the profile
/// @param ban_status: The ban status of the profile
fn set_ban_status(
ref self: ComponentState<TContractState>,
channel_id: u256,
profile: ContractAddress,
ban_status: bool
) {
assert(
self.channel_moderators.read((channel_id, get_caller_address())),
NOT_CHANNEL_MODERATOR
);

let mut new_channel_member: channelMember = self.channel_members.read(profile);
new_channel_member.ban_status = ban_status;
self.channel_members.write(profile, new_channel_member);

self
.emit(
ChannelBanStatusUpdated {
channel_id: channel_id,
transaction_executor: get_caller_address(),
profile: profile,
block_timestamp: get_block_timestamp(),
}
)
}


///@notice Get the channel parameters
/// @param channel_id: The id of the channel
/// @return The channel parameters
fn get_channel(self: @ComponentState<TContractState>, channel_id: u256) -> channelParams {
self.channels.read(channel_id)
}

///@notice Get the metadata URI of the channel
/// @param channel_id: The id of the channel
/// @return The metadata URI
fn get_channel_metadata_uri(
self: @ComponentState<TContractState>, channel_id: u256
) -> ByteArray {
let channel: channelParams = self.channels.read(channel_id);
channel.channel_metadata_uri
}

///@notice Check if the profile is a member of the channel
///@param profile: The address of the profile
///@return A tuple of the membership status and the channel id
fn is_channel_member(
self: @ComponentState<TContractState>, profile: ContractAddress, channel_id: u256
) -> bool {
let channel_member: channelMember = self.channel_members.read(profile);
if (channel_member.channel_id == channel_id) {
true
} else {
false
}
}


///TODO :get the total number of mener of the channel
fn get_total_members(self: @ComponentState<TContractState>, channel_id: u256) -> u256 {
let channel: channelParams = self.channels.read(channel_id);
channel.channel_total_members
}

///@notice check for moderator
/// @param channel id
/// @param profile addresss
fn is_channel_mod(
self: @ComponentState<TContractState>, channel_id: u256, profile: ContractAddress
) -> bool {
self.channel_moderators.read((channel_id, profile))
}

fn get_channel_censorship_status(
self: @ComponentState<TContractState>, channel_id: u256
) -> bool {
let channel: channelParams = self.channels.read(channel_id);
channel.channel_censorship
}

///TODO introduce new storage for ban status
fn get_ban_status(self: @ComponentState<TContractState>, profile: ContractAddress) -> bool {
let channel_member: channelMember = self.channel_members.read(profile);
channel_member.ban_status
}
}
}
Loading

0 comments on commit a7d88f3

Please sign in to comment.