diff --git a/app/ante/ante.go b/app/ante/ante.go index 9f9ab1c3..aff66944 100644 --- a/app/ante/ante.go +++ b/app/ante/ante.go @@ -5,6 +5,9 @@ import ( ibckeeper "github.com/cosmos/ibc-go/v7/modules/core/keeper" feesharekeeper "github.com/terra-money/core/v2/x/feeshare/keeper" + smartaccountante "github.com/terra-money/core/v2/x/smartaccount/ante" + smartaccountkeeper "github.com/terra-money/core/v2/x/smartaccount/keeper" + "github.com/cosmos/cosmos-sdk/client" storetypes "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" @@ -14,6 +17,7 @@ import ( wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" wasmTypes "github.com/CosmWasm/wasmd/x/wasm/types" + terrawasmkeeper "github.com/terra-money/core/v2/x/wasm/keeper" ) // HandlerOptions extends the SDK's AnteHandler options by requiring the IBC @@ -21,12 +25,14 @@ import ( type HandlerOptions struct { ante.HandlerOptions - IBCkeeper *ibckeeper.Keeper - FeeShareKeeper feesharekeeper.Keeper - BankKeeper bankKeeper.Keeper - TxCounterStoreKey storetypes.StoreKey - WasmConfig wasmTypes.WasmConfig - TxConfig client.TxConfig + IBCkeeper *ibckeeper.Keeper + FeeShareKeeper feesharekeeper.Keeper + BankKeeper bankKeeper.Keeper + SmartAccountKeeper *smartaccountkeeper.Keeper + WasmKeeper *terrawasmkeeper.Keeper + TxCounterStoreKey storetypes.StoreKey + WasmConfig wasmTypes.WasmConfig + TxConfig client.TxConfig } // NewAnteHandler returns an AnteHandler that checks and increments sequence @@ -45,6 +51,14 @@ func NewAnteHandler(options HandlerOptions) (sdk.AnteHandler, error) { return nil, sdkerrors.Wrap(sdkerrors.ErrLogic, "sign mode handler is required for ante builder") } + if options.SmartAccountKeeper == nil { + return nil, sdkerrors.Wrap(sdkerrors.ErrLogic, "smart account keeper is required for ante builder") + } + + if options.WasmKeeper == nil { + return nil, sdkerrors.Wrap(sdkerrors.ErrLogic, "wasm keeper is required for ante builder") + } + sigGasConsumer := options.SigGasConsumer if sigGasConsumer == nil { sigGasConsumer = ante.DefaultSigVerificationGasConsumer @@ -60,11 +74,14 @@ func NewAnteHandler(options HandlerOptions) (sdk.AnteHandler, error) { ante.NewValidateMemoDecorator(options.AccountKeeper), ante.NewConsumeGasForTxSizeDecorator(options.AccountKeeper), ante.NewDeductFeeDecorator(options.AccountKeeper, options.BankKeeper, options.FeegrantKeeper, options.TxFeeChecker), + // TODO: remove the following line after the migration to the new signature verification decorator is done // SetPubKeyDecorator must be called before all signature verification decorators - ante.NewSetPubKeyDecorator(options.AccountKeeper), - ante.NewValidateSigCountDecorator(options.AccountKeeper), - ante.NewSigGasConsumeDecorator(options.AccountKeeper, sigGasConsumer), - ante.NewSigVerificationDecorator(options.AccountKeeper, options.SignModeHandler), + // ante.NewSetPubKeyDecorator(options.AccountKeeper), + // ante.NewValidateSigCountDecorator(options.AccountKeeper), + // ante.NewSigGasConsumeDecorator(options.AccountKeeper, sigGasConsumer), + // ante.NewSigVerificationDecorator(options.AccountKeeper, options.SignModeHandler), + smartaccountante.NewSmartAccountAuthDecorator(*options.SmartAccountKeeper, options.WasmKeeper, options.AccountKeeper, sigGasConsumer, options.SignModeHandler), + smartaccountante.NewPreTransactionHookDecorator(*options.SmartAccountKeeper, options.WasmKeeper), ante.NewIncrementSequenceDecorator(options.AccountKeeper), ibcante.NewRedundantRelayDecorator(options.IBCkeeper), } diff --git a/app/app.go b/app/app.go index 76c649e8..ac93ba8d 100644 --- a/app/app.go +++ b/app/app.go @@ -258,11 +258,13 @@ func NewTerraApp( SignModeHandler: encodingConfig.TxConfig.SignModeHandler(), SigGasConsumer: cosmosante.DefaultSigVerificationGasConsumer, }, - BankKeeper: app.Keepers.BankKeeper, - FeeShareKeeper: app.Keepers.FeeShareKeeper, - IBCkeeper: app.Keepers.IBCKeeper, - TxCounterStoreKey: app.keys[wasmtypes.StoreKey], - WasmConfig: wasmConfig, + BankKeeper: app.Keepers.BankKeeper, + SmartAccountKeeper: &app.Keepers.SmartAccountKeeper, + WasmKeeper: &app.Keepers.WasmKeeper, + FeeShareKeeper: app.Keepers.FeeShareKeeper, + IBCkeeper: app.Keepers.IBCKeeper, + TxCounterStoreKey: app.keys[wasmtypes.StoreKey], + WasmConfig: wasmConfig, }, ) if err != nil { diff --git a/app/keepers/keepers.go b/app/keepers/keepers.go index ea5613fb..45c5b7a3 100644 --- a/app/keepers/keepers.go +++ b/app/keepers/keepers.go @@ -1,9 +1,6 @@ package keepers import ( - - // #nosec G702 - "path/filepath" "github.com/cosmos/ibc-apps/middleware/packet-forward-middleware/v7/router" @@ -100,6 +97,9 @@ import ( feesharekeeper "github.com/terra-money/core/v2/x/feeshare/keeper" feesharetypes "github.com/terra-money/core/v2/x/feeshare/types" + smartaccountkeeper "github.com/terra-money/core/v2/x/smartaccount/keeper" + smartaccounttypes "github.com/terra-money/core/v2/x/smartaccount/types" + terraappconfig "github.com/terra-money/core/v2/app/config" // unnamed import of statik for swagger UI support _ "github.com/terra-money/core/v2/client/docs/statik" @@ -123,6 +123,7 @@ var maccPerms = map[string][]string{ tokenfactorytypes.ModuleName: {authtypes.Burner, authtypes.Minter}, alliancetypes.ModuleName: {authtypes.Burner, authtypes.Minter}, alliancetypes.RewardsPoolName: nil, + smartaccounttypes.ModuleName: nil, } type TerraAppKeepers struct { @@ -157,6 +158,7 @@ type TerraAppKeepers struct { AllianceKeeper alliancekeeper.Keeper FeeShareKeeper feesharekeeper.Keeper ICQKeeper icqkeeper.Keeper + SmartAccountKeeper smartaccountkeeper.Keeper // IBC hooks IBCHooksKeeper *ibchookskeeper.Keeper @@ -469,6 +471,11 @@ func NewTerraAppKeepers( wasmOpts..., ) + keepers.SmartAccountKeeper = smartaccountkeeper.NewKeeper( + appCodec, + keys[smartaccounttypes.StoreKey], + ) + keepers.Ics20WasmHooks.ContractKeeper = keepers.WasmKeeper.Keeper // Setup the contract keepers.WasmKeeper before the // hook for the BankKeeper othrwise the WasmKeeper @@ -571,6 +578,7 @@ func (app *TerraAppKeepers) initParamsKeeper(appCodec codec.BinaryCodec, legacyA paramsKeeper.Subspace(tokenfactorytypes.ModuleName).WithKeyTable(tokenfactorytypes.ParamKeyTable()) paramsKeeper.Subspace(feesharetypes.ModuleName).WithKeyTable(feesharetypes.ParamKeyTable()) paramsKeeper.Subspace(alliancetypes.ModuleName).WithKeyTable(alliancetypes.ParamKeyTable()) + paramsKeeper.Subspace(smartaccounttypes.ModuleName).WithKeyTable(smartaccounttypes.ParamKeyTable()) return paramsKeeper } diff --git a/app/keepers/keys.go b/app/keepers/keys.go index d02540e9..a2cee23b 100644 --- a/app/keepers/keys.go +++ b/app/keepers/keys.go @@ -46,6 +46,8 @@ import ( alliancetypes "github.com/terra-money/alliance/x/alliance/types" feesharetypes "github.com/terra-money/core/v2/x/feeshare/types" + smartaccounttypes "github.com/terra-money/core/v2/x/smartaccount/types" + // unnamed import of statik for swagger UI support _ "github.com/terra-money/core/v2/client/docs/statik" ) @@ -61,6 +63,7 @@ func (keepers *TerraAppKeepers) GenerateKeys() { consensusparamtypes.StoreKey, tokenfactorytypes.StoreKey, wasmtypes.StoreKey, ibcfeetypes.StoreKey, ibchookstypes.StoreKey, crisistypes.StoreKey, alliancetypes.StoreKey, feesharetypes.StoreKey, icqtypes.StoreKey, + smartaccounttypes.StoreKey, ) keepers.tkeys = sdk.NewTransientStoreKeys(paramstypes.TStoreKey) diff --git a/app/modules.go b/app/modules.go index caa50720..7e21fac2 100644 --- a/app/modules.go +++ b/app/modules.go @@ -21,6 +21,8 @@ import ( feegrantmodule "github.com/cosmos/cosmos-sdk/x/feegrant/module" "github.com/cosmos/cosmos-sdk/x/genutil" genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" + "github.com/terra-money/core/v2/x/smartaccount" + smartaccounttypes "github.com/terra-money/core/v2/x/smartaccount/types" "github.com/cosmos/cosmos-sdk/x/gov" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" @@ -117,6 +119,7 @@ var ModuleBasics = module.NewBasicManager( alliance.AppModuleBasic{}, feeshare.AppModuleBasic{}, icq.AppModuleBasic{}, + smartaccount.AppModuleBasic{}, ) // NOTE: Any module instantiated in the module manager that is later modified @@ -154,6 +157,7 @@ func appModules(app *TerraApp, encodingConfig terrappsparams.EncodingConfig, ski alliance.NewAppModule(app.appCodec, app.Keepers.AllianceKeeper, app.Keepers.StakingKeeper, app.Keepers.AccountKeeper, app.Keepers.BankKeeper, app.interfaceRegistry, app.GetSubspace(alliancetypes.ModuleName)), feeshare.NewAppModule(app.Keepers.FeeShareKeeper, app.Keepers.AccountKeeper, app.GetSubspace(feesharetypes.ModuleName)), icq.NewAppModule(app.Keepers.ICQKeeper), + smartaccount.NewAppModule(app.Keepers.SmartAccountKeeper, app.GetSubspace(smartaccounttypes.ModuleName)), } } @@ -191,6 +195,7 @@ var initGenesisOrder = []string{ feesharetypes.ModuleName, consensusparamtypes.ModuleName, icqtypes.ModuleName, + smartaccounttypes.ModuleName, } var beginBlockersOrder = []string{ @@ -223,6 +228,7 @@ var beginBlockersOrder = []string{ feesharetypes.ModuleName, consensusparamtypes.ModuleName, icqtypes.ModuleName, + smartaccounttypes.ModuleName, } var endBlockerOrder = []string{ @@ -255,4 +261,5 @@ var endBlockerOrder = []string{ feesharetypes.ModuleName, consensusparamtypes.ModuleName, icqtypes.ModuleName, + smartaccounttypes.ModuleName, } diff --git a/app/test_helpers/test_helpers.go b/app/test_helpers/test_helpers.go index 063b44d7..d6fe7aa4 100644 --- a/app/test_helpers/test_helpers.go +++ b/app/test_helpers/test_helpers.go @@ -6,7 +6,6 @@ import ( wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" dbm "github.com/cometbft/cometbft-db" - "github.com/cometbft/cometbft/crypto/ed25519" "github.com/cometbft/cometbft/libs/log" tmproto "github.com/cometbft/cometbft/proto/tendermint/types" "github.com/stretchr/testify/suite" @@ -16,6 +15,8 @@ import ( tokenfactorytypes "github.com/terra-money/core/v2/x/tokenfactory/types" "github.com/cosmos/cosmos-sdk/baseapp" + secp256k1 "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" + cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" sdk "github.com/cosmos/cosmos-sdk/types" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" @@ -32,6 +33,7 @@ type AppTestSuite struct { Ctx sdk.Context QueryHelper *baseapp.QueryServiceTestHelper TestAccs []sdk.AccAddress + TestAccPrivs []cryptotypes.PrivKey EncodingConfig appparams.EncodingConfig } @@ -80,7 +82,9 @@ func (s *AppTestSuite) Setup() { s.App.Keepers.DistrKeeper.SetFeePool(s.Ctx, distrtypes.InitialFeePool()) - s.TestAccs = s.CreateRandomAccounts(3) + testAccounts, privKeys := s.CreateRandomAccounts(3) + s.TestAccs = testAccounts + s.TestAccPrivs = privKeys } func (s *AppTestSuite) AssertEventEmitted(ctx sdk.Context, eventTypeExpected string, numEventsExpected int) { @@ -96,17 +100,20 @@ func (s *AppTestSuite) AssertEventEmitted(ctx sdk.Context, eventTypeExpected str } // CreateRandomAccounts is a function return a list of randomly generated AccAddresses -func (s *AppTestSuite) CreateRandomAccounts(numAccts int) []sdk.AccAddress { +func (s *AppTestSuite) CreateRandomAccounts(numAccts int) ([]sdk.AccAddress, []cryptotypes.PrivKey) { testAddrs := make([]sdk.AccAddress, numAccts) + testPrivKeys := make([]cryptotypes.PrivKey, numAccts) for i := 0; i < numAccts; i++ { - pk := ed25519.GenPrivKey().PubKey() + priv := secp256k1.GenPrivKey() + pk := priv.PubKey() testAddrs[i] = sdk.AccAddress(pk.Address()) + testPrivKeys[i] = priv err := s.FundAcc(testAddrs[i], sdk.NewCoins(sdk.NewInt64Coin("uluna", 100000000))) s.Require().NoError(err) } - return testAddrs + return testAddrs, testPrivKeys } // FundAcc funds target address with specified amount. diff --git a/proto/terra/smartaccount/v1/query.proto b/proto/terra/smartaccount/v1/query.proto index 100c2c40..773e0e22 100644 --- a/proto/terra/smartaccount/v1/query.proto +++ b/proto/terra/smartaccount/v1/query.proto @@ -4,6 +4,7 @@ package terra.smartaccount.v1; import "gogoproto/gogo.proto"; import "google/api/annotations.proto"; import "terra/smartaccount/v1/params.proto"; +import "terra/smartaccount/v1/setting.proto"; option go_package = "github.com/terra-money/core/v2/x/smartaccount/types"; @@ -12,6 +13,10 @@ service Query { rpc Params(QueryParamsRequest) returns (QueryParamsResponse) { option (google.api.http).get = "/terra/smartaccount/v1/params"; } + + rpc Setting(QuerySettingRequest) returns (QuerySettingResponse) { + option (google.api.http).get = "/terra/smartaccount/v1/params/{address}"; + } } // QueryParamsRequest is the request type for the Query/Params RPC method. @@ -23,3 +28,10 @@ message QueryParamsResponse { Params params = 1 [ (gogoproto.nullable) = false ]; } +message QuerySettingRequest { + string address = 1; +} + +message QuerySettingResponse { + Setting setting = 1 [ (gogoproto.nullable) = false ]; +} diff --git a/x/smartaccount/ante/auth.go b/x/smartaccount/ante/auth.go new file mode 100644 index 00000000..c48dc4fb --- /dev/null +++ b/x/smartaccount/ante/auth.go @@ -0,0 +1,290 @@ +package ante + +import ( + "encoding/json" + "fmt" + + cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" + "github.com/cosmos/cosmos-sdk/crypto/types/multisig" + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/cosmos/cosmos-sdk/types/tx/signing" + authante "github.com/cosmos/cosmos-sdk/x/auth/ante" + authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + "github.com/terra-money/core/v2/x/smartaccount/types" +) + +// SmartAccountAuthDecorator does authentication for smart accounts +type SmartAccountAuthDecorator struct { + sak SmartAccountKeeper + wk WasmKeeper + ak authante.AccountKeeper + signModeHandler authsigning.SignModeHandler + defaultVerifySigDecorator sdk.AnteHandler +} + +func NewSmartAccountAuthDecorator( + sak SmartAccountKeeper, + wk WasmKeeper, + ak authante.AccountKeeper, + sigGasConsumer func(meter sdk.GasMeter, sig signing.SignatureV2, params authtypes.Params) error, + signModeHandler authsigning.SignModeHandler, +) SmartAccountAuthDecorator { + if sigGasConsumer == nil { + sigGasConsumer = authante.DefaultSigVerificationGasConsumer + } + defaultVerifySigDecorator := sdk.ChainAnteDecorators( + authante.NewSetPubKeyDecorator(ak), + authante.NewValidateSigCountDecorator(ak), + authante.NewSigGasConsumeDecorator(ak, sigGasConsumer), + authante.NewSigVerificationDecorator(ak, signModeHandler), + ) + return SmartAccountAuthDecorator{ + sak: sak, + wk: wk, + ak: ak, + signModeHandler: signModeHandler, + defaultVerifySigDecorator: defaultVerifySigDecorator, + } +} + +// AnteHandle checks if the tx provides sufficient fee to cover the required fee from the fee market. +func (sad SmartAccountAuthDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (sdk.Context, error) { + // skip the smartaccount auth decorator if the tx is a simulation + if simulate { + return next(ctx, tx, simulate) + } + + sigTx, ok := tx.(authsigning.SigVerifiableTx) + if !ok { + return ctx, sdkerrors.ErrInvalidType.Wrap("expected SigVerifiableTx") + } + + // Signer here is the account that the state transition is affecting + // e.g. Account that is transferring some Coins + signers := sigTx.GetSigners() + account := signers[0].String() + + // check if the tx is from a smart account + setting, err := sad.sak.GetSetting(ctx, account) + if sdkerrors.ErrKeyNotFound.Is(err) { + // run through the default handlers for signature verification + newCtx, err := sad.defaultVerifySigDecorator(ctx, tx, simulate) + if err != nil { + return newCtx, err + } + // continue to the next handler after default signature verification + return next(newCtx, tx, simulate) + } else if err != nil { + return ctx, err + } + + // Current smartaccount only supports one signer (TODO review in the future) + if len(signers) != 1 { + return ctx, sdkerrors.ErrorInvalidSigner.Wrap("only one account is supported (sigTx.GetSigners()!= 1)") + } + + // Sender here is the account that signed the transaction + // Could be different from the account above (confusingly named signer) + signatures, err := sigTx.GetSignaturesV2() + if err != nil { + return ctx, err + } + if len(signatures) == 0 { + return ctx, sdkerrors.ErrNoSignatures.Wrap("no signatures found") + } else if len(signatures) > 1 { + // TODO: remove when support multi sig auth + return ctx, sdkerrors.ErrUnauthorized.Wrap("multiple signatures not supported") + } + + signature := signatures[0] + signaturesBs := [][]byte{} + + senderAddr, err := sdk.AccAddressFromHexUnsafe(signature.PubKey.Address().String()) + if err != nil { + return ctx, err + } + + acc, err := authante.GetSignerAcc(ctx, sad.ak, senderAddr) + if err != nil { + return ctx, err + } + var accNum uint64 + if ctx.BlockHeight() != 0 { + accNum = acc.GetAccountNumber() + } + + signerData := authsigning.SignerData{ + Address: senderAddr.String(), + ChainID: ctx.ChainID(), + AccountNumber: accNum, + Sequence: acc.GetSequence(), + PubKey: signature.PubKey, + } + + signatureBz, err := signatureDataToBz(signature.Data) + if err != nil { + return ctx, err + } + signedBytes, err := GetSignBytesArr(signature.PubKey, signerData, signature.Data, sad.signModeHandler, tx) + if err != nil { + return ctx, err + } + signaturesBs = append(signaturesBs, signatureBz...) + + ctx = ctx.WithValue(types.ModuleName, setting) + if setting.Authorization != nil && len(setting.Authorization) > 0 { + success := false + for _, auth := range setting.Authorization { + authMsg := types.Authorization{ + Sender: senderAddr.String(), + Account: account, + Data: []byte(auth.InitMsg), + Signatures: signaturesBs, + SignedBytes: signedBytes, + } + authMsgBz, err := json.Marshal(authMsg) + if err != nil { + return ctx, err + } + contractAddr, err := sdk.AccAddressFromBech32(auth.ContractAddress) + if err != nil { + return ctx, err + } + _, err = sad.wk.Sudo(ctx, contractAddr, authMsgBz) + // so long as one of the authorization is successful, we're good + if err == nil { + success = true + break + } + if err != nil && setting.Fallback { + return next(ctx, tx, simulate) + } else if err != nil { + return ctx, err + } + } + if success { + return next(ctx, tx, simulate) + } else if !setting.Fallback { + return ctx, sdkerrors.ErrUnauthorized.Wrap("authorization failed") + } + } + // run through the default handlers for signature verification + newCtx, err := sad.defaultVerifySigDecorator(ctx, tx, simulate) + if err != nil { + return newCtx, err + } + // continue to the next handler after default signature verification + return next(newCtx, tx, simulate) +} + +// signatureDataToBz converts a SignatureData into raw bytes signature. +// For SingleSignatureData, it returns the signature raw bytes. +// For MultiSignatureData, it returns an array of all individual signatures, +// as well as the aggregated signature. +func signatureDataToBz(data signing.SignatureData) ([][]byte, error) { + if data == nil { + return nil, fmt.Errorf("got empty SignatureData") + } + + switch data := data.(type) { + case *signing.SingleSignatureData: + return [][]byte{data.Signature}, nil + case *signing.MultiSignatureData: + sigs := [][]byte{} + var err error + + for _, d := range data.Signatures { + nestedSigs, err := signatureDataToBz(d) + if err != nil { + return nil, err + } + sigs = append(sigs, nestedSigs...) + } + + multisig := cryptotypes.MultiSignature{ + Signatures: sigs, + } + aggregatedSig, err := multisig.Marshal() + if err != nil { + return nil, err + } + sigs = append(sigs, aggregatedSig) + + return sigs, nil + default: + return nil, sdkerrors.ErrInvalidType.Wrapf("unexpected signature data type %T", data) + } +} + +func GetSignBytesArr(pubKey cryptotypes.PubKey, signerData authsigning.SignerData, sigData signing.SignatureData, handler authsigning.SignModeHandler, tx sdk.Tx) (signersBytes [][]byte, err error) { + switch data := sigData.(type) { + case *signing.SingleSignatureData: + signBytes, err := handler.GetSignBytes(data.SignMode, signerData, tx) + if err != nil { + return nil, err + } + if !pubKey.VerifySignature(signBytes, data.Signature) { + return nil, fmt.Errorf("unable to verify single signer signature") + } + return [][]byte{signBytes}, nil + + case *signing.MultiSignatureData: + multiPK, ok := pubKey.(multisig.PubKey) + if !ok { + return nil, fmt.Errorf("expected %T, got %T", (multisig.PubKey)(nil), pubKey) + } + return GetMultiSigSignBytes(multiPK, data, signerData, handler, tx) + default: + return nil, fmt.Errorf("unexpected SignatureData %T", sigData) + } +} + +func GetMultiSigSignBytes(multiPK multisig.PubKey, sig *signing.MultiSignatureData, signerData authsigning.SignerData, handler authsigning.SignModeHandler, tx sdk.Tx) (signersBytes [][]byte, err error) { + bitarray := sig.BitArray + sigs := sig.Signatures + size := bitarray.Count() + pubKeys := multiPK.GetPubKeys() + // ensure bit array is the correct size + if len(pubKeys) != size { + return nil, fmt.Errorf("bit array size is incorrect, expecting: %d", len(pubKeys)) + } + // ensure size of signature list + if len(sigs) < int(multiPK.GetThreshold()) || len(sigs) > size { + return nil, fmt.Errorf("signature size is incorrect %d", len(sigs)) + } + // ensure at least k signatures are set + if bitarray.NumTrueBitsBefore(size) < int(multiPK.GetThreshold()) { + return nil, fmt.Errorf("not enough signatures set, have %d, expected %d", bitarray.NumTrueBitsBefore(size), int(multiPK.GetThreshold())) + } + // index in the list of signatures which we are concerned with. + sigIndex := 0 + for i := 0; i < size; i++ { + if bitarray.GetIndex(i) { + si := sig.Signatures[sigIndex] + switch si := si.(type) { + case *signing.SingleSignatureData: + signerBytes, err := handler.GetSignBytes(si.SignMode, signerData, tx) + if err != nil { + return nil, err + } + signersBytes = append(signersBytes, signerBytes) + case *signing.MultiSignatureData: + nestedMultisigPk, ok := pubKeys[i].(multisig.PubKey) + if !ok { + return nil, fmt.Errorf("unable to parse pubkey of index %d", i) + } + signersBytesHold, err := GetMultiSigSignBytes(nestedMultisigPk, si, signerData, handler, tx) + if err != nil { + return nil, err + } + signersBytes = append(signersBytes, signersBytesHold...) + default: + return nil, fmt.Errorf("improper signature data type for index %d", sigIndex) + } + sigIndex++ + } + } + return signersBytes, nil +} diff --git a/x/smartaccount/ante/expected_keepers.go b/x/smartaccount/ante/expected_keepers.go index 64fbc392..19ebe298 100644 --- a/x/smartaccount/ante/expected_keepers.go +++ b/x/smartaccount/ante/expected_keepers.go @@ -9,3 +9,7 @@ import ( type SmartAccountKeeper interface { GetSetting(ctx sdk.Context, ownerAddr string) (*smartaccounttypes.Setting, error) } + +type WasmKeeper interface { + Sudo(ctx sdk.Context, contractAddress sdk.AccAddress, msg []byte) ([]byte, error) +} diff --git a/x/smartaccount/ante/pretransaction.go b/x/smartaccount/ante/pretransaction.go new file mode 100644 index 00000000..31865f6c --- /dev/null +++ b/x/smartaccount/ante/pretransaction.go @@ -0,0 +1,104 @@ +package ante + +import ( + "encoding/json" + + sdkerrors "cosmossdk.io/errors" + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrortypes "github.com/cosmos/cosmos-sdk/types/errors" + tx2 "github.com/cosmos/cosmos-sdk/types/tx" + authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing" + + wasmvmtypes "github.com/CosmWasm/wasmvm/types" + smartaccounttypes "github.com/terra-money/core/v2/x/smartaccount/types" +) + +// SmartAccountCheckDecorator does authentication for smart accounts +type PreTransactionHookDecorator struct { + smartaccountKeeper SmartAccountKeeper + wasmKeeper WasmKeeper +} + +func NewPreTransactionHookDecorator(sak SmartAccountKeeper, wk WasmKeeper) PreTransactionHookDecorator { + return PreTransactionHookDecorator{ + smartaccountKeeper: sak, + wasmKeeper: wk, + } +} + +// AnteHandle checks if the tx provides sufficient fee to cover the required fee from the fee market. +func (pth PreTransactionHookDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (sdk.Context, error) { + setting, ok := ctx.Value(smartaccounttypes.ModuleName).(smartaccounttypes.Setting) + if !ok { + return next(ctx, tx, simulate) + } + + if setting.PreTransaction != nil && len(setting.PreTransaction) > 0 { + for _, preTx := range setting.PreTransaction { + contractAddr, err := sdk.AccAddressFromBech32(preTx) + if err != nil { + return ctx, err + } + data, err := BuildPreTransactionHookMsg(tx) + if err != nil { + return ctx, err + } + _, err = pth.wasmKeeper.Sudo(ctx, contractAddr, data) + if err != nil { + return ctx, err + } + } + } + + return next(ctx, tx, simulate) +} + +// TODO: to refactor +func BuildPreTransactionHookMsg(tx sdk.Tx) ([]byte, error) { + sigTx, ok := tx.(authsigning.SigVerifiableTx) + if !ok { + return nil, sdkerrors.Wrap(sdkerrortypes.ErrInvalidType, "expected SigVerifiableTx") + } + + // Signer here is the account that the state transition is affecting + // e.g. Account that is transferring some Coins + signers := sigTx.GetSigners() + // Current only supports one signer (TODO review in the future) + if len(signers) != 1 { + return nil, sdkerrors.Wrap(sdkerrortypes.ErrorInvalidSigner, "only one signer is supported") + } + + // Sender here is the account that signed the transaction + // Could be different from the account above (confusingly named signer) + signatures, _ := sigTx.GetSignaturesV2() + if len(signatures) == 0 { + return nil, sdkerrors.Wrap(sdkerrortypes.ErrNoSignatures, "no signatures found") + } + senderAddr, err := sdk.AccAddressFromHexUnsafe(signatures[0].PubKey.Address().String()) + if err != nil { + return nil, err + } + + msgs := sigTx.GetMsgs() + anyMsgs, err := tx2.SetMsgs(msgs) + if err != nil { + return nil, err + } + var stargateMsgs []wasmvmtypes.CosmosMsg + for _, msg := range anyMsgs { + stargateMsg := wasmvmtypes.StargateMsg{ + TypeURL: msg.TypeUrl, + Value: msg.Value, + } + stargateMsgs = append(stargateMsgs, wasmvmtypes.CosmosMsg{ + Stargate: &stargateMsg, + }) + } + preTx := smartaccounttypes.PreTransaction{ + Sender: senderAddr.String(), + Account: signers[0].String(), + Messages: stargateMsgs, + } + msg := smartaccounttypes.SudoMsg{PreTransaction: &preTx} + return json.Marshal(msg) +} diff --git a/x/smartaccount/ante/smartaccount.go b/x/smartaccount/ante/smartaccount.go deleted file mode 100644 index 8b96a3be..00000000 --- a/x/smartaccount/ante/smartaccount.go +++ /dev/null @@ -1,49 +0,0 @@ -package ante - -import ( - sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" -) - -// SmartAccountCheckDecorator does authentication for smart accounts -type SmartAccountCheckDecorator struct { - smartaccountKeeper SmartAccountKeeper -} - -func NewFeeMarketCheckDecorator(sak SmartAccountKeeper) SmartAccountCheckDecorator { - return SmartAccountCheckDecorator{ - smartaccountKeeper: sak, - } -} - -// AnteHandle checks if the tx provides sufficient fee to cover the required fee from the fee market. -func (sad SmartAccountCheckDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (sdk.Context, error) { - // check if the tx is from a smart account - setting, err := sad.smartaccountKeeper.GetSetting(ctx, tx.GetMsgs()[0].GetSigners()[0].String()) - if sdkerrors.ErrKeyNotFound.Is(err) { - return next(ctx, tx, simulate) - } else if err != nil { - return ctx, err - } - - if setting.Authorization != nil && len(setting.Authorization) > 0 { - for _, auth := range setting.Authorization { - _ = auth - // TODO: add code that calls authorization on contracts - if err != nil && setting.Fallback { - return next(ctx, tx, simulate) - } else if err != nil { - return ctx, err - } - } - } - - if setting.PreTransaction != nil && len(setting.PreTransaction) > 0 { - for _, preTx := range setting.PreTransaction { - _ = preTx - // TODO: add code that calls pre-transaction on contracts - } - } - - return next(ctx, tx, simulate) -} diff --git a/x/smartaccount/ante/tests/ante_test.go b/x/smartaccount/ante/tests/ante_test.go new file mode 100644 index 00000000..48dfc44d --- /dev/null +++ b/x/smartaccount/ante/tests/ante_test.go @@ -0,0 +1,55 @@ +package tests + +import ( + wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/tx" + sdk "github.com/cosmos/cosmos-sdk/types" + authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" + "github.com/terra-money/core/v2/x/smartaccount/ante" + "github.com/terra-money/core/v2/x/smartaccount/test_helpers" + "testing" +) + +type AnteTestSuite struct { + test_helpers.SmartAccountTestSuite + + Decorator ante.PreTransactionHookDecorator + WasmKeeper *wasmkeeper.PermissionedKeeper +} + +func TestAnteSuite(t *testing.T) { + suite.Run(t, new(AnteTestSuite)) +} + +func (s *AnteTestSuite) Setup() { + s.SmartAccountTestSuite.Setup() + s.WasmKeeper = wasmkeeper.NewDefaultPermissionKeeper(s.App.Keepers.WasmKeeper) + s.Decorator = ante.NewPreTransactionHookDecorator(s.SmartAccountKeeper, s.WasmKeeper) +} + +func (s *AnteTestSuite) BuildDefaultMsgTx(accountIndex int, msgs ...sdk.Msg) client.TxBuilder { + pk := s.TestAccPrivs[accountIndex] + txBuilder := s.EncodingConfig.TxConfig.NewTxBuilder() + err := txBuilder.SetMsgs( + msgs..., + ) + require.NoError(s.T(), err) + signer := authsigning.SignerData{ + ChainID: "test", + AccountNumber: 0, + Sequence: 0, + } + sig, err := tx.SignWithPrivKey( + s.EncodingConfig.TxConfig.SignModeHandler().DefaultMode(), + signer, + txBuilder, + pk, + s.EncodingConfig.TxConfig, + 0, + ) + txBuilder.SetSignatures(sig) + return txBuilder +} diff --git a/x/smartaccount/ante/tests/pretransaction_test.go b/x/smartaccount/ante/tests/pretransaction_test.go new file mode 100644 index 00000000..dee3b642 --- /dev/null +++ b/x/smartaccount/ante/tests/pretransaction_test.go @@ -0,0 +1,89 @@ +package tests + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/bank/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + "github.com/stretchr/testify/require" + "github.com/terra-money/core/v2/x/smartaccount/test_helpers" + smartaccounttypes "github.com/terra-money/core/v2/x/smartaccount/types" +) + +func (s *AnteTestSuite) TestPreTransactionHookWithoutSmartAccount() { + s.Setup() + txBuilder := s.BuildDefaultMsgTx(0, &types.MsgSend{ + FromAddress: s.TestAccs[0].String(), + ToAddress: s.TestAccs[1].String(), + Amount: sdk.NewCoins(sdk.NewInt64Coin("uluna", 100000000)), + }) + _, err := s.Decorator.AnteHandle(s.Ctx, txBuilder.GetTx(), false, sdk.ChainAnteDecorators(sdk.Terminator{})) + require.NoError(s.T(), err) +} + +func (s *AnteTestSuite) TestPreTransactionHookWithEmptySmartAccount() { + s.Setup() + s.Ctx = s.Ctx.WithValue(smartaccounttypes.ModuleName, smartaccounttypes.Setting{}) + txBuilder := s.BuildDefaultMsgTx(0, &types.MsgSend{ + FromAddress: s.TestAccs[0].String(), + ToAddress: s.TestAccs[1].String(), + Amount: sdk.NewCoins(sdk.NewInt64Coin("uluna", 100000000)), + }) + _, err := s.Decorator.AnteHandle(s.Ctx, txBuilder.GetTx(), false, sdk.ChainAnteDecorators(sdk.Terminator{})) + require.NoError(s.T(), err) +} + +func (s *AnteTestSuite) TestInvalidContractAddress() { + s.Setup() + s.Ctx = s.Ctx.WithValue(smartaccounttypes.ModuleName, smartaccounttypes.Setting{ + PreTransaction: []string{s.TestAccs[0].String()}, + }) + txBuilder := s.BuildDefaultMsgTx(0, &types.MsgSend{ + FromAddress: s.TestAccs[0].String(), + ToAddress: s.TestAccs[1].String(), + Amount: sdk.NewCoins(sdk.NewInt64Coin("uluna", 100000000)), + }) + _, err := s.Decorator.AnteHandle(s.Ctx, txBuilder.GetTx(), false, sdk.ChainAnteDecorators(sdk.Terminator{})) + require.ErrorContainsf(s.T(), err, "no such contract", "error message: %s", err) +} + +func (s *AnteTestSuite) TestSendCoinsWithLimitSendHook() { + s.Setup() + + acc := s.TestAccs[0] + codeId, _, err := s.WasmKeeper.Create(s.Ctx, acc, test_helpers.LimitSendOnlyHookWasm, nil) + require.NoError(s.T(), err) + contractAddr, _, err := s.WasmKeeper.Instantiate(s.Ctx, codeId, acc, acc, []byte("{}"), "limit send", sdk.NewCoins()) + require.NoError(s.T(), err) + + s.Ctx = s.Ctx.WithValue(smartaccounttypes.ModuleName, smartaccounttypes.Setting{ + PreTransaction: []string{contractAddr.String()}, + }) + txBuilder := s.BuildDefaultMsgTx(0, &types.MsgSend{ + FromAddress: acc.String(), + ToAddress: acc.String(), + Amount: sdk.NewCoins(sdk.NewInt64Coin("uluna", 100000000)), + }) + _, err = s.Decorator.AnteHandle(s.Ctx, txBuilder.GetTx(), false, sdk.ChainAnteDecorators(sdk.Terminator{})) + require.NoError(s.T(), err) +} + +func (s *AnteTestSuite) TestStakingWithLimitSendHook() { + s.Setup() + + acc := s.TestAccs[0] + codeId, _, err := s.WasmKeeper.Create(s.Ctx, acc, test_helpers.LimitSendOnlyHookWasm, nil) + require.NoError(s.T(), err) + contractAddr, _, err := s.WasmKeeper.Instantiate(s.Ctx, codeId, acc, acc, []byte("{}"), "limit send", sdk.NewCoins()) + require.NoError(s.T(), err) + + s.Ctx = s.Ctx.WithValue(smartaccounttypes.ModuleName, smartaccounttypes.Setting{ + PreTransaction: []string{contractAddr.String()}, + }) + txBuilder := s.BuildDefaultMsgTx(0, &stakingtypes.MsgDelegate{ + DelegatorAddress: acc.String(), + ValidatorAddress: acc.String(), + Amount: sdk.NewInt64Coin("uluna", 100000000), + }) + _, err = s.Decorator.AnteHandle(s.Ctx, txBuilder.GetTx(), false, sdk.ChainAnteDecorators(sdk.Terminator{})) + require.ErrorContainsf(s.T(), err, "Unauthorized message type", "error message: %s", err) +} diff --git a/x/smartaccount/client/cli/query.go b/x/smartaccount/client/cli/query.go index aea74be7..c8f810e8 100644 --- a/x/smartaccount/client/cli/query.go +++ b/x/smartaccount/client/cli/query.go @@ -24,6 +24,7 @@ func GetQueryCmd() *cobra.Command { smartAccountsQueryCmd.AddCommand( GetCmdQueryParams(), + GetCmdQuerySetting(), ) return smartAccountsQueryCmd @@ -58,3 +59,33 @@ func GetCmdQueryParams() *cobra.Command { return cmd } + +func GetCmdQuerySetting() *cobra.Command { + cmd := &cobra.Command{ + Use: "setting", + Short: "Query the current smartaccount setting for address", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + queryClient := types.NewQueryClient(clientCtx) + + req := &types.QuerySettingRequest{ + Address: args[0], + } + + res, err := queryClient.Setting(context.Background(), req) + if err != nil { + return err + } + + return clientCtx.PrintProto(&res.Setting) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + + return cmd +} diff --git a/x/smartaccount/client/cli/tx.go b/x/smartaccount/client/cli/tx.go index e96fbd4c..9f8c1c73 100644 --- a/x/smartaccount/client/cli/tx.go +++ b/x/smartaccount/client/cli/tx.go @@ -4,13 +4,15 @@ import ( "github.com/spf13/cobra" "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/client/tx" "github.com/terra-money/core/v2/x/smartaccount/types" ) // NewTxCmd returns a root CLI command handler for certain modules/SmartAccounts // transaction commands. -func NewTxCmd() *cobra.Command { +func GetTxCmd() *cobra.Command { txCmd := &cobra.Command{ Use: types.ModuleName, Short: "SmartAccounts subcommands", @@ -19,6 +21,73 @@ func NewTxCmd() *cobra.Command { RunE: client.ValidateCmd, } - txCmd.AddCommand() + txCmd.AddCommand( + NewCreateSmartAccount(), + NewDisableSmartAccount(), + ) return txCmd } + +// NewRegisterFeeShare returns a CLI command handler for registering a +// contract for fee distribution +func NewCreateSmartAccount() *cobra.Command { + cmd := &cobra.Command{ + Use: "create-smart-account", + Short: "Create a smart account for the caller.", + Long: "Create a smart account for the caller.", + Args: cobra.ExactArgs(0), + RunE: func(cmd *cobra.Command, args []string) error { + cliCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + account := cliCtx.GetFromAddress() + + msg := &types.MsgCreateSmartAccount{ + Account: account.String(), + } + + if err := msg.ValidateBasic(); err != nil { + return err + } + + return tx.GenerateOrBroadcastTxCLI(cliCtx, cmd.Flags(), msg) + }, + } + + flags.AddTxFlagsToCmd(cmd) + return cmd +} + +// NewRegisterFeeShare returns a CLI command handler for registering a +// contract for fee distribution +func NewDisableSmartAccount() *cobra.Command { + cmd := &cobra.Command{ + Use: "disable-smart-account", + Short: "Disable smart account of the caller.", + Long: "Disable a smart account of the caller.", + Args: cobra.ExactArgs(0), + RunE: func(cmd *cobra.Command, args []string) error { + cliCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + account := cliCtx.GetFromAddress() + + msg := &types.MsgDisableSmartAccount{ + Account: account.String(), + } + + if err := msg.ValidateBasic(); err != nil { + return err + } + + return tx.GenerateOrBroadcastTxCLI(cliCtx, cmd.Flags(), msg) + }, + } + + flags.AddTxFlagsToCmd(cmd) + return cmd +} diff --git a/x/smartaccount/keeper/genesis.go b/x/smartaccount/keeper/genesis.go index 93b88e7e..0eaabd73 100644 --- a/x/smartaccount/keeper/genesis.go +++ b/x/smartaccount/keeper/genesis.go @@ -32,7 +32,9 @@ func (k Keeper) ExportGenesis(ctx sdk.Context) *types.GenesisState { defer iter.Close() for ; iter.Valid(); iter.Next() { var setting types.Setting - setting.Unmarshal(iter.Value()) + if err := setting.Unmarshal(iter.Value()); err != nil { + panic(err) + } settings = append(settings, &setting) } diff --git a/x/smartaccount/keeper/grpc_query.go b/x/smartaccount/keeper/grpc_query.go index 5b6a1237..0ee809ca 100644 --- a/x/smartaccount/keeper/grpc_query.go +++ b/x/smartaccount/keeper/grpc_query.go @@ -29,3 +29,16 @@ func (q Querier) Params( params := q.GetParams(ctx) return &types.QueryParamsResponse{Params: params}, nil } + +// Setting returns the fees module setting +func (q Querier) Setting( + c context.Context, + req *types.QuerySettingRequest, +) (*types.QuerySettingResponse, error) { + ctx := sdk.UnwrapSDKContext(c) + setting, err := q.GetSetting(ctx, req.Address) + if err != nil { + return nil, err + } + return &types.QuerySettingResponse{Setting: *setting}, nil +} diff --git a/x/smartaccount/keeper/keeper.go b/x/smartaccount/keeper/keeper.go index bda28b75..83169a34 100644 --- a/x/smartaccount/keeper/keeper.go +++ b/x/smartaccount/keeper/keeper.go @@ -45,12 +45,12 @@ func (k Keeper) GetSetting(ctx sdk.Context, ownerAddr string) (*types.Setting, e return nil, sdkerrors.ErrKeyNotFound.Wrapf("setting not found for ownerAddr: %s", ownerAddr) } - var setting *types.Setting + var setting types.Setting if err := setting.Unmarshal(bz); err != nil { return nil, err } - return setting, nil + return &setting, nil } // SetSetting sets the smart account setting for the ownerAddr diff --git a/x/smartaccount/keeper/msg_server.go b/x/smartaccount/keeper/msg_server.go index ee225adb..135c55d1 100644 --- a/x/smartaccount/keeper/msg_server.go +++ b/x/smartaccount/keeper/msg_server.go @@ -22,8 +22,15 @@ func (ms MsgServer) CreateSmartAccount( goCtx context.Context, msg *types.MsgCreateSmartAccount, ) (*types.MsgCreateSmartAccountResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) + + setting, _ := ms.k.GetSetting(ctx, msg.Account) + if setting != nil { + return nil, sdkerrors.ErrInvalidRequest.Wrapf("smart account already exists for %s", msg.Account) + } + if err := ms.k.SetSetting(ctx, types.Setting{ - Owner: msg.Account, + Owner: msg.Account, + Fallback: true, }); err != nil { return nil, err } diff --git a/x/smartaccount/module.go b/x/smartaccount/module.go index 789f88dc..3c24ab6c 100644 --- a/x/smartaccount/module.go +++ b/x/smartaccount/module.go @@ -17,7 +17,6 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" simtypes "github.com/cosmos/cosmos-sdk/types/simulation" - authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" "github.com/terra-money/core/v2/x/smartaccount/client/cli" "github.com/terra-money/core/v2/x/smartaccount/exported" @@ -90,7 +89,7 @@ func (b AppModuleBasic) RegisterGRPCGatewayRoutes(c client.Context, serveMux *ru // GetTxCmd returns the root tx command for the fees module. func (AppModuleBasic) GetTxCmd() *cobra.Command { - return cli.NewTxCmd() + return cli.GetTxCmd() } // GetQueryCmd returns the fees module's root query command. @@ -104,7 +103,6 @@ func (AppModuleBasic) GetQueryCmd() *cobra.Command { type AppModule struct { AppModuleBasic keeper keeper.Keeper - ak authkeeper.AccountKeeper // legacySubspace is used solely for migration of x/params managed parameters legacySubspace exported.Subspace @@ -113,13 +111,11 @@ type AppModule struct { // NewAppModule creates a new AppModule Object func NewAppModule( k keeper.Keeper, - ak authkeeper.AccountKeeper, ss exported.Subspace, ) AppModule { return AppModule{ AppModuleBasic: AppModuleBasic{}, keeper: k, - ak: ak, legacySubspace: ss, } } diff --git a/x/smartaccount/post/smartaccount.go b/x/smartaccount/post/smartaccount_posttx.go similarity index 100% rename from x/smartaccount/post/smartaccount.go rename to x/smartaccount/post/smartaccount_posttx.go diff --git a/x/smartaccount/test_helpers/test_data.go b/x/smartaccount/test_helpers/test_data.go new file mode 100644 index 00000000..8ef8b151 --- /dev/null +++ b/x/smartaccount/test_helpers/test_data.go @@ -0,0 +1,9 @@ +package test_helpers + +import _ "embed" + +//go:embed test_data/limit_send_only_hooks.wasm +var LimitSendOnlyHookWasm []byte + +//go:embed test_data/smart_auth_contract.wasm +var SmartAuthContractWasm []byte diff --git a/x/smartaccount/test_helpers/test_data/limit_send_only_hooks.wasm b/x/smartaccount/test_helpers/test_data/limit_send_only_hooks.wasm new file mode 100755 index 00000000..a727b685 Binary files /dev/null and b/x/smartaccount/test_helpers/test_data/limit_send_only_hooks.wasm differ diff --git a/x/smartaccount/test_helpers/test_data/smart_auth_contract.wasm b/x/smartaccount/test_helpers/test_data/smart_auth_contract.wasm new file mode 100755 index 00000000..8cb4f47d Binary files /dev/null and b/x/smartaccount/test_helpers/test_data/smart_auth_contract.wasm differ diff --git a/x/smartaccount/test_helpers/test_helpers.go b/x/smartaccount/test_helpers/test_helpers.go new file mode 100644 index 00000000..b32de108 --- /dev/null +++ b/x/smartaccount/test_helpers/test_helpers.go @@ -0,0 +1,20 @@ +package test_helpers + +import ( + "github.com/terra-money/core/v2/app/test_helpers" + "github.com/terra-money/core/v2/x/smartaccount/keeper" + wasmkeeper "github.com/terra-money/core/v2/x/wasm/keeper" +) + +type SmartAccountTestSuite struct { + test_helpers.AppTestSuite + + SmartAccountKeeper keeper.Keeper + WasmKeeper wasmkeeper.Keeper +} + +func (s *SmartAccountTestSuite) SetupTests() { + s.Setup() + s.SmartAccountKeeper = s.App.Keepers.SmartAccountKeeper + s.WasmKeeper = s.App.Keepers.WasmKeeper +} diff --git a/x/smartaccount/types/events.go b/x/smartaccount/types/events.go deleted file mode 100644 index 861e6862..00000000 --- a/x/smartaccount/types/events.go +++ /dev/null @@ -1,13 +0,0 @@ -package types - -const ( - EventTypeRegisterFeeShare = "register_feeshare" - EventTypeCancelFeeShare = "cancel_feeshare" - EventTypeUpdateFeeShare = "update_feeshare" - - EventTypePayoutFeeShare = "payout_feeshare" - - AttributeKeyContract = "contract" - AttributeKeyWithdrawerAddress = "withdrawer_address" - AttributeWithdrawPayouts = "payouts" -) diff --git a/x/smartaccount/types/events.pb.go b/x/smartaccount/types/events.pb.go deleted file mode 100644 index 41ca7a98..00000000 --- a/x/smartaccount/types/events.pb.go +++ /dev/null @@ -1,389 +0,0 @@ -// Code generated by protoc-gen-gogo. DO NOT EDIT. -// source: juno/feeshare/v1/events.proto - -package types - -import ( - fmt "fmt" - types "github.com/cosmos/cosmos-sdk/types" - _ "github.com/cosmos/gogoproto/gogoproto" - proto "github.com/cosmos/gogoproto/proto" - io "io" - math "math" - math_bits "math/bits" -) - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package - -// FeeShareEvent defines an instance that organizes fee distribution conditions for -// the owner of a given smart contract -type FeePayoutEvent struct { - // Address of the account that will receive the payout - WithdrawAddress string `protobuf:"bytes,1,opt,name=withdraw_address,json=withdrawAddress,proto3" json:"withdraw_address,omitempty"` - // Amount of the payout - FeesPaid []types.Coin `protobuf:"bytes,2,rep,name=fees_paid,json=feesPaid,proto3" json:"fees_paid"` -} - -func (m *FeePayoutEvent) Reset() { *m = FeePayoutEvent{} } -func (m *FeePayoutEvent) String() string { return proto.CompactTextString(m) } -func (*FeePayoutEvent) ProtoMessage() {} -func (*FeePayoutEvent) Descriptor() ([]byte, []int) { - return fileDescriptor_19637fb89a9eac93, []int{0} -} -func (m *FeePayoutEvent) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *FeePayoutEvent) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_FeePayoutEvent.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *FeePayoutEvent) XXX_Merge(src proto.Message) { - xxx_messageInfo_FeePayoutEvent.Merge(m, src) -} -func (m *FeePayoutEvent) XXX_Size() int { - return m.Size() -} -func (m *FeePayoutEvent) XXX_DiscardUnknown() { - xxx_messageInfo_FeePayoutEvent.DiscardUnknown(m) -} - -var xxx_messageInfo_FeePayoutEvent proto.InternalMessageInfo - -func (m *FeePayoutEvent) GetWithdrawAddress() string { - if m != nil { - return m.WithdrawAddress - } - return "" -} - -func (m *FeePayoutEvent) GetFeesPaid() []types.Coin { - if m != nil { - return m.FeesPaid - } - return nil -} - -func init() { - proto.RegisterType((*FeePayoutEvent)(nil), "juno.feeshare.v1.FeePayoutEvent") -} - -func init() { proto.RegisterFile("juno/feeshare/v1/events.proto", fileDescriptor_19637fb89a9eac93) } - -var fileDescriptor_19637fb89a9eac93 = []byte{ - // 267 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x44, 0x90, 0xb1, 0x4e, 0xc3, 0x30, - 0x18, 0x84, 0x13, 0x40, 0x88, 0x06, 0x09, 0xaa, 0x88, 0xa1, 0x54, 0xc2, 0x54, 0x4c, 0x65, 0xb1, - 0x09, 0xac, 0x2c, 0x34, 0x82, 0x81, 0xa9, 0xea, 0xc8, 0x52, 0x39, 0xf1, 0x4f, 0x62, 0xa4, 0xfa, - 0x8f, 0x6c, 0x27, 0x25, 0x6f, 0xc1, 0x63, 0x75, 0xec, 0xc8, 0x84, 0x50, 0xf2, 0x22, 0xc8, 0x09, - 0x55, 0xb7, 0xd3, 0x9d, 0xcf, 0xfe, 0x7c, 0xc1, 0xd5, 0x47, 0xa9, 0x90, 0xbd, 0x03, 0x98, 0x9c, - 0x6b, 0x60, 0x55, 0xc4, 0xa0, 0x02, 0x65, 0x0d, 0x2d, 0x34, 0x5a, 0x0c, 0x87, 0x2e, 0xa6, 0xbb, - 0x98, 0x56, 0xd1, 0x98, 0xa4, 0x68, 0x56, 0x68, 0x58, 0xc2, 0x8d, 0x3b, 0x9e, 0x80, 0xe5, 0x11, - 0x4b, 0x51, 0xaa, 0xbe, 0x31, 0xbe, 0xc8, 0x30, 0xc3, 0x4e, 0x32, 0xa7, 0x7a, 0xf7, 0xa6, 0x0e, - 0xce, 0x5e, 0x00, 0xe6, 0xbc, 0xc6, 0xd2, 0x3e, 0xbb, 0x07, 0xc2, 0xdb, 0x60, 0xb8, 0x96, 0x36, - 0x17, 0x9a, 0xaf, 0x97, 0x5c, 0x08, 0x0d, 0xc6, 0x8c, 0xfc, 0x89, 0x3f, 0x1d, 0x2c, 0xce, 0x77, - 0xfe, 0x53, 0x6f, 0x87, 0x8f, 0xc1, 0xc0, 0x11, 0x2c, 0x0b, 0x2e, 0xc5, 0xe8, 0x60, 0x72, 0x38, - 0x3d, 0xbd, 0xbf, 0xa4, 0x3d, 0x06, 0x75, 0x18, 0xf4, 0x1f, 0x83, 0xc6, 0x28, 0xd5, 0xec, 0x68, - 0xf3, 0x73, 0xed, 0x2d, 0x4e, 0x5c, 0x63, 0xce, 0xa5, 0x98, 0xbd, 0x6e, 0x1a, 0xe2, 0x6f, 0x1b, - 0xe2, 0xff, 0x36, 0xc4, 0xff, 0x6a, 0x89, 0xb7, 0x6d, 0x89, 0xf7, 0xdd, 0x12, 0xef, 0xed, 0x2e, - 0x93, 0x36, 0x2f, 0x13, 0x9a, 0xe2, 0x8a, 0xc5, 0xdd, 0x75, 0x31, 0x2a, 0xab, 0x79, 0x6a, 0x0d, - 0xeb, 0x66, 0xf9, 0xdc, 0x0f, 0x63, 0xeb, 0x02, 0x4c, 0x72, 0xdc, 0xfd, 0xe6, 0xe1, 0x2f, 0x00, - 0x00, 0xff, 0xff, 0xc2, 0xe4, 0xe9, 0x71, 0x36, 0x01, 0x00, 0x00, -} - -func (m *FeePayoutEvent) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *FeePayoutEvent) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *FeePayoutEvent) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.FeesPaid) > 0 { - for iNdEx := len(m.FeesPaid) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.FeesPaid[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintEvents(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - } - } - if len(m.WithdrawAddress) > 0 { - i -= len(m.WithdrawAddress) - copy(dAtA[i:], m.WithdrawAddress) - i = encodeVarintEvents(dAtA, i, uint64(len(m.WithdrawAddress))) - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func encodeVarintEvents(dAtA []byte, offset int, v uint64) int { - offset -= sovEvents(v) - base := offset - for v >= 1<<7 { - dAtA[offset] = uint8(v&0x7f | 0x80) - v >>= 7 - offset++ - } - dAtA[offset] = uint8(v) - return base -} -func (m *FeePayoutEvent) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.WithdrawAddress) - if l > 0 { - n += 1 + l + sovEvents(uint64(l)) - } - if len(m.FeesPaid) > 0 { - for _, e := range m.FeesPaid { - l = e.Size() - n += 1 + l + sovEvents(uint64(l)) - } - } - return n -} - -func sovEvents(x uint64) (n int) { - return (math_bits.Len64(x|1) + 6) / 7 -} -func sozEvents(x uint64) (n int) { - return sovEvents(uint64((x << 1) ^ uint64((int64(x) >> 63)))) -} -func (m *FeePayoutEvent) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowEvents - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: FeePayoutEvent: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: FeePayoutEvent: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field WithdrawAddress", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowEvents - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthEvents - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthEvents - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.WithdrawAddress = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field FeesPaid", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowEvents - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthEvents - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthEvents - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.FeesPaid = append(m.FeesPaid, types.Coin{}) - if err := m.FeesPaid[len(m.FeesPaid)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipEvents(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthEvents - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func skipEvents(dAtA []byte) (n int, err error) { - l := len(dAtA) - iNdEx := 0 - depth := 0 - for iNdEx < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowEvents - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - wireType := int(wire & 0x7) - switch wireType { - case 0: - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowEvents - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - iNdEx++ - if dAtA[iNdEx-1] < 0x80 { - break - } - } - case 1: - iNdEx += 8 - case 2: - var length int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowEvents - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - length |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if length < 0 { - return 0, ErrInvalidLengthEvents - } - iNdEx += length - case 3: - depth++ - case 4: - if depth == 0 { - return 0, ErrUnexpectedEndOfGroupEvents - } - depth-- - case 5: - iNdEx += 4 - default: - return 0, fmt.Errorf("proto: illegal wireType %d", wireType) - } - if iNdEx < 0 { - return 0, ErrInvalidLengthEvents - } - if depth == 0 { - return iNdEx, nil - } - } - return 0, io.ErrUnexpectedEOF -} - -var ( - ErrInvalidLengthEvents = fmt.Errorf("proto: negative length found during unmarshaling") - ErrIntOverflowEvents = fmt.Errorf("proto: integer overflow") - ErrUnexpectedEndOfGroupEvents = fmt.Errorf("proto: unexpected end of group") -) diff --git a/x/smartaccount/types/msg.go b/x/smartaccount/types/msg.go deleted file mode 100644 index ab1254f4..00000000 --- a/x/smartaccount/types/msg.go +++ /dev/null @@ -1 +0,0 @@ -package types diff --git a/x/smartaccount/types/msgs.go b/x/smartaccount/types/msgs.go new file mode 100644 index 00000000..e6fd9fc9 --- /dev/null +++ b/x/smartaccount/types/msgs.go @@ -0,0 +1,74 @@ +package types + +import sdk "github.com/cosmos/cosmos-sdk/types" + +var ( + _ sdk.Msg = &MsgCreateSmartAccount{} + _ sdk.Msg = &MsgDisableSmartAccount{} + _ sdk.Msg = &MsgUpdateAuthorization{} + _ sdk.Msg = &MsgUpdateTransactionHooks{} +) + +// GetSignBytes implements the LegacyMsg interface. +func (m MsgCreateSmartAccount) GetSignBytes() []byte { + return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(&m)) +} + +// GetSigners returns the expected signers for a MsgUpdateParams message. +func (m MsgCreateSmartAccount) GetSigners() []sdk.AccAddress { + addr, _ := sdk.AccAddressFromBech32(m.Account) + return []sdk.AccAddress{addr} +} + +// ValidateBasic does a sanity check on the provided data. +func (m MsgCreateSmartAccount) ValidateBasic() error { + return nil +} + +// GetSignBytes implements the LegacyMsg interface. +func (m MsgDisableSmartAccount) GetSignBytes() []byte { + return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(&m)) +} + +// GetSigners returns the expected signers for a MsgUpdateParams message. +func (m MsgDisableSmartAccount) GetSigners() []sdk.AccAddress { + addr, _ := sdk.AccAddressFromBech32(m.Account) + return []sdk.AccAddress{addr} +} + +// ValidateBasic does a sanity check on the provided data. +func (m MsgDisableSmartAccount) ValidateBasic() error { + return nil +} + +// GetSignBytes implements the LegacyMsg interface. +func (m MsgUpdateAuthorization) GetSignBytes() []byte { + return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(&m)) +} + +// GetSigners returns the expected signers for a MsgUpdateParams message. +func (m MsgUpdateAuthorization) GetSigners() []sdk.AccAddress { + addr, _ := sdk.AccAddressFromBech32(m.Account) + return []sdk.AccAddress{addr} +} + +// ValidateBasic does a sanity check on the provided data. +func (m MsgUpdateAuthorization) ValidateBasic() error { + return nil +} + +// GetSignBytes implements the LegacyMsg interface. +func (m MsgUpdateTransactionHooks) GetSignBytes() []byte { + return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(&m)) +} + +// GetSigners returns the expected signers for a MsgUpdateParams message. +func (m MsgUpdateTransactionHooks) GetSigners() []sdk.AccAddress { + addr, _ := sdk.AccAddressFromBech32(m.Account) + return []sdk.AccAddress{addr} +} + +// ValidateBasic does a sanity check on the provided data. +func (m MsgUpdateTransactionHooks) ValidateBasic() error { + return nil +} diff --git a/x/smartaccount/types/params_legacy.go b/x/smartaccount/types/params_legacy.go new file mode 100644 index 00000000..01d45683 --- /dev/null +++ b/x/smartaccount/types/params_legacy.go @@ -0,0 +1,18 @@ +package types + +import ( + paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" +) + +// Parameter store key +var () + +// ParamKeyTable returns the parameter key table. +func ParamKeyTable() paramtypes.KeyTable { + return paramtypes.NewKeyTable().RegisterParamSet(&Params{}) +} + +// ParamSetPairs returns the parameter set pairs. +func (p *Params) ParamSetPairs() paramtypes.ParamSetPairs { + return paramtypes.ParamSetPairs{} +} diff --git a/x/smartaccount/types/query.pb.go b/x/smartaccount/types/query.pb.go index b1222a80..d8711a07 100644 --- a/x/smartaccount/types/query.pb.go +++ b/x/smartaccount/types/query.pb.go @@ -112,34 +112,129 @@ func (m *QueryParamsResponse) GetParams() Params { return Params{} } +type QuerySettingRequest struct { + Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` +} + +func (m *QuerySettingRequest) Reset() { *m = QuerySettingRequest{} } +func (m *QuerySettingRequest) String() string { return proto.CompactTextString(m) } +func (*QuerySettingRequest) ProtoMessage() {} +func (*QuerySettingRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_93504f0f37d1a258, []int{2} +} +func (m *QuerySettingRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QuerySettingRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QuerySettingRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QuerySettingRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QuerySettingRequest.Merge(m, src) +} +func (m *QuerySettingRequest) XXX_Size() int { + return m.Size() +} +func (m *QuerySettingRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QuerySettingRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QuerySettingRequest proto.InternalMessageInfo + +func (m *QuerySettingRequest) GetAddress() string { + if m != nil { + return m.Address + } + return "" +} + +type QuerySettingResponse struct { + Setting Setting `protobuf:"bytes,1,opt,name=setting,proto3" json:"setting"` +} + +func (m *QuerySettingResponse) Reset() { *m = QuerySettingResponse{} } +func (m *QuerySettingResponse) String() string { return proto.CompactTextString(m) } +func (*QuerySettingResponse) ProtoMessage() {} +func (*QuerySettingResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_93504f0f37d1a258, []int{3} +} +func (m *QuerySettingResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QuerySettingResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QuerySettingResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QuerySettingResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QuerySettingResponse.Merge(m, src) +} +func (m *QuerySettingResponse) XXX_Size() int { + return m.Size() +} +func (m *QuerySettingResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QuerySettingResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QuerySettingResponse proto.InternalMessageInfo + +func (m *QuerySettingResponse) GetSetting() Setting { + if m != nil { + return m.Setting + } + return Setting{} +} + func init() { proto.RegisterType((*QueryParamsRequest)(nil), "terra.smartaccount.v1.QueryParamsRequest") proto.RegisterType((*QueryParamsResponse)(nil), "terra.smartaccount.v1.QueryParamsResponse") + proto.RegisterType((*QuerySettingRequest)(nil), "terra.smartaccount.v1.QuerySettingRequest") + proto.RegisterType((*QuerySettingResponse)(nil), "terra.smartaccount.v1.QuerySettingResponse") } func init() { proto.RegisterFile("terra/smartaccount/v1/query.proto", fileDescriptor_93504f0f37d1a258) } var fileDescriptor_93504f0f37d1a258 = []byte{ - // 289 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x52, 0x2c, 0x49, 0x2d, 0x2a, - 0x4a, 0xd4, 0x2f, 0xce, 0x4d, 0x2c, 0x2a, 0x49, 0x4c, 0x4e, 0xce, 0x2f, 0xcd, 0x2b, 0xd1, 0x2f, - 0x33, 0xd4, 0x2f, 0x2c, 0x4d, 0x2d, 0xaa, 0xd4, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x12, 0x05, - 0x2b, 0xd1, 0x43, 0x56, 0xa2, 0x57, 0x66, 0x28, 0x25, 0x92, 0x9e, 0x9f, 0x9e, 0x0f, 0x56, 0xa1, - 0x0f, 0x62, 0x41, 0x14, 0x4b, 0xc9, 0xa4, 0xe7, 0xe7, 0xa7, 0xe7, 0xa4, 0xea, 0x27, 0x16, 0x64, - 0xea, 0x27, 0xe6, 0xe5, 0xe5, 0x97, 0x24, 0x96, 0x64, 0xe6, 0xe7, 0x15, 0x43, 0x65, 0x95, 0xb0, - 0xdb, 0x56, 0x90, 0x58, 0x94, 0x98, 0x0b, 0x55, 0xa3, 0x24, 0xc2, 0x25, 0x14, 0x08, 0xb2, 0x3d, - 0x00, 0x2c, 0x18, 0x94, 0x5a, 0x58, 0x9a, 0x5a, 0x5c, 0xa2, 0x14, 0xc4, 0x25, 0x8c, 0x22, 0x5a, - 0x5c, 0x90, 0x9f, 0x57, 0x9c, 0x2a, 0x64, 0xcd, 0xc5, 0x06, 0xd1, 0x2c, 0xc1, 0xa8, 0xc0, 0xa8, - 0xc1, 0x6d, 0x24, 0xab, 0x87, 0xd5, 0xb1, 0x7a, 0x10, 0x6d, 0x4e, 0x2c, 0x27, 0xee, 0xc9, 0x33, - 0x04, 0x41, 0xb5, 0x18, 0x4d, 0x60, 0xe4, 0x62, 0x05, 0x1b, 0x2a, 0xd4, 0xc6, 0xc8, 0xc5, 0x06, - 0x51, 0x22, 0xa4, 0x89, 0xc3, 0x04, 0x4c, 0x37, 0x49, 0x69, 0x11, 0xa3, 0x14, 0xe2, 0x50, 0x25, - 0xd5, 0xa6, 0xcb, 0x4f, 0x26, 0x33, 0xc9, 0x0b, 0xc9, 0xea, 0xe3, 0x0b, 0x02, 0x27, 0xdf, 0x13, - 0x8f, 0xe4, 0x18, 0x2f, 0x3c, 0x92, 0x63, 0x7c, 0xf0, 0x48, 0x8e, 0x71, 0xc2, 0x63, 0x39, 0x86, - 0x0b, 0x8f, 0xe5, 0x18, 0x6e, 0x3c, 0x96, 0x63, 0x88, 0x32, 0x4e, 0xcf, 0x2c, 0xc9, 0x28, 0x4d, - 0xd2, 0x4b, 0xce, 0xcf, 0x85, 0x18, 0xa1, 0x9b, 0x9b, 0x9f, 0x97, 0x5a, 0xa9, 0x9f, 0x9c, 0x5f, - 0x94, 0xaa, 0x5f, 0x66, 0xa4, 0x5f, 0x81, 0x6a, 0x64, 0x49, 0x65, 0x41, 0x6a, 0x71, 0x12, 0x1b, - 0x38, 0x48, 0x8d, 0x01, 0x01, 0x00, 0x00, 0xff, 0xff, 0x14, 0xc4, 0x3e, 0x0c, 0xe6, 0x01, 0x00, - 0x00, + // 379 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x92, 0x4f, 0x4b, 0xf3, 0x30, + 0x1c, 0xc7, 0xdb, 0xf1, 0x3c, 0x1b, 0xc6, 0x5b, 0x9c, 0x30, 0x8a, 0xcb, 0xb4, 0x22, 0x3a, 0xc5, + 0x86, 0x6d, 0x47, 0xc1, 0xc3, 0xee, 0x82, 0x56, 0xf0, 0xe0, 0x2d, 0xeb, 0x42, 0x2d, 0xd8, 0xa4, + 0x4b, 0xd2, 0xe1, 0x10, 0x2f, 0x1e, 0x3c, 0x0b, 0x7b, 0x0f, 0xbe, 0x96, 0x1d, 0x07, 0x5e, 0x3c, + 0x89, 0x6c, 0xbe, 0x10, 0x59, 0x93, 0x81, 0xc5, 0x6d, 0xec, 0xd6, 0x3f, 0x9f, 0xef, 0xf7, 0xf7, + 0xc9, 0xaf, 0x05, 0x7b, 0x8a, 0x0a, 0x41, 0xb0, 0x8c, 0x89, 0x50, 0x24, 0x08, 0x78, 0xca, 0x14, + 0xee, 0x37, 0x70, 0x2f, 0xa5, 0x62, 0xe0, 0x25, 0x82, 0x2b, 0x0e, 0xb7, 0x33, 0xc4, 0xfb, 0x8d, + 0x78, 0xfd, 0x86, 0x53, 0x0e, 0x79, 0xc8, 0x33, 0x02, 0xcf, 0xae, 0x34, 0xec, 0xec, 0x84, 0x9c, + 0x87, 0xf7, 0x14, 0x93, 0x24, 0xc2, 0x84, 0x31, 0xae, 0x88, 0x8a, 0x38, 0x93, 0xe6, 0xad, 0xbb, + 0x78, 0x5a, 0x42, 0x04, 0x89, 0xe7, 0xcc, 0xfe, 0x62, 0x46, 0x52, 0xa5, 0x22, 0x16, 0x6a, 0xc8, + 0x2d, 0x03, 0x78, 0x35, 0x53, 0xbc, 0xcc, 0x92, 0x3e, 0xed, 0xa5, 0x54, 0x2a, 0xd7, 0x07, 0x5b, + 0xb9, 0xa7, 0x32, 0xe1, 0x4c, 0x52, 0x78, 0x06, 0x8a, 0x7a, 0x42, 0xc5, 0xde, 0xb5, 0x8f, 0x36, + 0x9b, 0x55, 0x6f, 0xe1, 0x89, 0x3c, 0x1d, 0x6b, 0xff, 0x1b, 0x7d, 0xd6, 0x2c, 0xdf, 0x44, 0x5c, + 0x6c, 0x3a, 0xaf, 0xf5, 0x7c, 0x33, 0x0a, 0x56, 0x40, 0x89, 0x74, 0xbb, 0x82, 0x4a, 0x5d, 0xba, + 0xe1, 0xcf, 0x6f, 0xdd, 0x1b, 0x50, 0xce, 0x07, 0x8c, 0xc5, 0x39, 0x28, 0x99, 0x33, 0x18, 0x0d, + 0xb4, 0x44, 0xc3, 0x04, 0x8d, 0xc7, 0x3c, 0xd4, 0x7c, 0x2b, 0x80, 0xff, 0x59, 0x31, 0x7c, 0xb1, + 0x41, 0x51, 0xbb, 0xc2, 0xfa, 0x92, 0x8e, 0xbf, 0xcb, 0x71, 0x8e, 0xd7, 0x41, 0xb5, 0xab, 0x7b, + 0xf0, 0xfc, 0xfe, 0x3d, 0x2c, 0xd4, 0x60, 0x15, 0xaf, 0xfa, 0x60, 0x70, 0x68, 0x83, 0x92, 0xb1, + 0x85, 0x2b, 0xeb, 0xf3, 0xcb, 0x73, 0x4e, 0xd6, 0x62, 0x8d, 0x0b, 0xce, 0x5c, 0xea, 0xf0, 0x70, + 0xa5, 0x0b, 0x7e, 0x34, 0xfb, 0x7f, 0x6a, 0x5f, 0x8c, 0x26, 0xc8, 0x1e, 0x4f, 0x90, 0xfd, 0x35, + 0x41, 0xf6, 0xeb, 0x14, 0x59, 0xe3, 0x29, 0xb2, 0x3e, 0xa6, 0xc8, 0xba, 0x6d, 0x85, 0x91, 0xba, + 0x4b, 0x3b, 0x5e, 0xc0, 0x63, 0x5d, 0x76, 0x1a, 0x73, 0x46, 0x07, 0x38, 0xe0, 0x82, 0xe2, 0x7e, + 0x13, 0x3f, 0xe4, 0xcb, 0xd5, 0x20, 0xa1, 0xb2, 0x53, 0xcc, 0xfe, 0xb8, 0xd6, 0x4f, 0x00, 0x00, + 0x00, 0xff, 0xff, 0x36, 0xd5, 0xfd, 0x0e, 0x2a, 0x03, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -155,6 +250,7 @@ const _ = grpc.SupportPackageIsVersion4 // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. type QueryClient interface { Params(ctx context.Context, in *QueryParamsRequest, opts ...grpc.CallOption) (*QueryParamsResponse, error) + Setting(ctx context.Context, in *QuerySettingRequest, opts ...grpc.CallOption) (*QuerySettingResponse, error) } type queryClient struct { @@ -174,9 +270,19 @@ func (c *queryClient) Params(ctx context.Context, in *QueryParamsRequest, opts . return out, nil } +func (c *queryClient) Setting(ctx context.Context, in *QuerySettingRequest, opts ...grpc.CallOption) (*QuerySettingResponse, error) { + out := new(QuerySettingResponse) + err := c.cc.Invoke(ctx, "/terra.smartaccount.v1.Query/Setting", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // QueryServer is the server API for Query service. type QueryServer interface { Params(context.Context, *QueryParamsRequest) (*QueryParamsResponse, error) + Setting(context.Context, *QuerySettingRequest) (*QuerySettingResponse, error) } // UnimplementedQueryServer can be embedded to have forward compatible implementations. @@ -186,6 +292,9 @@ type UnimplementedQueryServer struct { func (*UnimplementedQueryServer) Params(ctx context.Context, req *QueryParamsRequest) (*QueryParamsResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method Params not implemented") } +func (*UnimplementedQueryServer) Setting(ctx context.Context, req *QuerySettingRequest) (*QuerySettingResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Setting not implemented") +} func RegisterQueryServer(s grpc1.Server, srv QueryServer) { s.RegisterService(&_Query_serviceDesc, srv) @@ -209,6 +318,24 @@ func _Query_Params_Handler(srv interface{}, ctx context.Context, dec func(interf return interceptor(ctx, in, info, handler) } +func _Query_Setting_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QuerySettingRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).Setting(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/terra.smartaccount.v1.Query/Setting", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).Setting(ctx, req.(*QuerySettingRequest)) + } + return interceptor(ctx, in, info, handler) +} + var _Query_serviceDesc = grpc.ServiceDesc{ ServiceName: "terra.smartaccount.v1.Query", HandlerType: (*QueryServer)(nil), @@ -217,6 +344,10 @@ var _Query_serviceDesc = grpc.ServiceDesc{ MethodName: "Params", Handler: _Query_Params_Handler, }, + { + MethodName: "Setting", + Handler: _Query_Setting_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "terra/smartaccount/v1/query.proto", @@ -278,6 +409,69 @@ func (m *QueryParamsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *QuerySettingRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QuerySettingRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QuerySettingRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Address) > 0 { + i -= len(m.Address) + copy(dAtA[i:], m.Address) + i = encodeVarintQuery(dAtA, i, uint64(len(m.Address))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QuerySettingResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QuerySettingResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QuerySettingResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.Setting.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + func encodeVarintQuery(dAtA []byte, offset int, v uint64) int { offset -= sovQuery(v) base := offset @@ -309,6 +503,30 @@ func (m *QueryParamsResponse) Size() (n int) { return n } +func (m *QuerySettingRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Address) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QuerySettingResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.Setting.Size() + n += 1 + l + sovQuery(uint64(l)) + return n +} + func sovQuery(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -448,6 +666,171 @@ func (m *QueryParamsResponse) Unmarshal(dAtA []byte) error { } return nil } +func (m *QuerySettingRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QuerySettingRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QuerySettingRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Address", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Address = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QuerySettingResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QuerySettingResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QuerySettingResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Setting", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Setting.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipQuery(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 diff --git a/x/smartaccount/types/query.pb.gw.go b/x/smartaccount/types/query.pb.gw.go index 1fed9b88..73026180 100644 --- a/x/smartaccount/types/query.pb.gw.go +++ b/x/smartaccount/types/query.pb.gw.go @@ -51,6 +51,60 @@ func local_request_Query_Params_0(ctx context.Context, marshaler runtime.Marshal } +func request_Query_Setting_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QuerySettingRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["address"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "address") + } + + protoReq.Address, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "address", err) + } + + msg, err := client.Setting(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_Setting_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QuerySettingRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["address"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "address") + } + + protoReq.Address, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "address", err) + } + + msg, err := server.Setting(ctx, &protoReq) + return msg, metadata, err + +} + // RegisterQueryHandlerServer registers the http handlers for service Query to "mux". // UnaryRPC :call QueryServer directly. // StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. @@ -80,6 +134,29 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv }) + mux.Handle("GET", pattern_Query_Setting_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_Setting_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_Setting_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } @@ -141,13 +218,37 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie }) + mux.Handle("GET", pattern_Query_Setting_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_Setting_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_Setting_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } var ( pattern_Query_Params_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"terra", "smartaccount", "v1", "params"}, "", runtime.AssumeColonVerbOpt(false))) + + pattern_Query_Setting_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"terra", "smartaccount", "v1", "params", "address"}, "", runtime.AssumeColonVerbOpt(false))) ) var ( forward_Query_Params_0 = runtime.ForwardResponseMessage + + forward_Query_Setting_0 = runtime.ForwardResponseMessage ) diff --git a/x/smartaccount/types/setting.go b/x/smartaccount/types/setting.go index 098fe526..2a652e94 100644 --- a/x/smartaccount/types/setting.go +++ b/x/smartaccount/types/setting.go @@ -11,7 +11,7 @@ func NewSetting(ownerAddr string) Setting { } func NewSettings() []*Setting { - return []*Setting{} + return make([]*Setting, 0) } func DefaultSettings() []*Setting { diff --git a/x/smartaccount/types/wasm.go b/x/smartaccount/types/wasm.go index 619b9b81..87265072 100644 --- a/x/smartaccount/types/wasm.go +++ b/x/smartaccount/types/wasm.go @@ -2,22 +2,27 @@ package types import "github.com/CosmWasm/wasmvm/types" +type SudoMsg struct { + PreTransaction *PreTransaction `json:"pre_transaction,omitempty"` + PostTransaction *PostTransaction `json:"post_transaction,omitempty"` +} + type Authorization struct { Sender string `json:"sender"` Account string `json:"account"` Signatures [][]byte `json:"signatures"` - SignedBytes []byte `json:"signed_bytes"` + SignedBytes [][]byte `json:"signed_bytes"` Data []byte `json:"data"` } type PreTransaction struct { - Sender string `json:"sender"` - Account string `json:"account"` - Messages []types.StargateMsg `json:"messages"` + Sender string `json:"sender"` + Account string `json:"account"` + Messages []types.CosmosMsg `json:"msgs"` } type PostTransaction struct { - Sender string `json:"sender"` - Account string `json:"account"` - Msgs []types.StargateMsg `json:"msgs"` + Sender string `json:"sender"` + Account string `json:"account"` + Msgs []types.CosmosMsg `json:"msgs"` }