> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cosmos.network/llms.txt
> Use this file to discover all available pages before exploring further.

# Overview of app_di.go

<Note>
  **Synopsis**

  The Cosmos SDK allows much easier wiring of an `app.go` thanks to [runtime](/sdk/v0.53/build/building-apps/runtime) and app wiring.
  Learn more about the rationale of App Wiring in [ADR-057](/sdk/v0.53/build/architecture/adr-057-app-wiring).
</Note>

<Note>
  **Prerequisite Readings**

  * [What is `runtime`?](/sdk/v0.53/build/building-apps/runtime)
  * [Depinject documentation](/sdk/v0.53/build/packages/depinject)
  * [Modules depinject-ready](/sdk/v0.53/build/building-modules/depinject)
  * [ADR 057: App Wiring](/sdk/v0.53/build/architecture/adr-057-app-wiring)
</Note>

This section is intended to provide an overview of the `SimApp` `app_di.go` file with App Wiring.

## `app_config.go`

The `app_config.go` file is the single place to configure all modules parameters.

1. Create the `AppConfig` variable:

   ```go expandable theme={"theme":{"light":"github-light-high-contrast","dark":"github-dark-high-contrast"}}
   package simapp

   import (
       
   	"time"
       "google.golang.org/protobuf/types/known/durationpb"

   	runtimev1alpha1 "cosmossdk.io/api/cosmos/app/runtime/v1alpha1"
   	appv1alpha1 "cosmossdk.io/api/cosmos/app/v1alpha1"
   	authmodulev1 "cosmossdk.io/api/cosmos/auth/module/v1"
   	authzmodulev1 "cosmossdk.io/api/cosmos/authz/module/v1"
   	bankmodulev1 "cosmossdk.io/api/cosmos/bank/module/v1"
   	circuitmodulev1 "cosmossdk.io/api/cosmos/circuit/module/v1"
   	consensusmodulev1 "cosmossdk.io/api/cosmos/consensus/module/v1"
   	distrmodulev1 "cosmossdk.io/api/cosmos/distribution/module/v1"
   	epochsmodulev1 "cosmossdk.io/api/cosmos/epochs/module/v1"
   	evidencemodulev1 "cosmossdk.io/api/cosmos/evidence/module/v1"
   	feegrantmodulev1 "cosmossdk.io/api/cosmos/feegrant/module/v1"
   	genutilmodulev1 "cosmossdk.io/api/cosmos/genutil/module/v1"
   	govmodulev1 "cosmossdk.io/api/cosmos/gov/module/v1"
   	groupmodulev1 "cosmossdk.io/api/cosmos/group/module/v1"
   	mintmodulev1 "cosmossdk.io/api/cosmos/mint/module/v1"
   	nftmodulev1 "cosmossdk.io/api/cosmos/nft/module/v1"
   	protocolpoolmodulev1 "cosmossdk.io/api/cosmos/protocolpool/module/v1"
   	slashingmodulev1 "cosmossdk.io/api/cosmos/slashing/module/v1"
   	stakingmodulev1 "cosmossdk.io/api/cosmos/staking/module/v1"
   	txconfigv1 "cosmossdk.io/api/cosmos/tx/config/v1"
   	upgrademodulev1 "cosmossdk.io/api/cosmos/upgrade/module/v1"
   	vestingmodulev1 "cosmossdk.io/api/cosmos/vesting/module/v1"
       "cosmossdk.io/core/appconfig"
       "cosmossdk.io/depinject"
   	_ "cosmossdk.io/x/circuit" // import for side-effects
   	circuittypes "cosmossdk.io/x/circuit/types"
   	_ "cosmossdk.io/x/evidence" // import for side-effects
   	evidencetypes "cosmossdk.io/x/evidence/types"
       "cosmossdk.io/x/feegrant"
   	_ "cosmossdk.io/x/feegrant/module" // import for side-effects
   	"cosmossdk.io/x/nft"
   	_ "cosmossdk.io/x/nft/module" // import for side-effects
   	_ "cosmossdk.io/x/upgrade"    // import for side-effects
   	upgradetypes "cosmossdk.io/x/upgrade/types"
       "github.com/cosmos/cosmos-sdk/runtime"
       "github.com/cosmos/cosmos-sdk/types/module"
   	_ "github.com/cosmos/cosmos-sdk/x/auth/tx/config" // import for side-effects
   	authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
   	_ "github.com/cosmos/cosmos-sdk/x/auth/vesting" // import for side-effects
   	vestingtypes "github.com/cosmos/cosmos-sdk/x/auth/vesting/types"
       "github.com/cosmos/cosmos-sdk/x/authz"
   	_ "github.com/cosmos/cosmos-sdk/x/authz/module" // import for side-effects
   	_ "github.com/cosmos/cosmos-sdk/x/bank"         // import for side-effects
   	banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
   	_ "github.com/cosmos/cosmos-sdk/x/consensus" // import for side-effects
   	consensustypes "github.com/cosmos/cosmos-sdk/x/consensus/types"
   	_ "github.com/cosmos/cosmos-sdk/x/distribution" // import for side-effects
   	distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types"
   	_ "github.com/cosmos/cosmos-sdk/x/epochs" // import for side-effects
   	epochstypes "github.com/cosmos/cosmos-sdk/x/epochs/types"
       "github.com/cosmos/cosmos-sdk/x/genutil"
   	genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types"
       "github.com/cosmos/cosmos-sdk/x/gov"
   	govclient "github.com/cosmos/cosmos-sdk/x/gov/client"
   	govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
       "github.com/cosmos/cosmos-sdk/x/group"
   	_ "github.com/cosmos/cosmos-sdk/x/group/module" // import for side-effects
   	_ "github.com/cosmos/cosmos-sdk/x/mint"         // import for side-effects
   	minttypes "github.com/cosmos/cosmos-sdk/x/mint/types"
   	_ "github.com/cosmos/cosmos-sdk/x/protocolpool" // import for side-effects
   	protocolpooltypes "github.com/cosmos/cosmos-sdk/x/protocolpool/types"
   	_ "github.com/cosmos/cosmos-sdk/x/slashing" // import for side-effects
   	slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types"
   	_ "github.com/cosmos/cosmos-sdk/x/staking" // import for side-effects
   	stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
   )

   var (
   	// module account permissions
   	moduleAccPerms = []*authmodulev1.ModuleAccountPermission{
   		{
       Account: authtypes.FeeCollectorName
   },
   		{
       Account: distrtypes.ModuleName
   },
   		{
       Account: minttypes.ModuleName,
       Permissions: []string{
       authtypes.Minter
   }},
   		{
       Account: stakingtypes.BondedPoolName,
       Permissions: []string{
       authtypes.Burner, stakingtypes.ModuleName
   }},
   		{
       Account: stakingtypes.NotBondedPoolName,
       Permissions: []string{
       authtypes.Burner, stakingtypes.ModuleName
   }},
   		{
       Account: govtypes.ModuleName,
       Permissions: []string{
       authtypes.Burner
   }},
   		{
       Account: nft.ModuleName
   },
   		{
       Account: protocolpooltypes.ModuleName
   },
   		{
       Account: protocolpooltypes.ProtocolPoolEscrowAccount
   },
   }

   	// blocked account addresses
   	blockAccAddrs = []string{
       authtypes.FeeCollectorName,
   		distrtypes.ModuleName,
   		minttypes.ModuleName,
   		stakingtypes.BondedPoolName,
   		stakingtypes.NotBondedPoolName,
   		nft.ModuleName,
   		// We allow the following module accounts to receive funds:
   		// govtypes.ModuleName
   }

   ModuleConfig = []*appv1alpha1.ModuleConfig{
   		{
       Name: runtime.ModuleName,
       Config: appconfig.WrapAny(&runtimev1alpha1.Module{
       AppName: "SimApp",
   				// NOTE: upgrade module is required to be prioritized
   				PreBlockers: []string{
       upgradetypes.ModuleName,
   					authtypes.ModuleName,
   },
   				// During begin block slashing happens after distr.BeginBlocker so that
   				// there is nothing left over in the validator fee pool, so as to keep the
   				// CanWithdrawInvariant invariant.
   				// NOTE: staking module is required if HistoricalEntries param > 0
   				BeginBlockers: []string{
       minttypes.ModuleName,
   					distrtypes.ModuleName,
   					protocolpooltypes.ModuleName,
   					slashingtypes.ModuleName,
   					evidencetypes.ModuleName,
   					stakingtypes.ModuleName,
   					authz.ModuleName,
   					epochstypes.ModuleName,
   },
       EndBlockers: []string{
       govtypes.ModuleName,
   					stakingtypes.ModuleName,
   					feegrant.ModuleName,
   					group.ModuleName,
   					protocolpooltypes.ModuleName,
   },
       OverrideStoreKeys: []*runtimev1alpha1.StoreKeyConfig{
   					{
       ModuleName: authtypes.ModuleName,
       KvStoreKey: "acc",
   },
   },
   				// NOTE: The genutils module must occur after staking so that pools are
   				// properly initialized with tokens from genesis accounts.
   				// NOTE: The genutils module must also occur after auth so that it can access the params from auth.
   				InitGenesis: []string{
       authtypes.ModuleName,
   					banktypes.ModuleName,
   					distrtypes.ModuleName,
   					stakingtypes.ModuleName,
   					slashingtypes.ModuleName,
   					govtypes.ModuleName,
   					minttypes.ModuleName,
   					genutiltypes.ModuleName,
   					evidencetypes.ModuleName,
   					authz.ModuleName,
   					feegrant.ModuleName,
   					nft.ModuleName,
   					group.ModuleName,
   					upgradetypes.ModuleName,
   					vestingtypes.ModuleName,
   					circuittypes.ModuleName,
   					epochstypes.ModuleName,
   					protocolpooltypes.ModuleName,
   },
   				// When ExportGenesis is not specified, the export genesis module order
   				// is equal to the init genesis order
   				ExportGenesis: []string{
       consensustypes.ModuleName,
   					authtypes.ModuleName,
   					protocolpooltypes.ModuleName, // Must be exported before bank
   					banktypes.ModuleName,
   					distrtypes.ModuleName,
   					stakingtypes.ModuleName,
   					slashingtypes.ModuleName,
   					govtypes.ModuleName,
   					minttypes.ModuleName,
   					genutiltypes.ModuleName,
   					evidencetypes.ModuleName,
   					authz.ModuleName,
   					feegrant.ModuleName,
   					nft.ModuleName,
   					group.ModuleName,
   					upgradetypes.ModuleName,
   					vestingtypes.ModuleName,
   					circuittypes.ModuleName,
   					epochstypes.ModuleName,
   },
   				// Uncomment if you want to set a custom migration order here.
   				// OrderMigrations: []string{
   },
   }),
   },
   		{
       Name: authtypes.ModuleName,
       Config: appconfig.WrapAny(&authmodulev1.Module{
       Bech32Prefix:             "cosmos",
       ModuleAccountPermissions: moduleAccPerms,
   				// By default modules authority is the governance module. This is configurable with the following:
   				// Authority: "group", // A custom module authority can be set using a module name
   				// Authority: "cosmos1cwwv22j5ca08ggdv9c2uky355k908694z577tv", // or a specific address
   }),
   },
   		{
       Name:   vestingtypes.ModuleName,
       Config: appconfig.WrapAny(&vestingmodulev1.Module{
   }),
   },
   		{
       Name: banktypes.ModuleName,
       Config: appconfig.WrapAny(&bankmodulev1.Module{
       BlockedModuleAccountsOverride: blockAccAddrs,
   }),
   },
   		{
       Name: stakingtypes.ModuleName,
       Config: appconfig.WrapAny(&stakingmodulev1.Module{
   				// NOTE: specifying a prefix is only necessary when using bech32 addresses
   				// If not specfied, the auth Bech32Prefix appended with "valoper" and "valcons" is used by default
   				Bech32PrefixValidator: "cosmosvaloper",
   				Bech32PrefixConsensus: "cosmosvalcons",
   }),
   },
   		{
       Name:   slashingtypes.ModuleName,
       Config: appconfig.WrapAny(&slashingmodulev1.Module{
   }),
   },
   		{
       Name: "tx",
       Config: appconfig.WrapAny(&txconfigv1.Config{
       SkipAnteHandler: true, // Enable this to skip the default antehandlers and set custom ante handlers.
   }),
   },
   		{
       Name:   genutiltypes.ModuleName,
       Config: appconfig.WrapAny(&genutilmodulev1.Module{
   }),
   },
   		{
       Name:   authz.ModuleName,
       Config: appconfig.WrapAny(&authzmodulev1.Module{
   }),
   },
   		{
       Name:   upgradetypes.ModuleName,
       Config: appconfig.WrapAny(&upgrademodulev1.Module{
   }),
   },
   		{
       Name:   distrtypes.ModuleName,
       Config: appconfig.WrapAny(&distrmodulev1.Module{
   }),
   },
   		{
       Name:   evidencetypes.ModuleName,
       Config: appconfig.WrapAny(&evidencemodulev1.Module{
   }),
   },
   		{
       Name:   minttypes.ModuleName,
       Config: appconfig.WrapAny(&mintmodulev1.Module{
   }),
   },
   		{
       Name: group.ModuleName,
       Config: appconfig.WrapAny(&groupmodulev1.Module{
       MaxExecutionPeriod: durationpb.New(time.Second * 1209600),
       MaxMetadataLen:     255,
   }),
   },
   		{
       Name:   nft.ModuleName,
       Config: appconfig.WrapAny(&nftmodulev1.Module{
   }),
   },
   		{
       Name:   feegrant.ModuleName,
       Config: appconfig.WrapAny(&feegrantmodulev1.Module{
   }),
   },
   		{
       Name:   govtypes.ModuleName,
       Config: appconfig.WrapAny(&govmodulev1.Module{
   }),
   },
   		{
       Name:   consensustypes.ModuleName,
       Config: appconfig.WrapAny(&consensusmodulev1.Module{
   }),
   },
   		{
       Name:   circuittypes.ModuleName,
       Config: appconfig.WrapAny(&circuitmodulev1.Module{
   }),
   },
   		{
       Name:   epochstypes.ModuleName,
       Config: appconfig.WrapAny(&epochsmodulev1.Module{
   }),
   },
   		{
       Name:   protocolpooltypes.ModuleName,
       Config: appconfig.WrapAny(&protocolpoolmodulev1.Module{
   }),
   },
   }

   	// AppConfig is application configuration (used by depinject)

   AppConfig = depinject.Configs(appconfig.Compose(&appv1alpha1.Config{
       Modules: ModuleConfig,
   }),
   		depinject.Supply(
   			// supply custom module basics
   			map[string]module.AppModuleBasic{
       genutiltypes.ModuleName: genutil.NewAppModuleBasic(genutiltypes.DefaultMessageValidator),
   				govtypes.ModuleName: gov.NewAppModuleBasic(
   					[]govclient.ProposalHandler{
   },
   				),
   },
   		),
   	)
   )
   ```

   Where the `appConfig` combines the [runtime](/sdk/v0.53/build/building-apps/runtime) configuration and the (extra) modules configuration.

   ```go expandable theme={"theme":{"light":"github-light-high-contrast","dark":"github-dark-high-contrast"}}
   //go:build !app_v1

   package simapp

   import (
       
   	"io"

   	dbm "github.com/cosmos/cosmos-db"

   	clienthelpers "cosmossdk.io/client/v2/helpers"
       "cosmossdk.io/depinject"
       "cosmossdk.io/log"
   	storetypes "cosmossdk.io/store/types"
   	circuitkeeper "cosmossdk.io/x/circuit/keeper"
   	evidencekeeper "cosmossdk.io/x/evidence/keeper"
   	feegrantkeeper "cosmossdk.io/x/feegrant/keeper"
   	nftkeeper "cosmossdk.io/x/nft/keeper"
   	upgradekeeper "cosmossdk.io/x/upgrade/keeper"
       "github.com/cosmos/cosmos-sdk/baseapp"
       "github.com/cosmos/cosmos-sdk/client"
       "github.com/cosmos/cosmos-sdk/codec"
   	codectypes "github.com/cosmos/cosmos-sdk/codec/types"
       "github.com/cosmos/cosmos-sdk/runtime"
       "github.com/cosmos/cosmos-sdk/server"
       "github.com/cosmos/cosmos-sdk/server/api"
       "github.com/cosmos/cosmos-sdk/server/config"
   	servertypes "github.com/cosmos/cosmos-sdk/server/types"
   	testdata_pulsar "github.com/cosmos/cosmos-sdk/testutil/testdata/testpb"
       "github.com/cosmos/cosmos-sdk/types/module"
       "github.com/cosmos/cosmos-sdk/x/auth"
       "github.com/cosmos/cosmos-sdk/x/auth/ante"
   	authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
   	authsims "github.com/cosmos/cosmos-sdk/x/auth/simulation"
   	authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
   	authzkeeper "github.com/cosmos/cosmos-sdk/x/authz/keeper"
   	bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper"
   	consensuskeeper "github.com/cosmos/cosmos-sdk/x/consensus/keeper"
   	distrkeeper "github.com/cosmos/cosmos-sdk/x/distribution/keeper"
   	epochskeeper "github.com/cosmos/cosmos-sdk/x/epochs/keeper"
   	govkeeper "github.com/cosmos/cosmos-sdk/x/gov/keeper"
   	groupkeeper "github.com/cosmos/cosmos-sdk/x/group/keeper"
   	mintkeeper "github.com/cosmos/cosmos-sdk/x/mint/keeper"
   	protocolpoolkeeper "github.com/cosmos/cosmos-sdk/x/protocolpool/keeper"
   	slashingkeeper "github.com/cosmos/cosmos-sdk/x/slashing/keeper"
   	stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper"
   )

   // DefaultNodeHome default home directories for the application daemon
   var DefaultNodeHome string

   var (
   	_ runtime.AppI            = (*SimApp)(nil)
   	_ servertypes.Application = (*SimApp)(nil)
   )

   // SimApp extends an ABCI application, but with most of its parameters exported.
   // They are exported for convenience in creating helper functions, as object
   // capabilities aren't needed for testing.
   type SimApp struct {
   	*runtime.App
   	legacyAmino       *codec.LegacyAmino
   	appCodec          codec.Codec
   	txConfig          client.TxConfig
   	interfaceRegistry codectypes.InterfaceRegistry

   	// essential keepers
   	AccountKeeper         authkeeper.AccountKeeper
   	BankKeeper            bankkeeper.BaseKeeper
   	StakingKeeper         *stakingkeeper.Keeper
   	SlashingKeeper        slashingkeeper.Keeper
   	MintKeeper            mintkeeper.Keeper
   	DistrKeeper           distrkeeper.Keeper
   	GovKeeper             *govkeeper.Keeper
   	UpgradeKeeper         *upgradekeeper.Keeper
   	EvidenceKeeper        evidencekeeper.Keeper
   	ConsensusParamsKeeper consensuskeeper.Keeper
   	CircuitKeeper         circuitkeeper.Keeper

   	// supplementary keepers
   	FeeGrantKeeper     feegrantkeeper.Keeper
   	GroupKeeper        groupkeeper.Keeper
   	AuthzKeeper        authzkeeper.Keeper
   	NFTKeeper          nftkeeper.Keeper
   	EpochsKeeper       epochskeeper.Keeper
   	ProtocolPoolKeeper protocolpoolkeeper.Keeper

   	// simulation manager
   	sm *module.SimulationManager
   }

   func init() {
       var err error
   	DefaultNodeHome, err = clienthelpers.GetNodeHomeDirectory(".simapp")
       if err != nil {
       panic(err)
   }
   }

   // NewSimApp returns a reference to an initialized SimApp.
   func NewSimApp(
   	logger log.Logger,
   	db dbm.DB,
   	traceStore io.Writer,
   	loadLatest bool,
   	appOpts servertypes.AppOptions,
   	baseAppOptions ...func(*baseapp.BaseApp),
   ) *SimApp {
       var (
   		app        = &SimApp{
   }

   appBuilder *runtime.AppBuilder

   		// merge the AppConfig and other configuration in one config
   		appConfig = depinject.Configs(
   			AppConfig,
   			depinject.Supply(
   				// supply the application options
   				appOpts,
   				// supply the logger
   				logger,

   				// ADVANCED CONFIGURATION

   				//
   				// AUTH
   				//
   				// For providing a custom function required in auth to generate custom account types
   				// add it below. By default the auth module uses simulation.RandomGenesisAccounts.
   				//
   				// authtypes.RandomGenesisAccountsFn(simulation.RandomGenesisAccounts),
   				//
   				// For providing a custom a base account type add it below.
   				// By default the auth module uses authtypes.ProtoBaseAccount().
   				//
   				// func()

   sdk.AccountI {
       return authtypes.ProtoBaseAccount()
   },
   				//
   				// For providing a different address codec, add it below.
   				// By default the auth module uses a Bech32 address codec,
   				// with the prefix defined in the auth module configuration.
   				//
   				// func()

   address.Codec {
       return <- custom address codec type ->
   }

   				//
   				// STAKING
   				//
   				// For providing a different validator and consensus address codec, add it below.
   				// By default the staking module uses the bech32 prefix provided in the auth config,
   				// and appends "valoper" and "valcons" for validator and consensus addresses respectively.
   				// When providing a custom address codec in auth, custom address codecs must be provided here as well.
   				//
   				// func()

   runtime.ValidatorAddressCodec {
       return <- custom validator address codec type ->
   }
   				// func()

   runtime.ConsensusAddressCodec {
       return <- custom consensus address codec type ->
   }

   				//
   				// MINT
   				//

   				// For providing a custom inflation function for x/mint add here your
   				// custom function that implements the minttypes.InflationCalculationFn
   				// interface.
   			),
   		)
   	)
       if err := depinject.Inject(appConfig,
   		&appBuilder,
   		&app.appCodec,
   		&app.legacyAmino,
   		&app.txConfig,
   		&app.interfaceRegistry,
   		&app.AccountKeeper,
   		&app.BankKeeper,
   		&app.StakingKeeper,
   		&app.SlashingKeeper,
   		&app.MintKeeper,
   		&app.DistrKeeper,
   		&app.GovKeeper,
   		&app.UpgradeKeeper,
   		&app.AuthzKeeper,
   		&app.EvidenceKeeper,
   		&app.FeeGrantKeeper,
   		&app.GroupKeeper,
   		&app.NFTKeeper,
   		&app.ConsensusParamsKeeper,
   		&app.CircuitKeeper,
   		&app.EpochsKeeper,
   		&app.ProtocolPoolKeeper,
   	); err != nil {
       panic(err)
   }

   	// Below we could construct and set an application specific mempool and
   	// ABCI 1.0 PrepareProposal and ProcessProposal handlers. These defaults are
   	// already set in the SDK's BaseApp, this shows an example of how to override
   	// them.
   	//
   	// Example:
   	//
   	// app.App = appBuilder.Build(...)
   	// nonceMempool := mempool.NewSenderNonceMempool()
   	// abciPropHandler := NewDefaultProposalHandler(nonceMempool, app.App.BaseApp)
   	//
   	// app.App.BaseApp.SetMempool(nonceMempool)
   	// app.App.BaseApp.SetPrepareProposal(abciPropHandler.PrepareProposalHandler())
   	// app.App.BaseApp.SetProcessProposal(abciPropHandler.ProcessProposalHandler())
   	//
   	// Alternatively, you can construct BaseApp options, append those to
   	// baseAppOptions and pass them to the appBuilder.
   	//
   	// Example:
   	//
   	// prepareOpt = func(app *baseapp.BaseApp) {
   	// 	abciPropHandler := baseapp.NewDefaultProposalHandler(nonceMempool, app)
   	// 	app.SetPrepareProposal(abciPropHandler.PrepareProposalHandler())
   	//
   }
   	// baseAppOptions = append(baseAppOptions, prepareOpt)

   	// create and set dummy vote extension handler
       voteExtOp := func(bApp *baseapp.BaseApp) {
       voteExtHandler := NewVoteExtensionHandler()

   voteExtHandler.SetHandlers(bApp)
   }

   baseAppOptions = append(baseAppOptions, voteExtOp, baseapp.SetOptimisticExecution())

   app.App = appBuilder.Build(db, traceStore, baseAppOptions...)

   	// register streaming services
       if err := app.RegisterStreamingServices(appOpts, app.kvStoreKeys()); err != nil {
       panic(err)
   }

   	/****  Module Options ****/

   	// RegisterUpgradeHandlers is used for registering any on-chain upgrades.
   	app.RegisterUpgradeHandlers()

   	// add test gRPC service for testing gRPC queries in isolation
   	testdata_pulsar.RegisterQueryServer(app.GRPCQueryRouter(), testdata_pulsar.QueryImpl{
   })

   	// create the simulation manager and define the order of the modules for deterministic simulations
   	//
   	// NOTE: this is not required apps that don't use the simulator for fuzz testing
   	// transactions
       overrideModules := map[string]module.AppModuleSimulation{
       authtypes.ModuleName: auth.NewAppModule(app.appCodec, app.AccountKeeper, authsims.RandomGenesisAccounts, nil),
   }

   app.sm = module.NewSimulationManagerFromAppModules(app.ModuleManager.Modules, overrideModules)

   app.sm.RegisterStoreDecoders()

   	// A custom InitChainer can be set if extra pre-init-genesis logic is required.
   	// By default, when using app wiring enabled module, this is not required.
   	// For instance, the upgrade module will set automatically the module version map in its init genesis thanks to app wiring.
   	// However, when registering a module manually (i.e. that does not support app wiring), the module version map
   	// must be set manually as follow. The upgrade module will de-duplicate the module version map.
   	//
   	// app.SetInitChainer(func(ctx sdk.Context, req *abci.RequestInitChain) (*abci.ResponseInitChain, error) {
   	// 	app.UpgradeKeeper.SetModuleVersionMap(ctx, app.ModuleManager.GetVersionMap())
   	// 	return app.App.InitChainer(ctx, req)
   	//
   })

   	// set custom ante handler
   	app.setAnteHandler(app.txConfig)
       if err := app.Load(loadLatest); err != nil {
       panic(err)
   }

   return app
   }

   // setAnteHandler sets custom ante handlers.
   // "x/auth/tx" pre-defined ante handler have been disabled in app_config.
   func (app *SimApp)

   setAnteHandler(txConfig client.TxConfig) {
       anteHandler, err := NewAnteHandler(
   		HandlerOptions{
       ante.HandlerOptions{
       UnorderedNonceManager: app.AccountKeeper,
       AccountKeeper:         app.AccountKeeper,
       BankKeeper:            app.BankKeeper,
       SignModeHandler:       txConfig.SignModeHandler(),
       FeegrantKeeper:        app.FeeGrantKeeper,
       SigGasConsumer:        ante.DefaultSigVerificationGasConsumer,
   },
   			&app.CircuitKeeper,
   },
   	)
       if err != nil {
       panic(err)
   }

   	// Set the AnteHandler for the app
   	app.SetAnteHandler(anteHandler)
   }

   // LegacyAmino returns SimApp's amino codec.
   //
   // NOTE: This is solely to be used for testing purposes as it may be desirable
   // for modules to register their own custom testing types.
   func (app *SimApp)

   LegacyAmino() *codec.LegacyAmino {
       return app.legacyAmino
   }

   // AppCodec returns SimApp's app codec.
   //
   // NOTE: This is solely to be used for testing purposes as it may be desirable
   // for modules to register their own custom testing types.
   func (app *SimApp)

   AppCodec()

   codec.Codec {
       return app.appCodec
   }

   // InterfaceRegistry returns SimApp's InterfaceRegistry.
   func (app *SimApp)

   InterfaceRegistry()

   codectypes.InterfaceRegistry {
       return app.interfaceRegistry
   }

   // TxConfig returns SimApp's TxConfig
   func (app *SimApp)

   TxConfig()

   client.TxConfig {
       return app.txConfig
   }

   // GetKey returns the KVStoreKey for the provided store key.
   //
   // NOTE: This is solely to be used for testing purposes.
   func (app *SimApp)

   GetKey(storeKey string) *storetypes.KVStoreKey {
       sk := app.UnsafeFindStoreKey(storeKey)

   kvStoreKey, ok := sk.(*storetypes.KVStoreKey)
       if !ok {
       return nil
   }

   return kvStoreKey
   }

   func (app *SimApp)

   kvStoreKeys()

   map[string]*storetypes.KVStoreKey {
       keys := make(map[string]*storetypes.KVStoreKey)
       for _, k := range app.GetStoreKeys() {
       if kv, ok := k.(*storetypes.KVStoreKey); ok {
       keys[kv.Name()] = kv
   }
   	
   }

   return keys
   }

   // SimulationManager implements the SimulationApp interface
   func (app *SimApp)

   SimulationManager() *module.SimulationManager {
       return app.sm
   }

   // RegisterAPIRoutes registers all application module routes with the provided
   // API server.
   func (app *SimApp)

   RegisterAPIRoutes(apiSvr *api.Server, apiConfig config.APIConfig) {
       app.App.RegisterAPIRoutes(apiSvr, apiConfig)
   	// register swagger API in app.go so that other applications can override easily
       if err := server.RegisterSwaggerAPI(apiSvr.ClientCtx, apiSvr.Router, apiConfig.Swagger); err != nil {
       panic(err)
   }
   }

   // GetMaccPerms returns a copy of the module account permissions
   //
   // NOTE: This is solely to be used for testing purposes.
   func GetMaccPerms()

   map[string][]string {
       dup := make(map[string][]string)
       for _, perms := range moduleAccPerms {
       dup[perms.Account] = perms.Permissions
   }

   return dup
   }

   // BlockedAddresses returns all the app's blocked account addresses.
   func BlockedAddresses()

   map[string]bool {
       result := make(map[string]bool)
       if len(blockAccAddrs) > 0 {
       for _, addr := range blockAccAddrs {
       result[addr] = true
   }
   	
   }

   else {
       for addr := range GetMaccPerms() {
       result[addr] = true
   }
   	
   }

   return result
   }
   ```

2. Configure the `runtime` module:

   In this configuration, the order at which the modules are defined in PreBlockers, BeginBlocks, and EndBlockers is important.
   They are named in the order they should be executed by the module manager.

   ```go expandable theme={"theme":{"light":"github-light-high-contrast","dark":"github-dark-high-contrast"}}
   package simapp

   import (
       
   	"time"
       "google.golang.org/protobuf/types/known/durationpb"

   	runtimev1alpha1 "cosmossdk.io/api/cosmos/app/runtime/v1alpha1"
   	appv1alpha1 "cosmossdk.io/api/cosmos/app/v1alpha1"
   	authmodulev1 "cosmossdk.io/api/cosmos/auth/module/v1"
   	authzmodulev1 "cosmossdk.io/api/cosmos/authz/module/v1"
   	bankmodulev1 "cosmossdk.io/api/cosmos/bank/module/v1"
   	circuitmodulev1 "cosmossdk.io/api/cosmos/circuit/module/v1"
   	consensusmodulev1 "cosmossdk.io/api/cosmos/consensus/module/v1"
   	distrmodulev1 "cosmossdk.io/api/cosmos/distribution/module/v1"
   	epochsmodulev1 "cosmossdk.io/api/cosmos/epochs/module/v1"
   	evidencemodulev1 "cosmossdk.io/api/cosmos/evidence/module/v1"
   	feegrantmodulev1 "cosmossdk.io/api/cosmos/feegrant/module/v1"
   	genutilmodulev1 "cosmossdk.io/api/cosmos/genutil/module/v1"
   	govmodulev1 "cosmossdk.io/api/cosmos/gov/module/v1"
   	groupmodulev1 "cosmossdk.io/api/cosmos/group/module/v1"
   	mintmodulev1 "cosmossdk.io/api/cosmos/mint/module/v1"
   	nftmodulev1 "cosmossdk.io/api/cosmos/nft/module/v1"
   	protocolpoolmodulev1 "cosmossdk.io/api/cosmos/protocolpool/module/v1"
   	slashingmodulev1 "cosmossdk.io/api/cosmos/slashing/module/v1"
   	stakingmodulev1 "cosmossdk.io/api/cosmos/staking/module/v1"
   	txconfigv1 "cosmossdk.io/api/cosmos/tx/config/v1"
   	upgrademodulev1 "cosmossdk.io/api/cosmos/upgrade/module/v1"
   	vestingmodulev1 "cosmossdk.io/api/cosmos/vesting/module/v1"
       "cosmossdk.io/core/appconfig"
       "cosmossdk.io/depinject"
   	_ "cosmossdk.io/x/circuit" // import for side-effects
   	circuittypes "cosmossdk.io/x/circuit/types"
   	_ "cosmossdk.io/x/evidence" // import for side-effects
   	evidencetypes "cosmossdk.io/x/evidence/types"
       "cosmossdk.io/x/feegrant"
   	_ "cosmossdk.io/x/feegrant/module" // import for side-effects
   	"cosmossdk.io/x/nft"
   	_ "cosmossdk.io/x/nft/module" // import for side-effects
   	_ "cosmossdk.io/x/upgrade"    // import for side-effects
   	upgradetypes "cosmossdk.io/x/upgrade/types"
       "github.com/cosmos/cosmos-sdk/runtime"
       "github.com/cosmos/cosmos-sdk/types/module"
   	_ "github.com/cosmos/cosmos-sdk/x/auth/tx/config" // import for side-effects
   	authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
   	_ "github.com/cosmos/cosmos-sdk/x/auth/vesting" // import for side-effects
   	vestingtypes "github.com/cosmos/cosmos-sdk/x/auth/vesting/types"
       "github.com/cosmos/cosmos-sdk/x/authz"
   	_ "github.com/cosmos/cosmos-sdk/x/authz/module" // import for side-effects
   	_ "github.com/cosmos/cosmos-sdk/x/bank"         // import for side-effects
   	banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
   	_ "github.com/cosmos/cosmos-sdk/x/consensus" // import for side-effects
   	consensustypes "github.com/cosmos/cosmos-sdk/x/consensus/types"
   	_ "github.com/cosmos/cosmos-sdk/x/distribution" // import for side-effects
   	distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types"
   	_ "github.com/cosmos/cosmos-sdk/x/epochs" // import for side-effects
   	epochstypes "github.com/cosmos/cosmos-sdk/x/epochs/types"
       "github.com/cosmos/cosmos-sdk/x/genutil"
   	genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types"
       "github.com/cosmos/cosmos-sdk/x/gov"
   	govclient "github.com/cosmos/cosmos-sdk/x/gov/client"
   	govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
       "github.com/cosmos/cosmos-sdk/x/group"
   	_ "github.com/cosmos/cosmos-sdk/x/group/module" // import for side-effects
   	_ "github.com/cosmos/cosmos-sdk/x/mint"         // import for side-effects
   	minttypes "github.com/cosmos/cosmos-sdk/x/mint/types"
   	_ "github.com/cosmos/cosmos-sdk/x/protocolpool" // import for side-effects
   	protocolpooltypes "github.com/cosmos/cosmos-sdk/x/protocolpool/types"
   	_ "github.com/cosmos/cosmos-sdk/x/slashing" // import for side-effects
   	slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types"
   	_ "github.com/cosmos/cosmos-sdk/x/staking" // import for side-effects
   	stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
   )

   var (
   	// module account permissions
   	moduleAccPerms = []*authmodulev1.ModuleAccountPermission{
   		{
       Account: authtypes.FeeCollectorName
   },
   		{
       Account: distrtypes.ModuleName
   },
   		{
       Account: minttypes.ModuleName,
       Permissions: []string{
       authtypes.Minter
   }},
   		{
       Account: stakingtypes.BondedPoolName,
       Permissions: []string{
       authtypes.Burner, stakingtypes.ModuleName
   }},
   		{
       Account: stakingtypes.NotBondedPoolName,
       Permissions: []string{
       authtypes.Burner, stakingtypes.ModuleName
   }},
   		{
       Account: govtypes.ModuleName,
       Permissions: []string{
       authtypes.Burner
   }},
   		{
       Account: nft.ModuleName
   },
   		{
       Account: protocolpooltypes.ModuleName
   },
   		{
       Account: protocolpooltypes.ProtocolPoolEscrowAccount
   },
   }

   	// blocked account addresses
   	blockAccAddrs = []string{
       authtypes.FeeCollectorName,
   		distrtypes.ModuleName,
   		minttypes.ModuleName,
   		stakingtypes.BondedPoolName,
   		stakingtypes.NotBondedPoolName,
   		nft.ModuleName,
   		// We allow the following module accounts to receive funds:
   		// govtypes.ModuleName
   }

   ModuleConfig = []*appv1alpha1.ModuleConfig{
   		{
       Name: runtime.ModuleName,
       Config: appconfig.WrapAny(&runtimev1alpha1.Module{
       AppName: "SimApp",
   				// NOTE: upgrade module is required to be prioritized
   				PreBlockers: []string{
       upgradetypes.ModuleName,
   					authtypes.ModuleName,
   },
   				// During begin block slashing happens after distr.BeginBlocker so that
   				// there is nothing left over in the validator fee pool, so as to keep the
   				// CanWithdrawInvariant invariant.
   				// NOTE: staking module is required if HistoricalEntries param > 0
   				BeginBlockers: []string{
       minttypes.ModuleName,
   					distrtypes.ModuleName,
   					protocolpooltypes.ModuleName,
   					slashingtypes.ModuleName,
   					evidencetypes.ModuleName,
   					stakingtypes.ModuleName,
   					authz.ModuleName,
   					epochstypes.ModuleName,
   },
       EndBlockers: []string{
       govtypes.ModuleName,
   					stakingtypes.ModuleName,
   					feegrant.ModuleName,
   					group.ModuleName,
   					protocolpooltypes.ModuleName,
   },
       OverrideStoreKeys: []*runtimev1alpha1.StoreKeyConfig{
   					{
       ModuleName: authtypes.ModuleName,
       KvStoreKey: "acc",
   },
   },
   				// NOTE: The genutils module must occur after staking so that pools are
   				// properly initialized with tokens from genesis accounts.
   				// NOTE: The genutils module must also occur after auth so that it can access the params from auth.
   				InitGenesis: []string{
       authtypes.ModuleName,
   					banktypes.ModuleName,
   					distrtypes.ModuleName,
   					stakingtypes.ModuleName,
   					slashingtypes.ModuleName,
   					govtypes.ModuleName,
   					minttypes.ModuleName,
   					genutiltypes.ModuleName,
   					evidencetypes.ModuleName,
   					authz.ModuleName,
   					feegrant.ModuleName,
   					nft.ModuleName,
   					group.ModuleName,
   					upgradetypes.ModuleName,
   					vestingtypes.ModuleName,
   					circuittypes.ModuleName,
   					epochstypes.ModuleName,
   					protocolpooltypes.ModuleName,
   },
   				// When ExportGenesis is not specified, the export genesis module order
   				// is equal to the init genesis order
   				ExportGenesis: []string{
       consensustypes.ModuleName,
   					authtypes.ModuleName,
   					protocolpooltypes.ModuleName, // Must be exported before bank
   					banktypes.ModuleName,
   					distrtypes.ModuleName,
   					stakingtypes.ModuleName,
   					slashingtypes.ModuleName,
   					govtypes.ModuleName,
   					minttypes.ModuleName,
   					genutiltypes.ModuleName,
   					evidencetypes.ModuleName,
   					authz.ModuleName,
   					feegrant.ModuleName,
   					nft.ModuleName,
   					group.ModuleName,
   					upgradetypes.ModuleName,
   					vestingtypes.ModuleName,
   					circuittypes.ModuleName,
   					epochstypes.ModuleName,
   },
   				// Uncomment if you want to set a custom migration order here.
   				// OrderMigrations: []string{
   },
   }),
   },
   		{
       Name: authtypes.ModuleName,
       Config: appconfig.WrapAny(&authmodulev1.Module{
       Bech32Prefix:             "cosmos",
       ModuleAccountPermissions: moduleAccPerms,
   				// By default modules authority is the governance module. This is configurable with the following:
   				// Authority: "group", // A custom module authority can be set using a module name
   				// Authority: "cosmos1cwwv22j5ca08ggdv9c2uky355k908694z577tv", // or a specific address
   }),
   },
   		{
       Name:   vestingtypes.ModuleName,
       Config: appconfig.WrapAny(&vestingmodulev1.Module{
   }),
   },
   		{
       Name: banktypes.ModuleName,
       Config: appconfig.WrapAny(&bankmodulev1.Module{
       BlockedModuleAccountsOverride: blockAccAddrs,
   }),
   },
   		{
       Name: stakingtypes.ModuleName,
       Config: appconfig.WrapAny(&stakingmodulev1.Module{
   				// NOTE: specifying a prefix is only necessary when using bech32 addresses
   				// If not specfied, the auth Bech32Prefix appended with "valoper" and "valcons" is used by default
   				Bech32PrefixValidator: "cosmosvaloper",
   				Bech32PrefixConsensus: "cosmosvalcons",
   }),
   },
   		{
       Name:   slashingtypes.ModuleName,
       Config: appconfig.WrapAny(&slashingmodulev1.Module{
   }),
   },
   		{
       Name: "tx",
       Config: appconfig.WrapAny(&txconfigv1.Config{
       SkipAnteHandler: true, // Enable this to skip the default antehandlers and set custom ante handlers.
   }),
   },
   		{
       Name:   genutiltypes.ModuleName,
       Config: appconfig.WrapAny(&genutilmodulev1.Module{
   }),
   },
   		{
       Name:   authz.ModuleName,
       Config: appconfig.WrapAny(&authzmodulev1.Module{
   }),
   },
   		{
       Name:   upgradetypes.ModuleName,
       Config: appconfig.WrapAny(&upgrademodulev1.Module{
   }),
   },
   		{
       Name:   distrtypes.ModuleName,
       Config: appconfig.WrapAny(&distrmodulev1.Module{
   }),
   },
   		{
       Name:   evidencetypes.ModuleName,
       Config: appconfig.WrapAny(&evidencemodulev1.Module{
   }),
   },
   		{
       Name:   minttypes.ModuleName,
       Config: appconfig.WrapAny(&mintmodulev1.Module{
   }),
   },
   		{
       Name: group.ModuleName,
       Config: appconfig.WrapAny(&groupmodulev1.Module{
       MaxExecutionPeriod: durationpb.New(time.Second * 1209600),
       MaxMetadataLen:     255,
   }),
   },
   		{
       Name:   nft.ModuleName,
       Config: appconfig.WrapAny(&nftmodulev1.Module{
   }),
   },
   		{
       Name:   feegrant.ModuleName,
       Config: appconfig.WrapAny(&feegrantmodulev1.Module{
   }),
   },
   		{
       Name:   govtypes.ModuleName,
       Config: appconfig.WrapAny(&govmodulev1.Module{
   }),
   },
   		{
       Name:   consensustypes.ModuleName,
       Config: appconfig.WrapAny(&consensusmodulev1.Module{
   }),
   },
   		{
       Name:   circuittypes.ModuleName,
       Config: appconfig.WrapAny(&circuitmodulev1.Module{
   }),
   },
   		{
       Name:   epochstypes.ModuleName,
       Config: appconfig.WrapAny(&epochsmodulev1.Module{
   }),
   },
   		{
       Name:   protocolpooltypes.ModuleName,
       Config: appconfig.WrapAny(&protocolpoolmodulev1.Module{
   }),
   },
   }

   	// AppConfig is application configuration (used by depinject)

   AppConfig = depinject.Configs(appconfig.Compose(&appv1alpha1.Config{
       Modules: ModuleConfig,
   }),
   		depinject.Supply(
   			// supply custom module basics
   			map[string]module.AppModuleBasic{
       genutiltypes.ModuleName: genutil.NewAppModuleBasic(genutiltypes.DefaultMessageValidator),
   				govtypes.ModuleName: gov.NewAppModuleBasic(
   					[]govclient.ProposalHandler{
   },
   				),
   },
   		),
   	)
   )
   ```

3. Wire the other modules:

   Next to runtime, the other (depinject-enabled) modules are wired in the `AppConfig`:

   ```go expandable theme={"theme":{"light":"github-light-high-contrast","dark":"github-dark-high-contrast"}}
   package simapp

   import (
       
   	"time"
       "google.golang.org/protobuf/types/known/durationpb"

   	runtimev1alpha1 "cosmossdk.io/api/cosmos/app/runtime/v1alpha1"
   	appv1alpha1 "cosmossdk.io/api/cosmos/app/v1alpha1"
   	authmodulev1 "cosmossdk.io/api/cosmos/auth/module/v1"
   	authzmodulev1 "cosmossdk.io/api/cosmos/authz/module/v1"
   	bankmodulev1 "cosmossdk.io/api/cosmos/bank/module/v1"
   	circuitmodulev1 "cosmossdk.io/api/cosmos/circuit/module/v1"
   	consensusmodulev1 "cosmossdk.io/api/cosmos/consensus/module/v1"
   	distrmodulev1 "cosmossdk.io/api/cosmos/distribution/module/v1"
   	epochsmodulev1 "cosmossdk.io/api/cosmos/epochs/module/v1"
   	evidencemodulev1 "cosmossdk.io/api/cosmos/evidence/module/v1"
   	feegrantmodulev1 "cosmossdk.io/api/cosmos/feegrant/module/v1"
   	genutilmodulev1 "cosmossdk.io/api/cosmos/genutil/module/v1"
   	govmodulev1 "cosmossdk.io/api/cosmos/gov/module/v1"
   	groupmodulev1 "cosmossdk.io/api/cosmos/group/module/v1"
   	mintmodulev1 "cosmossdk.io/api/cosmos/mint/module/v1"
   	nftmodulev1 "cosmossdk.io/api/cosmos/nft/module/v1"
   	protocolpoolmodulev1 "cosmossdk.io/api/cosmos/protocolpool/module/v1"
   	slashingmodulev1 "cosmossdk.io/api/cosmos/slashing/module/v1"
   	stakingmodulev1 "cosmossdk.io/api/cosmos/staking/module/v1"
   	txconfigv1 "cosmossdk.io/api/cosmos/tx/config/v1"
   	upgrademodulev1 "cosmossdk.io/api/cosmos/upgrade/module/v1"
   	vestingmodulev1 "cosmossdk.io/api/cosmos/vesting/module/v1"
       "cosmossdk.io/core/appconfig"
       "cosmossdk.io/depinject"
   	_ "cosmossdk.io/x/circuit" // import for side-effects
   	circuittypes "cosmossdk.io/x/circuit/types"
   	_ "cosmossdk.io/x/evidence" // import for side-effects
   	evidencetypes "cosmossdk.io/x/evidence/types"
       "cosmossdk.io/x/feegrant"
   	_ "cosmossdk.io/x/feegrant/module" // import for side-effects
   	"cosmossdk.io/x/nft"
   	_ "cosmossdk.io/x/nft/module" // import for side-effects
   	_ "cosmossdk.io/x/upgrade"    // import for side-effects
   	upgradetypes "cosmossdk.io/x/upgrade/types"
       "github.com/cosmos/cosmos-sdk/runtime"
       "github.com/cosmos/cosmos-sdk/types/module"
   	_ "github.com/cosmos/cosmos-sdk/x/auth/tx/config" // import for side-effects
   	authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
   	_ "github.com/cosmos/cosmos-sdk/x/auth/vesting" // import for side-effects
   	vestingtypes "github.com/cosmos/cosmos-sdk/x/auth/vesting/types"
       "github.com/cosmos/cosmos-sdk/x/authz"
   	_ "github.com/cosmos/cosmos-sdk/x/authz/module" // import for side-effects
   	_ "github.com/cosmos/cosmos-sdk/x/bank"         // import for side-effects
   	banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
   	_ "github.com/cosmos/cosmos-sdk/x/consensus" // import for side-effects
   	consensustypes "github.com/cosmos/cosmos-sdk/x/consensus/types"
   	_ "github.com/cosmos/cosmos-sdk/x/distribution" // import for side-effects
   	distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types"
   	_ "github.com/cosmos/cosmos-sdk/x/epochs" // import for side-effects
   	epochstypes "github.com/cosmos/cosmos-sdk/x/epochs/types"
       "github.com/cosmos/cosmos-sdk/x/genutil"
   	genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types"
       "github.com/cosmos/cosmos-sdk/x/gov"
   	govclient "github.com/cosmos/cosmos-sdk/x/gov/client"
   	govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
       "github.com/cosmos/cosmos-sdk/x/group"
   	_ "github.com/cosmos/cosmos-sdk/x/group/module" // import for side-effects
   	_ "github.com/cosmos/cosmos-sdk/x/mint"         // import for side-effects
   	minttypes "github.com/cosmos/cosmos-sdk/x/mint/types"
   	_ "github.com/cosmos/cosmos-sdk/x/protocolpool" // import for side-effects
   	protocolpooltypes "github.com/cosmos/cosmos-sdk/x/protocolpool/types"
   	_ "github.com/cosmos/cosmos-sdk/x/slashing" // import for side-effects
   	slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types"
   	_ "github.com/cosmos/cosmos-sdk/x/staking" // import for side-effects
   	stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
   )

   var (
   	// module account permissions
   	moduleAccPerms = []*authmodulev1.ModuleAccountPermission{
   		{
       Account: authtypes.FeeCollectorName
   },
   		{
       Account: distrtypes.ModuleName
   },
   		{
       Account: minttypes.ModuleName,
       Permissions: []string{
       authtypes.Minter
   }},
   		{
       Account: stakingtypes.BondedPoolName,
       Permissions: []string{
       authtypes.Burner, stakingtypes.ModuleName
   }},
   		{
       Account: stakingtypes.NotBondedPoolName,
       Permissions: []string{
       authtypes.Burner, stakingtypes.ModuleName
   }},
   		{
       Account: govtypes.ModuleName,
       Permissions: []string{
       authtypes.Burner
   }},
   		{
       Account: nft.ModuleName
   },
   		{
       Account: protocolpooltypes.ModuleName
   },
   		{
       Account: protocolpooltypes.ProtocolPoolEscrowAccount
   },
   }

   	// blocked account addresses
   	blockAccAddrs = []string{
       authtypes.FeeCollectorName,
   		distrtypes.ModuleName,
   		minttypes.ModuleName,
   		stakingtypes.BondedPoolName,
   		stakingtypes.NotBondedPoolName,
   		nft.ModuleName,
   		// We allow the following module accounts to receive funds:
   		// govtypes.ModuleName
   }

   ModuleConfig = []*appv1alpha1.ModuleConfig{
   		{
       Name: runtime.ModuleName,
       Config: appconfig.WrapAny(&runtimev1alpha1.Module{
       AppName: "SimApp",
   				// NOTE: upgrade module is required to be prioritized
   				PreBlockers: []string{
       upgradetypes.ModuleName,
   					authtypes.ModuleName,
   },
   				// During begin block slashing happens after distr.BeginBlocker so that
   				// there is nothing left over in the validator fee pool, so as to keep the
   				// CanWithdrawInvariant invariant.
   				// NOTE: staking module is required if HistoricalEntries param > 0
   				BeginBlockers: []string{
       minttypes.ModuleName,
   					distrtypes.ModuleName,
   					protocolpooltypes.ModuleName,
   					slashingtypes.ModuleName,
   					evidencetypes.ModuleName,
   					stakingtypes.ModuleName,
   					authz.ModuleName,
   					epochstypes.ModuleName,
   },
       EndBlockers: []string{
       govtypes.ModuleName,
   					stakingtypes.ModuleName,
   					feegrant.ModuleName,
   					group.ModuleName,
   					protocolpooltypes.ModuleName,
   },
       OverrideStoreKeys: []*runtimev1alpha1.StoreKeyConfig{
   					{
       ModuleName: authtypes.ModuleName,
       KvStoreKey: "acc",
   },
   },
   				// NOTE: The genutils module must occur after staking so that pools are
   				// properly initialized with tokens from genesis accounts.
   				// NOTE: The genutils module must also occur after auth so that it can access the params from auth.
   				InitGenesis: []string{
       authtypes.ModuleName,
   					banktypes.ModuleName,
   					distrtypes.ModuleName,
   					stakingtypes.ModuleName,
   					slashingtypes.ModuleName,
   					govtypes.ModuleName,
   					minttypes.ModuleName,
   					genutiltypes.ModuleName,
   					evidencetypes.ModuleName,
   					authz.ModuleName,
   					feegrant.ModuleName,
   					nft.ModuleName,
   					group.ModuleName,
   					upgradetypes.ModuleName,
   					vestingtypes.ModuleName,
   					circuittypes.ModuleName,
   					epochstypes.ModuleName,
   					protocolpooltypes.ModuleName,
   },
   				// When ExportGenesis is not specified, the export genesis module order
   				// is equal to the init genesis order
   				ExportGenesis: []string{
       consensustypes.ModuleName,
   					authtypes.ModuleName,
   					protocolpooltypes.ModuleName, // Must be exported before bank
   					banktypes.ModuleName,
   					distrtypes.ModuleName,
   					stakingtypes.ModuleName,
   					slashingtypes.ModuleName,
   					govtypes.ModuleName,
   					minttypes.ModuleName,
   					genutiltypes.ModuleName,
   					evidencetypes.ModuleName,
   					authz.ModuleName,
   					feegrant.ModuleName,
   					nft.ModuleName,
   					group.ModuleName,
   					upgradetypes.ModuleName,
   					vestingtypes.ModuleName,
   					circuittypes.ModuleName,
   					epochstypes.ModuleName,
   },
   				// Uncomment if you want to set a custom migration order here.
   				// OrderMigrations: []string{
   },
   }),
   },
   		{
       Name: authtypes.ModuleName,
       Config: appconfig.WrapAny(&authmodulev1.Module{
       Bech32Prefix:             "cosmos",
       ModuleAccountPermissions: moduleAccPerms,
   				// By default modules authority is the governance module. This is configurable with the following:
   				// Authority: "group", // A custom module authority can be set using a module name
   				// Authority: "cosmos1cwwv22j5ca08ggdv9c2uky355k908694z577tv", // or a specific address
   }),
   },
   		{
       Name:   vestingtypes.ModuleName,
       Config: appconfig.WrapAny(&vestingmodulev1.Module{
   }),
   },
   		{
       Name: banktypes.ModuleName,
       Config: appconfig.WrapAny(&bankmodulev1.Module{
       BlockedModuleAccountsOverride: blockAccAddrs,
   }),
   },
   		{
       Name: stakingtypes.ModuleName,
       Config: appconfig.WrapAny(&stakingmodulev1.Module{
   				// NOTE: specifying a prefix is only necessary when using bech32 addresses
   				// If not specfied, the auth Bech32Prefix appended with "valoper" and "valcons" is used by default
   				Bech32PrefixValidator: "cosmosvaloper",
   				Bech32PrefixConsensus: "cosmosvalcons",
   }),
   },
   		{
       Name:   slashingtypes.ModuleName,
       Config: appconfig.WrapAny(&slashingmodulev1.Module{
   }),
   },
   		{
       Name: "tx",
       Config: appconfig.WrapAny(&txconfigv1.Config{
       SkipAnteHandler: true, // Enable this to skip the default antehandlers and set custom ante handlers.
   }),
   },
   		{
       Name:   genutiltypes.ModuleName,
       Config: appconfig.WrapAny(&genutilmodulev1.Module{
   }),
   },
   		{
       Name:   authz.ModuleName,
       Config: appconfig.WrapAny(&authzmodulev1.Module{
   }),
   },
   		{
       Name:   upgradetypes.ModuleName,
       Config: appconfig.WrapAny(&upgrademodulev1.Module{
   }),
   },
   		{
       Name:   distrtypes.ModuleName,
       Config: appconfig.WrapAny(&distrmodulev1.Module{
   }),
   },
   		{
       Name:   evidencetypes.ModuleName,
       Config: appconfig.WrapAny(&evidencemodulev1.Module{
   }),
   },
   		{
       Name:   minttypes.ModuleName,
       Config: appconfig.WrapAny(&mintmodulev1.Module{
   }),
   },
   		{
       Name: group.ModuleName,
       Config: appconfig.WrapAny(&groupmodulev1.Module{
       MaxExecutionPeriod: durationpb.New(time.Second * 1209600),
       MaxMetadataLen:     255,
   }),
   },
   		{
       Name:   nft.ModuleName,
       Config: appconfig.WrapAny(&nftmodulev1.Module{
   }),
   },
   		{
       Name:   feegrant.ModuleName,
       Config: appconfig.WrapAny(&feegrantmodulev1.Module{
   }),
   },
   		{
       Name:   govtypes.ModuleName,
       Config: appconfig.WrapAny(&govmodulev1.Module{
   }),
   },
   		{
       Name:   consensustypes.ModuleName,
       Config: appconfig.WrapAny(&consensusmodulev1.Module{
   }),
   },
   		{
       Name:   circuittypes.ModuleName,
       Config: appconfig.WrapAny(&circuitmodulev1.Module{
   }),
   },
   		{
       Name:   epochstypes.ModuleName,
       Config: appconfig.WrapAny(&epochsmodulev1.Module{
   }),
   },
   		{
       Name:   protocolpooltypes.ModuleName,
       Config: appconfig.WrapAny(&protocolpoolmodulev1.Module{
   }),
   },
   }

   	// AppConfig is application configuration (used by depinject)

   AppConfig = depinject.Configs(appconfig.Compose(&appv1alpha1.Config{
       Modules: ModuleConfig,
   }),
   		depinject.Supply(
   			// supply custom module basics
   			map[string]module.AppModuleBasic{
       genutiltypes.ModuleName: genutil.NewAppModuleBasic(genutiltypes.DefaultMessageValidator),
   				govtypes.ModuleName: gov.NewAppModuleBasic(
   					[]govclient.ProposalHandler{
   },
   				),
   },
   		),
   	)
   )
   ```

   Note: the `tx` isn't a module, but a configuration. It should be wired in the `AppConfig` as well.

   ```go expandable theme={"theme":{"light":"github-light-high-contrast","dark":"github-dark-high-contrast"}}
   package simapp

   import (
       
   	"time"
       "google.golang.org/protobuf/types/known/durationpb"

   	runtimev1alpha1 "cosmossdk.io/api/cosmos/app/runtime/v1alpha1"
   	appv1alpha1 "cosmossdk.io/api/cosmos/app/v1alpha1"
   	authmodulev1 "cosmossdk.io/api/cosmos/auth/module/v1"
   	authzmodulev1 "cosmossdk.io/api/cosmos/authz/module/v1"
   	bankmodulev1 "cosmossdk.io/api/cosmos/bank/module/v1"
   	circuitmodulev1 "cosmossdk.io/api/cosmos/circuit/module/v1"
   	consensusmodulev1 "cosmossdk.io/api/cosmos/consensus/module/v1"
   	distrmodulev1 "cosmossdk.io/api/cosmos/distribution/module/v1"
   	epochsmodulev1 "cosmossdk.io/api/cosmos/epochs/module/v1"
   	evidencemodulev1 "cosmossdk.io/api/cosmos/evidence/module/v1"
   	feegrantmodulev1 "cosmossdk.io/api/cosmos/feegrant/module/v1"
   	genutilmodulev1 "cosmossdk.io/api/cosmos/genutil/module/v1"
   	govmodulev1 "cosmossdk.io/api/cosmos/gov/module/v1"
   	groupmodulev1 "cosmossdk.io/api/cosmos/group/module/v1"
   	mintmodulev1 "cosmossdk.io/api/cosmos/mint/module/v1"
   	nftmodulev1 "cosmossdk.io/api/cosmos/nft/module/v1"
   	protocolpoolmodulev1 "cosmossdk.io/api/cosmos/protocolpool/module/v1"
   	slashingmodulev1 "cosmossdk.io/api/cosmos/slashing/module/v1"
   	stakingmodulev1 "cosmossdk.io/api/cosmos/staking/module/v1"
   	txconfigv1 "cosmossdk.io/api/cosmos/tx/config/v1"
   	upgrademodulev1 "cosmossdk.io/api/cosmos/upgrade/module/v1"
   	vestingmodulev1 "cosmossdk.io/api/cosmos/vesting/module/v1"
       "cosmossdk.io/core/appconfig"
       "cosmossdk.io/depinject"
   	_ "cosmossdk.io/x/circuit" // import for side-effects
   	circuittypes "cosmossdk.io/x/circuit/types"
   	_ "cosmossdk.io/x/evidence" // import for side-effects
   	evidencetypes "cosmossdk.io/x/evidence/types"
       "cosmossdk.io/x/feegrant"
   	_ "cosmossdk.io/x/feegrant/module" // import for side-effects
   	"cosmossdk.io/x/nft"
   	_ "cosmossdk.io/x/nft/module" // import for side-effects
   	_ "cosmossdk.io/x/upgrade"    // import for side-effects
   	upgradetypes "cosmossdk.io/x/upgrade/types"
       "github.com/cosmos/cosmos-sdk/runtime"
       "github.com/cosmos/cosmos-sdk/types/module"
   	_ "github.com/cosmos/cosmos-sdk/x/auth/tx/config" // import for side-effects
   	authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
   	_ "github.com/cosmos/cosmos-sdk/x/auth/vesting" // import for side-effects
   	vestingtypes "github.com/cosmos/cosmos-sdk/x/auth/vesting/types"
       "github.com/cosmos/cosmos-sdk/x/authz"
   	_ "github.com/cosmos/cosmos-sdk/x/authz/module" // import for side-effects
   	_ "github.com/cosmos/cosmos-sdk/x/bank"         // import for side-effects
   	banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
   	_ "github.com/cosmos/cosmos-sdk/x/consensus" // import for side-effects
   	consensustypes "github.com/cosmos/cosmos-sdk/x/consensus/types"
   	_ "github.com/cosmos/cosmos-sdk/x/distribution" // import for side-effects
   	distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types"
   	_ "github.com/cosmos/cosmos-sdk/x/epochs" // import for side-effects
   	epochstypes "github.com/cosmos/cosmos-sdk/x/epochs/types"
       "github.com/cosmos/cosmos-sdk/x/genutil"
   	genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types"
       "github.com/cosmos/cosmos-sdk/x/gov"
   	govclient "github.com/cosmos/cosmos-sdk/x/gov/client"
   	govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
       "github.com/cosmos/cosmos-sdk/x/group"
   	_ "github.com/cosmos/cosmos-sdk/x/group/module" // import for side-effects
   	_ "github.com/cosmos/cosmos-sdk/x/mint"         // import for side-effects
   	minttypes "github.com/cosmos/cosmos-sdk/x/mint/types"
   	_ "github.com/cosmos/cosmos-sdk/x/protocolpool" // import for side-effects
   	protocolpooltypes "github.com/cosmos/cosmos-sdk/x/protocolpool/types"
   	_ "github.com/cosmos/cosmos-sdk/x/slashing" // import for side-effects
   	slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types"
   	_ "github.com/cosmos/cosmos-sdk/x/staking" // import for side-effects
   	stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
   )

   var (
   	// module account permissions
   	moduleAccPerms = []*authmodulev1.ModuleAccountPermission{
   		{
       Account: authtypes.FeeCollectorName
   },
   		{
       Account: distrtypes.ModuleName
   },
   		{
       Account: minttypes.ModuleName,
       Permissions: []string{
       authtypes.Minter
   }},
   		{
       Account: stakingtypes.BondedPoolName,
       Permissions: []string{
       authtypes.Burner, stakingtypes.ModuleName
   }},
   		{
       Account: stakingtypes.NotBondedPoolName,
       Permissions: []string{
       authtypes.Burner, stakingtypes.ModuleName
   }},
   		{
       Account: govtypes.ModuleName,
       Permissions: []string{
       authtypes.Burner
   }},
   		{
       Account: nft.ModuleName
   },
   		{
       Account: protocolpooltypes.ModuleName
   },
   		{
       Account: protocolpooltypes.ProtocolPoolEscrowAccount
   },
   }

   	// blocked account addresses
   	blockAccAddrs = []string{
       authtypes.FeeCollectorName,
   		distrtypes.ModuleName,
   		minttypes.ModuleName,
   		stakingtypes.BondedPoolName,
   		stakingtypes.NotBondedPoolName,
   		nft.ModuleName,
   		// We allow the following module accounts to receive funds:
   		// govtypes.ModuleName
   }

   ModuleConfig = []*appv1alpha1.ModuleConfig{
   		{
       Name: runtime.ModuleName,
       Config: appconfig.WrapAny(&runtimev1alpha1.Module{
       AppName: "SimApp",
   				// NOTE: upgrade module is required to be prioritized
   				PreBlockers: []string{
       upgradetypes.ModuleName,
   					authtypes.ModuleName,
   },
   				// During begin block slashing happens after distr.BeginBlocker so that
   				// there is nothing left over in the validator fee pool, so as to keep the
   				// CanWithdrawInvariant invariant.
   				// NOTE: staking module is required if HistoricalEntries param > 0
   				BeginBlockers: []string{
       minttypes.ModuleName,
   					distrtypes.ModuleName,
   					protocolpooltypes.ModuleName,
   					slashingtypes.ModuleName,
   					evidencetypes.ModuleName,
   					stakingtypes.ModuleName,
   					authz.ModuleName,
   					epochstypes.ModuleName,
   },
       EndBlockers: []string{
       govtypes.ModuleName,
   					stakingtypes.ModuleName,
   					feegrant.ModuleName,
   					group.ModuleName,
   					protocolpooltypes.ModuleName,
   },
       OverrideStoreKeys: []*runtimev1alpha1.StoreKeyConfig{
   					{
       ModuleName: authtypes.ModuleName,
       KvStoreKey: "acc",
   },
   },
   				// NOTE: The genutils module must occur after staking so that pools are
   				// properly initialized with tokens from genesis accounts.
   				// NOTE: The genutils module must also occur after auth so that it can access the params from auth.
   				InitGenesis: []string{
       authtypes.ModuleName,
   					banktypes.ModuleName,
   					distrtypes.ModuleName,
   					stakingtypes.ModuleName,
   					slashingtypes.ModuleName,
   					govtypes.ModuleName,
   					minttypes.ModuleName,
   					genutiltypes.ModuleName,
   					evidencetypes.ModuleName,
   					authz.ModuleName,
   					feegrant.ModuleName,
   					nft.ModuleName,
   					group.ModuleName,
   					upgradetypes.ModuleName,
   					vestingtypes.ModuleName,
   					circuittypes.ModuleName,
   					epochstypes.ModuleName,
   					protocolpooltypes.ModuleName,
   },
   				// When ExportGenesis is not specified, the export genesis module order
   				// is equal to the init genesis order
   				ExportGenesis: []string{
       consensustypes.ModuleName,
   					authtypes.ModuleName,
   					protocolpooltypes.ModuleName, // Must be exported before bank
   					banktypes.ModuleName,
   					distrtypes.ModuleName,
   					stakingtypes.ModuleName,
   					slashingtypes.ModuleName,
   					govtypes.ModuleName,
   					minttypes.ModuleName,
   					genutiltypes.ModuleName,
   					evidencetypes.ModuleName,
   					authz.ModuleName,
   					feegrant.ModuleName,
   					nft.ModuleName,
   					group.ModuleName,
   					upgradetypes.ModuleName,
   					vestingtypes.ModuleName,
   					circuittypes.ModuleName,
   					epochstypes.ModuleName,
   },
   				// Uncomment if you want to set a custom migration order here.
   				// OrderMigrations: []string{
   },
   }),
   },
   		{
       Name: authtypes.ModuleName,
       Config: appconfig.WrapAny(&authmodulev1.Module{
       Bech32Prefix:             "cosmos",
       ModuleAccountPermissions: moduleAccPerms,
   				// By default modules authority is the governance module. This is configurable with the following:
   				// Authority: "group", // A custom module authority can be set using a module name
   				// Authority: "cosmos1cwwv22j5ca08ggdv9c2uky355k908694z577tv", // or a specific address
   }),
   },
   		{
       Name:   vestingtypes.ModuleName,
       Config: appconfig.WrapAny(&vestingmodulev1.Module{
   }),
   },
   		{
       Name: banktypes.ModuleName,
       Config: appconfig.WrapAny(&bankmodulev1.Module{
       BlockedModuleAccountsOverride: blockAccAddrs,
   }),
   },
   		{
       Name: stakingtypes.ModuleName,
       Config: appconfig.WrapAny(&stakingmodulev1.Module{
   				// NOTE: specifying a prefix is only necessary when using bech32 addresses
   				// If not specfied, the auth Bech32Prefix appended with "valoper" and "valcons" is used by default
   				Bech32PrefixValidator: "cosmosvaloper",
   				Bech32PrefixConsensus: "cosmosvalcons",
   }),
   },
   		{
       Name:   slashingtypes.ModuleName,
       Config: appconfig.WrapAny(&slashingmodulev1.Module{
   }),
   },
   		{
       Name: "tx",
       Config: appconfig.WrapAny(&txconfigv1.Config{
       SkipAnteHandler: true, // Enable this to skip the default antehandlers and set custom ante handlers.
   }),
   },
   		{
       Name:   genutiltypes.ModuleName,
       Config: appconfig.WrapAny(&genutilmodulev1.Module{
   }),
   },
   		{
       Name:   authz.ModuleName,
       Config: appconfig.WrapAny(&authzmodulev1.Module{
   }),
   },
   		{
       Name:   upgradetypes.ModuleName,
       Config: appconfig.WrapAny(&upgrademodulev1.Module{
   }),
   },
   		{
       Name:   distrtypes.ModuleName,
       Config: appconfig.WrapAny(&distrmodulev1.Module{
   }),
   },
   		{
       Name:   evidencetypes.ModuleName,
       Config: appconfig.WrapAny(&evidencemodulev1.Module{
   }),
   },
   		{
       Name:   minttypes.ModuleName,
       Config: appconfig.WrapAny(&mintmodulev1.Module{
   }),
   },
   		{
       Name: group.ModuleName,
       Config: appconfig.WrapAny(&groupmodulev1.Module{
       MaxExecutionPeriod: durationpb.New(time.Second * 1209600),
       MaxMetadataLen:     255,
   }),
   },
   		{
       Name:   nft.ModuleName,
       Config: appconfig.WrapAny(&nftmodulev1.Module{
   }),
   },
   		{
       Name:   feegrant.ModuleName,
       Config: appconfig.WrapAny(&feegrantmodulev1.Module{
   }),
   },
   		{
       Name:   govtypes.ModuleName,
       Config: appconfig.WrapAny(&govmodulev1.Module{
   }),
   },
   		{
       Name:   consensustypes.ModuleName,
       Config: appconfig.WrapAny(&consensusmodulev1.Module{
   }),
   },
   		{
       Name:   circuittypes.ModuleName,
       Config: appconfig.WrapAny(&circuitmodulev1.Module{
   }),
   },
   		{
       Name:   epochstypes.ModuleName,
       Config: appconfig.WrapAny(&epochsmodulev1.Module{
   }),
   },
   		{
       Name:   protocolpooltypes.ModuleName,
       Config: appconfig.WrapAny(&protocolpoolmodulev1.Module{
   }),
   },
   }

   	// AppConfig is application configuration (used by depinject)

   AppConfig = depinject.Configs(appconfig.Compose(&appv1alpha1.Config{
       Modules: ModuleConfig,
   }),
   		depinject.Supply(
   			// supply custom module basics
   			map[string]module.AppModuleBasic{
       genutiltypes.ModuleName: genutil.NewAppModuleBasic(genutiltypes.DefaultMessageValidator),
   				govtypes.ModuleName: gov.NewAppModuleBasic(
   					[]govclient.ProposalHandler{
   },
   				),
   },
   		),
   	)
   )
   ```

See the complete `app_config.go` file for `SimApp` [here](https://github.com/cosmos/cosmos-sdk/blob/v0.53.0-rc.2/simapp/app_config.go).

### Alternative formats

<Tip>
  The example above shows how to create an `AppConfig` using Go. However, it is also possible to create an `AppConfig` using YAML, or JSON.\
  The configuration can then be embed with `go:embed` and read with [`appconfig.LoadYAML`](https://pkg.go.dev/cosmossdk.io/core/appconfig#LoadYAML), or [`appconfig.LoadJSON`](https://pkg.go.dev/cosmossdk.io/core/appconfig#LoadJSON), in `app_di.go`.

  ```go theme={"theme":{"light":"github-light-high-contrast","dark":"github-dark-high-contrast"}}
  //go:embed app_config.yaml
  var (
      appConfigYaml []byte
      appConfig = appconfig.LoadYAML(appConfigYaml)
  )
  ```
</Tip>

```yaml expandable theme={"theme":{"light":"github-light-high-contrast","dark":"github-dark-high-contrast"}}
modules:
  - name: runtime
    config:
      "@type": cosmos.app.runtime.v1alpha1.Module
      app_name: SimApp
      begin_blockers: [staking, auth, bank]
      end_blockers: [bank, auth, staking]
      init_genesis: [bank, auth, staking]
  - name: auth
    config:
      "@type": cosmos.auth.module.v1.Module
      bech32_prefix: cosmos
  - name: bank
    config:
      "@type": cosmos.bank.module.v1.Module
  - name: staking
    config:
      "@type": cosmos.staking.module.v1.Module
  - name: tx
    config:
      "@type": cosmos.tx.module.v1.Module
```

A more complete example of `app.yaml` can be found [here](https://github.com/cosmos/cosmos-sdk/blob/release/v0.53.x/simapp/example_app.yaml).

## `app_di.go`

`app_di.go` is the place where `SimApp` is constructed. `depinject.Inject` automatically wires the app modules and keepers when provided with an application configuration (`AppConfig`). `SimApp` is constructed upon calling the injected `*runtime.AppBuilder` with `appBuilder.Build(...)`.\
In short `depinject` and the [`runtime` package](/sdk/v0.53/build/building-apps/runtime) abstract the wiring of the app, and the `AppBuilder` is the place where the app is constructed. [`runtime`](/sdk/v0.53/build/building-apps/runtime) takes care of registering the codecs, KV store, subspaces and instantiating `baseapp`.

```go expandable theme={"theme":{"light":"github-light-high-contrast","dark":"github-dark-high-contrast"}}
//go:build !app_v1

package simapp

import (
    
	"io"

	dbm "github.com/cosmos/cosmos-db"

	clienthelpers "cosmossdk.io/client/v2/helpers"
    "cosmossdk.io/depinject"
    "cosmossdk.io/log"
	storetypes "cosmossdk.io/store/types"
	circuitkeeper "cosmossdk.io/x/circuit/keeper"
	evidencekeeper "cosmossdk.io/x/evidence/keeper"
	feegrantkeeper "cosmossdk.io/x/feegrant/keeper"
	nftkeeper "cosmossdk.io/x/nft/keeper"
	upgradekeeper "cosmossdk.io/x/upgrade/keeper"
    "github.com/cosmos/cosmos-sdk/baseapp"
    "github.com/cosmos/cosmos-sdk/client"
    "github.com/cosmos/cosmos-sdk/codec"
	codectypes "github.com/cosmos/cosmos-sdk/codec/types"
    "github.com/cosmos/cosmos-sdk/runtime"
    "github.com/cosmos/cosmos-sdk/server"
    "github.com/cosmos/cosmos-sdk/server/api"
    "github.com/cosmos/cosmos-sdk/server/config"
	servertypes "github.com/cosmos/cosmos-sdk/server/types"
	testdata_pulsar "github.com/cosmos/cosmos-sdk/testutil/testdata/testpb"
    "github.com/cosmos/cosmos-sdk/types/module"
    "github.com/cosmos/cosmos-sdk/x/auth"
    "github.com/cosmos/cosmos-sdk/x/auth/ante"
	authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
	authsims "github.com/cosmos/cosmos-sdk/x/auth/simulation"
	authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
	authzkeeper "github.com/cosmos/cosmos-sdk/x/authz/keeper"
	bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper"
	consensuskeeper "github.com/cosmos/cosmos-sdk/x/consensus/keeper"
	distrkeeper "github.com/cosmos/cosmos-sdk/x/distribution/keeper"
	epochskeeper "github.com/cosmos/cosmos-sdk/x/epochs/keeper"
	govkeeper "github.com/cosmos/cosmos-sdk/x/gov/keeper"
	groupkeeper "github.com/cosmos/cosmos-sdk/x/group/keeper"
	mintkeeper "github.com/cosmos/cosmos-sdk/x/mint/keeper"
	protocolpoolkeeper "github.com/cosmos/cosmos-sdk/x/protocolpool/keeper"
	slashingkeeper "github.com/cosmos/cosmos-sdk/x/slashing/keeper"
	stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper"
)

// DefaultNodeHome default home directories for the application daemon
var DefaultNodeHome string

var (
	_ runtime.AppI            = (*SimApp)(nil)
	_ servertypes.Application = (*SimApp)(nil)
)

// SimApp extends an ABCI application, but with most of its parameters exported.
// They are exported for convenience in creating helper functions, as object
// capabilities aren't needed for testing.
type SimApp struct {
	*runtime.App
	legacyAmino       *codec.LegacyAmino
	appCodec          codec.Codec
	txConfig          client.TxConfig
	interfaceRegistry codectypes.InterfaceRegistry

	// essential keepers
	AccountKeeper         authkeeper.AccountKeeper
	BankKeeper            bankkeeper.BaseKeeper
	StakingKeeper         *stakingkeeper.Keeper
	SlashingKeeper        slashingkeeper.Keeper
	MintKeeper            mintkeeper.Keeper
	DistrKeeper           distrkeeper.Keeper
	GovKeeper             *govkeeper.Keeper
	UpgradeKeeper         *upgradekeeper.Keeper
	EvidenceKeeper        evidencekeeper.Keeper
	ConsensusParamsKeeper consensuskeeper.Keeper
	CircuitKeeper         circuitkeeper.Keeper

	// supplementary keepers
	FeeGrantKeeper     feegrantkeeper.Keeper
	GroupKeeper        groupkeeper.Keeper
	AuthzKeeper        authzkeeper.Keeper
	NFTKeeper          nftkeeper.Keeper
	EpochsKeeper       epochskeeper.Keeper
	ProtocolPoolKeeper protocolpoolkeeper.Keeper

	// simulation manager
	sm *module.SimulationManager
}

func init() {
    var err error
	DefaultNodeHome, err = clienthelpers.GetNodeHomeDirectory(".simapp")
    if err != nil {
    panic(err)
}
}

// NewSimApp returns a reference to an initialized SimApp.
func NewSimApp(
	logger log.Logger,
	db dbm.DB,
	traceStore io.Writer,
	loadLatest bool,
	appOpts servertypes.AppOptions,
	baseAppOptions ...func(*baseapp.BaseApp),
) *SimApp {
    var (
		app        = &SimApp{
}

appBuilder *runtime.AppBuilder

		// merge the AppConfig and other configuration in one config
		appConfig = depinject.Configs(
			AppConfig,
			depinject.Supply(
				// supply the application options
				appOpts,
				// supply the logger
				logger,

				// ADVANCED CONFIGURATION

				//
				// AUTH
				//
				// For providing a custom function required in auth to generate custom account types
				// add it below. By default the auth module uses simulation.RandomGenesisAccounts.
				//
				// authtypes.RandomGenesisAccountsFn(simulation.RandomGenesisAccounts),
				//
				// For providing a custom a base account type add it below.
				// By default the auth module uses authtypes.ProtoBaseAccount().
				//
				// func()

sdk.AccountI {
    return authtypes.ProtoBaseAccount()
},
				//
				// For providing a different address codec, add it below.
				// By default the auth module uses a Bech32 address codec,
				// with the prefix defined in the auth module configuration.
				//
				// func()

address.Codec {
    return <- custom address codec type ->
}

				//
				// STAKING
				//
				// For providing a different validator and consensus address codec, add it below.
				// By default the staking module uses the bech32 prefix provided in the auth config,
				// and appends "valoper" and "valcons" for validator and consensus addresses respectively.
				// When providing a custom address codec in auth, custom address codecs must be provided here as well.
				//
				// func()

runtime.ValidatorAddressCodec {
    return <- custom validator address codec type ->
}
				// func()

runtime.ConsensusAddressCodec {
    return <- custom consensus address codec type ->
}

				//
				// MINT
				//

				// For providing a custom inflation function for x/mint add here your
				// custom function that implements the minttypes.InflationCalculationFn
				// interface.
			),
		)
	)
    if err := depinject.Inject(appConfig,
		&appBuilder,
		&app.appCodec,
		&app.legacyAmino,
		&app.txConfig,
		&app.interfaceRegistry,
		&app.AccountKeeper,
		&app.BankKeeper,
		&app.StakingKeeper,
		&app.SlashingKeeper,
		&app.MintKeeper,
		&app.DistrKeeper,
		&app.GovKeeper,
		&app.UpgradeKeeper,
		&app.AuthzKeeper,
		&app.EvidenceKeeper,
		&app.FeeGrantKeeper,
		&app.GroupKeeper,
		&app.NFTKeeper,
		&app.ConsensusParamsKeeper,
		&app.CircuitKeeper,
		&app.EpochsKeeper,
		&app.ProtocolPoolKeeper,
	); err != nil {
    panic(err)
}

	// Below we could construct and set an application specific mempool and
	// ABCI 1.0 PrepareProposal and ProcessProposal handlers. These defaults are
	// already set in the SDK's BaseApp, this shows an example of how to override
	// them.
	//
	// Example:
	//
	// app.App = appBuilder.Build(...)
	// nonceMempool := mempool.NewSenderNonceMempool()
	// abciPropHandler := NewDefaultProposalHandler(nonceMempool, app.App.BaseApp)
	//
	// app.App.BaseApp.SetMempool(nonceMempool)
	// app.App.BaseApp.SetPrepareProposal(abciPropHandler.PrepareProposalHandler())
	// app.App.BaseApp.SetProcessProposal(abciPropHandler.ProcessProposalHandler())
	//
	// Alternatively, you can construct BaseApp options, append those to
	// baseAppOptions and pass them to the appBuilder.
	//
	// Example:
	//
	// prepareOpt = func(app *baseapp.BaseApp) {
	// 	abciPropHandler := baseapp.NewDefaultProposalHandler(nonceMempool, app)
	// 	app.SetPrepareProposal(abciPropHandler.PrepareProposalHandler())
	//
}
	// baseAppOptions = append(baseAppOptions, prepareOpt)

	// create and set dummy vote extension handler
    voteExtOp := func(bApp *baseapp.BaseApp) {
    voteExtHandler := NewVoteExtensionHandler()

voteExtHandler.SetHandlers(bApp)
}

baseAppOptions = append(baseAppOptions, voteExtOp, baseapp.SetOptimisticExecution())

app.App = appBuilder.Build(db, traceStore, baseAppOptions...)

	// register streaming services
    if err := app.RegisterStreamingServices(appOpts, app.kvStoreKeys()); err != nil {
    panic(err)
}

	/****  Module Options ****/

	// RegisterUpgradeHandlers is used for registering any on-chain upgrades.
	app.RegisterUpgradeHandlers()

	// add test gRPC service for testing gRPC queries in isolation
	testdata_pulsar.RegisterQueryServer(app.GRPCQueryRouter(), testdata_pulsar.QueryImpl{
})

	// create the simulation manager and define the order of the modules for deterministic simulations
	//
	// NOTE: this is not required apps that don't use the simulator for fuzz testing
	// transactions
    overrideModules := map[string]module.AppModuleSimulation{
    authtypes.ModuleName: auth.NewAppModule(app.appCodec, app.AccountKeeper, authsims.RandomGenesisAccounts, nil),
}

app.sm = module.NewSimulationManagerFromAppModules(app.ModuleManager.Modules, overrideModules)

app.sm.RegisterStoreDecoders()

	// A custom InitChainer can be set if extra pre-init-genesis logic is required.
	// By default, when using app wiring enabled module, this is not required.
	// For instance, the upgrade module will set automatically the module version map in its init genesis thanks to app wiring.
	// However, when registering a module manually (i.e. that does not support app wiring), the module version map
	// must be set manually as follow. The upgrade module will de-duplicate the module version map.
	//
	// app.SetInitChainer(func(ctx sdk.Context, req *abci.RequestInitChain) (*abci.ResponseInitChain, error) {
	// 	app.UpgradeKeeper.SetModuleVersionMap(ctx, app.ModuleManager.GetVersionMap())
	// 	return app.App.InitChainer(ctx, req)
	//
})

	// set custom ante handler
	app.setAnteHandler(app.txConfig)
    if err := app.Load(loadLatest); err != nil {
    panic(err)
}

return app
}

// setAnteHandler sets custom ante handlers.
// "x/auth/tx" pre-defined ante handler have been disabled in app_config.
func (app *SimApp)

setAnteHandler(txConfig client.TxConfig) {
    anteHandler, err := NewAnteHandler(
		HandlerOptions{
    ante.HandlerOptions{
    UnorderedNonceManager: app.AccountKeeper,
    AccountKeeper:         app.AccountKeeper,
    BankKeeper:            app.BankKeeper,
    SignModeHandler:       txConfig.SignModeHandler(),
    FeegrantKeeper:        app.FeeGrantKeeper,
    SigGasConsumer:        ante.DefaultSigVerificationGasConsumer,
},
			&app.CircuitKeeper,
},
	)
    if err != nil {
    panic(err)
}

	// Set the AnteHandler for the app
	app.SetAnteHandler(anteHandler)
}

// LegacyAmino returns SimApp's amino codec.
//
// NOTE: This is solely to be used for testing purposes as it may be desirable
// for modules to register their own custom testing types.
func (app *SimApp)

LegacyAmino() *codec.LegacyAmino {
    return app.legacyAmino
}

// AppCodec returns SimApp's app codec.
//
// NOTE: This is solely to be used for testing purposes as it may be desirable
// for modules to register their own custom testing types.
func (app *SimApp)

AppCodec()

codec.Codec {
    return app.appCodec
}

// InterfaceRegistry returns SimApp's InterfaceRegistry.
func (app *SimApp)

InterfaceRegistry()

codectypes.InterfaceRegistry {
    return app.interfaceRegistry
}

// TxConfig returns SimApp's TxConfig
func (app *SimApp)

TxConfig()

client.TxConfig {
    return app.txConfig
}

// GetKey returns the KVStoreKey for the provided store key.
//
// NOTE: This is solely to be used for testing purposes.
func (app *SimApp)

GetKey(storeKey string) *storetypes.KVStoreKey {
    sk := app.UnsafeFindStoreKey(storeKey)

kvStoreKey, ok := sk.(*storetypes.KVStoreKey)
    if !ok {
    return nil
}

return kvStoreKey
}

func (app *SimApp)

kvStoreKeys()

map[string]*storetypes.KVStoreKey {
    keys := make(map[string]*storetypes.KVStoreKey)
    for _, k := range app.GetStoreKeys() {
    if kv, ok := k.(*storetypes.KVStoreKey); ok {
    keys[kv.Name()] = kv
}
	
}

return keys
}

// SimulationManager implements the SimulationApp interface
func (app *SimApp)

SimulationManager() *module.SimulationManager {
    return app.sm
}

// RegisterAPIRoutes registers all application module routes with the provided
// API server.
func (app *SimApp)

RegisterAPIRoutes(apiSvr *api.Server, apiConfig config.APIConfig) {
    app.App.RegisterAPIRoutes(apiSvr, apiConfig)
	// register swagger API in app.go so that other applications can override easily
    if err := server.RegisterSwaggerAPI(apiSvr.ClientCtx, apiSvr.Router, apiConfig.Swagger); err != nil {
    panic(err)
}
}

// GetMaccPerms returns a copy of the module account permissions
//
// NOTE: This is solely to be used for testing purposes.
func GetMaccPerms()

map[string][]string {
    dup := make(map[string][]string)
    for _, perms := range moduleAccPerms {
    dup[perms.Account] = perms.Permissions
}

return dup
}

// BlockedAddresses returns all the app's blocked account addresses.
func BlockedAddresses()

map[string]bool {
    result := make(map[string]bool)
    if len(blockAccAddrs) > 0 {
    for _, addr := range blockAccAddrs {
    result[addr] = true
}
	
}

else {
    for addr := range GetMaccPerms() {
    result[addr] = true
}
	
}

return result
}
```

<Warning>
  When using `depinject.Inject`, the injected types must be pointers.
</Warning>

### Advanced Configuration

In advanced cases, it is possible to inject extra (module) configuration in a way that is not (yet) supported by `AppConfig`.\
In this case, use `depinject.Configs` for combining the extra configuration, and `AppConfig` and `depinject.Supply` for providing the extra configuration.
More information on how `depinject.Configs` and `depinject.Supply` function can be found in the [`depinject` documentation](https://pkg.go.dev/cosmossdk.io/depinject).

```go expandable theme={"theme":{"light":"github-light-high-contrast","dark":"github-dark-high-contrast"}}
//go:build !app_v1

package simapp

import (
    
	"io"

	dbm "github.com/cosmos/cosmos-db"

	clienthelpers "cosmossdk.io/client/v2/helpers"
    "cosmossdk.io/depinject"
    "cosmossdk.io/log"
	storetypes "cosmossdk.io/store/types"
	circuitkeeper "cosmossdk.io/x/circuit/keeper"
	evidencekeeper "cosmossdk.io/x/evidence/keeper"
	feegrantkeeper "cosmossdk.io/x/feegrant/keeper"
	nftkeeper "cosmossdk.io/x/nft/keeper"
	upgradekeeper "cosmossdk.io/x/upgrade/keeper"
    "github.com/cosmos/cosmos-sdk/baseapp"
    "github.com/cosmos/cosmos-sdk/client"
    "github.com/cosmos/cosmos-sdk/codec"
	codectypes "github.com/cosmos/cosmos-sdk/codec/types"
    "github.com/cosmos/cosmos-sdk/runtime"
    "github.com/cosmos/cosmos-sdk/server"
    "github.com/cosmos/cosmos-sdk/server/api"
    "github.com/cosmos/cosmos-sdk/server/config"
	servertypes "github.com/cosmos/cosmos-sdk/server/types"
	testdata_pulsar "github.com/cosmos/cosmos-sdk/testutil/testdata/testpb"
    "github.com/cosmos/cosmos-sdk/types/module"
    "github.com/cosmos/cosmos-sdk/x/auth"
    "github.com/cosmos/cosmos-sdk/x/auth/ante"
	authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
	authsims "github.com/cosmos/cosmos-sdk/x/auth/simulation"
	authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
	authzkeeper "github.com/cosmos/cosmos-sdk/x/authz/keeper"
	bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper"
	consensuskeeper "github.com/cosmos/cosmos-sdk/x/consensus/keeper"
	distrkeeper "github.com/cosmos/cosmos-sdk/x/distribution/keeper"
	epochskeeper "github.com/cosmos/cosmos-sdk/x/epochs/keeper"
	govkeeper "github.com/cosmos/cosmos-sdk/x/gov/keeper"
	groupkeeper "github.com/cosmos/cosmos-sdk/x/group/keeper"
	mintkeeper "github.com/cosmos/cosmos-sdk/x/mint/keeper"
	protocolpoolkeeper "github.com/cosmos/cosmos-sdk/x/protocolpool/keeper"
	slashingkeeper "github.com/cosmos/cosmos-sdk/x/slashing/keeper"
	stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper"
)

// DefaultNodeHome default home directories for the application daemon
var DefaultNodeHome string

var (
	_ runtime.AppI            = (*SimApp)(nil)
	_ servertypes.Application = (*SimApp)(nil)
)

// SimApp extends an ABCI application, but with most of its parameters exported.
// They are exported for convenience in creating helper functions, as object
// capabilities aren't needed for testing.
type SimApp struct {
	*runtime.App
	legacyAmino       *codec.LegacyAmino
	appCodec          codec.Codec
	txConfig          client.TxConfig
	interfaceRegistry codectypes.InterfaceRegistry

	// essential keepers
	AccountKeeper         authkeeper.AccountKeeper
	BankKeeper            bankkeeper.BaseKeeper
	StakingKeeper         *stakingkeeper.Keeper
	SlashingKeeper        slashingkeeper.Keeper
	MintKeeper            mintkeeper.Keeper
	DistrKeeper           distrkeeper.Keeper
	GovKeeper             *govkeeper.Keeper
	UpgradeKeeper         *upgradekeeper.Keeper
	EvidenceKeeper        evidencekeeper.Keeper
	ConsensusParamsKeeper consensuskeeper.Keeper
	CircuitKeeper         circuitkeeper.Keeper

	// supplementary keepers
	FeeGrantKeeper     feegrantkeeper.Keeper
	GroupKeeper        groupkeeper.Keeper
	AuthzKeeper        authzkeeper.Keeper
	NFTKeeper          nftkeeper.Keeper
	EpochsKeeper       epochskeeper.Keeper
	ProtocolPoolKeeper protocolpoolkeeper.Keeper

	// simulation manager
	sm *module.SimulationManager
}

func init() {
    var err error
	DefaultNodeHome, err = clienthelpers.GetNodeHomeDirectory(".simapp")
    if err != nil {
    panic(err)
}
}

// NewSimApp returns a reference to an initialized SimApp.
func NewSimApp(
	logger log.Logger,
	db dbm.DB,
	traceStore io.Writer,
	loadLatest bool,
	appOpts servertypes.AppOptions,
	baseAppOptions ...func(*baseapp.BaseApp),
) *SimApp {
    var (
		app        = &SimApp{
}

appBuilder *runtime.AppBuilder

		// merge the AppConfig and other configuration in one config
		appConfig = depinject.Configs(
			AppConfig,
			depinject.Supply(
				// supply the application options
				appOpts,
				// supply the logger
				logger,

				// ADVANCED CONFIGURATION

				//
				// AUTH
				//
				// For providing a custom function required in auth to generate custom account types
				// add it below. By default the auth module uses simulation.RandomGenesisAccounts.
				//
				// authtypes.RandomGenesisAccountsFn(simulation.RandomGenesisAccounts),
				//
				// For providing a custom a base account type add it below.
				// By default the auth module uses authtypes.ProtoBaseAccount().
				//
				// func()

sdk.AccountI {
    return authtypes.ProtoBaseAccount()
},
				//
				// For providing a different address codec, add it below.
				// By default the auth module uses a Bech32 address codec,
				// with the prefix defined in the auth module configuration.
				//
				// func()

address.Codec {
    return <- custom address codec type ->
}

				//
				// STAKING
				//
				// For providing a different validator and consensus address codec, add it below.
				// By default the staking module uses the bech32 prefix provided in the auth config,
				// and appends "valoper" and "valcons" for validator and consensus addresses respectively.
				// When providing a custom address codec in auth, custom address codecs must be provided here as well.
				//
				// func()

runtime.ValidatorAddressCodec {
    return <- custom validator address codec type ->
}
				// func()

runtime.ConsensusAddressCodec {
    return <- custom consensus address codec type ->
}

				//
				// MINT
				//

				// For providing a custom inflation function for x/mint add here your
				// custom function that implements the minttypes.InflationCalculationFn
				// interface.
			),
		)
	)
    if err := depinject.Inject(appConfig,
		&appBuilder,
		&app.appCodec,
		&app.legacyAmino,
		&app.txConfig,
		&app.interfaceRegistry,
		&app.AccountKeeper,
		&app.BankKeeper,
		&app.StakingKeeper,
		&app.SlashingKeeper,
		&app.MintKeeper,
		&app.DistrKeeper,
		&app.GovKeeper,
		&app.UpgradeKeeper,
		&app.AuthzKeeper,
		&app.EvidenceKeeper,
		&app.FeeGrantKeeper,
		&app.GroupKeeper,
		&app.NFTKeeper,
		&app.ConsensusParamsKeeper,
		&app.CircuitKeeper,
		&app.EpochsKeeper,
		&app.ProtocolPoolKeeper,
	); err != nil {
    panic(err)
}

	// Below we could construct and set an application specific mempool and
	// ABCI 1.0 PrepareProposal and ProcessProposal handlers. These defaults are
	// already set in the SDK's BaseApp, this shows an example of how to override
	// them.
	//
	// Example:
	//
	// app.App = appBuilder.Build(...)
	// nonceMempool := mempool.NewSenderNonceMempool()
	// abciPropHandler := NewDefaultProposalHandler(nonceMempool, app.App.BaseApp)
	//
	// app.App.BaseApp.SetMempool(nonceMempool)
	// app.App.BaseApp.SetPrepareProposal(abciPropHandler.PrepareProposalHandler())
	// app.App.BaseApp.SetProcessProposal(abciPropHandler.ProcessProposalHandler())
	//
	// Alternatively, you can construct BaseApp options, append those to
	// baseAppOptions and pass them to the appBuilder.
	//
	// Example:
	//
	// prepareOpt = func(app *baseapp.BaseApp) {
	// 	abciPropHandler := baseapp.NewDefaultProposalHandler(nonceMempool, app)
	// 	app.SetPrepareProposal(abciPropHandler.PrepareProposalHandler())
	//
}
	// baseAppOptions = append(baseAppOptions, prepareOpt)

	// create and set dummy vote extension handler
    voteExtOp := func(bApp *baseapp.BaseApp) {
    voteExtHandler := NewVoteExtensionHandler()

voteExtHandler.SetHandlers(bApp)
}

baseAppOptions = append(baseAppOptions, voteExtOp, baseapp.SetOptimisticExecution())

app.App = appBuilder.Build(db, traceStore, baseAppOptions...)

	// register streaming services
    if err := app.RegisterStreamingServices(appOpts, app.kvStoreKeys()); err != nil {
    panic(err)
}

	/****  Module Options ****/

	// RegisterUpgradeHandlers is used for registering any on-chain upgrades.
	app.RegisterUpgradeHandlers()

	// add test gRPC service for testing gRPC queries in isolation
	testdata_pulsar.RegisterQueryServer(app.GRPCQueryRouter(), testdata_pulsar.QueryImpl{
})

	// create the simulation manager and define the order of the modules for deterministic simulations
	//
	// NOTE: this is not required apps that don't use the simulator for fuzz testing
	// transactions
    overrideModules := map[string]module.AppModuleSimulation{
    authtypes.ModuleName: auth.NewAppModule(app.appCodec, app.AccountKeeper, authsims.RandomGenesisAccounts, nil),
}

app.sm = module.NewSimulationManagerFromAppModules(app.ModuleManager.Modules, overrideModules)

app.sm.RegisterStoreDecoders()

	// A custom InitChainer can be set if extra pre-init-genesis logic is required.
	// By default, when using app wiring enabled module, this is not required.
	// For instance, the upgrade module will set automatically the module version map in its init genesis thanks to app wiring.
	// However, when registering a module manually (i.e. that does not support app wiring), the module version map
	// must be set manually as follow. The upgrade module will de-duplicate the module version map.
	//
	// app.SetInitChainer(func(ctx sdk.Context, req *abci.RequestInitChain) (*abci.ResponseInitChain, error) {
	// 	app.UpgradeKeeper.SetModuleVersionMap(ctx, app.ModuleManager.GetVersionMap())
	// 	return app.App.InitChainer(ctx, req)
	//
})

	// set custom ante handler
	app.setAnteHandler(app.txConfig)
    if err := app.Load(loadLatest); err != nil {
    panic(err)
}

return app
}

// setAnteHandler sets custom ante handlers.
// "x/auth/tx" pre-defined ante handler have been disabled in app_config.
func (app *SimApp)

setAnteHandler(txConfig client.TxConfig) {
    anteHandler, err := NewAnteHandler(
		HandlerOptions{
    ante.HandlerOptions{
    UnorderedNonceManager: app.AccountKeeper,
    AccountKeeper:         app.AccountKeeper,
    BankKeeper:            app.BankKeeper,
    SignModeHandler:       txConfig.SignModeHandler(),
    FeegrantKeeper:        app.FeeGrantKeeper,
    SigGasConsumer:        ante.DefaultSigVerificationGasConsumer,
},
			&app.CircuitKeeper,
},
	)
    if err != nil {
    panic(err)
}

	// Set the AnteHandler for the app
	app.SetAnteHandler(anteHandler)
}

// LegacyAmino returns SimApp's amino codec.
//
// NOTE: This is solely to be used for testing purposes as it may be desirable
// for modules to register their own custom testing types.
func (app *SimApp)

LegacyAmino() *codec.LegacyAmino {
    return app.legacyAmino
}

// AppCodec returns SimApp's app codec.
//
// NOTE: This is solely to be used for testing purposes as it may be desirable
// for modules to register their own custom testing types.
func (app *SimApp)

AppCodec()

codec.Codec {
    return app.appCodec
}

// InterfaceRegistry returns SimApp's InterfaceRegistry.
func (app *SimApp)

InterfaceRegistry()

codectypes.InterfaceRegistry {
    return app.interfaceRegistry
}

// TxConfig returns SimApp's TxConfig
func (app *SimApp)

TxConfig()

client.TxConfig {
    return app.txConfig
}

// GetKey returns the KVStoreKey for the provided store key.
//
// NOTE: This is solely to be used for testing purposes.
func (app *SimApp)

GetKey(storeKey string) *storetypes.KVStoreKey {
    sk := app.UnsafeFindStoreKey(storeKey)

kvStoreKey, ok := sk.(*storetypes.KVStoreKey)
    if !ok {
    return nil
}

return kvStoreKey
}

func (app *SimApp)

kvStoreKeys()

map[string]*storetypes.KVStoreKey {
    keys := make(map[string]*storetypes.KVStoreKey)
    for _, k := range app.GetStoreKeys() {
    if kv, ok := k.(*storetypes.KVStoreKey); ok {
    keys[kv.Name()] = kv
}
	
}

return keys
}

// SimulationManager implements the SimulationApp interface
func (app *SimApp)

SimulationManager() *module.SimulationManager {
    return app.sm
}

// RegisterAPIRoutes registers all application module routes with the provided
// API server.
func (app *SimApp)

RegisterAPIRoutes(apiSvr *api.Server, apiConfig config.APIConfig) {
    app.App.RegisterAPIRoutes(apiSvr, apiConfig)
	// register swagger API in app.go so that other applications can override easily
    if err := server.RegisterSwaggerAPI(apiSvr.ClientCtx, apiSvr.Router, apiConfig.Swagger); err != nil {
    panic(err)
}
}

// GetMaccPerms returns a copy of the module account permissions
//
// NOTE: This is solely to be used for testing purposes.
func GetMaccPerms()

map[string][]string {
    dup := make(map[string][]string)
    for _, perms := range moduleAccPerms {
    dup[perms.Account] = perms.Permissions
}

return dup
}

// BlockedAddresses returns all the app's blocked account addresses.
func BlockedAddresses()

map[string]bool {
    result := make(map[string]bool)
    if len(blockAccAddrs) > 0 {
    for _, addr := range blockAccAddrs {
    result[addr] = true
}
	
}

else {
    for addr := range GetMaccPerms() {
    result[addr] = true
}
	
}

return result
}
```

### Registering non app wiring modules

It is possible to combine app wiring / depinject enabled modules with non-app wiring modules.
To do so, use the `app.RegisterModules` method to register the modules on your app, as well as `app.RegisterStores` for registering the extra stores needed.

```go expandable theme={"theme":{"light":"github-light-high-contrast","dark":"github-dark-high-contrast"}}
// ....
app.App = appBuilder.Build(db, traceStore, baseAppOptions...)

// register module manually
app.RegisterStores(storetypes.NewKVStoreKey(example.ModuleName))

app.ExampleKeeper = examplekeeper.NewKeeper(app.appCodec, app.AccountKeeper.AddressCodec(), runtime.NewKVStoreService(app.GetKey(example.ModuleName)), authtypes.NewModuleAddress(govtypes.ModuleName).String())
    exampleAppModule := examplemodule.NewAppModule(app.ExampleKeeper)
    if err := app.RegisterModules(&exampleAppModule); err != nil {
    panic(err)
}

// ....
```

<Warning>
  When using AutoCLI and combining app wiring and non-app wiring modules. The AutoCLI options should be manually constructed instead of injected.
  Otherwise it will miss the non depinject modules and not register their CLI.
</Warning>

### Complete `app_di.go`

<Tip>
  Note that in the complete `SimApp` `app_di.go` file, testing utilities are also defined, but they could as well be defined in a separate file.
</Tip>

```go expandable theme={"theme":{"light":"github-light-high-contrast","dark":"github-dark-high-contrast"}}
//go:build !app_v1

package simapp

import (
    
	"io"

	dbm "github.com/cosmos/cosmos-db"

	clienthelpers "cosmossdk.io/client/v2/helpers"
    "cosmossdk.io/depinject"
    "cosmossdk.io/log"
	storetypes "cosmossdk.io/store/types"
	circuitkeeper "cosmossdk.io/x/circuit/keeper"
	evidencekeeper "cosmossdk.io/x/evidence/keeper"
	feegrantkeeper "cosmossdk.io/x/feegrant/keeper"
	nftkeeper "cosmossdk.io/x/nft/keeper"
	upgradekeeper "cosmossdk.io/x/upgrade/keeper"
    "github.com/cosmos/cosmos-sdk/baseapp"
    "github.com/cosmos/cosmos-sdk/client"
    "github.com/cosmos/cosmos-sdk/codec"
	codectypes "github.com/cosmos/cosmos-sdk/codec/types"
    "github.com/cosmos/cosmos-sdk/runtime"
    "github.com/cosmos/cosmos-sdk/server"
    "github.com/cosmos/cosmos-sdk/server/api"
    "github.com/cosmos/cosmos-sdk/server/config"
	servertypes "github.com/cosmos/cosmos-sdk/server/types"
	testdata_pulsar "github.com/cosmos/cosmos-sdk/testutil/testdata/testpb"
    "github.com/cosmos/cosmos-sdk/types/module"
    "github.com/cosmos/cosmos-sdk/x/auth"
    "github.com/cosmos/cosmos-sdk/x/auth/ante"
	authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
	authsims "github.com/cosmos/cosmos-sdk/x/auth/simulation"
	authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
	authzkeeper "github.com/cosmos/cosmos-sdk/x/authz/keeper"
	bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper"
	consensuskeeper "github.com/cosmos/cosmos-sdk/x/consensus/keeper"
	distrkeeper "github.com/cosmos/cosmos-sdk/x/distribution/keeper"
	epochskeeper "github.com/cosmos/cosmos-sdk/x/epochs/keeper"
	govkeeper "github.com/cosmos/cosmos-sdk/x/gov/keeper"
	groupkeeper "github.com/cosmos/cosmos-sdk/x/group/keeper"
	mintkeeper "github.com/cosmos/cosmos-sdk/x/mint/keeper"
	protocolpoolkeeper "github.com/cosmos/cosmos-sdk/x/protocolpool/keeper"
	slashingkeeper "github.com/cosmos/cosmos-sdk/x/slashing/keeper"
	stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper"
)

// DefaultNodeHome default home directories for the application daemon
var DefaultNodeHome string

var (
	_ runtime.AppI            = (*SimApp)(nil)
	_ servertypes.Application = (*SimApp)(nil)
)

// SimApp extends an ABCI application, but with most of its parameters exported.
// They are exported for convenience in creating helper functions, as object
// capabilities aren't needed for testing.
type SimApp struct {
	*runtime.App
	legacyAmino       *codec.LegacyAmino
	appCodec          codec.Codec
	txConfig          client.TxConfig
	interfaceRegistry codectypes.InterfaceRegistry

	// essential keepers
	AccountKeeper         authkeeper.AccountKeeper
	BankKeeper            bankkeeper.BaseKeeper
	StakingKeeper         *stakingkeeper.Keeper
	SlashingKeeper        slashingkeeper.Keeper
	MintKeeper            mintkeeper.Keeper
	DistrKeeper           distrkeeper.Keeper
	GovKeeper             *govkeeper.Keeper
	UpgradeKeeper         *upgradekeeper.Keeper
	EvidenceKeeper        evidencekeeper.Keeper
	ConsensusParamsKeeper consensuskeeper.Keeper
	CircuitKeeper         circuitkeeper.Keeper

	// supplementary keepers
	FeeGrantKeeper     feegrantkeeper.Keeper
	GroupKeeper        groupkeeper.Keeper
	AuthzKeeper        authzkeeper.Keeper
	NFTKeeper          nftkeeper.Keeper
	EpochsKeeper       epochskeeper.Keeper
	ProtocolPoolKeeper protocolpoolkeeper.Keeper

	// simulation manager
	sm *module.SimulationManager
}

func init() {
    var err error
	DefaultNodeHome, err = clienthelpers.GetNodeHomeDirectory(".simapp")
    if err != nil {
    panic(err)
}
}

// NewSimApp returns a reference to an initialized SimApp.
func NewSimApp(
	logger log.Logger,
	db dbm.DB,
	traceStore io.Writer,
	loadLatest bool,
	appOpts servertypes.AppOptions,
	baseAppOptions ...func(*baseapp.BaseApp),
) *SimApp {
    var (
		app        = &SimApp{
}

appBuilder *runtime.AppBuilder

		// merge the AppConfig and other configuration in one config
		appConfig = depinject.Configs(
			AppConfig,
			depinject.Supply(
				// supply the application options
				appOpts,
				// supply the logger
				logger,

				// ADVANCED CONFIGURATION

				//
				// AUTH
				//
				// For providing a custom function required in auth to generate custom account types
				// add it below. By default the auth module uses simulation.RandomGenesisAccounts.
				//
				// authtypes.RandomGenesisAccountsFn(simulation.RandomGenesisAccounts),
				//
				// For providing a custom a base account type add it below.
				// By default the auth module uses authtypes.ProtoBaseAccount().
				//
				// func()

sdk.AccountI {
    return authtypes.ProtoBaseAccount()
},
				//
				// For providing a different address codec, add it below.
				// By default the auth module uses a Bech32 address codec,
				// with the prefix defined in the auth module configuration.
				//
				// func()

address.Codec {
    return <- custom address codec type ->
}

				//
				// STAKING
				//
				// For providing a different validator and consensus address codec, add it below.
				// By default the staking module uses the bech32 prefix provided in the auth config,
				// and appends "valoper" and "valcons" for validator and consensus addresses respectively.
				// When providing a custom address codec in auth, custom address codecs must be provided here as well.
				//
				// func()

runtime.ValidatorAddressCodec {
    return <- custom validator address codec type ->
}
				// func()

runtime.ConsensusAddressCodec {
    return <- custom consensus address codec type ->
}

				//
				// MINT
				//

				// For providing a custom inflation function for x/mint add here your
				// custom function that implements the minttypes.InflationCalculationFn
				// interface.
			),
		)
	)
    if err := depinject.Inject(appConfig,
		&appBuilder,
		&app.appCodec,
		&app.legacyAmino,
		&app.txConfig,
		&app.interfaceRegistry,
		&app.AccountKeeper,
		&app.BankKeeper,
		&app.StakingKeeper,
		&app.SlashingKeeper,
		&app.MintKeeper,
		&app.DistrKeeper,
		&app.GovKeeper,
		&app.UpgradeKeeper,
		&app.AuthzKeeper,
		&app.EvidenceKeeper,
		&app.FeeGrantKeeper,
		&app.GroupKeeper,
		&app.NFTKeeper,
		&app.ConsensusParamsKeeper,
		&app.CircuitKeeper,
		&app.EpochsKeeper,
		&app.ProtocolPoolKeeper,
	); err != nil {
    panic(err)
}

	// Below we could construct and set an application specific mempool and
	// ABCI 1.0 PrepareProposal and ProcessProposal handlers. These defaults are
	// already set in the SDK's BaseApp, this shows an example of how to override
	// them.
	//
	// Example:
	//
	// app.App = appBuilder.Build(...)
	// nonceMempool := mempool.NewSenderNonceMempool()
	// abciPropHandler := NewDefaultProposalHandler(nonceMempool, app.App.BaseApp)
	//
	// app.App.BaseApp.SetMempool(nonceMempool)
	// app.App.BaseApp.SetPrepareProposal(abciPropHandler.PrepareProposalHandler())
	// app.App.BaseApp.SetProcessProposal(abciPropHandler.ProcessProposalHandler())
	//
	// Alternatively, you can construct BaseApp options, append those to
	// baseAppOptions and pass them to the appBuilder.
	//
	// Example:
	//
	// prepareOpt = func(app *baseapp.BaseApp) {
	// 	abciPropHandler := baseapp.NewDefaultProposalHandler(nonceMempool, app)
	// 	app.SetPrepareProposal(abciPropHandler.PrepareProposalHandler())
	//
}
	// baseAppOptions = append(baseAppOptions, prepareOpt)

	// create and set dummy vote extension handler
    voteExtOp := func(bApp *baseapp.BaseApp) {
    voteExtHandler := NewVoteExtensionHandler()

voteExtHandler.SetHandlers(bApp)
}

baseAppOptions = append(baseAppOptions, voteExtOp, baseapp.SetOptimisticExecution())

app.App = appBuilder.Build(db, traceStore, baseAppOptions...)

	// register streaming services
    if err := app.RegisterStreamingServices(appOpts, app.kvStoreKeys()); err != nil {
    panic(err)
}

	/****  Module Options ****/

	// RegisterUpgradeHandlers is used for registering any on-chain upgrades.
	app.RegisterUpgradeHandlers()

	// add test gRPC service for testing gRPC queries in isolation
	testdata_pulsar.RegisterQueryServer(app.GRPCQueryRouter(), testdata_pulsar.QueryImpl{
})

	// create the simulation manager and define the order of the modules for deterministic simulations
	//
	// NOTE: this is not required apps that don't use the simulator for fuzz testing
	// transactions
    overrideModules := map[string]module.AppModuleSimulation{
    authtypes.ModuleName: auth.NewAppModule(app.appCodec, app.AccountKeeper, authsims.RandomGenesisAccounts, nil),
}

app.sm = module.NewSimulationManagerFromAppModules(app.ModuleManager.Modules, overrideModules)

app.sm.RegisterStoreDecoders()

	// A custom InitChainer can be set if extra pre-init-genesis logic is required.
	// By default, when using app wiring enabled module, this is not required.
	// For instance, the upgrade module will set automatically the module version map in its init genesis thanks to app wiring.
	// However, when registering a module manually (i.e. that does not support app wiring), the module version map
	// must be set manually as follow. The upgrade module will de-duplicate the module version map.
	//
	// app.SetInitChainer(func(ctx sdk.Context, req *abci.RequestInitChain) (*abci.ResponseInitChain, error) {
	// 	app.UpgradeKeeper.SetModuleVersionMap(ctx, app.ModuleManager.GetVersionMap())
	// 	return app.App.InitChainer(ctx, req)
	//
})

	// set custom ante handler
	app.setAnteHandler(app.txConfig)
    if err := app.Load(loadLatest); err != nil {
    panic(err)
}

return app
}

// setAnteHandler sets custom ante handlers.
// "x/auth/tx" pre-defined ante handler have been disabled in app_config.
func (app *SimApp)

setAnteHandler(txConfig client.TxConfig) {
    anteHandler, err := NewAnteHandler(
		HandlerOptions{
    ante.HandlerOptions{
    UnorderedNonceManager: app.AccountKeeper,
    AccountKeeper:         app.AccountKeeper,
    BankKeeper:            app.BankKeeper,
    SignModeHandler:       txConfig.SignModeHandler(),
    FeegrantKeeper:        app.FeeGrantKeeper,
    SigGasConsumer:        ante.DefaultSigVerificationGasConsumer,
},
			&app.CircuitKeeper,
},
	)
    if err != nil {
    panic(err)
}

	// Set the AnteHandler for the app
	app.SetAnteHandler(anteHandler)
}

// LegacyAmino returns SimApp's amino codec.
//
// NOTE: This is solely to be used for testing purposes as it may be desirable
// for modules to register their own custom testing types.
func (app *SimApp)

LegacyAmino() *codec.LegacyAmino {
    return app.legacyAmino
}

// AppCodec returns SimApp's app codec.
//
// NOTE: This is solely to be used for testing purposes as it may be desirable
// for modules to register their own custom testing types.
func (app *SimApp)

AppCodec()

codec.Codec {
    return app.appCodec
}

// InterfaceRegistry returns SimApp's InterfaceRegistry.
func (app *SimApp)

InterfaceRegistry()

codectypes.InterfaceRegistry {
    return app.interfaceRegistry
}

// TxConfig returns SimApp's TxConfig
func (app *SimApp)

TxConfig()

client.TxConfig {
    return app.txConfig
}

// GetKey returns the KVStoreKey for the provided store key.
//
// NOTE: This is solely to be used for testing purposes.
func (app *SimApp)

GetKey(storeKey string) *storetypes.KVStoreKey {
    sk := app.UnsafeFindStoreKey(storeKey)

kvStoreKey, ok := sk.(*storetypes.KVStoreKey)
    if !ok {
    return nil
}

return kvStoreKey
}

func (app *SimApp)

kvStoreKeys()

map[string]*storetypes.KVStoreKey {
    keys := make(map[string]*storetypes.KVStoreKey)
    for _, k := range app.GetStoreKeys() {
    if kv, ok := k.(*storetypes.KVStoreKey); ok {
    keys[kv.Name()] = kv
}
	
}

return keys
}

// SimulationManager implements the SimulationApp interface
func (app *SimApp)

SimulationManager() *module.SimulationManager {
    return app.sm
}

// RegisterAPIRoutes registers all application module routes with the provided
// API server.
func (app *SimApp)

RegisterAPIRoutes(apiSvr *api.Server, apiConfig config.APIConfig) {
    app.App.RegisterAPIRoutes(apiSvr, apiConfig)
	// register swagger API in app.go so that other applications can override easily
    if err := server.RegisterSwaggerAPI(apiSvr.ClientCtx, apiSvr.Router, apiConfig.Swagger); err != nil {
    panic(err)
}
}

// GetMaccPerms returns a copy of the module account permissions
//
// NOTE: This is solely to be used for testing purposes.
func GetMaccPerms()

map[string][]string {
    dup := make(map[string][]string)
    for _, perms := range moduleAccPerms {
    dup[perms.Account] = perms.Permissions
}

return dup
}

// BlockedAddresses returns all the app's blocked account addresses.
func BlockedAddresses()

map[string]bool {
    result := make(map[string]bool)
    if len(blockAccAddrs) > 0 {
    for _, addr := range blockAccAddrs {
    result[addr] = true
}
	
}

else {
    for addr := range GetMaccPerms() {
    result[addr] = true
}
	
}

return result
}
```
