From f9ba4275222a958540ade4d375ce43306cbc47e5 Mon Sep 17 00:00:00 2001 From: mubarak23 Date: Fri, 18 Oct 2024 14:05:11 +0100 Subject: [PATCH 1/3] feat:use TBA V3 for account profile --- Scarb.toml | 4 +-- src/hub/hub.cairo | 4 ++- src/interfaces/IHub.cairo | 3 +- src/interfaces/IProfile.cairo | 3 +- src/interfaces/IRegistry.cairo | 3 +- src/mocks/interfaces/IComposable.cairo | 3 +- src/mocks/registry.cairo | 44 ++++++++++---------------- src/profile/profile.cairo | 8 +++-- tests/test_hub.cairo | 7 ++-- tests/test_profile.cairo | 8 ++--- tests/test_publication.cairo | 11 ++++--- 11 files changed, 51 insertions(+), 47 deletions(-) diff --git a/Scarb.toml b/Scarb.toml index f00def2..0f14bf3 100644 --- a/Scarb.toml +++ b/Scarb.toml @@ -12,7 +12,7 @@ keywords = ["Karst", "SocialFi", "tokenbound", "cairo", "contracts", "starknet"] [dependencies] starknet = "2.8.2" openzeppelin = { git = "https://github.com/OpenZeppelin/cairo-contracts.git", tag = "v0.17.0" } -token_bound_accounts= { git = "https://github.com/Starknet-Africa-Edu/TBA", tag = "v0.3.0" } +token_bound_accounts= { git = "https://github.com/horuslabsio/TBA", branch = "v3"} alexandria_bytes = { git = "https://github.com/keep-starknet-strange/alexandria.git" } [dev-dependencies] @@ -23,5 +23,5 @@ url= "https://starknet-sepolia.public.blastapi.io" [[target.starknet-contract]] casm = true -build-external-contracts = ["token_bound_accounts::presets::account::Account"] +build-external-contracts = ["token_bound_accounts::components::presets::account_preset::AccountPreset"] allowed-libfuncs-list.name = "experimental" \ No newline at end of file diff --git a/src/hub/hub.cairo b/src/hub/hub.cairo index af8eb87..2ca9e54 100644 --- a/src/hub/hub.cairo +++ b/src/hub/hub.cairo @@ -190,7 +190,9 @@ pub mod KarstHub { let dispatcher = IHandleRegistryDispatcher { contract_address: self.handle_registry_contract_address.read() }; - dispatcher.get_handle(profile_address) + + let handle_id = dispatcher.get_handle(profile_address); + handle_id } /// @notice returns the full handle of a user diff --git a/src/interfaces/IHub.cairo b/src/interfaces/IHub.cairo index 79164e5..b21d08a 100644 --- a/src/interfaces/IHub.cairo +++ b/src/interfaces/IHub.cairo @@ -16,7 +16,8 @@ pub trait IHub { karstnft_contract_address: ContractAddress, registry_hash: felt252, implementation_hash: felt252, - salt: felt252 + salt: felt252, + chain_id: felt252 ) -> ContractAddress; fn set_profile_metadata_uri( diff --git a/src/interfaces/IProfile.cairo b/src/interfaces/IProfile.cairo index 6f7f554..c1a88d4 100644 --- a/src/interfaces/IProfile.cairo +++ b/src/interfaces/IProfile.cairo @@ -13,7 +13,8 @@ pub trait IProfile { karstnft_contract_address: ContractAddress, registry_hash: felt252, implementation_hash: felt252, - salt: felt252 + salt: felt252, + chain_id: felt252 ) -> ContractAddress; fn set_profile_metadata_uri( ref self: TState, profile_address: ContractAddress, metadata_uri: ByteArray diff --git a/src/interfaces/IRegistry.cairo b/src/interfaces/IRegistry.cairo index 6700c8f..9f60df3 100644 --- a/src/interfaces/IRegistry.cairo +++ b/src/interfaces/IRegistry.cairo @@ -13,7 +13,8 @@ pub trait IRegistry { implementation_hash: felt252, token_contract: ContractAddress, token_id: u256, - salt: felt252 + salt: felt252, + chain_id: felt252 ) -> ContractAddress; // ************************************************************************* diff --git a/src/mocks/interfaces/IComposable.cairo b/src/mocks/interfaces/IComposable.cairo index 1e9fc51..12ceebe 100644 --- a/src/mocks/interfaces/IComposable.cairo +++ b/src/mocks/interfaces/IComposable.cairo @@ -15,7 +15,8 @@ pub trait IComposable { karstnft_contract_address: ContractAddress, registry_hash: felt252, implementation_hash: felt252, - salt: felt252 + salt: felt252, + chain_id: felt252, ) -> ContractAddress; fn set_profile_metadata_uri( ref self: TState, profile_address: ContractAddress, metadata_uri: ByteArray diff --git a/src/mocks/registry.cairo b/src/mocks/registry.cairo index 68894b0..be188d5 100644 --- a/src/mocks/registry.cairo +++ b/src/mocks/registry.cairo @@ -7,18 +7,14 @@ pub mod Registry { use core::hash::HashStateTrait; use core::pedersen::PedersenTrait; use starknet::{ - ContractAddress, get_caller_address, syscalls::call_contract_syscall, class_hash::ClassHash, - syscalls::deploy_syscall, SyscallResultTrait, + ContractAddress, get_caller_address, get_contract_address, syscalls::call_contract_syscall, + class_hash::ClassHash, syscalls::deploy_syscall, SyscallResultTrait, storage::{Map, StorageMapReadAccess, StorageMapWriteAccess} }; use token_bound_accounts::interfaces::IRegistry::IRegistry; #[storage] - struct Storage { - registry_deployed_accounts: Map< - (ContractAddress, u256), u8 - >, // tracks no. of deployed accounts by registry for an NFT - } + pub struct Storage {} #[event] #[derive(Drop, starknet::Event)] @@ -53,27 +49,26 @@ pub mod Registry { implementation_hash: felt252, token_contract: ContractAddress, token_id: u256, - salt: felt252 + salt: felt252, + chain_id: felt252 ) -> ContractAddress { let owner = self._get_owner(token_contract, token_id); assert(owner == get_caller_address(), 'CALLER_IS_NOT_OWNER'); let mut constructor_calldata: Array = array![ - token_contract.into(), token_id.low.into(), token_id.high.into() + token_contract.into(), + token_id.low.into(), + token_id.high.into(), + get_contract_address().into(), + implementation_hash, + salt ]; let class_hash: ClassHash = implementation_hash.try_into().unwrap(); let result = deploy_syscall(class_hash, salt, constructor_calldata.span(), true); let (account_address, _) = result.unwrap_syscall(); - let new_deployment_index: u8 = self - .registry_deployed_accounts - .read((token_contract, token_id)) - + 1_u8; - self.registry_deployed_accounts.write((token_contract, token_id), new_deployment_index); - self.emit(AccountCreated { account_address, token_contract, token_id, }); - account_address } @@ -87,13 +82,17 @@ pub mod Registry { implementation_hash: felt252, token_contract: ContractAddress, token_id: u256, - salt: felt252 + salt: felt252, + chain_id: felt252 ) -> ContractAddress { let constructor_calldata_hash = PedersenTrait::new(0) .update(token_contract.into()) .update(token_id.low.into()) .update(token_id.high.into()) - .update(3) + .update(get_contract_address().into()) + .update(implementation_hash) + .update(salt) + .update(6) .finalize(); let prefix: felt252 = 'STARKNET_CONTRACT_ADDRESS'; @@ -108,15 +107,6 @@ pub mod Registry { account_address.try_into().unwrap() } - - /// @notice returns the total no. of deployed tokenbound accounts for an NFT by the registry - /// @param token_contract the contract address of the NFT - /// @param token_id the ID of the NFT - fn total_deployed_accounts( - self: @ContractState, token_contract: ContractAddress, token_id: u256 - ) -> u8 { - self.registry_deployed_accounts.read((token_contract, token_id)) - } } #[generate_trait] diff --git a/src/profile/profile.cairo b/src/profile/profile.cairo index f98b9be..5a7c5c5 100644 --- a/src/profile/profile.cairo +++ b/src/profile/profile.cairo @@ -65,7 +65,8 @@ pub mod ProfileComponent { karstnft_contract_address: ContractAddress, registry_hash: felt252, implementation_hash: felt252, - salt: felt252 + salt: felt252, + chain_id: felt252, ) -> ContractAddress { // mint karst nft let recipient = get_caller_address(); @@ -77,12 +78,13 @@ pub mod ProfileComponent { } let token_id = IKarstNFTDispatcher { contract_address: karstnft_contract_address } .get_user_token_id(recipient); - // create tokenbound account let profile_address = IRegistryLibraryDispatcher { class_hash: registry_hash.try_into().unwrap() } - .create_account(implementation_hash, karstnft_contract_address, token_id, salt); + .create_account( + implementation_hash, karstnft_contract_address, token_id, salt, chain_id + ); // deploy follow nft contract let mut constructor_calldata: Array = array![ diff --git a/tests/test_hub.cairo b/tests/test_hub.cairo index cb10f4e..be8f71a 100644 --- a/tests/test_hub.cairo +++ b/tests/test_hub.cairo @@ -46,7 +46,7 @@ fn __setup__() -> (ContractAddress, ContractAddress, ContractAddress, ContractAd let registry_class_hash = declare("Registry").unwrap().contract_class(); // declare tokenbound account - let account_class_hash = declare("Account").unwrap().contract_class(); + let account_class_hash = declare("AccountPreset").unwrap().contract_class(); // declare follownft let follow_nft_classhash = declare("Follow").unwrap().contract_class(); @@ -69,6 +69,7 @@ fn __setup__() -> (ContractAddress, ContractAddress, ContractAddress, ContractAd nft_contract_address, (*registry_class_hash.class_hash).into(), (*account_class_hash.class_hash).into(), + 2478, 2478 ); stop_cheat_caller_address(hub_contract_address); @@ -79,8 +80,10 @@ fn __setup__() -> (ContractAddress, ContractAddress, ContractAddress, ContractAd nft_contract_address, (*registry_class_hash.class_hash).into(), (*account_class_hash.class_hash).into(), + 2478, 2478 ); + stop_cheat_caller_address(hub_contract_address); start_cheat_caller_address(hub_contract_address, ADDRESS3.try_into().unwrap()); @@ -89,6 +92,7 @@ fn __setup__() -> (ContractAddress, ContractAddress, ContractAddress, ContractAd nft_contract_address, (*registry_class_hash.class_hash).into(), (*account_class_hash.class_hash).into(), + 2478, 2478 ); stop_cheat_caller_address(hub_contract_address); @@ -249,7 +253,6 @@ fn test_set_block_status() { #[test] fn test_get_handle_id() { let (hub_contract_address, user_one_profile_address, _, _, minted_handle_id) = __setup__(); - let dispatcher = IHubDispatcher { contract_address: hub_contract_address }; let handle_id = dispatcher.get_handle_id(user_one_profile_address); assert(handle_id == minted_handle_id, 'invalid handle id'); diff --git a/tests/test_profile.cairo b/tests/test_profile.cairo index 21da092..9cc1aec 100644 --- a/tests/test_profile.cairo +++ b/tests/test_profile.cairo @@ -32,7 +32,7 @@ fn __setup__() -> (ContractAddress, ContractAddress, felt252, felt252, ContractA let (registry_contract_address, _) = registry_class_hash.deploy(@array![]).unwrap_syscall(); // declare account - let account_class_hash = declare("Account").unwrap().contract_class(); + let account_class_hash = declare("AccountPreset").unwrap().contract_class(); // declare follownft let follow_nft_classhash = declare("Follow").unwrap().contract_class(); @@ -71,7 +71,7 @@ fn test_profile_creation() { start_cheat_caller_address(profile_contract_address, USER.try_into().unwrap()); start_cheat_caller_address(nft_contract_address, USER.try_into().unwrap()); let profile_address = profileDispatcher - .create_profile(nft_contract_address, registry_class_hash, account_class_hash, 2456,); + .create_profile(nft_contract_address, registry_class_hash, account_class_hash, 2456, 2456); // test a new karst nft is minted let last_minted_id = karstNFTDispatcher.get_last_minted_id(); @@ -103,7 +103,7 @@ fn test_profile_metadata() { start_cheat_caller_address(profile_contract_address, USER.try_into().unwrap()); start_cheat_caller_address(nft_contract_address, USER.try_into().unwrap()); let profile_address = profileDispatcher - .create_profile(nft_contract_address, registry_class_hash, account_class_hash, 2456); + .create_profile(nft_contract_address, registry_class_hash, account_class_hash, 2456, 2456); profileDispatcher .set_profile_metadata_uri( @@ -137,7 +137,7 @@ fn test_profile_creation_event() { start_cheat_caller_address(nft_contract_address, USER.try_into().unwrap()); let profile_address = profileDispatcher - .create_profile(nft_contract_address, registry_class_hash, account_class_hash, 2456,); + .create_profile(nft_contract_address, registry_class_hash, account_class_hash, 2456, 2456); let token_id = karstNFTDispatcher.get_user_token_id(USER.try_into().unwrap()); diff --git a/tests/test_publication.cairo b/tests/test_publication.cairo index 301de2a..0bd06c1 100644 --- a/tests/test_publication.cairo +++ b/tests/test_publication.cairo @@ -65,7 +65,7 @@ fn __setup__() -> ( .unwrap_syscall(); // declare account - let account_class_hash = declare("Account").unwrap().contract_class(); + let account_class_hash = declare("AccountPreset").unwrap().contract_class(); //declare collectnft let collect_nft_classhash = declare("CollectNFT").unwrap().contract_class(); @@ -80,7 +80,8 @@ fn __setup__() -> ( nft_contract_address, (*registry_class_hash.class_hash).into(), (*account_class_hash.class_hash).into(), - 2478 + 2478, + 2479 ); let content_URI: ByteArray = "ipfs://helloworld"; let mut spy = spy_events(); @@ -99,7 +100,8 @@ fn __setup__() -> ( nft_contract_address, (*registry_class_hash.class_hash).into(), (*account_class_hash.class_hash).into(), - 2479 + 2479, + 2482 ); let content_URI: ByteArray = "ipfs://helloworld"; dispatcher @@ -118,7 +120,8 @@ fn __setup__() -> ( nft_contract_address, (*registry_class_hash.class_hash).into(), (*account_class_hash.class_hash).into(), - 2480 + 2480, + 2481 ); let content_URI: ByteArray = "ipfs://helloworld"; dispatcher From e01e07e602b04e95148a86c34d4b41781f0979e8 Mon Sep 17 00:00:00 2001 From: mubarak23 Date: Sun, 20 Oct 2024 12:31:10 +0100 Subject: [PATCH 2/3] chore:remove chain_id from create profile interface --- src/interfaces/IHub.cairo | 3 +-- src/interfaces/IProfile.cairo | 3 +-- src/mocks/interfaces/IComposable.cairo | 3 +-- src/profile/profile.cairo | 7 ++++--- tests/test_hub.cairo | 3 --- tests/test_profile.cairo | 6 +++--- tests/test_publication.cairo | 9 +++------ 7 files changed, 13 insertions(+), 21 deletions(-) diff --git a/src/interfaces/IHub.cairo b/src/interfaces/IHub.cairo index b21d08a..79164e5 100644 --- a/src/interfaces/IHub.cairo +++ b/src/interfaces/IHub.cairo @@ -16,8 +16,7 @@ pub trait IHub { karstnft_contract_address: ContractAddress, registry_hash: felt252, implementation_hash: felt252, - salt: felt252, - chain_id: felt252 + salt: felt252 ) -> ContractAddress; fn set_profile_metadata_uri( diff --git a/src/interfaces/IProfile.cairo b/src/interfaces/IProfile.cairo index c1a88d4..6f7f554 100644 --- a/src/interfaces/IProfile.cairo +++ b/src/interfaces/IProfile.cairo @@ -13,8 +13,7 @@ pub trait IProfile { karstnft_contract_address: ContractAddress, registry_hash: felt252, implementation_hash: felt252, - salt: felt252, - chain_id: felt252 + salt: felt252 ) -> ContractAddress; fn set_profile_metadata_uri( ref self: TState, profile_address: ContractAddress, metadata_uri: ByteArray diff --git a/src/mocks/interfaces/IComposable.cairo b/src/mocks/interfaces/IComposable.cairo index 12ceebe..1e9fc51 100644 --- a/src/mocks/interfaces/IComposable.cairo +++ b/src/mocks/interfaces/IComposable.cairo @@ -15,8 +15,7 @@ pub trait IComposable { karstnft_contract_address: ContractAddress, registry_hash: felt252, implementation_hash: felt252, - salt: felt252, - chain_id: felt252, + salt: felt252 ) -> ContractAddress; fn set_profile_metadata_uri( ref self: TState, profile_address: ContractAddress, metadata_uri: ByteArray diff --git a/src/profile/profile.cairo b/src/profile/profile.cairo index 5a7c5c5..bd84298 100644 --- a/src/profile/profile.cairo +++ b/src/profile/profile.cairo @@ -5,7 +5,7 @@ pub mod ProfileComponent { // ************************************************************************* use core::{traits::TryInto}; use starknet::{ - ContractAddress, get_caller_address, get_block_timestamp, ClassHash, + get_tx_info, ContractAddress, get_caller_address, get_block_timestamp, ClassHash, syscalls::deploy_syscall, SyscallResultTrait, storage::{ StoragePointerWriteAccess, StoragePointerReadAccess, Map, StorageMapReadAccess, @@ -65,8 +65,7 @@ pub mod ProfileComponent { karstnft_contract_address: ContractAddress, registry_hash: felt252, implementation_hash: felt252, - salt: felt252, - chain_id: felt252, + salt: felt252 ) -> ContractAddress { // mint karst nft let recipient = get_caller_address(); @@ -78,6 +77,8 @@ pub mod ProfileComponent { } let token_id = IKarstNFTDispatcher { contract_address: karstnft_contract_address } .get_user_token_id(recipient); + let tx_info = get_tx_info().unbox(); + let chain_id = tx_info.chain_id; // create tokenbound account let profile_address = IRegistryLibraryDispatcher { class_hash: registry_hash.try_into().unwrap() diff --git a/tests/test_hub.cairo b/tests/test_hub.cairo index be8f71a..9f046f5 100644 --- a/tests/test_hub.cairo +++ b/tests/test_hub.cairo @@ -69,7 +69,6 @@ fn __setup__() -> (ContractAddress, ContractAddress, ContractAddress, ContractAd nft_contract_address, (*registry_class_hash.class_hash).into(), (*account_class_hash.class_hash).into(), - 2478, 2478 ); stop_cheat_caller_address(hub_contract_address); @@ -80,7 +79,6 @@ fn __setup__() -> (ContractAddress, ContractAddress, ContractAddress, ContractAd nft_contract_address, (*registry_class_hash.class_hash).into(), (*account_class_hash.class_hash).into(), - 2478, 2478 ); @@ -92,7 +90,6 @@ fn __setup__() -> (ContractAddress, ContractAddress, ContractAddress, ContractAd nft_contract_address, (*registry_class_hash.class_hash).into(), (*account_class_hash.class_hash).into(), - 2478, 2478 ); stop_cheat_caller_address(hub_contract_address); diff --git a/tests/test_profile.cairo b/tests/test_profile.cairo index 9cc1aec..6db0d08 100644 --- a/tests/test_profile.cairo +++ b/tests/test_profile.cairo @@ -71,7 +71,7 @@ fn test_profile_creation() { start_cheat_caller_address(profile_contract_address, USER.try_into().unwrap()); start_cheat_caller_address(nft_contract_address, USER.try_into().unwrap()); let profile_address = profileDispatcher - .create_profile(nft_contract_address, registry_class_hash, account_class_hash, 2456, 2456); + .create_profile(nft_contract_address, registry_class_hash, account_class_hash, 2456); // test a new karst nft is minted let last_minted_id = karstNFTDispatcher.get_last_minted_id(); @@ -103,7 +103,7 @@ fn test_profile_metadata() { start_cheat_caller_address(profile_contract_address, USER.try_into().unwrap()); start_cheat_caller_address(nft_contract_address, USER.try_into().unwrap()); let profile_address = profileDispatcher - .create_profile(nft_contract_address, registry_class_hash, account_class_hash, 2456, 2456); + .create_profile(nft_contract_address, registry_class_hash, account_class_hash, 2456); profileDispatcher .set_profile_metadata_uri( @@ -137,7 +137,7 @@ fn test_profile_creation_event() { start_cheat_caller_address(nft_contract_address, USER.try_into().unwrap()); let profile_address = profileDispatcher - .create_profile(nft_contract_address, registry_class_hash, account_class_hash, 2456, 2456); + .create_profile(nft_contract_address, registry_class_hash, account_class_hash, 2456); let token_id = karstNFTDispatcher.get_user_token_id(USER.try_into().unwrap()); diff --git a/tests/test_publication.cairo b/tests/test_publication.cairo index 0bd06c1..45b95ba 100644 --- a/tests/test_publication.cairo +++ b/tests/test_publication.cairo @@ -80,8 +80,7 @@ fn __setup__() -> ( nft_contract_address, (*registry_class_hash.class_hash).into(), (*account_class_hash.class_hash).into(), - 2478, - 2479 + 2478 ); let content_URI: ByteArray = "ipfs://helloworld"; let mut spy = spy_events(); @@ -100,8 +99,7 @@ fn __setup__() -> ( nft_contract_address, (*registry_class_hash.class_hash).into(), (*account_class_hash.class_hash).into(), - 2479, - 2482 + 2479 ); let content_URI: ByteArray = "ipfs://helloworld"; dispatcher @@ -120,8 +118,7 @@ fn __setup__() -> ( nft_contract_address, (*registry_class_hash.class_hash).into(), (*account_class_hash.class_hash).into(), - 2480, - 2481 + 2480 ); let content_URI: ByteArray = "ipfs://helloworld"; dispatcher From 8ffdecaa09af0a5af019e75e65312fb644adc0f7 Mon Sep 17 00:00:00 2001 From: mubarak23 Date: Mon, 21 Oct 2024 13:26:12 +0100 Subject: [PATCH 3/3] feat:use account v3 contract --- Scarb.toml | 2 +- tests/test_hub.cairo | 2 +- tests/test_profile.cairo | 2 +- tests/test_publication.cairo | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Scarb.toml b/Scarb.toml index 0f14bf3..9cd0427 100644 --- a/Scarb.toml +++ b/Scarb.toml @@ -23,5 +23,5 @@ url= "https://starknet-sepolia.public.blastapi.io" [[target.starknet-contract]] casm = true -build-external-contracts = ["token_bound_accounts::components::presets::account_preset::AccountPreset"] +build-external-contracts = ["token_bound_accounts::accountV3::accountV3::AccountV3"] allowed-libfuncs-list.name = "experimental" \ No newline at end of file diff --git a/tests/test_hub.cairo b/tests/test_hub.cairo index 9f046f5..258e42a 100644 --- a/tests/test_hub.cairo +++ b/tests/test_hub.cairo @@ -46,7 +46,7 @@ fn __setup__() -> (ContractAddress, ContractAddress, ContractAddress, ContractAd let registry_class_hash = declare("Registry").unwrap().contract_class(); // declare tokenbound account - let account_class_hash = declare("AccountPreset").unwrap().contract_class(); + let account_class_hash = declare("AccountV3").unwrap().contract_class(); // declare follownft let follow_nft_classhash = declare("Follow").unwrap().contract_class(); diff --git a/tests/test_profile.cairo b/tests/test_profile.cairo index 6db0d08..3ddcf10 100644 --- a/tests/test_profile.cairo +++ b/tests/test_profile.cairo @@ -32,7 +32,7 @@ fn __setup__() -> (ContractAddress, ContractAddress, felt252, felt252, ContractA let (registry_contract_address, _) = registry_class_hash.deploy(@array![]).unwrap_syscall(); // declare account - let account_class_hash = declare("AccountPreset").unwrap().contract_class(); + let account_class_hash = declare("AccountV3").unwrap().contract_class(); // declare follownft let follow_nft_classhash = declare("Follow").unwrap().contract_class(); diff --git a/tests/test_publication.cairo b/tests/test_publication.cairo index 45b95ba..7224b4e 100644 --- a/tests/test_publication.cairo +++ b/tests/test_publication.cairo @@ -65,7 +65,7 @@ fn __setup__() -> ( .unwrap_syscall(); // declare account - let account_class_hash = declare("AccountPreset").unwrap().contract_class(); + let account_class_hash = declare("AccountV3").unwrap().contract_class(); //declare collectnft let collect_nft_classhash = declare("CollectNFT").unwrap().contract_class();