From 2fb6953e713e70ac411b9f9324be3c0117a503e3 Mon Sep 17 00:00:00 2001 From: samuel1-ona Date: Wed, 23 Apr 2025 08:02:44 +0100 Subject: [PATCH] Chores: Set up the contracts for frontend integration --- .gitignore | 3 +- Makefile | 14 +- Scarb.toml | 6 + deployment.md | 32 ++ snfoundry.toml | 8 +- src/contract.md | 17 + src/mods.cairo | 1 - src/mods/errors.cairo | 1 + src/mods/events.cairo | 9 - src/mods/interfaces/IWeaver.cairo | 13 +- src/mods/interfaces/Iprotocol.cairo | 9 +- src/mods/protocol/protocolcomponent.cairo | 138 +++++---- src/mods/protocol/protocols.cairo | 19 +- src/mods/types.cairo | 16 +- src/mods/weaver_contract/weaver.cairo | 128 ++++++-- .../weaver_contract/weaver_component.cairo | 134 -------- tests/test_protocol_component.cairo | 290 ++++++++++++++++-- tests/test_weaver_contract.cairo | 210 +++++++------ 18 files changed, 650 insertions(+), 398 deletions(-) create mode 100644 deployment.md create mode 100644 src/contract.md delete mode 100644 src/mods/weaver_contract/weaver_component.cairo diff --git a/.gitignore b/.gitignore index fbef1de..1851687 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ target .snfoundry_cache/ -.vscode/ \ No newline at end of file +.vscode/ +.deployment.md/ \ No newline at end of file diff --git a/Makefile b/Makefile index 93ba6d0..82fb12d 100644 --- a/Makefile +++ b/Makefile @@ -2,6 +2,8 @@ declare: sncast \ declare \ --fee-token eth \ + --url https://starknet-sepolia.g.alchemy.com/starknet/version/rpc/v0_7/CGmQDezuhKApBVtytny0Hh7MvAHwTh8- \ + --name ${name} \ --contract-name ${name} deploy: @@ -23,5 +25,13 @@ upgrade: set_env: export STARKNET_ACCOUNT= - export STARKNET_KEYSTORE= - export STARKNET_RPC= \ No newline at end of file + export STARKNET_KEYSTORE= ../../keystore/keystore.json + export STARKNET_RPC= https://starknet-sepolia.g.alchemy.com/starknet/version/rpc/v0_7/CGmQDezuhKApBVtytny0Hh7MvAHwTh8- + + + sncast \ + account create \ + --url 'https://starknet-sepolia.g.alchemy.com/starknet/version/rpc/v0_7/CGmQDezuhKApBVtytny0Hh7MvAHwTh8- \' + --name weaver_deploy + + \ No newline at end of file diff --git a/Scarb.toml b/Scarb.toml index 05e140d..93686bb 100644 --- a/Scarb.toml +++ b/Scarb.toml @@ -23,3 +23,9 @@ test = "snforge test" [profile.dev.cairo] unstable-add-statements-code-locations-debug-info = true unstable-add-statements-functions-debug-info = true + + +[profile.default] +account = "weaver_deploy" +accounts-file = ".starknet_accounts/accounts.json" +network = "sepolia" diff --git a/deployment.md b/deployment.md new file mode 100644 index 0000000..d1810cb --- /dev/null +++ b/deployment.md @@ -0,0 +1,32 @@ +sncast account create --url https://starknet-sepolia.g.alchemy.com/starknet/version/rpc/v0_7/CGmQDezuhKApBVtytny0Hh7MvAHwTh8- --name weaver_deploy + + sncast account deploy --url https://starknet-sepolia.g.alchemy.com/starknet/version/rpc/v0_7/CGmQDezuhKApBVtytny0Hh7MvAHwTh8- --name weaver_deploy --fee-token eth + + sncast --account deploy_weaver declare --url https://starknet-sepolia.g.alchemy.com/starknet/version/rpc/v0_7/CGmQDezuhKApBVtytny0Hh7MvAHwTh8- --contract-name protocolNFT --fee-token eth + + sncast --account deploy_weaver declare --url https://starknet-sepolia.g.alchemy.com/starknet/version/rpc/v0_7/CGmQDezuhKApBVtytny0Hh7MvAHwTh8- --contract-name protocols --fee-token eth + + sncast --account deploy_weaver declare --url https://starknet-sepolia.g.alchemy.com/starknet/version/rpc/v0_7/CGmQDezuhKApBVtytny0Hh7MvAHwTh8- --contract-name WeaverNFT --fee-token eth + + sncast --account deploy_weaver declare --url https://starknet-sepolia.g.alchemy.com/starknet/version/rpc/v0_7/CGmQDezuhKApBVtytny0Hh7MvAHwTh8- --contract-name Weaver --fee-token eth + + + sncast --account deploy_weaver deploy --url https://starknet-sepolia.g.alchemy.com/starknet/version/rpc/v0_7/CGmQDezuhKApBVtytny0Hh7MvAHwTh8- --class-hash 0x00a48e557dce8fa7f837e547e2370cf4cb1ad4c6639b1ffc901c1ad1654460c1 --fee-token eth --constructor-calldata 0x05d1529a7e55E8f0E6591465E2c34bFF10d5e40F74f510cF8EA229a880096C3a + + sncast --account deploy_weaver deploy --url https://starknet-sepolia.g.alchemy.com/starknet/version/rpc/v0_7/CGmQDezuhKApBVtytny0Hh7MvAHwTh8- --class-hash 0x0689773dfcdaeff1fb3e94e7b3c00af755af354f5a4340bbbda35d7e4bb5c071 --fee-token eth --constructor-calldata 0x05d1529a7e55E8f0E6591465E2c34bFF10d5e40F74f510cF8EA229a880096C3a + + sncast --account deploy_weaver deploy --url https://starknet-sepolia.g.alchemy.com/starknet/version/rpc/v0_7/CGmQDezuhKApBVtytny0Hh7MvAHwTh8- --class-hash 0x054e3fc7fa075587839d33e723acb1c42e32e9f8fedd41e3244ce80fa8ad24e3 --fee-token eth --constructor-calldata 0x01f3801de0af4481bdc1bd20960ea7850d53375e5830f1c2ecaecbfc5987c814 + + sncast --account deploy_weaver deploy --url https://starknet-sepolia.g.alchemy.com/starknet/version/rpc/v0_7/CGmQDezuhKApBVtytny0Hh7MvAHwTh8- --class-hash 0x01f3801de0af4481bdc1bd20960ea7850d53375e5830f1c2ecaecbfc5987c814 --fee-token eth --constructor-calldata 0x00 0x01 0x05d1529a7e55E8f0E6591465E2c34bFF10d5e40F74f510cF8EA229a880096C3a + + + + + + + + + + + + diff --git a/snfoundry.toml b/snfoundry.toml index 306a097..49b39d3 100644 --- a/snfoundry.toml +++ b/snfoundry.toml @@ -1,11 +1,13 @@ -# Visit https://foundry-rs.github.io/starknet-foundry/appendix/snfoundry-toml.html + # and https://foundry-rs.github.io/starknet-foundry/projects/configuration.html for more information # [sncast.default] # Define a profile name -# url = "https://free-rpc.nethermind.io/sepolia-juno/v0_7" # Url of the RPC provider +# url = "https://starknet-sepolia.g.alchemy.com/starknet/version/rpc/v0_7/CGmQDezuhKApBVtytny0Hh7MvAHwTh8-" # Url of the RPC provider + # accounts-file = "../account-file" # Path to the file with the account data -# account = "mainuser" # Account from `accounts_file` or default account file that will be used for the transactions +# account = "Weavers_contract" # Account from `accounts_file` or default account file that will be used for the transactions # keystore = "~/keystore" # Path to the keystore file # wait-params = { timeout = 300, retry-interval = 10 } # Wait for submitted transaction parameters # block-explorer = "StarkScan" # Block explorer service used to display links to transaction details # show-explorer-links = true # Print links pointing to pages with transaction details in the chosen block explorer +# network = "sepolia" \ No newline at end of file diff --git a/src/contract.md b/src/contract.md new file mode 100644 index 0000000..0237852 --- /dev/null +++ b/src/contract.md @@ -0,0 +1,17 @@ + +// class hash +protocolNFT classhash: 0x01f3801de0af4481bdc1bd20960ea7850d53375e5830f1c2ecaecbfc5987c814 +protocols classhash: 0x054e3fc7fa075587839d33e723acb1c42e32e9f8fedd41e3244ce80fa8ad24e3 +weaver NFT classhash: 0x0689773dfcdaeff1fb3e94e7b3c00af755af354f5a4340bbbda35d7e4bb5c071 +weaverContract classhash: 0x00a48e557dce8fa7f837e547e2370cf4cb1ad4c6639b1ffc901c1ad1654460c1 + + +// address +weaverContract addressb: 0x000a6ab43cb891ee68a350dbfd2a972bab0379701c6fc115802284dad4d22dea +WeaverNFT address : 0x041def29d2d5c719c89788959db261c708303c6fe9ef2cdcddd3af6678c6bf07 +protocols address: 0x02d916e6f8d8e2dc8d3c9a8a6f25f5f72b280ed25fdaf18e09116800c608e26e +protocolNFT address: 0x051685ff5506f403a05385f0ae10ab637336da849925bc5ebf6cd0a04055de12 + + + + diff --git a/src/mods.cairo b/src/mods.cairo index 43e57a3..42ed5a3 100644 --- a/src/mods.cairo +++ b/src/mods.cairo @@ -15,7 +15,6 @@ pub mod interfaces { } pub mod weaver_contract { - pub mod weaver_component; pub mod weaver; } diff --git a/src/mods/errors.cairo b/src/mods/errors.cairo index 2cc0549..a82db60 100644 --- a/src/mods/errors.cairo +++ b/src/mods/errors.cairo @@ -17,4 +17,5 @@ pub mod Errors { pub const TASK_ALREADY_EXIST: felt252 = 'TASK_ALREADY_EXIST'; pub const TASK_NOT_YET_COMPLETED: felt252 = 'TASK_NOT_YET_COMPLETED'; pub const INVALID_PROTOCOL_ID: felt252 = 'INVALID_PROTOCOL_ID'; + pub const NOT_IN_PROTOCOL_CAMPAIGN: felt252 = 'NOT_IN_PROTOCOL_CAMPAIGN'; } diff --git a/src/mods/events.cairo b/src/mods/events.cairo index 811dbf7..f559921 100644 --- a/src/mods/events.cairo +++ b/src/mods/events.cairo @@ -24,12 +24,3 @@ pub struct UserRegistered { pub block_timestamp: u64, } - -#[derive(Copy, Drop, Debug, PartialEq, starknet::Event)] -pub struct TaskMinted { - #[key] - pub task_id: u256, - #[key] - pub user: ContractAddress, -} - diff --git a/src/mods/interfaces/IWeaver.cairo b/src/mods/interfaces/IWeaver.cairo index 712c6b1..b8f496b 100644 --- a/src/mods/interfaces/IWeaver.cairo +++ b/src/mods/interfaces/IWeaver.cairo @@ -5,12 +5,15 @@ use starknet::class_hash::ClassHash; // INTERFACE of WEAVER // ************************************************************************* -use crate::mods::types::{ProtocolInfo, TaskInfo, User}; +use crate::mods::types::{User}; #[starknet::interface] -pub trait IWeaver { - fn register_User(ref self: TState, Details: ByteArray); +pub trait IWeaver { + fn register_User(ref self: TContractState, Details: ByteArray); - fn get_register_user(self: @TState, address: ContractAddress) -> User; - fn get_owner(self: @TState) -> ContractAddress; + fn get_register_user(self: @TContractState, address: ContractAddress) -> User; + fn get_owner(self: @TContractState) -> ContractAddress; + fn set_erc721(ref self: TContractState, address: ContractAddress); + fn get_user_id(self: @TContractState) -> u256; + fn get_erc721(self: @TContractState) -> ContractAddress; } diff --git a/src/mods/interfaces/Iprotocol.cairo b/src/mods/interfaces/Iprotocol.cairo index 4a3350f..e0f7a5a 100644 --- a/src/mods/interfaces/Iprotocol.cairo +++ b/src/mods/interfaces/Iprotocol.cairo @@ -17,7 +17,6 @@ pub trait IProtocol { fn join_protocol_campaign(ref self: TState, campaign_user: ContractAddress, protocol_id: u256); fn set_protocol_matadata_uri(ref self: TState, protocol_id: u256, matadata_uri: ByteArray); fn protocol_register(ref self: TState, protocol_Details: ByteArray); - fn verfify_protocol(ref self: TState, protocol_address: ContractAddress); // ************************************************************************* @@ -33,10 +32,16 @@ pub trait IProtocol { fn get_protocol_matadata_uri(self: @TState, protocol_id: u256) -> ByteArray; fn get_protocol_campaign_users(self: @TState, protocol_id: u256) -> u256; - fn get_campaign_members(self: @TState, protocol_id: u256) -> CampaignMembers; fn get_registered_protocol(self: @TState, protocol_owner: ContractAddress) -> ProtocolInfo; fn get_protocol_nft_class_hash(self: @TState) -> ClassHash; + fn get_all_protocol_details(self: @TState) -> Array; + + fn get_all_campaign_for_members(self: @TState, user: ContractAddress) -> Array; + + fn get_campaign_for_member( + self: @TState, protocol_id: u256, user: ContractAddress + ) -> CampaignMembers; } diff --git a/src/mods/protocol/protocolcomponent.cairo b/src/mods/protocol/protocolcomponent.cairo index e79502f..c7e11a7 100644 --- a/src/mods/protocol/protocolcomponent.cairo +++ b/src/mods/protocol/protocolcomponent.cairo @@ -1,5 +1,5 @@ #[starknet::component] -pub mod ProtocolCampagin { +pub mod ProtocolCampaign { use core::traits::TryInto; use core::num::traits::zero::Zero; @@ -14,8 +14,7 @@ pub mod ProtocolCampagin { use openzeppelin_access::ownable::OwnableComponent; - use crate::mods::weaver_contract::weaver_component::WeaverComponent; - use crate::mods::weaver_contract::weaver_component::WeaverComponent::Weavers; + use crate::mods::interfaces::Iprotocol::IProtocol; use crate::mods::interfaces::ICustomNFT::{ICustomNFTDispatcher, ICustomNFTDispatcherTrait}; @@ -33,7 +32,6 @@ pub mod ProtocolCampagin { pub protocol_nft_class_hash: ClassHash, // The protocol nft class hash protocol_owner: Map::, // map the owner address and the protocol id protocols: Map::, // map the protocol details and the protocol id - protocol_initialized: Map::, // track if the protocol id has been used or not users_count: u256, pub Campaign_members: Map::< (u256, ContractAddress), CampaignMembers @@ -84,15 +82,6 @@ pub mod ProtocolCampagin { } - #[derive(Drop, starknet::Event)] - pub struct CreateTask { - pub protocol_id: u256, - pub task_id: u256, - pub protocol_owner: ContractAddress, - pub task_description: ByteArray, - pub block_timestamp: u64, - } - #[derive(Copy, Drop, Serde)] pub enum UserEventType { Register, @@ -118,7 +107,6 @@ pub mod ProtocolCampagin { TContractState, +HasComponent, +Drop, - impl Weavers: WeaverComponent::HasComponent, impl Ownable: OwnableComponent::HasComponent > of IProtocol> { ///@ protocol registeration @@ -155,33 +143,6 @@ pub mod ProtocolCampagin { } - /// @notice verify protocols after registeration, this is done by the admin - - fn verfify_protocol( - ref self: ComponentState, protocol_address: ContractAddress - ) { - let caller = get_dep_component!(@self, Weavers).get_owner(); - assert(caller == get_caller_address(), Errors::UNAUTHORIZED); - - let protocol_info = self.protocol_register.read(protocol_address); - assert(protocol_info.registered, Errors::PROTOCOL_NOT_REGISTERED); - - self - .protocol_register - .write(protocol_address, ProtocolInfo { verified: true, ..protocol_info }); - - self - .emit( - ProtocolRegistered { - protocol_id: protocol_info.protocol_id, - protocol_owner: get_caller_address(), - event_type: UserEventType::Verify, - block_timestamp: get_block_timestamp() - } - ); - } - - /// @notice Create a new protocol campaign fn create_protocol_campaign( ref self: ComponentState, protocol_id: u256, protocol_info: ByteArray @@ -193,8 +154,6 @@ pub mod ProtocolCampagin { Errors::PROTOCOL_NOT_REGISTERED ); let protocol_nft_class_hash = self.protocol_nft_class_hash.read(); - let protocol_initialized = self.protocol_initialized.read(protocol_id); - assert(!protocol_initialized, Errors::PROTOCOL_ALREADY_EXIST); let protocol_nft_address = self ._deploy_protocol_nft( @@ -213,24 +172,21 @@ pub mod ProtocolCampagin { } - /// @notice adds users to the protocol campaign - /// campaign_user: The user that joins the protocol campaign - /// protocol_id: The id of the protocol that the user will join their campaign + /// @notice adds users to the protocol campaign and the users needs to register first before + /// joining the campaign and have access to weaver NFT campaign_user: The user that joins + /// the protocol campaign protocol_id: The id of the protocol that the user will join their + /// campaign fn join_protocol_campaign( ref self: ComponentState, campaign_user: ContractAddress, protocol_id: u256 ) { - get_dep_component!(@self, Weavers).get_register_user(campaign_user); assert(protocol_id.is_non_zero(), Errors::INVALID_PROTOCOL_ID); assert(!campaign_user.is_zero(), Errors::INVALID_ADDRESS); let caller = get_caller_address(); assert(caller == campaign_user, Errors::UNAUTHORIZED); - let protocol_initialized = self.protocol_initialized.read(protocol_id); - assert(protocol_initialized, Errors::PROTOCOL_DOES_NOT_EXIST); - let (is_member, _): (bool, CampaignMembers) = self .is_campaign_member(campaign_user, protocol_id); @@ -242,7 +198,7 @@ pub mod ProtocolCampagin { } - /// @notice set the matadat uri of the protocol + /// @notice set the matadata uri of the protocol /// protcol_id: the protocol_id for the protocol /// matadata_uri: The protocol matadata uri @@ -289,18 +245,32 @@ pub mod ProtocolCampagin { fn get_protocol( self: @ComponentState, protocol_id: u256 ) -> ProtocolDetails { - return self.protocols.read(protocol_id); + let protocol = self.protocols.read(protocol_id); + let protocol_construct = ProtocolDetails { + protocol_details: Option::Some( + self.get_registered_protocol(protocol.protocol_owner) + ), + ..protocol + }; + return protocol_construct; } - fn get_campaign_members( - self: @ComponentState, protocol_id: u256 + /// @notice get the particular protocol campaign for each users + /// protocol_id: id of the returned community + /// user: The user that joined the protocol campaign + /// @return campaignMembers: The details of the protocol campaign for each users + + fn get_campaign_for_member( + self: @ComponentState, protocol_id: u256, user: ContractAddress ) -> CampaignMembers { let protocol = self.protocols.read(protocol_id); - let campaign_members = self - .Campaign_members - .read((protocol_id, protocol.protocol_owner)); - return campaign_members; + let campaign_members = self.Campaign_members.read((protocol_id, user)); + let campaign_construct = CampaignMembers { + campaign_details: Option::Some(self.get_protocol(protocol.protocol_id)), + ..campaign_members + }; + return campaign_construct; } @@ -336,6 +306,50 @@ pub mod ProtocolCampagin { fn get_protocol_nft_class_hash(self: @ComponentState) -> ClassHash { return self.protocol_nft_class_hash.read(); } + + fn get_all_protocol_details( + self: @ComponentState + ) -> Array { + let mut index = 1; + let mut protocol = array![]; + let protocol_counter = self.protocol_counter.read(); + while index <= protocol_counter { + let protocol_details = self.protocols.read(index); + let protocol_construct = ProtocolDetails { + protocol_details: Option::Some( + self.get_registered_protocol(protocol_details.protocol_owner) + ), + ..protocol_details + }; + protocol.append(protocol_construct); + index += 1; + }; + return protocol; + } + + fn get_all_campaign_for_members( + self: @ComponentState, user: ContractAddress + ) -> Array { + let mut index = 1; + let mut campaign_user = array![]; + let length = self.protocol_counter.read(); + while index <= length { + let campaign_details = self.Campaign_members.read((index, user)); + if campaign_details.user_address == user { + let campaign_construct = CampaignMembers { + campaign_details: Option::Some( + self.get_protocol(campaign_details.protocol_id) + ), + ..campaign_details + }; + + campaign_user.append(campaign_construct); + } + + index += 1; + }; + return campaign_user; + } } @@ -348,7 +362,6 @@ pub mod ProtocolCampagin { TContractState, +HasComponent, +Drop, - impl Weavers: WeaverComponent::HasComponent, impl Ownable: OwnableComponent::HasComponent > of PrivateTrait { // @notice initialize protocol component @@ -379,13 +392,13 @@ pub mod ProtocolCampagin { protocol_id: protocol_id, protocol_owner: protocol_owner, protocol_matadata_uri: "", + protocol_details: Option::None, protocol_nft_address: protocol_nft_address, protocol_campaign_members: 0, protocol_info: "", }; self.protocols.write(protocol_id, protocol_details); - self.protocol_initialized.write(protocol_id, true); self.protocol_owner.write(key: protocol_id, value: protocol_owner); self.protocol_counter.write(protocol_id); self.protocol_info.write(protocol_id, protocol_info); @@ -419,7 +432,10 @@ pub mod ProtocolCampagin { let minted_token_id = self._mint_protocol_nft(user, protocol_nft_address); let Campaign_members = CampaignMembers { - user_address: user, protocol_id: protocol_id, protocol_token_id: minted_token_id, + user_address: user, + protocol_id: protocol_id, + campaign_details: Option::None, + protocol_token_id: minted_token_id, }; // Update storage diff --git a/src/mods/protocol/protocols.cairo b/src/mods/protocol/protocols.cairo index afd79b4..d21b0c5 100644 --- a/src/mods/protocol/protocols.cairo +++ b/src/mods/protocol/protocols.cairo @@ -1,38 +1,33 @@ #[starknet::contract] pub mod protocols { use starknet::ContractAddress; - use crate::mods::protocol::protocolcomponent::ProtocolCampagin; - use crate::mods::weaver_contract::weaver_component::WeaverComponent; + use crate::mods::protocol::protocolcomponent::ProtocolCampaign; + // use crate::mods::weaver_contract::weaver_component::WeaverComponent; use openzeppelin_access::ownable::OwnableComponent; - component!(path: ProtocolCampagin, storage: Protocols, event: ProtocolEvent); + component!(path: ProtocolCampaign, storage: Protocols, event: ProtocolEvent); component!(path: OwnableComponent, storage: ownable, event: OwnableEvent); - component!(path: WeaverComponent, storage: weaver, event: WeaverEvent); #[abi(embed_v0)] - impl ProtocolImpl = ProtocolCampagin::ProtocolCampaigm; - impl protocolPrivateimpl = ProtocolCampagin::Private; + impl ProtocolImpl = ProtocolCampaign::ProtocolCampaigm; + impl protocolPrivateimpl = ProtocolCampaign::Private; #[storage] struct Storage { #[substorage(v0)] - pub Protocols: ProtocolCampagin::Storage, + pub Protocols: ProtocolCampaign::Storage, #[substorage(v0)] pub ownable: OwnableComponent::Storage, - #[substorage(v0)] - pub weaver: WeaverComponent::Storage, } #[event] #[derive(Drop, starknet::Event)] enum Event { #[flat] - ProtocolEvent: ProtocolCampagin::Event, + ProtocolEvent: ProtocolCampaign::Event, #[flat] OwnableEvent: OwnableComponent::Event, - #[flat] - WeaverEvent: WeaverComponent::Event, } diff --git a/src/mods/types.cairo b/src/mods/types.cairo index 14608da..3d66271 100644 --- a/src/mods/types.cairo +++ b/src/mods/types.cairo @@ -8,12 +8,6 @@ pub struct User { pub user_owner: ContractAddress, } -#[derive(Copy, Drop, Serde, starknet::Store)] -pub struct TaskInfo { - pub task_id: u256, - pub user: ContractAddress, - pub is_completed: bool, -} #[derive(Drop, Serde, Debug, PartialEq, starknet::Store)] pub struct ProtocolInfo { @@ -31,6 +25,7 @@ pub struct ProtocolDetails { pub protocol_owner: ContractAddress, pub protocol_matadata_uri: ByteArray, pub protocol_nft_address: ContractAddress, + pub protocol_details: Option, pub protocol_campaign_members: u256, pub protocol_info: ByteArray, } @@ -40,14 +35,7 @@ pub struct ProtocolDetails { pub struct CampaignMembers { pub user_address: ContractAddress, pub protocol_id: u256, + pub campaign_details: Option, pub protocol_token_id: u256, } -#[derive(Drop, Serde, Debug, PartialEq, starknet::Store)] -pub struct ProtocolCreateTask { - pub protocol_id: u256, - pub protocol_owner: ContractAddress, - pub task_Description: ByteArray, - pub task_id: u256, -} - diff --git a/src/mods/weaver_contract/weaver.cairo b/src/mods/weaver_contract/weaver.cairo index dad5aac..29ed9a0 100644 --- a/src/mods/weaver_contract/weaver.cairo +++ b/src/mods/weaver_contract/weaver.cairo @@ -1,40 +1,122 @@ #[starknet::contract] -pub mod WeaverContract { - use WeaverComponent::PrivateTrait; - use starknet::ContractAddress; - use crate::mods::weaver_contract::weaver_component::WeaverComponent; +pub mod Weaver { + // ************************************************************************* + // IMPORT + // ************************************************************************* + + use core::num::traits::Zero; + use starknet::storage::StoragePointerReadAccess; + use starknet::storage::StorageMapWriteAccess; + use starknet::storage::StorageMapReadAccess; + + use starknet::storage::StoragePointerWriteAccess; + use openzeppelin_access::ownable::OwnableComponent; - component!(path: WeaverComponent, storage: Weaver, event: WeaverEvent); - component!(path: OwnableComponent, storage: ownable, event: OwnableEvent); + use starknet::{ + SyscallResultTrait, class_hash::ClassHash, storage::Map, ContractAddress, + get_caller_address, get_block_timestamp, + }; + + use crate::mods::types::{User}; + use crate::mods::events::{Upgraded, UserRegistered, UserEventType}; + use crate::mods::errors::Errors; + use crate::mods::events; + use crate::mods::interfaces::IWeaver::IWeaver; + use crate::mods::interfaces::IWeaverNFT::{IWeaverNFTDispatcher, IWeaverNFTDispatcherTrait}; - #[abi(embed_v0)] - impl WeaverImpl = WeaverComponent::Weavers; - impl WeaverPrivateimpl = WeaverComponent::Private; + + // ************************************************************************* + // STORAGE + // ************************************************************************* #[storage] - struct Storage { - #[substorage(v0)] - pub Weaver: WeaverComponent::Storage, - #[substorage(v0)] - pub ownable: OwnableComponent::Storage, + pub struct Storage { + weaver_nft_address: ContractAddress, + users: Map::, + // user_index: Map::, + user_count: u256, + user: Map::, + pub owner: ContractAddress, } + + // ************************************************************************* + // EVENTS + // ************************************************************************* #[event] - #[derive(Drop, starknet::Event)] - enum Event { - #[flat] - WeaverEvent: WeaverComponent::Event, - #[flat] - OwnableEvent: OwnableComponent::Event, + #[derive(Copy, Drop, starknet::Event)] + pub enum Event { + Upgraded: Upgraded, + UserRegistered: UserRegistered, } #[constructor] fn constructor(ref self: ContractState, owner: ContractAddress) { - self.Weaver._initialize(owner); + self.owner.write(owner); } - fn set_erc721(ref self: ContractState, weaver_nft_address: ContractAddress) { - self.Weaver.set_erc721(weaver_nft_address); + + // ************************************************************************* + // EXTERNAL FUNCTIONS + // ************************************************************************* + + #[abi(embed_v0)] + impl WeaverImpl of IWeaver { + fn register_User(ref self: ContractState, Details: ByteArray) { + let caller = get_caller_address(); + assert(!self.users.read(caller).registered, Errors::USER_ALREADY_REGISTERED); + let id = self.user_count.read() + 1; + let user = User { + Details: Details, registered: true, user_id: id, user_owner: caller, + }; + self.users.write(caller, user); + self.user.write(id, caller); + self.user_count.write(id); + + let weavernft_dispatcher = IWeaverNFTDispatcher { + contract_address: self.weaver_nft_address.read(), + }; + weavernft_dispatcher.mint_weaver_nft(caller); + + self + .emit( + Event::UserRegistered( + events::UserRegistered { + user_id: id, + user: caller, + event_type: UserEventType::Register, + block_timestamp: get_block_timestamp(), + } + ) + ); + } + + + fn get_register_user(self: @ContractState, address: ContractAddress) -> User { + assert(address.is_non_zero(), Errors::INVALID_ADDRESS); + let user = self.users.read(address); + assert(user.registered, Errors::USER_NOT_REGISTERED); + return user; + } + + fn get_owner(self: @ContractState) -> ContractAddress { + return self.owner.read(); + } + + fn set_erc721(ref self: ContractState, address: ContractAddress) { + assert(get_caller_address() == self.owner.read(), Errors::UNAUTHORIZED); + assert(address.is_non_zero(), Errors::INVALID_ADDRESS); + self.weaver_nft_address.write(address); + } + + fn get_user_id(self: @ContractState) -> u256 { + return self.user_count.read(); + } + + fn get_erc721(self: @ContractState) -> ContractAddress { + return self.weaver_nft_address.read(); + } } } + diff --git a/src/mods/weaver_contract/weaver_component.cairo b/src/mods/weaver_contract/weaver_component.cairo deleted file mode 100644 index 99bc65e..0000000 --- a/src/mods/weaver_contract/weaver_component.cairo +++ /dev/null @@ -1,134 +0,0 @@ -#[starknet::component] -pub mod WeaverComponent { - // ************************************************************************* - // IMPORT - // ************************************************************************* - - use OwnableComponent::InternalTrait; - use core::num::traits::Zero; - use starknet::storage::StoragePointerReadAccess; - use starknet::storage::StorageMapWriteAccess; - use starknet::storage::StorageMapReadAccess; - - use starknet::storage::StoragePointerWriteAccess; - - use openzeppelin_access::ownable::OwnableComponent; - - use starknet::{ - SyscallResultTrait, class_hash::ClassHash, storage::Map, ContractAddress, - get_caller_address, get_block_timestamp - }; - - use crate::mods::types::{User}; - use crate::mods::events::{TaskMinted, Upgraded, UserRegistered, UserEventType}; - use crate::mods::errors::Errors; - use crate::mods::events; - use crate::mods::interfaces::IWeaver::IWeaver; - use crate::mods::interfaces::IWeaverNFT::{IWeaverNFTDispatcher, IWeaverNFTDispatcherTrait}; - - - // ************************************************************************* - // STORAGE - // ************************************************************************* - - #[storage] - pub struct Storage { - weaver_nft_address: ContractAddress, - users: Map::, - // user_index: Map::, - user_count: u256, - User_id: u256, - user: Map::, - owner: ContractAddress, - } - - - // ************************************************************************* - // EVENTS - // ************************************************************************* - #[event] - #[derive(Copy, Drop, starknet::Event)] - pub enum Event { - Upgraded: Upgraded, - UserRegistered: UserRegistered, - TaskMinted: TaskMinted, - } - - - // ************************************************************************* - // EXTERNAL FUNCTIONS - // ************************************************************************* - - #[embeddable_as(Weavers)] - impl WeaverImpl< - TContractState, - +HasComponent, - +Drop, - impl Ownable: OwnableComponent::HasComponent - > of IWeaver> { - fn register_User(ref self: ComponentState, Details: ByteArray) { - let caller = get_caller_address(); - assert(!self.users.read(caller).registered, Errors::USER_ALREADY_REGISTERED); - let id = self.user_count.read() + 1; - let user = User { - Details: Details, registered: true, user_id: id, user_owner: caller, - }; - self.users.write(caller, user); - self.user.write(id, caller); - self.user_count.write(id); - - let weavernft_dispatcher = IWeaverNFTDispatcher { - contract_address: self.weaver_nft_address.read(), - }; - weavernft_dispatcher.mint_weaver_nft(caller); - - self - .emit( - Event::UserRegistered( - events::UserRegistered { - user_id: id, - user: caller, - event_type: UserEventType::Register, - block_timestamp: get_block_timestamp(), - } - ) - ); - } - - fn get_register_user( - self: @ComponentState, address: ContractAddress - ) -> User { - assert(address.is_non_zero(), Errors::INVALID_ADDRESS); - assert(self.users.read(address).registered, Errors::USER_NOT_REGISTERED); - return self.users.read(address); - } - - fn get_owner(self: @ComponentState) -> ContractAddress { - return self.owner.read(); - } - } - - // ************************************************************************* - // PRIVATE FUNCTIONS - // ************************************************************************* - - #[generate_trait] - pub impl Private< - TContractState, - +HasComponent, - +Drop, - impl Ownable: OwnableComponent::HasComponent - > of PrivateTrait { - fn _initialize(ref self: ComponentState, owner: ContractAddress) { - let mut ownable_comp = get_dep_component_mut!(ref self, Ownable); - ownable_comp.initializer(owner); - } - - fn set_erc721(ref self: ComponentState, address: ContractAddress) { - assert(get_caller_address() == self.owner.read(), Errors::UNAUTHORIZED); - assert(address.is_non_zero(), Errors::INVALID_ADDRESS); - self.weaver_nft_address.write(address); - } - } -} - diff --git a/tests/test_protocol_component.cairo b/tests/test_protocol_component.cairo index 2a037eb..91c10c4 100644 --- a/tests/test_protocol_component.cairo +++ b/tests/test_protocol_component.cairo @@ -13,8 +13,16 @@ use weaver_contract::mods::interfaces::ICustomNFT::{ ICustomNFTDispatcher, ICustomNFTDispatcherTrait, }; use weaver_contract::mods::interfaces::Iprotocol::{IProtocolDispatcher, IProtocolDispatcherTrait}; -use weaver_contract::mods::protocol::protocolcomponent::ProtocolCampagin; +use weaver_contract::mods::interfaces::IWeaver::{IWeaverDispatcher, IWeaverDispatcherTrait}; +use weaver_contract::mods::interfaces::IWeaverNFT::{ + IWeaverNFTDispatcher, IWeaverNFTDispatcherTrait, +}; +use weaver_contract::mods::protocol::protocolcomponent::ProtocolCampaign; + use weaver_contract::mods::protocol::protocols::protocols; +use weaver_contract::mods::protocol::protocolcomponent::ProtocolCampaign::UserEventType; +use weaver_contract::mods::types::{CampaignMembers, ProtocolDetails, ProtocolInfo, User,}; + fn USER() -> ContractAddress { 'recipient'.try_into().unwrap() @@ -24,6 +32,11 @@ fn PROTOCOL() -> ContractAddress { 'protocol'.try_into().unwrap() } +fn OWNER() -> ContractAddress { + 'owner'.try_into().unwrap() +} + + fn ___setup___() -> ContractAddress { // deploy protocol nft let protocol_nft_class_hash = declare("protocolNFT").unwrap().contract_class(); @@ -38,6 +51,78 @@ fn ___setup___() -> ContractAddress { return protocol_contract_address; } + +fn setup_weaver() -> ContractAddress { + let weaver_class_hash = declare("Weaver").unwrap().contract_class(); + let mut calldata = array![]; + OWNER().serialize(ref calldata); + let (weaver_contract_address, _) = weaver_class_hash.deploy(@calldata).unwrap(); + let weaver_NFT = __deploy_weaver_erc721__(OWNER()); + let weaver = IWeaverDispatcher { contract_address: weaver_contract_address }; + + let owner = weaver.get_owner(); + + start_cheat_caller_address(weaver_contract_address, owner); + weaver.set_erc721(weaver_NFT); + stop_cheat_caller_address(weaver_contract_address); + + return weaver_contract_address; +} + + +fn __deploy_weaver_erc721__(admin: ContractAddress) -> ContractAddress { + let weaver_erc721_class_hash = declare("WeaverNFT").unwrap().contract_class(); + let mut calldata = array![]; + admin.serialize(ref calldata); + let (weaver_erc721_contract_address, _) = weaver_erc721_class_hash.deploy(@calldata).unwrap(); + + return weaver_erc721_contract_address; +} + + +#[test] +fn test_protocol_registration() { + let protocol_contract_address = ___setup___(); + let protocol_dispatcher = IProtocolDispatcher { contract_address: protocol_contract_address }; + let mut protocol_Details: ByteArray = "WEAVER"; + let protocol = PROTOCOL(); + + //register protocol + start_cheat_caller_address(protocol_contract_address, protocol); + protocol_dispatcher.protocol_register(protocol_Details.clone()); + let is_protocol_registered = protocol_dispatcher.get_registered_protocol(protocol); + assert!(is_protocol_registered.protocol_Details == "WEAVER", "Invalid protocol info"); + assert!(is_protocol_registered.protocol_owner == protocol, "Invalid protocol owner"); + assert!(is_protocol_registered.protocol_id == 1, "Invalid protocol id"); + assert!(is_protocol_registered.registered == true, "Invalid protocol registration"); + assert!(is_protocol_registered.verified == false, "Invalid protocol verification"); + stop_cheat_caller_address(protocol_contract_address); +} + +#[test] +#[should_panic(expected: 'PROTOCOL_ALREADY_REGISTERED')] +fn test_protocol_registration_already_registered() { + let protocol_contract_address = ___setup___(); + let protocol_dispatcher = IProtocolDispatcher { contract_address: protocol_contract_address }; + let mut protocol_Details: ByteArray = "WEAVER"; + let protocol = PROTOCOL(); + + //register protocol + start_cheat_caller_address(protocol_contract_address, protocol); + protocol_dispatcher.protocol_register(protocol_Details.clone()); + let is_protocol_registered = protocol_dispatcher.get_registered_protocol(protocol); + assert!(is_protocol_registered.protocol_Details == "WEAVER", "Invalid protocol info"); + stop_cheat_caller_address(protocol_contract_address); + + //register protocol again + start_cheat_caller_address(protocol_contract_address, protocol); + protocol_dispatcher.protocol_register(protocol_Details.clone()); + let is_protocol_registered = protocol_dispatcher.get_registered_protocol(protocol); + assert!(is_protocol_registered.protocol_Details == "WEAVER", "Invalid protocol info"); + stop_cheat_caller_address(protocol_contract_address); +} + + #[test] fn test_create_protocol_campaign() { let protocol_contract_address = ___setup___(); @@ -48,6 +133,13 @@ fn test_create_protocol_campaign() { let mut protocol_info: ByteArray = "WEAVER"; let protocol = PROTOCOL(); + // register protocol + start_cheat_caller_address(protocol_contract_address, protocol); + protocol_dispatcher.protocol_register(protocol_info.clone()); + let is_protocol_registered = protocol_dispatcher.get_registered_protocol(protocol); + assert!(is_protocol_registered.protocol_Details == "WEAVER", "Invalid protocol info"); + stop_cheat_caller_address(protocol_contract_address); + start_cheat_caller_address(protocol_contract_address, protocol); let create_campaign = protocol_dispatcher.create_protocol_campaign(id, protocol_info.clone()); assert!(create_campaign == 111, "Invalid protocol campaign id"); @@ -64,16 +156,18 @@ fn test_create_protocol_campaign() { } #[test] -#[should_panic(expected: 'PROTOCOL_ALREADY_EXIST')] -fn test_create_protocol_campaign_already_exist() { +#[should_panic(expected: 'PROTOCOL_NOT_REGISTERED')] +fn test_create_protocol_campaign_by_unregistered_protocol() { let protocol_contract_address = ___setup___(); - let protocol_dispatcher = IProtocolDispatcher { contract_address: protocol_contract_address }; let id: u256 = 111; let mut protocol_info: ByteArray = "WEAVER"; let protocol = PROTOCOL(); + // skip protocol registration, to check if the protocol without registration can create a + // campaign + start_cheat_caller_address(protocol_contract_address, protocol); let create_campaign = protocol_dispatcher.create_protocol_campaign(id, protocol_info.clone()); assert!(create_campaign == 111, "Invalid protocol campaign id"); @@ -87,14 +181,60 @@ fn test_create_protocol_campaign_already_exist() { "protocol nft address is not deployed" ); stop_cheat_caller_address(protocol_contract_address); +} + + +#[test] +fn test_join_protocol_campaign() { + let protocol_contract_address = ___setup___(); + + let protocol_dispatcher = IProtocolDispatcher { contract_address: protocol_contract_address }; + + let id: u256 = 111; + let mut protocol_info: ByteArray = "WEAVER"; + let protocol = PROTOCOL(); + + // register protocol + start_cheat_caller_address(protocol_contract_address, protocol); + protocol_dispatcher.protocol_register(protocol_info.clone()); + let is_protocol_registered = protocol_dispatcher.get_registered_protocol(protocol); + assert!(is_protocol_registered.protocol_Details == "WEAVER", "Invalid protocol info"); + stop_cheat_caller_address(protocol_contract_address); start_cheat_caller_address(protocol_contract_address, protocol); let create_campaign = protocol_dispatcher.create_protocol_campaign(id, protocol_info.clone()); + assert!(create_campaign == 111, "Invalid protocol campaign id"); + + let protocol_data = protocol_dispatcher.get_protocol(id); + assert!(protocol_data.protocol_id == id, "Invalid protocol id"); + assert!(protocol_data.protocol_owner == protocol, "Invalid protocol owner"); + assert!(protocol_data.protocol_campaign_members == 0, "Invalid protocol campaign members"); + assert!( + protocol_data.protocol_nft_address != contract_address_const::<0>(), + "protocol nft address is not deployed" + ); + + stop_cheat_caller_address(protocol_contract_address); + + let user = USER(); + start_cheat_caller_address(protocol_contract_address, user); + + let protocol_data = protocol_dispatcher.get_protocol(id); + protocol_dispatcher.join_protocol_campaign(user, id); + let is_user_joined = protocol_dispatcher.get_campaign_for_member(id, user); + assert!(is_user_joined.user_address == user, "Invalid user address"); + assert!(is_user_joined.protocol_id == id, "Invalid protocol id"); + + let all_user_campaign = protocol_dispatcher.get_all_campaign_for_members(user); + assert_eq!(all_user_campaign[0].protocol_id, @id, "Invalid protocol id"); + assert_eq!(all_user_campaign[0].user_address, @user, "Invalid user address"); stop_cheat_caller_address(protocol_contract_address); } + #[test] -fn test_emit_create_protocol_campaign() { +#[should_panic(expected: 'INVALID_PROTOCOL_ID')] +fn test_join_protocol_campaign_invalid_protocol_id() { let protocol_contract_address = ___setup___(); let protocol_dispatcher = IProtocolDispatcher { contract_address: protocol_contract_address }; @@ -103,7 +243,12 @@ fn test_emit_create_protocol_campaign() { let mut protocol_info: ByteArray = "WEAVER"; let protocol = PROTOCOL(); - let mut spy = spy_events(); + // register protocol + start_cheat_caller_address(protocol_contract_address, protocol); + protocol_dispatcher.protocol_register(protocol_info.clone()); + let is_protocol_registered = protocol_dispatcher.get_registered_protocol(protocol); + assert!(is_protocol_registered.protocol_Details == "WEAVER", "Invalid protocol info"); + stop_cheat_caller_address(protocol_contract_address); start_cheat_caller_address(protocol_contract_address, protocol); let create_campaign = protocol_dispatcher.create_protocol_campaign(id, protocol_info.clone()); @@ -117,29 +262,60 @@ fn test_emit_create_protocol_campaign() { protocol_data.protocol_nft_address != contract_address_const::<0>(), "protocol nft address is not deployed" ); + stop_cheat_caller_address(protocol_contract_address); - spy - .assert_emitted( - @array![ - ( - protocol_contract_address, - ProtocolCampagin::Event::ProtocolCampaign( - ProtocolCampagin::ProtocolCampaign { - protocol_id: id, - protocol_owner: protocol, - protocol_nft_address: protocol_data.protocol_nft_address, - block_timestamp: get_block_timestamp() - } - ) - ) - ] - ) + let user = USER(); + + start_cheat_caller_address(protocol_contract_address, user); + + let user_join_campaign = protocol_dispatcher.join_protocol_campaign(user, 0); + + stop_cheat_caller_address(protocol_contract_address); } +#[test] +#[should_panic(expected: 'INVALID_ADDRESS')] +fn test_join_protocol_campaign_with_zero_address() { + let protocol_contract_address = ___setup___(); + + let protocol_dispatcher = IProtocolDispatcher { contract_address: protocol_contract_address }; + + let id: u256 = 111; + let mut protocol_info: ByteArray = "WEAVER"; + let protocol = PROTOCOL(); + let zero_address = contract_address_const::<0>(); + + // register protocol + start_cheat_caller_address(protocol_contract_address, protocol); + protocol_dispatcher.protocol_register(protocol_info.clone()); + let is_protocol_registered = protocol_dispatcher.get_registered_protocol(protocol); + assert!(is_protocol_registered.protocol_Details == "WEAVER", "Invalid protocol info"); + stop_cheat_caller_address(protocol_contract_address); + + start_cheat_caller_address(protocol_contract_address, protocol); + let create_campaign = protocol_dispatcher.create_protocol_campaign(id, protocol_info.clone()); + assert!(create_campaign == 111, "Invalid protocol campaign id"); + + let protocol_data = protocol_dispatcher.get_protocol(id); + assert!(protocol_data.protocol_id == id, "Invalid protocol id"); + assert!(protocol_data.protocol_owner == protocol, "Invalid protocol owner"); + assert!(protocol_data.protocol_campaign_members == 0, "Invalid protocol campaign members"); + assert!( + protocol_data.protocol_nft_address != contract_address_const::<0>(), + "protocol nft address is not deployed" + ); + + stop_cheat_caller_address(protocol_contract_address); + + start_cheat_caller_address(protocol_contract_address, zero_address); + let user_join_campaign = protocol_dispatcher.join_protocol_campaign(zero_address, id); + stop_cheat_caller_address(protocol_contract_address); +} #[test] -fn test_join_prototocl_campaign() { +#[should_panic(expected: 'UNAUTHORIZED')] +fn test_join_protocol_campaign_not_caller() { let protocol_contract_address = ___setup___(); let protocol_dispatcher = IProtocolDispatcher { contract_address: protocol_contract_address }; @@ -147,6 +323,14 @@ fn test_join_prototocl_campaign() { let id: u256 = 111; let mut protocol_info: ByteArray = "WEAVER"; let protocol = PROTOCOL(); + let zero_address = contract_address_const::<0>(); + + // register protocol + start_cheat_caller_address(protocol_contract_address, protocol); + protocol_dispatcher.protocol_register(protocol_info.clone()); + let is_protocol_registered = protocol_dispatcher.get_registered_protocol(protocol); + assert!(is_protocol_registered.protocol_Details == "WEAVER", "Invalid protocol info"); + stop_cheat_caller_address(protocol_contract_address); start_cheat_caller_address(protocol_contract_address, protocol); let create_campaign = protocol_dispatcher.create_protocol_campaign(id, protocol_info.clone()); @@ -160,13 +344,69 @@ fn test_join_prototocl_campaign() { protocol_data.protocol_nft_address != contract_address_const::<0>(), "protocol nft address is not deployed" ); + stop_cheat_caller_address(protocol_contract_address); let user = USER(); start_cheat_caller_address(protocol_contract_address, user); - let join_campaign = protocol_dispatcher.join_protocol_campaign(user, id); - + let user_join_campaign = protocol_dispatcher.join_protocol_campaign(protocol, id); stop_cheat_caller_address(protocol_contract_address); } + +#[test] +fn test_weaver_register_user() { + let weaver_contract_address = setup_weaver(); + let weaver = IWeaverDispatcher { contract_address: weaver_contract_address }; + let user = USER(); + let user_details: ByteArray = "WEAVER"; + start_cheat_caller_address(weaver_contract_address, user); + weaver.register_User(user_details.clone()); + let is_user_registered = weaver.get_register_user(user); + assert!(is_user_registered.registered == true, "Invalid user registration"); + assert!(is_user_registered.user_id == 1, "Invalid user id"); + assert!(is_user_registered.user_owner == user, "Invalid user owner"); + assert!(is_user_registered.Details == "WEAVER", "Invalid user details"); + stop_cheat_caller_address(weaver_contract_address); +} + +#[test] +#[should_panic(expected: 'USER_ALREADY_REGISTERED')] +fn test_weaver_register_user_already_registered() { + let weaver_contract_address = setup_weaver(); + let weaver = IWeaverDispatcher { contract_address: weaver_contract_address }; + let user = USER(); + let user_details: ByteArray = "WEAVER"; + start_cheat_caller_address(weaver_contract_address, user); + weaver.register_User(user_details.clone()); + let is_user_registered = weaver.get_register_user(user); + assert!(is_user_registered.registered == true, "Invalid user registration"); + assert!(is_user_registered.user_id == 1, "Invalid user id"); + assert!(is_user_registered.user_owner == user, "Invalid user owner"); + assert!(is_user_registered.Details == "WEAVER", "Invalid user details"); + stop_cheat_caller_address(weaver_contract_address); + + start_cheat_caller_address(weaver_contract_address, user); + weaver.register_User(user_details.clone()); + let is_user_registered = weaver.get_register_user(user); + assert!(is_user_registered.registered == true, "Invalid user registration"); + assert!(is_user_registered.user_id == 1, "Invalid user id"); + assert!(is_user_registered.user_owner == user, "Invalid user owner"); + assert!(is_user_registered.Details == "WEAVER", "Invalid user details"); + stop_cheat_caller_address(weaver_contract_address); +} + +#[test] +fn test_set_erc721() { + let weaver_contract_address = setup_weaver(); + let weaver = IWeaverDispatcher { contract_address: weaver_contract_address }; + let owner = weaver.get_owner(); + let weaver_erc721 = __deploy_weaver_erc721__(owner); + start_cheat_caller_address(weaver_contract_address, owner); + weaver.set_erc721(weaver_erc721); + weaver.get_erc721(); + assert!(weaver.get_erc721() == weaver_erc721, "Invalid erc721 address"); + stop_cheat_caller_address(weaver_contract_address); +} + diff --git a/tests/test_weaver_contract.cairo b/tests/test_weaver_contract.cairo index 97769a7..831e687 100644 --- a/tests/test_weaver_contract.cairo +++ b/tests/test_weaver_contract.cairo @@ -1,151 +1,149 @@ -use core::option::OptionTrait; -use core::result::ResultTrait; -use core::traits::{TryInto}; -use core::byte_array::ByteArray; - -use snforge_std::{ - declare, start_cheat_caller_address, stop_cheat_caller_address, ContractClassTrait, - DeclareResultTrait, spy_events, EventSpyAssertionsTrait, -}; +// use core::option::OptionTrait; +// use core::result::ResultTrait; +// use core::traits::{TryInto}; +// use core::byte_array::ByteArray; + +// use snforge_std::{ +// declare, start_cheat_caller_address, stop_cheat_caller_address, ContractClassTrait, +// DeclareResultTrait, spy_events, EventSpyAssertionsTrait, +// }; + +// use starknet::{ContractAddress, get_block_timestamp}; + +// use weaver_contract::mods::interfaces::IWeaver::{IWeaverDispatcher, IWeaverDispatcherTrait}; +// use weaver_contract::mods::interfaces::IWeaverNFT::{ +// IWeaverNFTDispatcher, IWeaverNFTDispatcherTrait +// }; +// use weaver_contract::mods::events::{UserRegistered}; +// // use weaver_contract::mods::weaver_contract::events::Event; + +// fn OWNER() -> ContractAddress { +// 'owner'.try_into().unwrap() +// } -use starknet::{ContractAddress, get_block_timestamp}; +// fn USER() -> ContractAddress { +// 'recipient'.try_into().unwrap() +// } -use weaver_contract::mods::interfaces::IWeaver::{IWeaverDispatcher, IWeaverDispatcherTrait}; -use weaver_contract::mods::interfaces::IWeaverNFT::{ - IWeaverNFTDispatcher, IWeaverNFTDispatcherTrait -}; -use weaver_contract::mods::events::{UserRegistered, TaskMinted}; -use weaver_contract::mods::weaver_contract::weaver::Weaver::{Event}; +// fn __setup__() -> ContractAddress { +// let class_hash = declare("Weaver").unwrap().contract_class(); +// let mut calldata = array![]; +// OWNER().serialize(ref calldata); +// let (contract_address, _) = class_hash.deploy(@calldata).unwrap(); +// let nft_address = __deploy_WeaverNFT__(contract_address); +// let weaver_contract = IWeaverDispatcher { contract_address: contract_address }; +// start_cheat_caller_address(contract_address, OWNER()); +// weaver_contract.set_erc721(nft_address); +// stop_cheat_caller_address(contract_address); + +// return contract_address; +// } +// fn __deploy_WeaverNFT__(admin: ContractAddress) -> ContractAddress { +// let nft_class_hash = declare("WeaverNFT").unwrap().contract_class(); +// let mut calldata = array![]; +// admin.serialize(ref calldata); -fn OWNER() -> ContractAddress { - 'owner'.try_into().unwrap() -} +// let (nft_contract_address, _) = nft_class_hash.deploy(@calldata).unwrap(); -fn USER() -> ContractAddress { - 'recipient'.try_into().unwrap() -} +// return (nft_contract_address); +// } -fn __setup__() -> ContractAddress { - let class_hash = declare("Weaver").unwrap().contract_class(); - let mut calldata = array![]; - OWNER().serialize(ref calldata); - let (contract_address, _) = class_hash.deploy(@calldata).unwrap(); - let nft_address = __deploy_WeaverNFT__(contract_address); - let weaver_contract = IWeaverDispatcher { contract_address: contract_address }; - start_cheat_caller_address(contract_address, OWNER()); - weaver_contract.set_erc721(nft_address); - stop_cheat_caller_address(contract_address); +// #[test] +// fn test_weaver_constructor() { +// let weaver_contract_address = __setup__(); +// let weaver_contract = IWeaverDispatcher { contract_address: weaver_contract_address }; - return contract_address; -} +// let owner = weaver_contract.get_owner(); -fn __deploy_WeaverNFT__(admin: ContractAddress) -> ContractAddress { - let nft_class_hash = declare("WeaverNFT").unwrap().contract_class(); - let mut calldata = array![]; - admin.serialize(ref calldata); +// assert_eq!(owner, OWNER()); +// } - let (nft_contract_address, _) = nft_class_hash.deploy(@calldata).unwrap(); +// #[test] +// fn test_register_user() { +// let weaver_contract_address = __setup__(); +// let weaver_contract = IWeaverDispatcher { contract_address: weaver_contract_address }; - return (nft_contract_address); -} +// let user: ContractAddress = USER(); +// start_cheat_caller_address(weaver_contract_address, user); +// let details: ByteArray = "Test User"; +// weaver_contract.register_User(details); -#[test] -fn test_weaver_constructor() { - let weaver_contract_address = __setup__(); - let weaver_contract = IWeaverDispatcher { contract_address: weaver_contract_address }; +// let is_registered = weaver_contract.get_register_user(user); +// assert!(is_registered.Details == "Test User", "User should be registered"); - assert_eq!(weaver_contract.owner(), OWNER()); -} +// stop_cheat_caller_address(weaver_contract_address); +// } +// // #[test] +// // fn test_register_user_emit_event() { +// // let weaver_contract_address = __setup__(); +// // let weaver_contract = IWeaverDispatcher { contract_address: weaver_contract_address }; -#[test] -fn test_register_user() { - let weaver_contract_address = __setup__(); - let weaver_contract = IWeaverDispatcher { contract_address: weaver_contract_address }; +// // let mut spy = spy_events(); - let user: ContractAddress = USER(); - start_cheat_caller_address(weaver_contract_address, user); +// // let user: ContractAddress = USER(); +// // start_cheat_caller_address(weaver_contract_address, user); - let details: ByteArray = "Test User"; - weaver_contract.register_User(details); +// // let details: ByteArray = "Test User"; +// // weaver_contract.register_User(details); - let is_registered = weaver_contract.get_register_user(user); - assert!(is_registered.Details == "Test User", "User should be registered"); +// // let is_registered = weaver_contract.get_register_user(user); +// // assert!(is_registered.Details == "Test User", "User should be registered"); - stop_cheat_caller_address(weaver_contract_address); -} +// // let expected_event = Event::UserRegistered(UserRegistered { user: user }); +// // spy.assert_emitted(@array![(weaver_contract_address, expected_event)]); +// // stop_cheat_caller_address(weaver_contract_address); +// // } // #[test] -// fn test_register_user_emit_event() { +// #[should_panic(expected: 'USER_ALREADY_REGISTERED')] +// fn test_already_registered_should_panic() { // let weaver_contract_address = __setup__(); // let weaver_contract = IWeaverDispatcher { contract_address: weaver_contract_address }; -// let mut spy = spy_events(); - // let user: ContractAddress = USER(); // start_cheat_caller_address(weaver_contract_address, user); +// // First registration should succeed // let details: ByteArray = "Test User"; // weaver_contract.register_User(details); // let is_registered = weaver_contract.get_register_user(user); // assert!(is_registered.Details == "Test User", "User should be registered"); -// let expected_event = Event::UserRegistered(UserRegistered { user: user }); -// spy.assert_emitted(@array![(weaver_contract_address, expected_event)]); +// // Second registration attempt with same address should fail +// let new_details: ByteArray = "Test User"; +// weaver_contract.register_User(new_details); // stop_cheat_caller_address(weaver_contract_address); // } +// // #[test] +// // fn test_nft_was_minted_after_user_registers() { +// // let weaver_contract_address = __setup__(); +// // let weaver_contract = IWeaverDispatcher { contract_address: weaver_contract_address }; +// // let nft_dispatcher = IWeaverNFTDispatcher { contract_address: weaver_contract.erc_721() }; -#[test] -#[should_panic(expected: 'USER_ALREADY_REGISTERED')] -fn test_already_registered_should_panic() { - let weaver_contract_address = __setup__(); - let weaver_contract = IWeaverDispatcher { contract_address: weaver_contract_address }; - - let user: ContractAddress = USER(); - start_cheat_caller_address(weaver_contract_address, user); - - // First registration should succeed - let details: ByteArray = "Test User"; - weaver_contract.register_User(details); - - let is_registered = weaver_contract.get_register_user(user); - assert!(is_registered.Details == "Test User", "User should be registered"); - - // Second registration attempt with same address should fail - let new_details: ByteArray = "Test User"; - weaver_contract.register_User(new_details); - - stop_cheat_caller_address(weaver_contract_address); -} - - -#[test] -fn test_nft_was_minted_after_user_registers() { - let weaver_contract_address = __setup__(); - let weaver_contract = IWeaverDispatcher { contract_address: weaver_contract_address }; - let nft_dispatcher = IWeaverNFTDispatcher { contract_address: weaver_contract.erc_721() }; +// // let user: ContractAddress = USER(); +// // start_cheat_caller_address(weaver_contract_address, user); - let user: ContractAddress = USER(); - start_cheat_caller_address(weaver_contract_address, user); +// // let details: ByteArray = "Test User"; +// // weaver_contract.register_User(details); - let details: ByteArray = "Test User"; - weaver_contract.register_User(details); +// // let minted_token_id = nft_dispatcher.get_user_token_id(user); +// // assert!(minted_token_id > 0, "NFT NOT Minted!"); - let minted_token_id = nft_dispatcher.get_user_token_id(user); - assert!(minted_token_id > 0, "NFT NOT Minted!"); +// // let last_minted_id = nft_dispatcher.get_last_minted_id(); +// // assert_eq!(minted_token_id, last_minted_id, "Minted token ID should match the last minted +// // ID"); - let last_minted_id = nft_dispatcher.get_last_minted_id(); - assert_eq!(minted_token_id, last_minted_id, "Minted token ID should match the last minted ID"); +// // let mint_timestamp = nft_dispatcher.get_token_mint_timestamp(minted_token_id); +// // let current_block_timestamp = get_block_timestamp(); +// // assert_eq!(mint_timestamp, current_block_timestamp, "Mint timestamp not matched"); - let mint_timestamp = nft_dispatcher.get_token_mint_timestamp(minted_token_id); - let current_block_timestamp = get_block_timestamp(); - assert_eq!(mint_timestamp, current_block_timestamp, "Mint timestamp not matched"); +// // stop_cheat_caller_address(weaver_contract_address); +// // } - stop_cheat_caller_address(weaver_contract_address); -}