diff --git a/.github/workflows/md-link-checker-config.json b/.github/workflows/md-link-checker-config.json index 6dedfd4ed2..8c15416958 100644 --- a/.github/workflows/md-link-checker-config.json +++ b/.github/workflows/md-link-checker-config.json @@ -1,5 +1,8 @@ { "ignorePatterns": [ + { + "pattern": "^https://twitter.com" + }, { "pattern": "^https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/reviewing-changes-in-pull-requests/commenting-on-a-pull-request" }, diff --git a/.gitpod/readme.md b/.gitpod/readme.md index 3503c1fd98..6894ce078e 100644 --- a/.gitpod/readme.md +++ b/.gitpod/readme.md @@ -42,7 +42,7 @@ ignite chain serve curl https://get.ignite.com/cli | bash ``` -The latest `ignite` binary is downloaded from the project repo and installed in `/usr/local/bin`. Learn more about [installing Ignite CLI](https://docs.ignite.com/guide/install). +The latest `ignite` binary is downloaded from the project repo and installed in `/usr/local/bin`. Learn more about [installing Ignite CLI](https://docs.ignite.com/welcome/install). ## Stay in touch diff --git a/contributing.md b/contributing.md index 8a5f051a21..4d7bd22bb3 100644 --- a/contributing.md +++ b/contributing.md @@ -68,11 +68,10 @@ used as the commit message. When you open a PR for the Ignite CLI codebase, you must also update the relevant documentation. For changes to: -* [Developer Guide](https://docs.ignite.com/guide) tutorials, update content in the `/docs/guide` folder. -* [Knowledge Base](https://docs.ignite.com/kb), update content in the `/docs/kb` folder. -* [Ignite CLI reference](https://docs.ignite.com/cli), navigate to the `./ignite/cmd` package and update the +* [Developer Guide](https://docs.ignite.com/guide) tutorials, update content in the `/docs/docs/02-guide` folder. +* [Ignite CLI reference](https://docs.ignite.com/references/cli), navigate to the `./ignite/cmd` package and update the documentation of the related command from its `cobra.Command` struct. The CLI docs are automatically generated, so do - not make changes to `docs/cli/index.md`. + not make changes to `docs/docs/08-references/01-cli.md`. ### Ask for help diff --git a/docs/docs/02-guide/02-getting-started.md b/docs/docs/02-guide/02-getting-started.md index d1d8c7c161..09b48891e5 100644 --- a/docs/docs/02-guide/02-getting-started.md +++ b/docs/docs/02-guide/02-getting-started.md @@ -29,8 +29,8 @@ following command: ignite scaffold chain example ``` -The [`ignite scaffold chain`](../references/cli#ignite-scaffold-chain) command will create a -new blockchain in a new directory `example`. +The `ignite scaffold chain` command will create a new blockchain in a new +directory `example`. The new blockchain is built using the Cosmos SDK framework and imports several standard modules to provide a range of functionality. These modules include @@ -132,14 +132,13 @@ To start a blockchain node in development, you can run the following command: ignite chain serve ``` -The [`ignite chain serve`](../references/cli#ignite-scaffold-chain) command is used to start -a blockchain node in development mode. It first compiles and installs the binary -using the `ignite chain build` command, then initializes the blockchain's data -directory for a single validator using the `ignite chain init` command. After -that, it starts the node locally and enables automatic code reloading so that -changes to the code can be reflected in the running blockchain without having to -restart the node. This allows for faster development and testing of the -blockchain. +The `ignite chain serve` command is used to start a blockchain node in +development mode. It first compiles and installs the binary using the +`ignite chain build` command, then initializes the blockchain's data directory +for a single validator using the `ignite chain init` command. After that, it +starts the node locally and enables automatic code reloading so that changes to +the code can be reflected in the running blockchain without having to restart +the node. This allows for faster development and testing of the blockchain. Congratulations! 🥳 You have successfully created a brand-new Cosmos blockchain using the Ignite CLI. This blockchain uses the delegated proof of stake (DPoS) diff --git a/docs/docs/03-clients/02-typescript.md b/docs/docs/03-clients/02-typescript.md index 3c8d29e81d..5cfbf7705d 100644 --- a/docs/docs/03-clients/02-typescript.md +++ b/docs/docs/03-clients/02-typescript.md @@ -8,8 +8,7 @@ Ignite offers powerful functionality for generating client-side code for your blockchain. Think of this as a one-click client SDK generation tailored specifically for your blockchain. -See [`ignite generate ts-client --help`](../references/cli#ignite-generate-ts-client) learn -more on how to use TypeScript code generation. +See `ignite generate ts-client --help` learn more on how to use TypeScript code generation. ## Starting a node diff --git a/docs/docs/06-migration/v0.26.0.md b/docs/docs/06-migration/v0.26.0.md index f8895aabf1..61bf0c5dbb 100644 --- a/docs/docs/06-migration/v0.26.0.md +++ b/docs/docs/06-migration/v0.26.0.md @@ -22,7 +22,7 @@ specific changes that will need to be followed for Ignite scaffolded chains. ### Removing `cosmosibckeeper` -Ignite CLI `v0.26.0` has deprecated [pkg/cosmosibckeeper](https://github.com/ignite/cli/tree/main/ignite/pkg/cosmosibckeeper). +Ignite CLI `v0.26.0` has deprecated [pkg/cosmosibckeeper](https://github.com/ignite/cli/tree/v0.26.0/ignite/pkg/cosmosibckeeper). This package contained interfaces for ibc-related keepers. Newly scaffolded chains now include the interface files in their `./x/{moduleName}/types` directory in a new `expected_ibc_keeper.go` file. To migrate, create the following file for each module: diff --git a/docs/docs/06-migration/v0.27.1.md b/docs/docs/06-migration/v0.27.1.md new file mode 100644 index 0000000000..7ef0f8c4d6 --- /dev/null +++ b/docs/docs/06-migration/v0.27.1.md @@ -0,0 +1,1210 @@ +--- +sidebar_position: 991 +title: v0.27.1 +description: For chains that were scaffolded with Ignite CLI versions lower than v0.27.0. changes are required to use Ignite CLI v0.27.1. +--- + +## Cosmos SDK v0.47.3 upgrade notes + +### Imports + +To use the new cosmos SDK make sure you update `go.mod` dependencies: + +```go title="go.mod" +go 1.19 + +require ( + // remove-start + github.com/cosmos/cosmos-sdk v0.46.7 + github.com/tendermint/tendermint v0.34.24 + github.com/tendermint/tm-db v0.6.7 + github.com/cosmos/ibc-go/v7 v7.1.0 + github.com/gogo/protobuf v1.3.3 + github.com/regen-network/cosmos-proto v0.3.1 + // remove-end + // highlight-start + cosmossdk.io/api v0.3.1 + github.com/cosmos/cosmos-sdk v0.47.3 + github.com/cometbft/cometbft v0.37.1 + github.com/cometbft/cometbft-db v0.7.0 + github.com/cosmos/ibc-go/v6 v6.1.0 + github.com/cosmos/gogoproto v1.4.7 + // highlight-end + + // ... +) + +replace ( + // remove-start + github.com/confio/ics23/go => github.com/cosmos/cosmos-sdk/ics23/go v0.8.0 + github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 + // remove-end + // highlight-next-line + github.com/syndtr/goleveldb => github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 +) +``` + +The Cosmos SDK has migrated to CometBFT as its default consensus engine which requires +changes in your app imports: + +1. Replace `github.com/tendermint/tendermint` by `github.com/cometbft/cometbft` +2. Replace `github.com/tendermint/tm-db` by `github.com/cometbft/cometbft-db` +3. Verify `github.com/tendermint/tendermint` is not an indirect or direct dependency + +The SDK has also migrated from `gogo/protobuf` to `cosmos/gogoproto`. This means you must +replace all `github.com/gogo/protobuf` imports with `github.com/cosmos/gogoproto`. This change +might introduce breaking changes to your proto layout. Follow the official +[Cosmos migration guide](https://docs.cosmos.network/main/migrations/upgrading#gogoproto-import-paths) +to make sure you are using the correct layout. + +You might need to replace the following imports: + +1. Replace `github.com/cosmos/cosmos-sdk/simapp` by `cosmossdk.io/simapp` + +### App changes + +Applications scaffolded with older version of Ignite CLI would require the following changes +to some of the app files: + +```go title="app/app.go" +import ( + //... + + // remove-next-line + tmjson "github.com/tendermint/tendermint/libs/json" + // highlight-next-line + "encoding/json" + + // highlight-start + autocliv1 "cosmossdk.io/api/cosmos/autocli/v1" + reflectionv1 "cosmossdk.io/api/cosmos/reflection/v1" + "github.com/cosmos/cosmos-sdk/runtime" + runtimeservices "github.com/cosmos/cosmos-sdk/runtime/services" + "github.com/cosmos/cosmos-sdk/x/consensus" + consensusparamkeeper "github.com/cosmos/cosmos-sdk/x/consensus/keeper" + consensusparamtypes "github.com/cosmos/cosmos-sdk/x/consensus/types" + // highlight-end +) + +func getGovProposalHandlers() []govclient.ProposalHandler { + // ... + govProposalHandlers = append(govProposalHandlers, + paramsclient.ProposalHandler, + // remove-next-line + distrclient.ProposalHandler, + upgradeclient.LegacyProposalHandler, + // ... + ) + + return govProposalHandlers +} + +var ( + // ... + + ModuleBasics = module.NewBasicManager( + auth.AppModuleBasic{}, + authzmodule.AppModuleBasic{}, + // remove-next-line + genutil.AppModuleBasic{}, + // highlight-next-line + genutil.NewAppModuleBasic(genutiltypes.DefaultMessageValidator), + bank.AppModuleBasic{}, + // ... + vesting.AppModuleBasic{}, + // highlight-next-line + consensus.AppModuleBasic{}, + //... + ) +) + +var ( + // highlight-next-line + _ runtime.AppI = (*App)(nil) + _ servertypes.Application = (*App)(nil) + // remove-next-line + _ simapp.App = (*App)(nil) +) + +type App struct { + *baseapp.BaseApp + + cdc *codec.LegacyAmino + appCodec codec.Codec + interfaceRegistry types.InterfaceRegistry + // highlight-next-line + txConfig client.TxConfig + + invCheckPeriod uint + + // ... + // remove-start + StakingKeeper stakingkeeper.Keeper + CrisisKeeper crisiskeeper.Keeper + UpgradeKeeper upgradekeeper.Keeper + // remove-end + // highlight-start + StakingKeeper *stakingkeeper.Keeper + CrisisKeeper *crisiskeeper.Keeper + UpgradeKeeper *upgradekeeper.Keeper + // highlight-end + // ... + FeeGrantKeeper feegrantkeeper.Keeper + GroupKeeper groupkeeper.Keeper + // highlight-next-line + ConsensusParamsKeeper consensusparamkeeper.Keeper + + // ... +} + +func New( + logger log.Logger, + db dbm.DB, + traceStore io.Writer, + loadLatest bool, + skipUpgradeHeights map[int64]bool, + homePath string, + invCheckPeriod uint, + encodingConfig appparams.EncodingConfig, + appOpts servertypes.AppOptions, + baseAppOptions ...func(*baseapp.BaseApp), +) *App { + appCodec := encodingConfig.Marshaler + cdc := encodingConfig.Amino + interfaceRegistry := encodingConfig.InterfaceRegistry + // highlight-next-line + txConfig := encodingConfig.TxConfig + + // ... + + bApp.SetCommitMultiStoreTracer(traceStore) + bApp.SetVersion(version.Version) + bApp.SetInterfaceRegistry(interfaceRegistry) + // highlight-next-line + bApp.SetTxEncoder(txConfig.TxEncoder()) + + keys := sdk.NewKVStoreKeys( + // ... + banktypes.StoreKey, + stakingtypes.StoreKey, + // highlight-next-line + crisistypes.StoreKey, + // ... + group.StoreKey, + icacontrollertypes.StoreKey, + // highlight-next-line + consensusparamtypes.StoreKey, + // ... + ) + + // ... + + app := &App{ + // ... + interfaceRegistry: interfaceRegistry, + // highlight-next-line + txConfig: txConfig, + invCheckPeriod: invCheckPeriod, + // ... + } + + // ... + + // set the BaseApp's parameter store + // remove-next-line + bApp.SetParamStore(app.ParamsKeeper.Subspace(baseapp.Paramspace).WithKeyTable(paramstypes.ConsensusParamsKeyTable())) + // highlight-start + app.ConsensusParamsKeeper = consensusparamkeeper.NewKeeper(appCodec, keys[upgradetypes.StoreKey], authtypes.NewModuleAddress(govtypes.ModuleName).String()) + bApp.SetParamStore(&app.ConsensusParamsKeeper) + // highlight-end + + // ... + + app.AccountKeeper = authkeeper.NewAccountKeeper( + appCodec, + keys[authtypes.StoreKey], + // remove-next-line + app.GetSubspace(authtypes.ModuleName), + authtypes.ProtoBaseAccount, + maccPerms, + sdk.Bech32PrefixAccAddr, + // highlight-next-line + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + ) + + app.BankKeeper = bankkeeper.NewBaseKeeper( + appCodec, + keys[banktypes.StoreKey], + app.AccountKeeper, + // remove-next-line + app.GetSubspace(banktypes.ModuleName), + app.BlockedModuleAccountAddrs(), + // highlight-next-line + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + ) + + app.StakingKeeper = stakingkeeper.NewKeeper( + appCodec, + keys[stakingtypes.StoreKey], + app.AccountKeeper, + app.BankKeeper, + // remove-next-line + app.GetSubspace(stakingtypes.ModuleName), + // highlight-next-line + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + ) + + app.MintKeeper = mintkeeper.NewKeeper( + appCodec, + keys[minttypes.StoreKey], + // remove-next-line + app.GetSubspace(minttypes.ModuleName), + // remove-next-line + &app.StakingKeeper, + // highlight-next-line + app.StakingKeeper, + app.AccountKeeper, + app.BankKeeper, + authtypes.FeeCollectorName, + // highlight-next-line + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + ) + + app.DistrKeeper = distrkeeper.NewKeeper( + appCodec, + keys[distrtypes.StoreKey], + // remove-next-line + app.GetSubspace(distrtypes.ModuleName), + app.AccountKeeper, + app.BankKeeper, + // remove-next-line + &app.StakingKeeper, + // highlight-next-line + app.StakingKeeper, + authtypes.FeeCollectorName, + // highlight-next-line + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + ) + + app.SlashingKeeper = slashingkeeper.NewKeeper( + appCodec, + // highlight-next-line + cdc, + keys[slashingtypes.StoreKey], + // remove-next-line + &app.StakingKeeper, + // highlight-next-line + app.StakingKeeper, + // remove-next-line + app.GetSubspace(slashingtypes.ModuleName), + // highlight-next-line + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + ) + + app.CrisisKeeper = crisiskeeper.NewKeeper( + // remove-next-line + app.GetSubspace(crisistypes.ModuleName), + // highlight-start + appCodec, + keys[crisistypes.StoreKey], + // highlight-end + invCheckPeriod, + app.BankKeeper, + authtypes.FeeCollectorName, + // highlight-next-line + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + ) + + // ... + + // Create evidence Keeper for to register the IBC light client misbehaviour evidence route + evidenceKeeper := evidencekeeper.NewKeeper( + appCodec, + keys[evidencetypes.StoreKey], + // remove-next-line + &app.StakingKeeper, + // highlight-next-line + app.StakingKeeper, + app.SlashingKeeper, + ) + // If evidence needs to be handled for the app, set routes in router here and seal + app.EvidenceKeeper = *evidenceKeeper + + // highlight-start + govConfig := govtypes.DefaultConfig() + govKeeper := govkeeper.NewKeeper( + appCodec, + keys[govtypes.StoreKey], + app.AccountKeeper, + app.BankKeeper, + app.StakingKeeper, + app.MsgServiceRouter(), + govConfig, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + ) + // highlight-end + + govRouter := govv1beta1.NewRouter() + govRouter. + AddRoute(govtypes.RouterKey, govv1beta1.ProposalHandler). + AddRoute(paramproposal.RouterKey, params.NewParamChangeProposalHandler(app.ParamsKeeper)). + // remove-next-line + AddRoute(distrtypes.RouterKey, distr.NewCommunityPoolSpendProposalHandler(app.DistrKeeper)). + AddRoute(upgradetypes.RouterKey, upgrade.NewSoftwareUpgradeProposalHandler(app.UpgradeKeeper)). + AddRoute(ibcclienttypes.RouterKey, ibcclient.NewClientProposalHandler(app.IBCKeeper.ClientKeeper)) + // highlight-next-line + govKeeper.SetLegacyRouter(govRouter) + + // remove-start + govConfig := govtypes.DefaultConfig() + app.GovKeeper = govkeeper.NewKeeper( + appCodec, + keys[govtypes.StoreKey], + app.GetSubspace(govtypes.ModuleName), + app.AccountKeeper, + app.BankKeeper, + &app.StakingKeeper, + govRouter, + app.MsgServiceRouter(), + govConfig, + ) + // remove-end + // highlight-start + app.GovKeeper = *govKeeper.SetHooks( + govtypes.NewMultiGovHooks( + // register the governance hooks + ), + ) + // highlight-end + + // ... + + // remove-start + app.GovKeeper.SetHooks( + govtypes.NewMultiGovHooks( + // insert governance hooks receivers here + ), + ) + // remove-end + + // ... + + app.mm = module.NewManager( + genutil.NewAppModule( + app.AccountKeeper, + app.StakingKeeper, + app.BaseApp.DeliverTx, + encodingConfig.TxConfig, + ), + // remove-next-line + auth.NewAppModule(appCodec, app.AccountKeeper, nil), + // highlight-next-line + auth.NewAppModule(appCodec, app.AccountKeeper, authsims.RandomGenesisAccounts, app.GetSubspace(authtypes.ModuleName)), + authzmodule.NewAppModule(appCodec, app.AuthzKeeper, app.AccountKeeper, app.BankKeeper, app.interfaceRegistry), + vesting.NewAppModule(app.AccountKeeper, app.BankKeeper), + // remove-start + bank.NewAppModule(appCodec, app.BankKeeper, app.AccountKeeper), + capability.NewAppModule(appCodec, *app.CapabilityKeeper), + // remove-end + // highlight-start + bank.NewAppModule(appCodec, app.BankKeeper, app.AccountKeeper, app.GetSubspace(banktypes.ModuleName)), + capability.NewAppModule(appCodec, *app.CapabilityKeeper, false), + // highlight-end + feegrantmodule.NewAppModule(appCodec, app.AccountKeeper, app.BankKeeper, app.FeeGrantKeeper, app.interfaceRegistry), + groupmodule.NewAppModule(appCodec, app.GroupKeeper, app.AccountKeeper, app.BankKeeper, app.interfaceRegistry), + // remove-start + crisis.NewAppModule(&app.CrisisKeeper, skipGenesisInvariants), + gov.NewAppModule(appCodec, app.GovKeeper, app.AccountKeeper, app.BankKeeper), + mint.NewAppModule(appCodec, app.MintKeeper, app.AccountKeeper, minttypes.DefaultInflationCalculationFn), + slashing.NewAppModule(appCodec, app.SlashingKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper), + distr.NewAppModule(appCodec, app.DistrKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper), + staking.NewAppModule(appCodec, app.StakingKeeper, app.AccountKeeper, app.BankKeeper), + // remove-end + // highlight-start + gov.NewAppModule(appCodec, &app.GovKeeper, app.AccountKeeper, app.BankKeeper, app.GetSubspace(govtypes.ModuleName)), + mint.NewAppModule(appCodec, app.MintKeeper, app.AccountKeeper, nil, app.GetSubspace(minttypes.ModuleName)), + slashing.NewAppModule(appCodec, app.SlashingKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper, app.GetSubspace(slashingtypes.ModuleName)), + distr.NewAppModule(appCodec, app.DistrKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper, app.GetSubspace(distrtypes.ModuleName)), + staking.NewAppModule(appCodec, app.StakingKeeper, app.AccountKeeper, app.BankKeeper, app.GetSubspace(stakingtypes.ModuleName)), + // highlight-end + upgrade.NewAppModule(app.UpgradeKeeper), + evidence.NewAppModule(app.EvidenceKeeper), + // highlight-next-line + consensus.NewAppModule(appCodec, app.ConsensusParamsKeeper), + ibc.NewAppModule(app.IBCKeeper), + params.NewAppModule(app.ParamsKeeper), + transferModule, + icaModule, + // this line is used by starport scaffolding # stargate/app/appModule + + // highlight-start + // always be last to make sure that it checks for all invariants and not only part of them + crisis.NewAppModule(app.CrisisKeeper, skipGenesisInvariants, app.GetSubspace(crisistypes.ModuleName)), + // highlight-end + ) + + app.mm.SetOrderBeginBlockers( + // ... + paramstypes.ModuleName, + vestingtypes.ModuleName, + // highlight-next-line + consensusparamtypes.ModuleName, + // ... + ) + + app.mm.SetOrderEndBlockers( + // ... + paramstypes.ModuleName, + upgradetypes.ModuleName, + vestingtypes.ModuleName, + // highlight-next-line + consensusparamtypes.ModuleName, + // ... + ) + + // remove-next-line + app.mm.SetOrderInitGenesis( + // highlight-next-line + genesisModuleOrder := []string{ + // ... + paramstypes.ModuleName, + upgradetypes.ModuleName, + vestingtypes.ModuleName, + // highlight-next-line + consensusparamtypes.ModuleName, + // ... + // remove-next-line + ) + // highlight-start + } + app.mm.SetOrderInitGenesis(genesisModuleOrder...) + app.mm.SetOrderExportGenesis(genesisModuleOrder...) + // highlight-end + + // remove-start + app.mm.RegisterInvariants(&app.CrisisKeeper) + app.mm.RegisterRoutes(app.Router(), app.QueryRouter(), encodingConfig.Amino) + // remove-end + // highlight-next-line + app.mm.RegisterInvariants(app.CrisisKeeper) + + app.configurator = module.NewConfigurator(app.appCodec, app.MsgServiceRouter(), app.GRPCQueryRouter()) + app.mm.RegisterServices(app.configurator) + + // highlight-start + autocliv1.RegisterQueryServer(app.GRPCQueryRouter(), runtimeservices.NewAutoCLIQueryService(app.mm.Modules)) + reflectionSvc, err := runtimeservices.NewReflectionService() + if err != nil { + panic(err) + } + reflectionv1.RegisterReflectionServiceServer(app.GRPCQueryRouter(), reflectionSvc) + // highlight-end + + // create the simulation manager and define the order of the modules for deterministic simulations + // remove-start + app.sm = module.NewSimulationManager( + // ... + ) + // remove-end + // highlight-start + overrideModules := map[string]module.AppModuleSimulation{ + authtypes.ModuleName: auth.NewAppModule(app.appCodec, app.AccountKeeper, authsims.RandomGenesisAccounts, app.GetSubspace(authtypes.ModuleName)), + } + app.sm = module.NewSimulationManagerFromAppModules(app.mm.Modules, overrideModules) + // highlight-end + app.sm.RegisterStoreDecoders() + + // ... + + // remove-start + app.SetInitChainer(app.InitChainer) + app.SetBeginBlocker(app.BeginBlocker) + // remove-end + + // ... +} + +func (app *App) InitChainer(ctx sdk.Context, req abci.RequestInitChain) abci.ResponseInitChain { + var genesisState GenesisState + // remove-next-line + if err := tmjson.Unmarshal(req.AppStateBytes, &genesisState); err != nil { + // highlight-next-line + if err := json.Unmarshal(req.AppStateBytes, &genesisState); err != nil { + panic(err) + } + // ... +} + +// remove-start +// GetMaccPerms returns a copy of the module account permissions +func GetMaccPerms() map[string][]string { + dupMaccPerms := make(map[string][]string) + for k, v := range maccPerms { + dupMaccPerms[k] = v + } + return dupMaccPerms +} +// remove-end + +// highlight-start +// TxConfig returns App's TxConfig. +func (app *App) TxConfig() client.TxConfig { + return app.txConfig +} + +// Configurator get app configurator +func (app *App) Configurator() module.Configurator { + return app.configurator +} + +// ModuleManager returns the app ModuleManager +func (app *App) ModuleManager() *module.Manager { + return app.mm +} +// highlight-end +``` + +```go title="app/simulation_test.go" +import ( + // ... + // remove-start + "cosmossdk.io/simapp" + tmtypes "github.com/tendermint/tendermint/types" + // remove-end + // highlight-start + "encoding/json" + "fmt" + "math/rand" + "runtime/debug" + "strings" + + dbm "github.com/cometbft/cometbft-db" + "github.com/cometbft/cometbft/libs/log" + "github.com/cosmos/cosmos-sdk/baseapp" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/server" + storetypes "github.com/cosmos/cosmos-sdk/store/types" + simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" + sdk "github.com/cosmos/cosmos-sdk/types" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + authzkeeper "github.com/cosmos/cosmos-sdk/x/authz/keeper" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" + distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types" + evidencetypes "github.com/cosmos/cosmos-sdk/x/evidence/types" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" + paramstypes "github.com/cosmos/cosmos-sdk/x/params/types" + simcli "github.com/cosmos/cosmos-sdk/x/simulation/client/cli" + slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + // highlight-end +) + +// highlight-start +type storeKeysPrefixes struct { + A storetypes.StoreKey + B storetypes.StoreKey + Prefixes [][]byte +} +// highlight-end + +// Get flags every time the simulator is run +func init() { + // remove-next-line + simapp.GetSimulatorFlags() + // highlight-next-line + simcli.GetSimulatorFlags() +} + +// remove-start +var defaultConsensusParams = &abci.ConsensusParams{ + Block: &abci.BlockParams{ + MaxBytes: 200000, + MaxGas: 2000000, + }, + Evidence: &tmproto.EvidenceParams{ + MaxAgeNumBlocks: 302400, + MaxAgeDuration: 504 * time.Hour, // 3 weeks is the max duration + MaxBytes: 10000, + }, + Validator: &tmproto.ValidatorParams{ + PubKeyTypes: []string{ + tmtypes.ABCIPubKeyTypeEd25519, + }, + }, +} +// remove-end +// highlight-start +func fauxMerkleModeOpt(bapp *baseapp.BaseApp) { + bapp.SetFauxMerkleMode() +} +// highlight-end + +func BenchmarkSimulation(b *testing.B) { + // remove-start + simapp.FlagEnabledValue = true + simapp.FlagCommitValue = true + + config, db, dir, logger, _, err := simapp.SetupSimulation("goleveldb-app-sim", "Simulation") + // remove-end + // highlight-start + simcli.FlagSeedValue = time.Now().Unix() + simcli.FlagVerboseValue = true + simcli.FlagCommitValue = true + simcli.FlagEnabledValue = true + + config := simcli.NewConfigFromFlags() + config.ChainID = "mars-simapp" + db, dir, logger, _, err := simtestutil.SetupSimulation( + config, + "leveldb-bApp-sim", + "Simulation", + simcli.FlagVerboseValue, + simcli.FlagEnabledValue, + ) + // highlight-end + + require.NoError(b, err, "simulation setup failed") + + b.Cleanup(func() { + // remove-start + db.Close() + err = os.RemoveAll(dir) + require.NoError(b, err) + // remove-end + // highlight-start + require.NoError(b, db.Close()) + require.NoError(b, os.RemoveAll(dir)) + // highlight-end + }) + + + // remove-next-line + encoding := app.MakeEncodingConfig() + // highlight-start + appOptions := make(simtestutil.AppOptionsMap, 0) + appOptions[flags.FlagHome] = app.DefaultNodeHome + appOptions[server.FlagInvCheckPeriod] = simcli.FlagPeriodValue + // highlight-end + + // remove-next-line + app := app.New( + // highlight-next-line + bApp := app.New( + logger, + db, + nil, + true, + map[int64]bool{}, + app.DefaultNodeHome, + 0, + // remove-start + encoding, + simapp.EmptyAppOptions{}, + // remove-end + // highlight-start + app.MakeEncodingConfig(), + appOptions, + baseapp.SetChainID(config.ChainID), + // highlight-end + ) + // highlight-next-line + require.Equal(b, app.Name, bApp.Name()) + + _, simParams, simErr := simulation.SimulateFromSeed( + b, + os.Stdout, + // remove-start + app.BaseApp, + simapp.AppStateFn(app.AppCodec(), app.SimulationManager()), + simulationtypes.RandomAccounts, + simapp.SimulationOperations(app, app.AppCodec(), config), + app.ModuleAccountAddrs(), + config, + app.AppCodec(), + // remove-end + // highlight-start + bApp.BaseApp, + simtestutil.AppStateFn( + bApp.AppCodec(), + bApp.SimulationManager(), + app.NewDefaultGenesisState(bApp.AppCodec()), + ), + simtestutil.SimulationOperations(bApp, bApp.AppCodec(), config), + bApp.ModuleAccountAddrs(), + config, + bApp.AppCodec(), + // highlight-end + ) + + // remove-next-line + err = simapp.CheckExportSimulation(app, config, simParams) + // highlight-next-line + err = simtestutil.CheckExportSimulation(bApp, config, simParams) + require.NoError(b, err) + require.NoError(b, simErr) + + if config.Commit { + // remove-next-line + simapp.PrintStats(db) + // highlight-next-line + simtestutil.PrintStats(db) + } +} +``` + +```go title="x/{{moduleName}}/module_simulation.go" +import ( + // ... + // remove-next-line + simappparams "cosmossdk.io/simapp/params" +) + +var ( + // ... + // remove-next-line + _ = simappparams.StakePerAccount + // highlight-next-line + _ = rand.Rand{} +) + +// remove-start +func (am AppModule) RandomizedParams(_ *rand.Rand) []simtypes.ParamChange { + // ... +} +// remove-end +// highlight-start +// ProposalMsgs returns msgs used for governance proposals for simulations. +func (am AppModule) ProposalMsgs(simState module.SimulationState) []simtypes.WeightedProposalMsg { + return []simtypes.WeightedProposalMsg{ + // this line is used by starport scaffolding # simapp/module/OpMsg + } +} +// highlight-end +``` + +### Deprecations + +The app module might contains some legacy methods that are deprecated and can be removed: + +```go title="x/{{moduleName}}/module.go" +// remove-start +// Deprecated: use RegisterServices +func (am AppModule) Route() sdk.Route { return sdk.Route{} } + +// Deprecated: use RegisterServices +func (AppModule) QuerierRoute() string { return types.RouterKey } + +// Deprecated: use RegisterServices +func (am AppModule) LegacyQuerierHandler(_ *codec.LegacyAmino) sdk.Querier { + return nil +} +// remove-end +``` + +### Other required changes + +Changes required to the network test util: + +```go title="testutil/network/network.go" +import ( + // ... + + // remove-start + "github.com/cosmos/cosmos-sdk/simapp" + pruningtypes "github.com/cosmos/cosmos-sdk/pruning/types" + // remove-end + // highlight-start + pruningtypes "github.com/cosmos/cosmos-sdk/store/pruning/types" + simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" + // highlight-end +) + +func New(t *testing.T, configs ...Config) *Network { + // ... + + net, err := network.New(t, t.TempDir(), cfg) + require.NoError(t, err) + // highlight-start + _, err = net.WaitForHeight(1) + require.NoError(t, err) + // highlight-end + + // ... +} + +func DefaultConfig() network.Config { + // remove-next-line + encoding := app.MakeEncodingConfig() + // highlight-start + var ( + encoding = app.MakeEncodingConfig() + chainID = "chain-" + tmrand.NewRand().Str(6) + ) + // highlight-end + + return network.Config{ + // ... + // remove-next-line + AppConstructor: func(val network.Validator) servertypes.Application { + // highlight-next-line + AppConstructor: func(val network.ValidatorI) servertypes.Application { + return app.New( + // remove-next-line + val.Ctx.Logger, + // highlight-next-line + val.GetCtx().Logger, + tmdb.NewMemDB(), + nil, + true, + map[int64]bool{}, + // remove-next-line + val.Ctx.Config.RootDir, + // highlight-next-line + val.GetCtx().Config.RootDir, + 0, + encoding, + // remove-start + simapp.EmptyAppOptions{}, + baseapp.SetPruning(pruningtypes.NewPruningOptionsFromString(val.AppConfig.Pruning)), + baseapp.SetMinGasPrices(val.AppConfig.MinGasPrices), + // remove-end + // highlight-start + simtestutil.EmptyAppOptions{}, + baseapp.SetPruning(pruningtypes.NewPruningOptionsFromString(val.GetAppConfig().Pruning)), + baseapp.SetMinGasPrices(val.GetAppConfig().MinGasPrices), + baseapp.SetChainID(chainID), + // highlight-end + ) + }, + // ... + // remove-next-line + ChainID: "chain-" + tmrand.NewRand().Str(6), + // highlight-next-line + ChainID: chainID, + // ... + } +} +``` + +Update the collect genesis transactions command and add the new message validator argument: + +```go title="cmd/{{binaryNamePrefix}}d/cmd/root.go" +import ( + // ... + + // highlight-start + tmtypes "github.com/cometbft/cometbft/types" + "github.com/cosmos/cosmos-sdk/x/genutil" + genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" + // highlight-end +) + +func initRootCmd(rootCmd *cobra.Command, encodingConfig params.EncodingConfig) { + // ... + + // highlight-next-line + gentxModule := app.ModuleBasics[genutiltypes.ModuleName].(genutil.AppModuleBasic) + rootCmd.AddCommand( + // ... + // remove-next-line + genutilcli.CollectGenTxsCmd(banktypes.GenesisBalancesIterator{}, app.DefaultHome), + // highlight-next-line + genutilcli.CollectGenTxsCmd(banktypes.GenesisBalancesIterator{}, app.DefaultNodeHome, gentxModule.GenTxValidator), + // ... + ) + + // ... +} + +func (a appCreator) newApp( + logger log.Logger, + db dbm.DB, + traceStore io.Writer, + appOpts servertypes.AppOptions, +) servertypes.Application { + // ... + + pruningOpts, err := server.GetPruningOptionsFromFlags(appOpts) + if err != nil { + panic(err) + } + + // highlight-start + homeDir := cast.ToString(appOpts.Get(flags.FlagHome)) + chainID := cast.ToString(appOpts.Get(flags.FlagChainID)) + if chainID == "" { + // fallback to genesis chain-id + appGenesis, err := tmtypes.GenesisDocFromFile(filepath.Join(homeDir, "config", "genesis.json")) + if err != nil { + panic(err) + } + + chainID = appGenesis.ChainID + } + // highlight-end + + // ... + + return app.New( + // ... + baseapp.SetPruning(pruningOpts), + baseapp.SetMinGasPrices(cast.ToString(appOpts.Get(server.FlagMinGasPrices))), + // remove-next-line + baseapp.SetMinRetainBlocks(cast.ToUint64(appOpts.Get(server.FlagMinRetainBlocks))), + baseapp.SetHaltHeight(cast.ToUint64(appOpts.Get(server.FlagHaltHeight))), + baseapp.SetHaltTime(cast.ToUint64(appOpts.Get(server.FlagHaltTime))), + // highlight-next-line + baseapp.SetMinRetainBlocks(cast.ToUint64(appOpts.Get(server.FlagMinRetainBlocks))), + // ... + baseapp.SetIAVLDisableFastNode(cast.ToBool(appOpts.Get(server.FlagDisableIAVLFastNode))), + // highlight-next-line + baseapp.SetChainID(chainID), + ) +) + +func (a appCreator) appExport( + logger log.Logger, + db dbm.DB, + traceStore io.Writer, + height int64, + forZeroHeight bool, + jailAllowedAddrs []string, + appOpts servertypes.AppOptions, + // highlight-next-line + modulesToExport []string, +) (servertypes.ExportedApp, error) { + // ... + + // remove-next-line + return app.ExportAppStateAndValidators(forZeroHeight, jailAllowedAddrs) + // highlight-next-line + return app.ExportAppStateAndValidators(forZeroHeight, jailAllowedAddrs, modulesToExport) +} +``` + +Add the new extra argument to `ExportAppStateAndValidators`: + +```go title="app/export.go" +func (app *App) ExportAppStateAndValidators( + forZeroHeight bool, + jailAllowedAddrs []string, + // highlight-next-line + modulesToExport []string, +) (servertypes.ExportedApp, error) { + // ... + + // remove-next-line + genState := app.mm.ExportGenesis(ctx, app.appCodec) + // highlight-next-line + genState := app.mm.ExportGenesisForModules(ctx, app.appCodec, modulesToExport) + appState, err := json.MarshalIndent(genState, "", " ") + if err != nil { + return servertypes.ExportedApp{}, err + } + + // ... +} +``` + +### Migration + +You can also follow other Cosmos SDK migration steps in their [upgrade guide](https://docs.cosmos.network/main/migrations/upgrading#v047x). +Specially the [parameter migration](https://docs.cosmos.network/main/migrations/upgrading#xconsensus) which +is required if you want to run the updated version keeping you current app state. + +## Query commands + +Query commands context initialization should be changed to: + +```go title="x/{moduleName}/client/cli/query_{typeName}.go" +RunE: func(cmd *cobra.Command, args []string) (err error) { + // remove-next-line + clientCtx := client.GetClientContextFromCmd(cmd) + // highlight-start + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + // highlight-end + + // ... +} +``` + + +## ibc-go v7 + +Chains that are newly scaffolded with Ignite CLI `v0.27.1` now use `ibc-go/v7` for IBC functionality. It is +required to upgrade to the newest version of `ibc-go`. + +Applications scaffolded with older version of Ignite CLI require the following changes to the app file: + +```go title="app/app.go" +import ( + // ... + // remove-start + ica "github.com/cosmos/ibc-go/v6/modules/apps/27-interchain-accounts" + icacontrollerkeeper "github.com/cosmos/ibc-go/v6/modules/apps/27-interchain-accounts/controller/keeper" + icacontrollertypes "github.com/cosmos/ibc-go/v6/modules/apps/27-interchain-accounts/controller/types" + icahost "github.com/cosmos/ibc-go/v6/modules/apps/27-interchain-accounts/host" + icahostkeeper "github.com/cosmos/ibc-go/v6/modules/apps/27-interchain-accounts/host/keeper" + icahosttypes "github.com/cosmos/ibc-go/v6/modules/apps/27-interchain-accounts/host/types" + icatypes "github.com/cosmos/ibc-go/v6/modules/apps/27-interchain-accounts/types" + "github.com/cosmos/ibc-go/v6/modules/apps/transfer" + ibctransferkeeper "github.com/cosmos/ibc-go/v6/modules/apps/transfer/keeper" + ibctransfertypes "github.com/cosmos/ibc-go/v6/modules/apps/transfer/types" + ibc "github.com/cosmos/ibc-go/v6/modules/core" + ibcclient "github.com/cosmos/ibc-go/v6/modules/core/02-client" + ibcclientclient "github.com/cosmos/ibc-go/v6/modules/core/02-client/client" + ibcclienttypes "github.com/cosmos/ibc-go/v6/modules/core/02-client/types" + ibcporttypes "github.com/cosmos/ibc-go/v6/modules/core/05-port/types" + ibchost "github.com/cosmos/ibc-go/v6/modules/core/24-host" + ibckeeper "github.com/cosmos/ibc-go/v6/modules/core/keeper" + // remove-end + // highlight-start + ica "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts" + icacontrollerkeeper "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller/keeper" + icacontrollertypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller/types" + icahost "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/host" + icahostkeeper "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/host/keeper" + icahosttypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/host/types" + icatypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types" + "github.com/cosmos/ibc-go/v7/modules/apps/transfer" + ibctransferkeeper "github.com/cosmos/ibc-go/v7/modules/apps/transfer/keeper" + ibctransfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" + ibc "github.com/cosmos/ibc-go/v7/modules/core" + ibcclient "github.com/cosmos/ibc-go/v7/modules/core/02-client" + ibcclientclient "github.com/cosmos/ibc-go/v7/modules/core/02-client/client" + ibcclienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + ibcporttypes "github.com/cosmos/ibc-go/v7/modules/core/05-port/types" + ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported" + ibckeeper "github.com/cosmos/ibc-go/v7/modules/core/keeper" + solomachine "github.com/cosmos/ibc-go/v7/modules/light-clients/06-solomachine" + ibctm "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" + // highlight-end +) + +var ( + // ... + + ModuleBasics = module.NewBasicManager( + // ... + groupmodule.AppModuleBasic{}, + ibc.AppModuleBasic{}, + // highlight-start + ibctm.AppModuleBasic{}, + solomachine.AppModuleBasic{}, + // highlight-end + upgrade.AppModuleBasic{}, + // ... + ) +) + +func New( + logger log.Logger, + db dbm.DB, + traceStore io.Writer, + loadLatest bool, + skipUpgradeHeights map[int64]bool, + homePath string, + invCheckPeriod uint, + encodingConfig appparams.EncodingConfig, + appOpts servertypes.AppOptions, + baseAppOptions ...func(*baseapp.BaseApp), +) *App { + // ... + + keys := sdk.NewKVStoreKeys( + // ... + govtypes.StoreKey, + paramstypes.StoreKey, + // remove-next-line + ibchost.StoreKey, + // highlight-next-line + ibcexported.StoreKey, + // ... + ) + + // ... + // grant capabilities for the ibc and ibc-transfer modules + // remove-next-line + scopedIBCKeeper := app.CapabilityKeeper.ScopeToModule(ibchost.ModuleName) + // highlight-next-line + scopedIBCKeeper := app.CapabilityKeeper.ScopeToModule(ibcexported.ModuleName) + scopedICAControllerKeeper := app.CapabilityKeeper.ScopeToModule(icacontrollertypes.SubModuleName) + + // ... + + app.IBCKeeper = ibckeeper.NewKeeper( + appCodec, + // remove-start + keys[ibchost.StoreKey], + app.GetSubspace(ibchost.ModuleName), + // remove-end + // highlight-start + keys[ibcexported.StoreKey], + app.GetSubspace(ibcexported.ModuleName), + // highlight-end + app.StakingKeeper, + app.UpgradeKeeper, + scopedIBCKeeper, + ) + + // ... + + app.mm.SetOrderBeginBlockers( + // ... + crisistypes.ModuleName, + ibctransfertypes.ModuleName, + // remove-next-line + ibchost.ModuleName, + // highlight-next-line + ibcexported.ModuleName, + // ... + ) + + app.mm.SetOrderEndBlockers( + // ... + stakingtypes.ModuleName, + ibctransfertypes.ModuleName, + // remove-next-line + ibchost.ModuleName, + // highlight-next-line + ibcexported.ModuleName, + // ... + ) + + genesisModuleOrder := []string{ + // ... + genutiltypes.ModuleName, + ibctransfertypes.ModuleName, + // remove-next-line + ibchost.ModuleName, + // highlight-next-line + ibcexported.ModuleName, + // ... + } + + // ... +) + +func initParamsKeeper(appCodec codec.BinaryCodec, legacyAmino *codec.LegacyAmino, key, tkey storetypes.StoreKey) paramskeeper.Keeper { + // ... + paramsKeeper.Subspace(crisistypes.ModuleName) + paramsKeeper.Subspace(ibctransfertypes.ModuleName) + // remove-next-line + paramsKeeper.Subspace(ibchost.ModuleName) + // highlight-next-line + paramsKeeper.Subspace(ibcexported.ModuleName) + // ... +} +``` + + +You can follow other IBC migration steps in their [migration guide v6 to v7](https://github.com/cosmos/ibc-go/blob/v7.0.1/docs/migrations/v6-to-v7.md). + +## Doctor command + +As the final steps it's recommended to run `ignite doctor` and `go mod tidy`. diff --git a/docs/versioned_docs/version-v0.25.2/guide/04-nameservice/01-init.md b/docs/versioned_docs/version-v0.25.2/guide/04-nameservice/01-init.md index 735a3fbf08..ed865a804a 100644 --- a/docs/versioned_docs/version-v0.25.2/guide/04-nameservice/01-init.md +++ b/docs/versioned_docs/version-v0.25.2/guide/04-nameservice/01-init.md @@ -9,7 +9,7 @@ Scaffold a blockchain and create a `nameservice` module for the nameservice app. ## Create a Blockchain -Scaffold a new Cosmos SDK blockchain using the `ignite scaffold chain` command. The [ignite scaffold chain](../../../references/cli#ignite-scaffold-chain) command accepts one argument: the Go module path that is used for the project. +Scaffold a new Cosmos SDK blockchain using the `ignite scaffold chain` command. The `ignite scaffold chain` command accepts one argument: the Go module path that is used for the project. By default, a chain is scaffolded with a new empty Cosmos SDK module. You want to create the nameservice module without scaffolding a module, so use the `--no-module` flag: diff --git a/docs/versioned_docs/version-v0.25.2/guide/04-nameservice/02-messages.md b/docs/versioned_docs/version-v0.25.2/guide/04-nameservice/02-messages.md index 5919ee5abf..0f426c4147 100644 --- a/docs/versioned_docs/version-v0.25.2/guide/04-nameservice/02-messages.md +++ b/docs/versioned_docs/version-v0.25.2/guide/04-nameservice/02-messages.md @@ -70,7 +70,7 @@ Now, you are ready to implement these Cosmos SDK messages to achieve the desired Use the `ignite scaffold message` command to scaffold new messages for your module. -- The [`ignite scaffold message`](../../../references/cli#ignite-scaffold-message) command accepts the message name as the first argument and a list of fields for the message. +- The `ignite scaffold message` command accepts the message name as the first argument and a list of fields for the message. - By default, a message is scaffolded in a module with a name that matches the name of the project, in this case `nameservice`. ### Add the MsgBuyName Message diff --git a/docs/versioned_docs/version-v0.25.2/guide/04-nameservice/03-types.md b/docs/versioned_docs/version-v0.25.2/guide/04-nameservice/03-types.md index e9decc4a8f..23d04c3fdc 100644 --- a/docs/versioned_docs/version-v0.25.2/guide/04-nameservice/03-types.md +++ b/docs/versioned_docs/version-v0.25.2/guide/04-nameservice/03-types.md @@ -11,7 +11,7 @@ Now that you've defined messages that trigger state transitions, it's time to im For the nameservice blockchain, define a `whois` type and the create and delete methods. -Because Ignite CLI does the heavy lifting for you, choose from several [ignite scaffold](../../../references/cli#ignite-scaffold) commands to create CRUD functionality code for data stored in different ways: +Because Ignite CLI does the heavy lifting for you, choose from several `ignite scaffold` commands to create CRUD functionality code for data stored in different ways: - Array, a list-like data structure - Map (key-value pairs) diff --git a/docs/versioned_docs/version-v0.25.2/guide/06-loan.md b/docs/versioned_docs/version-v0.25.2/guide/06-loan.md index 0a269e64ba..518cd8c0a1 100644 --- a/docs/versioned_docs/version-v0.25.2/guide/06-loan.md +++ b/docs/versioned_docs/version-v0.25.2/guide/06-loan.md @@ -100,7 +100,7 @@ Use the `--dep` flag to specify that this module depends on and is going to inte ## Scaffold a list -Use the [scaffold list](../../references/cli#ignite-scaffold-list) command to scaffold code necessary to store loans in an array-like data structure: +Use the `ignite scaffold list` command to scaffold code necessary to store loans in an array-like data structure: ```bash ignite scaffold list loan amount fee collateral deadline state borrower lender --no-message diff --git a/docs/versioned_docs/version-v0.26.1/02-guide/02-getting-started.md b/docs/versioned_docs/version-v0.26.1/02-guide/02-getting-started.md index d1d8c7c161..09b48891e5 100644 --- a/docs/versioned_docs/version-v0.26.1/02-guide/02-getting-started.md +++ b/docs/versioned_docs/version-v0.26.1/02-guide/02-getting-started.md @@ -29,8 +29,8 @@ following command: ignite scaffold chain example ``` -The [`ignite scaffold chain`](../references/cli#ignite-scaffold-chain) command will create a -new blockchain in a new directory `example`. +The `ignite scaffold chain` command will create a new blockchain in a new +directory `example`. The new blockchain is built using the Cosmos SDK framework and imports several standard modules to provide a range of functionality. These modules include @@ -132,14 +132,13 @@ To start a blockchain node in development, you can run the following command: ignite chain serve ``` -The [`ignite chain serve`](../references/cli#ignite-scaffold-chain) command is used to start -a blockchain node in development mode. It first compiles and installs the binary -using the `ignite chain build` command, then initializes the blockchain's data -directory for a single validator using the `ignite chain init` command. After -that, it starts the node locally and enables automatic code reloading so that -changes to the code can be reflected in the running blockchain without having to -restart the node. This allows for faster development and testing of the -blockchain. +The `ignite chain serve` command is used to start a blockchain node in +development mode. It first compiles and installs the binary using the +`ignite chain build` command, then initializes the blockchain's data directory +for a single validator using the `ignite chain init` command. After that, it +starts the node locally and enables automatic code reloading so that changes to +the code can be reflected in the running blockchain without having to restart +the node. This allows for faster development and testing of the blockchain. Congratulations! 🥳 You have successfully created a brand-new Cosmos blockchain using the Ignite CLI. This blockchain uses the delegated proof of stake (DPoS) diff --git a/docs/versioned_docs/version-v0.26.1/03-clients/02-typescript.md b/docs/versioned_docs/version-v0.26.1/03-clients/02-typescript.md index 3c8d29e81d..5cfbf7705d 100644 --- a/docs/versioned_docs/version-v0.26.1/03-clients/02-typescript.md +++ b/docs/versioned_docs/version-v0.26.1/03-clients/02-typescript.md @@ -8,8 +8,7 @@ Ignite offers powerful functionality for generating client-side code for your blockchain. Think of this as a one-click client SDK generation tailored specifically for your blockchain. -See [`ignite generate ts-client --help`](../references/cli#ignite-generate-ts-client) learn -more on how to use TypeScript code generation. +See `ignite generate ts-client --help` learn more on how to use TypeScript code generation. ## Starting a node diff --git a/docs/versioned_docs/version-v0.26.1/06-migration/v0.26.0.md b/docs/versioned_docs/version-v0.26.1/06-migration/v0.26.0.md index f8895aabf1..61bf0c5dbb 100644 --- a/docs/versioned_docs/version-v0.26.1/06-migration/v0.26.0.md +++ b/docs/versioned_docs/version-v0.26.1/06-migration/v0.26.0.md @@ -22,7 +22,7 @@ specific changes that will need to be followed for Ignite scaffolded chains. ### Removing `cosmosibckeeper` -Ignite CLI `v0.26.0` has deprecated [pkg/cosmosibckeeper](https://github.com/ignite/cli/tree/main/ignite/pkg/cosmosibckeeper). +Ignite CLI `v0.26.0` has deprecated [pkg/cosmosibckeeper](https://github.com/ignite/cli/tree/v0.26.0/ignite/pkg/cosmosibckeeper). This package contained interfaces for ibc-related keepers. Newly scaffolded chains now include the interface files in their `./x/{moduleName}/types` directory in a new `expected_ibc_keeper.go` file. To migrate, create the following file for each module: diff --git a/docs/versioned_docs/version-v0.27.1/02-guide/02-getting-started.md b/docs/versioned_docs/version-v0.27.1/02-guide/02-getting-started.md index d1d8c7c161..09b48891e5 100644 --- a/docs/versioned_docs/version-v0.27.1/02-guide/02-getting-started.md +++ b/docs/versioned_docs/version-v0.27.1/02-guide/02-getting-started.md @@ -29,8 +29,8 @@ following command: ignite scaffold chain example ``` -The [`ignite scaffold chain`](../references/cli#ignite-scaffold-chain) command will create a -new blockchain in a new directory `example`. +The `ignite scaffold chain` command will create a new blockchain in a new +directory `example`. The new blockchain is built using the Cosmos SDK framework and imports several standard modules to provide a range of functionality. These modules include @@ -132,14 +132,13 @@ To start a blockchain node in development, you can run the following command: ignite chain serve ``` -The [`ignite chain serve`](../references/cli#ignite-scaffold-chain) command is used to start -a blockchain node in development mode. It first compiles and installs the binary -using the `ignite chain build` command, then initializes the blockchain's data -directory for a single validator using the `ignite chain init` command. After -that, it starts the node locally and enables automatic code reloading so that -changes to the code can be reflected in the running blockchain without having to -restart the node. This allows for faster development and testing of the -blockchain. +The `ignite chain serve` command is used to start a blockchain node in +development mode. It first compiles and installs the binary using the +`ignite chain build` command, then initializes the blockchain's data directory +for a single validator using the `ignite chain init` command. After that, it +starts the node locally and enables automatic code reloading so that changes to +the code can be reflected in the running blockchain without having to restart +the node. This allows for faster development and testing of the blockchain. Congratulations! 🥳 You have successfully created a brand-new Cosmos blockchain using the Ignite CLI. This blockchain uses the delegated proof of stake (DPoS) diff --git a/docs/versioned_docs/version-v0.27.1/03-clients/02-typescript.md b/docs/versioned_docs/version-v0.27.1/03-clients/02-typescript.md index 3c8d29e81d..5cfbf7705d 100644 --- a/docs/versioned_docs/version-v0.27.1/03-clients/02-typescript.md +++ b/docs/versioned_docs/version-v0.27.1/03-clients/02-typescript.md @@ -8,8 +8,7 @@ Ignite offers powerful functionality for generating client-side code for your blockchain. Think of this as a one-click client SDK generation tailored specifically for your blockchain. -See [`ignite generate ts-client --help`](../references/cli#ignite-generate-ts-client) learn -more on how to use TypeScript code generation. +See `ignite generate ts-client --help` learn more on how to use TypeScript code generation. ## Starting a node diff --git a/docs/versioned_docs/version-v0.27.1/06-migration/v0.26.0.md b/docs/versioned_docs/version-v0.27.1/06-migration/v0.26.0.md index f8895aabf1..61bf0c5dbb 100644 --- a/docs/versioned_docs/version-v0.27.1/06-migration/v0.26.0.md +++ b/docs/versioned_docs/version-v0.27.1/06-migration/v0.26.0.md @@ -22,7 +22,7 @@ specific changes that will need to be followed for Ignite scaffolded chains. ### Removing `cosmosibckeeper` -Ignite CLI `v0.26.0` has deprecated [pkg/cosmosibckeeper](https://github.com/ignite/cli/tree/main/ignite/pkg/cosmosibckeeper). +Ignite CLI `v0.26.0` has deprecated [pkg/cosmosibckeeper](https://github.com/ignite/cli/tree/v0.26.0/ignite/pkg/cosmosibckeeper). This package contained interfaces for ibc-related keepers. Newly scaffolded chains now include the interface files in their `./x/{moduleName}/types` directory in a new `expected_ibc_keeper.go` file. To migrate, create the following file for each module: diff --git a/docs/versioned_docs/version-v0.27.1/06-migration/v0.27.1.md b/docs/versioned_docs/version-v0.27.1/06-migration/v0.27.1.md new file mode 100644 index 0000000000..7ef0f8c4d6 --- /dev/null +++ b/docs/versioned_docs/version-v0.27.1/06-migration/v0.27.1.md @@ -0,0 +1,1210 @@ +--- +sidebar_position: 991 +title: v0.27.1 +description: For chains that were scaffolded with Ignite CLI versions lower than v0.27.0. changes are required to use Ignite CLI v0.27.1. +--- + +## Cosmos SDK v0.47.3 upgrade notes + +### Imports + +To use the new cosmos SDK make sure you update `go.mod` dependencies: + +```go title="go.mod" +go 1.19 + +require ( + // remove-start + github.com/cosmos/cosmos-sdk v0.46.7 + github.com/tendermint/tendermint v0.34.24 + github.com/tendermint/tm-db v0.6.7 + github.com/cosmos/ibc-go/v7 v7.1.0 + github.com/gogo/protobuf v1.3.3 + github.com/regen-network/cosmos-proto v0.3.1 + // remove-end + // highlight-start + cosmossdk.io/api v0.3.1 + github.com/cosmos/cosmos-sdk v0.47.3 + github.com/cometbft/cometbft v0.37.1 + github.com/cometbft/cometbft-db v0.7.0 + github.com/cosmos/ibc-go/v6 v6.1.0 + github.com/cosmos/gogoproto v1.4.7 + // highlight-end + + // ... +) + +replace ( + // remove-start + github.com/confio/ics23/go => github.com/cosmos/cosmos-sdk/ics23/go v0.8.0 + github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 + // remove-end + // highlight-next-line + github.com/syndtr/goleveldb => github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 +) +``` + +The Cosmos SDK has migrated to CometBFT as its default consensus engine which requires +changes in your app imports: + +1. Replace `github.com/tendermint/tendermint` by `github.com/cometbft/cometbft` +2. Replace `github.com/tendermint/tm-db` by `github.com/cometbft/cometbft-db` +3. Verify `github.com/tendermint/tendermint` is not an indirect or direct dependency + +The SDK has also migrated from `gogo/protobuf` to `cosmos/gogoproto`. This means you must +replace all `github.com/gogo/protobuf` imports with `github.com/cosmos/gogoproto`. This change +might introduce breaking changes to your proto layout. Follow the official +[Cosmos migration guide](https://docs.cosmos.network/main/migrations/upgrading#gogoproto-import-paths) +to make sure you are using the correct layout. + +You might need to replace the following imports: + +1. Replace `github.com/cosmos/cosmos-sdk/simapp` by `cosmossdk.io/simapp` + +### App changes + +Applications scaffolded with older version of Ignite CLI would require the following changes +to some of the app files: + +```go title="app/app.go" +import ( + //... + + // remove-next-line + tmjson "github.com/tendermint/tendermint/libs/json" + // highlight-next-line + "encoding/json" + + // highlight-start + autocliv1 "cosmossdk.io/api/cosmos/autocli/v1" + reflectionv1 "cosmossdk.io/api/cosmos/reflection/v1" + "github.com/cosmos/cosmos-sdk/runtime" + runtimeservices "github.com/cosmos/cosmos-sdk/runtime/services" + "github.com/cosmos/cosmos-sdk/x/consensus" + consensusparamkeeper "github.com/cosmos/cosmos-sdk/x/consensus/keeper" + consensusparamtypes "github.com/cosmos/cosmos-sdk/x/consensus/types" + // highlight-end +) + +func getGovProposalHandlers() []govclient.ProposalHandler { + // ... + govProposalHandlers = append(govProposalHandlers, + paramsclient.ProposalHandler, + // remove-next-line + distrclient.ProposalHandler, + upgradeclient.LegacyProposalHandler, + // ... + ) + + return govProposalHandlers +} + +var ( + // ... + + ModuleBasics = module.NewBasicManager( + auth.AppModuleBasic{}, + authzmodule.AppModuleBasic{}, + // remove-next-line + genutil.AppModuleBasic{}, + // highlight-next-line + genutil.NewAppModuleBasic(genutiltypes.DefaultMessageValidator), + bank.AppModuleBasic{}, + // ... + vesting.AppModuleBasic{}, + // highlight-next-line + consensus.AppModuleBasic{}, + //... + ) +) + +var ( + // highlight-next-line + _ runtime.AppI = (*App)(nil) + _ servertypes.Application = (*App)(nil) + // remove-next-line + _ simapp.App = (*App)(nil) +) + +type App struct { + *baseapp.BaseApp + + cdc *codec.LegacyAmino + appCodec codec.Codec + interfaceRegistry types.InterfaceRegistry + // highlight-next-line + txConfig client.TxConfig + + invCheckPeriod uint + + // ... + // remove-start + StakingKeeper stakingkeeper.Keeper + CrisisKeeper crisiskeeper.Keeper + UpgradeKeeper upgradekeeper.Keeper + // remove-end + // highlight-start + StakingKeeper *stakingkeeper.Keeper + CrisisKeeper *crisiskeeper.Keeper + UpgradeKeeper *upgradekeeper.Keeper + // highlight-end + // ... + FeeGrantKeeper feegrantkeeper.Keeper + GroupKeeper groupkeeper.Keeper + // highlight-next-line + ConsensusParamsKeeper consensusparamkeeper.Keeper + + // ... +} + +func New( + logger log.Logger, + db dbm.DB, + traceStore io.Writer, + loadLatest bool, + skipUpgradeHeights map[int64]bool, + homePath string, + invCheckPeriod uint, + encodingConfig appparams.EncodingConfig, + appOpts servertypes.AppOptions, + baseAppOptions ...func(*baseapp.BaseApp), +) *App { + appCodec := encodingConfig.Marshaler + cdc := encodingConfig.Amino + interfaceRegistry := encodingConfig.InterfaceRegistry + // highlight-next-line + txConfig := encodingConfig.TxConfig + + // ... + + bApp.SetCommitMultiStoreTracer(traceStore) + bApp.SetVersion(version.Version) + bApp.SetInterfaceRegistry(interfaceRegistry) + // highlight-next-line + bApp.SetTxEncoder(txConfig.TxEncoder()) + + keys := sdk.NewKVStoreKeys( + // ... + banktypes.StoreKey, + stakingtypes.StoreKey, + // highlight-next-line + crisistypes.StoreKey, + // ... + group.StoreKey, + icacontrollertypes.StoreKey, + // highlight-next-line + consensusparamtypes.StoreKey, + // ... + ) + + // ... + + app := &App{ + // ... + interfaceRegistry: interfaceRegistry, + // highlight-next-line + txConfig: txConfig, + invCheckPeriod: invCheckPeriod, + // ... + } + + // ... + + // set the BaseApp's parameter store + // remove-next-line + bApp.SetParamStore(app.ParamsKeeper.Subspace(baseapp.Paramspace).WithKeyTable(paramstypes.ConsensusParamsKeyTable())) + // highlight-start + app.ConsensusParamsKeeper = consensusparamkeeper.NewKeeper(appCodec, keys[upgradetypes.StoreKey], authtypes.NewModuleAddress(govtypes.ModuleName).String()) + bApp.SetParamStore(&app.ConsensusParamsKeeper) + // highlight-end + + // ... + + app.AccountKeeper = authkeeper.NewAccountKeeper( + appCodec, + keys[authtypes.StoreKey], + // remove-next-line + app.GetSubspace(authtypes.ModuleName), + authtypes.ProtoBaseAccount, + maccPerms, + sdk.Bech32PrefixAccAddr, + // highlight-next-line + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + ) + + app.BankKeeper = bankkeeper.NewBaseKeeper( + appCodec, + keys[banktypes.StoreKey], + app.AccountKeeper, + // remove-next-line + app.GetSubspace(banktypes.ModuleName), + app.BlockedModuleAccountAddrs(), + // highlight-next-line + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + ) + + app.StakingKeeper = stakingkeeper.NewKeeper( + appCodec, + keys[stakingtypes.StoreKey], + app.AccountKeeper, + app.BankKeeper, + // remove-next-line + app.GetSubspace(stakingtypes.ModuleName), + // highlight-next-line + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + ) + + app.MintKeeper = mintkeeper.NewKeeper( + appCodec, + keys[minttypes.StoreKey], + // remove-next-line + app.GetSubspace(minttypes.ModuleName), + // remove-next-line + &app.StakingKeeper, + // highlight-next-line + app.StakingKeeper, + app.AccountKeeper, + app.BankKeeper, + authtypes.FeeCollectorName, + // highlight-next-line + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + ) + + app.DistrKeeper = distrkeeper.NewKeeper( + appCodec, + keys[distrtypes.StoreKey], + // remove-next-line + app.GetSubspace(distrtypes.ModuleName), + app.AccountKeeper, + app.BankKeeper, + // remove-next-line + &app.StakingKeeper, + // highlight-next-line + app.StakingKeeper, + authtypes.FeeCollectorName, + // highlight-next-line + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + ) + + app.SlashingKeeper = slashingkeeper.NewKeeper( + appCodec, + // highlight-next-line + cdc, + keys[slashingtypes.StoreKey], + // remove-next-line + &app.StakingKeeper, + // highlight-next-line + app.StakingKeeper, + // remove-next-line + app.GetSubspace(slashingtypes.ModuleName), + // highlight-next-line + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + ) + + app.CrisisKeeper = crisiskeeper.NewKeeper( + // remove-next-line + app.GetSubspace(crisistypes.ModuleName), + // highlight-start + appCodec, + keys[crisistypes.StoreKey], + // highlight-end + invCheckPeriod, + app.BankKeeper, + authtypes.FeeCollectorName, + // highlight-next-line + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + ) + + // ... + + // Create evidence Keeper for to register the IBC light client misbehaviour evidence route + evidenceKeeper := evidencekeeper.NewKeeper( + appCodec, + keys[evidencetypes.StoreKey], + // remove-next-line + &app.StakingKeeper, + // highlight-next-line + app.StakingKeeper, + app.SlashingKeeper, + ) + // If evidence needs to be handled for the app, set routes in router here and seal + app.EvidenceKeeper = *evidenceKeeper + + // highlight-start + govConfig := govtypes.DefaultConfig() + govKeeper := govkeeper.NewKeeper( + appCodec, + keys[govtypes.StoreKey], + app.AccountKeeper, + app.BankKeeper, + app.StakingKeeper, + app.MsgServiceRouter(), + govConfig, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + ) + // highlight-end + + govRouter := govv1beta1.NewRouter() + govRouter. + AddRoute(govtypes.RouterKey, govv1beta1.ProposalHandler). + AddRoute(paramproposal.RouterKey, params.NewParamChangeProposalHandler(app.ParamsKeeper)). + // remove-next-line + AddRoute(distrtypes.RouterKey, distr.NewCommunityPoolSpendProposalHandler(app.DistrKeeper)). + AddRoute(upgradetypes.RouterKey, upgrade.NewSoftwareUpgradeProposalHandler(app.UpgradeKeeper)). + AddRoute(ibcclienttypes.RouterKey, ibcclient.NewClientProposalHandler(app.IBCKeeper.ClientKeeper)) + // highlight-next-line + govKeeper.SetLegacyRouter(govRouter) + + // remove-start + govConfig := govtypes.DefaultConfig() + app.GovKeeper = govkeeper.NewKeeper( + appCodec, + keys[govtypes.StoreKey], + app.GetSubspace(govtypes.ModuleName), + app.AccountKeeper, + app.BankKeeper, + &app.StakingKeeper, + govRouter, + app.MsgServiceRouter(), + govConfig, + ) + // remove-end + // highlight-start + app.GovKeeper = *govKeeper.SetHooks( + govtypes.NewMultiGovHooks( + // register the governance hooks + ), + ) + // highlight-end + + // ... + + // remove-start + app.GovKeeper.SetHooks( + govtypes.NewMultiGovHooks( + // insert governance hooks receivers here + ), + ) + // remove-end + + // ... + + app.mm = module.NewManager( + genutil.NewAppModule( + app.AccountKeeper, + app.StakingKeeper, + app.BaseApp.DeliverTx, + encodingConfig.TxConfig, + ), + // remove-next-line + auth.NewAppModule(appCodec, app.AccountKeeper, nil), + // highlight-next-line + auth.NewAppModule(appCodec, app.AccountKeeper, authsims.RandomGenesisAccounts, app.GetSubspace(authtypes.ModuleName)), + authzmodule.NewAppModule(appCodec, app.AuthzKeeper, app.AccountKeeper, app.BankKeeper, app.interfaceRegistry), + vesting.NewAppModule(app.AccountKeeper, app.BankKeeper), + // remove-start + bank.NewAppModule(appCodec, app.BankKeeper, app.AccountKeeper), + capability.NewAppModule(appCodec, *app.CapabilityKeeper), + // remove-end + // highlight-start + bank.NewAppModule(appCodec, app.BankKeeper, app.AccountKeeper, app.GetSubspace(banktypes.ModuleName)), + capability.NewAppModule(appCodec, *app.CapabilityKeeper, false), + // highlight-end + feegrantmodule.NewAppModule(appCodec, app.AccountKeeper, app.BankKeeper, app.FeeGrantKeeper, app.interfaceRegistry), + groupmodule.NewAppModule(appCodec, app.GroupKeeper, app.AccountKeeper, app.BankKeeper, app.interfaceRegistry), + // remove-start + crisis.NewAppModule(&app.CrisisKeeper, skipGenesisInvariants), + gov.NewAppModule(appCodec, app.GovKeeper, app.AccountKeeper, app.BankKeeper), + mint.NewAppModule(appCodec, app.MintKeeper, app.AccountKeeper, minttypes.DefaultInflationCalculationFn), + slashing.NewAppModule(appCodec, app.SlashingKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper), + distr.NewAppModule(appCodec, app.DistrKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper), + staking.NewAppModule(appCodec, app.StakingKeeper, app.AccountKeeper, app.BankKeeper), + // remove-end + // highlight-start + gov.NewAppModule(appCodec, &app.GovKeeper, app.AccountKeeper, app.BankKeeper, app.GetSubspace(govtypes.ModuleName)), + mint.NewAppModule(appCodec, app.MintKeeper, app.AccountKeeper, nil, app.GetSubspace(minttypes.ModuleName)), + slashing.NewAppModule(appCodec, app.SlashingKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper, app.GetSubspace(slashingtypes.ModuleName)), + distr.NewAppModule(appCodec, app.DistrKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper, app.GetSubspace(distrtypes.ModuleName)), + staking.NewAppModule(appCodec, app.StakingKeeper, app.AccountKeeper, app.BankKeeper, app.GetSubspace(stakingtypes.ModuleName)), + // highlight-end + upgrade.NewAppModule(app.UpgradeKeeper), + evidence.NewAppModule(app.EvidenceKeeper), + // highlight-next-line + consensus.NewAppModule(appCodec, app.ConsensusParamsKeeper), + ibc.NewAppModule(app.IBCKeeper), + params.NewAppModule(app.ParamsKeeper), + transferModule, + icaModule, + // this line is used by starport scaffolding # stargate/app/appModule + + // highlight-start + // always be last to make sure that it checks for all invariants and not only part of them + crisis.NewAppModule(app.CrisisKeeper, skipGenesisInvariants, app.GetSubspace(crisistypes.ModuleName)), + // highlight-end + ) + + app.mm.SetOrderBeginBlockers( + // ... + paramstypes.ModuleName, + vestingtypes.ModuleName, + // highlight-next-line + consensusparamtypes.ModuleName, + // ... + ) + + app.mm.SetOrderEndBlockers( + // ... + paramstypes.ModuleName, + upgradetypes.ModuleName, + vestingtypes.ModuleName, + // highlight-next-line + consensusparamtypes.ModuleName, + // ... + ) + + // remove-next-line + app.mm.SetOrderInitGenesis( + // highlight-next-line + genesisModuleOrder := []string{ + // ... + paramstypes.ModuleName, + upgradetypes.ModuleName, + vestingtypes.ModuleName, + // highlight-next-line + consensusparamtypes.ModuleName, + // ... + // remove-next-line + ) + // highlight-start + } + app.mm.SetOrderInitGenesis(genesisModuleOrder...) + app.mm.SetOrderExportGenesis(genesisModuleOrder...) + // highlight-end + + // remove-start + app.mm.RegisterInvariants(&app.CrisisKeeper) + app.mm.RegisterRoutes(app.Router(), app.QueryRouter(), encodingConfig.Amino) + // remove-end + // highlight-next-line + app.mm.RegisterInvariants(app.CrisisKeeper) + + app.configurator = module.NewConfigurator(app.appCodec, app.MsgServiceRouter(), app.GRPCQueryRouter()) + app.mm.RegisterServices(app.configurator) + + // highlight-start + autocliv1.RegisterQueryServer(app.GRPCQueryRouter(), runtimeservices.NewAutoCLIQueryService(app.mm.Modules)) + reflectionSvc, err := runtimeservices.NewReflectionService() + if err != nil { + panic(err) + } + reflectionv1.RegisterReflectionServiceServer(app.GRPCQueryRouter(), reflectionSvc) + // highlight-end + + // create the simulation manager and define the order of the modules for deterministic simulations + // remove-start + app.sm = module.NewSimulationManager( + // ... + ) + // remove-end + // highlight-start + overrideModules := map[string]module.AppModuleSimulation{ + authtypes.ModuleName: auth.NewAppModule(app.appCodec, app.AccountKeeper, authsims.RandomGenesisAccounts, app.GetSubspace(authtypes.ModuleName)), + } + app.sm = module.NewSimulationManagerFromAppModules(app.mm.Modules, overrideModules) + // highlight-end + app.sm.RegisterStoreDecoders() + + // ... + + // remove-start + app.SetInitChainer(app.InitChainer) + app.SetBeginBlocker(app.BeginBlocker) + // remove-end + + // ... +} + +func (app *App) InitChainer(ctx sdk.Context, req abci.RequestInitChain) abci.ResponseInitChain { + var genesisState GenesisState + // remove-next-line + if err := tmjson.Unmarshal(req.AppStateBytes, &genesisState); err != nil { + // highlight-next-line + if err := json.Unmarshal(req.AppStateBytes, &genesisState); err != nil { + panic(err) + } + // ... +} + +// remove-start +// GetMaccPerms returns a copy of the module account permissions +func GetMaccPerms() map[string][]string { + dupMaccPerms := make(map[string][]string) + for k, v := range maccPerms { + dupMaccPerms[k] = v + } + return dupMaccPerms +} +// remove-end + +// highlight-start +// TxConfig returns App's TxConfig. +func (app *App) TxConfig() client.TxConfig { + return app.txConfig +} + +// Configurator get app configurator +func (app *App) Configurator() module.Configurator { + return app.configurator +} + +// ModuleManager returns the app ModuleManager +func (app *App) ModuleManager() *module.Manager { + return app.mm +} +// highlight-end +``` + +```go title="app/simulation_test.go" +import ( + // ... + // remove-start + "cosmossdk.io/simapp" + tmtypes "github.com/tendermint/tendermint/types" + // remove-end + // highlight-start + "encoding/json" + "fmt" + "math/rand" + "runtime/debug" + "strings" + + dbm "github.com/cometbft/cometbft-db" + "github.com/cometbft/cometbft/libs/log" + "github.com/cosmos/cosmos-sdk/baseapp" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/server" + storetypes "github.com/cosmos/cosmos-sdk/store/types" + simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" + sdk "github.com/cosmos/cosmos-sdk/types" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + authzkeeper "github.com/cosmos/cosmos-sdk/x/authz/keeper" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" + distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types" + evidencetypes "github.com/cosmos/cosmos-sdk/x/evidence/types" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" + paramstypes "github.com/cosmos/cosmos-sdk/x/params/types" + simcli "github.com/cosmos/cosmos-sdk/x/simulation/client/cli" + slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + // highlight-end +) + +// highlight-start +type storeKeysPrefixes struct { + A storetypes.StoreKey + B storetypes.StoreKey + Prefixes [][]byte +} +// highlight-end + +// Get flags every time the simulator is run +func init() { + // remove-next-line + simapp.GetSimulatorFlags() + // highlight-next-line + simcli.GetSimulatorFlags() +} + +// remove-start +var defaultConsensusParams = &abci.ConsensusParams{ + Block: &abci.BlockParams{ + MaxBytes: 200000, + MaxGas: 2000000, + }, + Evidence: &tmproto.EvidenceParams{ + MaxAgeNumBlocks: 302400, + MaxAgeDuration: 504 * time.Hour, // 3 weeks is the max duration + MaxBytes: 10000, + }, + Validator: &tmproto.ValidatorParams{ + PubKeyTypes: []string{ + tmtypes.ABCIPubKeyTypeEd25519, + }, + }, +} +// remove-end +// highlight-start +func fauxMerkleModeOpt(bapp *baseapp.BaseApp) { + bapp.SetFauxMerkleMode() +} +// highlight-end + +func BenchmarkSimulation(b *testing.B) { + // remove-start + simapp.FlagEnabledValue = true + simapp.FlagCommitValue = true + + config, db, dir, logger, _, err := simapp.SetupSimulation("goleveldb-app-sim", "Simulation") + // remove-end + // highlight-start + simcli.FlagSeedValue = time.Now().Unix() + simcli.FlagVerboseValue = true + simcli.FlagCommitValue = true + simcli.FlagEnabledValue = true + + config := simcli.NewConfigFromFlags() + config.ChainID = "mars-simapp" + db, dir, logger, _, err := simtestutil.SetupSimulation( + config, + "leveldb-bApp-sim", + "Simulation", + simcli.FlagVerboseValue, + simcli.FlagEnabledValue, + ) + // highlight-end + + require.NoError(b, err, "simulation setup failed") + + b.Cleanup(func() { + // remove-start + db.Close() + err = os.RemoveAll(dir) + require.NoError(b, err) + // remove-end + // highlight-start + require.NoError(b, db.Close()) + require.NoError(b, os.RemoveAll(dir)) + // highlight-end + }) + + + // remove-next-line + encoding := app.MakeEncodingConfig() + // highlight-start + appOptions := make(simtestutil.AppOptionsMap, 0) + appOptions[flags.FlagHome] = app.DefaultNodeHome + appOptions[server.FlagInvCheckPeriod] = simcli.FlagPeriodValue + // highlight-end + + // remove-next-line + app := app.New( + // highlight-next-line + bApp := app.New( + logger, + db, + nil, + true, + map[int64]bool{}, + app.DefaultNodeHome, + 0, + // remove-start + encoding, + simapp.EmptyAppOptions{}, + // remove-end + // highlight-start + app.MakeEncodingConfig(), + appOptions, + baseapp.SetChainID(config.ChainID), + // highlight-end + ) + // highlight-next-line + require.Equal(b, app.Name, bApp.Name()) + + _, simParams, simErr := simulation.SimulateFromSeed( + b, + os.Stdout, + // remove-start + app.BaseApp, + simapp.AppStateFn(app.AppCodec(), app.SimulationManager()), + simulationtypes.RandomAccounts, + simapp.SimulationOperations(app, app.AppCodec(), config), + app.ModuleAccountAddrs(), + config, + app.AppCodec(), + // remove-end + // highlight-start + bApp.BaseApp, + simtestutil.AppStateFn( + bApp.AppCodec(), + bApp.SimulationManager(), + app.NewDefaultGenesisState(bApp.AppCodec()), + ), + simtestutil.SimulationOperations(bApp, bApp.AppCodec(), config), + bApp.ModuleAccountAddrs(), + config, + bApp.AppCodec(), + // highlight-end + ) + + // remove-next-line + err = simapp.CheckExportSimulation(app, config, simParams) + // highlight-next-line + err = simtestutil.CheckExportSimulation(bApp, config, simParams) + require.NoError(b, err) + require.NoError(b, simErr) + + if config.Commit { + // remove-next-line + simapp.PrintStats(db) + // highlight-next-line + simtestutil.PrintStats(db) + } +} +``` + +```go title="x/{{moduleName}}/module_simulation.go" +import ( + // ... + // remove-next-line + simappparams "cosmossdk.io/simapp/params" +) + +var ( + // ... + // remove-next-line + _ = simappparams.StakePerAccount + // highlight-next-line + _ = rand.Rand{} +) + +// remove-start +func (am AppModule) RandomizedParams(_ *rand.Rand) []simtypes.ParamChange { + // ... +} +// remove-end +// highlight-start +// ProposalMsgs returns msgs used for governance proposals for simulations. +func (am AppModule) ProposalMsgs(simState module.SimulationState) []simtypes.WeightedProposalMsg { + return []simtypes.WeightedProposalMsg{ + // this line is used by starport scaffolding # simapp/module/OpMsg + } +} +// highlight-end +``` + +### Deprecations + +The app module might contains some legacy methods that are deprecated and can be removed: + +```go title="x/{{moduleName}}/module.go" +// remove-start +// Deprecated: use RegisterServices +func (am AppModule) Route() sdk.Route { return sdk.Route{} } + +// Deprecated: use RegisterServices +func (AppModule) QuerierRoute() string { return types.RouterKey } + +// Deprecated: use RegisterServices +func (am AppModule) LegacyQuerierHandler(_ *codec.LegacyAmino) sdk.Querier { + return nil +} +// remove-end +``` + +### Other required changes + +Changes required to the network test util: + +```go title="testutil/network/network.go" +import ( + // ... + + // remove-start + "github.com/cosmos/cosmos-sdk/simapp" + pruningtypes "github.com/cosmos/cosmos-sdk/pruning/types" + // remove-end + // highlight-start + pruningtypes "github.com/cosmos/cosmos-sdk/store/pruning/types" + simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" + // highlight-end +) + +func New(t *testing.T, configs ...Config) *Network { + // ... + + net, err := network.New(t, t.TempDir(), cfg) + require.NoError(t, err) + // highlight-start + _, err = net.WaitForHeight(1) + require.NoError(t, err) + // highlight-end + + // ... +} + +func DefaultConfig() network.Config { + // remove-next-line + encoding := app.MakeEncodingConfig() + // highlight-start + var ( + encoding = app.MakeEncodingConfig() + chainID = "chain-" + tmrand.NewRand().Str(6) + ) + // highlight-end + + return network.Config{ + // ... + // remove-next-line + AppConstructor: func(val network.Validator) servertypes.Application { + // highlight-next-line + AppConstructor: func(val network.ValidatorI) servertypes.Application { + return app.New( + // remove-next-line + val.Ctx.Logger, + // highlight-next-line + val.GetCtx().Logger, + tmdb.NewMemDB(), + nil, + true, + map[int64]bool{}, + // remove-next-line + val.Ctx.Config.RootDir, + // highlight-next-line + val.GetCtx().Config.RootDir, + 0, + encoding, + // remove-start + simapp.EmptyAppOptions{}, + baseapp.SetPruning(pruningtypes.NewPruningOptionsFromString(val.AppConfig.Pruning)), + baseapp.SetMinGasPrices(val.AppConfig.MinGasPrices), + // remove-end + // highlight-start + simtestutil.EmptyAppOptions{}, + baseapp.SetPruning(pruningtypes.NewPruningOptionsFromString(val.GetAppConfig().Pruning)), + baseapp.SetMinGasPrices(val.GetAppConfig().MinGasPrices), + baseapp.SetChainID(chainID), + // highlight-end + ) + }, + // ... + // remove-next-line + ChainID: "chain-" + tmrand.NewRand().Str(6), + // highlight-next-line + ChainID: chainID, + // ... + } +} +``` + +Update the collect genesis transactions command and add the new message validator argument: + +```go title="cmd/{{binaryNamePrefix}}d/cmd/root.go" +import ( + // ... + + // highlight-start + tmtypes "github.com/cometbft/cometbft/types" + "github.com/cosmos/cosmos-sdk/x/genutil" + genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" + // highlight-end +) + +func initRootCmd(rootCmd *cobra.Command, encodingConfig params.EncodingConfig) { + // ... + + // highlight-next-line + gentxModule := app.ModuleBasics[genutiltypes.ModuleName].(genutil.AppModuleBasic) + rootCmd.AddCommand( + // ... + // remove-next-line + genutilcli.CollectGenTxsCmd(banktypes.GenesisBalancesIterator{}, app.DefaultHome), + // highlight-next-line + genutilcli.CollectGenTxsCmd(banktypes.GenesisBalancesIterator{}, app.DefaultNodeHome, gentxModule.GenTxValidator), + // ... + ) + + // ... +} + +func (a appCreator) newApp( + logger log.Logger, + db dbm.DB, + traceStore io.Writer, + appOpts servertypes.AppOptions, +) servertypes.Application { + // ... + + pruningOpts, err := server.GetPruningOptionsFromFlags(appOpts) + if err != nil { + panic(err) + } + + // highlight-start + homeDir := cast.ToString(appOpts.Get(flags.FlagHome)) + chainID := cast.ToString(appOpts.Get(flags.FlagChainID)) + if chainID == "" { + // fallback to genesis chain-id + appGenesis, err := tmtypes.GenesisDocFromFile(filepath.Join(homeDir, "config", "genesis.json")) + if err != nil { + panic(err) + } + + chainID = appGenesis.ChainID + } + // highlight-end + + // ... + + return app.New( + // ... + baseapp.SetPruning(pruningOpts), + baseapp.SetMinGasPrices(cast.ToString(appOpts.Get(server.FlagMinGasPrices))), + // remove-next-line + baseapp.SetMinRetainBlocks(cast.ToUint64(appOpts.Get(server.FlagMinRetainBlocks))), + baseapp.SetHaltHeight(cast.ToUint64(appOpts.Get(server.FlagHaltHeight))), + baseapp.SetHaltTime(cast.ToUint64(appOpts.Get(server.FlagHaltTime))), + // highlight-next-line + baseapp.SetMinRetainBlocks(cast.ToUint64(appOpts.Get(server.FlagMinRetainBlocks))), + // ... + baseapp.SetIAVLDisableFastNode(cast.ToBool(appOpts.Get(server.FlagDisableIAVLFastNode))), + // highlight-next-line + baseapp.SetChainID(chainID), + ) +) + +func (a appCreator) appExport( + logger log.Logger, + db dbm.DB, + traceStore io.Writer, + height int64, + forZeroHeight bool, + jailAllowedAddrs []string, + appOpts servertypes.AppOptions, + // highlight-next-line + modulesToExport []string, +) (servertypes.ExportedApp, error) { + // ... + + // remove-next-line + return app.ExportAppStateAndValidators(forZeroHeight, jailAllowedAddrs) + // highlight-next-line + return app.ExportAppStateAndValidators(forZeroHeight, jailAllowedAddrs, modulesToExport) +} +``` + +Add the new extra argument to `ExportAppStateAndValidators`: + +```go title="app/export.go" +func (app *App) ExportAppStateAndValidators( + forZeroHeight bool, + jailAllowedAddrs []string, + // highlight-next-line + modulesToExport []string, +) (servertypes.ExportedApp, error) { + // ... + + // remove-next-line + genState := app.mm.ExportGenesis(ctx, app.appCodec) + // highlight-next-line + genState := app.mm.ExportGenesisForModules(ctx, app.appCodec, modulesToExport) + appState, err := json.MarshalIndent(genState, "", " ") + if err != nil { + return servertypes.ExportedApp{}, err + } + + // ... +} +``` + +### Migration + +You can also follow other Cosmos SDK migration steps in their [upgrade guide](https://docs.cosmos.network/main/migrations/upgrading#v047x). +Specially the [parameter migration](https://docs.cosmos.network/main/migrations/upgrading#xconsensus) which +is required if you want to run the updated version keeping you current app state. + +## Query commands + +Query commands context initialization should be changed to: + +```go title="x/{moduleName}/client/cli/query_{typeName}.go" +RunE: func(cmd *cobra.Command, args []string) (err error) { + // remove-next-line + clientCtx := client.GetClientContextFromCmd(cmd) + // highlight-start + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + // highlight-end + + // ... +} +``` + + +## ibc-go v7 + +Chains that are newly scaffolded with Ignite CLI `v0.27.1` now use `ibc-go/v7` for IBC functionality. It is +required to upgrade to the newest version of `ibc-go`. + +Applications scaffolded with older version of Ignite CLI require the following changes to the app file: + +```go title="app/app.go" +import ( + // ... + // remove-start + ica "github.com/cosmos/ibc-go/v6/modules/apps/27-interchain-accounts" + icacontrollerkeeper "github.com/cosmos/ibc-go/v6/modules/apps/27-interchain-accounts/controller/keeper" + icacontrollertypes "github.com/cosmos/ibc-go/v6/modules/apps/27-interchain-accounts/controller/types" + icahost "github.com/cosmos/ibc-go/v6/modules/apps/27-interchain-accounts/host" + icahostkeeper "github.com/cosmos/ibc-go/v6/modules/apps/27-interchain-accounts/host/keeper" + icahosttypes "github.com/cosmos/ibc-go/v6/modules/apps/27-interchain-accounts/host/types" + icatypes "github.com/cosmos/ibc-go/v6/modules/apps/27-interchain-accounts/types" + "github.com/cosmos/ibc-go/v6/modules/apps/transfer" + ibctransferkeeper "github.com/cosmos/ibc-go/v6/modules/apps/transfer/keeper" + ibctransfertypes "github.com/cosmos/ibc-go/v6/modules/apps/transfer/types" + ibc "github.com/cosmos/ibc-go/v6/modules/core" + ibcclient "github.com/cosmos/ibc-go/v6/modules/core/02-client" + ibcclientclient "github.com/cosmos/ibc-go/v6/modules/core/02-client/client" + ibcclienttypes "github.com/cosmos/ibc-go/v6/modules/core/02-client/types" + ibcporttypes "github.com/cosmos/ibc-go/v6/modules/core/05-port/types" + ibchost "github.com/cosmos/ibc-go/v6/modules/core/24-host" + ibckeeper "github.com/cosmos/ibc-go/v6/modules/core/keeper" + // remove-end + // highlight-start + ica "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts" + icacontrollerkeeper "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller/keeper" + icacontrollertypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller/types" + icahost "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/host" + icahostkeeper "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/host/keeper" + icahosttypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/host/types" + icatypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types" + "github.com/cosmos/ibc-go/v7/modules/apps/transfer" + ibctransferkeeper "github.com/cosmos/ibc-go/v7/modules/apps/transfer/keeper" + ibctransfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" + ibc "github.com/cosmos/ibc-go/v7/modules/core" + ibcclient "github.com/cosmos/ibc-go/v7/modules/core/02-client" + ibcclientclient "github.com/cosmos/ibc-go/v7/modules/core/02-client/client" + ibcclienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + ibcporttypes "github.com/cosmos/ibc-go/v7/modules/core/05-port/types" + ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported" + ibckeeper "github.com/cosmos/ibc-go/v7/modules/core/keeper" + solomachine "github.com/cosmos/ibc-go/v7/modules/light-clients/06-solomachine" + ibctm "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" + // highlight-end +) + +var ( + // ... + + ModuleBasics = module.NewBasicManager( + // ... + groupmodule.AppModuleBasic{}, + ibc.AppModuleBasic{}, + // highlight-start + ibctm.AppModuleBasic{}, + solomachine.AppModuleBasic{}, + // highlight-end + upgrade.AppModuleBasic{}, + // ... + ) +) + +func New( + logger log.Logger, + db dbm.DB, + traceStore io.Writer, + loadLatest bool, + skipUpgradeHeights map[int64]bool, + homePath string, + invCheckPeriod uint, + encodingConfig appparams.EncodingConfig, + appOpts servertypes.AppOptions, + baseAppOptions ...func(*baseapp.BaseApp), +) *App { + // ... + + keys := sdk.NewKVStoreKeys( + // ... + govtypes.StoreKey, + paramstypes.StoreKey, + // remove-next-line + ibchost.StoreKey, + // highlight-next-line + ibcexported.StoreKey, + // ... + ) + + // ... + // grant capabilities for the ibc and ibc-transfer modules + // remove-next-line + scopedIBCKeeper := app.CapabilityKeeper.ScopeToModule(ibchost.ModuleName) + // highlight-next-line + scopedIBCKeeper := app.CapabilityKeeper.ScopeToModule(ibcexported.ModuleName) + scopedICAControllerKeeper := app.CapabilityKeeper.ScopeToModule(icacontrollertypes.SubModuleName) + + // ... + + app.IBCKeeper = ibckeeper.NewKeeper( + appCodec, + // remove-start + keys[ibchost.StoreKey], + app.GetSubspace(ibchost.ModuleName), + // remove-end + // highlight-start + keys[ibcexported.StoreKey], + app.GetSubspace(ibcexported.ModuleName), + // highlight-end + app.StakingKeeper, + app.UpgradeKeeper, + scopedIBCKeeper, + ) + + // ... + + app.mm.SetOrderBeginBlockers( + // ... + crisistypes.ModuleName, + ibctransfertypes.ModuleName, + // remove-next-line + ibchost.ModuleName, + // highlight-next-line + ibcexported.ModuleName, + // ... + ) + + app.mm.SetOrderEndBlockers( + // ... + stakingtypes.ModuleName, + ibctransfertypes.ModuleName, + // remove-next-line + ibchost.ModuleName, + // highlight-next-line + ibcexported.ModuleName, + // ... + ) + + genesisModuleOrder := []string{ + // ... + genutiltypes.ModuleName, + ibctransfertypes.ModuleName, + // remove-next-line + ibchost.ModuleName, + // highlight-next-line + ibcexported.ModuleName, + // ... + } + + // ... +) + +func initParamsKeeper(appCodec codec.BinaryCodec, legacyAmino *codec.LegacyAmino, key, tkey storetypes.StoreKey) paramskeeper.Keeper { + // ... + paramsKeeper.Subspace(crisistypes.ModuleName) + paramsKeeper.Subspace(ibctransfertypes.ModuleName) + // remove-next-line + paramsKeeper.Subspace(ibchost.ModuleName) + // highlight-next-line + paramsKeeper.Subspace(ibcexported.ModuleName) + // ... +} +``` + + +You can follow other IBC migration steps in their [migration guide v6 to v7](https://github.com/cosmos/ibc-go/blob/v7.0.1/docs/migrations/v6-to-v7.md). + +## Doctor command + +As the final steps it's recommended to run `ignite doctor` and `go mod tidy`. diff --git a/readme.md b/readme.md index b85be1ca38..ff12192ace 100644 --- a/readme.md +++ b/readme.md @@ -34,7 +34,7 @@ with Ignite CLI, see the [Ignite CLI Developer Tutorials](https://docs.ignite.com/guide). To install Ignite CLI locally on GNU, Linux, or macOS, see [Install Ignite -CLI](https://docs.ignite.com/guide/install). +CLI](https://docs.ignite.com/welcome/install). To learn more about building a JavaScript frontend for your Cosmos SDK blockchain, see [ignite/web](https://github.com/ignite/web). @@ -136,9 +136,8 @@ development version of the code. You can create a branch from `main` and create a pull request, or maintain your own fork and submit a cross-repository pull request. -Our [Ignite CLI bounty program](https://docs.ignite.com/bounty) provides -incentives for your participation and pays rewards. Track new, in-progress, and -completed bounties on the [Bounty +Our Ignite CLI bounty program provides incentives for your participation and +pays rewards. Track new, in-progress, and completed bounties on the [Bounty board](https://github.com/ignite/cli/projects/5) in GitHub. **Important** Before you start implementing a new Ignite CLI feature, the first