diff --git a/src/proposals.cairo b/src/proposals.cairo
index beabcd9a..7f3c294c 100644
--- a/src/proposals.cairo
+++ b/src/proposals.cairo
@@ -1,6 +1,6 @@
 // Proposals component. Does not depend on anything. Holds governance token address.
 
-use konoha::types::{ContractType, PropDetails, VoteStatus};
+use konoha::types::{ContractType, PropDetails, VoteStatus, CustomProposalConfig};
 use starknet::ContractAddress;
 
 #[starknet::interface]
@@ -19,6 +19,7 @@ trait IProposals<TContractState> {
     fn submit_custom_proposal(
         ref self: TContractState, custom_proposal_type: u32, calldata: Span<felt252>
     ) -> u32;
+    fn get_custom_proposal_type(self: @TContractState, i: u32) -> CustomProposalConfig;
 }
 
 #[starknet::component]
@@ -56,6 +57,7 @@ mod proposals {
     use konoha::types::ContractType;
     use konoha::types::PropDetails;
     use konoha::types::VoteStatus;
+    use konoha::types::CustomProposalConfig;
     use konoha::traits::IERC20Dispatcher;
     use konoha::traits::IERC20DispatcherTrait;
     use konoha::traits::get_governance_token_address_self;
@@ -241,6 +243,26 @@ mod proposals {
             let res: u256 = (caller_balance * constants::NEW_PROPOSAL_QUORUM).into();
             assert(total_supply < res, 'not enough tokens to submit');
         }
+
+        fn _find_free_custom_proposal_type(self: @ComponentState<TContractState>) -> u32 {
+            let mut i = 0;
+            let mut res = self.custom_proposal_type.read(i);
+            while (res.target.is_non_zero()) {
+                i += 1;
+                res = self.custom_proposal_type.read(i);
+            };
+            i
+        }
+
+        fn add_custom_proposal_config(
+            ref self: ComponentState<TContractState>, config: CustomProposalConfig
+        ) -> u32 {
+            let idx = self._find_free_custom_proposal_type();
+            assert(config.target.is_non_zero(), 'target must be nonzero');
+            assert(config.selector.is_non_zero(), 'selector must be nonzero');
+            self.custom_proposal_type.write(idx, config);
+            idx
+        }
     }
 
     #[embeddable_as(ProposalsImpl)]
@@ -493,5 +515,11 @@ mod proposals {
                 return constants::MINUS_ONE; // yay_tally < nay_tally
             }
         }
+
+        fn get_custom_proposal_type(
+            self: @ComponentState<TContractState>, i: u32
+        ) -> CustomProposalConfig {
+            self.custom_proposal_type.read(i)
+        }
     }
 }
diff --git a/src/testing/setup.cairo b/src/testing/setup.cairo
index b880882d..7e8507b7 100644
--- a/src/testing/setup.cairo
+++ b/src/testing/setup.cairo
@@ -9,13 +9,13 @@ use snforge_std::{
 };
 
 
-use governance::contract::IGovernanceDispatcher;
-use governance::contract::IGovernanceDispatcherTrait;
-use governance::proposals::IProposalsDispatcher;
-use governance::proposals::IProposalsDispatcherTrait;
-use governance::upgrades::IUpgradesDispatcher;
-use governance::upgrades::IUpgradesDispatcherTrait;
-use governance::constants;
+use konoha::contract::IGovernanceDispatcher;
+use konoha::contract::IGovernanceDispatcherTrait;
+use konoha::proposals::IProposalsDispatcher;
+use konoha::proposals::IProposalsDispatcherTrait;
+use konoha::upgrades::IUpgradesDispatcher;
+use konoha::upgrades::IUpgradesDispatcherTrait;
+use konoha::constants;
 use openzeppelin::token::erc20::interface::IERC20;
 use starknet::get_block_timestamp;
 
diff --git a/src/upgrades.cairo b/src/upgrades.cairo
index 23311814..5e33f541 100644
--- a/src/upgrades.cairo
+++ b/src/upgrades.cairo
@@ -19,7 +19,7 @@ mod upgrades {
     use starknet::ContractAddress;
     use starknet::class_hash;
 
-    use konoha::types::PropDetails;
+    use konoha::types::{CustomProposalConfig, PropDetails};
     use konoha::contract::Governance;
     use konoha::contract::Governance::ContractState;