mirror of
				https://github.com/0glabs/0g-chain.git
				synced 2025-10-31 14:47:29 +00:00 
			
		
		
		
	Additional Hard module queries (#884)
* unsynced deposits/borrows queriers * cli queriers * rest querier * implement interest factor querier * querier cli * querier rest * fix typo in comment
This commit is contained in:
		
							parent
							
								
									99095a8fc3
								
							
						
					
					
						commit
						656c5a80b8
					
				| @ -38,11 +38,14 @@ func GetQueryCmd(queryRoute string, cdc *codec.Codec) *cobra.Command { | |||||||
| 		queryParamsCmd(queryRoute, cdc), | 		queryParamsCmd(queryRoute, cdc), | ||||||
| 		queryModAccountsCmd(queryRoute, cdc), | 		queryModAccountsCmd(queryRoute, cdc), | ||||||
| 		queryDepositsCmd(queryRoute, cdc), | 		queryDepositsCmd(queryRoute, cdc), | ||||||
|  | 		queryUnsyncedDepositsCmd(queryRoute, cdc), | ||||||
| 		queryTotalDepositedCmd(queryRoute, cdc), | 		queryTotalDepositedCmd(queryRoute, cdc), | ||||||
| 		queryBorrowsCmd(queryRoute, cdc), | 		queryBorrowsCmd(queryRoute, cdc), | ||||||
|  | 		queryUnsyncedBorrowsCmd(queryRoute, cdc), | ||||||
| 		queryTotalBorrowedCmd(queryRoute, cdc), | 		queryTotalBorrowedCmd(queryRoute, cdc), | ||||||
| 		queryInterestRateCmd(queryRoute, cdc), | 		queryInterestRateCmd(queryRoute, cdc), | ||||||
| 		queryReserves(queryRoute, cdc), | 		queryReserves(queryRoute, cdc), | ||||||
|  | 		queryInterestFactorsCmd(queryRoute, cdc), | ||||||
| 	)...) | 	)...) | ||||||
| 
 | 
 | ||||||
| 	return hardQueryCmd | 	return hardQueryCmd | ||||||
| @ -115,6 +118,66 @@ func queryModAccountsCmd(queryRoute string, cdc *codec.Codec) *cobra.Command { | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | func queryUnsyncedDepositsCmd(queryRoute string, cdc *codec.Codec) *cobra.Command { | ||||||
|  | 	cmd := &cobra.Command{ | ||||||
|  | 		Use:   "unsynced-deposits", | ||||||
|  | 		Short: "query hard module unsynced deposits with optional filters", | ||||||
|  | 		Long: strings.TrimSpace(`query for all hard module unsynced deposits or a specific unsynced deposit using flags: | ||||||
|  | 
 | ||||||
|  | 		Example: | ||||||
|  | 		$ kvcli q hard unsynced-deposits | ||||||
|  | 		$ kvcli q hard unsynced-deposits --owner kava1l0xsq2z7gqd7yly0g40y5836g0appumark77ny --denom bnb | ||||||
|  | 		$ kvcli q hard unsynced-deposits --denom ukava | ||||||
|  | 		$ kvcli q hard unsynced-deposits --denom btcb`, | ||||||
|  | 		), | ||||||
|  | 		Args: cobra.NoArgs, | ||||||
|  | 		RunE: func(cmd *cobra.Command, args []string) error { | ||||||
|  | 			cliCtx := context.NewCLIContext().WithCodec(cdc) | ||||||
|  | 
 | ||||||
|  | 			var owner sdk.AccAddress | ||||||
|  | 
 | ||||||
|  | 			ownerBech := viper.GetString(flagOwner) | ||||||
|  | 			denom := viper.GetString(flagDenom) | ||||||
|  | 
 | ||||||
|  | 			if len(ownerBech) != 0 { | ||||||
|  | 				depositOwner, err := sdk.AccAddressFromBech32(ownerBech) | ||||||
|  | 				if err != nil { | ||||||
|  | 					return err | ||||||
|  | 				} | ||||||
|  | 				owner = depositOwner | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			page := viper.GetInt(flags.FlagPage) | ||||||
|  | 			limit := viper.GetInt(flags.FlagLimit) | ||||||
|  | 
 | ||||||
|  | 			params := types.NewQueryUnsyncedDepositsParams(page, limit, denom, owner) | ||||||
|  | 			bz, err := cdc.MarshalJSON(params) | ||||||
|  | 			if err != nil { | ||||||
|  | 				return err | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			route := fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryGetUnsyncedDeposits) | ||||||
|  | 			res, height, err := cliCtx.QueryWithData(route, bz) | ||||||
|  | 			if err != nil { | ||||||
|  | 				return err | ||||||
|  | 			} | ||||||
|  | 			cliCtx = cliCtx.WithHeight(height) | ||||||
|  | 
 | ||||||
|  | 			var deposits types.Deposits | ||||||
|  | 			if err := cdc.UnmarshalJSON(res, &deposits); err != nil { | ||||||
|  | 				return fmt.Errorf("failed to unmarshal deposits: %w", err) | ||||||
|  | 			} | ||||||
|  | 			return cliCtx.PrintOutput(deposits) | ||||||
|  | 		}, | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	cmd.Flags().Int(flags.FlagPage, 1, "pagination page to query for") | ||||||
|  | 	cmd.Flags().Int(flags.FlagLimit, 100, "pagination limit (max 100)") | ||||||
|  | 	cmd.Flags().String(flagOwner, "", "(optional) filter for unsynced deposits by owner address") | ||||||
|  | 	cmd.Flags().String(flagDenom, "", "(optional) filter for unsynced deposits by denom") | ||||||
|  | 	return cmd | ||||||
|  | } | ||||||
|  | 
 | ||||||
| func queryDepositsCmd(queryRoute string, cdc *codec.Codec) *cobra.Command { | func queryDepositsCmd(queryRoute string, cdc *codec.Codec) *cobra.Command { | ||||||
| 	cmd := &cobra.Command{ | 	cmd := &cobra.Command{ | ||||||
| 		Use:   "deposits", | 		Use:   "deposits", | ||||||
| @ -175,6 +238,64 @@ func queryDepositsCmd(queryRoute string, cdc *codec.Codec) *cobra.Command { | |||||||
| 	return cmd | 	return cmd | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | func queryUnsyncedBorrowsCmd(queryRoute string, cdc *codec.Codec) *cobra.Command { | ||||||
|  | 	cmd := &cobra.Command{ | ||||||
|  | 		Use:   "unsynced-borrows", | ||||||
|  | 		Short: "query hard module unsynced borrows with optional filters", | ||||||
|  | 		Long: strings.TrimSpace(`query for all hard module unsynced borrows or a specific unsynced borrow using flags: | ||||||
|  | 
 | ||||||
|  | 		Example: | ||||||
|  | 		$ kvcli q hard unsynced-borrows | ||||||
|  | 		$ kvcli q hard unsynced-borrows --owner kava1l0xsq2z7gqd7yly0g40y5836g0appumark77ny | ||||||
|  | 		$ kvcli q hard unsynced-borrows --denom bnb`, | ||||||
|  | 		), | ||||||
|  | 		Args: cobra.NoArgs, | ||||||
|  | 		RunE: func(cmd *cobra.Command, args []string) error { | ||||||
|  | 			cliCtx := context.NewCLIContext().WithCodec(cdc) | ||||||
|  | 
 | ||||||
|  | 			var owner sdk.AccAddress | ||||||
|  | 
 | ||||||
|  | 			ownerBech := viper.GetString(flagOwner) | ||||||
|  | 			denom := viper.GetString(flagDenom) | ||||||
|  | 
 | ||||||
|  | 			if len(ownerBech) != 0 { | ||||||
|  | 				borrowOwner, err := sdk.AccAddressFromBech32(ownerBech) | ||||||
|  | 				if err != nil { | ||||||
|  | 					return err | ||||||
|  | 				} | ||||||
|  | 				owner = borrowOwner | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			page := viper.GetInt(flags.FlagPage) | ||||||
|  | 			limit := viper.GetInt(flags.FlagLimit) | ||||||
|  | 
 | ||||||
|  | 			params := types.NewQueryUnsyncedBorrowsParams(page, limit, owner, denom) | ||||||
|  | 			bz, err := cdc.MarshalJSON(params) | ||||||
|  | 			if err != nil { | ||||||
|  | 				return err | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			route := fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryGetUnsyncedBorrows) | ||||||
|  | 			res, height, err := cliCtx.QueryWithData(route, bz) | ||||||
|  | 			if err != nil { | ||||||
|  | 				return err | ||||||
|  | 			} | ||||||
|  | 			cliCtx = cliCtx.WithHeight(height) | ||||||
|  | 
 | ||||||
|  | 			var borrows types.Borrows | ||||||
|  | 			if err := cdc.UnmarshalJSON(res, &borrows); err != nil { | ||||||
|  | 				return fmt.Errorf("failed to unmarshal borrows: %w", err) | ||||||
|  | 			} | ||||||
|  | 			return cliCtx.PrintOutput(borrows) | ||||||
|  | 		}, | ||||||
|  | 	} | ||||||
|  | 	cmd.Flags().Int(flags.FlagPage, 1, "pagination page to query for") | ||||||
|  | 	cmd.Flags().Int(flags.FlagLimit, 100, "pagination limit (max 100)") | ||||||
|  | 	cmd.Flags().String(flagOwner, "", "(optional) filter for unsynced borrows by owner address") | ||||||
|  | 	cmd.Flags().String(flagDenom, "", "(optional) filter for unsynced borrows by denom") | ||||||
|  | 	return cmd | ||||||
|  | } | ||||||
|  | 
 | ||||||
| func queryBorrowsCmd(queryRoute string, cdc *codec.Codec) *cobra.Command { | func queryBorrowsCmd(queryRoute string, cdc *codec.Codec) *cobra.Command { | ||||||
| 	cmd := &cobra.Command{ | 	cmd := &cobra.Command{ | ||||||
| 		Use:   "borrows", | 		Use:   "borrows", | ||||||
| @ -404,3 +525,46 @@ func queryReserves(queryRoute string, cdc *codec.Codec) *cobra.Command { | |||||||
| 	cmd.Flags().String(flagDenom, "", "(optional) filter reserve coins by denom") | 	cmd.Flags().String(flagDenom, "", "(optional) filter reserve coins by denom") | ||||||
| 	return cmd | 	return cmd | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | func queryInterestFactorsCmd(queryRoute string, cdc *codec.Codec) *cobra.Command { | ||||||
|  | 	cmd := &cobra.Command{ | ||||||
|  | 		Use:   "interest-factors", | ||||||
|  | 		Short: "get current global interest factors", | ||||||
|  | 		Long: strings.TrimSpace(`get current global interest factors: | ||||||
|  | 
 | ||||||
|  | 		Example: | ||||||
|  | 		$ kvcli q hard interest-factors | ||||||
|  | 		$ kvcli q hard interest-factors --denom bnb`, | ||||||
|  | 		), | ||||||
|  | 		Args: cobra.NoArgs, | ||||||
|  | 		RunE: func(cmd *cobra.Command, args []string) error { | ||||||
|  | 			cliCtx := context.NewCLIContext().WithCodec(cdc) | ||||||
|  | 
 | ||||||
|  | 			denom := viper.GetString(flagDenom) | ||||||
|  | 
 | ||||||
|  | 			// Construct query with params
 | ||||||
|  | 			params := types.NewQueryInterestFactorsParams(denom) | ||||||
|  | 			bz, err := cdc.MarshalJSON(params) | ||||||
|  | 			if err != nil { | ||||||
|  | 				return err | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			// Execute query
 | ||||||
|  | 			route := fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryGetInterestFactors) | ||||||
|  | 			res, height, err := cliCtx.QueryWithData(route, bz) | ||||||
|  | 			if err != nil { | ||||||
|  | 				return err | ||||||
|  | 			} | ||||||
|  | 			cliCtx = cliCtx.WithHeight(height) | ||||||
|  | 
 | ||||||
|  | 			// Decode and print results
 | ||||||
|  | 			var interestFactors types.InterestFactors | ||||||
|  | 			if err := cdc.UnmarshalJSON(res, &interestFactors); err != nil { | ||||||
|  | 				return fmt.Errorf("failed to unmarshal interest factors: %w", err) | ||||||
|  | 			} | ||||||
|  | 			return cliCtx.PrintOutput(interestFactors) | ||||||
|  | 		}, | ||||||
|  | 	} | ||||||
|  | 	cmd.Flags().String(flagDenom, "", "(optional) filter interest factors by denom") | ||||||
|  | 	return cmd | ||||||
|  | } | ||||||
|  | |||||||
| @ -16,13 +16,16 @@ import ( | |||||||
| 
 | 
 | ||||||
| func registerQueryRoutes(cliCtx context.CLIContext, r *mux.Router) { | func registerQueryRoutes(cliCtx context.CLIContext, r *mux.Router) { | ||||||
| 	r.HandleFunc(fmt.Sprintf("/%s/parameters", types.ModuleName), queryParamsHandlerFn(cliCtx)).Methods("GET") | 	r.HandleFunc(fmt.Sprintf("/%s/parameters", types.ModuleName), queryParamsHandlerFn(cliCtx)).Methods("GET") | ||||||
|  | 	r.HandleFunc(fmt.Sprintf("/%s/unsynced-deposits", types.ModuleName), queryUnsyncedDepositsHandlerFn(cliCtx)).Methods("GET") | ||||||
| 	r.HandleFunc(fmt.Sprintf("/%s/deposits", types.ModuleName), queryDepositsHandlerFn(cliCtx)).Methods("GET") | 	r.HandleFunc(fmt.Sprintf("/%s/deposits", types.ModuleName), queryDepositsHandlerFn(cliCtx)).Methods("GET") | ||||||
| 	r.HandleFunc(fmt.Sprintf("/%s/total-deposited", types.ModuleName), queryTotalDepositedHandlerFn(cliCtx)).Methods("GET") | 	r.HandleFunc(fmt.Sprintf("/%s/total-deposited", types.ModuleName), queryTotalDepositedHandlerFn(cliCtx)).Methods("GET") | ||||||
| 	r.HandleFunc(fmt.Sprintf("/%s/accounts", types.ModuleName), queryModAccountsHandlerFn(cliCtx)).Methods("GET") | 	r.HandleFunc(fmt.Sprintf("/%s/accounts", types.ModuleName), queryModAccountsHandlerFn(cliCtx)).Methods("GET") | ||||||
|  | 	r.HandleFunc(fmt.Sprintf("/%s/unsynced-borrows", types.ModuleName), queryUnsyncedBorrowsHandlerFn(cliCtx)).Methods("GET") | ||||||
| 	r.HandleFunc(fmt.Sprintf("/%s/borrows", types.ModuleName), queryBorrowsHandlerFn(cliCtx)).Methods("GET") | 	r.HandleFunc(fmt.Sprintf("/%s/borrows", types.ModuleName), queryBorrowsHandlerFn(cliCtx)).Methods("GET") | ||||||
| 	r.HandleFunc(fmt.Sprintf("/%s/total-borrowed", types.ModuleName), queryTotalBorrowedHandlerFn(cliCtx)).Methods("GET") | 	r.HandleFunc(fmt.Sprintf("/%s/total-borrowed", types.ModuleName), queryTotalBorrowedHandlerFn(cliCtx)).Methods("GET") | ||||||
| 	r.HandleFunc(fmt.Sprintf("/%s/interest-rate", types.ModuleName), queryInterestRateHandlerFn(cliCtx)).Methods("GET") | 	r.HandleFunc(fmt.Sprintf("/%s/interest-rate", types.ModuleName), queryInterestRateHandlerFn(cliCtx)).Methods("GET") | ||||||
| 	r.HandleFunc(fmt.Sprintf("/%s/reserves", types.ModuleName), queryReservesHandlerFn(cliCtx)).Methods("GET") | 	r.HandleFunc(fmt.Sprintf("/%s/reserves", types.ModuleName), queryReservesHandlerFn(cliCtx)).Methods("GET") | ||||||
|  | 	r.HandleFunc(fmt.Sprintf("/%s/interest-factors", types.ModuleName), queryInterestFactorsHandlerFn(cliCtx)).Methods("GET") | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func queryParamsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { | func queryParamsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { | ||||||
| @ -93,6 +96,54 @@ func queryDepositsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | func queryUnsyncedDepositsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { | ||||||
|  | 	return func(w http.ResponseWriter, r *http.Request) { | ||||||
|  | 		_, page, limit, err := rest.ParseHTTPArgsWithLimit(r, 0) | ||||||
|  | 		if err != nil { | ||||||
|  | 			rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  | 		// Parse the query height
 | ||||||
|  | 		cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r) | ||||||
|  | 		if !ok { | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		var denom string | ||||||
|  | 		var owner sdk.AccAddress | ||||||
|  | 
 | ||||||
|  | 		if x := r.URL.Query().Get(RestDenom); len(x) != 0 { | ||||||
|  | 			denom = strings.TrimSpace(x) | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if x := r.URL.Query().Get(RestOwner); len(x) != 0 { | ||||||
|  | 			ownerStr := strings.ToLower(strings.TrimSpace(x)) | ||||||
|  | 			owner, err = sdk.AccAddressFromBech32(ownerStr) | ||||||
|  | 			if err != nil { | ||||||
|  | 				rest.WriteErrorResponse(w, http.StatusBadRequest, fmt.Sprintf("cannot parse address from deposit owner %s", ownerStr)) | ||||||
|  | 				return | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		params := types.NewQueryUnsyncedDepositsParams(page, limit, denom, owner) | ||||||
|  | 
 | ||||||
|  | 		bz, err := cliCtx.Codec.MarshalJSON(params) | ||||||
|  | 		if err != nil { | ||||||
|  | 			rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		route := fmt.Sprintf("custom/%s/%s", types.ModuleName, types.QueryGetUnsyncedDeposits) | ||||||
|  | 		res, height, err := cliCtx.QueryWithData(route, bz) | ||||||
|  | 		cliCtx = cliCtx.WithHeight(height) | ||||||
|  | 		if err != nil { | ||||||
|  | 			rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  | 		rest.PostProcessResponse(w, cliCtx, res) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
| func queryTotalDepositedHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { | func queryTotalDepositedHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { | ||||||
| 	return func(w http.ResponseWriter, r *http.Request) { | 	return func(w http.ResponseWriter, r *http.Request) { | ||||||
| 		_, _, _, err := rest.ParseHTTPArgsWithLimit(r, 0) | 		_, _, _, err := rest.ParseHTTPArgsWithLimit(r, 0) | ||||||
| @ -179,6 +230,54 @@ func queryBorrowsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | func queryUnsyncedBorrowsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { | ||||||
|  | 	return func(w http.ResponseWriter, r *http.Request) { | ||||||
|  | 		_, page, limit, err := rest.ParseHTTPArgsWithLimit(r, 0) | ||||||
|  | 		if err != nil { | ||||||
|  | 			rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  | 		// Parse the query height
 | ||||||
|  | 		cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r) | ||||||
|  | 		if !ok { | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		var denom string | ||||||
|  | 		var owner sdk.AccAddress | ||||||
|  | 
 | ||||||
|  | 		if x := r.URL.Query().Get(RestDenom); len(x) != 0 { | ||||||
|  | 			denom = strings.TrimSpace(x) | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if x := r.URL.Query().Get(RestOwner); len(x) != 0 { | ||||||
|  | 			ownerStr := strings.ToLower(strings.TrimSpace(x)) | ||||||
|  | 			owner, err = sdk.AccAddressFromBech32(ownerStr) | ||||||
|  | 			if err != nil { | ||||||
|  | 				rest.WriteErrorResponse(w, http.StatusBadRequest, fmt.Sprintf("cannot parse address from borrow owner %s", ownerStr)) | ||||||
|  | 				return | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		params := types.NewQueryUnsyncedBorrowsParams(page, limit, owner, denom) | ||||||
|  | 
 | ||||||
|  | 		bz, err := cliCtx.Codec.MarshalJSON(params) | ||||||
|  | 		if err != nil { | ||||||
|  | 			rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		route := fmt.Sprintf("custom/%s/%s", types.ModuleName, types.QueryGetUnsyncedBorrows) | ||||||
|  | 		res, height, err := cliCtx.QueryWithData(route, bz) | ||||||
|  | 		cliCtx = cliCtx.WithHeight(height) | ||||||
|  | 		if err != nil { | ||||||
|  | 			rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  | 		rest.PostProcessResponse(w, cliCtx, res) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
| func queryTotalBorrowedHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { | func queryTotalBorrowedHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { | ||||||
| 	return func(w http.ResponseWriter, r *http.Request) { | 	return func(w http.ResponseWriter, r *http.Request) { | ||||||
| 		_, _, _, err := rest.ParseHTTPArgsWithLimit(r, 0) | 		_, _, _, err := rest.ParseHTTPArgsWithLimit(r, 0) | ||||||
| @ -330,3 +429,41 @@ func queryReservesHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { | |||||||
| 		rest.PostProcessResponse(w, cliCtx, res) | 		rest.PostProcessResponse(w, cliCtx, res) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | func queryInterestFactorsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { | ||||||
|  | 	return func(w http.ResponseWriter, r *http.Request) { | ||||||
|  | 		_, _, _, err := rest.ParseHTTPArgsWithLimit(r, 0) | ||||||
|  | 		if err != nil { | ||||||
|  | 			rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  | 		// Parse the query height
 | ||||||
|  | 		cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r) | ||||||
|  | 		if !ok { | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		var denom string | ||||||
|  | 
 | ||||||
|  | 		if x := r.URL.Query().Get(RestDenom); len(x) != 0 { | ||||||
|  | 			denom = strings.TrimSpace(x) | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		params := types.NewQueryInterestFactorsParams(denom) | ||||||
|  | 
 | ||||||
|  | 		bz, err := cliCtx.Codec.MarshalJSON(params) | ||||||
|  | 		if err != nil { | ||||||
|  | 			rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		route := fmt.Sprintf("custom/%s/%s", types.ModuleName, types.QueryGetInterestFactors) | ||||||
|  | 		res, height, err := cliCtx.QueryWithData(route, bz) | ||||||
|  | 		cliCtx = cliCtx.WithHeight(height) | ||||||
|  | 		if err != nil { | ||||||
|  | 			rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  | 		rest.PostProcessResponse(w, cliCtx, res) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | |||||||
| @ -306,6 +306,21 @@ func (k Keeper) SetBorrowInterestFactor(ctx sdk.Context, denom string, borrowInt | |||||||
| 	store.Set([]byte(denom), bz) | 	store.Set([]byte(denom), bz) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // IterateBorrowInterestFactors iterates over all borrow interest factors in the store and returns
 | ||||||
|  | // both the borrow interest factor and the key (denom) it's stored under
 | ||||||
|  | func (k Keeper) IterateBorrowInterestFactors(ctx sdk.Context, cb func(denom string, factor sdk.Dec) (stop bool)) { | ||||||
|  | 	store := prefix.NewStore(ctx.KVStore(k.key), types.BorrowInterestFactorPrefix) | ||||||
|  | 	iterator := sdk.KVStorePrefixIterator(store, []byte{}) | ||||||
|  | 	defer iterator.Close() | ||||||
|  | 	for ; iterator.Valid(); iterator.Next() { | ||||||
|  | 		var factor sdk.Dec | ||||||
|  | 		k.cdc.MustUnmarshalBinaryBare(iterator.Value(), &factor) | ||||||
|  | 		if cb(string(iterator.Key()), factor) { | ||||||
|  | 			break | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // GetSupplyInterestFactor returns the current supply interest factor for an individual market
 | // GetSupplyInterestFactor returns the current supply interest factor for an individual market
 | ||||||
| func (k Keeper) GetSupplyInterestFactor(ctx sdk.Context, denom string) (sdk.Dec, bool) { | func (k Keeper) GetSupplyInterestFactor(ctx sdk.Context, denom string) (sdk.Dec, bool) { | ||||||
| 	store := prefix.NewStore(ctx.KVStore(k.key), types.SupplyInterestFactorPrefix) | 	store := prefix.NewStore(ctx.KVStore(k.key), types.SupplyInterestFactorPrefix) | ||||||
| @ -324,3 +339,18 @@ func (k Keeper) SetSupplyInterestFactor(ctx sdk.Context, denom string, supplyInt | |||||||
| 	bz := k.cdc.MustMarshalBinaryBare(supplyInterestFactor) | 	bz := k.cdc.MustMarshalBinaryBare(supplyInterestFactor) | ||||||
| 	store.Set([]byte(denom), bz) | 	store.Set([]byte(denom), bz) | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | // IterateSupplyInterestFactors iterates over all supply interest factors in the store and returns
 | ||||||
|  | // both the supply interest factor and the key (denom) it's stored under
 | ||||||
|  | func (k Keeper) IterateSupplyInterestFactors(ctx sdk.Context, cb func(denom string, factor sdk.Dec) (stop bool)) { | ||||||
|  | 	store := prefix.NewStore(ctx.KVStore(k.key), types.SupplyInterestFactorPrefix) | ||||||
|  | 	iterator := sdk.KVStorePrefixIterator(store, []byte{}) | ||||||
|  | 	defer iterator.Close() | ||||||
|  | 	for ; iterator.Valid(); iterator.Next() { | ||||||
|  | 		var factor sdk.Dec | ||||||
|  | 		k.cdc.MustUnmarshalBinaryBare(iterator.Value(), &factor) | ||||||
|  | 		if cb(string(iterator.Key()), factor) { | ||||||
|  | 			break | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | |||||||
| @ -22,16 +22,22 @@ func NewQuerier(k Keeper) sdk.Querier { | |||||||
| 			return queryGetModAccounts(ctx, req, k) | 			return queryGetModAccounts(ctx, req, k) | ||||||
| 		case types.QueryGetDeposits: | 		case types.QueryGetDeposits: | ||||||
| 			return queryGetDeposits(ctx, req, k) | 			return queryGetDeposits(ctx, req, k) | ||||||
|  | 		case types.QueryGetUnsyncedDeposits: | ||||||
|  | 			return queryGetUnsyncedDeposits(ctx, req, k) | ||||||
| 		case types.QueryGetTotalDeposited: | 		case types.QueryGetTotalDeposited: | ||||||
| 			return queryGetTotalDeposited(ctx, req, k) | 			return queryGetTotalDeposited(ctx, req, k) | ||||||
| 		case types.QueryGetBorrows: | 		case types.QueryGetBorrows: | ||||||
| 			return queryGetBorrows(ctx, req, k) | 			return queryGetBorrows(ctx, req, k) | ||||||
|  | 		case types.QueryGetUnsyncedBorrows: | ||||||
|  | 			return queryGetUnsyncedBorrows(ctx, req, k) | ||||||
| 		case types.QueryGetTotalBorrowed: | 		case types.QueryGetTotalBorrowed: | ||||||
| 			return queryGetTotalBorrowed(ctx, req, k) | 			return queryGetTotalBorrowed(ctx, req, k) | ||||||
| 		case types.QueryGetInterestRate: | 		case types.QueryGetInterestRate: | ||||||
| 			return queryGetInterestRate(ctx, req, k) | 			return queryGetInterestRate(ctx, req, k) | ||||||
| 		case types.QueryGetReserves: | 		case types.QueryGetReserves: | ||||||
| 			return queryGetReserves(ctx, req, k) | 			return queryGetReserves(ctx, req, k) | ||||||
|  | 		case types.QueryGetInterestFactors: | ||||||
|  | 			return queryGetInterestFactors(ctx, req, k) | ||||||
| 		default: | 		default: | ||||||
| 			return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unknown %s query endpoint", types.ModuleName) | 			return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unknown %s query endpoint", types.ModuleName) | ||||||
| 		} | 		} | ||||||
| @ -147,6 +153,62 @@ func queryGetDeposits(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, | |||||||
| 	return bz, nil | 	return bz, nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | func queryGetUnsyncedDeposits(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) { | ||||||
|  | 
 | ||||||
|  | 	var params types.QueryUnsyncedDepositsParams | ||||||
|  | 	err := types.ModuleCdc.UnmarshalJSON(req.Data, ¶ms) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) | ||||||
|  | 	} | ||||||
|  | 	denom := len(params.Denom) > 0 | ||||||
|  | 	owner := len(params.Owner) > 0 | ||||||
|  | 
 | ||||||
|  | 	var deposits types.Deposits | ||||||
|  | 	switch { | ||||||
|  | 	case owner && denom: | ||||||
|  | 		deposit, found := k.GetDeposit(ctx, params.Owner) | ||||||
|  | 		if found { | ||||||
|  | 			for _, coin := range deposit.Amount { | ||||||
|  | 				if coin.Denom == params.Denom { | ||||||
|  | 					deposits = append(deposits, deposit) | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	case owner: | ||||||
|  | 		deposit, found := k.GetDeposit(ctx, params.Owner) | ||||||
|  | 		if found { | ||||||
|  | 			deposits = append(deposits, deposit) | ||||||
|  | 		} | ||||||
|  | 	case denom: | ||||||
|  | 		k.IterateDeposits(ctx, func(deposit types.Deposit) (stop bool) { | ||||||
|  | 			if deposit.Amount.AmountOf(params.Denom).IsPositive() { | ||||||
|  | 				deposits = append(deposits, deposit) | ||||||
|  | 			} | ||||||
|  | 			return false | ||||||
|  | 		}) | ||||||
|  | 	default: | ||||||
|  | 		k.IterateDeposits(ctx, func(deposit types.Deposit) (stop bool) { | ||||||
|  | 			deposits = append(deposits, deposit) | ||||||
|  | 			return false | ||||||
|  | 		}) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	var bz []byte | ||||||
|  | 
 | ||||||
|  | 	start, end := client.Paginate(len(deposits), params.Page, params.Limit, 100) | ||||||
|  | 	if start < 0 || end < 0 { | ||||||
|  | 		deposits = types.Deposits{} | ||||||
|  | 	} else { | ||||||
|  | 		deposits = deposits[start:end] | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	bz, err = codec.MarshalJSONIndent(types.ModuleCdc, deposits) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) | ||||||
|  | 	} | ||||||
|  | 	return bz, nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
| func queryGetBorrows(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) { | func queryGetBorrows(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) { | ||||||
| 
 | 
 | ||||||
| 	var params types.QueryBorrowsParams | 	var params types.QueryBorrowsParams | ||||||
| @ -219,6 +281,62 @@ func queryGetBorrows(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, | |||||||
| 	return bz, nil | 	return bz, nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | func queryGetUnsyncedBorrows(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) { | ||||||
|  | 
 | ||||||
|  | 	var params types.QueryUnsyncedBorrowsParams | ||||||
|  | 	err := types.ModuleCdc.UnmarshalJSON(req.Data, ¶ms) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) | ||||||
|  | 	} | ||||||
|  | 	denom := len(params.Denom) > 0 | ||||||
|  | 	owner := len(params.Owner) > 0 | ||||||
|  | 
 | ||||||
|  | 	var borrows types.Borrows | ||||||
|  | 	switch { | ||||||
|  | 	case owner && denom: | ||||||
|  | 		borrow, found := k.GetBorrow(ctx, params.Owner) | ||||||
|  | 		if found { | ||||||
|  | 			for _, coin := range borrow.Amount { | ||||||
|  | 				if coin.Denom == params.Denom { | ||||||
|  | 					borrows = append(borrows, borrow) | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	case owner: | ||||||
|  | 		borrow, found := k.GetBorrow(ctx, params.Owner) | ||||||
|  | 		if found { | ||||||
|  | 			borrows = append(borrows, borrow) | ||||||
|  | 		} | ||||||
|  | 	case denom: | ||||||
|  | 		k.IterateBorrows(ctx, func(borrow types.Borrow) (stop bool) { | ||||||
|  | 			if borrow.Amount.AmountOf(params.Denom).IsPositive() { | ||||||
|  | 				borrows = append(borrows, borrow) | ||||||
|  | 			} | ||||||
|  | 			return false | ||||||
|  | 		}) | ||||||
|  | 	default: | ||||||
|  | 		k.IterateBorrows(ctx, func(borrow types.Borrow) (stop bool) { | ||||||
|  | 			borrows = append(borrows, borrow) | ||||||
|  | 			return false | ||||||
|  | 		}) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	var bz []byte | ||||||
|  | 
 | ||||||
|  | 	start, end := client.Paginate(len(borrows), params.Page, params.Limit, 100) | ||||||
|  | 	if start < 0 || end < 0 { | ||||||
|  | 		borrows = types.Borrows{} | ||||||
|  | 	} else { | ||||||
|  | 		borrows = borrows[start:end] | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	bz, err = codec.MarshalJSONIndent(types.ModuleCdc, borrows) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) | ||||||
|  | 	} | ||||||
|  | 	return bz, nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
| func queryGetTotalBorrowed(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) { | func queryGetTotalBorrowed(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) { | ||||||
| 	var params types.QueryTotalBorrowedParams | 	var params types.QueryTotalBorrowedParams | ||||||
| 	err := types.ModuleCdc.UnmarshalJSON(req.Data, ¶ms) | 	err := types.ModuleCdc.UnmarshalJSON(req.Data, ¶ms) | ||||||
| @ -355,3 +473,58 @@ func queryGetReserves(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, | |||||||
| 
 | 
 | ||||||
| 	return bz, nil | 	return bz, nil | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | func queryGetInterestFactors(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) { | ||||||
|  | 	var params types.QueryInterestFactorsParams | ||||||
|  | 	err := types.ModuleCdc.UnmarshalJSON(req.Data, ¶ms) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	var interestFactors types.InterestFactors | ||||||
|  | 	if len(params.Denom) > 0 { | ||||||
|  | 		// Fetch supply/borrow interest factors for a single denom
 | ||||||
|  | 		interestFactor := types.InterestFactor{} | ||||||
|  | 		interestFactor.Denom = params.Denom | ||||||
|  | 		supplyInterestFactor, found := k.GetSupplyInterestFactor(ctx, params.Denom) | ||||||
|  | 		if found { | ||||||
|  | 			interestFactor.SupplyInterestFactor = supplyInterestFactor | ||||||
|  | 		} | ||||||
|  | 		borrowInterestFactor, found := k.GetBorrowInterestFactor(ctx, params.Denom) | ||||||
|  | 		if found { | ||||||
|  | 			interestFactor.BorrowInterestFactor = borrowInterestFactor | ||||||
|  | 		} | ||||||
|  | 		interestFactors = append(interestFactors, interestFactor) | ||||||
|  | 	} else { | ||||||
|  | 		interestFactorMap := make(map[string]types.InterestFactor) | ||||||
|  | 		// Populate mapping with supply interest factors
 | ||||||
|  | 		k.IterateSupplyInterestFactors(ctx, func(denom string, factor sdk.Dec) (stop bool) { | ||||||
|  | 			interestFactor := types.InterestFactor{Denom: denom, SupplyInterestFactor: factor} | ||||||
|  | 			interestFactorMap[denom] = interestFactor | ||||||
|  | 			return false | ||||||
|  | 		}) | ||||||
|  | 		// Populate mapping with borrow interest factors
 | ||||||
|  | 		k.IterateBorrowInterestFactors(ctx, func(denom string, factor sdk.Dec) (stop bool) { | ||||||
|  | 			interestFactor, ok := interestFactorMap[denom] | ||||||
|  | 			if !ok { | ||||||
|  | 				newInterestFactor := types.InterestFactor{Denom: denom, BorrowInterestFactor: factor} | ||||||
|  | 				interestFactorMap[denom] = newInterestFactor | ||||||
|  | 			} else { | ||||||
|  | 				interestFactor.BorrowInterestFactor = factor | ||||||
|  | 				interestFactorMap[denom] = interestFactor | ||||||
|  | 			} | ||||||
|  | 			return false | ||||||
|  | 		}) | ||||||
|  | 		// Translate mapping to slice
 | ||||||
|  | 		for _, val := range interestFactorMap { | ||||||
|  | 			interestFactors = append(interestFactors, val) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	bz, err := codec.MarshalJSONIndent(types.ModuleCdc, interestFactors) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return bz, nil | ||||||
|  | } | ||||||
|  | |||||||
| @ -6,14 +6,17 @@ import ( | |||||||
| 
 | 
 | ||||||
| // Querier routes for the hard module
 | // Querier routes for the hard module
 | ||||||
| const ( | const ( | ||||||
| 	QueryGetParams         = "params" | 	QueryGetParams           = "params" | ||||||
| 	QueryGetModuleAccounts = "accounts" | 	QueryGetModuleAccounts   = "accounts" | ||||||
| 	QueryGetDeposits       = "deposits" | 	QueryGetDeposits         = "deposits" | ||||||
| 	QueryGetTotalDeposited = "total-deposited" | 	QueryGetUnsyncedDeposits = "unsynced-deposits" | ||||||
| 	QueryGetBorrows        = "borrows" | 	QueryGetTotalDeposited   = "total-deposited" | ||||||
| 	QueryGetTotalBorrowed  = "total-borrowed" | 	QueryGetBorrows          = "borrows" | ||||||
| 	QueryGetInterestRate   = "interest-rate" | 	QueryGetUnsyncedBorrows  = "unsynced-borrows" | ||||||
| 	QueryGetReserves       = "reserves" | 	QueryGetTotalBorrowed    = "total-borrowed" | ||||||
|  | 	QueryGetInterestRate     = "interest-rate" | ||||||
|  | 	QueryGetReserves         = "reserves" | ||||||
|  | 	QueryGetInterestFactors  = "interest-factors" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // QueryDepositsParams is the params for a filtered deposit query
 | // QueryDepositsParams is the params for a filtered deposit query
 | ||||||
| @ -34,6 +37,24 @@ func NewQueryDepositsParams(page, limit int, denom string, owner sdk.AccAddress) | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // QueryUnsyncedDepositsParams is the params for a filtered unsynced deposit query.
 | ||||||
|  | type QueryUnsyncedDepositsParams struct { | ||||||
|  | 	Page  int            `json:"page" yaml:"page"` | ||||||
|  | 	Limit int            `json:"limit" yaml:"limit"` | ||||||
|  | 	Denom string         `json:"denom" yaml:"denom"` | ||||||
|  | 	Owner sdk.AccAddress `json:"owner" yaml:"owner"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // NewQueryUnsyncedDepositsParams creates a new QueryUnsyncedDepositsParams
 | ||||||
|  | func NewQueryUnsyncedDepositsParams(page, limit int, denom string, owner sdk.AccAddress) QueryUnsyncedDepositsParams { | ||||||
|  | 	return QueryUnsyncedDepositsParams{ | ||||||
|  | 		Page:  page, | ||||||
|  | 		Limit: limit, | ||||||
|  | 		Denom: denom, | ||||||
|  | 		Owner: owner, | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // QueryAccountParams is the params for a filtered module account query
 | // QueryAccountParams is the params for a filtered module account query
 | ||||||
| type QueryAccountParams struct { | type QueryAccountParams struct { | ||||||
| 	Page  int    `json:"page" yaml:"page"` | 	Page  int    `json:"page" yaml:"page"` | ||||||
| @ -68,6 +89,24 @@ func NewQueryBorrowsParams(page, limit int, owner sdk.AccAddress, denom string) | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // QueryUnsyncedBorrowsParams is the params for a filtered unsynced borrows query
 | ||||||
|  | type QueryUnsyncedBorrowsParams struct { | ||||||
|  | 	Page  int            `json:"page" yaml:"page"` | ||||||
|  | 	Limit int            `json:"limit" yaml:"limit"` | ||||||
|  | 	Owner sdk.AccAddress `json:"owner" yaml:"owner"` | ||||||
|  | 	Denom string         `json:"denom" yaml:"denom"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // NewQueryUnsyncedBorrowsParams creates a new QueryUnsyncedBorrowsParams
 | ||||||
|  | func NewQueryUnsyncedBorrowsParams(page, limit int, owner sdk.AccAddress, denom string) QueryUnsyncedBorrowsParams { | ||||||
|  | 	return QueryUnsyncedBorrowsParams{ | ||||||
|  | 		Page:  page, | ||||||
|  | 		Limit: limit, | ||||||
|  | 		Owner: owner, | ||||||
|  | 		Denom: denom, | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // QueryTotalBorrowedParams is the params for a filtered total borrowed coins query
 | // QueryTotalBorrowedParams is the params for a filtered total borrowed coins query
 | ||||||
| type QueryTotalBorrowedParams struct { | type QueryTotalBorrowedParams struct { | ||||||
| 	Denom string `json:"denom" yaml:"denom"` | 	Denom string `json:"denom" yaml:"denom"` | ||||||
| @ -134,3 +173,34 @@ func NewQueryReservesParams(denom string) QueryReservesParams { | |||||||
| 		Denom: denom, | 		Denom: denom, | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | // QueryInterestFactorsParams is the params for a filtered interest factors query
 | ||||||
|  | type QueryInterestFactorsParams struct { | ||||||
|  | 	Denom string `json:"denom" yaml:"denom"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // NewQueryInterestFactorsParams creates a new QueryInterestFactorsParams
 | ||||||
|  | func NewQueryInterestFactorsParams(denom string) QueryInterestFactorsParams { | ||||||
|  | 	return QueryInterestFactorsParams{ | ||||||
|  | 		Denom: denom, | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // InterestFactor is a unique type returned by interest factor queries
 | ||||||
|  | type InterestFactor struct { | ||||||
|  | 	Denom                string  `json:"denom" yaml:"denom"` | ||||||
|  | 	BorrowInterestFactor sdk.Dec `json:"borrow_interest_factor" yaml:"borrow_interest_factor"` | ||||||
|  | 	SupplyInterestFactor sdk.Dec `json:"supply_interest_factor" yaml:"supply_interest_factor"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // NewInterestFactor returns a new instance of InterestFactor
 | ||||||
|  | func NewInterestFactor(denom string, supplyInterestFactor, borrowInterestFactor sdk.Dec) InterestFactor { | ||||||
|  | 	return InterestFactor{ | ||||||
|  | 		Denom:                denom, | ||||||
|  | 		SupplyInterestFactor: supplyInterestFactor, | ||||||
|  | 		BorrowInterestFactor: borrowInterestFactor, | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // InterestFactors is a slice of InterestFactor
 | ||||||
|  | type InterestFactors = []InterestFactor | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Denali Marsh
						Denali Marsh