diff --git a/changelog.md b/changelog.md
index 2262c0061a..02dc56bcba 100644
--- a/changelog.md
+++ b/changelog.md
@@ -21,6 +21,7 @@
- [#4691](https://github.com/ignite/cli/pull/4691), [#4706](https://github.com/ignite/cli/pull/4706), [#4725](https://github.com/ignite/cli/pull/4725), [#4737](https://github.com/ignite/cli/pull/4737) Fix ts-client query template and solely Go template for `ts-client` generation.
- [#4742](https://github.com/ignite/cli/pull/4742) Updates Vue composables template for new ts-client and tanstack/vue-query v5
+- [#4744](https://github.com/ignite/cli/pull/4744) Remove `react` frontend generation via `s react` command. Use the [Ignite CCA App](https://github.com/ignite/apps) instead.
## [`v29.0.0`](https://github.com/ignite/cli/releases/tag/v29.0.0)
diff --git a/docs/docs/04-clients/03-vue.md b/docs/docs/04-clients/03-vue.md
index f62f1f4e55..66f8d8fd9f 100644
--- a/docs/docs/04-clients/03-vue.md
+++ b/docs/docs/04-clients/03-vue.md
@@ -99,20 +99,22 @@ purposes, but you should not do this in production.
In the `example` directory run the following command to start your blockchain:
-```
+```bash
ignite chain serve
```
To start your Vue application, go to the `vue` directory and run the following
command in a separate terminal window:
-```
-npm install && npm run dev
+:::note
+Make sure you have [pnpm](https://pnpm.io/) installed.
+:::
+
+```bash
+pnpm install && pnpm dev
```
-It is recommended to run `npm install` before starting your app with `npm run
-dev` to ensure that all dependencies are installed (including the ones that the
-API client has, see `vue/postinstall.js`).
+It is recommended to run `pnpm install` before starting your app with `pnpm dev` to ensure that all dependencies are installed (including the ones that the API client has, see `vue/postinstall.js`).
Open your browser and navigate to
[http://localhost:5173/](http://localhost:5173/).
diff --git a/docs/docs/04-clients/04-react.md b/docs/docs/04-clients/04-react.md
deleted file mode 100644
index e915b3121e..0000000000
--- a/docs/docs/04-clients/04-react.md
+++ /dev/null
@@ -1,135 +0,0 @@
-# React frontend
-
-:::warning
-The React frontend is being reworked and is not yet stable.
-In the meantime, refer to the [Ignite CCA App](https://ignite.com/marketplace/cca).
-:::
-
-Welcome to this tutorial on using Ignite to develop a web application for your
-blockchain with React. Ignite is a tool that simplifies the process of building
-a blockchain application by providing a set of templates and generators that can
-be used to get up and running quickly.
-
-One of the features of Ignite is its support for [React](https://reactjs.org/), a
-popular JavaScript framework for building user interfaces. In this tutorial, you
-will learn how to use Ignite to create a new blockchain and scaffold a React
-frontend template. This will give you a basic foundation for your web
-application and make it easier to get started building out the rest of your
-application.
-
-Once you have your blockchain and React template set up, the next step is to
-generate an API client. This will allow you to easily interact with your
-blockchain from your web application, enabling you to retrieve data and make
-transactions. By the end of this tutorial, you will have a fully functional web
-application that is connected to your own blockchain.
-
-Prerequisites:
-
-* [Node.js](https://nodejs.org/en/)
-* [Keplr](https://www.keplr.app/) Chrome extension
-
-## Create a blockchain and a React app
-
-Create a new blockchain project:
-
-```
-ignite scaffold chain example
-```
-
-To create a React frontend template, go to the `example` directory and run the
-following command:
-
-```
-ignite scaffold react
-```
-
-This will create a new React project in the `react` directory. This project can be
-used with any blockchain, but it depends on an API client to interact with the
-blockchain. To generate an API client, run the following command in the
-`example` directory:
-
-```
-ignite generate hooks
-```
-
-This command generates two directories:
-
-* `ts-client`: a framework-agnostic TypeScript client that can be used to
- interact with your blockchain. You can learn more about how to use this client
- in the [TypeScript client tutorial](/clients/typescript).
-* `react/src/hooks`: a collection of
- [React Hooks](https://reactjs.org/docs/hooks-intro.html) that wrap
- the TypeScript client and make it easier to interact with your blockchain from
- your React application.
-
-## Set up Keplr and an account
-
-Open your browser with the Keplr wallet extension installed. Follow [the
-instructions](https://keplr.crunch.help/en/getting-started/creating-a-new-keplr-account)
-to create a new account or use an existing one. Make sure to save the mnemonic
-phrase as you will need it in the next step.
-
-Do not use a mnemonic phrase that is associated with an account that holds
-assets you care about. If you do, you risk losing those assets. It's a good
-practice to create a new account for development purposes.
-
-Add the account you're using in Keplr to your blockchain's `config.yml` file:
-
-```yml
-accounts:
- - name: alice
- coins: [20000token, 200000000stake]
- - name: bob
- coins: [10000token, 100000000stake]
- # highlight-start
- - name: frank
- coins: [10000token, 100000000stake]
- mnemonic: struggle since inmate safe logic kite tag web win stay security wonder
- # highlight-end
-```
-
-Replace the `struggle since...` mnemonic with the one you saved in the previous
-step.
-
-Adding an account with a mnemonic to the config file will tell Ignite CLI to add
-the account to the blockchain when you start it. This is useful for development
-purposes, but you should not do this in production.
-
-## Start a blockchain and a React app
-
-In the `example` directory run the following command to start your blockchain:
-
-```
-ignite chain serve
-```
-
-To start your React application, go to the `react` directory and run the following
-command in a separate terminal window:
-
-```
-npm install && npm run dev
-```
-
-It is recommended to run `npm install` before starting your app with `npm run
-dev` to ensure that all dependencies are installed (including the ones that the
-API client has, see `react/postinstall.js`).
-
-Open your browser and navigate to
-[http://localhost:5173/](http://localhost:5173/).
-
-
-
-Press "Connect wallet", enter your password into Keplr and press "Approve" to
-add your blockchain to Keplr.
-
-
-
-Make sure to select the account you're using for development purposes and the
-"Example Network" in Keplr's blockchain dropdown. You should see a list of
-assets in your React app.
-
-
-
-Congratulations! You have successfully created a client-side React application and
-connected it to your blockchain. You can modify the source code of your React
-application to build out the rest of your project.
\ No newline at end of file
diff --git a/docs/versioned_docs/version-v29/04-clients/04-react.md b/docs/versioned_docs/version-v29/04-clients/04-react.md
deleted file mode 100644
index e915b3121e..0000000000
--- a/docs/versioned_docs/version-v29/04-clients/04-react.md
+++ /dev/null
@@ -1,135 +0,0 @@
-# React frontend
-
-:::warning
-The React frontend is being reworked and is not yet stable.
-In the meantime, refer to the [Ignite CCA App](https://ignite.com/marketplace/cca).
-:::
-
-Welcome to this tutorial on using Ignite to develop a web application for your
-blockchain with React. Ignite is a tool that simplifies the process of building
-a blockchain application by providing a set of templates and generators that can
-be used to get up and running quickly.
-
-One of the features of Ignite is its support for [React](https://reactjs.org/), a
-popular JavaScript framework for building user interfaces. In this tutorial, you
-will learn how to use Ignite to create a new blockchain and scaffold a React
-frontend template. This will give you a basic foundation for your web
-application and make it easier to get started building out the rest of your
-application.
-
-Once you have your blockchain and React template set up, the next step is to
-generate an API client. This will allow you to easily interact with your
-blockchain from your web application, enabling you to retrieve data and make
-transactions. By the end of this tutorial, you will have a fully functional web
-application that is connected to your own blockchain.
-
-Prerequisites:
-
-* [Node.js](https://nodejs.org/en/)
-* [Keplr](https://www.keplr.app/) Chrome extension
-
-## Create a blockchain and a React app
-
-Create a new blockchain project:
-
-```
-ignite scaffold chain example
-```
-
-To create a React frontend template, go to the `example` directory and run the
-following command:
-
-```
-ignite scaffold react
-```
-
-This will create a new React project in the `react` directory. This project can be
-used with any blockchain, but it depends on an API client to interact with the
-blockchain. To generate an API client, run the following command in the
-`example` directory:
-
-```
-ignite generate hooks
-```
-
-This command generates two directories:
-
-* `ts-client`: a framework-agnostic TypeScript client that can be used to
- interact with your blockchain. You can learn more about how to use this client
- in the [TypeScript client tutorial](/clients/typescript).
-* `react/src/hooks`: a collection of
- [React Hooks](https://reactjs.org/docs/hooks-intro.html) that wrap
- the TypeScript client and make it easier to interact with your blockchain from
- your React application.
-
-## Set up Keplr and an account
-
-Open your browser with the Keplr wallet extension installed. Follow [the
-instructions](https://keplr.crunch.help/en/getting-started/creating-a-new-keplr-account)
-to create a new account or use an existing one. Make sure to save the mnemonic
-phrase as you will need it in the next step.
-
-Do not use a mnemonic phrase that is associated with an account that holds
-assets you care about. If you do, you risk losing those assets. It's a good
-practice to create a new account for development purposes.
-
-Add the account you're using in Keplr to your blockchain's `config.yml` file:
-
-```yml
-accounts:
- - name: alice
- coins: [20000token, 200000000stake]
- - name: bob
- coins: [10000token, 100000000stake]
- # highlight-start
- - name: frank
- coins: [10000token, 100000000stake]
- mnemonic: struggle since inmate safe logic kite tag web win stay security wonder
- # highlight-end
-```
-
-Replace the `struggle since...` mnemonic with the one you saved in the previous
-step.
-
-Adding an account with a mnemonic to the config file will tell Ignite CLI to add
-the account to the blockchain when you start it. This is useful for development
-purposes, but you should not do this in production.
-
-## Start a blockchain and a React app
-
-In the `example` directory run the following command to start your blockchain:
-
-```
-ignite chain serve
-```
-
-To start your React application, go to the `react` directory and run the following
-command in a separate terminal window:
-
-```
-npm install && npm run dev
-```
-
-It is recommended to run `npm install` before starting your app with `npm run
-dev` to ensure that all dependencies are installed (including the ones that the
-API client has, see `react/postinstall.js`).
-
-Open your browser and navigate to
-[http://localhost:5173/](http://localhost:5173/).
-
-
-
-Press "Connect wallet", enter your password into Keplr and press "Approve" to
-add your blockchain to Keplr.
-
-
-
-Make sure to select the account you're using for development purposes and the
-"Example Network" in Keplr's blockchain dropdown. You should see a list of
-assets in your React app.
-
-
-
-Congratulations! You have successfully created a client-side React application and
-connected it to your blockchain. You can modify the source code of your React
-application to build out the rest of your project.
\ No newline at end of file
diff --git a/go.mod b/go.mod
index 4aba4e2c46..660ccde906 100644
--- a/go.mod
+++ b/go.mod
@@ -41,7 +41,7 @@ require (
github.com/hashicorp/go-hclog v1.6.3
github.com/hashicorp/go-plugin v1.6.3
github.com/iancoleman/strcase v0.3.0
- github.com/ignite/web v0.6.1
+ github.com/ignite/web v1.0.8
github.com/lib/pq v1.10.9
github.com/mitchellh/mapstructure v1.5.0
github.com/muesli/reflow v0.3.0
diff --git a/go.sum b/go.sum
index 08404755fb..07d09532a4 100644
--- a/go.sum
+++ b/go.sum
@@ -1107,8 +1107,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/ianlancetaylor/demangle v0.0.0-20210905161508-09a460cdf81d/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w=
github.com/ianlancetaylor/demangle v0.0.0-20230524184225-eabc099b10ab/go.mod h1:gx7rwoVhcfuVKG5uya9Hs3Sxj7EIvldVofAWIUtGouw=
-github.com/ignite/web v0.6.1 h1:kHG+T7NnR8cCPjAGxEFQD+njVYM08toeG57iYRXzpwo=
-github.com/ignite/web v0.6.1/go.mod h1:WZWBaBYF8RazN7dE462BLpvXDY8ScacxcJ07BKwX/jY=
+github.com/ignite/web v1.0.8 h1:St3L6UJj70+h16+No5em8Vn2Hx93tS2G1MyWO/Kt1cc=
+github.com/ignite/web v1.0.8/go.mod h1:WZWBaBYF8RazN7dE462BLpvXDY8ScacxcJ07BKwX/jY=
github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
github.com/imdario/mergo v0.3.15 h1:M8XP7IuFNsqUx6VPK2P9OSmsYsI/YFaGil0uD21V3dM=
github.com/imdario/mergo v0.3.15/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY=
diff --git a/ignite/cmd/generate.go b/ignite/cmd/generate.go
index 16ca7065e9..1fec283aa3 100644
--- a/ignite/cmd/generate.go
+++ b/ignite/cmd/generate.go
@@ -33,11 +33,12 @@ meant to be edited by hand.
flagSetPath(c)
flagSetClearCache(c)
- c.AddCommand(NewGenerateGo())
- c.AddCommand(NewGenerateTSClient())
- c.AddCommand(NewGenerateComposables())
- c.AddCommand(NewGenerateHooks())
- c.AddCommand(NewGenerateOpenAPI())
+ c.AddCommand(
+ NewGenerateGo(),
+ NewGenerateTSClient(),
+ NewGenerateComposables(),
+ NewGenerateOpenAPI(),
+ )
return c
}
diff --git a/ignite/cmd/generate_hooks.go b/ignite/cmd/generate_hooks.go
deleted file mode 100644
index 91975278f5..0000000000
--- a/ignite/cmd/generate_hooks.go
+++ /dev/null
@@ -1,58 +0,0 @@
-package ignitecmd
-
-import (
- "github.com/spf13/cobra"
-
- "github.com/ignite/cli/v29/ignite/pkg/cliui"
- "github.com/ignite/cli/v29/ignite/pkg/cliui/icons"
- "github.com/ignite/cli/v29/ignite/services/chain"
-)
-
-func NewGenerateHooks() *cobra.Command {
- c := &cobra.Command{
- Use: "hooks",
- Short: "TypeScript frontend client and React hooks",
- RunE: generateHooksHandler,
- }
-
- c.Flags().AddFlagSet(flagSetYes())
- c.Flags().StringP(flagOutput, "o", "", "React hooks output path")
-
- return c
-}
-
-func generateHooksHandler(cmd *cobra.Command, _ []string) error {
- session := cliui.New(
- cliui.StartSpinnerWithText(statusGenerating),
- cliui.WithoutUserInteraction(getYes(cmd)),
- )
- defer session.End()
-
- c, err := chain.NewWithHomeFlags(
- cmd,
- chain.WithOutputer(session),
- chain.CollectEvents(session.EventBus()),
- chain.PrintGeneratedPaths())
- if err != nil {
- return err
- }
-
- cacheStorage, err := newCache(cmd)
- if err != nil {
- return err
- }
-
- output, _ := cmd.Flags().GetString(flagOutput)
-
- var opts []chain.GenerateTarget
- if flagGetEnableProtoVendor(cmd) {
- opts = append(opts, chain.GenerateProtoVendor())
- }
-
- err = c.Generate(cmd.Context(), cacheStorage, chain.GenerateHooks(output), opts...)
- if err != nil {
- return err
- }
-
- return session.Println(icons.OK, "Generated Typescript Client and React hooks")
-}
diff --git a/ignite/cmd/scaffold_react.go b/ignite/cmd/scaffold_react.go
index dc26c49c1f..60a9dfd47d 100644
--- a/ignite/cmd/scaffold_react.go
+++ b/ignite/cmd/scaffold_react.go
@@ -2,40 +2,14 @@ package ignitecmd
import (
"github.com/spf13/cobra"
-
- chainconfig "github.com/ignite/cli/v29/ignite/config/chain"
- "github.com/ignite/cli/v29/ignite/pkg/cliui"
- "github.com/ignite/cli/v29/ignite/pkg/cosmosgen"
)
// NewScaffoldReact scaffolds a React app for a chain.
func NewScaffoldReact() *cobra.Command {
c := &cobra.Command{
- Hidden: true, // hidden util we have a better ts-client.
- Use: "react",
- Short: "React web app template",
- Args: cobra.NoArgs,
- PreRunE: migrationPreRunHandler,
- RunE: scaffoldReactHandler,
+ Use: "react",
+ Deprecated: "the React scaffolding feature is removed from Ignite CLI.\nPlease use the Ignite CCA app to create a React app.\nFor more information, visit: https://ignite.com/marketplace/CCA",
}
- c.Flags().AddFlagSet(flagSetYes())
- c.Flags().StringP(flagPath, "p", "./"+chainconfig.DefaultReactPath, "path to scaffold content of the React app")
-
return c
}
-
-func scaffoldReactHandler(cmd *cobra.Command, _ []string) error {
- session := cliui.New(
- cliui.StartSpinnerWithText(statusScaffolding),
- cliui.WithoutUserInteraction(getYes(cmd)),
- )
- defer session.End()
-
- path := flagGetPath(cmd)
- if err := cosmosgen.React(path); err != nil {
- return err
- }
-
- return session.Printf("\nš Scaffolded a React app in %s.\n\n", path)
-}
diff --git a/ignite/cmd/scaffold_vue.go b/ignite/cmd/scaffold_vue.go
index 2228979414..541b1e001e 100644
--- a/ignite/cmd/scaffold_vue.go
+++ b/ignite/cmd/scaffold_vue.go
@@ -1,6 +1,8 @@
package ignitecmd
import (
+ "path/filepath"
+
"github.com/spf13/cobra"
chainconfig "github.com/ignite/cli/v29/ignite/config/chain"
@@ -11,7 +13,6 @@ import (
// NewScaffoldVue scaffolds a Vue.js app for a chain.
func NewScaffoldVue() *cobra.Command {
c := &cobra.Command{
- Hidden: true, // hidden util we have a better ts-client.
Use: "vue",
Short: "Vue 3 web app template",
Args: cobra.NoArgs,
@@ -20,7 +21,6 @@ func NewScaffoldVue() *cobra.Command {
}
c.Flags().AddFlagSet(flagSetYes())
- c.Flags().StringP(flagPath, "p", "./"+chainconfig.DefaultVuePath, "path to scaffold content of the Vue.js app")
return c
}
@@ -32,7 +32,7 @@ func scaffoldVueHandler(cmd *cobra.Command, _ []string) error {
)
defer session.End()
- path := flagGetPath(cmd)
+ path := filepath.Join(".", chainconfig.DefaultVuePath)
if err := cosmosgen.Vue(path); err != nil {
return err
}
diff --git a/ignite/config/chain/base/config.go b/ignite/config/chain/base/config.go
index c2772f73f3..5b1cfdce4f 100644
--- a/ignite/config/chain/base/config.go
+++ b/ignite/config/chain/base/config.go
@@ -41,9 +41,6 @@ type Client struct {
// Composables configures code generation for Vue 3 composables.
Composables Composables `yaml:"composables,omitempty" doc:"Configures Vue 3 composables code generation."`
- // Hooks configures code generation for React hooks.
- Hooks Hooks `yaml:"hooks,omitempty" doc:"Configures React hooks code generation."`
-
// OpenAPI configures OpenAPI spec generation for API.
OpenAPI OpenAPI `yaml:"openapi,omitempty" doc:"Configures OpenAPI spec generation for the API."`
}
@@ -60,12 +57,6 @@ type Composables struct {
Path string `yaml:"path" doc:"Relative path where the application's composable files are located."`
}
-// Hooks configures code generation for react-query hooks.
-type Hooks struct {
- // Path configures out location for generated vue-query hooks.
- Path string `yaml:"path" doc:"Relative path where the application's hooks files are located."`
-}
-
// OpenAPI configures OpenAPI spec generation for API.
type OpenAPI struct {
Path string `yaml:"path" doc:"Relative path where the application's OpenAPI files are located."`
diff --git a/ignite/config/chain/config.go b/ignite/config/chain/config.go
index 778b5c6220..0fa14999bf 100644
--- a/ignite/config/chain/config.go
+++ b/ignite/config/chain/config.go
@@ -26,10 +26,6 @@ var (
// The path is relative to the app's directory.
DefaultVuePath = "vue"
- // DefaultReactPath defines the default relative path to use when scaffolding a React app.
- // The path is relative to the app's directory.
- DefaultReactPath = "react"
-
// DefaultComposablesPath defines the default relative path to use when generating useQuery composables for a Vue app.
// The path is relative to the app's directory.
DefaultComposablesPath = "vue/src/composables"
@@ -37,10 +33,6 @@ var (
// DefaultVueTypesPath defines the default vue types path.
DefaultVueTypesPath = "vue/src/views/Types.vue"
- // DefaultHooksPath defines the default relative path to use when generating useQuery hooks for a React app.
- // The path is relative to the app's directory.
- DefaultHooksPath = "react/src/hooks"
-
// DefaultOpenAPIPath defines the default relative path to use when generating an OpenAPI schema.
// The path is relative to the app's directory.
DefaultOpenAPIPath = "docs/static/openapi.json"
@@ -100,16 +92,6 @@ func ComposablesPath(conf *Config) string {
return DefaultComposablesPath
}
-// HooksPath returns the relative path to the React useQuery hooks directory.
-// Path is relative to the app's directory.
-func HooksPath(conf *Config) string {
- if path := strings.TrimSpace(conf.Client.Hooks.Path); path != "" {
- return filepath.Clean(path)
- }
-
- return DefaultHooksPath
-}
-
// LocateDefault locates the default path for the config file.
// Returns ErrConfigNotFound when no config file found.
func LocateDefault(root string) (path string, err error) {
diff --git a/ignite/pkg/cosmosgen/cosmosgen.go b/ignite/pkg/cosmosgen/cosmosgen.go
index 15f9093136..6152fe16e9 100644
--- a/ignite/pkg/cosmosgen/cosmosgen.go
+++ b/ignite/pkg/cosmosgen/cosmosgen.go
@@ -29,9 +29,6 @@ type generateOptions struct {
composablesOut func(module.Module) string
composablesRootPath string
- hooksOut func(module.Module) string
- hooksRootPath string
-
specOut string
}
@@ -58,13 +55,6 @@ func WithComposablesGeneration(out ModulePathFunc, composablesRootPath string) O
}
}
-func WithHooksGeneration(out ModulePathFunc, hooksRootPath string) Option {
- return func(o *generateOptions) {
- o.hooksOut = out
- o.hooksRootPath = hooksRootPath
- }
-}
-
// WithGoGeneration adds protobuf (gogoproto) code generation.
func WithGoGeneration() Option {
return func(o *generateOptions) {
@@ -102,6 +92,7 @@ type generator struct {
appPath string
protoDir string
goModPath string
+ frontendPath string
opts *generateOptions
sdkImport string
sdkDir string
@@ -122,7 +113,7 @@ func (g *generator) cleanup() {
// Generate generates code from protoDir of an SDK app residing at appPath with given options.
// protoDir must be relative to the projectPath.
-func Generate(ctx context.Context, cacheStorage cache.Storage, appPath, protoDir, goModPath string, options ...Option) error {
+func Generate(ctx context.Context, cacheStorage cache.Storage, appPath, protoDir, goModPath string, frontendPath string, options ...Option) error {
buf, err := cosmosbuf.New(cacheStorage, goModPath)
if err != nil {
return err
@@ -133,6 +124,7 @@ func Generate(ctx context.Context, cacheStorage cache.Storage, appPath, protoDir
appPath: appPath,
protoDir: protoDir,
goModPath: goModPath,
+ frontendPath: frontendPath,
opts: &generateOptions{},
thirdModules: make(map[string][]module.Module),
thirdModuleIncludes: make(map[string]protoIncludes),
@@ -180,26 +172,14 @@ func Generate(ctx context.Context, cacheStorage cache.Storage, appPath, protoDir
}
if g.opts.composablesRootPath != "" {
- if err := g.generateComposables("vue"); err != nil {
+ if err := g.generateComposables(); err != nil {
return err
}
// Update Vue app dependencies when Vue composables are generated.
// This update is required to link the "ts-client" folder so the
// package is available during development before publishing it.
- if err := g.updateComposableDependencies("vue"); err != nil {
- return err
- }
- }
- if g.opts.hooksRootPath != "" {
- if err := g.generateComposables("react"); err != nil {
- return err
- }
-
- // Update React app dependencies when React hooks are generated.
- // This update is required to link the "ts-client" folder so the
- // package is available during development before publishing it.
- if err := g.updateComposableDependencies("react"); err != nil {
+ if err := g.updateComposableDependencies(); err != nil {
return err
}
}
diff --git a/ignite/pkg/cosmosgen/generate_composables.go b/ignite/pkg/cosmosgen/generate_composables.go
index 864dcd94af..98a642a815 100644
--- a/ignite/pkg/cosmosgen/generate_composables.go
+++ b/ignite/pkg/cosmosgen/generate_composables.go
@@ -15,31 +15,30 @@ import (
"github.com/ignite/cli/v29/ignite/pkg/gomodulepath"
)
-type composablesGenerator struct {
- g *generator
- frontendType string
-}
+func (g *generator) checkVueExists() error {
+ _, err := os.Stat(filepath.Join(g.appPath, g.frontendPath))
+ if errors.Is(err, os.ErrNotExist) {
+ return errors.New("frontend does not exist, please run `ignite scaffold vue` first")
+ }
-func newComposablesGenerator(g *generator, frontendType string) *composablesGenerator {
- return &composablesGenerator{g, frontendType}
+ return err
}
-func (g *generator) updateComposableDependencies(frontendType string) error {
- // Init the path to the appropriate frontend folder inside the app
- frontendPath := filepath.Join(g.appPath, frontendType)
- packagesPath := filepath.Join(frontendPath, "package.json")
- if _, err := os.Stat(packagesPath); errors.Is(err, os.ErrNotExist) {
- return nil
+func (g *generator) updateComposableDependencies() error {
+ if err := g.checkVueExists(); err != nil {
+ return err
}
- // Read the Vue app package file
+ // Init the path to the appropriate frontend folder inside the app
+ frontendPath := filepath.Join(g.appPath, g.frontendPath)
+ packagesPath := filepath.Join(g.appPath, g.frontendPath, "package.json")
+
b, err := os.ReadFile(packagesPath)
if err != nil {
return err
}
- var pkg map[string]interface{}
-
+ var pkg map[string]any
if err := json.Unmarshal(b, &pkg); err != nil {
return errors.Errorf("error parsing %s: %w", packagesPath, err)
}
@@ -90,7 +89,11 @@ func (g *generator) updateComposableDependencies(frontendType string) error {
return nil
}
-func (g *generator) generateComposables(frontendType string) error {
+func (g *generator) generateComposables() error {
+ if err := g.checkVueExists(); err != nil {
+ return err
+ }
+
chainPath, _, err := gomodulepath.Find(g.appPath)
if err != nil {
return err
@@ -106,7 +109,7 @@ func (g *generator) generateComposables(frontendType string) error {
data.Modules = append(data.Modules, modules...)
}
- vsg := newComposablesGenerator(g, frontendType)
+ vsg := newComposablesGenerator(g)
if err := vsg.generateComposableTemplates(data); err != nil {
return err
}
@@ -114,6 +117,14 @@ func (g *generator) generateComposables(frontendType string) error {
return vsg.generateRootTemplates(data)
}
+type composablesGenerator struct {
+ g *generator
+}
+
+func newComposablesGenerator(g *generator) *composablesGenerator {
+ return &composablesGenerator{g}
+}
+
func (g *composablesGenerator) generateComposableTemplates(p generatePayload) error {
gg := &errgroup.Group{}
@@ -127,35 +138,22 @@ func (g *composablesGenerator) generateComposableTemplates(p generatePayload) er
}
func (g *composablesGenerator) generateComposableTemplate(m module.Module, p generatePayload) error {
- var outDir string
- if g.frontendType == "vue" {
- outDir = g.g.opts.composablesOut(m)
- } else {
- outDir = g.g.opts.hooksOut(m)
- }
-
+ outDir := g.g.opts.composablesOut(m)
if err := os.MkdirAll(outDir, 0o766); err != nil {
return err
}
return templateTSClientComposable.Write(outDir, "", struct {
- Module module.Module
- PackageNS string
- FrontendType string
+ Module module.Module
+ PackageNS string
}{
- Module: m,
- PackageNS: p.PackageNS,
- FrontendType: g.frontendType,
+ Module: m,
+ PackageNS: p.PackageNS,
})
}
func (g *composablesGenerator) generateRootTemplates(p generatePayload) error {
- var outDir string
- if g.frontendType == "vue" {
- outDir = g.g.opts.composablesRootPath
- } else {
- outDir = g.g.opts.hooksRootPath
- }
+ outDir := g.g.opts.composablesRootPath
if err := os.MkdirAll(outDir, 0o766); err != nil {
return err
}
diff --git a/ignite/pkg/cosmosgen/templates/composable/index.ts.tpl b/ignite/pkg/cosmosgen/templates/composable/index.ts.tpl
index 352f128f56..4f3a97eb5a 100644
--- a/ignite/pkg/cosmosgen/templates/composable/index.ts.tpl
+++ b/ignite/pkg/cosmosgen/templates/composable/index.ts.tpl
@@ -1,5 +1,5 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
-import { useQuery, type UseQueryOptions, useInfiniteQuery, type UseInfiniteQueryOptions, type InfiniteData } from "@tanstack/{{- .FrontendType -}}-query";
+import { useQuery, type UseQueryOptions, useInfiniteQuery, type UseInfiniteQueryOptions, type InfiniteData } from "@tanstack/vue-query";
import { useClient } from '../useClient';
export default function use{{ camelCaseUpperSta $.Module.Pkg.Name }}() {
diff --git a/ignite/pkg/cosmosgen/webtemplates.go b/ignite/pkg/cosmosgen/webtemplates.go
index 3c3c2f3ea5..000e70096a 100644
--- a/ignite/pkg/cosmosgen/webtemplates.go
+++ b/ignite/pkg/cosmosgen/webtemplates.go
@@ -6,11 +6,6 @@ import (
"github.com/ignite/cli/v29/ignite/pkg/localfs"
)
-// React scaffolds a React app for a chain.
-func React(path string) error {
- return localfs.Save(webtemplates.ReactBoilerplate(), path)
-}
-
// Vue scaffolds a Vue.js app for a chain.
func Vue(path string) error {
return localfs.Save(webtemplates.VueBoilerplate(), path)
diff --git a/ignite/services/chain/generate.go b/ignite/services/chain/generate.go
index b9d68728d8..97c8f05cef 100644
--- a/ignite/services/chain/generate.go
+++ b/ignite/services/chain/generate.go
@@ -21,11 +21,9 @@ type generateOptions struct {
isGoEnabled bool
isTSClientEnabled bool
isComposablesEnabled bool
- isHooksEnabled bool
isOpenAPIEnabled bool
tsClientPath string
composablesPath string
- hooksPath string
}
// GenerateTarget is a target to generate code for from proto files.
@@ -60,16 +58,6 @@ func GenerateComposables(path string) GenerateTarget {
}
}
-// GenerateHooks enables generating proto based Typescript Client and React composables.
-func GenerateHooks(path string) GenerateTarget {
- return func(o *generateOptions) {
- o.isOpenAPIEnabled = true
- o.isTSClientEnabled = true
- o.isHooksEnabled = true
- o.hooksPath = path
- }
-}
-
// GenerateOpenAPI enables generating OpenAPI spec for your chain.
func GenerateOpenAPI() GenerateTarget {
return func(o *generateOptions) {
@@ -111,10 +99,6 @@ func (c *Chain) generateFromConfig(ctx context.Context, cacheStorage cache.Stora
if p := conf.Client.Composables.Path; p != "" {
targets = append(targets, GenerateComposables(p))
}
-
- if p := conf.Client.Hooks.Path; p != "" {
- targets = append(targets, GenerateHooks(p))
- }
}
// Generate proto based code for Go and optionally for any optional targets
@@ -152,8 +136,8 @@ func (c *Chain) Generate(
}
var (
- openAPIPath, tsClientPath, composablesPath, hooksPath string
- updateConfig bool
+ openAPIPath, tsClientPath, composablesPath string
+ updateConfig bool
)
if targetOptions.isOpenAPIEnabled {
@@ -222,36 +206,13 @@ func (c *Chain) Generate(
)
}
- if targetOptions.isHooksEnabled {
- hooksPath = targetOptions.hooksPath
- if hooksPath == "" {
- hooksPath = chainconfig.HooksPath(conf)
-
- if conf.Client.Hooks.Path == "" {
- conf.Client.Hooks.Path = hooksPath
- updateConfig = true
- }
- }
-
- // Non-absolute Hooks output paths must be treated as relative to the app directory
- if !filepath.IsAbs(hooksPath) {
- hooksPath = filepath.Join(c.app.Path, hooksPath)
- }
-
- options = append(options,
- cosmosgen.WithHooksGeneration(
- cosmosgen.ComposableModulePath(hooksPath),
- hooksPath,
- ),
- )
- }
-
if err := cosmosgen.Generate(
ctx,
cacheStorage,
c.app.Path,
conf.Build.Proto.Path,
c.app.ImportPath,
+ chainconfig.DefaultVuePath,
options...,
); err != nil {
return &CannotBuildAppError{err}
@@ -281,14 +242,6 @@ func (c *Chain) Generate(
)
}
- if targetOptions.isHooksEnabled {
- c.ev.Send(
- fmt.Sprintf("React hooks path: %s", hooksPath),
- events.Icon(icons.Bullet),
- events.ProgressFinish(),
- )
- }
-
if targetOptions.isOpenAPIEnabled {
c.ev.Send(
fmt.Sprintf("OpenAPI path: %s", openAPIPath),
diff --git a/ignite/services/scaffolder/scaffolder.go b/ignite/services/scaffolder/scaffolder.go
index a54d95639c..723a77b6bc 100644
--- a/ignite/services/scaffolder/scaffolder.go
+++ b/ignite/services/scaffolder/scaffolder.go
@@ -176,7 +176,15 @@ func protoc(ctx context.Context, cacheStorage cache.Storage, projectPath, protoD
options = append(options, cosmosgen.WithOpenAPIGeneration(openAPIPath))
}
- if err := cosmosgen.Generate(ctx, cacheStorage, projectPath, protoDir, goModPath, options...); err != nil {
+ if err := cosmosgen.Generate(
+ ctx,
+ cacheStorage,
+ projectPath,
+ protoDir,
+ goModPath,
+ chainconfig.DefaultVuePath,
+ options...,
+ ); err != nil {
return err
}
diff --git a/ignite/templates/app/files/readme.md.plush b/ignite/templates/app/files/readme.md.plush
index c480ea2870..c0e2c15248 100644
--- a/ignite/templates/app/files/readme.md.plush
+++ b/ignite/templates/app/files/readme.md.plush
@@ -15,11 +15,10 @@ Your blockchain in development can be configured with `config.yml`. To learn mor
### Web Frontend
-Additionally, Ignite CLI offers both Vue and React options for frontend scaffolding:
+Additionally, Ignite CLI offers a frontend scaffolding feature (based on Vue) to help you quickly build a web frontend for your blockchain:
-For a Vue frontend, use: `ignite scaffold vue`
-For a React frontend, use: `ignite scaffold react`
-These commands can be run within your scaffolded blockchain project.
+Use: `ignite scaffold vue`
+This command can be run within your scaffolded blockchain project.
For more information see the [monorepo for Ignite front-end development](https://github.com/ignite/web).
diff --git a/integration/app.go b/integration/app.go
index dc3aee6994..6de6125627 100644
--- a/integration/app.go
+++ b/integration/app.go
@@ -376,8 +376,15 @@ func (a *App) addScaffoldCmd(typeName string, args ...string) {
index := ""
response := ""
params := ""
- name := args[0]
- args = args[1:]
+ name := typeName
+
+ // in the case of scaffolding commands that do no take arguments
+ // we can skip the argument parsing
+ if len(args) > 0 {
+ name = args[0]
+ args = args[1:]
+ }
+
filteredArgs := make([]string, 0)
// remove the flags from the args
diff --git a/integration/client.go b/integration/client.go
deleted file mode 100644
index c48df283f2..0000000000
--- a/integration/client.go
+++ /dev/null
@@ -1,156 +0,0 @@
-package envtest
-
-import (
- "bytes"
- "maps"
- "os"
- "os/exec"
- "path/filepath"
- "runtime"
-
- "github.com/stretchr/testify/require"
-
- chainconfig "github.com/ignite/cli/v29/ignite/config/chain"
- "github.com/ignite/cli/v29/ignite/pkg/cmdrunner"
- "github.com/ignite/cli/v29/ignite/pkg/cmdrunner/step"
-)
-
-type clientOptions struct {
- env map[string]string
- testName, testFilePath string
-}
-
-// ClientOption defines options for the TS client test runner.
-type ClientOption func(*clientOptions)
-
-// ClientEnv option defines environment values for the tests.
-func ClientEnv(env map[string]string) ClientOption {
- return func(o *clientOptions) {
- maps.Copy(o.env, env)
- }
-}
-
-// ClientTestName option defines a pattern to match the test names that should be run.
-func ClientTestName(pattern string) ClientOption {
- return func(o *clientOptions) {
- o.testName = pattern
- }
-}
-
-// ClientTestFile option defines the name of the file where to look for tests.
-func ClientTestFile(filePath string) ClientOption {
- return func(o *clientOptions) {
- o.testFilePath = filePath
- }
-}
-
-// RunClientTests runs the Typescript client tests.
-func (a App) RunClientTests(options ...ClientOption) bool {
- npm, err := exec.LookPath("npm")
- require.NoError(a.env.t, err, "npm binary not found")
-
- // The root dir for the tests must be an absolute path.
- // It is used as the start search point to find test files.
- rootDir, err := os.Getwd()
- require.NoError(a.env.t, err)
-
- // The filename of this module is required to be able to define the location
- // of the TS client test runner package to be used as working directory when
- // running the tests.
- _, filename, _, ok := runtime.Caller(0)
- if !ok {
- a.env.t.Fatal("failed to read file name")
- }
-
- opts := clientOptions{
- env: map[string]string{
- // Absolute path to the blockchain app directory
- "TEST_CHAIN_PATH": a.path,
- // Absolute path to the TS client directory
- "TEST_TSCLIENT_DIR": filepath.Join(a.path, chainconfig.DefaultTSClientPath),
- },
- }
- for _, o := range options {
- o(&opts)
- }
-
- var (
- output bytes.Buffer
- env []string
- )
-
- // Install the dependencies needed to run TS client tests
- ok = a.env.Exec("install client dependencies", step.NewSteps(
- step.New(
- step.Workdir(filepath.Join(a.path, chainconfig.DefaultTSClientPath)),
- step.Stdout(&output),
- step.Exec(npm, "install"),
- step.PostExec(func(err error) error {
- // Print the npm output when there is an error
- if err != nil {
- a.env.t.Log("\n", output.String())
- }
-
- return err
- }),
- ),
- ))
- if !ok {
- return false
- }
-
- output.Reset()
-
- args := []string{"run", "test", "--", "--dir", rootDir}
- if opts.testName != "" {
- args = append(args, "-t", opts.testName)
- }
-
- if opts.testFilePath != "" {
- args = append(args, opts.testFilePath)
- }
-
- for k, v := range opts.env {
- env = append(env, cmdrunner.Env(k, v))
- }
-
- // The tests are run from the TS client test runner package directory
- runnerDir := filepath.Join(filepath.Dir(filename), "testdata/tstestrunner")
-
- // TODO: Ignore stderr ? Errors are already displayed with traceback in the stdout
- return a.env.Exec("run client tests", step.NewSteps(
- // Make sure the test runner dependencies are installed
- step.New(
- step.Workdir(runnerDir),
- step.Stdout(&output),
- step.Exec(npm, "install"),
- step.PostExec(func(err error) error {
- // Print the npm output when there is an error
- if err != nil {
- a.env.t.Log("\n", output.String())
- }
-
- return err
- }),
- ),
- // Run the TS client tests
- step.New(
- step.Workdir(runnerDir),
- step.Stdout(&output),
- step.Env(env...),
- step.PreExec(func() error {
- // Clear the output from the previous step
- output.Reset()
-
- return nil
- }),
- step.Exec(npm, args...),
- step.PostExec(func(err error) error {
- // Always print tests output to be available on errors or when verbose is enabled
- a.env.t.Log("\n", output.String())
-
- return err
- }),
- ),
- ))
-}
diff --git a/integration/cosmosgen/bank_module_test.go b/integration/cosmosgen/bank_module_test.go
deleted file mode 100644
index 53875f2211..0000000000
--- a/integration/cosmosgen/bank_module_test.go
+++ /dev/null
@@ -1,91 +0,0 @@
-package cosmosgen_test
-
-import (
- "context"
- "encoding/json"
- "fmt"
- "testing"
-
- "github.com/stretchr/testify/require"
-
- chainconfig "github.com/ignite/cli/v29/ignite/config/chain"
- "github.com/ignite/cli/v29/ignite/config/chain/base"
- "github.com/ignite/cli/v29/ignite/pkg/xurl"
- envtest "github.com/ignite/cli/v29/integration"
-)
-
-// TestBankModule tests the bank module by creating accounts, transferring tokens between them, and querying the account balances.
-func TestBankModule(t *testing.T) {
- t.Skip()
-
- var (
- env = envtest.New(t)
- app = env.ScaffoldApp("chain", "--no-module")
- servers = app.RandomizeServerPorts()
- )
-
- queryAPI, err := xurl.HTTP(servers.API)
- require.NoError(t, err)
-
- txAPI, err := xurl.HTTP(servers.RPC)
- require.NoError(t, err)
-
- // Accounts to be included in the genesis
- accounts := []base.Account{
- {
- Name: "account1",
- Address: "cosmos1j8hw8283hj80hhq8urxaj40syrzqp77dt8qwhm",
- Mnemonic: fmt.Sprint(
- "toe mail light plug pact length excess predict real artwork laundry when steel ",
- "online adapt clutch debate vehicle dash alter rifle virtual season almost",
- ),
- Coins: []string{"10000token", "10000stake"},
- },
- {
- Name: "account2",
- Address: "cosmos19yy9sf00k00cjcwh532haeq8s63uhdy7qs5m2n",
- Mnemonic: fmt.Sprint(
- "someone major rule wrestle forget want job record coil table enter gold bracket ",
- "zone tent music grow shiver width index radio matter asset when",
- ),
- Coins: []string{"100token", "100stake"},
- },
- {
- Name: "account3",
- Address: "cosmos10957ee377t2xpwyt4mlpedjldp592h0ylt8uz7",
- Mnemonic: fmt.Sprint(
- "edit effort own cat chuckle rookie mechanic side tool sausage other fade math ",
- "joy midnight cabin act plastic spawn loud chest invest budget rebel",
- ),
- Coins: []string{"100token", "100stake"},
- },
- }
-
- app.EditConfig(func(cfg *chainconfig.Config) {
- cfg.Accounts = append(cfg.Accounts, accounts...)
- })
-
- env.Must(app.GenerateTSClient())
-
- ctx, cancel := context.WithTimeout(env.Ctx(), envtest.ServeTimeout)
- defer cancel()
-
- go func() {
- app.Serve("should serve app", envtest.ExecCtx(ctx))
- }()
-
- // Wait for the server to be up before running the client tests
- app.WaitChainUp(ctx, servers.API)
-
- testAccounts, err := json.Marshal(accounts)
- require.NoError(t, err)
-
- env.Must(app.RunClientTests(
- envtest.ClientTestFile("bank_module_test.ts"),
- envtest.ClientEnv(map[string]string{
- "TEST_QUERY_API": queryAPI,
- "TEST_TX_API": txAPI,
- "TEST_ACCOUNTS": string(testAccounts),
- }),
- ))
-}
diff --git a/integration/cosmosgen/bank_module_test.ts b/integration/cosmosgen/bank_module_test.ts
deleted file mode 100644
index 8a6090ac97..0000000000
--- a/integration/cosmosgen/bank_module_test.ts
+++ /dev/null
@@ -1,61 +0,0 @@
-import { describe, expect, it } from "vitest";
-import { DirectSecp256k1HdWallet } from "@cosmjs/proto-signing";
-import { isDeliverTxSuccess } from "@cosmjs/stargate";
-
-describe("bank module", async () => {
- const { Client } = await import("client");
-
- it("should transfer to two different addresses", async () => {
- const { account1, account2, account3 } = globalThis.accounts;
-
- const mnemonic = account1["Mnemonic"];
- const wallet = await DirectSecp256k1HdWallet.fromMnemonic(mnemonic);
- const [account] = await wallet.getAccounts();
-
- const denom = "token";
- const env = {
- denom,
- rpcURL: globalThis.txApi,
- apiURL: globalThis.queryApi,
- };
- const client = new Client(env, wallet);
-
- const toAddresses = [account2["Address"], account3["Address"]];
-
- // Both accounts start with 100token before the transfer
- const result = await client.signAndBroadcast([
- client.CosmosBankV1Beta1.tx.msgSend({
- value: {
- fromAddress: account.address,
- toAddress: toAddresses[0],
- amount: [{ denom, amount: "100" }],
- },
- }),
- client.CosmosBankV1Beta1.tx.msgSend({
- value: {
- fromAddress: account.address,
- toAddress: toAddresses[1],
- amount: [{ denom, amount: "200" }],
- },
- }),
- ]);
-
- expect(isDeliverTxSuccess(result)).toEqual(true);
-
- // Check that the transfers were successful
- const cases = [
- { address: toAddresses[0], wantAmount: "200" },
- { address: toAddresses[1], wantAmount: "300" },
- ];
-
- for (let tc of cases) {
- let response = await client.CosmosBankV1Beta1.query.queryBalance(
- tc.address,
- { denom }
- );
-
- expect(response.statusText).toEqual("OK");
- expect(response.data.balance.amount).toEqual(tc.wantAmount);
- }
- });
-});
diff --git a/integration/cosmosgen/cosmosgen_composables_test.go b/integration/cosmosgen/cosmosgen_composables_test.go
index 37e62e2982..d7ecdb9fd5 100644
--- a/integration/cosmosgen/cosmosgen_composables_test.go
+++ b/integration/cosmosgen/cosmosgen_composables_test.go
@@ -12,7 +12,9 @@ import (
)
func TestCosmosGenScaffoldComposables(t *testing.T) {
- t.Skip()
+ if envtest.IsCI {
+ t.Skip("Skipping TestCosmosGenScaffoldComposables test in CI environment")
+ }
var (
env = envtest.New(t)
@@ -67,6 +69,12 @@ func TestCosmosGenScaffoldComposables(t *testing.T) {
composablesDirGenerated := filepath.Join(app.SourcePath(), "vue/src/composables")
require.NoError(t, os.RemoveAll(composablesDirGenerated))
+ app.Scaffold(
+ "scaffold vue",
+ false,
+ "vue",
+ )
+
app.Generate(
"generate composables",
false,
@@ -94,16 +102,25 @@ func TestCosmosGenScaffoldComposables(t *testing.T) {
"useCosmosUpgradeV1Beta1",
"useCosmosVestingV1Beta1",
// custom modules
- "useTestBlogBlog",
- "useTestBlogWithmsg",
- "useTestBlogWithoutmsg",
+ "useBlogBlogV1",
+ "useBlogWithmsgV1",
+ "useBlogWithoutmsgV1",
}
for _, mod := range expectedQueryModules {
-
_, err := os.Stat(filepath.Join(composablesDirGenerated, mod))
if assert.False(t, os.IsNotExist(err), "missing composable %q in %s", mod, composablesDirGenerated) {
assert.NoError(t, err)
}
}
+
+ if t.Failed() {
+ // list composables files
+ composablesFiles, err := os.ReadDir(composablesDirGenerated)
+ require.NoError(t, err)
+ t.Log("Composables files:", len(composablesFiles))
+ for _, file := range composablesFiles {
+ t.Logf(" - %s", file.Name())
+ }
+ }
}
diff --git a/integration/cosmosgen/cosmosgen_hooks_test.go b/integration/cosmosgen/cosmosgen_hooks_test.go
deleted file mode 100644
index 352af6a4bf..0000000000
--- a/integration/cosmosgen/cosmosgen_hooks_test.go
+++ /dev/null
@@ -1,151 +0,0 @@
-package cosmosgen_test
-
-import (
- "os"
- "path/filepath"
- "testing"
-
- "github.com/stretchr/testify/assert"
- "github.com/stretchr/testify/require"
-
- "github.com/ignite/cli/v29/ignite/pkg/cmdrunner/step"
- envtest "github.com/ignite/cli/v29/integration"
-)
-
-func TestCosmosGenScaffoldHooks(t *testing.T) {
- t.Skip()
-
- var (
- env = envtest.New(t)
- app = env.ScaffoldApp("github.com/test/blog")
- )
-
- const (
- withMsgModuleName = "withmsg"
- withoutMsgModuleName = "withoutmsg"
- )
-
- env.Must(env.Exec("add custom module with message",
- step.NewSteps(step.New(
- step.Exec(
- envtest.IgniteApp,
- "s",
- "module",
- "--yes",
- withMsgModuleName,
- ),
- step.Workdir(app.SourcePath()),
- )),
- ))
-
- env.Must(env.Exec("create a message",
- step.NewSteps(step.New(
- step.Exec(
- envtest.IgniteApp,
- "s",
- "message",
- "--yes",
- "mymessage",
- "myfield1",
- "myfield2:bool",
- "--module",
- withMsgModuleName,
- ),
- step.Workdir(app.SourcePath()),
- )),
- ))
-
- env.Must(env.Exec("add custom module without message",
- step.NewSteps(step.New(
- step.Exec(
- envtest.IgniteApp,
- "s",
- "module",
- "--yes",
- withoutMsgModuleName,
- ),
- step.Workdir(app.SourcePath()),
- )),
- ))
-
- env.Must(env.Exec("create a type",
- step.NewSteps(step.New(
- step.Exec(
- envtest.IgniteApp,
- "s",
- "type",
- "--yes",
- "mytype",
- "mytypefield",
- "--module",
- withoutMsgModuleName,
- ),
- step.Workdir(app.SourcePath()),
- )),
- ))
-
- env.Must(env.Exec("create a query",
- step.NewSteps(step.New(
- step.Exec(
- envtest.IgniteApp,
- "s",
- "query",
- "--yes",
- "myQuery",
- "mytypefield",
- "--module",
- withoutMsgModuleName,
- ),
- step.Workdir(app.SourcePath()),
- )),
- ))
-
- hooksDireGenerated := filepath.Join(app.SourcePath(), "react/src/hooks")
- require.NoError(t, os.RemoveAll(hooksDireGenerated))
-
- env.Must(env.Exec("generate hooks",
- step.NewSteps(step.New(
- step.Exec(
- envtest.IgniteApp,
- "g",
- "hooks",
- "--yes",
- "--clear-cache",
- ),
- step.Workdir(app.SourcePath()),
- )),
- ))
-
- expectedQueryModules := []string{
- "useCosmosAuthV1Beta1",
- "useCosmosAuthzV1Beta1",
- "useCosmosBankV1Beta1",
- "useCosmosBaseTendermintV1Beta1",
- "useCosmosDistributionV1Beta1",
- "useCosmosEvidenceV1Beta1",
- "useCosmosFeegrantV1Beta1",
- "useCosmosGovV1Beta1",
- "useCosmosGovV1",
- "useCosmosGroupV1",
- "useCosmosMintV1Beta1",
- "useCosmosNftV1Beta1",
- "useCosmosParamsV1Beta1",
- "useCosmosSlashingV1Beta1",
- "useCosmosStakingV1Beta1",
- "useCosmosTxV1Beta1",
- "useCosmosUpgradeV1Beta1",
- "useCosmosVestingV1Beta1",
- // custom modules
- "useTestBlogBlog",
- "useTestBlogWithmsg",
- "useTestBlogWithoutmsg",
- }
-
- for _, mod := range expectedQueryModules {
-
- _, err := os.Stat(filepath.Join(hooksDireGenerated, mod))
- if assert.False(t, os.IsNotExist(err), "missing hook %q in %s", mod, hooksDireGenerated) {
- assert.NoError(t, err)
- }
- }
-}
diff --git a/integration/cosmosgen/cosmosgen_test.go b/integration/cosmosgen/cosmosgen_test.go
index af1473e651..22f289432a 100644
--- a/integration/cosmosgen/cosmosgen_test.go
+++ b/integration/cosmosgen/cosmosgen_test.go
@@ -13,7 +13,9 @@ import (
)
func TestCosmosGenScaffold(t *testing.T) {
- t.Skip("skip till we add a buf token into the CI")
+ if envtest.IsCI {
+ t.Skip("Skipping CosmosGenScaffold test in CI environment")
+ }
var (
env = envtest.New(t)
@@ -147,4 +149,14 @@ func TestCosmosGenScaffold(t *testing.T) {
assert.NoError(t, err)
}
}
+
+ if t.Failed() {
+ // list ts-client files
+ tsFiles, err := os.ReadDir(tsDirGenerated)
+ require.NoError(t, err)
+ t.Log("TS files:", len(tsFiles))
+ for _, file := range tsFiles {
+ t.Logf(" - %s", file.Name())
+ }
+ }
}
diff --git a/integration/cosmosgen/custom_module_test.go b/integration/cosmosgen/custom_module_test.go
deleted file mode 100644
index e740c5dd84..0000000000
--- a/integration/cosmosgen/custom_module_test.go
+++ /dev/null
@@ -1,89 +0,0 @@
-package cosmosgen_test
-
-import (
- "context"
- "encoding/json"
- "fmt"
- "testing"
-
- "github.com/stretchr/testify/require"
-
- chainconfig "github.com/ignite/cli/v29/ignite/config/chain"
- "github.com/ignite/cli/v29/ignite/config/chain/base"
- "github.com/ignite/cli/v29/ignite/pkg/cmdrunner/step"
- "github.com/ignite/cli/v29/ignite/pkg/xurl"
- envtest "github.com/ignite/cli/v29/integration"
-)
-
-func TestCustomModule(t *testing.T) {
- t.Skip()
-
- var (
- env = envtest.New(t)
- app = env.ScaffoldApp("chain", "--no-module")
- servers = app.RandomizeServerPorts()
- )
-
- queryAPI, err := xurl.HTTP(servers.API)
- require.NoError(t, err)
-
- txAPI, err := xurl.HTTP(servers.RPC)
- require.NoError(t, err)
-
- // Accounts to be included in the genesis
- accounts := []base.Account{
- {
- Name: "account1",
- Address: "cosmos1j8hw8283hj80hhq8urxaj40syrzqp77dt8qwhm",
- Mnemonic: fmt.Sprint(
- "toe mail light plug pact length excess predict real artwork laundry when ",
- "steel online adapt clutch debate vehicle dash alter rifle virtual season almost",
- ),
- Coins: []string{"10000token", "10000stake"},
- },
- }
-
- app.EditConfig(func(cfg *chainconfig.Config) {
- cfg.Accounts = append(cfg.Accounts, accounts...)
- })
-
- path := app.SourcePath()
-
- env.Must(env.Exec("create a module",
- step.NewSteps(step.New(
- step.Exec(envtest.IgniteApp, "s", "module", "disco", "--require-registration", "--yes"),
- step.Workdir(path),
- )),
- ))
-
- env.Must(env.Exec("create a list type",
- step.NewSteps(step.New(
- step.Exec(envtest.IgniteApp, "s", "list", "entry", "name", "--module", "disco", "--yes"),
- step.Workdir(path),
- )),
- ))
-
- env.Must(app.GenerateTSClient())
-
- ctx, cancel := context.WithTimeout(env.Ctx(), envtest.ServeTimeout)
- defer cancel()
-
- go func() {
- app.Serve("serve app", envtest.ExecCtx(ctx))
- }()
-
- // Wait for the server to be up before running the client tests
- app.WaitChainUp(ctx, servers.API)
-
- testAccounts, err := json.Marshal(accounts)
- require.NoError(t, err)
-
- env.Must(app.RunClientTests(
- envtest.ClientTestFile("custom_module_test.ts"),
- envtest.ClientEnv(map[string]string{
- "TEST_QUERY_API": queryAPI,
- "TEST_TX_API": txAPI,
- "TEST_ACCOUNTS": string(testAccounts),
- }),
- ))
-}
diff --git a/integration/cosmosgen/custom_module_test.ts b/integration/cosmosgen/custom_module_test.ts
deleted file mode 100644
index 4d51795238..0000000000
--- a/integration/cosmosgen/custom_module_test.ts
+++ /dev/null
@@ -1,41 +0,0 @@
-import { describe, expect, it } from 'vitest'
-import { DirectSecp256k1HdWallet } from '@cosmjs/proto-signing'
-import { isDeliverTxSuccess } from '@cosmjs/stargate'
-
-describe('custom module', async () => {
- const { Client } = await import('client')
-
- it('should create a list entry', async () => {
- const { account1 } = globalThis.accounts
-
- const mnemonic = account1['Mnemonic']
- const wallet = await DirectSecp256k1HdWallet.fromMnemonic(mnemonic)
- const [account] = await wallet.getAccounts();
-
- const denom = 'token'
- const env = {
- denom,
- rpcURL: globalThis.txApi,
- apiURL: globalThis.queryApi,
- }
- const client = new Client(env, wallet)
-
- const entry = {
- id: '0',
- creator: account.address,
- name: "test",
- }
-
- // Create a new list entry
- const result = await client.ChainDisco.tx.sendMsgCreateEntry({ value: entry })
-
- expect(isDeliverTxSuccess(result)).toEqual(true)
-
- // Check that the list entry is created
- const response = await client.ChainDisco.query.queryEntryAll()
-
- expect(response.statusText).toEqual('OK')
- expect(response.data['Entry']).toHaveLength(1)
- expect(response.data['Entry'][0]).toEqual(entry)
- })
-})
diff --git a/integration/env.go b/integration/env.go
index 00406147e9..72767c4377 100644
--- a/integration/env.go
+++ b/integration/env.go
@@ -33,7 +33,7 @@ var (
// invoked.
IgniteApp = path.Join(os.TempDir(), "ignite-tests", "ignite")
- isCI, _ = strconv.ParseBool(os.Getenv("CI"))
+ IsCI, _ = strconv.ParseBool(os.Getenv("CI"))
compileBinaryOnce sync.Once
)
diff --git a/integration/exec.go b/integration/exec.go
index 0e4d48869b..02d1fd11f3 100644
--- a/integration/exec.go
+++ b/integration/exec.go
@@ -81,7 +81,7 @@ func (e Env) Exec(msg string, steps step.Steps, options ...ExecOption) (ok bool)
fmt.Printf("Executing %d step(s) for %q\n", len(steps), msg)
copts = append(copts, cmdrunner.EnableDebug())
}
- if isCI {
+ if IsCI {
copts = append(copts, cmdrunner.EndSignal(os.Kill))
}
err := cmdrunner.