diff --git a/assets/generated/BanegasFarm-ProjectCard-generated.svg b/assets/generated/sft_projects/BanegasFarm-ProjectCard-generated.svg similarity index 100% rename from assets/generated/BanegasFarm-ProjectCard-generated.svg rename to assets/generated/sft_projects/BanegasFarm-ProjectCard-generated.svg diff --git a/assets/generated/BanegasFarm-Vintage2024-generated.svg b/assets/generated/sft_projects/BanegasFarm-Vintage2024-generated.svg similarity index 100% rename from assets/generated/BanegasFarm-Vintage2024-generated.svg rename to assets/generated/sft_projects/BanegasFarm-Vintage2024-generated.svg diff --git a/assets/generated/LasDelicias-ProjectCard-generated.svg b/assets/generated/sft_projects/LasDelicias-ProjectCard-generated.svg similarity index 100% rename from assets/generated/LasDelicias-ProjectCard-generated.svg rename to assets/generated/sft_projects/LasDelicias-ProjectCard-generated.svg diff --git a/assets/generated/Manjarisoa-ProjectCard-generated.svg b/assets/generated/sft_projects/Manjarisoa-ProjectCard-generated.svg similarity index 100% rename from assets/generated/Manjarisoa-ProjectCard-generated.svg rename to assets/generated/sft_projects/Manjarisoa-ProjectCard-generated.svg diff --git a/assets/generated/example_slot_uri.json b/assets/generated/sft_projects/example_slot_uri.json similarity index 100% rename from assets/generated/example_slot_uri.json rename to assets/generated/sft_projects/example_slot_uri.json diff --git a/assets/generated/example_token_uri.json b/assets/generated/sft_projects/example_token_uri.json similarity index 100% rename from assets/generated/example_token_uri.json rename to assets/generated/sft_projects/example_token_uri.json diff --git a/assets/generated/vintages/BanegasFarm.svg b/assets/generated/vintages/BanegasFarm.svg new file mode 100644 index 0000000..2848ee3 --- /dev/null +++ b/assets/generated/vintages/BanegasFarm.svg @@ -0,0 +1 @@ +Vintage2023Certified byERSSupply133ktStatusAuditedLiveBanegas FarmBased in Costa RicaBy Corcovado Foundation \ No newline at end of file diff --git a/assets/generated/vintages/Karathuru.svg b/assets/generated/vintages/Karathuru.svg new file mode 100644 index 0000000..ffc1eaf --- /dev/null +++ b/assets/generated/vintages/Karathuru.svg @@ -0,0 +1 @@ +Vintage2023Certified byVerraSupply133ktStatusAuditedLiveKarathuruBased in MyanmarBy Wordview Intl Foundation \ No newline at end of file diff --git a/assets/generated/vintages/LasDelicias.svg b/assets/generated/vintages/LasDelicias.svg new file mode 100644 index 0000000..9942398 --- /dev/null +++ b/assets/generated/vintages/LasDelicias.svg @@ -0,0 +1 @@ +Vintage2023Certified byWildsenseSupply133ktStatusAuditedLiveLas DeliciasBased in PanamaBy Fundacion Naturaleza Panama \ No newline at end of file diff --git a/assets/generated/vintages/Manjarisoa.svg b/assets/generated/vintages/Manjarisoa.svg new file mode 100644 index 0000000..bc3e75a --- /dev/null +++ b/assets/generated/vintages/Manjarisoa.svg @@ -0,0 +1 @@ +Vintage2023Certified byWildsenseSupply133ktStatusAuditedPausedManjarisoaBased in MadagascarBy Forest Calling Action \ No newline at end of file diff --git a/src/lib.cairo b/src/lib.cairo index 6aaef99..a584d8f 100644 --- a/src/lib.cairo +++ b/src/lib.cairo @@ -119,6 +119,21 @@ mod metadata { mod static; } + mod las_delicias { + mod contract; + mod static; + } + + mod karathuru { + mod contract; + mod static; + } + + mod manjarisoa { + mod contract; + mod static; + } + mod models; } } diff --git a/src/metadata/vintages/karathuru/contract.cairo b/src/metadata/vintages/karathuru/contract.cairo new file mode 100644 index 0000000..3722948 --- /dev/null +++ b/src/metadata/vintages/karathuru/contract.cairo @@ -0,0 +1,38 @@ +#[starknet::interface] +trait IMetadataDescriptor { + fn construct_uri(self: @TContractState, token_id: u256) -> Span; +} + +#[starknet::contract] +mod KarathuruCPV3Uri { + use starknet::{get_contract_address, ContractAddress}; + + use metadata::metadata::vintages::template::{svg, storage, data as template_data}; + use metadata::metadata::vintages::template::json::generate_json; + use metadata::metadata::vintages::karathuru::static::get_static_data; + + use openzeppelin::introspection::interface::{ISRC5Dispatcher, ISRC5DispatcherTrait, ISRC5_ID}; + + #[storage] + struct Storage {} + + #[external(v0)] + impl CPV3Metadata of super::IMetadataDescriptor { + fn construct_uri(self: @ContractState, token_id: u256) -> Span { + // [Check] calling contract is compatible + let contract = get_contract_address(); + self.compatible(contract); + let static_data = get_static_data(); + generate_json(contract, token_id, static_data) + } + } + #[generate_trait] + impl CPV3MetadataInternal of IInternal { + fn compatible(self: @ContractState, contract_address: ContractAddress) { + let src5 = ISRC5Dispatcher { contract_address }; + let is_SRC5 = src5.supports_interface(ISRC5_ID); + assert(src5.supports_interface(ISRC5_ID), 'ISRC5 not supported'); + } + } +} + diff --git a/src/metadata/vintages/karathuru/static.cairo b/src/metadata/vintages/karathuru/static.cairo new file mode 100644 index 0000000..d946eef --- /dev/null +++ b/src/metadata/vintages/karathuru/static.cairo @@ -0,0 +1,77 @@ +use metadata::metadata::common::models::{ProjectStaticData, String, Shortstring}; + +const NAME: Shortstring = 'Karathuru'; +const DEVELOPER: Shortstring = 'Wordview Intl Foundation'; +const CERTIFIER: Shortstring = 'Verra'; +const AREA: u32 = 86; +const COUNTRY: Shortstring = 'Myanmar'; +const END_YEAR: u32 = 2047; // get from project +const END_MONTH: u8 = 12; // get from project +const DURATION_IN_YEARS: u32 = consteval_int!(2047 - 2024); // get from project +const TOTAL_CU: u64 = 70589; // get from project +const PROJECTED_CU: u64 = 70589; // get from project +const COLOR: Shortstring = 'Blue'; +const TYPE: Shortstring = 'ARR'; +const CATEGORY: Shortstring = 'Mangrove'; +const SOURCE: Shortstring = 'Carbonable'; +const PAUSED: u8 = 0; + +#[inline(always)] +fn get_sdgs_() -> Span { + array![4, 5, 8, 13, 14, 15].span() +} + +#[inline(always)] +fn get_static_data() -> ProjectStaticData { + ProjectStaticData { + name: array![NAME].span(), + description: get_description_(), + developer: array![DEVELOPER].span(), + certifier: array![CERTIFIER].span(), + area: AREA, + country: array![COUNTRY].span(), + end_year: END_YEAR, + end_month: END_MONTH, + duration_in_years: DURATION_IN_YEARS, + total_cu: TOTAL_CU, + projected_cu: PROJECTED_CU, + color: array![COLOR].span(), + type_: array![TYPE].span(), + category: array![CATEGORY].span(), + source: array![SOURCE].span(), + sdgs: get_sdgs_(), + background_component: 'bg.Karathuru.jpg.b64', + external_url: get_external_url_(), + paused: PAUSED, + } +} + +#[inline(always)] +fn get_external_url_() -> Span { + array!['https://app.carbonable.io/', 'launchpad/', 'mangroves-regeneration-', 'karathuru'] + .span() +} + +#[inline(always)] +fn get_description_() -> Span { + let mut data = Default::default(); + add_description_(ref data); + data.span() +} + +#[inline(always)] +fn add_description_(ref data: Array) { + data.append('The project involves the'); + data.append(' regeneration of 228 ha in 2023'); + data.append(' with the planting of 570,000'); + data.append(' trees (2,500 per ha), and the'); + data.append(' restoration of a carbon sink t'); + data.append('hat will result in a forecasted'); + data.append(' amount of 374,285 certified'); + data.append(' carbon units amongst which'); + data.append(' 187,142 Carbon Units will be'); + data.append(' reserved for investors and the'); + data.append(' other half to local'); + data.append(' communities.'); +} + diff --git a/src/metadata/vintages/las_delicias/contract.cairo b/src/metadata/vintages/las_delicias/contract.cairo new file mode 100644 index 0000000..1fbc486 --- /dev/null +++ b/src/metadata/vintages/las_delicias/contract.cairo @@ -0,0 +1,40 @@ +#[starknet::interface] +trait IMetadataDescriptor { + fn construct_uri(self: @TContractState, token_id: u256) -> Span; +} + +#[starknet::contract] +mod LasDeliciasCPV3Uri { + use starknet::{get_contract_address, ContractAddress}; + + use metadata::metadata::vintages::template::{svg, storage, data as template_data}; + use metadata::metadata::vintages::template::json::generate_json; + use metadata::metadata::vintages::las_delicias::static::get_static_data; + + use debug::PrintTrait; + + use openzeppelin::introspection::interface::{ISRC5Dispatcher, ISRC5DispatcherTrait, ISRC5_ID}; + + #[storage] + struct Storage {} + + #[external(v0)] + impl CPV3Metadata of super::IMetadataDescriptor { + fn construct_uri(self: @ContractState, token_id: u256) -> Span { + // [Check] calling contract is compatible + let contract = get_contract_address(); + self.compatible(contract); + let static_data = get_static_data(); + generate_json(contract, token_id, static_data) + } + } + #[generate_trait] + impl CPV3MetadataInternal of IInternal { + fn compatible(self: @ContractState, contract_address: ContractAddress) { + let src5 = ISRC5Dispatcher { contract_address }; + let is_SRC5 = src5.supports_interface(ISRC5_ID); + assert(src5.supports_interface(ISRC5_ID), 'ISRC5 not supported'); + } + } +} + diff --git a/src/metadata/vintages/las_delicias/static.cairo b/src/metadata/vintages/las_delicias/static.cairo new file mode 100644 index 0000000..927b9eb --- /dev/null +++ b/src/metadata/vintages/las_delicias/static.cairo @@ -0,0 +1,78 @@ +use metadata::metadata::common::models::{ProjectStaticData, String, Shortstring}; + +const NAME: Shortstring = 'Las Delicias'; +const DEVELOPER: Shortstring = 'Fundacion Naturaleza Panama'; +const CERTIFIER: Shortstring = 'Wildsense'; +const AREA: u32 = 18; +const COUNTRY: Shortstring = 'Panama'; +const END_YEAR: u32 = 2042; // get from project +const END_MONTH: u8 = 12; // get from project +const DURATION_IN_YEARS: u32 = consteval_int!(2042 - 2022); // get from project +const TOTAL_CU: u64 = 3603; // get from project +const PROJECTED_CU: u64 = 3603; // get from project +const COLOR: Shortstring = 'Blue'; +const TYPE: Shortstring = 'ARR'; +const CATEGORY: Shortstring = 'Mangrove'; +const SOURCE: Shortstring = 'Carbonable'; +const PAUSED: u8 = 0; + +#[inline(always)] +fn get_sdgs_() -> Span { + array![8, 13, 14, 15].span() +} + +#[inline(always)] +fn get_static_data() -> ProjectStaticData { + ProjectStaticData { + name: array![NAME].span(), + description: get_description_(), + developer: array![DEVELOPER].span(), + certifier: array![CERTIFIER].span(), + area: AREA, + country: array![COUNTRY].span(), + end_year: END_YEAR, + end_month: END_MONTH, + duration_in_years: DURATION_IN_YEARS, + total_cu: TOTAL_CU, + projected_cu: PROJECTED_CU, + color: array![COLOR].span(), + type_: array![TYPE].span(), + category: array![CATEGORY].span(), + source: array![SOURCE].span(), + sdgs: get_sdgs_(), + background_component: 'bg.LasDelicias.jpg.b64', + external_url: get_external_url_(), + paused: PAUSED, + } +} + +#[inline(always)] +fn get_external_url_() -> Span { + array![ + 'https://app.carbonable.io/', 'launchpad/', 'mangroves-regeneration-', 'las-delicias-panama' + ] + .span() +} + +#[inline(always)] +fn get_description_() -> Span { + let mut data = Default::default(); + add_description_(ref data); + data.span() +} + +#[inline(always)] +fn add_description_(ref data: Array) { + data.append('Carbonable\'s Las Delicias NFTs'); + data.append(': Dive into Nature\'s VIP Club!'); + data.append(' Unlock a world of green and bl'); + data.append('ue with Panama\'s mangrove rest'); + data.append('orers! By securing an NFT, you'); + data.append('\'re not only backing an eco-mi'); + data.append('ssion, but you\'re also claimin'); + data.append('g prime carbon credits. Stay ah'); + data.append('ead, make waves, and grab yours'); + data.append(' now. Nature\'s red carpet is r'); + data.append('olling out!'); +} + diff --git a/src/metadata/vintages/manjarisoa/contract.cairo b/src/metadata/vintages/manjarisoa/contract.cairo new file mode 100644 index 0000000..c973c01 --- /dev/null +++ b/src/metadata/vintages/manjarisoa/contract.cairo @@ -0,0 +1,40 @@ +#[starknet::interface] +trait IMetadataDescriptor { + fn construct_uri(self: @TContractState, token_id: u256) -> Span; +} + +#[starknet::contract] +mod ManjarisoaCPV3Uri { + use starknet::{get_contract_address, ContractAddress}; + + use metadata::metadata::vintages::template::{svg, storage, data as template_data}; + use metadata::metadata::vintages::template::json::generate_json; + use metadata::metadata::vintages::manjarisoa::static::get_static_data; + + use debug::PrintTrait; + + use openzeppelin::introspection::interface::{ISRC5Dispatcher, ISRC5DispatcherTrait, ISRC5_ID}; + + #[storage] + struct Storage {} + + #[external(v0)] + impl CPV3Metadata of super::IMetadataDescriptor { + fn construct_uri(self: @ContractState, token_id: u256) -> Span { + // [Check] calling contract is compatible + let contract = get_contract_address(); + self.compatible(contract); + let static_data = get_static_data(); + generate_json(contract, token_id, static_data) + } + } + #[generate_trait] + impl CPV3MetadataInternal of IInternal { + fn compatible(self: @ContractState, contract_address: ContractAddress) { + let src5 = ISRC5Dispatcher { contract_address }; + let is_SRC5 = src5.supports_interface(ISRC5_ID); + assert(src5.supports_interface(ISRC5_ID), 'ISRC5 not supported'); + } + } +} + diff --git a/src/metadata/vintages/manjarisoa/static.cairo b/src/metadata/vintages/manjarisoa/static.cairo new file mode 100644 index 0000000..e7e5526 --- /dev/null +++ b/src/metadata/vintages/manjarisoa/static.cairo @@ -0,0 +1,75 @@ +use metadata::metadata::common::models::{ProjectStaticData, String, Shortstring}; + +const NAME: Shortstring = 'Manjarisoa'; +const DEVELOPER: Shortstring = 'Forest Calling Action'; +const CERTIFIER: Shortstring = 'Wildsense'; +const AREA: u32 = 20; +const COUNTRY: Shortstring = 'Madagascar'; +const END_YEAR: u32 = 2043; // get from project +const END_MONTH: u8 = 12; // get from project +const DURATION_IN_YEARS: u32 = consteval_int!(2043 - 2022); // get from project +const TOTAL_CU: u64 = 8000; // get from project +const PROJECTED_CU: u64 = 8000; // get from project +const COLOR: Shortstring = 'Green'; +const TYPE: Shortstring = 'ARR'; +const CATEGORY: Shortstring = 'Forest'; +const SOURCE: Shortstring = 'Carbonable'; +const PAUSED: u8 = 1; + +#[inline(always)] +fn get_sdgs_() -> Span { + array![8, 13, 15].span() +} + +#[inline(always)] +fn get_static_data() -> ProjectStaticData { + ProjectStaticData { + name: array![NAME].span(), + description: get_description_(), + developer: array![DEVELOPER].span(), + certifier: array![CERTIFIER].span(), + area: AREA, + country: array![COUNTRY].span(), + end_year: END_YEAR, + end_month: END_MONTH, + duration_in_years: DURATION_IN_YEARS, + total_cu: TOTAL_CU, + projected_cu: PROJECTED_CU, + color: array![COLOR].span(), + type_: array![TYPE].span(), + category: array![CATEGORY].span(), + source: array![SOURCE].span(), + sdgs: get_sdgs_(), + background_component: 'bg.Manjarisoa.jpg.b64', + external_url: get_external_url_(), + paused: PAUSED, + } +} + +#[inline(always)] +fn get_external_url_() -> Span { + array!['https://app.carbonable.io/', 'launchpad/', 'forest-regeneration-', 'madagascar'].span() +} + +#[inline(always)] +fn get_description_() -> Span { + let mut data = Default::default(); + add_description_(ref data); + data.span() +} + +#[inline(always)] +fn add_description_(ref data: Array) { + data.append('Carbonable\'s Manjarisoa NFTs:'); + data.append(' Join the forest-saving brigade'); + data.append(' in Madagascar! Step into Madag'); + data.append('ascar\'s vibrant forest symphon'); + data.append('y! Your NFT not only champions'); + data.append(' a biodiversity-rich mission bu'); + data.append('t also earns you top-tier carbo'); + data.append('n credits. Get ready for nature'); + data.append('\'s grand performance, starring'); + data.append(' lemurs, birds, and frogs. Natu'); + data.append('re\'s encore is calling-be there'); + data.append('!'); +} diff --git a/src/metadata/vintages/template/storage.cairo b/src/metadata/vintages/template/storage.cairo index 44f121a..b95778d 100644 --- a/src/metadata/vintages/template/storage.cairo +++ b/src/metadata/vintages/template/storage.cairo @@ -22,7 +22,7 @@ fn fetch_data(contract_address: ContractAddress, token_id: u256) -> StorageData let mut start_year: u32 = 1970; let mut end_year: u32 = 2999; if num != 0 && token_id <= num.into() { - vintage = *all_vintages.at(token_id.try_into().unwrap()); + vintage = *all_vintages.at((token_id - 1).try_into().unwrap()); start_year = *all_vintages.at(0).year; end_year = *all_vintages.at(all_vintages.len() - 1).year; } diff --git a/src/tests/test_cpv3_metadata.cairo b/src/tests/test_cpv3_metadata.cairo index 437ea7f..7e2a239 100644 --- a/src/tests/test_cpv3_metadata.cairo +++ b/src/tests/test_cpv3_metadata.cairo @@ -7,6 +7,9 @@ use starknet::syscalls::deploy_syscall; use test::test_utils::assert_eq; use metadata::metadata::vintages::banegas_farm::contract::BanegasCPV3Uri; +use metadata::metadata::vintages::karathuru::contract::KarathuruCPV3Uri; +use metadata::metadata::vintages::las_delicias::contract::LasDeliciasCPV3Uri; +use metadata::metadata::vintages::manjarisoa::contract::ManjarisoaCPV3Uri; use metadata::tests::mocks::cpv3_project::CPV3ProjectMock; use metadata::interfaces::slot_descriptor::{ IUriDescriptorLibraryDispatcher, IUriDescriptorDispatcherTrait @@ -132,7 +135,7 @@ fn test_construct_uri() { let token_id = 1_u256; let metadata = IUriDescriptorLibraryDispatcher { - class_hash: as_class(BanegasCPV3Uri::TEST_CLASS_HASH) + class_hash: as_class(KarathuruCPV3Uri::TEST_CLASS_HASH) }; set_contract_address(project_address);