package cli

import (
	"errors"
	"fmt"

	"github.com/spf13/cobra"
	"github.com/spf13/pflag"

	"github.com/cosmos/cosmos-sdk/client"
	"github.com/cosmos/cosmos-sdk/client/flags"

	"github.com/provenance-io/provenance/x/exchange"
)

// SetupCmdTxCreateAsk adds all the flags needed for MakeMsgCreateAsk.
func SetupCmdTxCreateAsk(cmd *cobra.Command) {
	cmd.Flags().String(FlagSeller, "", "The seller (defaults to --from account)")
	cmd.Flags().Uint32(FlagMarket, 0, "The market id (required)")
	cmd.Flags().String(FlagAssets, "", "The assets for this order, e.g. 10nhash (required)")
	cmd.Flags().String(FlagPrice, "", "The price for this order, e.g. 10nhash (required)")
	cmd.Flags().String(FlagSettlementFee, "", "The settlement fee Coin string for this order, e.g. 10nhash")
	cmd.Flags().Bool(FlagPartial, false, "Allow this order to be partially filled")
	cmd.Flags().String(FlagExternalID, "", "The external id for this order")
	cmd.Flags().String(FlagCreationFee, "", "The ask order creation fee, e.g. 10nhash")

	cmd.MarkFlagsOneRequired(flags.FlagFrom, FlagSeller)
	MarkFlagsRequired(cmd, FlagMarket, FlagAssets, FlagPrice)

	AddUseArgs(cmd,
		ReqSignerUse(FlagSeller),
		ReqFlagUse(FlagMarket, "market id"),
		ReqFlagUse(FlagAssets, "assets"),
		ReqFlagUse(FlagPrice, "price"),
		UseFlagsBreak,
		OptFlagUse(FlagSettlementFee, "seller settlement flat fee"),
		OptFlagUse(FlagPartial, ""),
		OptFlagUse(FlagExternalID, "external id"),
		OptFlagUse(FlagCreationFee, "creation fee"),
	)
	AddUseDetails(cmd, ReqSignerDesc(FlagSeller))

	cmd.Args = cobra.NoArgs
}

// MakeMsgCreateAsk reads all the SetupCmdTxCreateAsk flags and creates the desired Msg.
// Satisfies the msgMaker type.
func MakeMsgCreateAsk(clientCtx client.Context, flagSet *pflag.FlagSet, _ []string) (*exchange.MsgCreateAskRequest, error) {
	msg := &exchange.MsgCreateAskRequest{}

	errs := make([]error, 8)
	msg.AskOrder.Seller, errs[0] = ReadAddrFlagOrFrom(clientCtx, flagSet, FlagSeller)
	msg.AskOrder.MarketId, errs[1] = flagSet.GetUint32(FlagMarket)
	msg.AskOrder.Assets, errs[2] = ReadReqCoinFlag(flagSet, FlagAssets)
	msg.AskOrder.Price, errs[3] = ReadReqCoinFlag(flagSet, FlagPrice)
	msg.AskOrder.SellerSettlementFlatFee, errs[4] = ReadCoinFlag(flagSet, FlagSettlementFee)
	msg.AskOrder.AllowPartial, errs[5] = flagSet.GetBool(FlagPartial)
	msg.AskOrder.ExternalId, errs[6] = flagSet.GetString(FlagExternalID)
	msg.OrderCreationFee, errs[7] = ReadCoinFlag(flagSet, FlagCreationFee)

	return msg, errors.Join(errs...)
}

// SetupCmdTxCreateBid adds all the flags needed for MakeMsgCreateBid.
func SetupCmdTxCreateBid(cmd *cobra.Command) {
	cmd.Flags().String(FlagBuyer, "", "The buyer (defaults to --from account)")
	cmd.Flags().Uint32(FlagMarket, 0, "The market id (required)")
	cmd.Flags().String(FlagAssets, "", "The assets for this order, e.g. 10nhash (required)")
	cmd.Flags().String(FlagPrice, "", "The price for this order, e.g. 10nhash (required)")
	cmd.Flags().String(FlagSettlementFee, "", "The settlement fee Coin string for this order, e.g. 10nhash")
	cmd.Flags().Bool(FlagPartial, false, "Allow this order to be partially filled")
	cmd.Flags().String(FlagExternalID, "", "The external id for this order")
	cmd.Flags().String(FlagCreationFee, "", "The bid order creation fee, e.g. 10nhash")

	cmd.MarkFlagsOneRequired(flags.FlagFrom, FlagBuyer)
	MarkFlagsRequired(cmd, FlagMarket, FlagAssets, FlagPrice)

	AddUseArgs(cmd,
		ReqSignerUse(FlagBuyer),
		ReqFlagUse(FlagMarket, "market id"),
		ReqFlagUse(FlagAssets, "assets"),
		ReqFlagUse(FlagPrice, "price"),
		UseFlagsBreak,
		OptFlagUse(FlagSettlementFee, "seller settlement flat fee"),
		OptFlagUse(FlagPartial, ""),
		OptFlagUse(FlagExternalID, "external id"),
		OptFlagUse(FlagCreationFee, "creation fee"),
	)
	AddUseDetails(cmd, ReqSignerDesc(FlagBuyer))

	cmd.Args = cobra.NoArgs
}

// MakeMsgCreateBid reads all the SetupCmdTxCreateBid flags and creates the desired Msg.
// Satisfies the msgMaker type.
func MakeMsgCreateBid(clientCtx client.Context, flagSet *pflag.FlagSet, _ []string) (*exchange.MsgCreateBidRequest, error) {
	msg := &exchange.MsgCreateBidRequest{}

	errs := make([]error, 8)
	msg.BidOrder.Buyer, errs[0] = ReadAddrFlagOrFrom(clientCtx, flagSet, FlagBuyer)
	msg.BidOrder.MarketId, errs[1] = flagSet.GetUint32(FlagMarket)
	msg.BidOrder.Assets, errs[2] = ReadReqCoinFlag(flagSet, FlagAssets)
	msg.BidOrder.Price, errs[3] = ReadReqCoinFlag(flagSet, FlagPrice)
	msg.BidOrder.BuyerSettlementFees, errs[4] = ReadCoinsFlag(flagSet, FlagSettlementFee)
	msg.BidOrder.AllowPartial, errs[5] = flagSet.GetBool(FlagPartial)
	msg.BidOrder.ExternalId, errs[6] = flagSet.GetString(FlagExternalID)
	msg.OrderCreationFee, errs[7] = ReadCoinFlag(flagSet, FlagCreationFee)

	return msg, errors.Join(errs...)
}

// SetupCmdTxCommitFunds adds all the flags needed for the MakeMsgCommitFunds.
func SetupCmdTxCommitFunds(cmd *cobra.Command) {
	cmd.Flags().String(FlagAccount, "", "The account committing funds (defaults to --from account)")
	cmd.Flags().Uint32(FlagMarket, 0, "The market id (required)")
	cmd.Flags().String(FlagAmount, "", "The amount to commit, e.g. 10nhash (required)")
	cmd.Flags().String(FlagCreationFee, "", "The commitment creation fee, e.g. 10nhash")
	cmd.Flags().String(FlagTag, "", "The event tag to include in the events with this commitment")

	cmd.MarkFlagsOneRequired(flags.FlagFrom, FlagAccount)
	MarkFlagsRequired(cmd, FlagMarket, FlagAmount)

	AddUseArgs(cmd,
		ReqSignerUse(FlagAccount),
		ReqFlagUse(FlagMarket, "market id"),
		ReqFlagUse(FlagAmount, "amount"),
		UseFlagsBreak,
		OptFlagUse(FlagCreationFee, "creation fee"),
		OptFlagUse(FlagTag, "event tag"),
	)
	AddUseDetails(cmd, ReqSignerDesc(FlagAccount))

	cmd.Args = cobra.NoArgs
}

// MakeMsgCommitFunds reads all the SetupCmdTxCommitFunds flags and creates the desired Msg.
// Satisfies the msgMaker type.
func MakeMsgCommitFunds(clientCtx client.Context, flagSet *pflag.FlagSet, _ []string) (*exchange.MsgCommitFundsRequest, error) {
	msg := &exchange.MsgCommitFundsRequest{}

	errs := make([]error, 5)
	msg.Account, errs[0] = ReadAddrFlagOrFrom(clientCtx, flagSet, FlagAccount)
	msg.MarketId, errs[1] = flagSet.GetUint32(FlagMarket)
	msg.Amount, errs[2] = ReadReqCoinsFlag(flagSet, FlagAmount)
	msg.CreationFee, errs[3] = ReadCoinFlag(flagSet, FlagCreationFee)
	msg.EventTag, errs[4] = flagSet.GetString(FlagTag)

	return msg, errors.Join(errs...)
}

// SetupCmdTxSendAndCommit adds the flags needed for MakeMsgSendAndCommit.
func SetupCmdTxSendAndCommit(cmd *cobra.Command) {
	cmd.Flags().String(FlagSender, "", "The account sending the funds (defaults to --from account)")
	cmd.Flags().String(FlagTo, "", "The recipient address (required)")
	cmd.Flags().Uint32(FlagMarket, 0, "The market id to commit funds to (required)")
	cmd.Flags().String(FlagAmount, "", "The coins to send and commit (required)")
	cmd.Flags().String(FlagTag, "", "An optional event tag")

	cmd.MarkFlagsOneRequired(flags.FlagFrom, FlagSender)
	MarkFlagsRequired(cmd, FlagTo, FlagMarket, FlagAmount)

	AddUseArgs(cmd,
		ReqSignerUse(FlagSender),
		ReqFlagUse(FlagTo, "recipient address"),
		ReqFlagUse(FlagMarket, "market id"),
		ReqFlagUse(FlagAmount, "amount"),
		UseFlagsBreak,
		OptFlagUse(FlagTag, "event tag"),
	)
	AddUseDetails(cmd, ReqSignerDesc(FlagSender))

	cmd.Args = cobra.NoArgs
}

// MakeMsgSendAndCommit builds a MsgSendAndCommitRequest from the provided command and flags.
func MakeMsgSendAndCommit(clientCtx client.Context, flagSet *pflag.FlagSet, _ []string) (*exchange.MsgSendAndCommitRequest, error) {
	msg := &exchange.MsgSendAndCommitRequest{}

	errs := make([]error, 5)
	msg.Sender, errs[0] = ReadAddrFlagOrFrom(clientCtx, flagSet, FlagSender)
	msg.ToAddress, errs[1] = flagSet.GetString(FlagTo)
	msg.MarketId, errs[2] = flagSet.GetUint32(FlagMarket)
	msg.Amount, errs[3] = ReadReqCoinsFlag(flagSet, FlagAmount)
	msg.EventTag, errs[4] = flagSet.GetString(FlagTag)

	return msg, errors.Join(errs...)
}

// SetupCmdTxCancelOrder adds all the flags needed for the MakeMsgCancelOrder.
func SetupCmdTxCancelOrder(cmd *cobra.Command) {
	cmd.Flags().String(FlagSigner, "", "The signer (defaults to --from account)")
	cmd.Flags().Uint64(FlagOrder, 0, "The order id")

	cmd.MarkFlagsOneRequired(flags.FlagFrom, FlagSigner)

	AddUseArgs(cmd,
		fmt.Sprintf("{<order id>|--%s <order id>}", FlagOrder),
		ReqSignerUse(FlagSigner),
	)
	AddUseDetails(cmd,
		ReqSignerDesc(FlagSigner),
		"The <order id> must be provided either as the first argument or using the --order flag, but not both.",
	)

	cmd.Args = cobra.MaximumNArgs(1)
}

// MakeMsgCancelOrder reads all the SetupCmdTxCancelOrder flags and the provided args and creates the desired Msg.
// Satisfies the msgMaker type.
func MakeMsgCancelOrder(clientCtx client.Context, flagSet *pflag.FlagSet, args []string) (*exchange.MsgCancelOrderRequest, error) {
	msg := &exchange.MsgCancelOrderRequest{}

	errs := make([]error, 2)
	msg.Signer, errs[0] = ReadAddrFlagOrFrom(clientCtx, flagSet, FlagSigner)
	msg.OrderId, errs[1] = ReadFlagOrderOrArg(flagSet, args)

	return msg, errors.Join(errs...)
}

// SetupCmdTxFillBids adds all the flags needed for MakeMsgFillBids.
func SetupCmdTxFillBids(cmd *cobra.Command) {
	cmd.Flags().String(FlagSeller, "", "The seller (defaults to --from account)")
	cmd.Flags().Uint32(FlagMarket, 0, "The market id (required)")
	cmd.Flags().String(FlagAssets, "", "The total assets you are filling, e.g. 10nhash (required)")
	cmd.Flags().UintSlice(FlagBids, nil, "The bid order ids (repeatable, required)")
	cmd.Flags().String(FlagSettlementFee, "", "The settlement fee Coin string for this order, e.g. 10nhash")
	cmd.Flags().String(FlagCreationFee, "", "The ask order creation fee, e.g. 10nhash")

	cmd.MarkFlagsOneRequired(flags.FlagFrom, FlagSeller)
	MarkFlagsRequired(cmd, FlagMarket, FlagAssets, FlagBids)

	AddUseArgs(cmd,
		ReqSignerUse(FlagSeller),
		ReqFlagUse(FlagMarket, "market id"),
		ReqFlagUse(FlagAssets, "total assets"),
		ReqFlagUse(FlagBids, "bid order ids"),
		UseFlagsBreak,
		OptFlagUse(FlagSettlementFee, "seller settlement flat fee"),
		OptFlagUse(FlagCreationFee, "ask order creation fee"),
	)
	AddUseDetails(cmd, ReqSignerDesc(FlagSeller), RepeatableDesc)

	cmd.Args = cobra.NoArgs
}

// MakeMsgFillBids reads all the SetupCmdTxFillBids flags and creates the desired Msg.
// Satisfies the msgMaker type.
func MakeMsgFillBids(clientCtx client.Context, flagSet *pflag.FlagSet, _ []string) (*exchange.MsgFillBidsRequest, error) {
	msg := &exchange.MsgFillBidsRequest{}

	errs := make([]error, 6)
	msg.Seller, errs[0] = ReadAddrFlagOrFrom(clientCtx, flagSet, FlagSeller)
	msg.MarketId, errs[1] = flagSet.GetUint32(FlagMarket)
	msg.TotalAssets, errs[2] = ReadCoinsFlag(flagSet, FlagAssets)
	msg.BidOrderIds, errs[3] = ReadOrderIDsFlag(flagSet, FlagBids)
	msg.SellerSettlementFlatFee, errs[4] = ReadCoinFlag(flagSet, FlagSettlementFee)
	msg.AskOrderCreationFee, errs[5] = ReadCoinFlag(flagSet, FlagCreationFee)

	return msg, errors.Join(errs...)
}

// SetupCmdTxFillAsks adds all the flags needed for MakeMsgFillAsks.
func SetupCmdTxFillAsks(cmd *cobra.Command) {
	cmd.Flags().String(FlagBuyer, "", "The buyer (defaults to --from account)")
	cmd.Flags().Uint32(FlagMarket, 0, "The market id (required)")
	cmd.Flags().String(FlagPrice, "", "The total price you are paying, e.g. 10nhash (required)")
	cmd.Flags().UintSlice(FlagAsks, nil, "The ask order ids (repeatable, required)")
	cmd.Flags().String(FlagSettlementFee, "", "The settlement fee Coin string for this order, e.g. 10nhash")
	cmd.Flags().String(FlagCreationFee, "", "The bid order creation fee, e.g. 10nhash")

	cmd.MarkFlagsOneRequired(flags.FlagFrom, FlagBuyer)
	MarkFlagsRequired(cmd, FlagMarket, FlagPrice, FlagAsks)

	AddUseArgs(cmd,
		ReqSignerUse(FlagBuyer),
		ReqFlagUse(FlagMarket, "market id"),
		ReqFlagUse(FlagPrice, "total price"),
		ReqFlagUse(FlagAsks, "ask order ids"),
		UseFlagsBreak,
		OptFlagUse(FlagSettlementFee, "buyer settlement fees"),
		OptFlagUse(FlagCreationFee, "bid order creation fee"),
	)
	AddUseDetails(cmd, ReqSignerDesc(FlagBuyer), RepeatableDesc)

	cmd.Args = cobra.NoArgs
}

// MakeMsgFillAsks reads all the SetupCmdTxFillAsks flags and creates the desired Msg.
// Satisfies the msgMaker type.
func MakeMsgFillAsks(clientCtx client.Context, flagSet *pflag.FlagSet, _ []string) (*exchange.MsgFillAsksRequest, error) {
	msg := &exchange.MsgFillAsksRequest{}

	errs := make([]error, 6)
	msg.Buyer, errs[0] = ReadAddrFlagOrFrom(clientCtx, flagSet, FlagBuyer)
	msg.MarketId, errs[1] = flagSet.GetUint32(FlagMarket)
	msg.TotalPrice, errs[2] = ReadReqCoinFlag(flagSet, FlagPrice)
	msg.AskOrderIds, errs[3] = ReadOrderIDsFlag(flagSet, FlagAsks)
	msg.BuyerSettlementFees, errs[4] = ReadCoinsFlag(flagSet, FlagSettlementFee)
	msg.BidOrderCreationFee, errs[5] = ReadCoinFlag(flagSet, FlagCreationFee)

	return msg, errors.Join(errs...)
}

// SetupCmdTxMarketSettle adds all the flags needed for MakeMsgMarketSettle.
func SetupCmdTxMarketSettle(cmd *cobra.Command) {
	AddFlagsAdmin(cmd)
	cmd.Flags().Uint32(FlagMarket, 0, "The market id (required)")
	cmd.Flags().UintSlice(FlagAsks, nil, "The ask order ids (repeatable, required)")
	cmd.Flags().UintSlice(FlagBids, nil, "The bid order ids (repeatable, required)")
	cmd.Flags().Bool(FlagPartial, false, "Expect partial settlement")

	MarkFlagsRequired(cmd, FlagMarket, FlagAsks, FlagBids)

	AddUseArgs(cmd,
		ReqAdminUse,
		ReqFlagUse(FlagMarket, "market id"),
		ReqFlagUse(FlagAsks, "ask order ids"),
		ReqFlagUse(FlagBids, "bid order ids"),
		OptFlagUse(FlagPartial, ""),
	)
	AddUseDetails(cmd, ReqAdminDesc, RepeatableDesc)

	cmd.Args = cobra.NoArgs
}

// MakeMsgMarketSettle reads all the SetupCmdTxMarketSettle flags and creates the desired Msg.
// Satisfies the msgMaker type.
func MakeMsgMarketSettle(clientCtx client.Context, flagSet *pflag.FlagSet, _ []string) (*exchange.MsgMarketSettleRequest, error) {
	msg := &exchange.MsgMarketSettleRequest{}

	errs := make([]error, 5)
	msg.Admin, errs[0] = ReadFlagsAdminOrFrom(clientCtx, flagSet)
	msg.MarketId, errs[1] = flagSet.GetUint32(FlagMarket)
	msg.AskOrderIds, errs[2] = ReadOrderIDsFlag(flagSet, FlagAsks)
	msg.BidOrderIds, errs[3] = ReadOrderIDsFlag(flagSet, FlagBids)
	msg.ExpectPartial, errs[4] = flagSet.GetBool(FlagPartial)

	return msg, errors.Join(errs...)
}

// SetupCmdTxMarketCommitmentSettle adds all the flags needed for MakeMsgMarketCommitmentSettle.
func SetupCmdTxMarketCommitmentSettle(cmd *cobra.Command) {
	AddFlagsAdminOpt(cmd)
	cmd.Flags().Uint32(FlagMarket, 0, "The market id (required)")
	cmd.Flags().StringSlice(FlagInputs, nil, "The inputs for this commitment settlement (repeatable)")
	cmd.Flags().StringSlice(FlagOutputs, nil, "The outputs for this commitment settlement (repeatable)")
	cmd.Flags().StringSlice(FlagSettlementFees, nil, "The fees to collect during this commitment settlement (repeatable)")
	cmd.Flags().StringSlice(FlagNavs, nil, "The net-asset-values to update during this commitment settlement (repeatable)")
	cmd.Flags().String(FlagTag, "", "The tag to include in the events emitted as part of this commitment settlement")
	cmd.Flags().String(FlagFile, "", "a json file of a Tx with a MsgMarketCommitmentSettleRequest")

	cmd.MarkFlagsOneRequired(FlagFile, flags.FlagFrom, FlagAdmin, FlagAuthority)
	cmd.MarkFlagsOneRequired(FlagFile, FlagMarket)

	AddUseArgs(cmd,
		ReqAdminUse,
		OptFlagUse(FlagMarket, "market id"),
		UseFlagsBreak,
		OptFlagUse(FlagInputs, "account-amount"),
		OptFlagUse(FlagOutputs, "account-amount"),
		UseFlagsBreak,
		OptFlagUse(FlagSettlementFees, "account-amount"),
		OptFlagUse(FlagNavs, "nav"),
		OptFlagUse(FlagTag, "event tag"),
		UseFlagsBreak,
		OptFlagUse(FlagFile, "filename"),
	)
	AddUseDetails(cmd,
		ReqAdminDesc, RepeatableDesc, AccountAmountDesc, NAVDesc,
		MsgFileDesc(&exchange.MsgMarketCommitmentSettleRequest{}),
	)

	cmd.Args = cobra.NoArgs
}

// MakeMsgMarketCommitmentSettle reads all the SetupCmdTxMarketCommitmentSettle flags and creates the desired Msg.
// Satisfies the msgMaker type.
func MakeMsgMarketCommitmentSettle(clientCtx client.Context, flagSet *pflag.FlagSet, _ []string) (*exchange.MsgMarketCommitmentSettleRequest, error) {
	var msg *exchange.MsgMarketCommitmentSettleRequest

	errs := make([]error, 8)
	msg, errs[0] = ReadMsgMarketCommitmentSettleFromFileFlag(clientCtx, flagSet)
	msg.Admin, errs[1] = ReadFlagsAdminOrFromOrDefault(clientCtx, flagSet, msg.Admin)
	msg.MarketId, errs[2] = ReadFlagUint32OrDefault(flagSet, FlagMarket, msg.MarketId)
	msg.Inputs, errs[3] = ReadFlagAccountAmountsOrDefault(flagSet, FlagInputs, msg.Inputs)
	msg.Outputs, errs[4] = ReadFlagAccountAmountsOrDefault(flagSet, FlagOutputs, msg.Outputs)
	msg.Fees, errs[5] = ReadFlagAccountAmountsOrDefault(flagSet, FlagSettlementFees, msg.Fees)
	msg.Navs, errs[6] = ReadFlagNetAssetPricesOrDefault(flagSet, FlagNavs, msg.Navs)
	msg.EventTag, errs[7] = ReadFlagStringOrDefault(flagSet, FlagTag, msg.EventTag)

	return msg, errors.Join(errs...)
}

// SetupCmdTxMarketReleaseCommitments adds all the flags needed for MakeMsgMarketReleaseCommitments.
func SetupCmdTxMarketReleaseCommitments(cmd *cobra.Command) {
	AddFlagsAdmin(cmd)
	cmd.Flags().Uint32(FlagMarket, 0, "The market id (required)")
	cmd.Flags().StringSlice(FlagRelease, nil, "The accounts and amounts to release (repeatable)")
	cmd.Flags().StringSlice(FlagReleaseAll, nil, "The accounts that should have all funds released (repeatable)")
	cmd.Flags().String(FlagTag, "", "The tag to include in the events emitted as part of these releases")

	MarkFlagsRequired(cmd, FlagMarket)
	cmd.MarkFlagsOneRequired(FlagRelease, FlagReleaseAll)

	AddUseArgs(cmd,
		ReqAdminUse,
		ReqFlagUse(FlagMarket, "market id"),
		UseFlagsBreak,
		OptFlagUse(FlagRelease, "account-amount"),
		OptFlagUse(FlagReleaseAll, "account"),
		OptFlagUse(FlagTag, "event tag"),
	)
	AddUseDetails(cmd,
		ReqAdminDesc,
		fmt.Sprintf("At least one of --%s and/or --%s must be provided", FlagRelease, FlagReleaseAll),
		RepeatableDesc, AccountAmountDesc,
	)

	cmd.Args = cobra.NoArgs
}

// MakeMsgMarketReleaseCommitments reads all the SetupCmdTxMarketReleaseCommitments flags and creates the desired Msg.
// Satisfies the msgMaker type.
func MakeMsgMarketReleaseCommitments(clientCtx client.Context, flagSet *pflag.FlagSet, _ []string) (*exchange.MsgMarketReleaseCommitmentsRequest, error) {
	msg := &exchange.MsgMarketReleaseCommitmentsRequest{}

	var releaseAll []exchange.AccountAmount
	errs := make([]error, 5)
	msg.Admin, errs[0] = ReadFlagsAdminOrFrom(clientCtx, flagSet)
	msg.MarketId, errs[1] = flagSet.GetUint32(FlagMarket)
	msg.ToRelease, errs[2] = ReadFlagAccountAmounts(flagSet, FlagRelease)
	releaseAll, errs[3] = ReadFlagAccountsWithoutAmounts(flagSet, FlagReleaseAll)
	msg.ToRelease = append(msg.ToRelease, releaseAll...)
	msg.EventTag, errs[4] = flagSet.GetString(FlagTag)

	return msg, errors.Join(errs...)
}

// SetupCmdTxMarketTransferCommitment adds all the flags needed for MakeMsgMarketTransferCommitment.
func SetupCmdTxMarketTransferCommitment(cmd *cobra.Command) {
	AddFlagsAdmin(cmd)
	cmd.Flags().String(FlagAccount, "", "The account that will receive the funds (required)")
	cmd.Flags().String(FlagAmount, "", "The amount to withdraw (required)")
	cmd.Flags().Uint32(FlagCurrentMarket, 0, "The current market id (required)")
	cmd.Flags().Uint32(FlagNewMarket, 0, "The new market id (required)")
	cmd.Flags().String(FlagTag, "", "The tag to include in the events emitted as part of these transfer")

	MarkFlagsRequired(cmd, FlagAccount, FlagAmount, FlagCurrentMarket, FlagNewMarket)

	AddUseArgs(cmd,
		ReqAdminUse,
		ReqFlagUse(FlagAccount, "account"),
		ReqFlagUse(FlagAmount, "amount"),
		ReqFlagUse(FlagCurrentMarket, "current market id"),
		ReqFlagUse(FlagNewMarket, "new market id"),
		OptFlagUse(FlagTag, "event tag"),
	)
	AddUseDetails(cmd, ReqAdminDesc)

	cmd.Args = cobra.NoArgs
}

// MakeMsgMarketTransferCommitment reads all the SetupCmdTxMarketTransferCommitment flags and creates the desired Msg.
// Satisfies the msgMaker type.
func MakeMsgMarketTransferCommitment(clientCtx client.Context, flagSet *pflag.FlagSet, _ []string) (*exchange.MsgMarketTransferCommitmentRequest, error) {
	msg := &exchange.MsgMarketTransferCommitmentRequest{}

	errs := make([]error, 6)
	msg.Admin, errs[0] = ReadFlagsAdminOrFrom(clientCtx, flagSet)
	msg.Account, errs[1] = flagSet.GetString(FlagAccount)
	msg.Amount, errs[2] = ReadCoinsFlag(flagSet, FlagAmount)
	msg.CurrentMarketId, errs[3] = flagSet.GetUint32(FlagCurrentMarket)
	msg.NewMarketId, errs[4] = flagSet.GetUint32(FlagNewMarket)
	msg.EventTag, errs[5] = flagSet.GetString(FlagTag)
	return msg, errors.Join(errs...)
}

// SetupCmdTxMarketSetOrderExternalID adds all the flags needed for MakeMsgMarketSetOrderExternalID.
func SetupCmdTxMarketSetOrderExternalID(cmd *cobra.Command) {
	AddFlagsAdmin(cmd)
	cmd.Flags().Uint32(FlagMarket, 0, "The market id (required)")
	cmd.Flags().Uint64(FlagOrder, 0, "The order id (required)")
	cmd.Flags().String(FlagExternalID, "", "The new external id for this order")

	MarkFlagsRequired(cmd, FlagMarket, FlagOrder)

	AddUseArgs(cmd,
		ReqAdminUse,
		ReqFlagUse(FlagMarket, "market id"),
		ReqFlagUse(FlagOrder, "order id"),
		OptFlagUse(FlagExternalID, "external id"),
	)
	AddUseDetails(cmd, ReqAdminDesc)

	cmd.Args = cobra.NoArgs
}

// MakeMsgMarketSetOrderExternalID reads all the SetupCmdTxMarketSetOrderExternalID flags and creates the desired Msg.
// Satisfies the msgMaker type.
func MakeMsgMarketSetOrderExternalID(clientCtx client.Context, flagSet *pflag.FlagSet, _ []string) (*exchange.MsgMarketSetOrderExternalIDRequest, error) {
	msg := &exchange.MsgMarketSetOrderExternalIDRequest{}

	errs := make([]error, 4)
	msg.Admin, errs[0] = ReadFlagsAdminOrFrom(clientCtx, flagSet)
	msg.MarketId, errs[1] = flagSet.GetUint32(FlagMarket)
	msg.OrderId, errs[2] = flagSet.GetUint64(FlagOrder)
	msg.ExternalId, errs[3] = flagSet.GetString(FlagExternalID)

	return msg, errors.Join(errs...)
}

// SetupCmdTxMarketWithdraw adds all the flags needed for MakeMsgMarketWithdraw.
func SetupCmdTxMarketWithdraw(cmd *cobra.Command) {
	AddFlagsAdmin(cmd)
	cmd.Flags().Uint32(FlagMarket, 0, "The market id (required)")
	cmd.Flags().String(FlagTo, "", "The address that will receive the funds (required)")
	cmd.Flags().String(FlagAmount, "", "The amount to withdraw (required)")

	MarkFlagsRequired(cmd, FlagMarket, FlagTo, FlagAmount)

	AddUseArgs(cmd,
		ReqAdminUse,
		ReqFlagUse(FlagMarket, "market id"),
		ReqFlagUse(FlagTo, "to address"),
		ReqFlagUse(FlagAmount, "amount"),
	)
	AddUseDetails(cmd, ReqAdminDesc)

	cmd.Args = cobra.NoArgs
}

// MakeMsgMarketWithdraw reads all the SetupCmdTxMarketWithdraw flags and creates the desired Msg.
// Satisfies the msgMaker type.
func MakeMsgMarketWithdraw(clientCtx client.Context, flagSet *pflag.FlagSet, _ []string) (*exchange.MsgMarketWithdrawRequest, error) {
	msg := &exchange.MsgMarketWithdrawRequest{}

	errs := make([]error, 4)
	msg.Admin, errs[0] = ReadFlagsAdminOrFrom(clientCtx, flagSet)
	msg.MarketId, errs[1] = flagSet.GetUint32(FlagMarket)
	msg.ToAddress, errs[2] = flagSet.GetString(FlagTo)
	msg.Amount, errs[3] = ReadCoinsFlag(flagSet, FlagAmount)

	return msg, errors.Join(errs...)
}

// AddFlagsMarketDetails adds all the flags needed for ReadFlagsMarketDetails.
func AddFlagsMarketDetails(cmd *cobra.Command) {
	cmd.Flags().String(FlagName, "", fmt.Sprintf("A short name for the market (max %d chars)", exchange.MaxName))
	cmd.Flags().String(FlagDescription, "", fmt.Sprintf("A description of the market (max %d chars)", exchange.MaxDescription))
	cmd.Flags().String(FlagURL, "", fmt.Sprintf("The market's website URL (max %d chars)", exchange.MaxWebsiteURL))
	cmd.Flags().String(FlagIcon, "", fmt.Sprintf("The market's icon URI (max %d chars)", exchange.MaxIconURI))
}

// ReadFlagsMarketDetails reads all the AddFlagsMarketDetails flags and creates the desired MarketDetails.
func ReadFlagsMarketDetails(flagSet *pflag.FlagSet, def exchange.MarketDetails) (exchange.MarketDetails, error) {
	rv := exchange.MarketDetails{}

	errs := make([]error, 4)
	rv.Name, errs[0] = ReadFlagStringOrDefault(flagSet, FlagName, def.Name)
	rv.Description, errs[1] = ReadFlagStringOrDefault(flagSet, FlagDescription, def.Description)
	rv.WebsiteUrl, errs[2] = ReadFlagStringOrDefault(flagSet, FlagURL, def.WebsiteUrl)
	rv.IconUri, errs[3] = ReadFlagStringOrDefault(flagSet, FlagIcon, def.IconUri)

	return rv, errors.Join(errs...)
}

// SetupCmdTxMarketUpdateDetails adds all the flags needed for MakeMsgMarketUpdateDetails.
func SetupCmdTxMarketUpdateDetails(cmd *cobra.Command) {
	AddFlagsAdmin(cmd)
	cmd.Flags().Uint32(FlagMarket, 0, "The market id (required)")
	AddFlagsMarketDetails(cmd)

	MarkFlagsRequired(cmd, FlagMarket)

	AddUseArgs(cmd,
		ReqAdminUse,
		ReqFlagUse(FlagMarket, "market id"),
		UseFlagsBreak,
		OptFlagUse(FlagName, "name"),
		OptFlagUse(FlagDescription, "description"),
		OptFlagUse(FlagURL, "website url"),
		OptFlagUse(FlagIcon, "icon uri"),
	)
	AddUseDetails(cmd,
		ReqAdminDesc,
		`All fields of a market's details will be updated.
If you omit an optional flag, that field will be updated to an empty string.`,
	)

	cmd.Args = cobra.NoArgs
}

// MakeMsgMarketUpdateDetails reads all the SetupCmdTxMarketUpdateDetails flags and creates the desired Msg.
// Satisfies the msgMaker type.
func MakeMsgMarketUpdateDetails(clientCtx client.Context, flagSet *pflag.FlagSet, _ []string) (*exchange.MsgMarketUpdateDetailsRequest, error) {
	msg := &exchange.MsgMarketUpdateDetailsRequest{}

	errs := make([]error, 3)
	msg.Admin, errs[0] = ReadFlagsAdminOrFrom(clientCtx, flagSet)
	msg.MarketId, errs[1] = flagSet.GetUint32(FlagMarket)
	msg.MarketDetails, errs[2] = ReadFlagsMarketDetails(flagSet, exchange.MarketDetails{})

	return msg, errors.Join(errs...)
}

// SetupCmdTxMarketUpdateAcceptingOrders adds all the flags needed for MakeMsgMarketUpdateAcceptingOrders.
func SetupCmdTxMarketUpdateAcceptingOrders(cmd *cobra.Command) {
	AddFlagsAdmin(cmd)
	cmd.Flags().Uint32(FlagMarket, 0, "The market id (required)")
	AddFlagsEnableDisable(cmd, "accepting_orders")

	MarkFlagsRequired(cmd, FlagMarket)

	AddUseArgs(cmd,
		ReqAdminUse,
		ReqFlagUse(FlagMarket, "market id"),
		ReqEnableDisableUse,
	)
	AddUseDetails(cmd, ReqAdminDesc, ReqEnableDisableDesc)

	cmd.Args = cobra.NoArgs
}

// MakeMsgMarketUpdateAcceptingOrders reads all the SetupCmdTxMarketUpdateAcceptingOrders flags and creates the desired Msg.
// Satisfies the msgMaker type.
func MakeMsgMarketUpdateAcceptingOrders(clientCtx client.Context, flagSet *pflag.FlagSet, _ []string) (*exchange.MsgMarketUpdateAcceptingOrdersRequest, error) {
	msg := &exchange.MsgMarketUpdateAcceptingOrdersRequest{}

	errs := make([]error, 3)
	msg.Admin, errs[0] = ReadFlagsAdminOrFrom(clientCtx, flagSet)
	msg.MarketId, errs[1] = flagSet.GetUint32(FlagMarket)
	msg.AcceptingOrders, errs[2] = ReadFlagsEnableDisable(flagSet)

	return msg, errors.Join(errs...)
}

// SetupCmdTxMarketUpdateUserSettle adds all the flags needed for MakeMsgMarketUpdateUserSettle.
func SetupCmdTxMarketUpdateUserSettle(cmd *cobra.Command) {
	AddFlagsAdmin(cmd)
	cmd.Flags().Uint32(FlagMarket, 0, "The market id (required)")
	AddFlagsEnableDisable(cmd, "allow_user_settlement")

	MarkFlagsRequired(cmd, FlagMarket)

	AddUseArgs(cmd,
		ReqAdminUse,
		ReqFlagUse(FlagMarket, "market id"),
		ReqEnableDisableUse,
	)
	AddUseDetails(cmd, ReqAdminDesc, ReqEnableDisableDesc)

	cmd.Args = cobra.NoArgs
}

// MakeMsgMarketUpdateUserSettle reads all the SetupCmdTxMarketUpdateUserSettle flags and creates the desired Msg.
// Satisfies the msgMaker type.
func MakeMsgMarketUpdateUserSettle(clientCtx client.Context, flagSet *pflag.FlagSet, _ []string) (*exchange.MsgMarketUpdateUserSettleRequest, error) {
	msg := &exchange.MsgMarketUpdateUserSettleRequest{}

	errs := make([]error, 3)
	msg.Admin, errs[0] = ReadFlagsAdminOrFrom(clientCtx, flagSet)
	msg.MarketId, errs[1] = flagSet.GetUint32(FlagMarket)
	msg.AllowUserSettlement, errs[2] = ReadFlagsEnableDisable(flagSet)

	return msg, errors.Join(errs...)
}

// SetupCmdTxMarketUpdateAcceptingCommitments adds all the flags needed for MakeMarketUpdateAcceptingCommitmentsOrders.
func SetupCmdTxMarketUpdateAcceptingCommitments(cmd *cobra.Command) {
	AddFlagsAdmin(cmd)
	cmd.Flags().Uint32(FlagMarket, 0, "The market id (required)")
	AddFlagsEnableDisable(cmd, "accepting_commitments")

	MarkFlagsRequired(cmd, FlagMarket)

	AddUseArgs(cmd,
		ReqAdminUse,
		ReqFlagUse(FlagMarket, "market id"),
		ReqEnableDisableUse,
	)
	AddUseDetails(cmd, ReqAdminDesc, ReqEnableDisableDesc)

	cmd.Args = cobra.NoArgs
}

// MakeMsgMarketUpdateAcceptingCommitments reads all the SetupCmdTxMarketUpdateAcceptingCommitments flags and creates the desired Msg.
// Satisfies the msgMaker type.
func MakeMsgMarketUpdateAcceptingCommitments(clientCtx client.Context, flagSet *pflag.FlagSet, _ []string) (*exchange.MsgMarketUpdateAcceptingCommitmentsRequest, error) {
	msg := &exchange.MsgMarketUpdateAcceptingCommitmentsRequest{}

	errs := make([]error, 3)
	msg.Admin, errs[0] = ReadFlagsAdminOrFrom(clientCtx, flagSet)
	msg.MarketId, errs[1] = flagSet.GetUint32(FlagMarket)
	msg.AcceptingCommitments, errs[2] = ReadFlagsEnableDisable(flagSet)

	return msg, errors.Join(errs...)
}

// SetupCmdTxMarketUpdateIntermediaryDenom adds all the flags needed for MakeMsgMarketUpdateIntermediaryDenom.
func SetupCmdTxMarketUpdateIntermediaryDenom(cmd *cobra.Command) {
	AddFlagsAdmin(cmd)
	cmd.Flags().Uint32(FlagMarket, 0, "The market id (required)")
	cmd.Flags().String(FlagDenom, "", "The new intermediary denomination (required)")

	MarkFlagsRequired(cmd, FlagMarket, FlagDenom)

	AddUseArgs(cmd,
		ReqAdminUse,
		ReqFlagUse(FlagMarket, "market id"),
		ReqFlagUse(FlagDenom, "denom"),
	)
	AddUseDetails(cmd, ReqAdminDesc)

	cmd.Args = cobra.NoArgs
}

// MakeMsgMarketUpdateIntermediaryDenom reads all the SetupCmdTxMarketUpdateIntermediaryDenom flags and creates the desired Msg.
// Satisfies the msgMaker type.
func MakeMsgMarketUpdateIntermediaryDenom(clientCtx client.Context, flagSet *pflag.FlagSet, _ []string) (*exchange.MsgMarketUpdateIntermediaryDenomRequest, error) {
	msg := &exchange.MsgMarketUpdateIntermediaryDenomRequest{}

	errs := make([]error, 3)
	msg.Admin, errs[0] = ReadFlagsAdminOrFrom(clientCtx, flagSet)
	msg.MarketId, errs[1] = flagSet.GetUint32(FlagMarket)
	msg.IntermediaryDenom, errs[2] = flagSet.GetString(FlagDenom)

	return msg, errors.Join(errs...)
}

// SetupCmdTxMarketManagePermissions adds all the flags needed for MakeMsgMarketManagePermissions.
func SetupCmdTxMarketManagePermissions(cmd *cobra.Command) {
	AddFlagsAdmin(cmd)
	cmd.Flags().Uint32(FlagMarket, 0, "The market id (required)")
	cmd.Flags().StringSlice(FlagRevokeAll, nil, "Addresses to revoke all permissions from (repeatable)")
	cmd.Flags().StringSlice(FlagRevoke, nil, "<access grants> to remove from the market (repeatable)")
	cmd.Flags().StringSlice(FlagGrant, nil, "<access grants> to add to the market (repeatable)")

	cmd.MarkFlagsOneRequired(FlagRevokeAll, FlagRevoke, FlagGrant)
	MarkFlagsRequired(cmd, FlagMarket)

	AddUseArgs(cmd,
		ReqAdminUse,
		ReqFlagUse(FlagMarket, "market id"),
		UseFlagsBreak,
		OptFlagUse(FlagRevokeAll, "addresses"),
		OptFlagUse(FlagRevoke, "access grants"),
		OptFlagUse(FlagGrant, "access grants"),
	)
	AddUseDetails(cmd, ReqAdminDesc, RepeatableDesc, AccessGrantsDesc)

	cmd.Args = cobra.NoArgs
}

// MakeMsgMarketManagePermissions reads all the SetupCmdTxMarketManagePermissions flags and creates the desired Msg.
// Satisfies the msgMaker type.
func MakeMsgMarketManagePermissions(clientCtx client.Context, flagSet *pflag.FlagSet, _ []string) (*exchange.MsgMarketManagePermissionsRequest, error) {
	msg := &exchange.MsgMarketManagePermissionsRequest{}

	errs := make([]error, 5)
	msg.Admin, errs[0] = ReadFlagsAdminOrFrom(clientCtx, flagSet)
	msg.MarketId, errs[1] = flagSet.GetUint32(FlagMarket)
	msg.RevokeAll, errs[2] = flagSet.GetStringSlice(FlagRevokeAll)
	msg.ToRevoke, errs[3] = ReadAccessGrantsFlag(flagSet, FlagRevoke, nil)
	msg.ToGrant, errs[4] = ReadAccessGrantsFlag(flagSet, FlagGrant, nil)

	return msg, errors.Join(errs...)
}

// SetupCmdTxMarketManageReqAttrs adds all the flags needed for MakeMsgMarketManageReqAttrs.
func SetupCmdTxMarketManageReqAttrs(cmd *cobra.Command) {
	AddFlagsAdmin(cmd)
	cmd.Flags().Uint32(FlagMarket, 0, "The market id (required)")
	cmd.Flags().StringSlice(FlagAskAdd, nil, "The create-ask required attributes to add (repeatable)")
	cmd.Flags().StringSlice(FlagAskRemove, nil, "The create-ask required attributes to remove (repeatable)")
	cmd.Flags().StringSlice(FlagBidAdd, nil, "The create-bid required attributes to add (repeatable)")
	cmd.Flags().StringSlice(FlagBidRemove, nil, "The create-bid required attributes to remove (repeatable)")
	cmd.Flags().StringSlice(FlagCommitmentAdd, nil, "The create-commitment required attributes to add (repeatable)")
	cmd.Flags().StringSlice(FlagCommitmentRemove, nil, "The create-commitment required attributes to remove (repeatable)")

	cmd.MarkFlagsOneRequired(FlagAskAdd, FlagAskRemove, FlagBidAdd, FlagBidRemove, FlagCommitmentAdd, FlagCommitmentRemove)
	MarkFlagsRequired(cmd, FlagMarket)

	AddUseArgs(cmd,
		ReqAdminUse,
		ReqFlagUse(FlagMarket, "market id"),
		UseFlagsBreak,
		OptFlagUse(FlagAskAdd, "attrs"),
		OptFlagUse(FlagAskRemove, "attrs"),
		UseFlagsBreak,
		OptFlagUse(FlagBidAdd, "attrs"),
		OptFlagUse(FlagBidRemove, "attrs"),
		UseFlagsBreak,
		OptFlagUse(FlagCommitmentAdd, "attrs"),
		OptFlagUse(FlagCommitmentRemove, "attrs"),
	)
	AddUseDetails(cmd, ReqAdminDesc, RepeatableDesc)

	cmd.Args = cobra.NoArgs
}

// MakeMsgMarketManageReqAttrs reads all the SetupCmdTxMarketManageReqAttrs flags and creates the desired Msg.
// Satisfies the msgMaker type.
func MakeMsgMarketManageReqAttrs(clientCtx client.Context, flagSet *pflag.FlagSet, _ []string) (*exchange.MsgMarketManageReqAttrsRequest, error) {
	msg := &exchange.MsgMarketManageReqAttrsRequest{}

	errs := make([]error, 8)
	msg.Admin, errs[0] = ReadFlagsAdminOrFrom(clientCtx, flagSet)
	msg.MarketId, errs[1] = flagSet.GetUint32(FlagMarket)
	msg.CreateAskToAdd, errs[2] = flagSet.GetStringSlice(FlagAskAdd)
	msg.CreateAskToRemove, errs[3] = flagSet.GetStringSlice(FlagAskRemove)
	msg.CreateBidToAdd, errs[4] = flagSet.GetStringSlice(FlagBidAdd)
	msg.CreateBidToRemove, errs[5] = flagSet.GetStringSlice(FlagBidRemove)
	msg.CreateCommitmentToAdd, errs[6] = flagSet.GetStringSlice(FlagCommitmentAdd)
	msg.CreateCommitmentToRemove, errs[7] = flagSet.GetStringSlice(FlagCommitmentRemove)

	return msg, errors.Join(errs...)
}

// SetupCmdTxCreatePayment adds all the flags needed for MakeMsgCreatePayment.
func SetupCmdTxCreatePayment(cmd *cobra.Command) {
	cmd.Flags().String(FlagSource, "", "The source account (defaults to --from account)")
	cmd.Flags().String(FlagSourceAmount, "", "The source funds, e.g. 10nhash")
	cmd.Flags().String(FlagTarget, "", "The target account")
	cmd.Flags().String(FlagTargetAmount, "", "The target funds, e.g. 10nhash")
	cmd.Flags().String(FlagExternalID, "", "The external id")
	cmd.Flags().String(FlagFile, "", "a json file of a Tx with a MsgCreatePaymentRequest")

	cmd.MarkFlagsOneRequired(FlagFile, flags.FlagFrom, FlagSource)

	AddUseArgs(cmd,
		ReqSignerUse(FlagSource),
		OptFlagUse(FlagSourceAmount, "source amount"),
		UseFlagsBreak,
		OptFlagUse(FlagTarget, "target"),
		OptFlagUse(FlagTargetAmount, "target amount"),
		OptFlagUse(FlagExternalID, "external id"),
		UseFlagsBreak,
		OptFlagUse(FlagFile, "filename"),
	)
	AddUseDetails(cmd, ReqSignerDesc(FlagSource), MsgFileDesc(&exchange.MsgCreatePaymentRequest{}))

	cmd.Args = cobra.NoArgs
}

// MakeMsgCreatePayment reads all the SetupCmdTxCreatePayment flags and creates the desired Msg.
// Satisfies the msgMaker type.
func MakeMsgCreatePayment(clientCtx client.Context, flagSet *pflag.FlagSet, _ []string) (*exchange.MsgCreatePaymentRequest, error) {
	msg := &exchange.MsgCreatePaymentRequest{}

	errs := make([]error, 6)
	msg.Payment, errs[0] = ReadPaymentFromFileFlag(clientCtx, flagSet)
	msg.Payment.Source, errs[1] = ReadAddrFlagOrFromOrDefault(clientCtx, flagSet, FlagSource, msg.Payment.Source)
	msg.Payment.SourceAmount, errs[2] = ReadCoinsFlagOrDefault(flagSet, FlagSourceAmount, msg.Payment.SourceAmount)
	msg.Payment.Target, errs[3] = ReadFlagStringOrDefault(flagSet, FlagTarget, msg.Payment.Target)
	msg.Payment.TargetAmount, errs[4] = ReadCoinsFlagOrDefault(flagSet, FlagTargetAmount, msg.Payment.TargetAmount)
	msg.Payment.ExternalId, errs[5] = ReadFlagStringOrDefault(flagSet, FlagExternalID, msg.Payment.ExternalId)

	return msg, errors.Join(errs...)
}

// SetupCmdTxAcceptPayment adds all the flags needed for MakeMsgAcceptPayment.
func SetupCmdTxAcceptPayment(cmd *cobra.Command) {
	cmd.Flags().String(FlagSource, "", "The source account")
	cmd.Flags().String(FlagSourceAmount, "", "The source funds, e.g. 10nhash")
	cmd.Flags().String(FlagTarget, "", "The target account (defaults to --from account)")
	cmd.Flags().String(FlagTargetAmount, "", "The target funds, e.g. 10nhash")
	cmd.Flags().String(FlagExternalID, "", "The external id")
	cmd.Flags().String(FlagFile, "", "a json file of a Tx with a MsgAcceptPaymentRequest")

	cmd.MarkFlagsOneRequired(FlagFile, flags.FlagFrom, FlagTarget)

	AddUseArgs(cmd,
		OptFlagUse(FlagSource, "source"),
		OptFlagUse(FlagSourceAmount, "source amount"),
		UseFlagsBreak,
		ReqSignerUse(FlagTarget),
		OptFlagUse(FlagTargetAmount, "target amount"),
		OptFlagUse(FlagExternalID, "external id"),
		UseFlagsBreak,
		OptFlagUse(FlagFile, "filename"),
	)
	AddUseDetails(cmd, ReqSignerDesc(FlagTarget), MsgFileDesc(&exchange.MsgAcceptPaymentRequest{}))

	cmd.Args = cobra.NoArgs
}

// MakeMsgAcceptPayment reads all the SetupCmdTxAcceptPayment flags and creates the desired Msg.
// Satisfies the msgMaker type.
func MakeMsgAcceptPayment(clientCtx client.Context, flagSet *pflag.FlagSet, _ []string) (*exchange.MsgAcceptPaymentRequest, error) {
	msg := &exchange.MsgAcceptPaymentRequest{}

	errs := make([]error, 6)
	msg.Payment, errs[0] = ReadPaymentFromFileFlag(clientCtx, flagSet)
	msg.Payment.Source, errs[1] = ReadFlagStringOrDefault(flagSet, FlagSource, msg.Payment.Source)
	msg.Payment.SourceAmount, errs[2] = ReadCoinsFlagOrDefault(flagSet, FlagSourceAmount, msg.Payment.SourceAmount)
	msg.Payment.Target, errs[3] = ReadAddrFlagOrFromOrDefault(clientCtx, flagSet, FlagTarget, msg.Payment.Target)
	msg.Payment.TargetAmount, errs[4] = ReadCoinsFlagOrDefault(flagSet, FlagTargetAmount, msg.Payment.TargetAmount)
	msg.Payment.ExternalId, errs[5] = ReadFlagStringOrDefault(flagSet, FlagExternalID, msg.Payment.ExternalId)

	return msg, errors.Join(errs...)
}

// SetupCmdTxRejectPayment adds all the flags needed for MakeMsgRejectPayment.
func SetupCmdTxRejectPayment(cmd *cobra.Command) {
	cmd.Flags().String(FlagTarget, "", "The target account (defaults to --from account)")
	cmd.Flags().String(FlagSource, "", "The source account")
	cmd.Flags().String(FlagExternalID, "", "The external id")

	cmd.MarkFlagsOneRequired(flags.FlagFrom, FlagTarget)
	MarkFlagsRequired(cmd, FlagSource)

	AddUseArgs(cmd,
		ReqSignerUse(FlagTarget),
		ReqFlagUse(FlagSource, "source"),
		OptFlagUse(FlagExternalID, "external id"),
	)
	AddUseDetails(cmd, ReqSignerDesc(FlagTarget))

	cmd.Args = cobra.NoArgs
}

// MakeMsgRejectPayment reads all the SetupCmdTxRejectPayment flags and creates the desired Msg.
// Satisfies the msgMaker type.
func MakeMsgRejectPayment(clientCtx client.Context, flagSet *pflag.FlagSet, _ []string) (*exchange.MsgRejectPaymentRequest, error) {
	msg := &exchange.MsgRejectPaymentRequest{}

	errs := make([]error, 3)
	msg.Target, errs[0] = ReadAddrFlagOrFrom(clientCtx, flagSet, FlagTarget)
	msg.Source, errs[1] = flagSet.GetString(FlagSource)
	msg.ExternalId, errs[2] = flagSet.GetString(FlagExternalID)

	return msg, errors.Join(errs...)
}

// SetupCmdTxRejectPayments adds all the flags needed for MakeMsgRejectPayments.
func SetupCmdTxRejectPayments(cmd *cobra.Command) {
	cmd.Flags().String(FlagTarget, "", "The target account (defaults to --from account)")
	cmd.Flags().StringSlice(FlagSources, nil, "The source accounts (repeatable, required)")

	cmd.MarkFlagsOneRequired(flags.FlagFrom, FlagTarget)
	MarkFlagsRequired(cmd, FlagSources)

	AddUseArgs(cmd,
		ReqSignerUse(FlagTarget),
		ReqFlagUse(FlagSources, "sources"),
	)
	AddUseDetails(cmd, ReqSignerDesc(FlagTarget), RepeatableDesc)

	cmd.Args = cobra.NoArgs
}

// MakeMsgRejectPayments reads all the SetupCmdTxRejectPayments flags and creates the desired Msg.
// Satisfies the msgMaker type.
func MakeMsgRejectPayments(clientCtx client.Context, flagSet *pflag.FlagSet, _ []string) (*exchange.MsgRejectPaymentsRequest, error) {
	msg := &exchange.MsgRejectPaymentsRequest{}

	errs := make([]error, 2)
	msg.Target, errs[0] = ReadAddrFlagOrFrom(clientCtx, flagSet, FlagTarget)
	msg.Sources, errs[1] = flagSet.GetStringSlice(FlagSources)

	return msg, errors.Join(errs...)
}

// SetupCmdTxCancelPayments adds all the flags needed for MakeMsgCancelPayments.
func SetupCmdTxCancelPayments(cmd *cobra.Command) {
	cmd.Flags().String(FlagSource, "", "The source account (defaults to --from account)")
	cmd.Flags().StringSlice(FlagExternalIDs, nil, "The external ids (repeatable, required)")
	cmd.Flags().Bool(FlagEmptyExternalID, false, "Include an empty string in the external ids")

	cmd.MarkFlagsOneRequired(flags.FlagFrom, FlagSource)
	MarkFlagsRequired(cmd, FlagExternalIDs)

	AddUseArgs(cmd,
		ReqSignerUse(FlagSource),
		ReqFlagUse(FlagExternalIDs, "external ids"),
		OptFlagUse(FlagEmptyExternalID, ""),
	)
	AddUseDetails(cmd, ReqSignerDesc(FlagSource), RepeatableDesc)

	cmd.Args = cobra.NoArgs
}

// MakeMsgCancelPayments reads all the SetupCmdTxCancelPayments flags and creates the desired Msg.
// Satisfies the msgMaker type.
func MakeMsgCancelPayments(clientCtx client.Context, flagSet *pflag.FlagSet, _ []string) (*exchange.MsgCancelPaymentsRequest, error) {
	msg := &exchange.MsgCancelPaymentsRequest{}

	errs := make([]error, 3)
	msg.Source, errs[0] = ReadAddrFlagOrFrom(clientCtx, flagSet, FlagSource)
	msg.ExternalIds, errs[1] = flagSet.GetStringSlice(FlagExternalIDs)
	var incEmpty bool
	incEmpty, errs[2] = flagSet.GetBool(FlagEmptyExternalID)
	if incEmpty {
		msg.ExternalIds = append(msg.ExternalIds, "")
	}

	return msg, errors.Join(errs...)
}

// SetupCmdTxChangePaymentTarget adds all the flags needed for MakeMsgChangePaymentTarget.
func SetupCmdTxChangePaymentTarget(cmd *cobra.Command) {
	cmd.Flags().String(FlagSource, "", "The source account (defaults to --from account)")
	cmd.Flags().String(FlagExternalID, "", "The external id")
	cmd.Flags().String(FlagNewTarget, "", "The new target account")

	cmd.MarkFlagsOneRequired(flags.FlagFrom, FlagSource)

	AddUseArgs(cmd,
		ReqSignerUse(FlagSource),
		OptFlagUse(FlagExternalID, "external id"),
		OptFlagUse(FlagNewTarget, "new target"),
	)
	AddUseDetails(cmd, ReqSignerDesc(FlagSource))

	cmd.Args = cobra.NoArgs
}

// MakeMsgChangePaymentTarget reads all the SetupCmdTxChangePaymentTarget flags and creates the desired Msg.
// Satisfies the msgMaker type.
func MakeMsgChangePaymentTarget(clientCtx client.Context, flagSet *pflag.FlagSet, _ []string) (*exchange.MsgChangePaymentTargetRequest, error) {
	msg := &exchange.MsgChangePaymentTargetRequest{}

	errs := make([]error, 3)
	msg.Source, errs[0] = ReadAddrFlagOrFrom(clientCtx, flagSet, FlagSource)
	msg.ExternalId, errs[1] = flagSet.GetString(FlagExternalID)
	msg.NewTarget, errs[2] = flagSet.GetString(FlagNewTarget)

	return msg, errors.Join(errs...)
}

// SetupCmdTxGovCreateMarket adds all the flags needed for MakeMsgGovCreateMarket.
func SetupCmdTxGovCreateMarket(cmd *cobra.Command) {
	cmd.Flags().String(FlagAuthority, "", "The authority address to use (defaults to the governance module account)")
	cmd.Flags().Uint32(FlagMarket, 0, "The market id")
	AddFlagsMarketDetails(cmd)
	cmd.Flags().StringSlice(FlagCreateAsk, nil, "The create-ask fee options, e.g. 10nhash (repeatable)")
	cmd.Flags().StringSlice(FlagCreateBid, nil, "The create-bid fee options, e.g. 10nhash (repeatable)")
	cmd.Flags().StringSlice(FlagSellerFlat, nil, "The seller settlement flat fee options, e.g. 10nhash (repeatable)")
	cmd.Flags().StringSlice(FlagSellerRatios, nil, "The seller settlement fee ratios, e.g. 100nhash:1nhash (repeatable)")
	cmd.Flags().StringSlice(FlagBuyerFlat, nil, "The buyer settlement flat fee options, e.g. 10nhash (repeatable)")
	cmd.Flags().StringSlice(FlagBuyerRatios, nil, "The buyer settlement fee ratios, e.g. 100nhash:1nhash (repeatable)")
	cmd.Flags().Bool(FlagAcceptingOrders, false, "The market should allow orders to be created")
	cmd.Flags().Bool(FlagAllowUserSettle, false, "The market should allow user-initiated settlement")
	cmd.Flags().StringSlice(FlagAccessGrants, nil, "The <access grants> that the market should have (repeatable)")
	cmd.Flags().StringSlice(FlagReqAttrAsk, nil, "Attributes required to create ask orders (repeatable)")
	cmd.Flags().StringSlice(FlagReqAttrBid, nil, "Attributes required to create bid orders (repeatable)")
	cmd.Flags().String(FlagProposal, "", "a json file of a Tx with a gov proposal with a MsgGovCreateMarketRequest")
	cmd.Flags().Bool(FlagAcceptingCommitments, false, "The market should allow commitments to be created")
	cmd.Flags().StringSlice(FlagCreateCommitment, nil, "The create-commitment fee options, e.g. 10nhash (repeatable)")
	cmd.Flags().Uint32(FlagBips, 0, "The commitment settlement bips (min=0, max=10,000)")
	cmd.Flags().String(FlagDenom, "", "The intermediary denom")
	cmd.Flags().StringSlice(FlagReqAttrCommitment, nil, "Attributes required to create commitments (repeatable)")

	cmd.MarkFlagsOneRequired(
		FlagMarket, FlagName, FlagDescription, FlagURL, FlagIcon,
		FlagCreateAsk, FlagCreateBid, FlagCreateCommitment,
		FlagSellerFlat, FlagSellerRatios, FlagBuyerFlat, FlagBuyerRatios,
		FlagAcceptingOrders, FlagAllowUserSettle, FlagAcceptingCommitments, FlagAccessGrants,
		FlagReqAttrAsk, FlagReqAttrBid, FlagReqAttrCommitment,
		FlagBips, FlagDenom,
		FlagProposal,
	)

	AddUseArgs(cmd,
		OptFlagUse(FlagAuthority, "authority"),
		OptFlagUse(FlagMarket, "market id"),
		UseFlagsBreak,
		OptFlagUse(FlagName, "name"),
		OptFlagUse(FlagDescription, "description"),
		OptFlagUse(FlagURL, "website url"),
		OptFlagUse(FlagIcon, "icon uri"),
		UseFlagsBreak,
		OptFlagUse(FlagCreateAsk, "coins"),
		OptFlagUse(FlagCreateBid, "coins"),
		OptFlagUse(FlagCreateCommitment, "coins"),
		UseFlagsBreak,
		OptFlagUse(FlagSellerFlat, "coins"),
		OptFlagUse(FlagSellerRatios, "fee ratios"),
		UseFlagsBreak,
		OptFlagUse(FlagBuyerFlat, "coins"),
		OptFlagUse(FlagBuyerRatios, "fee ratios"),
		UseFlagsBreak,
		OptFlagUse(FlagAcceptingOrders, ""),
		OptFlagUse(FlagAllowUserSettle, ""),
		OptFlagUse(FlagAcceptingCommitments, ""),
		UseFlagsBreak,
		OptFlagUse(FlagAccessGrants, "access grants"),
		UseFlagsBreak,
		OptFlagUse(FlagReqAttrAsk, "attrs"),
		OptFlagUse(FlagReqAttrBid, "attrs"),
		OptFlagUse(FlagReqAttrCommitment, "attrs"),
		UseFlagsBreak,
		OptFlagUse(FlagBips, "bips"),
		OptFlagUse(FlagDenom, "denom"),
		UseFlagsBreak,
		OptFlagUse(FlagProposal, "json filename"),
	)
	AddUseDetails(cmd,
		AuthorityDesc, RepeatableDesc, AccessGrantsDesc, FeeRatioDesc,
		ProposalFileDesc(&exchange.MsgGovCreateMarketRequest{}),
	)

	cmd.Args = cobra.NoArgs
}

// MakeMsgGovCreateMarket reads all the SetupCmdTxGovCreateMarket flags and creates the desired Msg.
// Satisfies the msgMaker type.
func MakeMsgGovCreateMarket(clientCtx client.Context, flagSet *pflag.FlagSet, _ []string) (*exchange.MsgGovCreateMarketRequest, error) {
	var msg *exchange.MsgGovCreateMarketRequest

	errs := make([]error, 20)
	msg, errs[0] = ReadMsgGovCreateMarketRequestFromProposalFlag(clientCtx, flagSet)
	msg.Authority, errs[1] = ReadFlagAuthorityOrDefault(flagSet, msg.Authority)
	msg.Market.MarketId, errs[2] = ReadFlagUint32OrDefault(flagSet, FlagMarket, msg.Market.MarketId)
	msg.Market.MarketDetails, errs[3] = ReadFlagsMarketDetails(flagSet, msg.Market.MarketDetails)
	msg.Market.FeeCreateAskFlat, errs[4] = ReadFlatFeeFlag(flagSet, FlagCreateAsk, msg.Market.FeeCreateAskFlat)
	msg.Market.FeeCreateBidFlat, errs[5] = ReadFlatFeeFlag(flagSet, FlagCreateBid, msg.Market.FeeCreateBidFlat)
	msg.Market.FeeCreateCommitmentFlat, errs[6] = ReadFlatFeeFlag(flagSet, FlagCreateCommitment, msg.Market.FeeCreateCommitmentFlat)
	msg.Market.FeeSellerSettlementFlat, errs[7] = ReadFlatFeeFlag(flagSet, FlagSellerFlat, msg.Market.FeeSellerSettlementFlat)
	msg.Market.FeeSellerSettlementRatios, errs[8] = ReadFeeRatiosFlag(flagSet, FlagSellerRatios, msg.Market.FeeSellerSettlementRatios)
	msg.Market.FeeBuyerSettlementFlat, errs[9] = ReadFlatFeeFlag(flagSet, FlagBuyerFlat, msg.Market.FeeBuyerSettlementFlat)
	msg.Market.FeeBuyerSettlementRatios, errs[10] = ReadFeeRatiosFlag(flagSet, FlagBuyerRatios, msg.Market.FeeBuyerSettlementRatios)
	msg.Market.AcceptingOrders, errs[11] = ReadFlagBoolOrDefault(flagSet, FlagAcceptingOrders, msg.Market.AcceptingOrders)
	msg.Market.AllowUserSettlement, errs[12] = ReadFlagBoolOrDefault(flagSet, FlagAllowUserSettle, msg.Market.AllowUserSettlement)
	msg.Market.AcceptingCommitments, errs[13] = ReadFlagBoolOrDefault(flagSet, FlagAcceptingCommitments, msg.Market.AcceptingCommitments)
	msg.Market.AccessGrants, errs[14] = ReadAccessGrantsFlag(flagSet, FlagAccessGrants, msg.Market.AccessGrants)
	msg.Market.ReqAttrCreateAsk, errs[15] = ReadFlagStringSliceOrDefault(flagSet, FlagReqAttrAsk, msg.Market.ReqAttrCreateAsk)
	msg.Market.ReqAttrCreateBid, errs[16] = ReadFlagStringSliceOrDefault(flagSet, FlagReqAttrBid, msg.Market.ReqAttrCreateBid)
	msg.Market.ReqAttrCreateCommitment, errs[17] = ReadFlagStringSliceOrDefault(flagSet, FlagReqAttrCommitment, msg.Market.ReqAttrCreateCommitment)
	msg.Market.CommitmentSettlementBips, errs[18] = ReadFlagUint32OrDefault(flagSet, FlagBips, msg.Market.CommitmentSettlementBips)
	msg.Market.IntermediaryDenom, errs[19] = ReadFlagStringOrDefault(flagSet, FlagDenom, msg.Market.IntermediaryDenom)

	return msg, errors.Join(errs...)
}

// SetupCmdTxGovManageFees adds all the flags needed for MakeMsgGovManageFees.
func SetupCmdTxGovManageFees(cmd *cobra.Command) {
	cmd.Flags().String(FlagAuthority, "", "The authority address to use (defaults to the governance module account)")
	cmd.Flags().Uint32(FlagMarket, 0, "The market id (required)")
	cmd.Flags().StringSlice(FlagAskAdd, nil, "Create-ask flat fee options to add, e.g. 10nhash (repeatable)")
	cmd.Flags().StringSlice(FlagAskRemove, nil, "Create-ask flat fee options to remove, e.g. 10nhash (repeatable)")
	cmd.Flags().StringSlice(FlagBidAdd, nil, "Create-bid flat fee options to add, e.g. 10nhash (repeatable)")
	cmd.Flags().StringSlice(FlagBidRemove, nil, "Create-bid flat fee options to remove, e.g. 10nhash (repeatable)")
	cmd.Flags().StringSlice(FlagSellerFlatAdd, nil, "Seller settlement flat fee options to add, e.g. 10nhash (repeatable)")
	cmd.Flags().StringSlice(FlagSellerFlatRemove, nil, "Seller settlement flat fee options to remove, e.g. 10nhash (repeatable)")
	cmd.Flags().StringSlice(FlagSellerRatiosAdd, nil, "Seller settlement fee ratios to add, e.g. 100nhash:1nhash (repeatable)")
	cmd.Flags().StringSlice(FlagSellerRatiosRemove, nil, "Seller settlement fee ratios to remove, e.g. 100nhash:1nhash (repeatable)")
	cmd.Flags().StringSlice(FlagBuyerFlatAdd, nil, "Buyer settlement flat fee options to add, e.g. 10nhash (repeatable)")
	cmd.Flags().StringSlice(FlagBuyerFlatRemove, nil, "Buyer settlement flat fee options to remove, e.g. 10nhash (repeatable)")
	cmd.Flags().StringSlice(FlagBuyerRatiosAdd, nil, "Seller settlement fee ratios to add, e.g. 100nhash:1nhash (repeatable)")
	cmd.Flags().StringSlice(FlagBuyerRatiosRemove, nil, "Seller settlement fee ratios to remove, e.g. 100nhash:1nhash (repeatable)")
	cmd.Flags().StringSlice(FlagCommitmentAdd, nil, "Create-commitment flat fee options to add, e.g. 10nhash (repeatable)")
	cmd.Flags().StringSlice(FlagCommitmentRemove, nil, "Create-commitment flat fee options to remove, e.g. 10nhash (repeatable)")
	cmd.Flags().Uint32(FlagBips, 0, "Commitment settlement bips")
	cmd.Flags().Bool(FlagUnsetBips, false, "Unset the commitment settlement bips")
	cmd.Flags().String(FlagProposal, "", "a json file of a Tx with a gov proposal with a MsgGovManageFeesRequest")

	MarkFlagsRequired(cmd, FlagMarket)
	cmd.MarkFlagsOneRequired(
		FlagAskAdd, FlagAskRemove, FlagBidAdd, FlagBidRemove,
		FlagSellerFlatAdd, FlagSellerFlatRemove, FlagSellerRatiosAdd, FlagSellerRatiosRemove,
		FlagBuyerFlatAdd, FlagBuyerFlatRemove, FlagBuyerRatiosAdd, FlagBuyerRatiosRemove,
		FlagCommitmentAdd, FlagCommitmentRemove, FlagBips, FlagUnsetBips,
		FlagProposal,
	)

	AddUseArgs(cmd,
		ReqFlagUse(FlagMarket, "market id"),
		OptFlagUse(FlagAuthority, "authority"),
		UseFlagsBreak,
		OptFlagUse(FlagAskAdd, "coins"),
		OptFlagUse(FlagAskRemove, "coins"),
		UseFlagsBreak,
		OptFlagUse(FlagBidAdd, "coins"),
		OptFlagUse(FlagBidRemove, "coins"),
		UseFlagsBreak,
		OptFlagUse(FlagCommitmentAdd, "coins"),
		OptFlagUse(FlagCommitmentRemove, "coins"),
		UseFlagsBreak,
		OptFlagUse(FlagSellerFlatAdd, "coins"),
		OptFlagUse(FlagSellerFlatRemove, "coins"),
		UseFlagsBreak,
		OptFlagUse(FlagSellerRatiosAdd, "fee ratios"),
		OptFlagUse(FlagSellerRatiosRemove, "fee ratios"),
		UseFlagsBreak,
		OptFlagUse(FlagBuyerFlatAdd, "coins"),
		OptFlagUse(FlagBuyerFlatRemove, "coins"),
		UseFlagsBreak,
		OptFlagUse(FlagBuyerRatiosAdd, "fee ratios"),
		OptFlagUse(FlagBuyerRatiosRemove, "fee ratios"),
		UseFlagsBreak,
		OptFlagUse(FlagBips, "bips"),
		OptFlagUse(FlagUnsetBips, ""),
		UseFlagsBreak,
		OptFlagUse(FlagProposal, "json filename"),
	)
	AddUseDetails(cmd,
		AuthorityDesc, RepeatableDesc, FeeRatioDesc,
		ProposalFileDesc(&exchange.MsgGovManageFeesRequest{}),
	)

	cmd.Args = cobra.NoArgs
}

// MakeMsgGovManageFees reads all the SetupCmdTxGovManageFees flags and creates the desired Msg.
// Satisfies the msgMaker type.
func MakeMsgGovManageFees(clientCtx client.Context, flagSet *pflag.FlagSet, _ []string) (*exchange.MsgGovManageFeesRequest, error) {
	var msg *exchange.MsgGovManageFeesRequest

	errs := make([]error, 19)
	msg, errs[0] = ReadMsgGovManageFeesRequestFromProposalFlag(clientCtx, flagSet)
	msg.Authority, errs[1] = ReadFlagAuthorityOrDefault(flagSet, msg.Authority)
	msg.MarketId, errs[2] = ReadFlagUint32OrDefault(flagSet, FlagMarket, msg.MarketId)
	msg.AddFeeCreateAskFlat, errs[3] = ReadFlatFeeFlag(flagSet, FlagAskAdd, msg.AddFeeCreateAskFlat)
	msg.RemoveFeeCreateAskFlat, errs[4] = ReadFlatFeeFlag(flagSet, FlagAskRemove, msg.RemoveFeeCreateAskFlat)
	msg.AddFeeCreateBidFlat, errs[5] = ReadFlatFeeFlag(flagSet, FlagBidAdd, msg.AddFeeCreateBidFlat)
	msg.RemoveFeeCreateBidFlat, errs[6] = ReadFlatFeeFlag(flagSet, FlagBidRemove, msg.RemoveFeeCreateBidFlat)
	msg.AddFeeCreateCommitmentFlat, errs[7] = ReadFlatFeeFlag(flagSet, FlagCommitmentAdd, msg.AddFeeCreateCommitmentFlat)
	msg.RemoveFeeCreateCommitmentFlat, errs[8] = ReadFlatFeeFlag(flagSet, FlagCommitmentRemove, msg.RemoveFeeCreateCommitmentFlat)
	msg.AddFeeSellerSettlementFlat, errs[9] = ReadFlatFeeFlag(flagSet, FlagSellerFlatAdd, msg.AddFeeSellerSettlementFlat)
	msg.RemoveFeeSellerSettlementFlat, errs[10] = ReadFlatFeeFlag(flagSet, FlagSellerFlatRemove, msg.RemoveFeeSellerSettlementFlat)
	msg.AddFeeSellerSettlementRatios, errs[11] = ReadFeeRatiosFlag(flagSet, FlagSellerRatiosAdd, msg.AddFeeSellerSettlementRatios)
	msg.RemoveFeeSellerSettlementRatios, errs[12] = ReadFeeRatiosFlag(flagSet, FlagSellerRatiosRemove, msg.RemoveFeeSellerSettlementRatios)
	msg.AddFeeBuyerSettlementFlat, errs[13] = ReadFlatFeeFlag(flagSet, FlagBuyerFlatAdd, msg.AddFeeBuyerSettlementFlat)
	msg.RemoveFeeBuyerSettlementFlat, errs[14] = ReadFlatFeeFlag(flagSet, FlagBuyerFlatRemove, msg.RemoveFeeBuyerSettlementFlat)
	msg.AddFeeBuyerSettlementRatios, errs[15] = ReadFeeRatiosFlag(flagSet, FlagBuyerRatiosAdd, msg.AddFeeBuyerSettlementRatios)
	msg.RemoveFeeBuyerSettlementRatios, errs[16] = ReadFeeRatiosFlag(flagSet, FlagBuyerRatiosRemove, msg.RemoveFeeBuyerSettlementRatios)
	msg.SetFeeCommitmentSettlementBips, errs[17] = ReadFlagUint32OrDefault(flagSet, FlagBips, msg.SetFeeCommitmentSettlementBips)
	msg.UnsetFeeCommitmentSettlementBips, errs[18] = ReadFlagBoolOrDefault(flagSet, FlagUnsetBips, msg.UnsetFeeCommitmentSettlementBips)

	return msg, errors.Join(errs...)
}

// SetupCmdTxGovCloseMarket adds all the flags needed for MakeMsgGovCloseMarket.
func SetupCmdTxGovCloseMarket(cmd *cobra.Command) {
	cmd.Flags().String(FlagAuthority, "", "The authority address to use (defaults to the governance module account)")
	cmd.Flags().Uint32(FlagMarket, 0, "The market id (required)")

	MarkFlagsRequired(cmd, FlagMarket)

	AddUseArgs(cmd,
		ReqFlagUse(FlagMarket, "market id"),
		OptFlagUse(FlagAuthority, "authority"),
	)
	AddUseDetails(cmd, AuthorityDesc)

	cmd.Args = cobra.NoArgs
}

// MakeMsgGovCloseMarket reads all the SetupCmdTxGovCloseMarket flags and creates the desired Msg.
// Satisfies the msgMaker type.
func MakeMsgGovCloseMarket(_ client.Context, flagSet *pflag.FlagSet, _ []string) (*exchange.MsgGovCloseMarketRequest, error) {
	msg := &exchange.MsgGovCloseMarketRequest{}

	errs := make([]error, 2)
	msg.Authority, errs[0] = ReadFlagAuthority(flagSet)
	msg.MarketId, errs[1] = flagSet.GetUint32(FlagMarket)

	return msg, errors.Join(errs...)
}

// SetupCmdTxUpdateParams adds all the flags needed for MakeMsgUpdateParams.
func SetupCmdTxUpdateParams(cmd *cobra.Command) {
	cmd.Flags().String(FlagAuthority, "", "The authority address to use (defaults to the governance module account)")
	cmd.Flags().Uint32(FlagDefault, 0, "The default split (required)")
	cmd.Flags().StringSlice(FlagSplit, nil, "The denom-splits (repeatable)")

	MarkFlagsRequired(cmd, FlagDefault)

	AddUseArgs(cmd,
		ReqFlagUse(FlagDefault, "amount"),
		OptFlagUse(FlagSplit, "splits"),
		OptFlagUse(FlagAuthority, "authority"),
	)
	AddUseDetails(cmd,
		AuthorityDesc,
		RepeatableDesc,
		`A <split> has the format "<denom>:<amount>".
An <amount> is in basis points and is limited to 0 to 10,000 (both inclusive).

Example <split>: nhash:500`,
	)

	cmd.Args = cobra.NoArgs
}

// MakeMsgUpdateParams reads all the SetupCmdTxUpdateParams flags and creates the desired Msg.
// Satisfies the msgMaker type.
func MakeMsgUpdateParams(_ client.Context, flagSet *pflag.FlagSet, _ []string) (*exchange.MsgUpdateParamsRequest, error) {
	msg := &exchange.MsgUpdateParamsRequest{}

	errs := make([]error, 3)
	msg.Authority, errs[0] = ReadFlagAuthority(flagSet)
	msg.Params.DefaultSplit, errs[1] = flagSet.GetUint32(FlagDefault)
	msg.Params.DenomSplits, errs[2] = ReadSplitsFlag(flagSet, FlagSplit)

	return msg, errors.Join(errs...)
}
