---
# System prepended metadata

title: NFT treasury w/ChatGPT

---

# NFT treasury w/ChatGPT

create me code for a substrate pallet that mints RMRK NFTs when a proposal is approved through a referendum, these NFTs are held in a separate account which also connects into the referendum pallet

```
use frame_support::{decl_module, decl_storage, dispatch::DispatchResult};
use frame_system::{self as system, ensure_signed};
use sp_runtime::traits::StaticLookup;
use sp_std::vec::Vec;
use orml_nft::Nft;
use pallet_referendum::{self as referendum, *};

#[derive(Clone, Debug, Eq, PartialEq)]
pub struct RmrkNftData {
    pub name: Vec<u8>,
    pub symbol: Vec<u8>,
    pub properties: Vec<u8>,
}

pub trait Trait: system::Trait + referendum::Trait + orml_nft::Trait {
    type Event: From<Event<Self>> + Into<<Self as system::Trait>::Event>;
}

decl_storage! {
    trait Store for Module<T: Trait> as RmrkNftModule {
        pub RmrkNft get(fn rmrk_nft): map hasher(blake2_128_concat) T::Hash => Option<Nft<T::AccountId, T::Hash>>;
    }
}

decl_event!(
    pub enum Event<T>
    where
        AccountId = <T as system::Trait>::AccountId,
        Hash = <T as system::Trait>::Hash,
    {
        RmrkNftMinted(AccountId, Hash, RmrkNftData),
    }
);

decl_module! {
    pub struct Module<T: Trait> for enum Call where origin: T::Origin {
        fn mint_rmrk_nft(origin, proposal_id: ReferendumIndex, data: RmrkNftData) -> DispatchResult {
            let sender = ensure_signed(origin)?;

            // Verify that the proposal is approved
            let is_approved = Referendum::<T>::is_approved(proposal_id)?;
            ensure!(is_approved, "Referendum is not approved.");

            // Get the proposal hash
            let proposal_hash = <referendum::Module<T>>::proposal_hash(proposal_id);

            // Generate the RMRK NFT ID from the proposal hash
            let rmrk_nft_id = T::Hashing::hash_of(&proposal_hash);

            // Check if the RMRK NFT already exists
            ensure!(RmrkNft::<T>::get(&rmrk_nft_id).is_none(), "RMRK NFT already exists.");

            // Get the account to hold the RMRK NFT
            let account_id = Self::rmrk_nft_account();

            // Mint the RMRK NFT and transfer it to the holding account
            <orml_nft::Module<T>>::mint(&sender, account_id.clone(), rmrk_nft_id)?;
            <RmrkNft<T>>::insert(&rmrk_nft_id, Nft::<T::AccountId, T::Hash>::new(
                account_id.clone(), data.name, data.symbol, data.properties,
            ));

            // Emit an event for the RMRK NFT minting
            Self::deposit_event(Event::<T>::RmrkNftMinted(sender, rmrk_nft_id, data));

            Ok(())
        }
    }
}

impl<T: Trait> Module<T> {
    // This function returns the account that holds the RMRK NFTs
    fn rmrk_nft_account() -> T::AccountId {
        // You can customize this function to fit your needs
        T::Lookup::lookup("RMRK_NFT_ACCOUNT").unwrap_or_default()
    }
```
