github.com/cosmos/cosmos-sdk@v0.50.10/x/gov/client/cli/util.go (about) 1 package cli 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "os" 7 8 "github.com/spf13/cobra" 9 "github.com/spf13/pflag" 10 11 "github.com/cosmos/cosmos-sdk/client" 12 "github.com/cosmos/cosmos-sdk/codec" 13 sdk "github.com/cosmos/cosmos-sdk/types" 14 govutils "github.com/cosmos/cosmos-sdk/x/gov/client/utils" 15 govv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" 16 ) 17 18 type legacyProposal struct { 19 Title string 20 Description string 21 Type string 22 Deposit string 23 } 24 25 // validate the legacyProposal 26 func (p legacyProposal) validate() error { 27 if p.Type == "" { 28 return fmt.Errorf("proposal type is required") 29 } 30 31 if p.Title == "" { 32 return fmt.Errorf("proposal title is required") 33 } 34 35 if p.Description == "" { 36 return fmt.Errorf("proposal description is required") 37 } 38 return nil 39 } 40 41 // parseSubmitLegacyProposal reads and parses the legacy proposal. 42 func parseSubmitLegacyProposal(fs *pflag.FlagSet) (*legacyProposal, error) { 43 proposal := &legacyProposal{} 44 proposalFile, _ := fs.GetString(FlagProposal) 45 46 if proposalFile == "" { 47 proposalType, _ := fs.GetString(FlagProposalType) 48 proposal.Title, _ = fs.GetString(FlagTitle) 49 proposal.Description, _ = fs.GetString(FlagDescription) 50 proposal.Type = govutils.NormalizeProposalType(proposalType) 51 proposal.Deposit, _ = fs.GetString(FlagDeposit) 52 if err := proposal.validate(); err != nil { 53 return nil, err 54 } 55 56 return proposal, nil 57 } 58 59 for _, flag := range ProposalFlags { 60 if v, _ := fs.GetString(flag); v != "" { 61 return nil, fmt.Errorf("--%s flag provided alongside --proposal, which is a noop", flag) 62 } 63 } 64 65 contents, err := os.ReadFile(proposalFile) 66 if err != nil { 67 return nil, err 68 } 69 70 err = json.Unmarshal(contents, proposal) 71 if err != nil { 72 return nil, err 73 } 74 75 if err := proposal.validate(); err != nil { 76 return nil, err 77 } 78 79 return proposal, nil 80 } 81 82 // proposal defines the new Msg-based proposal. 83 type proposal struct { 84 // Msgs defines an array of sdk.Msgs proto-JSON-encoded as Anys. 85 Messages []json.RawMessage `json:"messages,omitempty"` 86 Metadata string `json:"metadata"` 87 Deposit string `json:"deposit"` 88 Title string `json:"title"` 89 Summary string `json:"summary"` 90 Expedited bool `json:"expedited"` 91 } 92 93 // parseSubmitProposal reads and parses the proposal. 94 func parseSubmitProposal(cdc codec.Codec, path string) (proposal, []sdk.Msg, sdk.Coins, error) { 95 var proposal proposal 96 97 contents, err := os.ReadFile(path) 98 if err != nil { 99 return proposal, nil, nil, err 100 } 101 102 err = json.Unmarshal(contents, &proposal) 103 if err != nil { 104 return proposal, nil, nil, err 105 } 106 107 msgs := make([]sdk.Msg, len(proposal.Messages)) 108 for i, anyJSON := range proposal.Messages { 109 var msg sdk.Msg 110 err := cdc.UnmarshalInterfaceJSON(anyJSON, &msg) 111 if err != nil { 112 return proposal, nil, nil, err 113 } 114 115 msgs[i] = msg 116 } 117 118 deposit, err := sdk.ParseCoinsNormalized(proposal.Deposit) 119 if err != nil { 120 return proposal, nil, nil, err 121 } 122 123 return proposal, msgs, deposit, nil 124 } 125 126 // AddGovPropFlagsToCmd adds flags for defining MsgSubmitProposal fields. 127 // 128 // See also ReadGovPropFlags. 129 func AddGovPropFlagsToCmd(cmd *cobra.Command) { 130 cmd.Flags().String(FlagDeposit, "", "The deposit to include with the governance proposal") 131 cmd.Flags().String(FlagMetadata, "", "The metadata to include with the governance proposal") 132 cmd.Flags().String(FlagTitle, "", "The title to put on the governance proposal") 133 cmd.Flags().String(FlagSummary, "", "The summary to include with the governance proposal") 134 } 135 136 // ReadGovPropFlags parses a MsgSubmitProposal from the provided context and flags. 137 // Setting the messages is up to the caller. 138 // 139 // See also AddGovPropFlagsToCmd. 140 func ReadGovPropFlags(clientCtx client.Context, flagSet *pflag.FlagSet) (*govv1.MsgSubmitProposal, error) { 141 rv := &govv1.MsgSubmitProposal{} 142 143 deposit, err := flagSet.GetString(FlagDeposit) 144 if err != nil { 145 return nil, fmt.Errorf("could not read deposit: %w", err) 146 } 147 if len(deposit) > 0 { 148 rv.InitialDeposit, err = sdk.ParseCoinsNormalized(deposit) 149 if err != nil { 150 return nil, fmt.Errorf("invalid deposit: %w", err) 151 } 152 } 153 154 rv.Metadata, err = flagSet.GetString(FlagMetadata) 155 if err != nil { 156 return nil, fmt.Errorf("could not read metadata: %w", err) 157 } 158 159 rv.Title, err = flagSet.GetString(FlagTitle) 160 if err != nil { 161 return nil, fmt.Errorf("could not read title: %w", err) 162 } 163 164 rv.Summary, err = flagSet.GetString(FlagSummary) 165 if err != nil { 166 return nil, fmt.Errorf("could not read summary: %w", err) 167 } 168 169 rv.Proposer = clientCtx.GetFromAddress().String() 170 171 return rv, nil 172 }