diff --git a/app/app.go b/app/app.go index 55acb08..c53225e 100644 --- a/app/app.go +++ b/app/app.go @@ -706,7 +706,7 @@ func New( authtypes.NewModuleAddress(govtypes.ModuleName).String(), ) - tfOpts := tokenbindings.RegisterCustomPlugins(&app.BankKeeper, &app.TokenFactoryKeeper) + tfOpts := tokenbindings.RegisterCustomPlugins(app.GRPCQueryRouter(), appCodec, &app.BankKeeper, &app.TokenFactoryKeeper, &app.LiquidityKeeper) wasmOpts = append(wasmOpts, tfOpts...) wasmDir := filepath.Join(homePath, "data") diff --git a/x/tokenfactory/bindings/message_plugin.go b/x/tokenfactory/bindings/message_plugin.go index a09a48f..f86db3a 100644 --- a/x/tokenfactory/bindings/message_plugin.go +++ b/x/tokenfactory/bindings/message_plugin.go @@ -15,15 +15,18 @@ import ( bindingstypes "github.com/ChihuahuaChain/chihuahua/x/tokenfactory/bindings/types" tokenfactorykeeper "github.com/ChihuahuaChain/chihuahua/x/tokenfactory/keeper" tokenfactorytypes "github.com/ChihuahuaChain/chihuahua/x/tokenfactory/types" + liquiditykeeper "github.com/Victor118/liquidity/x/liquidity/keeper" + liquiditytypes "github.com/Victor118/liquidity/x/liquidity/types" ) // CustomMessageDecorator returns decorator for custom CosmWasm bindings messages -func CustomMessageDecorator(bank bankkeeper.Keeper, tokenFactory *tokenfactorykeeper.Keeper) func(wasmkeeper.Messenger) wasmkeeper.Messenger { +func CustomMessageDecorator(bank bankkeeper.Keeper, tokenFactory *tokenfactorykeeper.Keeper, liquidityKeeper *liquiditykeeper.Keeper) func(wasmkeeper.Messenger) wasmkeeper.Messenger { return func(old wasmkeeper.Messenger) wasmkeeper.Messenger { return &CustomMessenger{ wrapped: old, bank: bank, tokenFactory: tokenFactory, + liquidity: liquidityKeeper, } } } @@ -32,6 +35,7 @@ type CustomMessenger struct { wrapped wasmkeeper.Messenger bank bankkeeper.Keeper tokenFactory *tokenfactorykeeper.Keeper + liquidity *liquiditykeeper.Keeper } var _ wasmkeeper.Messenger = (*CustomMessenger)(nil) @@ -41,7 +45,7 @@ func (m *CustomMessenger) DispatchMsg(ctx sdk.Context, contractAddr sdk.AccAddre if msg.Custom != nil { // only handle the happy path where this is really creating / minting / swapping ... // leave everything else for the wrapped version - var contractMsg bindingstypes.TokenFactoryMsg + var contractMsg bindingstypes.WasmMsg if err := json.Unmarshal(msg.Custom, &contractMsg); err != nil { return nil, nil, nil, errorsmod.Wrap(err, "token factory msg") } @@ -67,11 +71,14 @@ func (m *CustomMessenger) DispatchMsg(ctx sdk.Context, contractAddr sdk.AccAddre if contractMsg.CreateStakedrop != nil { return m.createStakedrop(ctx, contractAddr, contractMsg.CreateStakedrop) } + if contractMsg.CreatePool != nil { + return m.createPool(ctx, contractAddr, contractMsg.CreatePool) + } } return m.wrapped.DispatchMsg(ctx, contractAddr, contractIBCPortID, msg) } -// createDenom creates a new token denom +// createDenom creates a stakedrop, an amount of tokens distributed to stakers over a range of block func (m *CustomMessenger) createStakedrop(ctx sdk.Context, contractAddr sdk.AccAddress, createStakedrop *bindingstypes.CreateStakedrop) ([]sdk.Event, [][]byte, [][]*types.Any, error) { bz, err := PerformCreateStakedrop(m.tokenFactory, m.bank, ctx, contractAddr, createStakedrop) if err != nil { @@ -107,6 +114,42 @@ func PerformCreateStakedrop(f *tokenfactorykeeper.Keeper, b bankkeeper.Keeper, c return resp.Marshal() } +// createDenom creates a new token denom +func (m *CustomMessenger) createPool(ctx sdk.Context, contractAddr sdk.AccAddress, createPool *bindingstypes.CreatePool) ([]sdk.Event, [][]byte, [][]*types.Any, error) { + bz, err := PerformCreatePool(m.liquidity, m.bank, ctx, contractAddr, createPool) + if err != nil { + return nil, nil, nil, errorsmod.Wrap(err, "perform create pool") + } + // TODO: double check how this is all encoded to the contract + return nil, [][]byte{bz}, nil, nil +} + +// PerformCreateStakedrop is used with createStakedrop to create a stakedrop; validates the msgCreateStakedrop. +func PerformCreatePool(f *liquiditykeeper.Keeper, b bankkeeper.Keeper, ctx sdk.Context, contractAddr sdk.AccAddress, createPool *bindingstypes.CreatePool) ([]byte, error) { + if createPool == nil { + return nil, wasmvmtypes.InvalidRequest{Err: "create stakedrop null create stakedrop"} + } + + msgServer := liquiditykeeper.NewMsgServerImpl(*f) + + msgCreatePool := liquiditytypes.NewMsgCreatePool(contractAddr, uint32(1), sdk.NewCoins(sdk.NewCoin(createPool.Denom1, createPool.Amount1), sdk.NewCoin(createPool.Denom2, createPool.Amount2))) + + if err := msgCreatePool.ValidateBasic(); err != nil { + return nil, errorsmod.Wrap(err, "failed validating MsgCreateStakedrop") + } + + // Create denom + resp, err := msgServer.CreatePool( + ctx, + msgCreatePool, + ) + if err != nil { + return nil, errorsmod.Wrap(err, "creating stakedrop") + } + + return resp.Marshal() +} + // createDenom creates a new token denom func (m *CustomMessenger) createDenom(ctx sdk.Context, contractAddr sdk.AccAddress, createDenom *bindingstypes.CreateDenom) ([]sdk.Event, [][]byte, [][]*types.Any, error) { bz, err := PerformCreateDenom(m.tokenFactory, m.bank, ctx, contractAddr, createDenom) diff --git a/x/tokenfactory/bindings/query_plugin.go b/x/tokenfactory/bindings/query_plugin.go index 27c0759..61a3c56 100644 --- a/x/tokenfactory/bindings/query_plugin.go +++ b/x/tokenfactory/bindings/query_plugin.go @@ -7,15 +7,22 @@ import ( wasmvmtypes "github.com/CosmWasm/wasmvm/v2/types" errorsmod "cosmossdk.io/errors" - bindingstypes "github.com/ChihuahuaChain/chihuahua/x/tokenfactory/bindings/types" tftypes "github.com/ChihuahuaChain/chihuahua/x/tokenfactory/types" + wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" sdk "github.com/cosmos/cosmos-sdk/types" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + ibctransfertypes "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types" + ibcclienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" //nolint:staticcheck + ibcconnectiontypes "github.com/cosmos/ibc-go/v8/modules/core/03-connection/types" + ibcchanneltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" ) // CustomQuerier dispatches custom CosmWasm bindings queries. func CustomQuerier(qp *QueryPlugin) func(ctx sdk.Context, request json.RawMessage) ([]byte, error) { return func(ctx sdk.Context, request json.RawMessage) ([]byte, error) { + ctx.Logger().Error("CustomQuerier ***************************************") var contractQuery bindingstypes.TokenFactoryQuery if err := json.Unmarshal(request, &contractQuery); err != nil { return nil, errorsmod.Wrap(err, "osmosis query") @@ -82,6 +89,7 @@ func CustomQuerier(qp *QueryPlugin) func(ctx sdk.Context, request json.RawMessag return bz, nil case contractQuery.Params != nil: + ctx.Logger().Error("CustomQuerier : PARAMS***************************************") res, err := qp.GetParams(ctx) if err != nil { return nil, err @@ -91,7 +99,8 @@ func CustomQuerier(qp *QueryPlugin) func(ctx sdk.Context, request json.RawMessag if err != nil { return nil, fmt.Errorf("failed to JSON marshal ParamsResponse: %w", err) } - + ctx.Logger().Error(fmt.Sprintf("EVERYTHING IS OK IN PARAMS *************************************** %+v ", res)) + ctx.Logger().Error(fmt.Sprintf("Serialized JSON: %s", string(bz))) return bz, nil case contractQuery.Stakedrop != nil: stakedropsByDenom := []tftypes.Stakedrop{} @@ -145,3 +154,32 @@ func ConvertSdkCoinToWasmCoin(coin sdk.Coin) wasmvmtypes.Coin { Amount: coin.Amount.String(), } } + +func AcceptedStargateQueries() wasmkeeper.AcceptedQueries { + return wasmkeeper.AcceptedQueries{ + // ibc + "/ibc.core.client.v1.Query/ClientState": &ibcclienttypes.QueryClientStateResponse{}, + "/ibc.core.client.v1.Query/ConsensusState": &ibcclienttypes.QueryConsensusStateResponse{}, + "/ibc.core.connection.v1.Query/Connection": &ibcconnectiontypes.QueryConnectionResponse{}, + "/ibc.core.channel.v1.Query/ChannelClientState": &ibcchanneltypes.QueryChannelClientStateResponse{}, + + // token factory + "/osmosis.tokenfactory.v1beta1.Query/Params": &tftypes.QueryParamsResponse{}, + "/osmosis.tokenfactory.v1beta1.Query/DenomAuthorityMetadata": &tftypes.QueryDenomAuthorityMetadataResponse{}, + "/osmosis.tokenfactory.v1beta1.Query/DenomsFromCreator": &tftypes.QueryDenomsFromCreatorResponse{}, + + // transfer + "/ibc.applications.transfer.v1.Query/DenomTrace": &ibctransfertypes.QueryDenomTraceResponse{}, + "/ibc.applications.transfer.v1.Query/EscrowAddress": &ibctransfertypes.QueryEscrowAddressResponse{}, + + // auth + "/cosmos.auth.v1beta1.Query/Account": &authtypes.QueryAccountResponse{}, + "/cosmos.auth.v1beta1.Query/Params": &authtypes.QueryParamsResponse{}, + + // bank + "/cosmos.bank.v1beta1.Query/Balance": &banktypes.QueryBalanceResponse{}, + "/cosmos.bank.v1beta1.Query/DenomMetadata": &banktypes.QueryDenomsMetadataResponse{}, + "/cosmos.bank.v1beta1.Query/Params": &banktypes.QueryParamsResponse{}, + "/cosmos.bank.v1beta1.Query/SupplyOf": &banktypes.QuerySupplyOfResponse{}, + } +} diff --git a/x/tokenfactory/bindings/types/msg.go b/x/tokenfactory/bindings/types/msg.go index d219306..df9bf54 100644 --- a/x/tokenfactory/bindings/types/msg.go +++ b/x/tokenfactory/bindings/types/msg.go @@ -2,7 +2,7 @@ package types import "cosmossdk.io/math" -type TokenFactoryMsg struct { +type WasmMsg struct { /// Contracts can create denoms, namespaced under the contract's address. /// A contract may create any number of independent sub-denoms. CreateDenom *CreateDenom `json:"create_denom,omitempty"` @@ -21,6 +21,8 @@ type TokenFactoryMsg struct { ForceTransfer *ForceTransfer `json:"force_transfer,omitempty"` CreateStakedrop *CreateStakedrop `json:"create_stakedrop,omitempty"` + + CreatePool *CreatePool `json:"create_pool,omitempty"` } type CreateStakedrop struct { @@ -71,3 +73,14 @@ type ForceTransfer struct { FromAddress string `json:"from_address"` ToAddress string `json:"to_address"` } + +// Message for liquidity module +// TODO binding folder should be extracted from tokenfactory module +type CreatePool struct { + PoolCreatorAddress string `json:"denom"` + PoolTypeId uint32 `json:"pool_type_id"` + Amount1 math.Int `json:"amount1"` + Denom1 string `json:"denom1"` + Amount2 math.Int `json:"amount2"` + Denom2 string `json:"denom2"` +} diff --git a/x/tokenfactory/bindings/wasm.go b/x/tokenfactory/bindings/wasm.go index d209c79..99bc88d 100644 --- a/x/tokenfactory/bindings/wasm.go +++ b/x/tokenfactory/bindings/wasm.go @@ -2,23 +2,31 @@ package bindings import ( wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/baseapp" bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" tokenfactorykeeper "github.com/ChihuahuaChain/chihuahua/x/tokenfactory/keeper" + liquiditykeeper "github.com/Victor118/liquidity/x/liquidity/keeper" ) func RegisterCustomPlugins( + grpcRouter *baseapp.GRPCQueryRouter, + appCodec codec.Codec, bank bankkeeper.Keeper, tokenFactory *tokenfactorykeeper.Keeper, + liquidity *liquiditykeeper.Keeper, ) []wasmkeeper.Option { wasmQueryPlugin := NewQueryPlugin(bank, tokenFactory) queryPluginOpt := wasmkeeper.WithQueryPlugins(&wasmkeeper.QueryPlugins{ - Custom: CustomQuerier(wasmQueryPlugin), + Custom: CustomQuerier(wasmQueryPlugin), + Stargate: wasmkeeper.AcceptListStargateQuerier(AcceptedStargateQueries(), grpcRouter, appCodec), + Grpc: wasmkeeper.AcceptListGrpcQuerier(AcceptedStargateQueries(), grpcRouter, appCodec), }) messengerDecoratorOpt := wasmkeeper.WithMessageHandlerDecorator( - CustomMessageDecorator(bank, tokenFactory), + CustomMessageDecorator(bank, tokenFactory, liquidity), ) return []wasmkeeper.Option{ diff --git a/x/tokenfactory/keeper/createdenom.go b/x/tokenfactory/keeper/createdenom.go index 3823b44..97d2dbc 100644 --- a/x/tokenfactory/keeper/createdenom.go +++ b/x/tokenfactory/keeper/createdenom.go @@ -9,6 +9,7 @@ import ( // ConvertToBaseToken converts a fee amount in a whitelisted fee token to the base fee token amount func (k Keeper) CreateDenom(ctx sdk.Context, creatorAddr string, subdenom string) (newTokenDenom string, err error) { + denom, err := k.validateCreateDenom(ctx, creatorAddr, subdenom) if err != nil { return "", err