@@ -11,6 +11,7 @@ use crate::{
1111 signatory_record:: get_signatory_record_address,
1212 single_signer_instruction:: InstructionData ,
1313 token_owner_record:: get_token_owner_record_address,
14+ vote_record:: get_vote_record_address,
1415 } ,
1516 tools:: bpf_loader_upgradeable:: get_program_data_address,
1617} ;
@@ -178,7 +179,6 @@ pub enum GovernanceInstruction {
178179 /// 2. `[signer]` Governance Authority (Token Owner or Governance Delegate)
179180 /// 3. `[writable]` Signatory Record Account
180181 /// 4. `[writable]` Beneficiary Account which would receive lamports from the disposed Signatory Record Account
181- /// 5. `[]` Clock sysvar
182182 RemoveSignatory {
183183 #[ allow( dead_code) ]
184184 /// Signatory to remove from the Proposal
@@ -222,10 +222,11 @@ pub enum GovernanceInstruction {
222222 hold_up_time : u64 ,
223223 } ,
224224
225- /// Cancels Proposal and moves it into Canceled
225+ /// Cancels Proposal by changing its state to Canceled
226226 ///
227227 /// 0. `[writable]` Proposal account
228- /// 1. `[signer]` Governance Authority (Token Owner or Governance Delegate)
228+ /// 1. `[]` Token Owner Record account. PDA seeds: ['governance',realm, governing_token_mint, governing_token_owner]
229+ /// 2 `[signer]` Governance Authority (Token Owner or Governance Delegate)
229230 CancelProposal ,
230231
231232 /// Signs off Proposal indicating the Signatory approves the Proposal
@@ -241,26 +242,45 @@ pub enum GovernanceInstruction {
241242 /// By doing so you indicate you approve or disapprove of running the Proposal set of instructions
242243 /// If you tip the consensus then the instructions can begin to be run after their hold up time
243244 ///
244- /// 0. `[writable]` Proposal account
245- /// 1. `[writable]` Token Owner Record account. PDA seeds: ['governance',realm, governing_token_mint, governing_token_owner]
246- /// 2. `[writable]` Proposal Vote Record account. PDA seeds: ['governance',proposal,governing_token_owner]
247- /// 3. `[signer]` Governance Authority account
248- /// 4. `[]` Governance account
249- Vote {
245+ /// 0. `[]` Governance account
246+ /// 1. `[writable]` Proposal account
247+ /// 2. `[writable]` Token Owner Record account. PDA seeds: ['governance',realm, governing_token_mint, governing_token_owner]
248+ /// 3. `[signer]` Governance Authority (Token Owner or Governance Delegate)
249+ /// 4. `[writable]` Proposal VoteRecord account. PDA seeds: ['governance',proposal,governing_token_owner_record]
250+ /// 5. `[]` Governing Token Mint
251+ /// 6. `[signer]` Payer
252+ /// 7. `[]` System program
253+ /// 8. `[]` Rent sysvar
254+ /// 9. `[]` Clock sysvar
255+ CastVote {
250256 #[ allow( dead_code) ]
251257 /// Yes/No vote
252258 vote : Vote ,
253259 } ,
254260
261+ /// Finalizes vote in case the Vote was not automatically tipped within max_voting_time period
262+ ///
263+ /// 0. `[]` Governance account
264+ /// 1. `[writable]` Proposal account
265+ /// 2. `[]` Governing Token Mint
266+ /// 3. `[]` Clock sysvar
267+ FinalizeVote { } ,
268+
255269 /// Relinquish Vote removes voter weight from a Proposal and removes it from voter's active votes
256270 /// If the Proposal is still being voted on then the voter's weight won't count towards the vote outcome
257271 /// If the Proposal is already in decided state then the instruction has no impact on the Proposal
258272 /// and only allows voters to prune their outstanding votes in case they wanted to withdraw Governing tokens from the Realm
259273 ///
260- /// 0. `[writable]` Proposal account
261- /// 1. `[writable]` Token Owner Record account. PDA seeds: ['governance',realm, governing_token_mint, governing_token_owner]
262- /// 2. `[writable]` Proposal Vote Record account. PDA seeds: ['governance',proposal,governing_token_owner]
263- /// 3. `[signer]` Governance Authority account
274+ /// 0. `[]` Governance account
275+ /// 1. `[writable]` Proposal account
276+ /// 2. `[writable]` TokenOwnerRecord account. PDA seeds: ['governance',realm, governing_token_mint, governing_token_owner]
277+ /// 3. `[writable]` Proposal VoteRecord account. PDA seeds: ['governance',proposal,governing_token_owner_record]
278+ /// 4. `[]` Governing Token Mint
279+
280+ /// 5. `[signer]` Optional Governance Authority (Token Owner or Governance Delegate)
281+ /// It's required only when Proposal is still being voted on
282+ /// 6. `[writable]` Optional Beneficiary account which would receive lamports when VoteRecord Account is disposed
283+ /// It's required only when Proposal is still being voted on
264284 RelinquishVote ,
265285
266286 /// Executes an instruction in the Proposal
@@ -494,7 +514,7 @@ pub fn create_proposal(
494514 name : String ,
495515 description_link : String ,
496516 governing_token_mint : & Pubkey ,
497- proposal_index : u16 ,
517+ proposal_index : u32 ,
498518) -> Instruction {
499519 let proposal_address = get_proposal_address (
500520 governance,
@@ -578,7 +598,6 @@ pub fn remove_signatory(
578598 AccountMeta :: new_readonly( * governance_authority, true ) ,
579599 AccountMeta :: new( signatory_record_address, false ) ,
580600 AccountMeta :: new( * beneficiary, false ) ,
581- AccountMeta :: new_readonly( sysvar:: clock:: id( ) , false ) ,
582601 ] ;
583602
584603 let instruction = GovernanceInstruction :: RemoveSignatory {
@@ -615,3 +634,118 @@ pub fn sign_off_proposal(
615634 data : instruction. try_to_vec ( ) . unwrap ( ) ,
616635 }
617636}
637+
638+ /// Creates CastVote instruction
639+ pub fn cast_vote (
640+ // Accounts
641+ governance : & Pubkey ,
642+ proposal : & Pubkey ,
643+ token_owner_record : & Pubkey ,
644+ governance_authority : & Pubkey ,
645+ governing_token_mint : & Pubkey ,
646+ payer : & Pubkey ,
647+ // Args
648+ vote : Vote ,
649+ ) -> Instruction {
650+ let vote_record_address = get_vote_record_address ( & proposal, & token_owner_record) ;
651+
652+ let accounts = vec ! [
653+ AccountMeta :: new_readonly( * governance, false ) ,
654+ AccountMeta :: new( * proposal, false ) ,
655+ AccountMeta :: new( * token_owner_record, false ) ,
656+ AccountMeta :: new_readonly( * governance_authority, true ) ,
657+ AccountMeta :: new( vote_record_address, false ) ,
658+ AccountMeta :: new_readonly( * governing_token_mint, false ) ,
659+ AccountMeta :: new_readonly( * payer, true ) ,
660+ AccountMeta :: new_readonly( system_program:: id( ) , false ) ,
661+ AccountMeta :: new_readonly( sysvar:: rent:: id( ) , false ) ,
662+ AccountMeta :: new_readonly( sysvar:: clock:: id( ) , false ) ,
663+ ] ;
664+
665+ let instruction = GovernanceInstruction :: CastVote { vote } ;
666+
667+ Instruction {
668+ program_id : id ( ) ,
669+ accounts,
670+ data : instruction. try_to_vec ( ) . unwrap ( ) ,
671+ }
672+ }
673+
674+ /// Creates FinalizeVote instruction
675+ pub fn finalize_vote (
676+ // Accounts
677+ governance : & Pubkey ,
678+ proposal : & Pubkey ,
679+ governing_token_mint : & Pubkey ,
680+ ) -> Instruction {
681+ let accounts = vec ! [
682+ AccountMeta :: new_readonly( * governance, false ) ,
683+ AccountMeta :: new( * proposal, false ) ,
684+ AccountMeta :: new_readonly( * governing_token_mint, false ) ,
685+ AccountMeta :: new_readonly( sysvar:: clock:: id( ) , false ) ,
686+ ] ;
687+
688+ let instruction = GovernanceInstruction :: FinalizeVote { } ;
689+
690+ Instruction {
691+ program_id : id ( ) ,
692+ accounts,
693+ data : instruction. try_to_vec ( ) . unwrap ( ) ,
694+ }
695+ }
696+
697+ /// Creates RelinquishVote instruction
698+ pub fn relinquish_vote (
699+ // Accounts
700+ governance : & Pubkey ,
701+ proposal : & Pubkey ,
702+ token_owner_record : & Pubkey ,
703+ governing_token_mint : & Pubkey ,
704+ governance_authority : Option < Pubkey > ,
705+ beneficiary : Option < Pubkey > ,
706+ ) -> Instruction {
707+ let vote_record_address = get_vote_record_address ( & proposal, & token_owner_record) ;
708+
709+ let mut accounts = vec ! [
710+ AccountMeta :: new_readonly( * governance, false ) ,
711+ AccountMeta :: new( * proposal, false ) ,
712+ AccountMeta :: new( * token_owner_record, false ) ,
713+ AccountMeta :: new( vote_record_address, false ) ,
714+ AccountMeta :: new_readonly( * governing_token_mint, false ) ,
715+ ] ;
716+
717+ if let Some ( governance_authority) = governance_authority {
718+ accounts. push ( AccountMeta :: new_readonly ( governance_authority, true ) ) ;
719+ accounts. push ( AccountMeta :: new ( beneficiary. unwrap ( ) , false ) ) ;
720+ }
721+
722+ let instruction = GovernanceInstruction :: RelinquishVote { } ;
723+
724+ Instruction {
725+ program_id : id ( ) ,
726+ accounts,
727+ data : instruction. try_to_vec ( ) . unwrap ( ) ,
728+ }
729+ }
730+
731+ /// Creates CancelProposal instruction
732+ pub fn cancel_proposal (
733+ // Accounts
734+ proposal : & Pubkey ,
735+ token_owner_record : & Pubkey ,
736+ governance_authority : & Pubkey ,
737+ ) -> Instruction {
738+ let accounts = vec ! [
739+ AccountMeta :: new( * proposal, false ) ,
740+ AccountMeta :: new_readonly( * token_owner_record, false ) ,
741+ AccountMeta :: new_readonly( * governance_authority, true ) ,
742+ ] ;
743+
744+ let instruction = GovernanceInstruction :: CancelProposal { } ;
745+
746+ Instruction {
747+ program_id : id ( ) ,
748+ accounts,
749+ data : instruction. try_to_vec ( ) . unwrap ( ) ,
750+ }
751+ }
0 commit comments