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 fb20cffb..a4c84c17 100644 --- a/app/app.go +++ b/app/app.go @@ -259,11 +259,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 { @@ -271,9 +273,10 @@ func NewTerraApp( } postHandler := post.NewPostHandler( post.HandlerOptions{ - FeeShareKeeper: app.Keepers.FeeShareKeeper, - BankKeeper: app.Keepers.BankKeeper, - WasmKeeper: app.Keepers.WasmKeeper, + FeeShareKeeper: app.Keepers.FeeShareKeeper, + BankKeeper: app.Keepers.BankKeeper, + WasmKeeper: app.Keepers.WasmKeeper, + SmartAccountKeeper: &app.Keepers.SmartAccountKeeper, }, ) diff --git a/app/genesis.go b/app/genesis.go index fd5dabba..60908a01 100644 --- a/app/genesis.go +++ b/app/genesis.go @@ -18,6 +18,7 @@ import ( govtypesv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + smartaccounttypes "github.com/terra-money/core/v2/x/smartaccount/types" ) // GenesisState - The genesis state of the blockchain is represented here as a map of raw json @@ -79,6 +80,12 @@ func (genState GenesisState) SetDefaultTerraConfig(cdc codec.JSONCodec) GenesisS } genState[icatypes.ModuleName] = cdc.MustMarshalJSON(&icaGenState) + var smartaccountGenState smartaccounttypes.GenesisState + cdc.MustUnmarshalJSON(genState[smartaccounttypes.ModuleName], &smartaccountGenState) + setting := smartaccounttypes.NewSetting("terra1tck9vx8vwu6l83zy76ssdkhnhw8dfcrt80hc6x") + smartaccountGenState.Settings = smartaccounttypes.NewSettings(&setting) + genState[smartaccounttypes.ModuleName] = cdc.MustMarshalJSON(&smartaccountGenState) + return genState } diff --git a/app/genesis_test.go b/app/genesis_test.go index 8d59640e..eaa3a68f 100644 --- a/app/genesis_test.go +++ b/app/genesis_test.go @@ -2,6 +2,7 @@ package app_test import ( "encoding/json" + "io/ioutil" "os" "testing" "time" @@ -21,6 +22,7 @@ import ( "github.com/terra-money/alliance/x/alliance" "github.com/terra-money/core/v2/app" "github.com/terra-money/core/v2/x/feeshare" + "github.com/terra-money/core/v2/x/smartaccount" "github.com/terra-money/core/v2/x/tokenfactory" mocktestutils "github.com/cosmos/cosmos-sdk/testutil/mock" @@ -226,6 +228,7 @@ func (s *AppGenesisTestSuite) TestMigration() { "upgrade": upgrade.AppModule{}.ConsensusVersion(), "vesting": vesting.AppModule{}.ConsensusVersion(), "wasm": wasm.AppModule{}.ConsensusVersion(), + "smartaccount": smartaccount.AppModule{}.ConsensusVersion(), }, ) s.Require().NoError(err) @@ -259,6 +262,7 @@ func (s *AppGenesisTestSuite) TestMigration() { "upgrade": 2, "vesting": 1, "wasm": 4, + "smartaccount": 1, }) } @@ -687,6 +691,41 @@ func (s *AppGenesisTestSuite) TestGenesis() { "redelegations": [], "exported": false }, + "smartaccount": { + "params": { + }, + "settings": [ + { + "owner": "terra1tck9vx8vwu6l83zy76ssdkhnhw8dfcrt80hc6x", + "authorization": [], + "pre_transaction": [], + "post_transaction": [], + "fallback": true + } + ] + }, + "staking": { + "delegations": [ + ], + "exported": false, + "last_total_power": "0", + "last_validator_powers": [ + ], + "params": { + "bond_denom": "uluna", + "historical_entries": 10000, + "max_entries": 7, + "max_validators": 100, + "min_commission_rate": "0.000000000000000000", + "unbonding_time": "1814400s" + }, + "redelegations": [ + ], + "unbonding_delegations": [ + ], + "validators": [ + ] + }, "tokenfactory": { "params": { "denom_creation_fee": [ @@ -723,5 +762,7 @@ func (s *AppGenesisTestSuite) TestGenesis() { "sequences": [] } }` + // write jsonGenState to file for debugging + ioutil.WriteFile("genesis1.json", jsonGenState, 0644) s.Require().JSONEq(string(jsonGenState), expectedState) } diff --git a/app/keepers/keepers.go b/app/keepers/keepers.go index f826ae20..18320663 100644 --- a/app/keepers/keepers.go +++ b/app/keepers/keepers.go @@ -1,9 +1,6 @@ package keepers import ( - - // #nosec G702 - "path/filepath" ibctransfer "github.com/cosmos/ibc-go/v7/modules/apps/transfer" @@ -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" @@ -121,6 +121,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 { @@ -155,6 +156,7 @@ type TerraAppKeepers struct { AllianceKeeper alliancekeeper.Keeper FeeShareKeeper feesharekeeper.Keeper ICQKeeper icqkeeper.Keeper + SmartAccountKeeper smartaccountkeeper.Keeper // IBC hooks IBCHooksKeeper *ibchookskeeper.Keeper @@ -467,6 +469,12 @@ func NewTerraAppKeepers( wasmOpts..., ) + keepers.SmartAccountKeeper = smartaccountkeeper.NewKeeper( + appCodec, + keys[smartaccounttypes.StoreKey], + keepers.WasmKeeper.Keeper, + ) + keepers.Ics20WasmHooks.ContractKeeper = keepers.WasmKeeper.Keeper // Setup the contract keepers.WasmKeeper before the // hook for the BankKeeper othrwise the WasmKeeper @@ -569,6 +577,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 51a44e77..1f367bc9 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 ef723723..616929b4 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/post/post.go b/app/post/post.go index d10d3668..b00f9f2d 100644 --- a/app/post/post.go +++ b/app/post/post.go @@ -2,6 +2,8 @@ package post import ( feesharepost "github.com/terra-money/core/v2/x/feeshare/post" + smartaccountkeeper "github.com/terra-money/core/v2/x/smartaccount/keeper" + smartaccountpost "github.com/terra-money/core/v2/x/smartaccount/post" customwasmkeeper "github.com/terra-money/core/v2/x/wasm/keeper" wasmpost "github.com/terra-money/core/v2/x/wasm/post" @@ -12,6 +14,8 @@ type HandlerOptions struct { FeeShareKeeper feesharepost.FeeShareKeeper BankKeeper feesharepost.BankKeeper WasmKeeper customwasmkeeper.Keeper + + SmartAccountKeeper *smartaccountkeeper.Keeper } func NewPostHandler(options HandlerOptions) sdk.PostHandler { @@ -19,6 +23,7 @@ func NewPostHandler(options HandlerOptions) sdk.PostHandler { postDecorators := []sdk.PostDecorator{ feesharepost.NewFeeSharePayoutDecorator(options.FeeShareKeeper, options.BankKeeper, options.WasmKeeper), wasmpost.NewWasmdDecorator(options.WasmKeeper), + smartaccountpost.NewPostTransactionHookDecorator(options.SmartAccountKeeper, options.WasmKeeper), } return sdk.ChainPostDecorators(postDecorators...) 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/integration-tests/package-lock.json b/integration-tests/package-lock.json index f3e09188..c02b0528 100644 --- a/integration-tests/package-lock.json +++ b/integration-tests/package-lock.json @@ -9,7 +9,8 @@ "version": "v2.11.0", "license": "MIT", "dependencies": { - "@terra-money/feather.js": "^2.1.0-beta.2", + "@terra-money/feather.js": "2.1.0-beta.4", + "@terra-money/terra.proto": "5.1.0-beta.3", "moment": "^2.29.4" }, "devDependencies": { @@ -1106,12 +1107,12 @@ } }, "node_modules/@terra-money/feather.js": { - "version": "2.1.0-beta.2", - "resolved": "https://registry.npmjs.org/@terra-money/feather.js/-/feather.js-2.1.0-beta.2.tgz", - "integrity": "sha512-WIeh7Mm3RI1FB+IivUovCZpXG/Lo65UiSSKHdQjHxp6bTerHgbEyh6AS5GwBEpJJrIqXUboUD7tiUW/kmVLfbQ==", + "version": "2.1.0-beta.4", + "resolved": "https://registry.npmjs.org/@terra-money/feather.js/-/feather.js-2.1.0-beta.4.tgz", + "integrity": "sha512-WrD0CZ2vdbvu5oqnCWSmhgzgIZkRD2qXdeRva5br1I75TieJ0paLZTH5JIDUPQR1SnYABzeSEvDK8SK+fc8rPw==", "dependencies": { "@terra-money/legacy.proto": "npm:@terra-money/terra.proto@^0.1.7", - "@terra-money/terra.proto": "^4.0.10", + "@terra-money/terra.proto": "^5.1.0-beta.3", "assert": "^2.0.0", "axios": "^0.27.2", "bech32": "^2.0.0", @@ -1150,9 +1151,9 @@ "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" }, "node_modules/@terra-money/terra.proto": { - "version": "4.0.10", - "resolved": "https://registry.npmjs.org/@terra-money/terra.proto/-/terra.proto-4.0.10.tgz", - "integrity": "sha512-cSTGri/X7r+RjTHKQ40lUDM7+lwWIiodLmBvuCUWMH8svji0D45StZTVGfaQ5wCnPr7KcDbZTERzyLKiSwsBqg==", + "version": "5.1.0-beta.3", + "resolved": "https://registry.npmjs.org/@terra-money/terra.proto/-/terra.proto-5.1.0-beta.3.tgz", + "integrity": "sha512-y69nixzKxV5AK/4Kgza/eF+0Ez++xpbnse5LrYI7ar43OMWP59gxeASeTZPLsbx8bG5CsqCtcRT/klFtwsDzXA==", "dependencies": { "@improbable-eng/grpc-web": "^0.14.1", "browser-headers": "^0.4.1", @@ -2483,20 +2484,6 @@ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", "dev": true }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, "node_modules/function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", @@ -5966,12 +5953,12 @@ } }, "@terra-money/feather.js": { - "version": "2.1.0-beta.2", - "resolved": "https://registry.npmjs.org/@terra-money/feather.js/-/feather.js-2.1.0-beta.2.tgz", - "integrity": "sha512-WIeh7Mm3RI1FB+IivUovCZpXG/Lo65UiSSKHdQjHxp6bTerHgbEyh6AS5GwBEpJJrIqXUboUD7tiUW/kmVLfbQ==", + "version": "2.1.0-beta.4", + "resolved": "https://registry.npmjs.org/@terra-money/feather.js/-/feather.js-2.1.0-beta.4.tgz", + "integrity": "sha512-WrD0CZ2vdbvu5oqnCWSmhgzgIZkRD2qXdeRva5br1I75TieJ0paLZTH5JIDUPQR1SnYABzeSEvDK8SK+fc8rPw==", "requires": { "@terra-money/legacy.proto": "npm:@terra-money/terra.proto@^0.1.7", - "@terra-money/terra.proto": "^4.0.10", + "@terra-money/terra.proto": "^5.1.0-beta.3", "assert": "^2.0.0", "axios": "^0.27.2", "bech32": "^2.0.0", @@ -6008,9 +5995,9 @@ } }, "@terra-money/terra.proto": { - "version": "4.0.10", - "resolved": "https://registry.npmjs.org/@terra-money/terra.proto/-/terra.proto-4.0.10.tgz", - "integrity": "sha512-cSTGri/X7r+RjTHKQ40lUDM7+lwWIiodLmBvuCUWMH8svji0D45StZTVGfaQ5wCnPr7KcDbZTERzyLKiSwsBqg==", + "version": "5.1.0-beta.3", + "resolved": "https://registry.npmjs.org/@terra-money/terra.proto/-/terra.proto-5.1.0-beta.3.tgz", + "integrity": "sha512-y69nixzKxV5AK/4Kgza/eF+0Ez++xpbnse5LrYI7ar43OMWP59gxeASeTZPLsbx8bG5CsqCtcRT/klFtwsDzXA==", "requires": { "@improbable-eng/grpc-web": "^0.14.1", "browser-headers": "^0.4.1", @@ -7079,13 +7066,6 @@ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", "dev": true }, - "fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "optional": true - }, "function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", diff --git a/integration-tests/package.json b/integration-tests/package.json index 05ad01bb..a6f7e2fb 100644 --- a/integration-tests/package.json +++ b/integration-tests/package.json @@ -4,10 +4,10 @@ "description": "Integration tests for Core using feather.js", "main": "index.ts", "scripts": { - "test:init" : "bash src/setup/init-test-framework.sh", + "test:init": "bash src/setup/init-test-framework.sh", "test:relayer": "bash src/setup/relayer/init-relayer.sh", - "test:chain:upgrade" : "bash src/setup/chain-upgrade/chain-upgrade.sh", - "test:start" : "jest --runInBand --detectOpenHandles", + "test:chain:upgrade": "bash src/setup/chain-upgrade/chain-upgrade.sh", + "test:start": "jest --runInBand --detectOpenHandles", "start": "npm run test:init && npm run test:relayer && npm run test:start", "test:clean": "rm -rf src/test-data chain-upgrade-data && pkill terrad && pkill terrad && pkill relayer" }, @@ -35,7 +35,8 @@ "typescript": "^5.2.2" }, "dependencies": { - "@terra-money/feather.js": "^2.1.0-beta.2", + "@terra-money/feather.js": "2.1.0-beta.4", + "@terra-money/terra.proto":"5.1.0-beta.3", "moment": "^2.29.4" } -} +} \ No newline at end of file diff --git a/integration-tests/src/helpers/mnemonics.ts b/integration-tests/src/helpers/mnemonics.ts index 47a68fbc..31ef9491 100644 --- a/integration-tests/src/helpers/mnemonics.ts +++ b/integration-tests/src/helpers/mnemonics.ts @@ -48,21 +48,21 @@ export function getMnemonics() { let wasmContracts = new MnemonicKey({ mnemonic: "degree under tray object thought mercy mushroom captain bus work faint basic twice cube noble man ripple close flush bunker dish spare hungry arm" }) - let mnemonic2 = new MnemonicKey({ + let smartaccControllerMnemonic = new MnemonicKey({ mnemonic: "range struggle season mesh antenna delay sell light yard path risk curve brain nut cabin injury dilemma fun comfort crumble today transfer bring draft" }) - let mnemonic3 = new MnemonicKey({ + let smartaccPreTxMnemonic = new MnemonicKey({ mnemonic: "giraffe trim element wheel cannon nothing enrich shiver upon output iron recall already fix appear produce fix behind scissors artefact excite tennis into side" }) - let mnemonic4 = new MnemonicKey({ + let smartaccPostTxMnemonic = new MnemonicKey({ mnemonic: "run turn cup combine sad toast roof already melt chimney arctic save avocado theory bracket cherry cotton fee once favorite swarm ignore dream element" }) - let mnemonic5 = new MnemonicKey({ - mnemonic: "script key fold coyote cage squirrel prevent pole auction slide vintage shoot mirror erosion equip goose capable critic test space sketch monkey eight candy" - }) - let mnemonic6 = new MnemonicKey({ + let smartaccAuthMnemonic = new MnemonicKey({ mnemonic: "work clap clarify edit explain exact depth ramp law hard feel beauty stumble occur prevent crush distance purpose scrap current describe skirt panther skirt" }) + let mnemonic1 = new MnemonicKey({ + mnemonic: "script key fold coyote cage squirrel prevent pole auction slide vintage shoot mirror erosion equip goose capable critic test space sketch monkey eight candy" + }) return { val1, @@ -79,10 +79,10 @@ export function getMnemonics() { tokenFactoryMnemonic, ibcHooksMnemonic, wasmContracts, - mnemonic2, - mnemonic3, - mnemonic4, - mnemonic5, - mnemonic6, + mnemonic1, + smartaccAuthMnemonic, + smartaccControllerMnemonic, + smartaccPreTxMnemonic, + smartaccPostTxMnemonic, } } \ No newline at end of file diff --git a/integration-tests/src/modules/smartaccount/auth.test.ts b/integration-tests/src/modules/smartaccount/auth.test.ts new file mode 100644 index 00000000..7b67c43b --- /dev/null +++ b/integration-tests/src/modules/smartaccount/auth.test.ts @@ -0,0 +1,239 @@ +import { Coins, MsgInstantiateContract, MsgSend, MsgStoreCode, SimplePublicKey } from "@terra-money/feather.js"; +import { AuthorizationMsg, Initialization, MsgCreateSmartAccount, MsgDisableSmartAccount, MsgUpdateAuthorization } from "@terra-money/feather.js/dist/core/smartaccount"; +import fs from "fs"; +import path from 'path'; +import { blockInclusion, getLCDClient, getMnemonics } from "../../helpers"; + +describe("Smartaccount Module (https://github.com/terra-money/core/tree/release/v2.6/x/smartaccount) ", () => { + // Prepare environment clients, accounts and wallets + const LCD = getLCDClient(); + const accounts = getMnemonics(); + const wallet = LCD.chain1.wallet(accounts.smartaccAuthMnemonic); + const controlledAccountAddress = accounts.smartaccAuthMnemonic.accAddress("terra"); + + const controller = LCD.chain1.wallet(accounts.smartaccControllerMnemonic); + const pubkey = accounts.smartaccControllerMnemonic.publicKey; + expect(pubkey).toBeDefined(); + + const pubkeybb = pubkey as SimplePublicKey; + const pubkeyStr = pubkeybb.key; + const initMsg = Initialization.fromData({ + account: controlledAccountAddress, + msg: pubkeyStr, + }); + + const deployer = LCD.chain1.wallet(accounts.tokenFactoryMnemonic); + const deployerAddress = accounts.tokenFactoryMnemonic.accAddress("terra"); + + let authContractAddress: string; + + test('Deploy smart account auth contract', async () => { + try { + let tx = await deployer.createAndSignTx({ + msgs: [new MsgStoreCode( + deployerAddress, + fs.readFileSync(path.join(__dirname, "/../../../../x/smartaccount/test_helpers/test_data/smart_auth_contract.wasm")).toString("base64"), + )], + chainID: "test-1", + }); + + let result = await LCD.chain1.tx.broadcastSync(tx, "test-1"); + await blockInclusion(); + let txResult = await LCD.chain1.tx.txInfo(result.txhash, "test-1") as any; + let codeId = Number(txResult.logs[0].events[1].attributes[1].value); + expect(codeId).toBeDefined(); + + const msgInstantiateContract = new MsgInstantiateContract( + deployerAddress, + deployerAddress, + codeId, + {}, + Coins.fromString("1uluna"), + "Smart auth contract " + Math.random(), + ); + + tx = await deployer.createAndSignTx({ + msgs: [msgInstantiateContract], + chainID: "test-1", + }); + result = await LCD.chain1.tx.broadcastSync(tx, "test-1"); + await blockInclusion(); + txResult = await LCD.chain1.tx.txInfo(result.txhash, "test-1") as any; + authContractAddress = txResult.logs[0].events[4].attributes[0].value; + expect(authContractAddress).toBeDefined(); + } catch(e: any) { + console.log(e) + expect(e).toBeUndefined(); + } + }); + + test('Create new smart account', async () => { + try { + // create the smartaccount + let tx = await wallet.createAndSignTx({ + msgs: [new MsgCreateSmartAccount( + controlledAccountAddress + )], + chainID: 'test-1', + gas: '400000', + }); + await LCD.chain1.tx.broadcastSync(tx, "test-1"); + await blockInclusion(); + // Query smartaccount setting for the smart waccount + let setting = await LCD.chain1.smartaccount.setting(controlledAccountAddress); + expect(setting.toData()) + .toEqual({ + owner: controlledAccountAddress, + authorization: [], + post_transaction: [], + pre_transaction: [], + fallback: true, + }); + } catch (e:any) { + console.log(e); + expect(e).toBeUndefined(); + } + }); + + test('Give smart account control to controller', async () => { + try { + // give control to controller + const authMsg = new AuthorizationMsg(authContractAddress, initMsg); + let tx = await wallet.createAndSignTx({ + msgs: [new MsgUpdateAuthorization( + controlledAccountAddress, + false, + [authMsg], + )], + chainID: 'test-1', + gas: '400000', + }); + await LCD.chain1.tx.broadcastSync(tx, "test-1"); + await blockInclusion(); + + // check if update authorization was successful + let setting = await LCD.chain1.smartaccount.setting(controlledAccountAddress); + expect(setting.toData()) + .toEqual({ + owner: controlledAccountAddress, + authorization: [authMsg.toData()], + post_transaction: [], + pre_transaction: [], + fallback: false, + }); + } catch (e:any) { + console.log(e) + expect(e).toBeUndefined(); + } + }); + + test('Only controller should be able to sign', async () => { + try { + // signing with the controlledAccountAddress should now fail + let tx = await wallet.createAndSignTx({ + msgs: [ + new MsgSend( + controlledAccountAddress, + controlledAccountAddress, + Coins.fromString("1uluna"), + ), + ], + chainID: "test-1", + gas: '400000', + }); + let result = await LCD.chain1.tx.broadcastSync(tx, "test-1"); + expect(result.raw_log).toEqual("authorization failed: unauthorized"); + + // signing with the controller should now succeed + tx = await controller.createAndSignTx({ + msgs: [ + new MsgSend( + controlledAccountAddress, + deployerAddress, + Coins.fromString("1uluna"), + ), + ], + chainID: "test-1", + gas: '400000', + }); + const deployerBalanceBefore = await LCD.chain1.bank.balance(deployerAddress); + result = await LCD.chain1.tx.broadcastSync(tx, "test-1"); + await blockInclusion(); + const deployerBalanceAfter = await LCD.chain1.bank.balance(deployerAddress); + const deltaBalance = deployerBalanceAfter[0].sub(deployerBalanceBefore[0]); + expect(deltaBalance.toString()).toEqual("1uluna"); + } catch (e:any) { + console.log(e) + expect(e).toBeUndefined(); + } + }); + + test('Disable smart contract', async () => { + try { + // signing with the controlledAccountAddress should now fail + let tx = await controller.createAndSignTx({ + msgs: [ + new MsgDisableSmartAccount( + controlledAccountAddress, + ), + ], + chainID: "test-1", + gas: '400000', + }); + let result = await LCD.chain1.tx.broadcastSync(tx, "test-1"); + expect(result.raw_log).toEqual("[]"); + await blockInclusion(); + + // check if update authorization was successful + try { + await LCD.chain1.smartaccount.setting(controlledAccountAddress); + } catch (e:any) { + expect(e).toBeDefined(); + } + } catch (e:any) { + console.log(e) + expect(e).toBeUndefined(); + } + }); + + test('Only original pk should be able to sign', async () => { + try { + // signing with the controller should now fail + let tx = await controller.createAndSignTx({ + msgs: [ + new MsgSend( + controlledAccountAddress, + controlledAccountAddress, + Coins.fromString("1uluna"), + ), + ], + chainID: "test-1", + gas: '400000', + }); + let result = await LCD.chain1.tx.broadcastSync(tx, "test-1"); + expect(result.raw_log).toEqual("pubKey does not match signer address terra1wm6wwmnsdkrdugw507q4ngak589t4alq7uaqhf with signer index: 0: invalid pubkey"); + + // signing with the original pk should now succeed + tx = await wallet.createAndSignTx({ + msgs: [ + new MsgSend( + controlledAccountAddress, + deployerAddress, + Coins.fromString("1uluna"), + ), + ], + chainID: "test-1", + gas: '400000', + }); + const deployerBalanceBefore = await LCD.chain1.bank.balance(deployerAddress); + result = await LCD.chain1.tx.broadcastSync(tx, "test-1"); + await blockInclusion(); + const deployerBalanceAfter = await LCD.chain1.bank.balance(deployerAddress); + const deltaBalance = deployerBalanceAfter[0].sub(deployerBalanceBefore[0]); + expect(deltaBalance.toString()).toEqual("1uluna"); + } catch (e:any) { + console.log(e) + expect(e).toBeUndefined(); + } + }); +}); \ No newline at end of file diff --git a/integration-tests/src/modules/smartaccount/posttx.test.ts b/integration-tests/src/modules/smartaccount/posttx.test.ts new file mode 100644 index 00000000..15aa2428 --- /dev/null +++ b/integration-tests/src/modules/smartaccount/posttx.test.ts @@ -0,0 +1,195 @@ +import { Coin, Coins, MsgInstantiateContract, MsgSend, MsgStoreCode } from "@terra-money/feather.js"; +import { MsgCreateSmartAccount, MsgUpdateTransactionHooks } from "@terra-money/feather.js/dist/core/smartaccount"; +import fs from "fs"; +import path from 'path'; +import { blockInclusion, getLCDClient, getMnemonics } from "../../helpers"; + +describe("Smartaccount Module (https://github.com/terra-money/core/tree/release/v2.6/x/smartaccount) ", () => { + // Prepare environment clients, accounts and wallets + const LCD = getLCDClient(); + const accounts = getMnemonics(); + const wallet = LCD.chain1.wallet(accounts.smartaccPreTxMnemonic); + const smartaccAddress = accounts.smartaccPreTxMnemonic.accAddress("terra"); + const receiver = accounts.smartaccControllerMnemonic.accAddress("terra") + + const deployer = LCD.chain1.wallet(accounts.tokenFactoryMnemonic); + const deployerAddress = accounts.tokenFactoryMnemonic.accAddress("terra"); + + let limitContractAddress: string; + + test('Create new smart account', async () => { + try { + // create the smartaccount + let tx = await wallet.createAndSignTx({ + msgs: [new MsgCreateSmartAccount( + smartaccAddress + )], + chainID: 'test-1', + gas: '400000', + }); + await LCD.chain1.tx.broadcastSync(tx, "test-1"); + await blockInclusion(); + // Query smartaccount setting for the smart waccount + let setting = await LCD.chain1.smartaccount.setting(smartaccAddress); + expect(setting.toData()) + .toEqual({ + owner: smartaccAddress, + authorization: [], + post_transaction: [], + pre_transaction: [], + fallback: true, + }); + } catch (e:any) { + console.log(e); + expect(e).toBeUndefined(); + } + }); + + test('Deploy smart account limit contract', async () => { + try { + let tx = await deployer.createAndSignTx({ + msgs: [new MsgStoreCode( + deployerAddress, + fs.readFileSync(path.join(__dirname, "/../../../../x/smartaccount/test_helpers/test_data/limit_min_coins_hooks.wasm")).toString("base64"), + )], + chainID: "test-1", + }); + + let result = await LCD.chain1.tx.broadcastSync(tx, "test-1"); + await blockInclusion(); + let txResult = await LCD.chain1.tx.txInfo(result.txhash, "test-1") as any; + let codeId = Number(txResult.logs[0].events[1].attributes[1].value); + expect(codeId).toBeDefined(); + + const msgInstantiateContract = new MsgInstantiateContract( + deployerAddress, + deployerAddress, + codeId, + {}, + Coins.fromString("1uluna"), + "limit contract " + Math.random(), + ); + + tx = await deployer.createAndSignTx({ + msgs: [msgInstantiateContract], + chainID: "test-1", + }); + result = await LCD.chain1.tx.broadcastSync(tx, "test-1"); + await blockInclusion(); + txResult = await LCD.chain1.tx.txInfo(result.txhash, "test-1") as any; + limitContractAddress = txResult.logs[0].events[4].attributes[0].value; + expect(limitContractAddress).toBeDefined(); + } catch(e: any) { + console.log(e) + expect(e).toBeUndefined(); + } + }); + + test('Update post tx hooks', async () => { + try { + // signing with the controlledAccountAddress should now fail + let tx = await wallet.createAndSignTx({ + msgs: [ + new MsgUpdateTransactionHooks( + smartaccAddress, + [], + [limitContractAddress], + ), + ], + chainID: "test-1", + gas: '400000', + }); + await LCD.chain1.tx.broadcastSync(tx, "test-1"); + await blockInclusion(); + + // check if update authorization was successful + let setting = await LCD.chain1.smartaccount.setting(smartaccAddress); + expect(setting.postTransaction).toEqual([limitContractAddress]); + } catch (e:any) { + console.log(e) + expect(e).toBeUndefined(); + } + }); + + test('Transaction should pass for sending below limit', async () => { + try { + let setting = await LCD.chain1.smartaccount.setting(smartaccAddress); + expect(setting.postTransaction).toEqual([limitContractAddress]); + + const balance = await LCD.chain1.bank.balance(smartaccAddress); + const coinsToSend = balance[0].sub(Coins.fromString("1000000uluna")); + + const receiverBalanceBefore = await LCD.chain1.bank.balance(receiver); + + let tx = await wallet.createAndSignTx({ + msgs: [ + new MsgSend( + smartaccAddress, + receiver, + coinsToSend, + ), + ], + chainID: "test-1", + gas: '400000', + }); + // expect.assertions(1); + await LCD.chain1.tx.broadcastSync(tx, "test-1"); + await blockInclusion(); + + // check that MsgSend succeeds + const receiverBalanceAfter = await LCD.chain1.bank.balance(receiver); + const deltaBalance = receiverBalanceAfter[0].sub(receiverBalanceBefore[0]); + expect(deltaBalance).toEqual(coinsToSend); + } catch (e:any) { + console.log(e) + expect(e).toBeUndefined(); + } + }); + + test('Transaction should fail for sending over limit', async () => { + try { + let setting = await LCD.chain1.smartaccount.setting(smartaccAddress); + expect(setting.postTransaction).toEqual([limitContractAddress]); + + // should have 940000uluna at this point 60000 + const balanceBefore = await LCD.chain1.bank.balance(smartaccAddress); + // leave 23905uluna for fees so transaction will not fail due to insufficient funds + // should cost 23705uluna + const coinsToSend = balanceBefore[0].sub(Coins.fromString("23905uluna")); + + const coinBefore = balanceBefore[0].find((coin: Coin) => coin.denom === "uluna"); + expect(coinBefore).toBeDefined(); + + let tx = await wallet.createAndSignTx({ + msgs: [ + new MsgSend( + smartaccAddress, + receiver, + coinsToSend, + ), + ], + chainID: "test-1", + }); + const fee_coins = tx.toData().auth_info.fee.amount; + + // fee_coins[0].amount string to number + const fee_amount = parseInt(fee_coins[0].amount); + + await LCD.chain1.tx.broadcastSync(tx, "test-1"); + await blockInclusion(); + + // check that MsgSend failed + const balanceAfter = await LCD.chain1.bank.balance(smartaccAddress); + const coinAfter = balanceAfter[0].find((coin: Coin) => coin.denom === "uluna"); + expect(coinAfter).toBeDefined(); + + // check that only fees were deducted + const coinAfter_amount = parseInt(coinAfter!.amount.toString()); + const balaceBeforeMinusFee = coinBefore!.amount.toNumber() - fee_amount; + expect(balaceBeforeMinusFee).toEqual(coinAfter_amount); + } catch (e:any) { + console.log(e) + expect(e).toBeUndefined(); + } + }); +}); \ No newline at end of file diff --git a/integration-tests/src/modules/smartaccount/pretx.test.ts b/integration-tests/src/modules/smartaccount/pretx.test.ts new file mode 100644 index 00000000..1aab9dd8 --- /dev/null +++ b/integration-tests/src/modules/smartaccount/pretx.test.ts @@ -0,0 +1,161 @@ +import { Coin, Coins, MsgDelegate, MsgInstantiateContract, MsgSend, MsgStoreCode, ValAddress } from "@terra-money/feather.js"; +import { MsgCreateSmartAccount, MsgUpdateTransactionHooks } from "@terra-money/feather.js/dist/core/smartaccount"; +import fs from "fs"; +import path from 'path'; +import { blockInclusion, getLCDClient, getMnemonics } from "../../helpers"; + +describe("Smartaccount Module (https://github.com/terra-money/core/tree/release/v2.6/x/smartaccount) ", () => { + // Prepare environment clients, accounts and wallets + const LCD = getLCDClient(); + const accounts = getMnemonics(); + const wallet = LCD.chain1.wallet(accounts.smartaccPostTxMnemonic); + const controlledAccountAddress = accounts.smartaccPostTxMnemonic.accAddress("terra"); + + const deployer = LCD.chain1.wallet(accounts.tokenFactoryMnemonic); + const deployerAddress = accounts.tokenFactoryMnemonic.accAddress("terra"); + + let limitContractAddress: string; + + test('Create new smart account', async () => { + try { + // create the smartaccount + let tx = await wallet.createAndSignTx({ + msgs: [new MsgCreateSmartAccount( + controlledAccountAddress + )], + chainID: 'test-1', + gas: '400000', + }); + await LCD.chain1.tx.broadcastSync(tx, "test-1"); + await blockInclusion(); + // Query smartaccount setting for the smart waccount + let setting = await LCD.chain1.smartaccount.setting(controlledAccountAddress); + expect(setting.toData()) + .toEqual({ + owner: controlledAccountAddress, + authorization: [], + post_transaction: [], + pre_transaction: [], + fallback: true, + }); + } catch (e:any) { + console.log(e); + expect(e).toBeUndefined(); + } + }); + + test('Deploy smart account limit contract', async () => { + try { + let tx = await deployer.createAndSignTx({ + msgs: [new MsgStoreCode( + deployerAddress, + fs.readFileSync(path.join(__dirname, "/../../../../x/smartaccount/test_helpers/test_data/limit_send_only_hooks.wasm")).toString("base64"), + )], + chainID: "test-1", + }); + + let result = await LCD.chain1.tx.broadcastSync(tx, "test-1"); + await blockInclusion(); + let txResult = await LCD.chain1.tx.txInfo(result.txhash, "test-1") as any; + let codeId = Number(txResult.logs[0].events[1].attributes[1].value); + expect(codeId).toBeDefined(); + + const msgInstantiateContract = new MsgInstantiateContract( + deployerAddress, + deployerAddress, + codeId, + {}, + Coins.fromString("1uluna"), + "limit contract " + Math.random(), + ); + + tx = await deployer.createAndSignTx({ + msgs: [msgInstantiateContract], + chainID: "test-1", + }); + result = await LCD.chain1.tx.broadcastSync(tx, "test-1"); + await blockInclusion(); + txResult = await LCD.chain1.tx.txInfo(result.txhash, "test-1") as any; + limitContractAddress = txResult.logs[0].events[4].attributes[0].value; + expect(limitContractAddress).toBeDefined(); + } catch(e: any) { + console.log(e) + expect(e).toBeUndefined(); + } + }); + + test('Update pre tx hooks', async () => { + try { + // signing with the controlledAccountAddress should now fail + let tx = await wallet.createAndSignTx({ + msgs: [ + new MsgUpdateTransactionHooks( + controlledAccountAddress, + [limitContractAddress], + [], + ), + ], + chainID: "test-1", + gas: '400000', + }); + await LCD.chain1.tx.broadcastSync(tx, "test-1"); + await blockInclusion(); + + // check if update authorization was successful + let setting = await LCD.chain1.smartaccount.setting(controlledAccountAddress); + expect(setting.preTransaction).toEqual([limitContractAddress]); + } catch (e:any) { + console.log(e) + expect(e).toBeUndefined(); + } + }); + + test('Transaction should fail for delegation', async () => { + try { + let setting = await LCD.chain1.smartaccount.setting(controlledAccountAddress); + expect(setting.preTransaction).toEqual([limitContractAddress]); + // signing with the controlledAccountAddress should now fail + let tx = await wallet.createAndSignTx({ + msgs: [ + new MsgDelegate( + controlledAccountAddress, + ValAddress.fromAccAddress(controlledAccountAddress, "terra"), + Coin.fromString("100000000uluna"), + ), + ], + chainID: "test-1", + gas: '400000', + }); + expect.assertions(1); + await LCD.chain1.tx.broadcastSync(tx, "test-1"); + await blockInclusion(); + } catch (e:any) { + console.log(e) + expect(e).toEqual("Unauthorized: Unauthorized message type: execute wasm contract failed"); + } + }); + + test('Transaction should pass for send', async () => { + try { + // signing with the controlledAccountAddress should now fail + let tx = await wallet.createAndSignTx({ + msgs: [ + new MsgSend( + controlledAccountAddress, + controlledAccountAddress, + Coins.fromString("100000000uluna"), + ), + ], + chainID: "test-1", + gas: '400000', + }); + let res = await LCD.chain1.tx.broadcastSync(tx, "test-1"); + await blockInclusion(); + let txResult = await LCD.chain1.tx.txInfo(res.txhash, "test-1") as any; + expect(txResult); + } catch (e:any) { + console.log(e) + expect(e).toBeUndefined(); + } + }); +}); \ No newline at end of file diff --git a/proto/terra/smartaccount/v1/genesis.proto b/proto/terra/smartaccount/v1/genesis.proto new file mode 100644 index 00000000..ace512c0 --- /dev/null +++ b/proto/terra/smartaccount/v1/genesis.proto @@ -0,0 +1,16 @@ +syntax = "proto3"; +package terra.smartaccount.v1; + +import "gogoproto/gogo.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"; + +// GenesisState defines the smartaccount module's genesis state. +message GenesisState { + // params defines the paramaters of the module. + Params params = 1 [ (gogoproto.nullable) = false ]; + + repeated Setting settings = 2; +} diff --git a/proto/terra/smartaccount/v1/params.proto b/proto/terra/smartaccount/v1/params.proto new file mode 100644 index 00000000..7d73f55d --- /dev/null +++ b/proto/terra/smartaccount/v1/params.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; +package terra.smartaccount.v1; + +import "gogoproto/gogo.proto"; + +option go_package = "github.com/terra-money/core/v2/x/smartaccount/types"; + +// Params defines the parameters for the smartaccount module. +message Params {} diff --git a/proto/terra/smartaccount/v1/query.proto b/proto/terra/smartaccount/v1/query.proto new file mode 100644 index 00000000..06bcb2c9 --- /dev/null +++ b/proto/terra/smartaccount/v1/query.proto @@ -0,0 +1,37 @@ +syntax = "proto3"; +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"; + +// Query defines the gRPC querier service. +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/setting/{address}"; + } +} + +// QueryParamsRequest is the request type for the Query/Params RPC method. +message QueryParamsRequest {} + +// QueryParamsResponse is the response type for the Query/Params RPC method. +message QueryParamsResponse { + // params is the returned FeeShare parameter + Params params = 1 [ (gogoproto.nullable) = false ]; +} + +message QuerySettingRequest { + string address = 1; +} + +message QuerySettingResponse { + Setting setting = 1 [ (gogoproto.nullable) = false ]; +} diff --git a/proto/terra/smartaccount/v1/setting.proto b/proto/terra/smartaccount/v1/setting.proto new file mode 100644 index 00000000..345792d1 --- /dev/null +++ b/proto/terra/smartaccount/v1/setting.proto @@ -0,0 +1,31 @@ +syntax = "proto3"; +package terra.smartaccount.v1; + +import "gogoproto/gogo.proto"; +import "cosmos_proto/cosmos.proto"; +import "terra/smartaccount/v1/wasm.proto"; + +option go_package = "github.com/terra-money/core/v2/x/smartaccount/types"; + +message Setting { + // Owner that can do priviledged operations on the Smart Account + // Defaults to the Smart Account Addr + string owner = 1 [ (cosmos_proto.scalar) = "cosmos.AddressString" ]; + + // List of contract addresses to perform auth instead of SigVerify + repeated AuthorizationMsg authorization = 2 [ (cosmos_proto.scalar) = "cosmos.AddressString" ]; + + // List of contract addresses to perform pre-txn logic + repeated string pre_transaction = 3 [ (cosmos_proto.scalar) = "cosmos.AddressString" ]; + + // List of contract addresses to perform post-txn logic + repeated string post_transaction = 4 [ (cosmos_proto.scalar) = "cosmos.AddressString" ]; + + // Fallback to default SigVerify if custom authorization fails + bool fallback = 5; +} + +message AuthorizationMsg { + string contract_address = 1; + Initialization init_msg = 2; +} \ No newline at end of file diff --git a/proto/terra/smartaccount/v1/tx.proto b/proto/terra/smartaccount/v1/tx.proto new file mode 100644 index 00000000..b3b725e7 --- /dev/null +++ b/proto/terra/smartaccount/v1/tx.proto @@ -0,0 +1,53 @@ +syntax = "proto3"; +package terra.smartaccount.v1; + +import "gogoproto/gogo.proto"; +import "cosmos/msg/v1/msg.proto"; +import "terra/smartaccount/v1/setting.proto"; + +option go_package = "github.com/terra-money/core/v2/x/smartaccount/types"; + +// Msg defines the fees Msg service. +service Msg { + option (cosmos.msg.v1.service) = true; + + // CreateSmartAccount defines a method for creating a smart account. + rpc CreateSmartAccount(MsgCreateSmartAccount) returns (MsgCreateSmartAccountResponse); + + // UpdateAuthorization defines a method for updating the wasm authentication contract. + rpc UpdateAuthorization(MsgUpdateAuthorization) returns (MsgUpdateAuthorizationResponse); + + // UpdateTransactionHooks defines a method for updating the wasm transaction hooks contract. + rpc UpdateTransactionHooks(MsgUpdateTransactionHooks) returns (MsgUpdateTransactionHooksResponse); + + // DisableSmartAccountMsg defines a method for converting smart account to basic account. + rpc DisableSmartAccount(MsgDisableSmartAccount) returns (MsgDisableSmartAccountResponse); +} + +message MsgCreateSmartAccount { + string account = 1; +} + +message MsgCreateSmartAccountResponse {} + +message MsgUpdateAuthorization { + string account = 1; + bool fallback = 2; + repeated AuthorizationMsg authorization_msgs = 3; +} + +message MsgUpdateAuthorizationResponse {} + +message MsgUpdateTransactionHooks { + string account = 1; + repeated string pre_transaction_hooks = 2; + repeated string post_transaction_hooks = 3; +} + +message MsgUpdateTransactionHooksResponse {} + +message MsgDisableSmartAccount { + string account = 1; +} + +message MsgDisableSmartAccountResponse {} \ No newline at end of file diff --git a/proto/terra/smartaccount/v1/wasm.proto b/proto/terra/smartaccount/v1/wasm.proto new file mode 100644 index 00000000..592d7e65 --- /dev/null +++ b/proto/terra/smartaccount/v1/wasm.proto @@ -0,0 +1,14 @@ +syntax = "proto3"; +package terra.smartaccount.v1; + +import "gogoproto/gogo.proto"; + +option go_package = "github.com/terra-money/core/v2/x/smartaccount/types"; + +message Initialization { + string account = 1 [(gogoproto.jsontag) = "account"]; + bytes msg = 2 [(gogoproto.jsontag) = "msg"]; +} + + + diff --git a/x/smartaccount/README.md b/x/smartaccount/README.md new file mode 100644 index 00000000..11b8e8cc --- /dev/null +++ b/x/smartaccount/README.md @@ -0,0 +1,3 @@ +# smart-account + +This module upgrades accounts on Terra to be smart accounts. Smart Accounts will be able to have different authentication methods, hooks that run before and after a transaction to perform checks. All logic will be written in CosmWasm for ease of upgrade and allows third-party devs to add more modules that could be used in the future. diff --git a/x/smartaccount/ante/auth.go b/x/smartaccount/ante/auth.go new file mode 100644 index 00000000..dcce944f --- /dev/null +++ b/x/smartaccount/ante/auth.go @@ -0,0 +1,362 @@ +package ante + +import ( + "encoding/json" + "fmt" + + "github.com/terra-money/core/v2/x/smartaccount/types" + + 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" +) + +// SmartAccountAuthDecorator does authentication for smart accounts +type SmartAccountAuthDecorator struct { + smartAccountKeeper SmartAccountKeeper + wasmKeeper WasmKeeper + accountKeeper 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{ + smartAccountKeeper: sak, + wasmKeeper: wk, + accountKeeper: 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) { + 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] + accountStr := account.String() + + // check if the tx is from a smart account + setting, err := sad.smartAccountKeeper.GetSetting(ctx, accountStr) + 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 + } + ctx = ctx.WithValue(types.ModuleName, setting) + // skip authorization checks if simulate since no signatures will be provided + if simulate { + return next(ctx, tx, simulate) + } + + // Current smartaccount only supports one signer + // Multiple signers here means that the transaction perform state changes on multiple wallets + // (Not the same as a multi-sig transaction) + 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) + senderAddrs, signaturesBs, signedBytes, err := sad.GetParamsForCustomAuthVerification(ctx, sigTx, account) + if err != nil { + return ctx, err + } + + // run through the custom authorization verification + if setting.Authorization != nil && len(setting.Authorization) > 0 { + success, err := sad.CustomAuthVerify( + ctx, + setting.Authorization, + senderAddrs, + accountStr, + signaturesBs, + signedBytes, + []byte{}, + ) + if err != nil { + return ctx, err + } + if success { + return next(ctx, tx, simulate) + } else if !setting.Fallback { + return ctx, sdkerrors.ErrUnauthorized.Wrap(fmt.Sprintf("authorization failed: %s", err)) + } + } + + // run through the default handlers for signature verification + // if no custom authorization is set or if the custom authorization fails with fallback + 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) +} + +func (sad SmartAccountAuthDecorator) GetParamsForCustomAuthVerification( + ctx sdk.Context, + sigTx authsigning.SigVerifiableTx, + account sdk.AccAddress, +) ( + senderAddrs []string, + signatureBzs [][]byte, + signedBzs [][]byte, + err error, +) { + signatures, err := sigTx.GetSignaturesV2() + if err != nil { + return nil, nil, nil, err + } + if len(signatures) == 0 { + return nil, nil, nil, sdkerrors.ErrNoSignatures.Wrap("no signatures found") + } + + for _, signature := range signatures { + // This is to get the list of signers that contributed to the signatures + sas, err := GetSignerAddrStrings(signature.PubKey) + if err != nil { + return nil, nil, nil, err + } + senderAddrs = append(senderAddrs, sas...) + + // This is to get the address of the signer (either a multisig or a single sig) + // For multisig, the address to generated from the json encoded list of signers + // See: https://github.com/cosmos/cosmos-sdk/blob/v0.47.10/crypto/keys/multisig/multisig.go + senderAddr, err := sdk.AccAddressFromHexUnsafe(signature.PubKey.Address().String()) + if err != nil { + return nil, nil, nil, err + } + + senderAcc, err := authante.GetSignerAcc(ctx, sad.accountKeeper, senderAddr) + if err != nil { + return nil, nil, nil, err + } + var senderAccNum uint64 + if ctx.BlockHeight() != 0 { + senderAccNum = senderAcc.GetAccountNumber() + } + + signerData := authsigning.SignerData{ + Address: senderAddr.String(), + ChainID: ctx.ChainID(), + AccountNumber: senderAccNum, + Sequence: senderAcc.GetSequence(), + PubKey: signature.PubKey, + } + + signatureBz, err := signatureDataToBz(signature.Data) + if err != nil { + return nil, nil, nil, err + } + signedBytes, err := GetSignBytesArr(signature.PubKey, signerData, signature.Data, sad.signModeHandler, sigTx) + signedBzs = append(signedBzs, signedBytes...) + if err != nil { + return nil, nil, nil, err + } + signatureBzs = append(signatureBzs, signatureBz...) + } + return senderAddrs, signatureBzs, signedBzs, nil +} + +func (sad SmartAccountAuthDecorator) CustomAuthVerify( + ctx sdk.Context, + authMsgs []*types.AuthorizationMsg, + senders []string, + account string, + signatures, + signedBytes [][]byte, + data []byte, +) (bool, error) { + success := false + var errs []error + for _, auth := range authMsgs { + authMsg := types.Authorization{ + Senders: senders, + Account: account, + Signatures: signatures, + SignedBytes: signedBytes, + Data: data, + } + sudoAuthMsg := types.SudoMsg{Authorization: &authMsg} + sudoAuthMsgBs, err := json.Marshal(sudoAuthMsg) + if err != nil { + return success, err + } + contractAddr, err := sdk.AccAddressFromBech32(auth.ContractAddress) + if err != nil { + return success, err + } + _, err = sad.wasmKeeper.Sudo(ctx, contractAddr, sudoAuthMsgBs) + // so long as one of the authorization is successful, we're good + if err == nil { + success = true + break + } else { + errs = append(errs, err) + } + } + if success { + return success, nil + } else { + return success, fmt.Errorf("%v", errs) + } +} + +// 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 + } + 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 +} + +func GetSignerAddrStrings(pubKey cryptotypes.PubKey) ([]string, error) { + switch pubKey := pubKey.(type) { + case multisig.PubKey: + pubKeys := pubKey.GetPubKeys() + var addrStrings []string + for _, pk := range pubKeys { + as, err := GetSignerAddrStrings(pk) + if err != nil { + return nil, err + } + addrStrings = append(addrStrings, as...) + } + return addrStrings, nil + default: + return []string{pubKey.Address().String()}, nil + } +} diff --git a/x/smartaccount/ante/expected_keepers.go b/x/smartaccount/ante/expected_keepers.go new file mode 100644 index 00000000..19ebe298 --- /dev/null +++ b/x/smartaccount/ante/expected_keepers.go @@ -0,0 +1,15 @@ +package ante + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + + smartaccounttypes "github.com/terra-money/core/v2/x/smartaccount/types" +) + +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..cfd0d4e9 --- /dev/null +++ b/x/smartaccount/ante/pretransaction.go @@ -0,0 +1,116 @@ +package ante + +import ( + "encoding/json" + + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "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" + "github.com/terra-money/core/v2/x/smartaccount/types" +) + +type PreTransactionHookDecorator struct { + smartAccountKeeper SmartAccountKeeper + wasmKeeper WasmKeeper +} + +func NewPreTransactionHookDecorator(sak SmartAccountKeeper, wk WasmKeeper) PreTransactionHookDecorator { + return PreTransactionHookDecorator{ + smartAccountKeeper: sak, + wasmKeeper: wk, + } +} + +func (pth PreTransactionHookDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (sdk.Context, error) { + setting, ok := ctx.Value(types.ModuleName).(*types.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 BuildPrePostTransactionHookMsg(tx sdk.Tx, isPreTx bool) ([]byte, error) { + sigTx, ok := tx.(authsigning.SigVerifiableTx) + if !ok { + return nil, 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() + // Current only supports one signer (TODO review in the future) + if len(signers) != 1 { + return nil, sdkerrors.ErrorInvalidSigner.Wrap("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.ErrNoSignatures.Wrap("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, + }) + } + var msg types.SudoMsg + if isPreTx { + preTx := types.PreTransaction{ + Sender: senderAddr.String(), + Account: signers[0].String(), + Messages: stargateMsgs, + } + msg = types.SudoMsg{PreTransaction: &preTx} + } else { + postTx := types.PostTransaction{ + Sender: senderAddr.String(), + Account: signers[0].String(), + Messages: stargateMsgs, + } + msg = types.SudoMsg{PostTransaction: &postTx} + } + + return json.Marshal(msg) +} + +func BuildPreTransactionHookMsg(tx sdk.Tx) ([]byte, error) { + return BuildPrePostTransactionHookMsg(tx, true) +} diff --git a/x/smartaccount/ante/tests/auth_test.go b/x/smartaccount/ante/tests/auth_test.go new file mode 100644 index 00000000..a0b9d821 --- /dev/null +++ b/x/smartaccount/ante/tests/auth_test.go @@ -0,0 +1,288 @@ +package tests + +import ( + "encoding/base64" + "encoding/json" + "testing" + + wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" + "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" + smartaccounttypes "github.com/terra-money/core/v2/x/smartaccount/types" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/tx" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/tx/signing" + authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing" + "github.com/cosmos/cosmos-sdk/x/bank/types" +) + +type AnteTestSuite struct { + test_helpers.SmartAccountTestSuite + + AuthDecorator ante.SmartAccountAuthDecorator + PreTxDecorator ante.PreTransactionHookDecorator + WasmKeeper *wasmkeeper.PermissionedKeeper +} + +func TestAnteSuite(t *testing.T) { + suite.Run(t, new(AnteTestSuite)) +} + +func (s *AnteTestSuite) Setup() { + s.SmartAccountTestSuite.SetupTests() + s.WasmKeeper = wasmkeeper.NewDefaultPermissionKeeper(s.App.Keepers.WasmKeeper) + s.AuthDecorator = ante.NewSmartAccountAuthDecorator(s.SmartAccountKeeper, s.WasmKeeper, s.App.Keepers.AccountKeeper, nil, s.EncodingConfig.TxConfig.SignModeHandler()) + s.PreTxDecorator = ante.NewPreTransactionHookDecorator(s.SmartAccountKeeper, s.WasmKeeper) + s.Ctx = s.Ctx.WithChainID("test") +} + +func (s *AnteTestSuite) TestAuthAnteHandler() { + s.Setup() + + // testAcc1 using private key of testAcc0 + acc := s.TestAccs[1] + pubKey := s.TestAccPrivs[0].PubKey() + // endcoding this since this should be encoded in base64 when submitted by the user + pkEncoded := []byte(base64.StdEncoding.EncodeToString(pubKey.Bytes())) + + codeId, _, err := s.WasmKeeper.Create(s.Ctx, acc, test_helpers.SmartAuthContractWasm, nil) + require.NoError(s.T(), err) + contractAddr, _, err := s.WasmKeeper.Instantiate(s.Ctx, codeId, acc, acc, []byte("{}"), "auth", sdk.NewCoins()) + require.NoError(s.T(), err) + + // create initMsg + initMsg := smartaccounttypes.Initialization{ + Account: acc.String(), + Msg: pkEncoded, + } + sudoInitMsg := smartaccounttypes.SudoMsg{Initialization: &initMsg} + sudoInitMsgBs, err := json.Marshal(sudoInitMsg) + require.NoError(s.T(), err) + + _, err = s.WasmKeeper.Sudo(s.Ctx, contractAddr, sudoInitMsgBs) + require.NoError(s.T(), err) + + // set settings + authMsg := &smartaccounttypes.AuthorizationMsg{ + ContractAddress: contractAddr.String(), + InitMsg: sudoInitMsg.Initialization, + } + err = s.SmartAccountKeeper.SetSetting(s.Ctx, smartaccounttypes.Setting{ + Owner: acc.String(), + Authorization: []*smartaccounttypes.AuthorizationMsg{authMsg}, + }) + require.NoError(s.T(), err) + + // signing with testAcc1 pk which should error + txBuilder := s.BuildDefaultMsgTx(1, &types.MsgSend{ + FromAddress: acc.String(), + ToAddress: acc.String(), + Amount: sdk.NewCoins(sdk.NewInt64Coin("uluna", 1)), + }) + _, err = s.AuthDecorator.AnteHandle(s.Ctx, txBuilder.GetTx(), false, sdk.ChainAnteDecorators(sdk.Terminator{})) + require.Error(s.T(), err) + + // signing with testAcc0 pk which should pass + txBuilder = s.BuildDefaultMsgTx(0, &types.MsgSend{ + FromAddress: acc.String(), + ToAddress: acc.String(), + Amount: sdk.NewCoins(sdk.NewInt64Coin("uluna", 1)), + }) + _, err = s.AuthDecorator.AnteHandle(s.Ctx, txBuilder.GetTx(), false, sdk.ChainAnteDecorators(sdk.Terminator{})) + require.NoError(s.T(), err) +} + +func (s *AnteTestSuite) TestAuthAnteHandlerWithMultisig() { + s.Setup() + + type MultiSigSetting struct { + Signers []string `json:"signers"` + PublicKeys []string `json:"public_keys"` + Threshold uint8 `json:"threshold"` + } + + acc1 := s.TestAccs[1] + acc2 := s.TestAccs[2] + pubKey1 := s.TestAccPrivs[1].PubKey() + pubKey2 := s.TestAccPrivs[2].PubKey() + pkEncoded1 := []byte(base64.StdEncoding.EncodeToString(pubKey1.Bytes())) + pkEncoded2 := []byte(base64.StdEncoding.EncodeToString(pubKey2.Bytes())) + + codeId, _, err := s.WasmKeeper.Create(s.Ctx, acc1, test_helpers.SmartMultiSigWasm, nil) + require.NoError(s.T(), err) + contractAddr, _, err := s.WasmKeeper.Instantiate(s.Ctx, codeId, acc1, acc1, []byte("{}"), "auth", sdk.NewCoins()) + require.NoError(s.T(), err) + + setting := MultiSigSetting{ + Signers: []string{acc1.String(), acc2.String()}, + PublicKeys: []string{string(pkEncoded1), string(pkEncoded2)}, + Threshold: 2, + } + settingBs, err := json.Marshal(setting) + require.NoError(s.T(), err) + + // create initMsg + initMsg := smartaccounttypes.Initialization{ + Account: acc1.String(), + Msg: settingBs, + } + sudoInitMsg := smartaccounttypes.SudoMsg{Initialization: &initMsg} + sudoInitMsgBs, err := json.Marshal(sudoInitMsg) + require.NoError(s.T(), err) + + _, err = s.WasmKeeper.Sudo(s.Ctx, contractAddr, sudoInitMsgBs) + require.NoError(s.T(), err) + + // set settings + authMsg := &smartaccounttypes.AuthorizationMsg{ + ContractAddress: contractAddr.String(), + InitMsg: sudoInitMsg.Initialization, + } + err = s.SmartAccountKeeper.SetSetting(s.Ctx, smartaccounttypes.Setting{ + Owner: acc1.String(), + Fallback: false, + Authorization: []*smartaccounttypes.AuthorizationMsg{authMsg}, + }) + require.NoError(s.T(), err) + + // signing with multisig should pass + txBuilder := s.BuildDefaultMultiSigMsgTx([]int{1, 2}, &types.MsgSend{ + FromAddress: acc1.String(), + ToAddress: acc1.String(), + Amount: sdk.NewCoins(sdk.NewInt64Coin("uluna", 1)), + }) + _, err = s.AuthDecorator.AnteHandle(s.Ctx, txBuilder.GetTx(), false, sdk.ChainAnteDecorators(sdk.Terminator{})) + require.NoError(s.T(), err) + + // signing with multisig with only 1 signer should fail + txBuilder = s.BuildDefaultMultiSigMsgTx([]int{1}, &types.MsgSend{ + FromAddress: acc1.String(), + ToAddress: acc1.String(), + Amount: sdk.NewCoins(sdk.NewInt64Coin("uluna", 1)), + }) + _, err = s.AuthDecorator.AnteHandle(s.Ctx, txBuilder.GetTx(), false, sdk.ChainAnteDecorators(sdk.Terminator{})) + require.Error(s.T(), err) + require.ErrorContainsf(s.T(), err, "required: 2, found: 1", "") +} + +func (s *AnteTestSuite) BuildDefaultMsgTx(accountIndex int, msgs ...sdk.Msg) client.TxBuilder { + pk := s.TestAccPrivs[accountIndex] + sender := s.TestAccs[accountIndex] + senderAcc := s.App.Keepers.AccountKeeper.GetAccount(s.Ctx, sender) + senderSeq := senderAcc.GetSequence() + txBuilder := s.EncodingConfig.TxConfig.NewTxBuilder() + err := txBuilder.SetMsgs( + msgs..., + ) + require.NoError(s.T(), err) + + signer := authsigning.SignerData{ + Address: sender.String(), + ChainID: "test", + AccountNumber: senderAcc.GetAccountNumber(), + Sequence: senderSeq, + PubKey: pk.PubKey(), + } + + emptySig := signing.SignatureV2{ + PubKey: signer.PubKey, + Data: &signing.SingleSignatureData{ + SignMode: s.EncodingConfig.TxConfig.SignModeHandler().DefaultMode(), + Signature: nil, + }, + Sequence: signer.Sequence, + } + + err = txBuilder.SetSignatures(emptySig) + require.NoError(s.T(), err) + + sigV2, err := tx.SignWithPrivKey( + s.EncodingConfig.TxConfig.SignModeHandler().DefaultMode(), + signer, + txBuilder, + pk, + s.EncodingConfig.TxConfig, + senderSeq, + ) + require.NoError(s.T(), err) + + err = txBuilder.SetSignatures(sigV2) + require.NoError(s.T(), err) + + return txBuilder +} + +func (s *AnteTestSuite) BuildDefaultMultiSigMsgTx(accountIndices []int, msgs ...sdk.Msg) client.TxBuilder { + + txBuilder := s.EncodingConfig.TxConfig.NewTxBuilder() + err := txBuilder.SetMsgs( + msgs..., + ) + require.NoError(s.T(), err) + + var emptySigs []signing.SignatureV2 + + for _, accountIndex := range accountIndices { + sender := s.TestAccs[accountIndex] + senderAcc := s.App.Keepers.AccountKeeper.GetAccount(s.Ctx, sender) + senderSeq := senderAcc.GetSequence() + pk := s.TestAccPrivs[accountIndex] + + signer := authsigning.SignerData{ + Address: sender.String(), + ChainID: "test", + AccountNumber: senderAcc.GetAccountNumber(), + Sequence: senderSeq, + PubKey: pk.PubKey(), + } + + emptySig := signing.SignatureV2{ + PubKey: signer.PubKey, + Data: &signing.SingleSignatureData{ + SignMode: s.EncodingConfig.TxConfig.SignModeHandler().DefaultMode(), + Signature: nil, + }, + Sequence: signer.Sequence, + } + + emptySigs = append(emptySigs, emptySig) + } + err = txBuilder.SetSignatures(emptySigs...) + + require.NoError(s.T(), err) + + var signed []signing.SignatureV2 + for _, accountIndex := range accountIndices { + sender := s.TestAccs[accountIndex] + senderAcc := s.App.Keepers.AccountKeeper.GetAccount(s.Ctx, sender) + senderSeq := senderAcc.GetSequence() + pk := s.TestAccPrivs[accountIndex] + + signer := authsigning.SignerData{ + Address: sender.String(), + ChainID: "test", + AccountNumber: senderAcc.GetAccountNumber(), + Sequence: senderSeq, + PubKey: pk.PubKey(), + } + sigV2, err := tx.SignWithPrivKey( + s.EncodingConfig.TxConfig.SignModeHandler().DefaultMode(), + signer, + txBuilder, + pk, + s.EncodingConfig.TxConfig, + senderSeq, + ) + require.NoError(s.T(), err) + signed = append(signed, sigV2) + } + + err = txBuilder.SetSignatures(signed...) + require.NoError(s.T(), err) + + 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..25999f29 --- /dev/null +++ b/x/smartaccount/ante/tests/pretransaction_test.go @@ -0,0 +1,100 @@ +package tests + +import ( + "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" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/bank/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/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.PreTxDecorator.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{ + Owner: 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.PreTxDecorator.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{ + Owner: s.TestAccs[0].String(), + 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.PreTxDecorator.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{ + Owner: acc.String(), + 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.PreTxDecorator.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) + + // set settings + s.Ctx = s.Ctx.WithValue(smartaccounttypes.ModuleName, &smartaccounttypes.Setting{ + Owner: acc.String(), + PreTransaction: []string{contractAddr.String()}, + }) + + txBuilder := s.BuildDefaultMsgTx(0, &stakingtypes.MsgDelegate{ + DelegatorAddress: acc.String(), + ValidatorAddress: acc.String(), + Amount: sdk.NewInt64Coin("uluna", 100000000), + }) + _, err = s.PreTxDecorator.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 new file mode 100644 index 00000000..c8f810e8 --- /dev/null +++ b/x/smartaccount/client/cli/query.go @@ -0,0 +1,91 @@ +package cli + +import ( + "context" + "fmt" + + "github.com/spf13/cobra" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + + "github.com/terra-money/core/v2/x/smartaccount/types" +) + +// GetQueryCmd returns the cli query commands for this module +func GetQueryCmd() *cobra.Command { + smartAccountsQueryCmd := &cobra.Command{ + Use: types.ModuleName, + Short: fmt.Sprintf("Querying commands for the %s module", types.ModuleName), + DisableFlagParsing: true, + SuggestionsMinimumDistance: 2, + RunE: client.ValidateCmd, + } + + smartAccountsQueryCmd.AddCommand( + GetCmdQueryParams(), + GetCmdQuerySetting(), + ) + + return smartAccountsQueryCmd +} + +// GetCmdQueryParams implements a command to return the current SmartAccounts +// parameters. +func GetCmdQueryParams() *cobra.Command { + cmd := &cobra.Command{ + Use: "params", + Short: "Query the current smartaccount module parameters", + Args: cobra.NoArgs, + RunE: func(cmd *cobra.Command, _ []string) error { + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + queryClient := types.NewQueryClient(clientCtx) + + params := &types.QueryParamsRequest{} + + res, err := queryClient.Params(context.Background(), params) + if err != nil { + return err + } + + return clientCtx.PrintProto(&res.Params) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + + 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 new file mode 100644 index 00000000..9f8c1c73 --- /dev/null +++ b/x/smartaccount/client/cli/tx.go @@ -0,0 +1,93 @@ +package cli + +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 GetTxCmd() *cobra.Command { + txCmd := &cobra.Command{ + Use: types.ModuleName, + Short: "SmartAccounts subcommands", + DisableFlagParsing: true, + SuggestionsMinimumDistance: 2, + RunE: client.ValidateCmd, + } + + 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/exported/exported.go b/x/smartaccount/exported/exported.go new file mode 100644 index 00000000..000114e6 --- /dev/null +++ b/x/smartaccount/exported/exported.go @@ -0,0 +1,18 @@ +package exported + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" +) + +type ( + ParamSet = paramtypes.ParamSet + + // Subspace defines an interface that implements the legacy x/params Subspace + // type. + // + // NOTE: This is used solely for migration of x/params managed parameters. + Subspace interface { + GetParamSet(ctx sdk.Context, ps ParamSet) + } +) diff --git a/x/smartaccount/keeper/genesis.go b/x/smartaccount/keeper/genesis.go new file mode 100644 index 00000000..0eaabd73 --- /dev/null +++ b/x/smartaccount/keeper/genesis.go @@ -0,0 +1,45 @@ +package keeper + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/terra-money/core/v2/x/smartaccount/types" +) + +// InitGenesis import module genesis +func (k Keeper) InitGenesis( + ctx sdk.Context, + genesisState types.GenesisState, +) { + if err := k.SetParams(ctx, genesisState.Params); err != nil { + panic(err) + } + + for _, setting := range genesisState.Settings { + if err := k.SetSetting(ctx, *setting); err != nil { + panic(err) + } + } +} + +// ExportGenesis export module state +func (k Keeper) ExportGenesis(ctx sdk.Context) *types.GenesisState { + store := ctx.KVStore(k.storeKey) + iter := sdk.KVStorePrefixIterator(store, types.KeyPrefixSetting) + + settings := []*types.Setting{} + + defer iter.Close() + for ; iter.Valid(); iter.Next() { + var setting types.Setting + if err := setting.Unmarshal(iter.Value()); err != nil { + panic(err) + } + settings = append(settings, &setting) + } + + return &types.GenesisState{ + Params: k.GetParams(ctx), + Settings: settings, + } +} diff --git a/x/smartaccount/keeper/genesis_test.go b/x/smartaccount/keeper/genesis_test.go new file mode 100644 index 00000000..cb03d5c6 --- /dev/null +++ b/x/smartaccount/keeper/genesis_test.go @@ -0,0 +1,101 @@ +package keeper_test + +import ( + "fmt" + "testing" + + "github.com/stretchr/testify/suite" + + "github.com/terra-money/core/v2/app/test_helpers" + + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/terra-money/core/v2/x/feeshare/types" +) + +type GenesisTestSuite struct { + test_helpers.AppTestSuite +} + +func TestGenesisTestSuite(t *testing.T) { + suite.Run(t, new(GenesisTestSuite)) +} + +func (suite *GenesisTestSuite) TestFeeShareInitGenesis() { + testCases := []struct { + name string + genesis types.GenesisState + expPanic bool + }{ + { + "default genesis", + types.GenesisState{ + Params: types.DefaultParams(), + }, + false, + }, + { + "custom genesis - feeshare disabled", + types.GenesisState{ + Params: types.Params{ + EnableFeeShare: false, + DeveloperShares: types.DefaultDeveloperShares, + AllowedDenoms: []string{"uluna"}, + }, + }, + false, + }, + { + "custom genesis - feeshare enabled, 0% developer shares", + types.GenesisState{ + Params: types.Params{ + EnableFeeShare: true, + DeveloperShares: sdk.NewDecWithPrec(0, 2), + AllowedDenoms: []string{"uluna"}, + }, + }, + false, + }, + { + "custom genesis - feeshare enabled, 100% developer shares", + types.GenesisState{ + Params: types.Params{ + EnableFeeShare: true, + DeveloperShares: sdk.NewDecWithPrec(100, 2), + AllowedDenoms: []string{"uluna"}, + }, + }, + false, + }, + { + "custom genesis - feeshare enabled, all denoms allowed", + types.GenesisState{ + Params: types.Params{ + EnableFeeShare: true, + DeveloperShares: sdk.NewDecWithPrec(10, 2), + AllowedDenoms: []string(nil), + }, + }, + false, + }, + } + + for _, tc := range testCases { + suite.Run(fmt.Sprintf("Case %s", tc.name), func() { + suite.AppTestSuite.Setup() // reset + + if tc.expPanic { + suite.Require().Panics(func() { + suite.App.Keepers.FeeShareKeeper.InitGenesis(suite.Ctx, tc.genesis) + }) + } else { + suite.Require().NotPanics(func() { + suite.App.Keepers.FeeShareKeeper.InitGenesis(suite.Ctx, tc.genesis) + }) + + params := suite.App.Keepers.FeeShareKeeper.GetParams(suite.Ctx) + suite.Require().Equal(tc.genesis.Params, params) + } + }) + } +} diff --git a/x/smartaccount/keeper/grpc_query.go b/x/smartaccount/keeper/grpc_query.go new file mode 100644 index 00000000..e80befbc --- /dev/null +++ b/x/smartaccount/keeper/grpc_query.go @@ -0,0 +1,51 @@ +package keeper + +import ( + "context" + "encoding/base64" + + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/terra-money/core/v2/x/smartaccount/types" +) + +var _ types.QueryServer = Querier{} + +// Querier defines a wrapper around the x/SmartAccounts keeper providing gRPC method +// handlers. +type Querier struct { + Keeper +} + +func NewQuerier(k Keeper) Querier { + return Querier{Keeper: k} +} + +// Params returns the fees module params +func (q Querier) Params( + c context.Context, + _ *types.QueryParamsRequest, +) (*types.QueryParamsResponse, error) { + ctx := sdk.UnwrapSDKContext(c) + 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 + } + for _, auth := range setting.Authorization { + auth.InitMsg.Msg, err = base64.StdEncoding.DecodeString(string(auth.InitMsg.Msg)) + 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 new file mode 100644 index 00000000..48b4bff5 --- /dev/null +++ b/x/smartaccount/keeper/keeper.go @@ -0,0 +1,85 @@ +package keeper + +import ( + "fmt" + + "github.com/cometbft/cometbft/libs/log" + + "github.com/cosmos/cosmos-sdk/codec" + storetypes "github.com/cosmos/cosmos-sdk/store/types" + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + + "github.com/terra-money/core/v2/x/smartaccount/types" +) + +// Keeper of this module maintains collections of smartaccount for contracts +// registered to receive transaction fees. +type Keeper struct { + storeKey storetypes.StoreKey + cdc codec.BinaryCodec + wasmKeeper types.WasmKeeper +} + +// NewKeeper creates new instances of the fees Keeper +func NewKeeper( + cdc codec.BinaryCodec, + storeKey storetypes.StoreKey, + wk types.WasmKeeper, +) Keeper { + + return Keeper{ + storeKey: storeKey, + cdc: cdc, + wasmKeeper: wk, + } +} + +// Logger returns a module-specific logger. +func (k Keeper) Logger(ctx sdk.Context) log.Logger { + return ctx.Logger().With("module", fmt.Sprintf("x/%s", types.ModuleName)) +} + +// GetSetting returns the smart account setting for the ownerAddr +func (k Keeper) GetSetting(ctx sdk.Context, ownerAddr string) (*types.Setting, error) { + store := ctx.KVStore(k.storeKey) + bz := store.Get(types.GetKeyPrefixSetting(ownerAddr)) + if bz == nil { + return nil, sdkerrors.ErrKeyNotFound.Wrapf("setting not found for ownerAddr: %s", ownerAddr) + } + + var setting types.Setting + if err := setting.Unmarshal(bz); err != nil { + return nil, err + } + + return &setting, nil +} + +// SetSetting sets the smart account setting for the ownerAddr +func (k Keeper) SetSetting(ctx sdk.Context, setting types.Setting) error { + store := ctx.KVStore(k.storeKey) + bz, err := setting.Marshal() + if err != nil { + return err + } + if setting.Owner == "" { + return sdkerrors.ErrInvalidRequest.Wrap("owner cannot be empty") + } + store.Set(types.GetKeyPrefixSetting(setting.Owner), bz) + return nil +} + +// DeleteSetting deletes the smart account setting for the ownerAddr +func (k Keeper) DeleteSetting(ctx sdk.Context, ownerAddr string) error { + store := ctx.KVStore(k.storeKey) + if ownerAddr == "" { + return sdkerrors.ErrInvalidRequest.Wrap("owner cannot be empty") + } + bz := store.Get(types.GetKeyPrefixSetting(ownerAddr)) + if bz == nil { + return sdkerrors.ErrKeyNotFound.Wrapf("setting not found for ownerAddr: %s", ownerAddr) + } + store.Delete(types.GetKeyPrefixSetting(ownerAddr)) + return nil +} diff --git a/x/smartaccount/keeper/keeper_test.go b/x/smartaccount/keeper/keeper_test.go new file mode 100644 index 00000000..c0e0ca40 --- /dev/null +++ b/x/smartaccount/keeper/keeper_test.go @@ -0,0 +1,29 @@ +package keeper_test + +import ( + "testing" + + "github.com/stretchr/testify/suite" + + wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" + "github.com/terra-money/core/v2/x/smartaccount/keeper" + "github.com/terra-money/core/v2/x/smartaccount/test_helpers" + "github.com/terra-money/core/v2/x/smartaccount/types" +) + +type IntegrationTestSuite struct { + test_helpers.SmartAccountTestSuite + msgServer types.MsgServer + wasmKeeper *wasmkeeper.PermissionedKeeper +} + +func (s *IntegrationTestSuite) Setup() { + s.SmartAccountTestSuite.SetupTests() + s.msgServer = keeper.NewMsgServer(s.SmartAccountKeeper) + s.wasmKeeper = wasmkeeper.NewDefaultPermissionKeeper(s.App.Keepers.WasmKeeper) + s.Ctx = s.Ctx.WithChainID("test") +} + +func TestKeeperTestSuite(t *testing.T) { + suite.Run(t, new(IntegrationTestSuite)) +} diff --git a/x/smartaccount/keeper/migrator.go b/x/smartaccount/keeper/migrator.go new file mode 100644 index 00000000..f32381bb --- /dev/null +++ b/x/smartaccount/keeper/migrator.go @@ -0,0 +1,18 @@ +package keeper + +import ( + "github.com/terra-money/core/v2/x/smartaccount/exported" +) + +// Migrator is a struct for handling in-place state migrations. +type Migrator struct { + keeper Keeper + legacySubspace exported.Subspace +} + +func NewMigrator(k Keeper, ss exported.Subspace) Migrator { + return Migrator{ + keeper: k, + legacySubspace: ss, + } +} diff --git a/x/smartaccount/keeper/msg_server.go b/x/smartaccount/keeper/msg_server.go new file mode 100644 index 00000000..32048c4c --- /dev/null +++ b/x/smartaccount/keeper/msg_server.go @@ -0,0 +1,108 @@ +package keeper + +import ( + "context" + "encoding/json" + + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + + "github.com/terra-money/core/v2/x/smartaccount/types" +) + +var _ types.MsgServer = msgServer{} + +type msgServer struct { + k Keeper +} + +// NewMsgServer returns the MsgServer implementation. +func NewMsgServer(k Keeper) types.MsgServer { + return &msgServer{k} +} + +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, + Fallback: true, + }); err != nil { + return nil, err + } + return &types.MsgCreateSmartAccountResponse{}, nil +} + +func (ms msgServer) UpdateAuthorization( + goCtx context.Context, msg *types.MsgUpdateAuthorization, +) (*types.MsgUpdateAuthorizationResponse, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + + setting, err := ms.k.GetSetting(ctx, msg.Account) + if sdkerrors.ErrKeyNotFound.Is(err) { + setting = &types.Setting{ + Owner: msg.Account, + } + } else if err != nil { + return nil, err + } + setting.Authorization = msg.AuthorizationMsgs + for _, auth := range msg.AuthorizationMsgs { + sudoInitMsg := types.SudoMsg{Initialization: auth.InitMsg} + sudoInitMsgBs, err := json.Marshal(sudoInitMsg) + if err != nil { + return nil, err + } + + contractAddress, err := sdk.AccAddressFromBech32(auth.ContractAddress) + if err != nil { + return nil, err + } + if _, err := ms.k.wasmKeeper.Sudo(ctx, contractAddress, sudoInitMsgBs); err != nil { + return nil, err + } + } + setting.Fallback = msg.Fallback + if err := ms.k.SetSetting(ctx, *setting); err != nil { + return nil, err + } + return &types.MsgUpdateAuthorizationResponse{}, nil +} + +func (ms msgServer) UpdateTransactionHooks( + goCtx context.Context, msg *types.MsgUpdateTransactionHooks, +) (*types.MsgUpdateTransactionHooksResponse, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + setting, err := ms.k.GetSetting(ctx, msg.Account) + if sdkerrors.ErrKeyNotFound.Is(err) { + setting = &types.Setting{ + Owner: msg.Account, + } + } else if err != nil { + return nil, err + } + setting.PostTransaction = msg.PostTransactionHooks + setting.PreTransaction = msg.PreTransactionHooks + if err := ms.k.SetSetting(ctx, *setting); err != nil { + return nil, err + } + return &types.MsgUpdateTransactionHooksResponse{}, nil +} + +// DisableSmartAccount converts smart acc back to a basic acc +func (ms msgServer) DisableSmartAccount( + goCtx context.Context, msg *types.MsgDisableSmartAccount, +) (*types.MsgDisableSmartAccountResponse, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + if err := ms.k.DeleteSetting(ctx, msg.Account); err != nil { + return nil, err + } + return &types.MsgDisableSmartAccountResponse{}, nil +} diff --git a/x/smartaccount/keeper/msg_server_test.go b/x/smartaccount/keeper/msg_server_test.go new file mode 100644 index 00000000..ea7a260a --- /dev/null +++ b/x/smartaccount/keeper/msg_server_test.go @@ -0,0 +1,169 @@ +package keeper_test + +import ( + "encoding/base64" + + "github.com/stretchr/testify/require" + "github.com/terra-money/core/v2/x/smartaccount/test_helpers" + "github.com/terra-money/core/v2/x/smartaccount/types" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +func (s *IntegrationTestSuite) TestMsgCreateAndDisableSmartAccount() { + s.Setup() + sender := s.TestAccs[0] + + // Ensure that the smart account was not created + _, err := s.App.Keepers.SmartAccountKeeper.GetSetting(s.Ctx, sender.String()) + s.Require().Error(err) + + // Create a smart account + msg := types.NewMsgCreateSmartAccount(sender.String()) + _, err = s.msgServer.CreateSmartAccount(s.Ctx, msg) + s.Require().NoError(err) + + // Ensure that the smart account was created + _, err = s.App.Keepers.SmartAccountKeeper.GetSetting(s.Ctx, sender.String()) + s.Require().NoError(err) + + // Ensure that the smart account cannot be created again + _, err = s.msgServer.CreateSmartAccount(s.Ctx, msg) + s.Require().Error(err) + + // Disable the smart account + msgDisable := types.NewMsgDisableSmartAccount(sender.String()) + _, err = s.msgServer.DisableSmartAccount(s.Ctx, msgDisable) + s.Require().NoError(err) + + // Ensure that the smart account was disabled + _, err = s.App.Keepers.SmartAccountKeeper.GetSetting(s.Ctx, sender.String()) + s.Require().Error(err) +} + +func (s *IntegrationTestSuite) TestMsgUpdateAuthorization() { + s.Setup() + + // create smart account 1 + acc := s.TestAccs[1] + msg := types.NewMsgCreateSmartAccount(acc.String()) + _, err := s.msgServer.CreateSmartAccount(s.Ctx, msg) + s.Require().NoError(err) + + // testAcc1 using private key of testAcc0 + pubKey := s.TestAccPrivs[0].PubKey() + // endcoding this since this should be encoded in base64 when submitted by the user + pkEncoded := []byte(base64.StdEncoding.EncodeToString(pubKey.Bytes())) + + codeId, _, err := s.wasmKeeper.Create(s.Ctx, acc, test_helpers.SmartAuthContractWasm, nil) + require.NoError(s.T(), err) + contractAddr, _, err := s.wasmKeeper.Instantiate(s.Ctx, codeId, acc, acc, []byte("{}"), "auth", sdk.NewCoins()) + require.NoError(s.T(), err) + + // create updateAuth msg + initMsg := types.Initialization{ + Account: acc.String(), + Msg: pkEncoded, + } + authMsg := &types.AuthorizationMsg{ + ContractAddress: contractAddr.String(), + InitMsg: &initMsg, + } + _, err = s.msgServer.UpdateAuthorization(s.Ctx, types.NewMsgUpdateAuthorization( + acc.String(), + []*types.AuthorizationMsg{authMsg}, + false, + )) + require.NoError(s.T(), err) + + // Ensure that the smart account was updated + setting, err := s.App.Keepers.SmartAccountKeeper.GetSetting(s.Ctx, acc.String()) + s.Require().NoError(err) + s.Require().Equal(acc.String(), setting.Owner) + s.CheckAuthorizationEqual([]*types.AuthorizationMsg{authMsg}, setting.Authorization) + + // deploy another auth contract + contractAddr2, _, err := s.wasmKeeper.Instantiate(s.Ctx, codeId, acc, acc, []byte("{}"), "auth", sdk.NewCoins()) + require.NoError(s.T(), err) + + // create updateAuth msg + authMsg2 := &types.AuthorizationMsg{ + ContractAddress: contractAddr2.String(), + InitMsg: &initMsg, + } + _, err = s.msgServer.UpdateAuthorization(s.Ctx, types.NewMsgUpdateAuthorization( + acc.String(), + []*types.AuthorizationMsg{authMsg2}, + false, + )) + require.NoError(s.T(), err) + + // Ensure that the smart account was updated again + setting, err = s.App.Keepers.SmartAccountKeeper.GetSetting(s.Ctx, acc.String()) + s.Require().NoError(err) + s.Require().Equal(acc.String(), setting.Owner) + s.CheckAuthorizationEqual([]*types.AuthorizationMsg{authMsg2}, setting.Authorization) +} + +func (s *IntegrationTestSuite) TestMsgUpdateTransactionHooks() { + s.Setup() + sender := s.TestAccs[0] + + // Create a smart account + msg := types.NewMsgCreateSmartAccount(sender.String()) + _, err := s.msgServer.CreateSmartAccount(s.Ctx, msg) + s.Require().NoError(err) + + // update transaction hooks + pretx := []string{"hook1", "hook2"} + posttx := []string{"hook3", "hook4"} + msgUpdate := types.NewMsgUpdateTransactionHooks( + sender.String(), + pretx, + posttx, + ) + _, err = s.msgServer.UpdateTransactionHooks(s.Ctx, msgUpdate) + s.Require().NoError(err) + + // Ensure that the smart account was updated + setting, err := s.App.Keepers.SmartAccountKeeper.GetSetting(s.Ctx, sender.String()) + s.Require().NoError(err) + s.Require().Equal(sender.String(), setting.Owner) + s.Require().Equal(pretx, setting.PreTransaction) + s.Require().Equal(posttx, setting.PostTransaction) + + // update authorization again + pretx = []string{"hook5", "hook6"} + posttx = []string{"hook7", "hook8"} + msgUpdate = types.NewMsgUpdateTransactionHooks( + sender.String(), + pretx, + posttx, + ) + _, err = s.msgServer.UpdateTransactionHooks(s.Ctx, msgUpdate) + s.Require().NoError(err) + + // Ensure that the smart account was updated again + setting, err = s.App.Keepers.SmartAccountKeeper.GetSetting(s.Ctx, sender.String()) + s.Require().NoError(err) + s.Require().Equal(sender.String(), setting.Owner) + s.Require().Equal(pretx, setting.PreTransaction) + s.Require().Equal(posttx, setting.PostTransaction) +} + +func (s *IntegrationTestSuite) CheckSettingEqual(a types.Setting, b types.Setting) { + s.Require().Equal(a.Owner, b.Owner) + s.Require().Equal(a.Fallback, b.Fallback) + s.CheckAuthorizationEqual(a.Authorization, b.Authorization) + s.Require().Equal(a.PreTransaction, b.PreTransaction) + s.Require().Equal(a.PostTransaction, b.PostTransaction) +} + +func (s *IntegrationTestSuite) CheckAuthorizationEqual(a []*types.AuthorizationMsg, b []*types.AuthorizationMsg) { + s.Require().Equal(len(a), len(b)) + for i := range a { + s.Require().Equal(a[i].ContractAddress, b[i].ContractAddress) + s.Require().Equal(a[i].InitMsg.Msg, b[i].InitMsg.Msg) + s.Require().Equal(a[i].InitMsg.Account, b[i].InitMsg.Account) + } +} diff --git a/x/smartaccount/keeper/params.go b/x/smartaccount/keeper/params.go new file mode 100644 index 00000000..0b7be35e --- /dev/null +++ b/x/smartaccount/keeper/params.go @@ -0,0 +1,32 @@ +package keeper + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/terra-money/core/v2/x/smartaccount/types" +) + +// GetParams returns the total set of fees parameters. +func (k Keeper) GetParams(ctx sdk.Context) (p types.Params) { + store := ctx.KVStore(k.storeKey) + bz := store.Get(types.ParamsKey) + if bz == nil { + return p + } + + k.cdc.MustUnmarshal(bz, &p) + return p +} + +// SetParams sets the fees parameters to the param space. +func (k Keeper) SetParams(ctx sdk.Context, p types.Params) error { + if err := p.Validate(); err != nil { + return err + } + + store := ctx.KVStore(k.storeKey) + bz := k.cdc.MustMarshal(&p) + store.Set(types.ParamsKey, bz) + + return nil +} diff --git a/x/smartaccount/module.go b/x/smartaccount/module.go new file mode 100644 index 00000000..3c24ab6c --- /dev/null +++ b/x/smartaccount/module.go @@ -0,0 +1,194 @@ +package smartaccount + +import ( + "context" + "encoding/json" + "fmt" + + "github.com/gorilla/mux" + "github.com/grpc-ecosystem/grpc-gateway/runtime" + "github.com/spf13/cobra" + + abci "github.com/cometbft/cometbft/abci/types" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/codec" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/module" + simtypes "github.com/cosmos/cosmos-sdk/types/simulation" + + "github.com/terra-money/core/v2/x/smartaccount/client/cli" + "github.com/terra-money/core/v2/x/smartaccount/exported" + "github.com/terra-money/core/v2/x/smartaccount/keeper" + "github.com/terra-money/core/v2/x/smartaccount/types" +) + +// type check to ensure the interface is properly implemented +var ( + _ module.AppModule = AppModule{} + _ module.AppModuleBasic = AppModuleBasic{} + _ module.AppModuleSimulation = AppModule{} +) + +// ConsensusVersion defines the current x/smartaccount module consensus version. +const ConsensusVersion = 1 + +// AppModuleBasic type for the fees module +type AppModuleBasic struct{} + +// Name returns the fees module's name. +func (AppModuleBasic) Name() string { + return types.ModuleName +} + +// RegisterLegacyAminoCodec performs a no-op as the fees do not support Amino +// encoding. +func (AppModuleBasic) RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) { + types.RegisterLegacyAminoCodec(cdc) +} + +// ConsensusVersion returns the consensus state-breaking version for the module. +func (AppModuleBasic) ConsensusVersion() uint64 { + return ConsensusVersion +} + +// RegisterInterfaces registers interfaces and implementations of the fees +// module. +func (AppModuleBasic) RegisterInterfaces(interfaceRegistry codectypes.InterfaceRegistry) { + types.RegisterInterfaces(interfaceRegistry) +} + +// DefaultGenesis returns default genesis state as raw bytes for the fees +// module. +func (AppModuleBasic) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage { + return cdc.MustMarshalJSON(types.DefaultGenesisState()) +} + +// ValidateGenesis performs genesis state validation for the fees module. +func (b AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, _ client.TxEncodingConfig, bz json.RawMessage) error { + var genesisState types.GenesisState + if err := cdc.UnmarshalJSON(bz, &genesisState); err != nil { + return fmt.Errorf("failed to unmarshal %s genesis state: %w", types.ModuleName, err) + } + + return genesisState.Validate() +} + +// RegisterRESTRoutes performs a no-op as the fees module doesn't expose REST +// endpoints +func (AppModuleBasic) RegisterRESTRoutes(_ client.Context, _ *mux.Router) {} + +// RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the fees +// module. +func (b AppModuleBasic) RegisterGRPCGatewayRoutes(c client.Context, serveMux *runtime.ServeMux) { + if err := types.RegisterQueryHandlerClient(context.Background(), serveMux, types.NewQueryClient(c)); err != nil { + panic(err) + } +} + +// GetTxCmd returns the root tx command for the fees module. +func (AppModuleBasic) GetTxCmd() *cobra.Command { + return cli.GetTxCmd() +} + +// GetQueryCmd returns the fees module's root query command. +func (AppModuleBasic) GetQueryCmd() *cobra.Command { + return cli.GetQueryCmd() +} + +// ___________________________________________________________________________ + +// AppModule implements the AppModule interface for the fees module. +type AppModule struct { + AppModuleBasic + keeper keeper.Keeper + + // legacySubspace is used solely for migration of x/params managed parameters + legacySubspace exported.Subspace +} + +// NewAppModule creates a new AppModule Object +func NewAppModule( + k keeper.Keeper, + ss exported.Subspace, +) AppModule { + return AppModule{ + AppModuleBasic: AppModuleBasic{}, + keeper: k, + legacySubspace: ss, + } +} + +// Name returns the fees module's name. +func (AppModule) Name() string { + return types.ModuleName +} + +// RegisterInvariants registers the fees module's invariants. +func (am AppModule) RegisterInvariants(_ sdk.InvariantRegistry) {} + +// NewHandler returns nil - fees module doesn't expose tx gRPC endpoints +func (am AppModule) NewHandler() sdk.Handler { + return nil +} + +// QuerierRoute returns the claim module's query routing key. +func (am AppModule) QuerierRoute() string { + return types.RouterKey +} + +// RegisterServices registers a GRPC query service to respond to the +// module-specific GRPC queries. +func (am AppModule) RegisterServices(cfg module.Configurator) { + types.RegisterMsgServer(cfg.MsgServer(), keeper.NewMsgServer(am.keeper)) + types.RegisterQueryServer(cfg.QueryServer(), keeper.NewQuerier(am.keeper)) +} + +// BeginBlock executes all ABCI BeginBlock logic respective to the fees module. +func (am AppModule) BeginBlock(_ sdk.Context, _ abci.RequestBeginBlock) { +} + +// EndBlock executes all ABCI EndBlock logic respective to the fee-share module. It +// returns no validator updates. +func (am AppModule) EndBlock(_ sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate { + return []abci.ValidatorUpdate{} +} + +// InitGenesis performs the fees module's genesis initialization. It returns +// no validator updates. +func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, data json.RawMessage) []abci.ValidatorUpdate { + var genesisState types.GenesisState + + cdc.MustUnmarshalJSON(data, &genesisState) + am.keeper.InitGenesis(ctx, genesisState) + return []abci.ValidatorUpdate{} +} + +// ExportGenesis returns the fees module's exported genesis state as raw JSON bytes. +func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.RawMessage { + gs := am.keeper.ExportGenesis(ctx) + return cdc.MustMarshalJSON(gs) +} + +// ___________________________________________________________________________ + +// AppModuleSimulation functions + +// GenerateGenesisState creates a randomized GenState of the fees module. +func (am AppModule) GenerateGenesisState(_ *module.SimulationState) { +} + +// ProposalContents returns content functions for governance proposals. +func (am AppModule) ProposalContents(_ module.SimulationState) []simtypes.WeightedProposalMsg { + return []simtypes.WeightedProposalMsg{} +} + +// RegisterStoreDecoder registers a decoder for fees module's types. +func (am AppModule) RegisterStoreDecoder(_ sdk.StoreDecoderRegistry) { +} + +// WeightedOperations returns fees module weighted operations +func (am AppModule) WeightedOperations(_ module.SimulationState) []simtypes.WeightedOperation { + return []simtypes.WeightedOperation{} +} diff --git a/x/smartaccount/post/expected_keepers.go b/x/smartaccount/post/expected_keepers.go new file mode 100644 index 00000000..3a346f91 --- /dev/null +++ b/x/smartaccount/post/expected_keepers.go @@ -0,0 +1,15 @@ +package post + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + + smartaccounttypes "github.com/terra-money/core/v2/x/smartaccount/types" +) + +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/post/posttransaction.go b/x/smartaccount/post/posttransaction.go new file mode 100644 index 00000000..9a94859b --- /dev/null +++ b/x/smartaccount/post/posttransaction.go @@ -0,0 +1,55 @@ +package post + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/terra-money/core/v2/x/smartaccount/ante" + "github.com/terra-money/core/v2/x/smartaccount/types" +) + +type PostTransactionHookDecorator struct { + smartaccountKeeper SmartAccountKeeper + wasmKeeper WasmKeeper +} + +func NewPostTransactionHookDecorator(sak SmartAccountKeeper, wk WasmKeeper) PostTransactionHookDecorator { + return PostTransactionHookDecorator{ + smartaccountKeeper: sak, + wasmKeeper: wk, + } +} + +func (pth PostTransactionHookDecorator) PostHandle( + ctx sdk.Context, + tx sdk.Tx, + simulate bool, + success bool, + next sdk.PostHandler, +) (newCtx sdk.Context, err error) { + setting, ok := ctx.Value(types.ModuleName).(*types.Setting) + if !ok { + return next(ctx, tx, simulate, success) + } + + if setting.PostTransaction != nil && len(setting.PostTransaction) > 0 { + for _, postTx := range setting.PostTransaction { + contractAddr, err := sdk.AccAddressFromBech32(postTx) + if err != nil { + return ctx, err + } + data, err := BuildPostTransactionHookMsg(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, success) +} + +func BuildPostTransactionHookMsg(tx sdk.Tx) ([]byte, error) { + return ante.BuildPrePostTransactionHookMsg(tx, false) +} diff --git a/x/smartaccount/post/posttransaction_test.go b/x/smartaccount/post/posttransaction_test.go new file mode 100644 index 00000000..e1e93891 --- /dev/null +++ b/x/smartaccount/post/posttransaction_test.go @@ -0,0 +1,171 @@ +package post_test + +import ( + "testing" + + wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" + "github.com/terra-money/core/v2/x/smartaccount/post" + "github.com/terra-money/core/v2/x/smartaccount/test_helpers" + smartaccounttypes "github.com/terra-money/core/v2/x/smartaccount/types" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/tx" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/tx/signing" + authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing" + "github.com/cosmos/cosmos-sdk/x/bank/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" +) + +type PostTxTestSuite struct { + test_helpers.SmartAccountTestSuite + + PostTxDecorator post.PostTransactionHookDecorator + WasmKeeper *wasmkeeper.PermissionedKeeper +} + +func TestAnteSuite(t *testing.T) { + suite.Run(t, new(PostTxTestSuite)) +} + +func (s *PostTxTestSuite) Setup() { + s.SmartAccountTestSuite.SetupTests() + s.WasmKeeper = wasmkeeper.NewDefaultPermissionKeeper(s.App.Keepers.WasmKeeper) + s.PostTxDecorator = post.NewPostTransactionHookDecorator(s.SmartAccountKeeper, s.WasmKeeper) + s.Ctx = s.Ctx.WithChainID("test") +} + +func (s *PostTxTestSuite) TestPostTransactionHookWithoutSmartAccount() { + 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.PostTxDecorator.PostHandle(s.Ctx, txBuilder.GetTx(), false, true, sdk.ChainPostDecorators(sdk.Terminator{})) + require.NoError(s.T(), err) +} + +func (s *PostTxTestSuite) TestPostTransactionHookWithEmptySmartAccount() { + 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.PostTxDecorator.PostHandle(s.Ctx, txBuilder.GetTx(), false, true, sdk.ChainPostDecorators(sdk.Terminator{})) + require.NoError(s.T(), err) +} + +func (s *PostTxTestSuite) TestInvalidContractAddress() { + s.Setup() + s.Ctx = s.Ctx.WithValue(smartaccounttypes.ModuleName, &smartaccounttypes.Setting{ + PostTransaction: []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.PostTxDecorator.PostHandle(s.Ctx, txBuilder.GetTx(), false, true, sdk.ChainPostDecorators(sdk.Terminator{})) + require.ErrorContainsf(s.T(), err, "no such contract", "error message: %s", err) +} + +func (s *PostTxTestSuite) TestSendWithinLimitWithLimitCoinsSendHook() { + s.Setup() + + acc := s.TestAccs[0] + codeId, _, err := s.WasmKeeper.Create(s.Ctx, acc, test_helpers.LimitMinCoinsHookWasm, 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{ + PostTransaction: []string{contractAddr.String()}, + }) + + err = s.App.Keepers.BankKeeper.SendCoinsFromAccountToModule(s.Ctx, acc, smartaccounttypes.ModuleName, sdk.NewCoins(sdk.NewInt64Coin("uluna", 10000000))) + require.NoError(s.T(), err) + + txBuilder := s.BuildDefaultMsgTx(0, &types.MsgSend{ + FromAddress: acc.String(), + ToAddress: acc.String(), + Amount: sdk.NewCoins(sdk.NewInt64Coin("uluna", 10000000)), + }) + _, err = s.PostTxDecorator.PostHandle(s.Ctx, txBuilder.GetTx(), false, true, sdk.ChainPostDecorators(sdk.Terminator{})) + require.NoError(s.T(), err) +} + +func (s *PostTxTestSuite) TestSendOverLimitWithLimitCoinsSendHook() { + s.Setup() + + acc := s.TestAccs[0] + codeId, _, err := s.WasmKeeper.Create(s.Ctx, acc, test_helpers.LimitMinCoinsHookWasm, 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{ + PostTransaction: []string{contractAddr.String()}, + }) + + err = s.App.Keepers.BankKeeper.SendCoinsFromAccountToModule(s.Ctx, acc, smartaccounttypes.ModuleName, sdk.NewCoins(sdk.NewInt64Coin("uluna", 100000000))) + require.NoError(s.T(), err) + + txBuilder := s.BuildDefaultMsgTx(0, &stakingtypes.MsgDelegate{ + DelegatorAddress: acc.String(), + ValidatorAddress: acc.String(), + Amount: sdk.NewInt64Coin("uluna", 100000000), + }) + _, err = s.PostTxDecorator.PostHandle(s.Ctx, txBuilder.GetTx(), false, true, sdk.ChainPostDecorators(sdk.Terminator{})) + require.ErrorContainsf(s.T(), err, "Failed post transaction process", "error message: %s", err) +} + +func (s *PostTxTestSuite) BuildDefaultMsgTx(accountIndex int, msgs ...sdk.Msg) client.TxBuilder { + pk := s.TestAccPrivs[accountIndex] + sender := s.TestAccs[accountIndex] + acc := s.App.Keepers.AccountKeeper.GetAccount(s.Ctx, msgs[0].GetSigners()[0]) + txBuilder := s.EncodingConfig.TxConfig.NewTxBuilder() + err := txBuilder.SetMsgs( + msgs..., + ) + require.NoError(s.T(), err) + + signer := authsigning.SignerData{ + Address: sender.String(), + ChainID: "test", + AccountNumber: acc.GetAccountNumber(), + Sequence: acc.GetSequence(), + PubKey: pk.PubKey(), + } + + emptySig := signing.SignatureV2{ + PubKey: signer.PubKey, + Data: &signing.SingleSignatureData{ + SignMode: s.EncodingConfig.TxConfig.SignModeHandler().DefaultMode(), + Signature: nil, + }, + Sequence: signer.Sequence, + } + + err = txBuilder.SetSignatures(emptySig) + require.NoError(s.T(), err) + + sigV2, err := tx.SignWithPrivKey( + s.EncodingConfig.TxConfig.SignModeHandler().DefaultMode(), + signer, + txBuilder, + pk, + s.EncodingConfig.TxConfig, + acc.GetSequence(), + ) + require.NoError(s.T(), err) + + err = txBuilder.SetSignatures(sigV2) + require.NoError(s.T(), err) + + return txBuilder +} diff --git a/x/smartaccount/test_helpers/test_data.go b/x/smartaccount/test_helpers/test_data.go new file mode 100644 index 00000000..727651f2 --- /dev/null +++ b/x/smartaccount/test_helpers/test_data.go @@ -0,0 +1,15 @@ +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 + +//go:embed test_data/smart_auth_multisig.wasm +var SmartMultiSigWasm []byte + +//go:embed test_data/limit_min_coins_hooks.wasm +var LimitMinCoinsHookWasm []byte diff --git a/x/smartaccount/test_helpers/test_data/limit_min_coins_hooks.wasm b/x/smartaccount/test_helpers/test_data/limit_min_coins_hooks.wasm new file mode 100644 index 00000000..8337f10b Binary files /dev/null and b/x/smartaccount/test_helpers/test_data/limit_min_coins_hooks.wasm differ 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 100644 index 00000000..cdbb1513 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 100644 index 00000000..fec4ded0 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_data/smart_auth_multisig.wasm b/x/smartaccount/test_helpers/test_data/smart_auth_multisig.wasm new file mode 100644 index 00000000..e471f635 Binary files /dev/null and b/x/smartaccount/test_helpers/test_data/smart_auth_multisig.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..f4f85be9 --- /dev/null +++ b/x/smartaccount/test_helpers/test_helpers.go @@ -0,0 +1,17 @@ +package test_helpers + +import ( + "github.com/terra-money/core/v2/app/test_helpers" + "github.com/terra-money/core/v2/x/smartaccount/keeper" +) + +type SmartAccountTestSuite struct { + test_helpers.AppTestSuite + + SmartAccountKeeper keeper.Keeper +} + +func (s *SmartAccountTestSuite) SetupTests() { + s.Setup() + s.SmartAccountKeeper = s.App.Keepers.SmartAccountKeeper +} diff --git a/x/smartaccount/types/codec.go b/x/smartaccount/types/codec.go new file mode 100644 index 00000000..ebe019e9 --- /dev/null +++ b/x/smartaccount/types/codec.go @@ -0,0 +1,66 @@ +package types + +import ( + "github.com/cosmos/cosmos-sdk/codec" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/msgservice" + authzcodec "github.com/cosmos/cosmos-sdk/x/authz/codec" +) + +var ( + amino = codec.NewLegacyAmino() + + // ModuleCdc references the global erc20 module codec. Note, the codec should + // ONLY be used in certain instances of tests and for JSON encoding. + // + // The actual codec used for serialization should be provided to modules/erc20 and + // defined at the application level. + ModuleCdc = codec.NewProtoCodec(codectypes.NewInterfaceRegistry()) + + // AminoCdc is a amino codec created to support amino JSON compatible msgs. + AminoCdc = codec.NewAminoCodec(amino) +) + +const ( + // Amino names + createSmartAccount = "terra/MsgCreateSmartAccount" + disableSmartAccount = "terra/MsgDisableSmartAccount" + updateAuthorization = "terra/MsgUpdateAuthorization" + updateTransactionHooks = "terra/MsgUpdateTransactionHooks" +) + +// NOTE: This is required for the GetSignBytes function +func init() { + RegisterLegacyAminoCodec(amino) + + sdk.RegisterLegacyAminoCodec(amino) + + // Register all Amino interfaces and concrete types on the authz Amino codec + // so that this can later be used to properly serialize MsgGrant and MsgExec + // instances. + RegisterLegacyAminoCodec(authzcodec.Amino) +} + +// RegisterInterfaces register implementations +func RegisterInterfaces(registry codectypes.InterfaceRegistry) { + registry.RegisterImplementations( + (*sdk.Msg)(nil), + &MsgCreateSmartAccount{}, + &MsgUpdateAuthorization{}, + &MsgUpdateTransactionHooks{}, + &MsgDisableSmartAccount{}, + ) + + msgservice.RegisterMsgServiceDesc(registry, &_Msg_serviceDesc) +} + +// RegisterLegacyAminoCodec registers the necessary x/SmartAccounts interfaces and +// concrete types on the provided LegacyAmino codec. These types are used for +// Amino JSON serialization and EIP-712 compatibility. +func RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) { + cdc.RegisterConcrete(&MsgCreateSmartAccount{}, createSmartAccount, nil) + cdc.RegisterConcrete(&MsgUpdateAuthorization{}, updateAuthorization, nil) + cdc.RegisterConcrete(&MsgUpdateTransactionHooks{}, updateTransactionHooks, nil) + cdc.RegisterConcrete(&MsgDisableSmartAccount{}, disableSmartAccount, nil) +} diff --git a/x/smartaccount/types/codec_test.go b/x/smartaccount/types/codec_test.go new file mode 100644 index 00000000..7c54de29 --- /dev/null +++ b/x/smartaccount/types/codec_test.go @@ -0,0 +1,33 @@ +package types + +import ( + "testing" + + "github.com/stretchr/testify/suite" + + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +type CodecTestSuite struct { + suite.Suite +} + +func TestCodecSuite(t *testing.T) { + suite.Run(t, new(CodecTestSuite)) +} + +func (suite *CodecTestSuite) TestRegisterInterfaces() { + registry := codectypes.NewInterfaceRegistry() + registry.RegisterInterface(sdk.MsgInterfaceProtoName, (*sdk.Msg)(nil)) + RegisterInterfaces(registry) + + impls := registry.ListImplementations(sdk.MsgInterfaceProtoName) + suite.Require().Equal(4, len(impls)) + suite.Require().ElementsMatch([]string{ + "/terra.smartaccount.v1.MsgCreateSmartAccount", + "/terra.smartaccount.v1.MsgUpdateAuthorization", + "/terra.smartaccount.v1.MsgUpdateTransactionHooks", + "/terra.smartaccount.v1.MsgDisableSmartAccount", + }, impls) +} diff --git a/x/smartaccount/types/errors.go b/x/smartaccount/types/errors.go new file mode 100644 index 00000000..72733888 --- /dev/null +++ b/x/smartaccount/types/errors.go @@ -0,0 +1,9 @@ +package types + +import ( + errorsmod "cosmossdk.io/errors" +) + +var ( + ErrFeeShareDisabled = errorsmod.Register(ModuleName, 1, "smartaccount module is disabled by governance") +) diff --git a/x/smartaccount/types/expected_keepers.go b/x/smartaccount/types/expected_keepers.go new file mode 100644 index 00000000..228c93a4 --- /dev/null +++ b/x/smartaccount/types/expected_keepers.go @@ -0,0 +1,29 @@ +package types + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + acctypes "github.com/cosmos/cosmos-sdk/x/auth/types" +) + +// AccountKeeper defines the expected interface needed to retrieve account info. +type AccountKeeper interface { + GetModuleAddress(moduleName string) sdk.AccAddress + GetModuleAccount(ctx sdk.Context, name string) acctypes.ModuleAccountI + + HasAccount(ctx sdk.Context, addr sdk.AccAddress) bool + GetAccount(ctx sdk.Context, addr sdk.AccAddress) (account acctypes.AccountI) +} + +// BankKeeper defines the expected interface needed to retrieve account balances. +type BankKeeper interface { + SendCoinsFromModuleToAccount(ctx sdk.Context, senderModule string, recipientAddr sdk.AccAddress, amt sdk.Coins) error + SendCoinsFromAccountToModule(ctx sdk.Context, senderAddr sdk.AccAddress, recipientModule string, amt sdk.Coins) error + BurnCoins(ctx sdk.Context, moduleName string, amt sdk.Coins) error + GetBalance(ctx sdk.Context, addr sdk.AccAddress, denom string) sdk.Coin + GetAllBalances(ctx sdk.Context, addr sdk.AccAddress) sdk.Coins +} + +// WasmKeeper defines the expected interface needed to retrieve cosmwasm contracts. +type WasmKeeper interface { + Sudo(ctx sdk.Context, contractAddress sdk.AccAddress, msg []byte) ([]byte, error) +} diff --git a/x/smartaccount/types/genesis.go b/x/smartaccount/types/genesis.go new file mode 100644 index 00000000..dcdece22 --- /dev/null +++ b/x/smartaccount/types/genesis.go @@ -0,0 +1,32 @@ +package types + +// NewGenesisState creates a new genesis state. +func NewGenesisState(params Params, settings []*Setting) GenesisState { + return GenesisState{ + Params: params, + Settings: settings, + } +} + +// DefaultGenesisState sets default evm genesis state with empty accounts and +// default params and chain config values. +func DefaultGenesisState() *GenesisState { + return &GenesisState{ + Params: DefaultParams(), + Settings: DefaultSettings(), + } +} + +// Validate performs basic genesis state validation returning an error upon any +// failure. +func (gs GenesisState) Validate() error { + if err := gs.Params.Validate(); err != nil { + return err + } + for _, setting := range gs.Settings { + if err := setting.Validate(); err != nil { + return err + } + } + return nil +} diff --git a/x/smartaccount/types/genesis.pb.go b/x/smartaccount/types/genesis.pb.go new file mode 100644 index 00000000..655de284 --- /dev/null +++ b/x/smartaccount/types/genesis.pb.go @@ -0,0 +1,389 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: terra/smartaccount/v1/genesis.proto + +package types + +import ( + fmt "fmt" + _ "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 + +// GenesisState defines the smartaccount module's genesis state. +type GenesisState struct { + // params defines the paramaters of the module. + Params Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params"` + Settings []*Setting `protobuf:"bytes,2,rep,name=settings,proto3" json:"settings,omitempty"` +} + +func (m *GenesisState) Reset() { *m = GenesisState{} } +func (m *GenesisState) String() string { return proto.CompactTextString(m) } +func (*GenesisState) ProtoMessage() {} +func (*GenesisState) Descriptor() ([]byte, []int) { + return fileDescriptor_8785c0eaaec41a7d, []int{0} +} +func (m *GenesisState) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *GenesisState) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_GenesisState.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 *GenesisState) XXX_Merge(src proto.Message) { + xxx_messageInfo_GenesisState.Merge(m, src) +} +func (m *GenesisState) XXX_Size() int { + return m.Size() +} +func (m *GenesisState) XXX_DiscardUnknown() { + xxx_messageInfo_GenesisState.DiscardUnknown(m) +} + +var xxx_messageInfo_GenesisState proto.InternalMessageInfo + +func (m *GenesisState) GetParams() Params { + if m != nil { + return m.Params + } + return Params{} +} + +func (m *GenesisState) GetSettings() []*Setting { + if m != nil { + return m.Settings + } + return nil +} + +func init() { + proto.RegisterType((*GenesisState)(nil), "terra.smartaccount.v1.GenesisState") +} + +func init() { + proto.RegisterFile("terra/smartaccount/v1/genesis.proto", fileDescriptor_8785c0eaaec41a7d) +} + +var fileDescriptor_8785c0eaaec41a7d = []byte{ + // 247 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x52, 0x2e, 0x49, 0x2d, 0x2a, + 0x4a, 0xd4, 0x2f, 0xce, 0x4d, 0x2c, 0x2a, 0x49, 0x4c, 0x4e, 0xce, 0x2f, 0xcd, 0x2b, 0xd1, 0x2f, + 0x33, 0xd4, 0x4f, 0x4f, 0xcd, 0x4b, 0x2d, 0xce, 0x2c, 0xd6, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, + 0x12, 0x05, 0x2b, 0xd2, 0x43, 0x56, 0xa4, 0x57, 0x66, 0x28, 0x25, 0x92, 0x9e, 0x9f, 0x9e, 0x0f, + 0x56, 0xa1, 0x0f, 0x62, 0x41, 0x14, 0x4b, 0x29, 0x61, 0x37, 0xb1, 0x20, 0xb1, 0x28, 0x31, 0x17, + 0x6a, 0xa0, 0x14, 0x0e, 0x5b, 0x8b, 0x53, 0x4b, 0x4a, 0x32, 0xf3, 0xd2, 0x21, 0x8a, 0x94, 0xda, + 0x19, 0xb9, 0x78, 0xdc, 0x21, 0xee, 0x08, 0x2e, 0x49, 0x2c, 0x49, 0x15, 0xb2, 0xe6, 0x62, 0x83, + 0x98, 0x22, 0xc1, 0xa8, 0xc0, 0xa8, 0xc1, 0x6d, 0x24, 0xab, 0x87, 0xd5, 0x5d, 0x7a, 0x01, 0x60, + 0x45, 0x4e, 0x2c, 0x27, 0xee, 0xc9, 0x33, 0x04, 0x41, 0xb5, 0x08, 0x59, 0x71, 0x71, 0x40, 0x8d, + 0x2f, 0x96, 0x60, 0x52, 0x60, 0xd6, 0xe0, 0x36, 0x92, 0xc3, 0xa1, 0x3d, 0x18, 0xa2, 0x2c, 0x08, + 0xae, 0xde, 0xc9, 0xf7, 0xc4, 0x23, 0x39, 0xc6, 0x0b, 0x8f, 0xe4, 0x18, 0x1f, 0x3c, 0x92, 0x63, + 0x9c, 0xf0, 0x58, 0x8e, 0xe1, 0xc2, 0x63, 0x39, 0x86, 0x1b, 0x8f, 0xe5, 0x18, 0xa2, 0x8c, 0xd3, + 0x33, 0x4b, 0x32, 0x4a, 0x93, 0xf4, 0x92, 0xf3, 0x73, 0xf5, 0xc1, 0xa6, 0xe9, 0xe6, 0xe6, 0xe7, + 0xa5, 0x56, 0xea, 0x27, 0xe7, 0x17, 0xa5, 0xea, 0x97, 0x19, 0xe9, 0x57, 0xa0, 0xfa, 0xb1, 0xa4, + 0xb2, 0x20, 0xb5, 0x38, 0x89, 0x0d, 0xec, 0x3f, 0x63, 0x40, 0x00, 0x00, 0x00, 0xff, 0xff, 0x69, + 0x35, 0x25, 0x81, 0x7c, 0x01, 0x00, 0x00, +} + +func (m *GenesisState) 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 *GenesisState) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Settings) > 0 { + for iNdEx := len(m.Settings) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Settings[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + { + size, err := m.Params.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func encodeVarintGenesis(dAtA []byte, offset int, v uint64) int { + offset -= sovGenesis(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *GenesisState) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.Params.Size() + n += 1 + l + sovGenesis(uint64(l)) + if len(m.Settings) > 0 { + for _, e := range m.Settings { + l = e.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + } + return n +} + +func sovGenesis(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozGenesis(x uint64) (n int) { + return sovGenesis(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *GenesisState) 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 ErrIntOverflowGenesis + } + 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: GenesisState: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GenesisState: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Params", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Params.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Settings", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Settings = append(m.Settings, &Setting{}) + if err := m.Settings[len(m.Settings)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenesis(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenesis + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipGenesis(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, ErrIntOverflowGenesis + } + 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, ErrIntOverflowGenesis + } + 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, ErrIntOverflowGenesis + } + 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, ErrInvalidLengthGenesis + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupGenesis + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthGenesis + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthGenesis = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowGenesis = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupGenesis = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/smartaccount/types/keys.go b/x/smartaccount/types/keys.go new file mode 100644 index 00000000..8ec9b910 --- /dev/null +++ b/x/smartaccount/types/keys.go @@ -0,0 +1,30 @@ +package types + +const ( + // module name + ModuleName = "smartaccount" + + // StoreKey to be used when creating the KVStore + StoreKey = ModuleName + + // RouterKey to be used for message routing + RouterKey = ModuleName +) + +// prefix bytes for the fees persistent store +const ( + prefixParams = iota + 1 + prefixSetting +) + +// KVStore key prefixes +var ( + ParamsKey = []byte{prefixParams} + KeyPrefixSetting = []byte{prefixSetting} +) + +// GetKeyPrefixSetting returns the KVStore key prefix for storing +// registered smartaccount contract for a deployer +func GetKeyPrefixSetting(ownderAddr string) []byte { + return append(KeyPrefixSetting, []byte(ownderAddr)...) +} diff --git a/x/smartaccount/types/msgs.go b/x/smartaccount/types/msgs.go new file mode 100644 index 00000000..c7be0221 --- /dev/null +++ b/x/smartaccount/types/msgs.go @@ -0,0 +1,77 @@ +package types + +import sdk "github.com/cosmos/cosmos-sdk/types" + +var ( + _ sdk.Msg = &MsgCreateSmartAccount{} + _ sdk.Msg = &MsgDisableSmartAccount{} + _ sdk.Msg = &MsgUpdateTransactionHooks{} +) + +func NewMsgCreateSmartAccount(account string) *MsgCreateSmartAccount { + return &MsgCreateSmartAccount{ + Account: account, + } +} + +func NewMsgDisableSmartAccount(account string) *MsgDisableSmartAccount { + return &MsgDisableSmartAccount{ + Account: account, + } +} + +func NewMsgUpdateTransactionHooks(account string, preTransactionHooks, postTransactionHooks []string) *MsgUpdateTransactionHooks { + return &MsgUpdateTransactionHooks{ + Account: account, + PreTransactionHooks: preTransactionHooks, + PostTransactionHooks: postTransactionHooks, + } +} + +// 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 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/msgs_update_authorization.go b/x/smartaccount/types/msgs_update_authorization.go new file mode 100644 index 00000000..fe650ea3 --- /dev/null +++ b/x/smartaccount/types/msgs_update_authorization.go @@ -0,0 +1,55 @@ +package types + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" +) + +var ( + _ sdk.Msg = &MsgUpdateTransactionHooks{} +) + +func NewMsgUpdateAuthorization(account string, authorizationMsgs []*AuthorizationMsg, fallback bool) *MsgUpdateAuthorization { + return &MsgUpdateAuthorization{ + Account: account, + AuthorizationMsgs: authorizationMsgs, + Fallback: fallback, + } +} + +// 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 { + if m.Account == "" { + return sdkerrors.ErrInvalidAddress.Wrap("account cannot be empty") + } + for _, auth := range m.AuthorizationMsgs { + if err := auth.ValidateBasic(); err != nil { + return err + } + } + return nil +} + +func (a AuthorizationMsg) ValidateBasic() error { + if a.ContractAddress == "" { + return sdkerrors.ErrInvalidAddress.Wrap("auth contract address cannot be empty") + } + if a.InitMsg == nil { + return sdkerrors.ErrInvalidRequest.Wrap("init msg cannot be nil") + } + if a.InitMsg.Account == "" { + return sdkerrors.ErrInvalidRequest.Wrap("init msg account cannot be empty") + } + return nil +} diff --git a/x/smartaccount/types/params.go b/x/smartaccount/types/params.go new file mode 100644 index 00000000..7998af2e --- /dev/null +++ b/x/smartaccount/types/params.go @@ -0,0 +1,14 @@ +package types + +// NewParams creates a new Params object +func NewParams() Params { + return Params{} +} + +func DefaultParams() Params { + return Params{} +} + +func (p Params) Validate() error { + return nil +} diff --git a/x/smartaccount/types/params.pb.go b/x/smartaccount/types/params.pb.go new file mode 100644 index 00000000..f0ed88b2 --- /dev/null +++ b/x/smartaccount/types/params.pb.go @@ -0,0 +1,268 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: terra/smartaccount/v1/params.proto + +package types + +import ( + fmt "fmt" + _ "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 + +// Params defines the parameters for the smartaccount module. +type Params struct { +} + +func (m *Params) Reset() { *m = Params{} } +func (m *Params) String() string { return proto.CompactTextString(m) } +func (*Params) ProtoMessage() {} +func (*Params) Descriptor() ([]byte, []int) { + return fileDescriptor_bcf523277b9090f5, []int{0} +} +func (m *Params) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Params) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Params.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 *Params) XXX_Merge(src proto.Message) { + xxx_messageInfo_Params.Merge(m, src) +} +func (m *Params) XXX_Size() int { + return m.Size() +} +func (m *Params) XXX_DiscardUnknown() { + xxx_messageInfo_Params.DiscardUnknown(m) +} + +var xxx_messageInfo_Params proto.InternalMessageInfo + +func init() { + proto.RegisterType((*Params)(nil), "terra.smartaccount.v1.Params") +} + +func init() { + proto.RegisterFile("terra/smartaccount/v1/params.proto", fileDescriptor_bcf523277b9090f5) +} + +var fileDescriptor_bcf523277b9090f5 = []byte{ + // 161 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x52, 0x2a, 0x49, 0x2d, 0x2a, + 0x4a, 0xd4, 0x2f, 0xce, 0x4d, 0x2c, 0x2a, 0x49, 0x4c, 0x4e, 0xce, 0x2f, 0xcd, 0x2b, 0xd1, 0x2f, + 0x33, 0xd4, 0x2f, 0x48, 0x2c, 0x4a, 0xcc, 0x2d, 0xd6, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x12, + 0x05, 0xab, 0xd1, 0x43, 0x56, 0xa3, 0x57, 0x66, 0x28, 0x25, 0x92, 0x9e, 0x9f, 0x9e, 0x0f, 0x56, + 0xa1, 0x0f, 0x62, 0x41, 0x14, 0x2b, 0x71, 0x70, 0xb1, 0x05, 0x80, 0x35, 0x3b, 0xf9, 0x9e, 0x78, + 0x24, 0xc7, 0x78, 0xe1, 0x91, 0x1c, 0xe3, 0x83, 0x47, 0x72, 0x8c, 0x13, 0x1e, 0xcb, 0x31, 0x5c, + 0x78, 0x2c, 0xc7, 0x70, 0xe3, 0xb1, 0x1c, 0x43, 0x94, 0x71, 0x7a, 0x66, 0x49, 0x46, 0x69, 0x92, + 0x5e, 0x72, 0x7e, 0xae, 0x3e, 0xd8, 0x6c, 0xdd, 0xdc, 0xfc, 0xbc, 0xd4, 0x4a, 0xfd, 0xe4, 0xfc, + 0xa2, 0x54, 0xfd, 0x32, 0x23, 0xfd, 0x0a, 0x54, 0xf7, 0x94, 0x54, 0x16, 0xa4, 0x16, 0x27, 0xb1, + 0x81, 0xcd, 0x37, 0x06, 0x04, 0x00, 0x00, 0xff, 0xff, 0xc9, 0x70, 0x6d, 0x70, 0xb2, 0x00, 0x00, + 0x00, +} + +func (m *Params) 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 *Params) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func encodeVarintParams(dAtA []byte, offset int, v uint64) int { + offset -= sovParams(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *Params) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func sovParams(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozParams(x uint64) (n int) { + return sovParams(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *Params) 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 ErrIntOverflowParams + } + 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: Params: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Params: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipParams(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthParams + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipParams(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, ErrIntOverflowParams + } + 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, ErrIntOverflowParams + } + 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, ErrIntOverflowParams + } + 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, ErrInvalidLengthParams + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupParams + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthParams + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthParams = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowParams = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupParams = fmt.Errorf("proto: unexpected end of group") +) 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.go b/x/smartaccount/types/query.go new file mode 100644 index 00000000..ab1254f4 --- /dev/null +++ b/x/smartaccount/types/query.go @@ -0,0 +1 @@ +package types diff --git a/x/smartaccount/types/query.pb.go b/x/smartaccount/types/query.pb.go new file mode 100644 index 00000000..1137f51c --- /dev/null +++ b/x/smartaccount/types/query.pb.go @@ -0,0 +1,917 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: terra/smartaccount/v1/query.proto + +package types + +import ( + context "context" + fmt "fmt" + _ "github.com/cosmos/gogoproto/gogoproto" + grpc1 "github.com/cosmos/gogoproto/grpc" + proto "github.com/cosmos/gogoproto/proto" + _ "google.golang.org/genproto/googleapis/api/annotations" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + 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 + +// QueryParamsRequest is the request type for the Query/Params RPC method. +type QueryParamsRequest struct { +} + +func (m *QueryParamsRequest) Reset() { *m = QueryParamsRequest{} } +func (m *QueryParamsRequest) String() string { return proto.CompactTextString(m) } +func (*QueryParamsRequest) ProtoMessage() {} +func (*QueryParamsRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_93504f0f37d1a258, []int{0} +} +func (m *QueryParamsRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryParamsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryParamsRequest.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 *QueryParamsRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryParamsRequest.Merge(m, src) +} +func (m *QueryParamsRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryParamsRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryParamsRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryParamsRequest proto.InternalMessageInfo + +// QueryParamsResponse is the response type for the Query/Params RPC method. +type QueryParamsResponse struct { + // params is the returned FeeShare parameter + Params Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params"` +} + +func (m *QueryParamsResponse) Reset() { *m = QueryParamsResponse{} } +func (m *QueryParamsResponse) String() string { return proto.CompactTextString(m) } +func (*QueryParamsResponse) ProtoMessage() {} +func (*QueryParamsResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_93504f0f37d1a258, []int{1} +} +func (m *QueryParamsResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryParamsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryParamsResponse.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 *QueryParamsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryParamsResponse.Merge(m, src) +} +func (m *QueryParamsResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryParamsResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryParamsResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryParamsResponse proto.InternalMessageInfo + +func (m *QueryParamsResponse) GetParams() Params { + if m != nil { + return m.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{ + // 381 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, 0x4f, 0x9e, 0x5b, 0x9c, 0x30, 0x8a, 0xcb, 0xb4, 0x22, 0xcc, + 0x89, 0x8d, 0xdb, 0x8e, 0x82, 0x87, 0xdd, 0x05, 0xad, 0xe0, 0xc1, 0x5b, 0xd6, 0x85, 0x5a, 0xb0, + 0x49, 0x97, 0xa4, 0xc3, 0x21, 0x5e, 0x3c, 0x78, 0x16, 0xf4, 0x3d, 0xf8, 0x56, 0x76, 0x1c, 0x78, + 0xf1, 0x24, 0xb2, 0xf9, 0x42, 0x64, 0x4d, 0x06, 0x16, 0xb7, 0xb1, 0x5b, 0xff, 0x7c, 0xbe, 0xdf, + 0xdf, 0x27, 0x7f, 0xc0, 0x8e, 0xa2, 0x42, 0x10, 0x2c, 0x63, 0x22, 0x14, 0x09, 0x02, 0x9e, 0x32, + 0x85, 0x07, 0x4d, 0xdc, 0x4f, 0xa9, 0x18, 0x7a, 0x89, 0xe0, 0x8a, 0xc3, 0xcd, 0x0c, 0xf1, 0x7e, + 0x22, 0xde, 0xa0, 0xe9, 0x94, 0x43, 0x1e, 0xf2, 0x8c, 0xc0, 0xb3, 0x27, 0x0d, 0x3b, 0x5b, 0x21, + 0xe7, 0xe1, 0x0d, 0xc5, 0x24, 0x89, 0x30, 0x61, 0x8c, 0x2b, 0xa2, 0x22, 0xce, 0xa4, 0xf9, 0xeb, + 0x2e, 0x9e, 0x96, 0x10, 0x41, 0xe2, 0x39, 0xb3, 0xbb, 0x98, 0x91, 0x54, 0xa9, 0x88, 0x85, 0x1a, + 0x72, 0xcb, 0x00, 0x9e, 0xcf, 0x14, 0xcf, 0xb2, 0xa4, 0x4f, 0xfb, 0x29, 0x95, 0xca, 0xf5, 0xc1, + 0x46, 0xee, 0xab, 0x4c, 0x38, 0x93, 0x14, 0x1e, 0x83, 0xa2, 0x9e, 0x50, 0xb1, 0xb7, 0xed, 0xfa, + 0xff, 0x56, 0xd5, 0x5b, 0xb8, 0x22, 0x4f, 0xc7, 0x3a, 0x7f, 0x46, 0x1f, 0x35, 0xcb, 0x37, 0x11, + 0x17, 0x9b, 0xce, 0x0b, 0x3d, 0xdf, 0x8c, 0x82, 0x15, 0x50, 0x22, 0xbd, 0x9e, 0xa0, 0x52, 0x97, + 0xfe, 0xf3, 0xe7, 0xaf, 0xee, 0x25, 0x28, 0xe7, 0x03, 0xc6, 0xe2, 0x04, 0x94, 0xcc, 0x1a, 0x8c, + 0x06, 0x5a, 0xa2, 0x61, 0x82, 0xc6, 0x63, 0x1e, 0x6a, 0xbd, 0x16, 0xc0, 0xdf, 0xac, 0x18, 0x3e, + 0xda, 0xa0, 0xa8, 0x5d, 0xe1, 0xfe, 0x92, 0x8e, 0xdf, 0x9b, 0xe3, 0x34, 0xd6, 0x41, 0xb5, 0xab, + 0xbb, 0xf7, 0xf0, 0xf6, 0xf5, 0x5c, 0xa8, 0xc1, 0x2a, 0x5e, 0x75, 0x60, 0xf0, 0xc5, 0x06, 0x25, + 0x63, 0x0b, 0x57, 0xd6, 0xe7, 0x37, 0xcf, 0x39, 0x58, 0x8b, 0x35, 0x2e, 0x47, 0x99, 0x4b, 0x03, + 0xd6, 0xf1, 0xca, 0x8b, 0x81, 0xef, 0xcc, 0x01, 0xdc, 0x77, 0x4e, 0x47, 0x13, 0x64, 0x8f, 0x27, + 0xc8, 0xfe, 0x9c, 0x20, 0xfb, 0x69, 0x8a, 0xac, 0xf1, 0x14, 0x59, 0xef, 0x53, 0x64, 0x5d, 0xb5, + 0xc3, 0x48, 0x5d, 0xa7, 0x5d, 0x2f, 0xe0, 0xb1, 0x6e, 0x3b, 0x8c, 0x39, 0xa3, 0x43, 0x1c, 0x70, + 0x41, 0xf1, 0xa0, 0x85, 0x6f, 0xf3, 0xed, 0x6a, 0x98, 0x50, 0xd9, 0x2d, 0x66, 0x57, 0xae, 0xfd, + 0x1d, 0x00, 0x00, 0xff, 0xff, 0x37, 0xb0, 0x22, 0xac, 0x2b, 0x03, 0x00, 0x00, +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion4 + +// QueryClient is the client API for Query service. +// +// 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 { + cc grpc1.ClientConn +} + +func NewQueryClient(cc grpc1.ClientConn) QueryClient { + return &queryClient{cc} +} + +func (c *queryClient) Params(ctx context.Context, in *QueryParamsRequest, opts ...grpc.CallOption) (*QueryParamsResponse, error) { + out := new(QueryParamsResponse) + err := c.cc.Invoke(ctx, "/terra.smartaccount.v1.Query/Params", in, out, opts...) + if err != nil { + return nil, err + } + 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. +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) +} + +func _Query_Params_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryParamsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).Params(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/terra.smartaccount.v1.Query/Params", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).Params(ctx, req.(*QueryParamsRequest)) + } + 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), + Methods: []grpc.MethodDesc{ + { + MethodName: "Params", + Handler: _Query_Params_Handler, + }, + { + MethodName: "Setting", + Handler: _Query_Setting_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "terra/smartaccount/v1/query.proto", +} + +func (m *QueryParamsRequest) 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 *QueryParamsRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryParamsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *QueryParamsResponse) 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 *QueryParamsResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryParamsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.Params.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 (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 + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *QueryParamsRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *QueryParamsResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.Params.Size() + n += 1 + l + sovQuery(uint64(l)) + 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 +} +func sozQuery(x uint64) (n int) { + return sovQuery(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *QueryParamsRequest) 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: QueryParamsRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryParamsRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + 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 *QueryParamsResponse) 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: QueryParamsResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryParamsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Params", 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.Params.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 (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 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowQuery + } + 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, ErrIntOverflowQuery + } + 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, ErrIntOverflowQuery + } + 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, ErrInvalidLengthQuery + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupQuery + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthQuery + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthQuery = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowQuery = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupQuery = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/smartaccount/types/query.pb.gw.go b/x/smartaccount/types/query.pb.gw.go new file mode 100644 index 00000000..33e638d3 --- /dev/null +++ b/x/smartaccount/types/query.pb.gw.go @@ -0,0 +1,254 @@ +// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT. +// source: terra/smartaccount/v1/query.proto + +/* +Package types is a reverse proxy. + +It translates gRPC into RESTful JSON APIs. +*/ +package types + +import ( + "context" + "io" + "net/http" + + "github.com/golang/protobuf/descriptor" + "github.com/golang/protobuf/proto" + "github.com/grpc-ecosystem/grpc-gateway/runtime" + "github.com/grpc-ecosystem/grpc-gateway/utilities" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/metadata" + "google.golang.org/grpc/status" +) + +// Suppress "imported and not used" errors +var _ codes.Code +var _ io.Reader +var _ status.Status +var _ = runtime.String +var _ = utilities.NewDoubleArray +var _ = descriptor.ForMessage +var _ = metadata.Join + +func request_Query_Params_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryParamsRequest + var metadata runtime.ServerMetadata + + msg, err := client.Params(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_Params_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryParamsRequest + var metadata runtime.ServerMetadata + + msg, err := server.Params(ctx, &protoReq) + return msg, metadata, err + +} + +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. +// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterQueryHandlerFromEndpoint instead. +func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, server QueryServer) error { + + mux.Handle("GET", pattern_Query_Params_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_Params_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_Params_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + 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 +} + +// RegisterQueryHandlerFromEndpoint is same as RegisterQueryHandler but +// automatically dials to "endpoint" and closes the connection when "ctx" gets done. +func RegisterQueryHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { + conn, err := grpc.Dial(endpoint, opts...) + if err != nil { + return err + } + defer func() { + if err != nil { + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + return + } + go func() { + <-ctx.Done() + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + }() + }() + + return RegisterQueryHandler(ctx, mux, conn) +} + +// RegisterQueryHandler registers the http handlers for service Query to "mux". +// The handlers forward requests to the grpc endpoint over "conn". +func RegisterQueryHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error { + return RegisterQueryHandlerClient(ctx, mux, NewQueryClient(conn)) +} + +// RegisterQueryHandlerClient registers the http handlers for service Query +// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "QueryClient". +// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "QueryClient" +// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in +// "QueryClient" to call the correct interceptors. +func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, client QueryClient) error { + + mux.Handle("GET", pattern_Query_Params_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_Params_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_Params_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + 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", "setting", "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 new file mode 100644 index 00000000..22063a93 --- /dev/null +++ b/x/smartaccount/types/setting.go @@ -0,0 +1,31 @@ +package types + +import fmt "fmt" + +// NewParams creates a new Params object +func NewSetting(ownerAddr string) Setting { + return Setting{ + Owner: ownerAddr, + Fallback: true, + } +} + +func NewSettings(setting ...*Setting) []*Setting { + return append([]*Setting(nil), setting...) +} + +func DefaultSettings() []*Setting { + return NewSettings() +} + +func (s Setting) Validate() error { + if s.Owner == "" { + return fmt.Errorf("owner cannot be empty") + } + + if (s.Authorization == nil || len(s.Authorization) == 0) && !s.Fallback { + return fmt.Errorf("fallback must be true without any authorization") + } + + return nil +} diff --git a/x/smartaccount/types/setting.pb.go b/x/smartaccount/types/setting.pb.go new file mode 100644 index 00000000..4dbfc532 --- /dev/null +++ b/x/smartaccount/types/setting.pb.go @@ -0,0 +1,782 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: terra/smartaccount/v1/setting.proto + +package types + +import ( + fmt "fmt" + _ "github.com/cosmos/cosmos-proto" + _ "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 + +type Setting struct { + // Owner that can do priviledged operations on the Smart Account + // Defaults to the Smart Account Addr + Owner string `protobuf:"bytes,1,opt,name=owner,proto3" json:"owner,omitempty"` + // List of contract addresses to perform auth instead of SigVerify + Authorization []*AuthorizationMsg `protobuf:"bytes,2,rep,name=authorization,proto3" json:"authorization,omitempty"` + // List of contract addresses to perform pre-txn logic + PreTransaction []string `protobuf:"bytes,3,rep,name=pre_transaction,json=preTransaction,proto3" json:"pre_transaction,omitempty"` + // List of contract addresses to perform post-txn logic + PostTransaction []string `protobuf:"bytes,4,rep,name=post_transaction,json=postTransaction,proto3" json:"post_transaction,omitempty"` + // Fallback to default SigVerify if custom authorization fails + Fallback bool `protobuf:"varint,5,opt,name=fallback,proto3" json:"fallback,omitempty"` +} + +func (m *Setting) Reset() { *m = Setting{} } +func (m *Setting) String() string { return proto.CompactTextString(m) } +func (*Setting) ProtoMessage() {} +func (*Setting) Descriptor() ([]byte, []int) { + return fileDescriptor_8b1bfc9d01b712f3, []int{0} +} +func (m *Setting) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Setting) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Setting.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 *Setting) XXX_Merge(src proto.Message) { + xxx_messageInfo_Setting.Merge(m, src) +} +func (m *Setting) XXX_Size() int { + return m.Size() +} +func (m *Setting) XXX_DiscardUnknown() { + xxx_messageInfo_Setting.DiscardUnknown(m) +} + +var xxx_messageInfo_Setting proto.InternalMessageInfo + +func (m *Setting) GetOwner() string { + if m != nil { + return m.Owner + } + return "" +} + +func (m *Setting) GetAuthorization() []*AuthorizationMsg { + if m != nil { + return m.Authorization + } + return nil +} + +func (m *Setting) GetPreTransaction() []string { + if m != nil { + return m.PreTransaction + } + return nil +} + +func (m *Setting) GetPostTransaction() []string { + if m != nil { + return m.PostTransaction + } + return nil +} + +func (m *Setting) GetFallback() bool { + if m != nil { + return m.Fallback + } + return false +} + +type AuthorizationMsg struct { + ContractAddress string `protobuf:"bytes,1,opt,name=contract_address,json=contractAddress,proto3" json:"contract_address,omitempty"` + InitMsg *Initialization `protobuf:"bytes,2,opt,name=init_msg,json=initMsg,proto3" json:"init_msg,omitempty"` +} + +func (m *AuthorizationMsg) Reset() { *m = AuthorizationMsg{} } +func (m *AuthorizationMsg) String() string { return proto.CompactTextString(m) } +func (*AuthorizationMsg) ProtoMessage() {} +func (*AuthorizationMsg) Descriptor() ([]byte, []int) { + return fileDescriptor_8b1bfc9d01b712f3, []int{1} +} +func (m *AuthorizationMsg) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *AuthorizationMsg) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_AuthorizationMsg.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 *AuthorizationMsg) XXX_Merge(src proto.Message) { + xxx_messageInfo_AuthorizationMsg.Merge(m, src) +} +func (m *AuthorizationMsg) XXX_Size() int { + return m.Size() +} +func (m *AuthorizationMsg) XXX_DiscardUnknown() { + xxx_messageInfo_AuthorizationMsg.DiscardUnknown(m) +} + +var xxx_messageInfo_AuthorizationMsg proto.InternalMessageInfo + +func (m *AuthorizationMsg) GetContractAddress() string { + if m != nil { + return m.ContractAddress + } + return "" +} + +func (m *AuthorizationMsg) GetInitMsg() *Initialization { + if m != nil { + return m.InitMsg + } + return nil +} + +func init() { + proto.RegisterType((*Setting)(nil), "terra.smartaccount.v1.Setting") + proto.RegisterType((*AuthorizationMsg)(nil), "terra.smartaccount.v1.AuthorizationMsg") +} + +func init() { + proto.RegisterFile("terra/smartaccount/v1/setting.proto", fileDescriptor_8b1bfc9d01b712f3) +} + +var fileDescriptor_8b1bfc9d01b712f3 = []byte{ + // 389 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x92, 0xc1, 0xae, 0xd2, 0x40, + 0x14, 0x86, 0x29, 0x88, 0xe0, 0x10, 0x85, 0x34, 0x98, 0x54, 0x16, 0x4d, 0x83, 0x31, 0xd6, 0x05, + 0x9d, 0x00, 0x2f, 0x20, 0xba, 0x72, 0xc1, 0xa6, 0xb8, 0x72, 0xd3, 0x0c, 0xc3, 0x38, 0x4c, 0xa4, + 0x33, 0xcd, 0xcc, 0x01, 0xc4, 0x8d, 0xaf, 0xe0, 0xc3, 0xf8, 0x0c, 0xc6, 0x25, 0x71, 0xe5, 0xd2, + 0xc0, 0x8b, 0x98, 0x76, 0xaa, 0x17, 0x6e, 0xb8, 0xdc, 0x5d, 0xa7, 0xf3, 0x9d, 0xef, 0x3f, 0x73, + 0x72, 0xd0, 0x73, 0x60, 0x5a, 0x13, 0x6c, 0x52, 0xa2, 0x81, 0x50, 0xaa, 0xd6, 0x12, 0xf0, 0x66, + 0x88, 0x0d, 0x03, 0x10, 0x92, 0x47, 0x99, 0x56, 0xa0, 0xdc, 0xa7, 0x05, 0x14, 0x9d, 0x42, 0xd1, + 0x66, 0xd8, 0xeb, 0x72, 0xc5, 0x55, 0x41, 0xe0, 0xfc, 0xcb, 0xc2, 0xbd, 0x67, 0x54, 0x99, 0x54, + 0x99, 0xc4, 0x5e, 0xd8, 0x43, 0x79, 0x15, 0x5c, 0x0e, 0xdb, 0x12, 0x93, 0x5a, 0xa2, 0xff, 0xa3, + 0x8a, 0x1a, 0x33, 0x9b, 0xed, 0x46, 0xa8, 0xae, 0xb6, 0x92, 0x69, 0xcf, 0x09, 0x9c, 0xf0, 0xd1, + 0x1b, 0xef, 0xd7, 0xf7, 0x41, 0xb7, 0xd4, 0x4d, 0x16, 0x0b, 0xcd, 0x8c, 0x99, 0x81, 0x16, 0x92, + 0xc7, 0x16, 0x73, 0x39, 0x7a, 0x4c, 0xd6, 0xb0, 0x54, 0x5a, 0x7c, 0x21, 0x20, 0x94, 0xf4, 0xaa, + 0x41, 0x2d, 0x6c, 0x8d, 0x5e, 0x46, 0x17, 0xbb, 0x8f, 0x26, 0xa7, 0xec, 0xd4, 0xf0, 0x2b, 0x01, + 0xe7, 0x5e, 0x77, 0x82, 0xda, 0x99, 0x66, 0x09, 0x68, 0x22, 0x0d, 0xa1, 0x45, 0x54, 0x2d, 0xa8, + 0x5d, 0x6d, 0xf1, 0x49, 0xa6, 0xd9, 0xfb, 0x1b, 0xde, 0x7d, 0x8b, 0x3a, 0x99, 0x32, 0x70, 0xe6, + 0x78, 0x70, 0x8f, 0xa3, 0x9d, 0x57, 0x9c, 0x4a, 0x7a, 0xa8, 0xf9, 0x91, 0xac, 0x56, 0x73, 0x42, + 0x3f, 0x79, 0xf5, 0xc0, 0x09, 0x9b, 0xf1, 0xff, 0x73, 0xff, 0x2b, 0xea, 0xdc, 0x7e, 0xa0, 0xfb, + 0x0a, 0x75, 0xa8, 0x92, 0xa0, 0x09, 0x85, 0x84, 0x58, 0xb5, 0x9d, 0x6d, 0xdc, 0xfe, 0xf7, 0xbf, + 0x4c, 0x74, 0x5f, 0xa3, 0xa6, 0x90, 0x02, 0x92, 0xd4, 0x70, 0xaf, 0x1a, 0x38, 0x61, 0x6b, 0xf4, + 0xe2, 0x8e, 0x31, 0xbe, 0x93, 0x02, 0x04, 0x59, 0x95, 0x31, 0x71, 0x23, 0x2f, 0xcb, 0xa7, 0x39, + 0xfd, 0x79, 0xf0, 0x9d, 0xfd, 0xc1, 0x77, 0xfe, 0x1c, 0x7c, 0xe7, 0xdb, 0xd1, 0xaf, 0xec, 0x8f, + 0x7e, 0xe5, 0xf7, 0xd1, 0xaf, 0x7c, 0x18, 0x73, 0x01, 0xcb, 0xf5, 0x3c, 0xa2, 0x2a, 0xc5, 0x85, + 0x73, 0x90, 0x2a, 0xc9, 0x76, 0x98, 0x2a, 0xcd, 0xf0, 0x66, 0x84, 0x3f, 0x9f, 0x2f, 0x08, 0xec, + 0x32, 0x66, 0xe6, 0x0f, 0x8b, 0xfd, 0x18, 0xff, 0x0d, 0x00, 0x00, 0xff, 0xff, 0x31, 0x83, 0xf3, + 0x31, 0xb0, 0x02, 0x00, 0x00, +} + +func (m *Setting) 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 *Setting) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Setting) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Fallback { + i-- + if m.Fallback { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x28 + } + if len(m.PostTransaction) > 0 { + for iNdEx := len(m.PostTransaction) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.PostTransaction[iNdEx]) + copy(dAtA[i:], m.PostTransaction[iNdEx]) + i = encodeVarintSetting(dAtA, i, uint64(len(m.PostTransaction[iNdEx]))) + i-- + dAtA[i] = 0x22 + } + } + if len(m.PreTransaction) > 0 { + for iNdEx := len(m.PreTransaction) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.PreTransaction[iNdEx]) + copy(dAtA[i:], m.PreTransaction[iNdEx]) + i = encodeVarintSetting(dAtA, i, uint64(len(m.PreTransaction[iNdEx]))) + i-- + dAtA[i] = 0x1a + } + } + if len(m.Authorization) > 0 { + for iNdEx := len(m.Authorization) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Authorization[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintSetting(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + if len(m.Owner) > 0 { + i -= len(m.Owner) + copy(dAtA[i:], m.Owner) + i = encodeVarintSetting(dAtA, i, uint64(len(m.Owner))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *AuthorizationMsg) 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 *AuthorizationMsg) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *AuthorizationMsg) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.InitMsg != nil { + { + size, err := m.InitMsg.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintSetting(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if len(m.ContractAddress) > 0 { + i -= len(m.ContractAddress) + copy(dAtA[i:], m.ContractAddress) + i = encodeVarintSetting(dAtA, i, uint64(len(m.ContractAddress))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func encodeVarintSetting(dAtA []byte, offset int, v uint64) int { + offset -= sovSetting(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *Setting) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Owner) + if l > 0 { + n += 1 + l + sovSetting(uint64(l)) + } + if len(m.Authorization) > 0 { + for _, e := range m.Authorization { + l = e.Size() + n += 1 + l + sovSetting(uint64(l)) + } + } + if len(m.PreTransaction) > 0 { + for _, s := range m.PreTransaction { + l = len(s) + n += 1 + l + sovSetting(uint64(l)) + } + } + if len(m.PostTransaction) > 0 { + for _, s := range m.PostTransaction { + l = len(s) + n += 1 + l + sovSetting(uint64(l)) + } + } + if m.Fallback { + n += 2 + } + return n +} + +func (m *AuthorizationMsg) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.ContractAddress) + if l > 0 { + n += 1 + l + sovSetting(uint64(l)) + } + if m.InitMsg != nil { + l = m.InitMsg.Size() + n += 1 + l + sovSetting(uint64(l)) + } + return n +} + +func sovSetting(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozSetting(x uint64) (n int) { + return sovSetting(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *Setting) 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 ErrIntOverflowSetting + } + 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: Setting: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Setting: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Owner", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSetting + } + 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 ErrInvalidLengthSetting + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthSetting + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Owner = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Authorization", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSetting + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthSetting + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthSetting + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Authorization = append(m.Authorization, &AuthorizationMsg{}) + if err := m.Authorization[len(m.Authorization)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PreTransaction", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSetting + } + 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 ErrInvalidLengthSetting + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthSetting + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.PreTransaction = append(m.PreTransaction, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PostTransaction", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSetting + } + 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 ErrInvalidLengthSetting + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthSetting + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.PostTransaction = append(m.PostTransaction, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Fallback", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSetting + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Fallback = bool(v != 0) + default: + iNdEx = preIndex + skippy, err := skipSetting(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthSetting + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *AuthorizationMsg) 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 ErrIntOverflowSetting + } + 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: AuthorizationMsg: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: AuthorizationMsg: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ContractAddress", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSetting + } + 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 ErrInvalidLengthSetting + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthSetting + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ContractAddress = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field InitMsg", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSetting + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthSetting + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthSetting + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.InitMsg == nil { + m.InitMsg = &Initialization{} + } + if err := m.InitMsg.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipSetting(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthSetting + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipSetting(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, ErrIntOverflowSetting + } + 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, ErrIntOverflowSetting + } + 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, ErrIntOverflowSetting + } + 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, ErrInvalidLengthSetting + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupSetting + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthSetting + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthSetting = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowSetting = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupSetting = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/smartaccount/types/tx.pb.go b/x/smartaccount/types/tx.pb.go new file mode 100644 index 00000000..5ffdaaab --- /dev/null +++ b/x/smartaccount/types/tx.pb.go @@ -0,0 +1,1737 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: terra/smartaccount/v1/tx.proto + +package types + +import ( + context "context" + fmt "fmt" + _ "github.com/cosmos/cosmos-sdk/types/msgservice" + _ "github.com/cosmos/gogoproto/gogoproto" + grpc1 "github.com/cosmos/gogoproto/grpc" + proto "github.com/cosmos/gogoproto/proto" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + 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 + +type MsgCreateSmartAccount struct { + Account string `protobuf:"bytes,1,opt,name=account,proto3" json:"account,omitempty"` +} + +func (m *MsgCreateSmartAccount) Reset() { *m = MsgCreateSmartAccount{} } +func (m *MsgCreateSmartAccount) String() string { return proto.CompactTextString(m) } +func (*MsgCreateSmartAccount) ProtoMessage() {} +func (*MsgCreateSmartAccount) Descriptor() ([]byte, []int) { + return fileDescriptor_a2931e7b90fb4027, []int{0} +} +func (m *MsgCreateSmartAccount) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgCreateSmartAccount) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgCreateSmartAccount.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 *MsgCreateSmartAccount) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgCreateSmartAccount.Merge(m, src) +} +func (m *MsgCreateSmartAccount) XXX_Size() int { + return m.Size() +} +func (m *MsgCreateSmartAccount) XXX_DiscardUnknown() { + xxx_messageInfo_MsgCreateSmartAccount.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgCreateSmartAccount proto.InternalMessageInfo + +func (m *MsgCreateSmartAccount) GetAccount() string { + if m != nil { + return m.Account + } + return "" +} + +type MsgCreateSmartAccountResponse struct { +} + +func (m *MsgCreateSmartAccountResponse) Reset() { *m = MsgCreateSmartAccountResponse{} } +func (m *MsgCreateSmartAccountResponse) String() string { return proto.CompactTextString(m) } +func (*MsgCreateSmartAccountResponse) ProtoMessage() {} +func (*MsgCreateSmartAccountResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_a2931e7b90fb4027, []int{1} +} +func (m *MsgCreateSmartAccountResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgCreateSmartAccountResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgCreateSmartAccountResponse.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 *MsgCreateSmartAccountResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgCreateSmartAccountResponse.Merge(m, src) +} +func (m *MsgCreateSmartAccountResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgCreateSmartAccountResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgCreateSmartAccountResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgCreateSmartAccountResponse proto.InternalMessageInfo + +type MsgUpdateAuthorization struct { + Account string `protobuf:"bytes,1,opt,name=account,proto3" json:"account,omitempty"` + Fallback bool `protobuf:"varint,2,opt,name=fallback,proto3" json:"fallback,omitempty"` + AuthorizationMsgs []*AuthorizationMsg `protobuf:"bytes,3,rep,name=authorization_msgs,json=authorizationMsgs,proto3" json:"authorization_msgs,omitempty"` +} + +func (m *MsgUpdateAuthorization) Reset() { *m = MsgUpdateAuthorization{} } +func (m *MsgUpdateAuthorization) String() string { return proto.CompactTextString(m) } +func (*MsgUpdateAuthorization) ProtoMessage() {} +func (*MsgUpdateAuthorization) Descriptor() ([]byte, []int) { + return fileDescriptor_a2931e7b90fb4027, []int{2} +} +func (m *MsgUpdateAuthorization) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgUpdateAuthorization) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgUpdateAuthorization.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 *MsgUpdateAuthorization) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgUpdateAuthorization.Merge(m, src) +} +func (m *MsgUpdateAuthorization) XXX_Size() int { + return m.Size() +} +func (m *MsgUpdateAuthorization) XXX_DiscardUnknown() { + xxx_messageInfo_MsgUpdateAuthorization.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgUpdateAuthorization proto.InternalMessageInfo + +func (m *MsgUpdateAuthorization) GetAccount() string { + if m != nil { + return m.Account + } + return "" +} + +func (m *MsgUpdateAuthorization) GetFallback() bool { + if m != nil { + return m.Fallback + } + return false +} + +func (m *MsgUpdateAuthorization) GetAuthorizationMsgs() []*AuthorizationMsg { + if m != nil { + return m.AuthorizationMsgs + } + return nil +} + +type MsgUpdateAuthorizationResponse struct { +} + +func (m *MsgUpdateAuthorizationResponse) Reset() { *m = MsgUpdateAuthorizationResponse{} } +func (m *MsgUpdateAuthorizationResponse) String() string { return proto.CompactTextString(m) } +func (*MsgUpdateAuthorizationResponse) ProtoMessage() {} +func (*MsgUpdateAuthorizationResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_a2931e7b90fb4027, []int{3} +} +func (m *MsgUpdateAuthorizationResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgUpdateAuthorizationResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgUpdateAuthorizationResponse.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 *MsgUpdateAuthorizationResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgUpdateAuthorizationResponse.Merge(m, src) +} +func (m *MsgUpdateAuthorizationResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgUpdateAuthorizationResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgUpdateAuthorizationResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgUpdateAuthorizationResponse proto.InternalMessageInfo + +type MsgUpdateTransactionHooks struct { + Account string `protobuf:"bytes,1,opt,name=account,proto3" json:"account,omitempty"` + PreTransactionHooks []string `protobuf:"bytes,2,rep,name=pre_transaction_hooks,json=preTransactionHooks,proto3" json:"pre_transaction_hooks,omitempty"` + PostTransactionHooks []string `protobuf:"bytes,3,rep,name=post_transaction_hooks,json=postTransactionHooks,proto3" json:"post_transaction_hooks,omitempty"` +} + +func (m *MsgUpdateTransactionHooks) Reset() { *m = MsgUpdateTransactionHooks{} } +func (m *MsgUpdateTransactionHooks) String() string { return proto.CompactTextString(m) } +func (*MsgUpdateTransactionHooks) ProtoMessage() {} +func (*MsgUpdateTransactionHooks) Descriptor() ([]byte, []int) { + return fileDescriptor_a2931e7b90fb4027, []int{4} +} +func (m *MsgUpdateTransactionHooks) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgUpdateTransactionHooks) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgUpdateTransactionHooks.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 *MsgUpdateTransactionHooks) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgUpdateTransactionHooks.Merge(m, src) +} +func (m *MsgUpdateTransactionHooks) XXX_Size() int { + return m.Size() +} +func (m *MsgUpdateTransactionHooks) XXX_DiscardUnknown() { + xxx_messageInfo_MsgUpdateTransactionHooks.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgUpdateTransactionHooks proto.InternalMessageInfo + +func (m *MsgUpdateTransactionHooks) GetAccount() string { + if m != nil { + return m.Account + } + return "" +} + +func (m *MsgUpdateTransactionHooks) GetPreTransactionHooks() []string { + if m != nil { + return m.PreTransactionHooks + } + return nil +} + +func (m *MsgUpdateTransactionHooks) GetPostTransactionHooks() []string { + if m != nil { + return m.PostTransactionHooks + } + return nil +} + +type MsgUpdateTransactionHooksResponse struct { +} + +func (m *MsgUpdateTransactionHooksResponse) Reset() { *m = MsgUpdateTransactionHooksResponse{} } +func (m *MsgUpdateTransactionHooksResponse) String() string { return proto.CompactTextString(m) } +func (*MsgUpdateTransactionHooksResponse) ProtoMessage() {} +func (*MsgUpdateTransactionHooksResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_a2931e7b90fb4027, []int{5} +} +func (m *MsgUpdateTransactionHooksResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgUpdateTransactionHooksResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgUpdateTransactionHooksResponse.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 *MsgUpdateTransactionHooksResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgUpdateTransactionHooksResponse.Merge(m, src) +} +func (m *MsgUpdateTransactionHooksResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgUpdateTransactionHooksResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgUpdateTransactionHooksResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgUpdateTransactionHooksResponse proto.InternalMessageInfo + +type MsgDisableSmartAccount struct { + Account string `protobuf:"bytes,1,opt,name=account,proto3" json:"account,omitempty"` +} + +func (m *MsgDisableSmartAccount) Reset() { *m = MsgDisableSmartAccount{} } +func (m *MsgDisableSmartAccount) String() string { return proto.CompactTextString(m) } +func (*MsgDisableSmartAccount) ProtoMessage() {} +func (*MsgDisableSmartAccount) Descriptor() ([]byte, []int) { + return fileDescriptor_a2931e7b90fb4027, []int{6} +} +func (m *MsgDisableSmartAccount) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgDisableSmartAccount) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgDisableSmartAccount.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 *MsgDisableSmartAccount) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgDisableSmartAccount.Merge(m, src) +} +func (m *MsgDisableSmartAccount) XXX_Size() int { + return m.Size() +} +func (m *MsgDisableSmartAccount) XXX_DiscardUnknown() { + xxx_messageInfo_MsgDisableSmartAccount.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgDisableSmartAccount proto.InternalMessageInfo + +func (m *MsgDisableSmartAccount) GetAccount() string { + if m != nil { + return m.Account + } + return "" +} + +type MsgDisableSmartAccountResponse struct { +} + +func (m *MsgDisableSmartAccountResponse) Reset() { *m = MsgDisableSmartAccountResponse{} } +func (m *MsgDisableSmartAccountResponse) String() string { return proto.CompactTextString(m) } +func (*MsgDisableSmartAccountResponse) ProtoMessage() {} +func (*MsgDisableSmartAccountResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_a2931e7b90fb4027, []int{7} +} +func (m *MsgDisableSmartAccountResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgDisableSmartAccountResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgDisableSmartAccountResponse.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 *MsgDisableSmartAccountResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgDisableSmartAccountResponse.Merge(m, src) +} +func (m *MsgDisableSmartAccountResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgDisableSmartAccountResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgDisableSmartAccountResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgDisableSmartAccountResponse proto.InternalMessageInfo + +func init() { + proto.RegisterType((*MsgCreateSmartAccount)(nil), "terra.smartaccount.v1.MsgCreateSmartAccount") + proto.RegisterType((*MsgCreateSmartAccountResponse)(nil), "terra.smartaccount.v1.MsgCreateSmartAccountResponse") + proto.RegisterType((*MsgUpdateAuthorization)(nil), "terra.smartaccount.v1.MsgUpdateAuthorization") + proto.RegisterType((*MsgUpdateAuthorizationResponse)(nil), "terra.smartaccount.v1.MsgUpdateAuthorizationResponse") + proto.RegisterType((*MsgUpdateTransactionHooks)(nil), "terra.smartaccount.v1.MsgUpdateTransactionHooks") + proto.RegisterType((*MsgUpdateTransactionHooksResponse)(nil), "terra.smartaccount.v1.MsgUpdateTransactionHooksResponse") + proto.RegisterType((*MsgDisableSmartAccount)(nil), "terra.smartaccount.v1.MsgDisableSmartAccount") + proto.RegisterType((*MsgDisableSmartAccountResponse)(nil), "terra.smartaccount.v1.MsgDisableSmartAccountResponse") +} + +func init() { proto.RegisterFile("terra/smartaccount/v1/tx.proto", fileDescriptor_a2931e7b90fb4027) } + +var fileDescriptor_a2931e7b90fb4027 = []byte{ + // 489 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x94, 0x3d, 0x6f, 0xd3, 0x40, + 0x18, 0xc7, 0x73, 0x35, 0x2f, 0xed, 0x31, 0xe1, 0x36, 0xc1, 0x58, 0xc2, 0x18, 0x77, 0x20, 0x42, + 0xd4, 0x47, 0xdc, 0x22, 0xb1, 0x16, 0x18, 0x58, 0xbc, 0x98, 0x97, 0x81, 0x25, 0xba, 0x98, 0xe3, + 0x62, 0x35, 0xf6, 0x59, 0xf7, 0x5c, 0xa2, 0x14, 0x16, 0x06, 0x24, 0x56, 0xbe, 0x01, 0x1b, 0x33, + 0x1f, 0x83, 0xb1, 0x23, 0x23, 0x4a, 0x06, 0xbe, 0x06, 0xb2, 0x93, 0x98, 0x24, 0x9c, 0x03, 0xd9, + 0x7c, 0x7e, 0x7e, 0xff, 0xff, 0x73, 0xcf, 0x8b, 0x0e, 0x3b, 0x8a, 0x49, 0x49, 0x09, 0xa4, 0x54, + 0x2a, 0x1a, 0xc7, 0x62, 0x98, 0x29, 0x32, 0xea, 0x10, 0x35, 0xf6, 0x73, 0x29, 0x94, 0x30, 0x9b, + 0x65, 0xdc, 0x5f, 0x8e, 0xfb, 0xa3, 0x8e, 0x7d, 0xc0, 0x05, 0x17, 0x25, 0x41, 0x8a, 0xaf, 0x19, + 0x6c, 0xdf, 0x88, 0x05, 0xa4, 0x02, 0x48, 0x0a, 0xbc, 0x30, 0x49, 0x81, 0xcf, 0x03, 0x87, 0xfa, + 0x2c, 0xc0, 0x94, 0x4a, 0xb2, 0x39, 0xe4, 0x75, 0x70, 0x33, 0x04, 0xfe, 0x44, 0x32, 0xaa, 0xd8, + 0xf3, 0x82, 0x3c, 0x9d, 0x91, 0xa6, 0x85, 0xaf, 0xce, 0x45, 0x16, 0x72, 0x51, 0x7b, 0x2f, 0x5a, + 0x1c, 0xbd, 0xdb, 0xf8, 0x96, 0x56, 0x12, 0x31, 0xc8, 0x45, 0x06, 0xcc, 0xfb, 0x8a, 0x70, 0x2b, + 0x04, 0xfe, 0x32, 0x7f, 0x43, 0x15, 0x3b, 0x1d, 0xaa, 0xbe, 0x90, 0xc9, 0x3b, 0xaa, 0x12, 0x91, + 0xd5, 0xbb, 0x9a, 0x36, 0xde, 0x7d, 0x4b, 0x07, 0x83, 0x1e, 0x8d, 0xcf, 0xac, 0x1d, 0x17, 0xb5, + 0x77, 0xa3, 0xea, 0x6c, 0xbe, 0xc2, 0x26, 0x5d, 0xb6, 0xe9, 0xa6, 0xc0, 0xc1, 0x32, 0x5c, 0xa3, + 0x7d, 0x2d, 0xb8, 0xeb, 0x6b, 0x9b, 0xe5, 0xaf, 0xe4, 0x0d, 0x81, 0x47, 0xd7, 0xe9, 0xda, 0x1f, + 0xf0, 0x5c, 0xec, 0xe8, 0xef, 0x59, 0x95, 0xf2, 0x05, 0xe1, 0x9b, 0x15, 0xf2, 0x42, 0xd2, 0x0c, + 0x68, 0x5c, 0x00, 0xcf, 0x84, 0x38, 0x83, 0x0d, 0xd5, 0x04, 0xb8, 0x99, 0x4b, 0xd6, 0x55, 0x7f, + 0x14, 0xdd, 0x7e, 0x21, 0xb1, 0x76, 0x5c, 0xa3, 0xbd, 0x17, 0xed, 0xe7, 0xf2, 0x6f, 0xb7, 0x13, + 0xdc, 0xca, 0x05, 0x28, 0x8d, 0xc8, 0x28, 0x45, 0x07, 0x45, 0x74, 0x5d, 0xe5, 0x1d, 0xe2, 0x3b, + 0xb5, 0x17, 0xac, 0xca, 0x08, 0xca, 0x81, 0x3c, 0x4d, 0x80, 0xf6, 0x06, 0xff, 0x3b, 0xe6, 0x59, + 0x73, 0x34, 0x9a, 0x85, 0x6b, 0xf0, 0xe9, 0x12, 0x36, 0x42, 0xe0, 0xe6, 0x18, 0x9b, 0x9a, 0x05, + 0xba, 0x5f, 0x33, 0x18, 0xed, 0xee, 0xd8, 0x27, 0xdb, 0xd0, 0x8b, 0x1b, 0x98, 0xef, 0xf1, 0xbe, + 0x6e, 0xcb, 0x8e, 0xea, 0xcd, 0x34, 0xb8, 0xfd, 0x70, 0x2b, 0xbc, 0x4a, 0xfe, 0x11, 0xe1, 0x56, + 0xcd, 0x62, 0x3c, 0xf8, 0x97, 0xe3, 0xba, 0xc2, 0x7e, 0xb4, 0xad, 0x62, 0xb9, 0x07, 0xba, 0xc1, + 0x6e, 0xe8, 0x81, 0x06, 0xdf, 0xd4, 0x83, 0x0d, 0x2b, 0x60, 0x5f, 0xfe, 0xf0, 0xeb, 0xdb, 0x3d, + 0xf4, 0x38, 0xfc, 0x3e, 0x71, 0xd0, 0xc5, 0xc4, 0x41, 0x3f, 0x27, 0x0e, 0xfa, 0x3c, 0x75, 0x1a, + 0x17, 0x53, 0xa7, 0xf1, 0x63, 0xea, 0x34, 0x5e, 0x1f, 0xf3, 0x44, 0xf5, 0x87, 0x3d, 0x3f, 0x16, + 0x29, 0x29, 0x33, 0x1c, 0xa5, 0x22, 0x63, 0xe7, 0x24, 0x16, 0x92, 0x91, 0x51, 0x40, 0xc6, 0xab, + 0xef, 0x93, 0x3a, 0xcf, 0x19, 0xf4, 0xae, 0x94, 0x6f, 0xd3, 0xf1, 0xef, 0x00, 0x00, 0x00, 0xff, + 0xff, 0x03, 0x17, 0x58, 0xde, 0x28, 0x05, 0x00, 0x00, +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion4 + +// MsgClient is the client API for Msg service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type MsgClient interface { + // CreateSmartAccount defines a method for creating a smart account. + CreateSmartAccount(ctx context.Context, in *MsgCreateSmartAccount, opts ...grpc.CallOption) (*MsgCreateSmartAccountResponse, error) + // UpdateAuthorization defines a method for updating the wasm authentication contract. + UpdateAuthorization(ctx context.Context, in *MsgUpdateAuthorization, opts ...grpc.CallOption) (*MsgUpdateAuthorizationResponse, error) + // UpdateTransactionHooks defines a method for updating the wasm transaction hooks contract. + UpdateTransactionHooks(ctx context.Context, in *MsgUpdateTransactionHooks, opts ...grpc.CallOption) (*MsgUpdateTransactionHooksResponse, error) + // DisableSmartAccountMsg defines a method for converting smart account to basic account. + DisableSmartAccount(ctx context.Context, in *MsgDisableSmartAccount, opts ...grpc.CallOption) (*MsgDisableSmartAccountResponse, error) +} + +type msgClient struct { + cc grpc1.ClientConn +} + +func NewMsgClient(cc grpc1.ClientConn) MsgClient { + return &msgClient{cc} +} + +func (c *msgClient) CreateSmartAccount(ctx context.Context, in *MsgCreateSmartAccount, opts ...grpc.CallOption) (*MsgCreateSmartAccountResponse, error) { + out := new(MsgCreateSmartAccountResponse) + err := c.cc.Invoke(ctx, "/terra.smartaccount.v1.Msg/CreateSmartAccount", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *msgClient) UpdateAuthorization(ctx context.Context, in *MsgUpdateAuthorization, opts ...grpc.CallOption) (*MsgUpdateAuthorizationResponse, error) { + out := new(MsgUpdateAuthorizationResponse) + err := c.cc.Invoke(ctx, "/terra.smartaccount.v1.Msg/UpdateAuthorization", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *msgClient) UpdateTransactionHooks(ctx context.Context, in *MsgUpdateTransactionHooks, opts ...grpc.CallOption) (*MsgUpdateTransactionHooksResponse, error) { + out := new(MsgUpdateTransactionHooksResponse) + err := c.cc.Invoke(ctx, "/terra.smartaccount.v1.Msg/UpdateTransactionHooks", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *msgClient) DisableSmartAccount(ctx context.Context, in *MsgDisableSmartAccount, opts ...grpc.CallOption) (*MsgDisableSmartAccountResponse, error) { + out := new(MsgDisableSmartAccountResponse) + err := c.cc.Invoke(ctx, "/terra.smartaccount.v1.Msg/DisableSmartAccount", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// MsgServer is the server API for Msg service. +type MsgServer interface { + // CreateSmartAccount defines a method for creating a smart account. + CreateSmartAccount(context.Context, *MsgCreateSmartAccount) (*MsgCreateSmartAccountResponse, error) + // UpdateAuthorization defines a method for updating the wasm authentication contract. + UpdateAuthorization(context.Context, *MsgUpdateAuthorization) (*MsgUpdateAuthorizationResponse, error) + // UpdateTransactionHooks defines a method for updating the wasm transaction hooks contract. + UpdateTransactionHooks(context.Context, *MsgUpdateTransactionHooks) (*MsgUpdateTransactionHooksResponse, error) + // DisableSmartAccountMsg defines a method for converting smart account to basic account. + DisableSmartAccount(context.Context, *MsgDisableSmartAccount) (*MsgDisableSmartAccountResponse, error) +} + +// UnimplementedMsgServer can be embedded to have forward compatible implementations. +type UnimplementedMsgServer struct { +} + +func (*UnimplementedMsgServer) CreateSmartAccount(ctx context.Context, req *MsgCreateSmartAccount) (*MsgCreateSmartAccountResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method CreateSmartAccount not implemented") +} +func (*UnimplementedMsgServer) UpdateAuthorization(ctx context.Context, req *MsgUpdateAuthorization) (*MsgUpdateAuthorizationResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateAuthorization not implemented") +} +func (*UnimplementedMsgServer) UpdateTransactionHooks(ctx context.Context, req *MsgUpdateTransactionHooks) (*MsgUpdateTransactionHooksResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateTransactionHooks not implemented") +} +func (*UnimplementedMsgServer) DisableSmartAccount(ctx context.Context, req *MsgDisableSmartAccount) (*MsgDisableSmartAccountResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method DisableSmartAccount not implemented") +} + +func RegisterMsgServer(s grpc1.Server, srv MsgServer) { + s.RegisterService(&_Msg_serviceDesc, srv) +} + +func _Msg_CreateSmartAccount_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgCreateSmartAccount) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).CreateSmartAccount(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/terra.smartaccount.v1.Msg/CreateSmartAccount", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).CreateSmartAccount(ctx, req.(*MsgCreateSmartAccount)) + } + return interceptor(ctx, in, info, handler) +} + +func _Msg_UpdateAuthorization_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgUpdateAuthorization) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).UpdateAuthorization(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/terra.smartaccount.v1.Msg/UpdateAuthorization", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).UpdateAuthorization(ctx, req.(*MsgUpdateAuthorization)) + } + return interceptor(ctx, in, info, handler) +} + +func _Msg_UpdateTransactionHooks_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgUpdateTransactionHooks) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).UpdateTransactionHooks(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/terra.smartaccount.v1.Msg/UpdateTransactionHooks", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).UpdateTransactionHooks(ctx, req.(*MsgUpdateTransactionHooks)) + } + return interceptor(ctx, in, info, handler) +} + +func _Msg_DisableSmartAccount_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgDisableSmartAccount) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).DisableSmartAccount(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/terra.smartaccount.v1.Msg/DisableSmartAccount", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).DisableSmartAccount(ctx, req.(*MsgDisableSmartAccount)) + } + return interceptor(ctx, in, info, handler) +} + +var _Msg_serviceDesc = grpc.ServiceDesc{ + ServiceName: "terra.smartaccount.v1.Msg", + HandlerType: (*MsgServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "CreateSmartAccount", + Handler: _Msg_CreateSmartAccount_Handler, + }, + { + MethodName: "UpdateAuthorization", + Handler: _Msg_UpdateAuthorization_Handler, + }, + { + MethodName: "UpdateTransactionHooks", + Handler: _Msg_UpdateTransactionHooks_Handler, + }, + { + MethodName: "DisableSmartAccount", + Handler: _Msg_DisableSmartAccount_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "terra/smartaccount/v1/tx.proto", +} + +func (m *MsgCreateSmartAccount) 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 *MsgCreateSmartAccount) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgCreateSmartAccount) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Account) > 0 { + i -= len(m.Account) + copy(dAtA[i:], m.Account) + i = encodeVarintTx(dAtA, i, uint64(len(m.Account))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgCreateSmartAccountResponse) 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 *MsgCreateSmartAccountResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgCreateSmartAccountResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *MsgUpdateAuthorization) 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 *MsgUpdateAuthorization) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgUpdateAuthorization) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.AuthorizationMsgs) > 0 { + for iNdEx := len(m.AuthorizationMsgs) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.AuthorizationMsgs[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + } + if m.Fallback { + i-- + if m.Fallback { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x10 + } + if len(m.Account) > 0 { + i -= len(m.Account) + copy(dAtA[i:], m.Account) + i = encodeVarintTx(dAtA, i, uint64(len(m.Account))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgUpdateAuthorizationResponse) 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 *MsgUpdateAuthorizationResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgUpdateAuthorizationResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *MsgUpdateTransactionHooks) 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 *MsgUpdateTransactionHooks) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgUpdateTransactionHooks) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.PostTransactionHooks) > 0 { + for iNdEx := len(m.PostTransactionHooks) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.PostTransactionHooks[iNdEx]) + copy(dAtA[i:], m.PostTransactionHooks[iNdEx]) + i = encodeVarintTx(dAtA, i, uint64(len(m.PostTransactionHooks[iNdEx]))) + i-- + dAtA[i] = 0x1a + } + } + if len(m.PreTransactionHooks) > 0 { + for iNdEx := len(m.PreTransactionHooks) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.PreTransactionHooks[iNdEx]) + copy(dAtA[i:], m.PreTransactionHooks[iNdEx]) + i = encodeVarintTx(dAtA, i, uint64(len(m.PreTransactionHooks[iNdEx]))) + i-- + dAtA[i] = 0x12 + } + } + if len(m.Account) > 0 { + i -= len(m.Account) + copy(dAtA[i:], m.Account) + i = encodeVarintTx(dAtA, i, uint64(len(m.Account))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgUpdateTransactionHooksResponse) 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 *MsgUpdateTransactionHooksResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgUpdateTransactionHooksResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *MsgDisableSmartAccount) 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 *MsgDisableSmartAccount) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgDisableSmartAccount) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Account) > 0 { + i -= len(m.Account) + copy(dAtA[i:], m.Account) + i = encodeVarintTx(dAtA, i, uint64(len(m.Account))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgDisableSmartAccountResponse) 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 *MsgDisableSmartAccountResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgDisableSmartAccountResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func encodeVarintTx(dAtA []byte, offset int, v uint64) int { + offset -= sovTx(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *MsgCreateSmartAccount) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Account) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + return n +} + +func (m *MsgCreateSmartAccountResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *MsgUpdateAuthorization) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Account) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + if m.Fallback { + n += 2 + } + if len(m.AuthorizationMsgs) > 0 { + for _, e := range m.AuthorizationMsgs { + l = e.Size() + n += 1 + l + sovTx(uint64(l)) + } + } + return n +} + +func (m *MsgUpdateAuthorizationResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *MsgUpdateTransactionHooks) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Account) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + if len(m.PreTransactionHooks) > 0 { + for _, s := range m.PreTransactionHooks { + l = len(s) + n += 1 + l + sovTx(uint64(l)) + } + } + if len(m.PostTransactionHooks) > 0 { + for _, s := range m.PostTransactionHooks { + l = len(s) + n += 1 + l + sovTx(uint64(l)) + } + } + return n +} + +func (m *MsgUpdateTransactionHooksResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *MsgDisableSmartAccount) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Account) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + return n +} + +func (m *MsgDisableSmartAccountResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func sovTx(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozTx(x uint64) (n int) { + return sovTx(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *MsgCreateSmartAccount) 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 ErrIntOverflowTx + } + 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: MsgCreateSmartAccount: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgCreateSmartAccount: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Account", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + 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 ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Account = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgCreateSmartAccountResponse) 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 ErrIntOverflowTx + } + 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: MsgCreateSmartAccountResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgCreateSmartAccountResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgUpdateAuthorization) 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 ErrIntOverflowTx + } + 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: MsgUpdateAuthorization: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgUpdateAuthorization: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Account", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + 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 ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Account = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Fallback", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Fallback = bool(v != 0) + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AuthorizationMsgs", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AuthorizationMsgs = append(m.AuthorizationMsgs, &AuthorizationMsg{}) + if err := m.AuthorizationMsgs[len(m.AuthorizationMsgs)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgUpdateAuthorizationResponse) 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 ErrIntOverflowTx + } + 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: MsgUpdateAuthorizationResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgUpdateAuthorizationResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgUpdateTransactionHooks) 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 ErrIntOverflowTx + } + 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: MsgUpdateTransactionHooks: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgUpdateTransactionHooks: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Account", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + 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 ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Account = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PreTransactionHooks", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + 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 ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.PreTransactionHooks = append(m.PreTransactionHooks, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PostTransactionHooks", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + 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 ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.PostTransactionHooks = append(m.PostTransactionHooks, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgUpdateTransactionHooksResponse) 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 ErrIntOverflowTx + } + 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: MsgUpdateTransactionHooksResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgUpdateTransactionHooksResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgDisableSmartAccount) 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 ErrIntOverflowTx + } + 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: MsgDisableSmartAccount: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgDisableSmartAccount: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Account", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + 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 ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Account = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgDisableSmartAccountResponse) 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 ErrIntOverflowTx + } + 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: MsgDisableSmartAccountResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgDisableSmartAccountResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipTx(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, ErrIntOverflowTx + } + 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, ErrIntOverflowTx + } + 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, ErrIntOverflowTx + } + 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, ErrInvalidLengthTx + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupTx + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthTx + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthTx = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowTx = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupTx = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/smartaccount/types/wasm.go b/x/smartaccount/types/wasm.go new file mode 100644 index 00000000..49e6621c --- /dev/null +++ b/x/smartaccount/types/wasm.go @@ -0,0 +1,30 @@ +package types + +import "github.com/CosmWasm/wasmvm/types" + +type SudoMsg struct { + Initialization *Initialization `json:"initialization,omitempty"` + Authorization *Authorization `json:"authorization,omitempty"` + PreTransaction *PreTransaction `json:"pre_transaction,omitempty"` + PostTransaction *PostTransaction `json:"post_transaction,omitempty"` +} + +type Authorization struct { + Senders []string `json:"senders"` + Account string `json:"account"` + Signatures [][]byte `json:"signatures"` + SignedBytes [][]byte `json:"signed_bytes"` + Data []byte `json:"data"` +} + +type PreTransaction struct { + Sender string `json:"sender"` + Account string `json:"account"` + Messages []types.CosmosMsg `json:"msgs"` +} + +type PostTransaction struct { + Sender string `json:"sender"` + Account string `json:"account"` + Messages []types.CosmosMsg `json:"msgs"` +} diff --git a/x/smartaccount/types/wasm.pb.go b/x/smartaccount/types/wasm.pb.go new file mode 100644 index 00000000..734fa909 --- /dev/null +++ b/x/smartaccount/types/wasm.pb.go @@ -0,0 +1,372 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: terra/smartaccount/v1/wasm.proto + +package types + +import ( + fmt "fmt" + _ "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 + +type Initialization struct { + Account string `protobuf:"bytes,1,opt,name=account,proto3" json:"account"` + Msg []byte `protobuf:"bytes,2,opt,name=msg,proto3" json:"msg"` +} + +func (m *Initialization) Reset() { *m = Initialization{} } +func (m *Initialization) String() string { return proto.CompactTextString(m) } +func (*Initialization) ProtoMessage() {} +func (*Initialization) Descriptor() ([]byte, []int) { + return fileDescriptor_0cff19e26b95f6af, []int{0} +} +func (m *Initialization) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Initialization) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Initialization.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 *Initialization) XXX_Merge(src proto.Message) { + xxx_messageInfo_Initialization.Merge(m, src) +} +func (m *Initialization) XXX_Size() int { + return m.Size() +} +func (m *Initialization) XXX_DiscardUnknown() { + xxx_messageInfo_Initialization.DiscardUnknown(m) +} + +var xxx_messageInfo_Initialization proto.InternalMessageInfo + +func (m *Initialization) GetAccount() string { + if m != nil { + return m.Account + } + return "" +} + +func (m *Initialization) GetMsg() []byte { + if m != nil { + return m.Msg + } + return nil +} + +func init() { + proto.RegisterType((*Initialization)(nil), "terra.smartaccount.v1.Initialization") +} + +func init() { proto.RegisterFile("terra/smartaccount/v1/wasm.proto", fileDescriptor_0cff19e26b95f6af) } + +var fileDescriptor_0cff19e26b95f6af = []byte{ + // 215 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x52, 0x28, 0x49, 0x2d, 0x2a, + 0x4a, 0xd4, 0x2f, 0xce, 0x4d, 0x2c, 0x2a, 0x49, 0x4c, 0x4e, 0xce, 0x2f, 0xcd, 0x2b, 0xd1, 0x2f, + 0x33, 0xd4, 0x2f, 0x4f, 0x2c, 0xce, 0xd5, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x12, 0x05, 0xab, + 0xd0, 0x43, 0x56, 0xa1, 0x57, 0x66, 0x28, 0x25, 0x92, 0x9e, 0x9f, 0x9e, 0x0f, 0x56, 0xa1, 0x0f, + 0x62, 0x41, 0x14, 0x2b, 0x05, 0x71, 0xf1, 0x79, 0xe6, 0x65, 0x96, 0x64, 0x26, 0xe6, 0x64, 0x56, + 0x25, 0x96, 0x64, 0xe6, 0xe7, 0x09, 0xa9, 0x72, 0xb1, 0x43, 0x75, 0x49, 0x30, 0x2a, 0x30, 0x6a, + 0x70, 0x3a, 0x71, 0xbf, 0xba, 0x27, 0x0f, 0x13, 0x0a, 0x82, 0x31, 0x84, 0x24, 0xb9, 0x98, 0x73, + 0x8b, 0xd3, 0x25, 0x98, 0x14, 0x18, 0x35, 0x78, 0x9c, 0xd8, 0x5f, 0xdd, 0x93, 0x07, 0x71, 0x83, + 0x40, 0x84, 0x93, 0xef, 0x89, 0x47, 0x72, 0x8c, 0x17, 0x1e, 0xc9, 0x31, 0x3e, 0x78, 0x24, 0xc7, + 0x38, 0xe1, 0xb1, 0x1c, 0xc3, 0x85, 0xc7, 0x72, 0x0c, 0x37, 0x1e, 0xcb, 0x31, 0x44, 0x19, 0xa7, + 0x67, 0x96, 0x64, 0x94, 0x26, 0xe9, 0x25, 0xe7, 0xe7, 0xea, 0x83, 0x5d, 0xa9, 0x9b, 0x9b, 0x9f, + 0x97, 0x5a, 0xa9, 0x9f, 0x9c, 0x5f, 0x94, 0xaa, 0x5f, 0x66, 0xa4, 0x5f, 0x81, 0xea, 0xaf, 0x92, + 0xca, 0x82, 0xd4, 0xe2, 0x24, 0x36, 0xb0, 0x4b, 0x8d, 0x01, 0x01, 0x00, 0x00, 0xff, 0xff, 0xb0, + 0x33, 0x24, 0x37, 0xfa, 0x00, 0x00, 0x00, +} + +func (m *Initialization) 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 *Initialization) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Initialization) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Msg) > 0 { + i -= len(m.Msg) + copy(dAtA[i:], m.Msg) + i = encodeVarintWasm(dAtA, i, uint64(len(m.Msg))) + i-- + dAtA[i] = 0x12 + } + if len(m.Account) > 0 { + i -= len(m.Account) + copy(dAtA[i:], m.Account) + i = encodeVarintWasm(dAtA, i, uint64(len(m.Account))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func encodeVarintWasm(dAtA []byte, offset int, v uint64) int { + offset -= sovWasm(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *Initialization) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Account) + if l > 0 { + n += 1 + l + sovWasm(uint64(l)) + } + l = len(m.Msg) + if l > 0 { + n += 1 + l + sovWasm(uint64(l)) + } + return n +} + +func sovWasm(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozWasm(x uint64) (n int) { + return sovWasm(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *Initialization) 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 ErrIntOverflowWasm + } + 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: Initialization: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Initialization: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Account", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowWasm + } + 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 ErrInvalidLengthWasm + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthWasm + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Account = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Msg", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowWasm + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthWasm + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthWasm + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Msg = append(m.Msg[:0], dAtA[iNdEx:postIndex]...) + if m.Msg == nil { + m.Msg = []byte{} + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipWasm(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthWasm + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipWasm(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, ErrIntOverflowWasm + } + 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, ErrIntOverflowWasm + } + 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, ErrIntOverflowWasm + } + 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, ErrInvalidLengthWasm + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupWasm + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthWasm + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthWasm = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowWasm = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupWasm = fmt.Errorf("proto: unexpected end of group") +)