> ## 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_v2.go

<Note>
  **Synopsis**

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

<Note>
  ### Pre-requisite Readings

  * [ADR 057: App Wiring](/sdk/v0.47/build/architecture/adr-057-app-wiring)
  * [Depinject Documentation](/sdk/v0.47/build/packages/depinject)
  * [Modules depinject-ready](/sdk/v0.47/build/building-modules/depinject)
</Note>

This section is intended to provide an overview of the `SimApp` `app_v2.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"

   	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"
   	capabilitymodulev1 "cosmossdk.io/api/cosmos/capability/module/v1"
   	consensusmodulev1 "cosmossdk.io/api/cosmos/consensus/module/v1"
   	crisismodulev1 "cosmossdk.io/api/cosmos/crisis/module/v1"
   	distrmodulev1 "cosmossdk.io/api/cosmos/distribution/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"
   	paramsmodulev1 "cosmossdk.io/api/cosmos/params/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"
       "google.golang.org/protobuf/types/known/durationpb"

   	authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
   	vestingtypes "github.com/cosmos/cosmos-sdk/x/auth/vesting/types"
       "github.com/cosmos/cosmos-sdk/x/authz"
   	banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
   	capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types"
   	consensustypes "github.com/cosmos/cosmos-sdk/x/consensus/types"
   	crisistypes "github.com/cosmos/cosmos-sdk/x/crisis/types"
   	distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types"
   	evidencetypes "github.com/cosmos/cosmos-sdk/x/evidence/types"
       "github.com/cosmos/cosmos-sdk/x/feegrant"
   	genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types"
   	govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
       "github.com/cosmos/cosmos-sdk/x/group"
   	minttypes "github.com/cosmos/cosmos-sdk/x/mint/types"
       "github.com/cosmos/cosmos-sdk/x/nft"
   	paramstypes "github.com/cosmos/cosmos-sdk/x/params/types"
   	slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types"
   	stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
   	upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"
   )

   var (

   	// 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.
   	// NOTE: Capability module must occur first so that it can initialize any capabilities
   	// so that other modules that want to create or claim capabilities afterwards in InitChain
   	// can do so safely.
   	genesisModuleOrder = []string{
       capabilitytypes.ModuleName, authtypes.ModuleName, banktypes.ModuleName,
   		distrtypes.ModuleName, stakingtypes.ModuleName, slashingtypes.ModuleName, govtypes.ModuleName,
   		minttypes.ModuleName, crisistypes.ModuleName, genutiltypes.ModuleName, evidencetypes.ModuleName, authz.ModuleName,
   		feegrant.ModuleName, nft.ModuleName, group.ModuleName, paramstypes.ModuleName, upgradetypes.ModuleName,
   		vestingtypes.ModuleName, consensustypes.ModuleName,
   }

   	// 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
   },
   }

   	// 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
   }

   	// application configuration (used by depinject)

   AppConfig = appconfig.Compose(&appv1alpha1.Config{
       Modules: []*appv1alpha1.ModuleConfig{
   			{
       Name: "runtime",
       Config: appconfig.WrapAny(&runtimev1alpha1.Module{
       AppName: "SimApp",
   					// 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
   					// NOTE: capability module's beginblocker must come before any modules using capabilities (e.g. IBC)

   BeginBlockers: []string{
       upgradetypes.ModuleName,
   						capabilitytypes.ModuleName,
   						minttypes.ModuleName,
   						distrtypes.ModuleName,
   						slashingtypes.ModuleName,
   						evidencetypes.ModuleName,
   						stakingtypes.ModuleName,
   						authtypes.ModuleName,
   						banktypes.ModuleName,
   						govtypes.ModuleName,
   						crisistypes.ModuleName,
   						genutiltypes.ModuleName,
   						authz.ModuleName,
   						feegrant.ModuleName,
   						nft.ModuleName,
   						group.ModuleName,
   						paramstypes.ModuleName,
   						vestingtypes.ModuleName,
   						consensustypes.ModuleName,
   },
       EndBlockers: []string{
       crisistypes.ModuleName,
   						govtypes.ModuleName,
   						stakingtypes.ModuleName,
   						capabilitytypes.ModuleName,
   						authtypes.ModuleName,
   						banktypes.ModuleName,
   						distrtypes.ModuleName,
   						slashingtypes.ModuleName,
   						minttypes.ModuleName,
   						genutiltypes.ModuleName,
   						evidencetypes.ModuleName,
   						authz.ModuleName,
   						feegrant.ModuleName,
   						nft.ModuleName,
   						group.ModuleName,
   						paramstypes.ModuleName,
   						consensustypes.ModuleName,
   						upgradetypes.ModuleName,
   						vestingtypes.ModuleName,
   },
       OverrideStoreKeys: []*runtimev1alpha1.StoreKeyConfig{
   						{
       ModuleName: authtypes.ModuleName,
       KvStoreKey: "acc",
   },
   },
       InitGenesis: genesisModuleOrder,
   					// When ExportGenesis is not specified, the export genesis module order
   					// is equal to the init genesis order
   					// ExportGenesis: genesisModuleOrder,
   					// Uncomment if you want to set a custom migration order here.
   					// OrderMigrations: nil,
   }),
   },
   			{
       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{
   }),
   },
   			{
       Name:   slashingtypes.ModuleName,
       Config: appconfig.WrapAny(&slashingmodulev1.Module{
   }),
   },
   			{
       Name:   paramstypes.ModuleName,
       Config: appconfig.WrapAny(&paramsmodulev1.Module{
   }),
   },
   			{
       Name:   "tx",
       Config: appconfig.WrapAny(&txconfigv1.Config{
   }),
   },
   			{
       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: capabilitytypes.ModuleName,
       Config: appconfig.WrapAny(&capabilitymodulev1.Module{
       SealKeeper: true,
   }),
   },
   			{
       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:   crisistypes.ModuleName,
       Config: appconfig.WrapAny(&crisismodulev1.Module{
   }),
   },
   			{
       Name:   consensustypes.ModuleName,
       Config: appconfig.WrapAny(&consensusmodulev1.Module{
   }),
   },
   },
   })
   )
   ```

2. Configure the `runtime` module:

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

   import (
       
   	"time"

   	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"
   	capabilitymodulev1 "cosmossdk.io/api/cosmos/capability/module/v1"
   	consensusmodulev1 "cosmossdk.io/api/cosmos/consensus/module/v1"
   	crisismodulev1 "cosmossdk.io/api/cosmos/crisis/module/v1"
   	distrmodulev1 "cosmossdk.io/api/cosmos/distribution/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"
   	paramsmodulev1 "cosmossdk.io/api/cosmos/params/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"
       "google.golang.org/protobuf/types/known/durationpb"

   	authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
   	vestingtypes "github.com/cosmos/cosmos-sdk/x/auth/vesting/types"
       "github.com/cosmos/cosmos-sdk/x/authz"
   	banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
   	capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types"
   	consensustypes "github.com/cosmos/cosmos-sdk/x/consensus/types"
   	crisistypes "github.com/cosmos/cosmos-sdk/x/crisis/types"
   	distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types"
   	evidencetypes "github.com/cosmos/cosmos-sdk/x/evidence/types"
       "github.com/cosmos/cosmos-sdk/x/feegrant"
   	genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types"
   	govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
       "github.com/cosmos/cosmos-sdk/x/group"
   	minttypes "github.com/cosmos/cosmos-sdk/x/mint/types"
       "github.com/cosmos/cosmos-sdk/x/nft"
   	paramstypes "github.com/cosmos/cosmos-sdk/x/params/types"
   	slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types"
   	stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
   	upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"
   )

   var (

   	// 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.
   	// NOTE: Capability module must occur first so that it can initialize any capabilities
   	// so that other modules that want to create or claim capabilities afterwards in InitChain
   	// can do so safely.
   	genesisModuleOrder = []string{
       capabilitytypes.ModuleName, authtypes.ModuleName, banktypes.ModuleName,
   		distrtypes.ModuleName, stakingtypes.ModuleName, slashingtypes.ModuleName, govtypes.ModuleName,
   		minttypes.ModuleName, crisistypes.ModuleName, genutiltypes.ModuleName, evidencetypes.ModuleName, authz.ModuleName,
   		feegrant.ModuleName, nft.ModuleName, group.ModuleName, paramstypes.ModuleName, upgradetypes.ModuleName,
   		vestingtypes.ModuleName, consensustypes.ModuleName,
   }

   	// 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
   },
   }

   	// 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
   }

   	// application configuration (used by depinject)

   AppConfig = appconfig.Compose(&appv1alpha1.Config{
       Modules: []*appv1alpha1.ModuleConfig{
   			{
       Name: "runtime",
       Config: appconfig.WrapAny(&runtimev1alpha1.Module{
       AppName: "SimApp",
   					// 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
   					// NOTE: capability module's beginblocker must come before any modules using capabilities (e.g. IBC)

   BeginBlockers: []string{
       upgradetypes.ModuleName,
   						capabilitytypes.ModuleName,
   						minttypes.ModuleName,
   						distrtypes.ModuleName,
   						slashingtypes.ModuleName,
   						evidencetypes.ModuleName,
   						stakingtypes.ModuleName,
   						authtypes.ModuleName,
   						banktypes.ModuleName,
   						govtypes.ModuleName,
   						crisistypes.ModuleName,
   						genutiltypes.ModuleName,
   						authz.ModuleName,
   						feegrant.ModuleName,
   						nft.ModuleName,
   						group.ModuleName,
   						paramstypes.ModuleName,
   						vestingtypes.ModuleName,
   						consensustypes.ModuleName,
   },
       EndBlockers: []string{
       crisistypes.ModuleName,
   						govtypes.ModuleName,
   						stakingtypes.ModuleName,
   						capabilitytypes.ModuleName,
   						authtypes.ModuleName,
   						banktypes.ModuleName,
   						distrtypes.ModuleName,
   						slashingtypes.ModuleName,
   						minttypes.ModuleName,
   						genutiltypes.ModuleName,
   						evidencetypes.ModuleName,
   						authz.ModuleName,
   						feegrant.ModuleName,
   						nft.ModuleName,
   						group.ModuleName,
   						paramstypes.ModuleName,
   						consensustypes.ModuleName,
   						upgradetypes.ModuleName,
   						vestingtypes.ModuleName,
   },
       OverrideStoreKeys: []*runtimev1alpha1.StoreKeyConfig{
   						{
       ModuleName: authtypes.ModuleName,
       KvStoreKey: "acc",
   },
   },
       InitGenesis: genesisModuleOrder,
   					// When ExportGenesis is not specified, the export genesis module order
   					// is equal to the init genesis order
   					// ExportGenesis: genesisModuleOrder,
   					// Uncomment if you want to set a custom migration order here.
   					// OrderMigrations: nil,
   }),
   },
   			{
       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{
   }),
   },
   			{
       Name:   slashingtypes.ModuleName,
       Config: appconfig.WrapAny(&slashingmodulev1.Module{
   }),
   },
   			{
       Name:   paramstypes.ModuleName,
       Config: appconfig.WrapAny(&paramsmodulev1.Module{
   }),
   },
   			{
       Name:   "tx",
       Config: appconfig.WrapAny(&txconfigv1.Config{
   }),
   },
   			{
       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: capabilitytypes.ModuleName,
       Config: appconfig.WrapAny(&capabilitymodulev1.Module{
       SealKeeper: true,
   }),
   },
   			{
       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:   crisistypes.ModuleName,
       Config: appconfig.WrapAny(&crisismodulev1.Module{
   }),
   },
   			{
       Name:   consensustypes.ModuleName,
       Config: appconfig.WrapAny(&consensusmodulev1.Module{
   }),
   },
   },
   })
   )
   ```

3. Configure the modules defined in the `BeginBlocker` and `EndBlocker` and the `tx` module:

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

   import (
       
   	"time"

   	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"
   	capabilitymodulev1 "cosmossdk.io/api/cosmos/capability/module/v1"
   	consensusmodulev1 "cosmossdk.io/api/cosmos/consensus/module/v1"
   	crisismodulev1 "cosmossdk.io/api/cosmos/crisis/module/v1"
   	distrmodulev1 "cosmossdk.io/api/cosmos/distribution/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"
   	paramsmodulev1 "cosmossdk.io/api/cosmos/params/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"
       "google.golang.org/protobuf/types/known/durationpb"

   	authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
   	vestingtypes "github.com/cosmos/cosmos-sdk/x/auth/vesting/types"
       "github.com/cosmos/cosmos-sdk/x/authz"
   	banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
   	capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types"
   	consensustypes "github.com/cosmos/cosmos-sdk/x/consensus/types"
   	crisistypes "github.com/cosmos/cosmos-sdk/x/crisis/types"
   	distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types"
   	evidencetypes "github.com/cosmos/cosmos-sdk/x/evidence/types"
       "github.com/cosmos/cosmos-sdk/x/feegrant"
   	genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types"
   	govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
       "github.com/cosmos/cosmos-sdk/x/group"
   	minttypes "github.com/cosmos/cosmos-sdk/x/mint/types"
       "github.com/cosmos/cosmos-sdk/x/nft"
   	paramstypes "github.com/cosmos/cosmos-sdk/x/params/types"
   	slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types"
   	stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
   	upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"
   )

   var (

   	// 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.
   	// NOTE: Capability module must occur first so that it can initialize any capabilities
   	// so that other modules that want to create or claim capabilities afterwards in InitChain
   	// can do so safely.
   	genesisModuleOrder = []string{
       capabilitytypes.ModuleName, authtypes.ModuleName, banktypes.ModuleName,
   		distrtypes.ModuleName, stakingtypes.ModuleName, slashingtypes.ModuleName, govtypes.ModuleName,
   		minttypes.ModuleName, crisistypes.ModuleName, genutiltypes.ModuleName, evidencetypes.ModuleName, authz.ModuleName,
   		feegrant.ModuleName, nft.ModuleName, group.ModuleName, paramstypes.ModuleName, upgradetypes.ModuleName,
   		vestingtypes.ModuleName, consensustypes.ModuleName,
   }

   	// 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
   },
   }

   	// 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
   }

   	// application configuration (used by depinject)

   AppConfig = appconfig.Compose(&appv1alpha1.Config{
       Modules: []*appv1alpha1.ModuleConfig{
   			{
       Name: "runtime",
       Config: appconfig.WrapAny(&runtimev1alpha1.Module{
       AppName: "SimApp",
   					// 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
   					// NOTE: capability module's beginblocker must come before any modules using capabilities (e.g. IBC)

   BeginBlockers: []string{
       upgradetypes.ModuleName,
   						capabilitytypes.ModuleName,
   						minttypes.ModuleName,
   						distrtypes.ModuleName,
   						slashingtypes.ModuleName,
   						evidencetypes.ModuleName,
   						stakingtypes.ModuleName,
   						authtypes.ModuleName,
   						banktypes.ModuleName,
   						govtypes.ModuleName,
   						crisistypes.ModuleName,
   						genutiltypes.ModuleName,
   						authz.ModuleName,
   						feegrant.ModuleName,
   						nft.ModuleName,
   						group.ModuleName,
   						paramstypes.ModuleName,
   						vestingtypes.ModuleName,
   						consensustypes.ModuleName,
   },
       EndBlockers: []string{
       crisistypes.ModuleName,
   						govtypes.ModuleName,
   						stakingtypes.ModuleName,
   						capabilitytypes.ModuleName,
   						authtypes.ModuleName,
   						banktypes.ModuleName,
   						distrtypes.ModuleName,
   						slashingtypes.ModuleName,
   						minttypes.ModuleName,
   						genutiltypes.ModuleName,
   						evidencetypes.ModuleName,
   						authz.ModuleName,
   						feegrant.ModuleName,
   						nft.ModuleName,
   						group.ModuleName,
   						paramstypes.ModuleName,
   						consensustypes.ModuleName,
   						upgradetypes.ModuleName,
   						vestingtypes.ModuleName,
   },
       OverrideStoreKeys: []*runtimev1alpha1.StoreKeyConfig{
   						{
       ModuleName: authtypes.ModuleName,
       KvStoreKey: "acc",
   },
   },
       InitGenesis: genesisModuleOrder,
   					// When ExportGenesis is not specified, the export genesis module order
   					// is equal to the init genesis order
   					// ExportGenesis: genesisModuleOrder,
   					// Uncomment if you want to set a custom migration order here.
   					// OrderMigrations: nil,
   }),
   },
   			{
       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{
   }),
   },
   			{
       Name:   slashingtypes.ModuleName,
       Config: appconfig.WrapAny(&slashingmodulev1.Module{
   }),
   },
   			{
       Name:   paramstypes.ModuleName,
       Config: appconfig.WrapAny(&paramsmodulev1.Module{
   }),
   },
   			{
       Name:   "tx",
       Config: appconfig.WrapAny(&txconfigv1.Config{
   }),
   },
   			{
       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: capabilitytypes.ModuleName,
       Config: appconfig.WrapAny(&capabilitymodulev1.Module{
       SealKeeper: true,
   }),
   },
   			{
       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:   crisistypes.ModuleName,
       Config: appconfig.WrapAny(&crisismodulev1.Module{
   }),
   },
   			{
       Name:   consensustypes.ModuleName,
       Config: appconfig.WrapAny(&consensusmodulev1.Module{
   }),
   },
   },
   })
   )
   ```

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

   import (
       
   	"time"

   	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"
   	capabilitymodulev1 "cosmossdk.io/api/cosmos/capability/module/v1"
   	consensusmodulev1 "cosmossdk.io/api/cosmos/consensus/module/v1"
   	crisismodulev1 "cosmossdk.io/api/cosmos/crisis/module/v1"
   	distrmodulev1 "cosmossdk.io/api/cosmos/distribution/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"
   	paramsmodulev1 "cosmossdk.io/api/cosmos/params/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"
       "google.golang.org/protobuf/types/known/durationpb"

   	authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
   	vestingtypes "github.com/cosmos/cosmos-sdk/x/auth/vesting/types"
       "github.com/cosmos/cosmos-sdk/x/authz"
   	banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
   	capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types"
   	consensustypes "github.com/cosmos/cosmos-sdk/x/consensus/types"
   	crisistypes "github.com/cosmos/cosmos-sdk/x/crisis/types"
   	distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types"
   	evidencetypes "github.com/cosmos/cosmos-sdk/x/evidence/types"
       "github.com/cosmos/cosmos-sdk/x/feegrant"
   	genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types"
   	govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
       "github.com/cosmos/cosmos-sdk/x/group"
   	minttypes "github.com/cosmos/cosmos-sdk/x/mint/types"
       "github.com/cosmos/cosmos-sdk/x/nft"
   	paramstypes "github.com/cosmos/cosmos-sdk/x/params/types"
   	slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types"
   	stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
   	upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"
   )

   var (

   	// 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.
   	// NOTE: Capability module must occur first so that it can initialize any capabilities
   	// so that other modules that want to create or claim capabilities afterwards in InitChain
   	// can do so safely.
   	genesisModuleOrder = []string{
       capabilitytypes.ModuleName, authtypes.ModuleName, banktypes.ModuleName,
   		distrtypes.ModuleName, stakingtypes.ModuleName, slashingtypes.ModuleName, govtypes.ModuleName,
   		minttypes.ModuleName, crisistypes.ModuleName, genutiltypes.ModuleName, evidencetypes.ModuleName, authz.ModuleName,
   		feegrant.ModuleName, nft.ModuleName, group.ModuleName, paramstypes.ModuleName, upgradetypes.ModuleName,
   		vestingtypes.ModuleName, consensustypes.ModuleName,
   }

   	// 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
   },
   }

   	// 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
   }

   	// application configuration (used by depinject)

   AppConfig = appconfig.Compose(&appv1alpha1.Config{
       Modules: []*appv1alpha1.ModuleConfig{
   			{
       Name: "runtime",
       Config: appconfig.WrapAny(&runtimev1alpha1.Module{
       AppName: "SimApp",
   					// 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
   					// NOTE: capability module's beginblocker must come before any modules using capabilities (e.g. IBC)

   BeginBlockers: []string{
       upgradetypes.ModuleName,
   						capabilitytypes.ModuleName,
   						minttypes.ModuleName,
   						distrtypes.ModuleName,
   						slashingtypes.ModuleName,
   						evidencetypes.ModuleName,
   						stakingtypes.ModuleName,
   						authtypes.ModuleName,
   						banktypes.ModuleName,
   						govtypes.ModuleName,
   						crisistypes.ModuleName,
   						genutiltypes.ModuleName,
   						authz.ModuleName,
   						feegrant.ModuleName,
   						nft.ModuleName,
   						group.ModuleName,
   						paramstypes.ModuleName,
   						vestingtypes.ModuleName,
   						consensustypes.ModuleName,
   },
       EndBlockers: []string{
       crisistypes.ModuleName,
   						govtypes.ModuleName,
   						stakingtypes.ModuleName,
   						capabilitytypes.ModuleName,
   						authtypes.ModuleName,
   						banktypes.ModuleName,
   						distrtypes.ModuleName,
   						slashingtypes.ModuleName,
   						minttypes.ModuleName,
   						genutiltypes.ModuleName,
   						evidencetypes.ModuleName,
   						authz.ModuleName,
   						feegrant.ModuleName,
   						nft.ModuleName,
   						group.ModuleName,
   						paramstypes.ModuleName,
   						consensustypes.ModuleName,
   						upgradetypes.ModuleName,
   						vestingtypes.ModuleName,
   },
       OverrideStoreKeys: []*runtimev1alpha1.StoreKeyConfig{
   						{
       ModuleName: authtypes.ModuleName,
       KvStoreKey: "acc",
   },
   },
       InitGenesis: genesisModuleOrder,
   					// When ExportGenesis is not specified, the export genesis module order
   					// is equal to the init genesis order
   					// ExportGenesis: genesisModuleOrder,
   					// Uncomment if you want to set a custom migration order here.
   					// OrderMigrations: nil,
   }),
   },
   			{
       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{
   }),
   },
   			{
       Name:   slashingtypes.ModuleName,
       Config: appconfig.WrapAny(&slashingmodulev1.Module{
   }),
   },
   			{
       Name:   paramstypes.ModuleName,
       Config: appconfig.WrapAny(&paramsmodulev1.Module{
   }),
   },
   			{
       Name:   "tx",
       Config: appconfig.WrapAny(&txconfigv1.Config{
   }),
   },
   			{
       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: capabilitytypes.ModuleName,
       Config: appconfig.WrapAny(&capabilitymodulev1.Module{
       SealKeeper: true,
   }),
   },
   			{
       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:   crisistypes.ModuleName,
       Config: appconfig.WrapAny(&crisismodulev1.Module{
   }),
   },
   			{
       Name:   consensustypes.ModuleName,
       Config: appconfig.WrapAny(&consensusmodulev1.Module{
   }),
   },
   },
   })
   )
   ```

### Complete `app_config.go`

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

import (
    
	"time"

	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"
	capabilitymodulev1 "cosmossdk.io/api/cosmos/capability/module/v1"
	consensusmodulev1 "cosmossdk.io/api/cosmos/consensus/module/v1"
	crisismodulev1 "cosmossdk.io/api/cosmos/crisis/module/v1"
	distrmodulev1 "cosmossdk.io/api/cosmos/distribution/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"
	paramsmodulev1 "cosmossdk.io/api/cosmos/params/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"
    "google.golang.org/protobuf/types/known/durationpb"

	authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
	vestingtypes "github.com/cosmos/cosmos-sdk/x/auth/vesting/types"
    "github.com/cosmos/cosmos-sdk/x/authz"
	banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
	capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types"
	consensustypes "github.com/cosmos/cosmos-sdk/x/consensus/types"
	crisistypes "github.com/cosmos/cosmos-sdk/x/crisis/types"
	distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types"
	evidencetypes "github.com/cosmos/cosmos-sdk/x/evidence/types"
    "github.com/cosmos/cosmos-sdk/x/feegrant"
	genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types"
	govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
    "github.com/cosmos/cosmos-sdk/x/group"
	minttypes "github.com/cosmos/cosmos-sdk/x/mint/types"
    "github.com/cosmos/cosmos-sdk/x/nft"
	paramstypes "github.com/cosmos/cosmos-sdk/x/params/types"
	slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types"
	stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
	upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"
)

var (

	// 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.
	// NOTE: Capability module must occur first so that it can initialize any capabilities
	// so that other modules that want to create or claim capabilities afterwards in InitChain
	// can do so safely.
	genesisModuleOrder = []string{
    capabilitytypes.ModuleName, authtypes.ModuleName, banktypes.ModuleName,
		distrtypes.ModuleName, stakingtypes.ModuleName, slashingtypes.ModuleName, govtypes.ModuleName,
		minttypes.ModuleName, crisistypes.ModuleName, genutiltypes.ModuleName, evidencetypes.ModuleName, authz.ModuleName,
		feegrant.ModuleName, nft.ModuleName, group.ModuleName, paramstypes.ModuleName, upgradetypes.ModuleName,
		vestingtypes.ModuleName, consensustypes.ModuleName,
}

	// 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
},
}

	// 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
}

	// application configuration (used by depinject)

AppConfig = appconfig.Compose(&appv1alpha1.Config{
    Modules: []*appv1alpha1.ModuleConfig{
			{
    Name: "runtime",
    Config: appconfig.WrapAny(&runtimev1alpha1.Module{
    AppName: "SimApp",
					// 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
					// NOTE: capability module's beginblocker must come before any modules using capabilities (e.g. IBC)

BeginBlockers: []string{
    upgradetypes.ModuleName,
						capabilitytypes.ModuleName,
						minttypes.ModuleName,
						distrtypes.ModuleName,
						slashingtypes.ModuleName,
						evidencetypes.ModuleName,
						stakingtypes.ModuleName,
						authtypes.ModuleName,
						banktypes.ModuleName,
						govtypes.ModuleName,
						crisistypes.ModuleName,
						genutiltypes.ModuleName,
						authz.ModuleName,
						feegrant.ModuleName,
						nft.ModuleName,
						group.ModuleName,
						paramstypes.ModuleName,
						vestingtypes.ModuleName,
						consensustypes.ModuleName,
},
    EndBlockers: []string{
    crisistypes.ModuleName,
						govtypes.ModuleName,
						stakingtypes.ModuleName,
						capabilitytypes.ModuleName,
						authtypes.ModuleName,
						banktypes.ModuleName,
						distrtypes.ModuleName,
						slashingtypes.ModuleName,
						minttypes.ModuleName,
						genutiltypes.ModuleName,
						evidencetypes.ModuleName,
						authz.ModuleName,
						feegrant.ModuleName,
						nft.ModuleName,
						group.ModuleName,
						paramstypes.ModuleName,
						consensustypes.ModuleName,
						upgradetypes.ModuleName,
						vestingtypes.ModuleName,
},
    OverrideStoreKeys: []*runtimev1alpha1.StoreKeyConfig{
						{
    ModuleName: authtypes.ModuleName,
    KvStoreKey: "acc",
},
},
    InitGenesis: genesisModuleOrder,
					// When ExportGenesis is not specified, the export genesis module order
					// is equal to the init genesis order
					// ExportGenesis: genesisModuleOrder,
					// Uncomment if you want to set a custom migration order here.
					// OrderMigrations: nil,
}),
},
			{
    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{
}),
},
			{
    Name:   slashingtypes.ModuleName,
    Config: appconfig.WrapAny(&slashingmodulev1.Module{
}),
},
			{
    Name:   paramstypes.ModuleName,
    Config: appconfig.WrapAny(&paramsmodulev1.Module{
}),
},
			{
    Name:   "tx",
    Config: appconfig.WrapAny(&txconfigv1.Config{
}),
},
			{
    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: capabilitytypes.ModuleName,
    Config: appconfig.WrapAny(&capabilitymodulev1.Module{
    SealKeeper: true,
}),
},
			{
    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:   crisistypes.ModuleName,
    Config: appconfig.WrapAny(&crisismodulev1.Module{
}),
},
			{
    Name:   consensustypes.ModuleName,
    Config: appconfig.WrapAny(&consensusmodulev1.Module{
}),
},
},
})
)
```

### 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_v2.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/91b1d83f1339e235a1dfa929ecc00084101a19e3/simapp/app.yaml).

## `app_v2.go`

`app_v2.go` is the place where `SimApp` is constructed. `depinject.Inject` facilitates that by automatically wiring the app modules and keepers, provided an application configuration `AppConfig` is provided. `SimApp` is constructed, when calling the injected `*runtime.AppBuilder`, with `appBuilder.Build(...)`.\
In short `depinject` and the [`runtime` package](https://pkg.go.dev/github.com/cosmos/cosmos-sdk/runtime) abstract the wiring of the app, and the `AppBuilder` is the place where the app is constructed. [`runtime`](https://pkg.go.dev/github.com/cosmos/cosmos-sdk/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 (
    
	_ "embed"
    "io"
    "os"
    "path/filepath"
    "github.com/tendermint/tendermint/libs/log"
	dbm "github.com/tendermint/tm-db"
    "cosmossdk.io/depinject"
    "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"
    "github.com/cosmos/cosmos-sdk/store/streaming"
	storetypes "github.com/cosmos/cosmos-sdk/store/types"
    "github.com/cosmos/cosmos-sdk/testutil/testdata_pulsar"
    "github.com/cosmos/cosmos-sdk/types/module"
    "github.com/cosmos/cosmos-sdk/x/auth"
	authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
	authsims "github.com/cosmos/cosmos-sdk/x/auth/simulation"
	_ "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"
	authzkeeper "github.com/cosmos/cosmos-sdk/x/authz/keeper"
	authzmodule "github.com/cosmos/cosmos-sdk/x/authz/module"
    "github.com/cosmos/cosmos-sdk/x/bank"
	bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper"
    "github.com/cosmos/cosmos-sdk/x/capability"
	capabilitykeeper "github.com/cosmos/cosmos-sdk/x/capability/keeper"
	consensus "github.com/cosmos/cosmos-sdk/x/consensus"
	consensuskeeper "github.com/cosmos/cosmos-sdk/x/consensus/keeper"
    "github.com/cosmos/cosmos-sdk/x/crisis"
	crisiskeeper "github.com/cosmos/cosmos-sdk/x/crisis/keeper"
	distr "github.com/cosmos/cosmos-sdk/x/distribution"
	distrkeeper "github.com/cosmos/cosmos-sdk/x/distribution/keeper"
    "github.com/cosmos/cosmos-sdk/x/evidence"
	evidencekeeper "github.com/cosmos/cosmos-sdk/x/evidence/keeper"
	feegrantkeeper "github.com/cosmos/cosmos-sdk/x/feegrant/keeper"
	feegrantmodule "github.com/cosmos/cosmos-sdk/x/feegrant/module"
    "github.com/cosmos/cosmos-sdk/x/genutil"
	genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types"
    "github.com/cosmos/cosmos-sdk/x/gov"
	govclient "github.com/cosmos/cosmos-sdk/x/gov/client"
	govkeeper "github.com/cosmos/cosmos-sdk/x/gov/keeper"
	groupkeeper "github.com/cosmos/cosmos-sdk/x/group/keeper"
	groupmodule "github.com/cosmos/cosmos-sdk/x/group/module"
    "github.com/cosmos/cosmos-sdk/x/mint"
	mintkeeper "github.com/cosmos/cosmos-sdk/x/mint/keeper"
	nftkeeper "github.com/cosmos/cosmos-sdk/x/nft/keeper"
	nftmodule "github.com/cosmos/cosmos-sdk/x/nft/module"
    "github.com/cosmos/cosmos-sdk/x/params"
	paramsclient "github.com/cosmos/cosmos-sdk/x/params/client"
	paramskeeper "github.com/cosmos/cosmos-sdk/x/params/keeper"
	paramstypes "github.com/cosmos/cosmos-sdk/x/params/types"
    "github.com/cosmos/cosmos-sdk/x/slashing"
	slashingkeeper "github.com/cosmos/cosmos-sdk/x/slashing/keeper"
    "github.com/cosmos/cosmos-sdk/x/staking"
	stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper"
    "github.com/cosmos/cosmos-sdk/x/upgrade"
	upgradeclient "github.com/cosmos/cosmos-sdk/x/upgrade/client"
	upgradekeeper "github.com/cosmos/cosmos-sdk/x/upgrade/keeper"
)

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

	// ModuleBasics defines the module BasicManager is in charge of setting up basic,
	// non-dependant module elements, such as codec registration
	// and genesis verification.
	ModuleBasics = module.NewBasicManager(
		auth.AppModuleBasic{
},
		genutil.NewAppModuleBasic(genutiltypes.DefaultMessageValidator),
		bank.AppModuleBasic{
},
		capability.AppModuleBasic{
},
		staking.AppModuleBasic{
},
		mint.AppModuleBasic{
},
		distr.AppModuleBasic{
},
		gov.NewAppModuleBasic(
			[]govclient.ProposalHandler{
    paramsclient.ProposalHandler,
				upgradeclient.LegacyProposalHandler,
				upgradeclient.LegacyCancelProposalHandler,
},
		),
		params.AppModuleBasic{
},
		crisis.AppModuleBasic{
},
		slashing.AppModuleBasic{
},
		feegrantmodule.AppModuleBasic{
},
		upgrade.AppModuleBasic{
},
		evidence.AppModuleBasic{
},
		authzmodule.AppModuleBasic{
},
		groupmodule.AppModuleBasic{
},
		vesting.AppModuleBasic{
},
		nftmodule.AppModuleBasic{
},
		consensus.AppModuleBasic{
},
	)
)

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

	// keepers
	AccountKeeper         authkeeper.AccountKeeper
	BankKeeper            bankkeeper.Keeper
	CapabilityKeeper      *capabilitykeeper.Keeper
	StakingKeeper         *stakingkeeper.Keeper
	SlashingKeeper        slashingkeeper.Keeper
	MintKeeper            mintkeeper.Keeper
	DistrKeeper           distrkeeper.Keeper
	GovKeeper             *govkeeper.Keeper
	CrisisKeeper          *crisiskeeper.Keeper
	UpgradeKeeper         *upgradekeeper.Keeper
	ParamsKeeper          paramskeeper.Keeper
	AuthzKeeper           authzkeeper.Keeper
	EvidenceKeeper        evidencekeeper.Keeper
	FeeGrantKeeper        feegrantkeeper.Keeper
	GroupKeeper           groupkeeper.Keeper
	NFTKeeper             nftkeeper.Keeper
	ConsensusParamsKeeper consensuskeeper.Keeper

	// simulation manager
	sm *module.SimulationManager
}

func init() {
    userHomeDir, err := os.UserHomeDir()
    if err != nil {
    panic(err)
}

DefaultNodeHome = filepath.Join(userHomeDir, ".simapp")
}

// 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
		// Below we could construct and set an application specific mempool and ABCI 1.0 Prepare and Process Proposal
		// handlers. These defaults are already set in the SDK's BaseApp, this shows an example of how to override
		// them.
		//
		// nonceMempool = mempool.NewSenderNonceMempool()
		// mempoolOpt   = baseapp.SetMempool(nonceMempool)
		// prepareOpt   = func(app *baseapp.BaseApp) {
		// 	app.SetPrepareProposal(app.DefaultPrepareProposal())
		//
}
		// processOpt = func(app *baseapp.BaseApp) {
		// 	app.SetProcessProposal(app.DefaultProcessProposal())
		//
}
		//
		// Further down we'd set the options in the AppBuilder like below.
		// baseAppOptions = append(baseAppOptions, mempoolOpt, prepareOpt, processOpt)

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

				// 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()

authtypes.AccountI {
    return authtypes.ProtoBaseAccount()
},

				//
				// 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.CapabilityKeeper,
		&app.StakingKeeper,
		&app.SlashingKeeper,
		&app.MintKeeper,
		&app.DistrKeeper,
		&app.GovKeeper,
		&app.CrisisKeeper,
		&app.UpgradeKeeper,
		&app.ParamsKeeper,
		&app.AuthzKeeper,
		&app.EvidenceKeeper,
		&app.FeeGrantKeeper,
		&app.GroupKeeper,
		&app.NFTKeeper,
		&app.ConsensusParamsKeeper,
	); err != nil {
    panic(err)
}

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

	// load state streaming if enabled
    if _, _, err := streaming.LoadStreamingServices(app.App.BaseApp, appOpts, app.appCodec, logger, app.kvStoreKeys()); err != nil {
    logger.Error("failed to load state streaming", "err", err)

os.Exit(1)
}

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

	app.ModuleManager.RegisterInvariants(app.CrisisKeeper)

	// 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, app.GetSubspace(authtypes.ModuleName)),
}

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 {
	// 	app.UpgradeKeeper.SetModuleVersionMap(ctx, app.ModuleManager.GetVersionMap())
	// 	return app.App.InitChainer(ctx, req)
	//
})
    if err := app.Load(loadLatest); err != nil {
    panic(err)
}

return app
}

// Name returns the name of the App
func (app *SimApp)

Name()

string {
    return app.BaseApp.Name()
}

// 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
}

// GetSubspace returns a param subspace for a given module name.
//
// NOTE: This is solely to be used for testing purposes.
func (app *SimApp)

GetSubspace(moduleName string)

paramstypes.Subspace {
    subspace, _ := app.ParamsKeeper.GetSubspace(moduleName)

return subspace
}

// 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` to providing that extra configuration.
More information on how work `depinject.Configs` and `depinject.Supply` 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 (
    
	_ "embed"
    "io"
    "os"
    "path/filepath"
    "github.com/tendermint/tendermint/libs/log"
	dbm "github.com/tendermint/tm-db"
    "cosmossdk.io/depinject"
    "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"
    "github.com/cosmos/cosmos-sdk/store/streaming"
	storetypes "github.com/cosmos/cosmos-sdk/store/types"
    "github.com/cosmos/cosmos-sdk/testutil/testdata_pulsar"
    "github.com/cosmos/cosmos-sdk/types/module"
    "github.com/cosmos/cosmos-sdk/x/auth"
	authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
	authsims "github.com/cosmos/cosmos-sdk/x/auth/simulation"
	_ "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"
	authzkeeper "github.com/cosmos/cosmos-sdk/x/authz/keeper"
	authzmodule "github.com/cosmos/cosmos-sdk/x/authz/module"
    "github.com/cosmos/cosmos-sdk/x/bank"
	bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper"
    "github.com/cosmos/cosmos-sdk/x/capability"
	capabilitykeeper "github.com/cosmos/cosmos-sdk/x/capability/keeper"
	consensus "github.com/cosmos/cosmos-sdk/x/consensus"
	consensuskeeper "github.com/cosmos/cosmos-sdk/x/consensus/keeper"
    "github.com/cosmos/cosmos-sdk/x/crisis"
	crisiskeeper "github.com/cosmos/cosmos-sdk/x/crisis/keeper"
	distr "github.com/cosmos/cosmos-sdk/x/distribution"
	distrkeeper "github.com/cosmos/cosmos-sdk/x/distribution/keeper"
    "github.com/cosmos/cosmos-sdk/x/evidence"
	evidencekeeper "github.com/cosmos/cosmos-sdk/x/evidence/keeper"
	feegrantkeeper "github.com/cosmos/cosmos-sdk/x/feegrant/keeper"
	feegrantmodule "github.com/cosmos/cosmos-sdk/x/feegrant/module"
    "github.com/cosmos/cosmos-sdk/x/genutil"
	genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types"
    "github.com/cosmos/cosmos-sdk/x/gov"
	govclient "github.com/cosmos/cosmos-sdk/x/gov/client"
	govkeeper "github.com/cosmos/cosmos-sdk/x/gov/keeper"
	groupkeeper "github.com/cosmos/cosmos-sdk/x/group/keeper"
	groupmodule "github.com/cosmos/cosmos-sdk/x/group/module"
    "github.com/cosmos/cosmos-sdk/x/mint"
	mintkeeper "github.com/cosmos/cosmos-sdk/x/mint/keeper"
	nftkeeper "github.com/cosmos/cosmos-sdk/x/nft/keeper"
	nftmodule "github.com/cosmos/cosmos-sdk/x/nft/module"
    "github.com/cosmos/cosmos-sdk/x/params"
	paramsclient "github.com/cosmos/cosmos-sdk/x/params/client"
	paramskeeper "github.com/cosmos/cosmos-sdk/x/params/keeper"
	paramstypes "github.com/cosmos/cosmos-sdk/x/params/types"
    "github.com/cosmos/cosmos-sdk/x/slashing"
	slashingkeeper "github.com/cosmos/cosmos-sdk/x/slashing/keeper"
    "github.com/cosmos/cosmos-sdk/x/staking"
	stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper"
    "github.com/cosmos/cosmos-sdk/x/upgrade"
	upgradeclient "github.com/cosmos/cosmos-sdk/x/upgrade/client"
	upgradekeeper "github.com/cosmos/cosmos-sdk/x/upgrade/keeper"
)

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

	// ModuleBasics defines the module BasicManager is in charge of setting up basic,
	// non-dependant module elements, such as codec registration
	// and genesis verification.
	ModuleBasics = module.NewBasicManager(
		auth.AppModuleBasic{
},
		genutil.NewAppModuleBasic(genutiltypes.DefaultMessageValidator),
		bank.AppModuleBasic{
},
		capability.AppModuleBasic{
},
		staking.AppModuleBasic{
},
		mint.AppModuleBasic{
},
		distr.AppModuleBasic{
},
		gov.NewAppModuleBasic(
			[]govclient.ProposalHandler{
    paramsclient.ProposalHandler,
				upgradeclient.LegacyProposalHandler,
				upgradeclient.LegacyCancelProposalHandler,
},
		),
		params.AppModuleBasic{
},
		crisis.AppModuleBasic{
},
		slashing.AppModuleBasic{
},
		feegrantmodule.AppModuleBasic{
},
		upgrade.AppModuleBasic{
},
		evidence.AppModuleBasic{
},
		authzmodule.AppModuleBasic{
},
		groupmodule.AppModuleBasic{
},
		vesting.AppModuleBasic{
},
		nftmodule.AppModuleBasic{
},
		consensus.AppModuleBasic{
},
	)
)

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

	// keepers
	AccountKeeper         authkeeper.AccountKeeper
	BankKeeper            bankkeeper.Keeper
	CapabilityKeeper      *capabilitykeeper.Keeper
	StakingKeeper         *stakingkeeper.Keeper
	SlashingKeeper        slashingkeeper.Keeper
	MintKeeper            mintkeeper.Keeper
	DistrKeeper           distrkeeper.Keeper
	GovKeeper             *govkeeper.Keeper
	CrisisKeeper          *crisiskeeper.Keeper
	UpgradeKeeper         *upgradekeeper.Keeper
	ParamsKeeper          paramskeeper.Keeper
	AuthzKeeper           authzkeeper.Keeper
	EvidenceKeeper        evidencekeeper.Keeper
	FeeGrantKeeper        feegrantkeeper.Keeper
	GroupKeeper           groupkeeper.Keeper
	NFTKeeper             nftkeeper.Keeper
	ConsensusParamsKeeper consensuskeeper.Keeper

	// simulation manager
	sm *module.SimulationManager
}

func init() {
    userHomeDir, err := os.UserHomeDir()
    if err != nil {
    panic(err)
}

DefaultNodeHome = filepath.Join(userHomeDir, ".simapp")
}

// 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
		// Below we could construct and set an application specific mempool and ABCI 1.0 Prepare and Process Proposal
		// handlers. These defaults are already set in the SDK's BaseApp, this shows an example of how to override
		// them.
		//
		// nonceMempool = mempool.NewSenderNonceMempool()
		// mempoolOpt   = baseapp.SetMempool(nonceMempool)
		// prepareOpt   = func(app *baseapp.BaseApp) {
		// 	app.SetPrepareProposal(app.DefaultPrepareProposal())
		//
}
		// processOpt = func(app *baseapp.BaseApp) {
		// 	app.SetProcessProposal(app.DefaultProcessProposal())
		//
}
		//
		// Further down we'd set the options in the AppBuilder like below.
		// baseAppOptions = append(baseAppOptions, mempoolOpt, prepareOpt, processOpt)

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

				// 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()

authtypes.AccountI {
    return authtypes.ProtoBaseAccount()
},

				//
				// 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.CapabilityKeeper,
		&app.StakingKeeper,
		&app.SlashingKeeper,
		&app.MintKeeper,
		&app.DistrKeeper,
		&app.GovKeeper,
		&app.CrisisKeeper,
		&app.UpgradeKeeper,
		&app.ParamsKeeper,
		&app.AuthzKeeper,
		&app.EvidenceKeeper,
		&app.FeeGrantKeeper,
		&app.GroupKeeper,
		&app.NFTKeeper,
		&app.ConsensusParamsKeeper,
	); err != nil {
    panic(err)
}

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

	// load state streaming if enabled
    if _, _, err := streaming.LoadStreamingServices(app.App.BaseApp, appOpts, app.appCodec, logger, app.kvStoreKeys()); err != nil {
    logger.Error("failed to load state streaming", "err", err)

os.Exit(1)
}

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

	app.ModuleManager.RegisterInvariants(app.CrisisKeeper)

	// 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, app.GetSubspace(authtypes.ModuleName)),
}

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 {
	// 	app.UpgradeKeeper.SetModuleVersionMap(ctx, app.ModuleManager.GetVersionMap())
	// 	return app.App.InitChainer(ctx, req)
	//
})
    if err := app.Load(loadLatest); err != nil {
    panic(err)
}

return app
}

// Name returns the name of the App
func (app *SimApp)

Name()

string {
    return app.BaseApp.Name()
}

// 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
}

// GetSubspace returns a param subspace for a given module name.
//
// NOTE: This is solely to be used for testing purposes.
func (app *SimApp)

GetSubspace(moduleName string)

paramstypes.Subspace {
    subspace, _ := app.ParamsKeeper.GetSubspace(moduleName)

return subspace
}

// 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
}
```

### Complete `app_v2.go`

<Tip>
  Note that in the complete `SimApp` `app_v2.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 (
    
	_ "embed"
    "io"
    "os"
    "path/filepath"
    "github.com/tendermint/tendermint/libs/log"
	dbm "github.com/tendermint/tm-db"
    "cosmossdk.io/depinject"
    "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"
    "github.com/cosmos/cosmos-sdk/store/streaming"
	storetypes "github.com/cosmos/cosmos-sdk/store/types"
    "github.com/cosmos/cosmos-sdk/testutil/testdata_pulsar"
    "github.com/cosmos/cosmos-sdk/types/module"
    "github.com/cosmos/cosmos-sdk/x/auth"
	authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
	authsims "github.com/cosmos/cosmos-sdk/x/auth/simulation"
	_ "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"
	authzkeeper "github.com/cosmos/cosmos-sdk/x/authz/keeper"
	authzmodule "github.com/cosmos/cosmos-sdk/x/authz/module"
    "github.com/cosmos/cosmos-sdk/x/bank"
	bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper"
    "github.com/cosmos/cosmos-sdk/x/capability"
	capabilitykeeper "github.com/cosmos/cosmos-sdk/x/capability/keeper"
	consensus "github.com/cosmos/cosmos-sdk/x/consensus"
	consensuskeeper "github.com/cosmos/cosmos-sdk/x/consensus/keeper"
    "github.com/cosmos/cosmos-sdk/x/crisis"
	crisiskeeper "github.com/cosmos/cosmos-sdk/x/crisis/keeper"
	distr "github.com/cosmos/cosmos-sdk/x/distribution"
	distrkeeper "github.com/cosmos/cosmos-sdk/x/distribution/keeper"
    "github.com/cosmos/cosmos-sdk/x/evidence"
	evidencekeeper "github.com/cosmos/cosmos-sdk/x/evidence/keeper"
	feegrantkeeper "github.com/cosmos/cosmos-sdk/x/feegrant/keeper"
	feegrantmodule "github.com/cosmos/cosmos-sdk/x/feegrant/module"
    "github.com/cosmos/cosmos-sdk/x/genutil"
	genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types"
    "github.com/cosmos/cosmos-sdk/x/gov"
	govclient "github.com/cosmos/cosmos-sdk/x/gov/client"
	govkeeper "github.com/cosmos/cosmos-sdk/x/gov/keeper"
	groupkeeper "github.com/cosmos/cosmos-sdk/x/group/keeper"
	groupmodule "github.com/cosmos/cosmos-sdk/x/group/module"
    "github.com/cosmos/cosmos-sdk/x/mint"
	mintkeeper "github.com/cosmos/cosmos-sdk/x/mint/keeper"
	nftkeeper "github.com/cosmos/cosmos-sdk/x/nft/keeper"
	nftmodule "github.com/cosmos/cosmos-sdk/x/nft/module"
    "github.com/cosmos/cosmos-sdk/x/params"
	paramsclient "github.com/cosmos/cosmos-sdk/x/params/client"
	paramskeeper "github.com/cosmos/cosmos-sdk/x/params/keeper"
	paramstypes "github.com/cosmos/cosmos-sdk/x/params/types"
    "github.com/cosmos/cosmos-sdk/x/slashing"
	slashingkeeper "github.com/cosmos/cosmos-sdk/x/slashing/keeper"
    "github.com/cosmos/cosmos-sdk/x/staking"
	stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper"
    "github.com/cosmos/cosmos-sdk/x/upgrade"
	upgradeclient "github.com/cosmos/cosmos-sdk/x/upgrade/client"
	upgradekeeper "github.com/cosmos/cosmos-sdk/x/upgrade/keeper"
)

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

	// ModuleBasics defines the module BasicManager is in charge of setting up basic,
	// non-dependant module elements, such as codec registration
	// and genesis verification.
	ModuleBasics = module.NewBasicManager(
		auth.AppModuleBasic{
},
		genutil.NewAppModuleBasic(genutiltypes.DefaultMessageValidator),
		bank.AppModuleBasic{
},
		capability.AppModuleBasic{
},
		staking.AppModuleBasic{
},
		mint.AppModuleBasic{
},
		distr.AppModuleBasic{
},
		gov.NewAppModuleBasic(
			[]govclient.ProposalHandler{
    paramsclient.ProposalHandler,
				upgradeclient.LegacyProposalHandler,
				upgradeclient.LegacyCancelProposalHandler,
},
		),
		params.AppModuleBasic{
},
		crisis.AppModuleBasic{
},
		slashing.AppModuleBasic{
},
		feegrantmodule.AppModuleBasic{
},
		upgrade.AppModuleBasic{
},
		evidence.AppModuleBasic{
},
		authzmodule.AppModuleBasic{
},
		groupmodule.AppModuleBasic{
},
		vesting.AppModuleBasic{
},
		nftmodule.AppModuleBasic{
},
		consensus.AppModuleBasic{
},
	)
)

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

	// keepers
	AccountKeeper         authkeeper.AccountKeeper
	BankKeeper            bankkeeper.Keeper
	CapabilityKeeper      *capabilitykeeper.Keeper
	StakingKeeper         *stakingkeeper.Keeper
	SlashingKeeper        slashingkeeper.Keeper
	MintKeeper            mintkeeper.Keeper
	DistrKeeper           distrkeeper.Keeper
	GovKeeper             *govkeeper.Keeper
	CrisisKeeper          *crisiskeeper.Keeper
	UpgradeKeeper         *upgradekeeper.Keeper
	ParamsKeeper          paramskeeper.Keeper
	AuthzKeeper           authzkeeper.Keeper
	EvidenceKeeper        evidencekeeper.Keeper
	FeeGrantKeeper        feegrantkeeper.Keeper
	GroupKeeper           groupkeeper.Keeper
	NFTKeeper             nftkeeper.Keeper
	ConsensusParamsKeeper consensuskeeper.Keeper

	// simulation manager
	sm *module.SimulationManager
}

func init() {
    userHomeDir, err := os.UserHomeDir()
    if err != nil {
    panic(err)
}

DefaultNodeHome = filepath.Join(userHomeDir, ".simapp")
}

// 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
		// Below we could construct and set an application specific mempool and ABCI 1.0 Prepare and Process Proposal
		// handlers. These defaults are already set in the SDK's BaseApp, this shows an example of how to override
		// them.
		//
		// nonceMempool = mempool.NewSenderNonceMempool()
		// mempoolOpt   = baseapp.SetMempool(nonceMempool)
		// prepareOpt   = func(app *baseapp.BaseApp) {
		// 	app.SetPrepareProposal(app.DefaultPrepareProposal())
		//
}
		// processOpt = func(app *baseapp.BaseApp) {
		// 	app.SetProcessProposal(app.DefaultProcessProposal())
		//
}
		//
		// Further down we'd set the options in the AppBuilder like below.
		// baseAppOptions = append(baseAppOptions, mempoolOpt, prepareOpt, processOpt)

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

				// 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()

authtypes.AccountI {
    return authtypes.ProtoBaseAccount()
},

				//
				// 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.CapabilityKeeper,
		&app.StakingKeeper,
		&app.SlashingKeeper,
		&app.MintKeeper,
		&app.DistrKeeper,
		&app.GovKeeper,
		&app.CrisisKeeper,
		&app.UpgradeKeeper,
		&app.ParamsKeeper,
		&app.AuthzKeeper,
		&app.EvidenceKeeper,
		&app.FeeGrantKeeper,
		&app.GroupKeeper,
		&app.NFTKeeper,
		&app.ConsensusParamsKeeper,
	); err != nil {
    panic(err)
}

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

	// load state streaming if enabled
    if _, _, err := streaming.LoadStreamingServices(app.App.BaseApp, appOpts, app.appCodec, logger, app.kvStoreKeys()); err != nil {
    logger.Error("failed to load state streaming", "err", err)

os.Exit(1)
}

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

	app.ModuleManager.RegisterInvariants(app.CrisisKeeper)

	// 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, app.GetSubspace(authtypes.ModuleName)),
}

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 {
	// 	app.UpgradeKeeper.SetModuleVersionMap(ctx, app.ModuleManager.GetVersionMap())
	// 	return app.App.InitChainer(ctx, req)
	//
})
    if err := app.Load(loadLatest); err != nil {
    panic(err)
}

return app
}

// Name returns the name of the App
func (app *SimApp)

Name()

string {
    return app.BaseApp.Name()
}

// 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
}

// GetSubspace returns a param subspace for a given module name.
//
// NOTE: This is solely to be used for testing purposes.
func (app *SimApp)

GetSubspace(moduleName string)

paramstypes.Subspace {
    subspace, _ := app.ParamsKeeper.GetSubspace(moduleName)

return subspace
}

// 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
}
```
