github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/x/feesplit/keeper/querier.go (about) 1 package keeper 2 3 import ( 4 "fmt" 5 "strings" 6 7 "github.com/ethereum/go-ethereum/common" 8 9 "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/codec" 10 "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/store/prefix" 11 sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types" 12 sdkerrors "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types/errors" 13 "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types/query" 14 abci "github.com/fibonacci-chain/fbc/libs/tendermint/abci/types" 15 "github.com/fibonacci-chain/fbc/x/feesplit/types" 16 ) 17 18 // NewQuerier is the module level router for state queries 19 func NewQuerier(keeper Keeper) sdk.Querier { 20 return func(ctx sdk.Context, path []string, req abci.RequestQuery) ([]byte, error) { 21 if len(path) < 1 { 22 return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, 23 "Insufficient parameters, at least 1 parameter is required") 24 } 25 26 switch path[0] { 27 case types.QueryParameters: 28 return queryParams(ctx, keeper) 29 case types.QueryFeeSplits: 30 return queryFeeSplits(ctx, req, keeper) 31 case types.QueryFeeSplit: 32 return queryFeeSplit(ctx, req, keeper) 33 case types.QueryDeployerFeeSplits: 34 return queryDeployerFeeSplits(ctx, req, keeper) 35 case types.QueryDeployerFeeSplitsDetail: 36 return queryDeployerFeeSplitsDetail(ctx, req, keeper) 37 case types.QueryWithdrawerFeeSplits: 38 return queryWithdrawerFeeSplits(ctx, req, keeper) 39 default: 40 return nil, sdkerrors.Wrap(sdkerrors.ErrUnknownRequest, "unknown query endpoint") 41 } 42 } 43 } 44 45 // queryFeeSplits returns all FeeSplits that have been registered for fee distribution 46 func queryFeeSplits( 47 ctx sdk.Context, 48 req abci.RequestQuery, 49 k Keeper, 50 ) ([]byte, sdk.Error) { 51 var params types.QueryWithdrawerFeeSplitsRequest 52 err := k.cdc.UnmarshalJSON(req.Data, ¶ms) 53 if err != nil { 54 return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) 55 } 56 57 var feeSplits []types.FeeSplitWithShare 58 store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixFeeSplit) 59 60 pageRes, err := query.Paginate(store, params.Pagination, func(_, value []byte) error { 61 var fee types.FeeSplit 62 if err := k.cdc.UnmarshalBinaryBare(value, &fee); err != nil { 63 return err 64 } 65 share, found := k.GetContractShare(ctx, fee.ContractAddress) 66 if !found { 67 share = k.GetParams(ctx).DeveloperShares 68 } 69 feeSplits = append(feeSplits, types.FeeSplitWithShare{ 70 ContractAddress: fee.ContractAddress.String(), 71 DeployerAddress: fee.DeployerAddress.String(), 72 WithdrawerAddress: fee.WithdrawerAddress.String(), 73 Share: share, 74 }) 75 return nil 76 }) 77 if err != nil { 78 return nil, sdkerrors.Wrap(sdkerrors.ErrInternal, err.Error()) 79 } 80 81 resp := &types.QueryFeeSplitsResponse{ 82 FeeSplits: feeSplits, 83 Pagination: pageRes, 84 } 85 res, err := codec.MarshalJSONIndent(types.ModuleCdc, resp) 86 if err != nil { 87 return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) 88 } 89 return res, nil 90 } 91 92 // queryFeeSplit returns the FeeSplit that has been registered for fee distribution for a given 93 // contract 94 func queryFeeSplit( 95 ctx sdk.Context, 96 req abci.RequestQuery, 97 k Keeper, 98 ) ([]byte, sdk.Error) { 99 var params types.QueryFeeSplitRequest 100 err := k.cdc.UnmarshalJSON(req.Data, ¶ms) 101 if err != nil { 102 return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) 103 } 104 105 if strings.TrimSpace(params.ContractAddress) == "" { 106 return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "contract address is empty") 107 } 108 109 // check if the contract is a non-zero hex address 110 if err := types.ValidateNonZeroAddress(params.ContractAddress); err != nil { 111 return nil, sdkerrors.Wrap( 112 sdkerrors.ErrInvalidRequest, 113 fmt.Sprintf("invalid format for contract %s, should be non-zero hex ('0x...')", params.ContractAddress), 114 ) 115 } 116 117 feeSplit, found := k.GetFeeSplit(ctx, common.HexToAddress(params.ContractAddress)) 118 if !found { 119 return nil, sdkerrors.Wrap( 120 sdkerrors.ErrInvalidRequest, 121 fmt.Sprintf("not found fees registered contract '%s'", params.ContractAddress), 122 ) 123 } 124 share, found := k.GetContractShare(ctx, feeSplit.ContractAddress) 125 if !found { 126 share = k.GetParams(ctx).DeveloperShares 127 } 128 129 resp := &types.QueryFeeSplitResponse{FeeSplit: types.FeeSplitWithShare{ 130 ContractAddress: feeSplit.ContractAddress.String(), 131 DeployerAddress: feeSplit.DeployerAddress.String(), 132 WithdrawerAddress: feeSplit.WithdrawerAddress.String(), 133 Share: share, 134 }} 135 res, err := codec.MarshalJSONIndent(types.ModuleCdc, resp) 136 if err != nil { 137 return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) 138 } 139 return res, nil 140 } 141 142 // queryParams returns the fees module params 143 func queryParams( 144 ctx sdk.Context, 145 k Keeper, 146 ) ([]byte, sdk.Error) { 147 params := k.GetParams(ctx) 148 res, err := codec.MarshalJSONIndent(k.cdc, types.QueryParamsResponse{Params: params}) 149 if err != nil { 150 return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) 151 } 152 153 return res, nil 154 } 155 156 // queryDeployerFeeSplits returns all contracts that have been registered for fee 157 // distribution by a given deployer 158 func queryDeployerFeeSplits( 159 ctx sdk.Context, 160 req abci.RequestQuery, 161 k Keeper, 162 ) ([]byte, sdk.Error) { 163 var params types.QueryDeployerFeeSplitsRequest 164 err := k.cdc.UnmarshalJSON(req.Data, ¶ms) 165 if err != nil { 166 return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) 167 } 168 169 if strings.TrimSpace(params.DeployerAddress) == "" { 170 return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "deployer address is empty") 171 } 172 173 deployer, err := sdk.AccAddressFromBech32(params.DeployerAddress) 174 if err != nil { 175 return nil, sdkerrors.Wrap( 176 sdkerrors.ErrInvalidRequest, 177 fmt.Sprintf("invalid format for deployer %s, should be bech32", params.DeployerAddress), 178 ) 179 } 180 181 var contracts []string 182 store := prefix.NewStore( 183 ctx.KVStore(k.storeKey), 184 types.GetKeyPrefixDeployer(deployer), 185 ) 186 187 pageRes, err := query.Paginate(store, params.Pagination, func(key, _ []byte) error { 188 contracts = append(contracts, common.BytesToAddress(key).Hex()) 189 return nil 190 }) 191 if err != nil { 192 return nil, sdkerrors.Wrap(sdkerrors.ErrInternal, err.Error()) 193 } 194 195 resp := &types.QueryDeployerFeeSplitsResponse{ 196 ContractAddresses: contracts, 197 Pagination: pageRes, 198 } 199 res, err := codec.MarshalJSONIndent(types.ModuleCdc, resp) 200 if err != nil { 201 return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) 202 } 203 return res, nil 204 } 205 206 // queryDeployerFeeSplitsDetail returns all contracts with feesplit info that have been registered for fee 207 // distribution by a given deployer 208 func queryDeployerFeeSplitsDetail( 209 ctx sdk.Context, 210 req abci.RequestQuery, 211 k Keeper, 212 ) ([]byte, sdk.Error) { 213 var params types.QueryDeployerFeeSplitsRequest 214 err := k.cdc.UnmarshalJSON(req.Data, ¶ms) 215 if err != nil { 216 return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) 217 } 218 219 if strings.TrimSpace(params.DeployerAddress) == "" { 220 return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "deployer address is empty") 221 } 222 223 deployer, err := sdk.AccAddressFromBech32(params.DeployerAddress) 224 if err != nil { 225 return nil, sdkerrors.Wrap( 226 sdkerrors.ErrInvalidRequest, 227 fmt.Sprintf("invalid format for deployer %s, should be bech32", params.DeployerAddress), 228 ) 229 } 230 231 var contracts []common.Address 232 store := prefix.NewStore( 233 ctx.KVStore(k.storeKey), 234 types.GetKeyPrefixDeployer(deployer), 235 ) 236 237 pageRes, err := query.Paginate(store, params.Pagination, func(key, _ []byte) error { 238 contracts = append(contracts, common.BytesToAddress(key)) 239 return nil 240 }) 241 if err != nil { 242 return nil, sdkerrors.Wrap(sdkerrors.ErrInternal, err.Error()) 243 } 244 245 var feeSplits []types.FeeSplitWithShare 246 for _, contract := range contracts { 247 feeSplit, found := k.GetFeeSplit(ctx, contract) 248 if !found { 249 continue 250 } 251 share, found := k.GetContractShare(ctx, feeSplit.ContractAddress) 252 if !found { 253 share = k.GetParams(ctx).DeveloperShares 254 } 255 256 feeSplits = append(feeSplits, types.FeeSplitWithShare{ 257 ContractAddress: feeSplit.ContractAddress.String(), 258 DeployerAddress: feeSplit.DeployerAddress.String(), 259 WithdrawerAddress: feeSplit.WithdrawerAddress.String(), 260 Share: share, 261 }) 262 } 263 264 if len(feeSplits) == 0 { 265 return nil, sdkerrors.Wrap( 266 sdkerrors.ErrInvalidRequest, 267 fmt.Sprintf("not found fees registered contract for deployer '%s'", params.DeployerAddress), 268 ) 269 } 270 resp := &types.QueryDeployerFeeSplitsResponseV2{ 271 FeeSplits: feeSplits, 272 Pagination: pageRes, 273 } 274 res, err := codec.MarshalJSONIndent(types.ModuleCdc, resp) 275 if err != nil { 276 return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) 277 } 278 return res, nil 279 } 280 281 // queryWithdrawerFeeSplits returns all fees for a given withdraw address 282 func queryWithdrawerFeeSplits( 283 ctx sdk.Context, 284 req abci.RequestQuery, 285 k Keeper, 286 ) ([]byte, sdk.Error) { 287 var params types.QueryWithdrawerFeeSplitsRequest 288 err := k.cdc.UnmarshalJSON(req.Data, ¶ms) 289 if err != nil { 290 return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) 291 } 292 293 if strings.TrimSpace(params.WithdrawerAddress) == "" { 294 return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "withdraw address is empty") 295 } 296 297 withdrawer, err := sdk.AccAddressFromBech32(params.WithdrawerAddress) 298 if err != nil { 299 return nil, sdkerrors.Wrap( 300 sdkerrors.ErrInvalidRequest, 301 fmt.Sprintf("invalid format for withdraw addr %s, should be bech32", params.WithdrawerAddress), 302 ) 303 } 304 305 var contracts []string 306 store := prefix.NewStore( 307 ctx.KVStore(k.storeKey), 308 types.GetKeyPrefixWithdrawer(withdrawer), 309 ) 310 311 pageRes, err := query.Paginate(store, params.Pagination, func(key, _ []byte) error { 312 contracts = append(contracts, common.BytesToAddress(key).Hex()) 313 314 return nil 315 }) 316 if err != nil { 317 return nil, sdkerrors.Wrap(sdkerrors.ErrInternal, err.Error()) 318 } 319 320 resp := &types.QueryWithdrawerFeeSplitsResponse{ 321 ContractAddresses: contracts, 322 Pagination: pageRes, 323 } 324 res, err := codec.MarshalJSONIndent(types.ModuleCdc, resp) 325 if err != nil { 326 return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) 327 } 328 return res, nil 329 }