From 8673fcb20c8cfccbcfe99ed03e3d06b07731cfba Mon Sep 17 00:00:00 2001 From: Julien Robert Date: Tue, 19 Nov 2024 12:33:22 +0100 Subject: [PATCH 01/12] feat: scaffold chain-registry files --- ignite/cmd/scaffold.go | 1 + ignite/cmd/scaffold_chain_registry.go | 81 ++++++ ignite/services/scaffolder/chain_registry.go | 269 +++++++++++++++++++ 3 files changed, 351 insertions(+) create mode 100644 ignite/cmd/scaffold_chain_registry.go create mode 100644 ignite/services/scaffolder/chain_registry.go diff --git a/ignite/cmd/scaffold.go b/ignite/cmd/scaffold.go index e1a64e2173..f4b381523a 100644 --- a/ignite/cmd/scaffold.go +++ b/ignite/cmd/scaffold.go @@ -127,6 +127,7 @@ with an "--ibc" flag. Note that the default module is not IBC-enabled. NewScaffoldPacket(), NewScaffoldVue(), NewScaffoldReact(), + NewScaffoldChainRegistry(), ) return c diff --git a/ignite/cmd/scaffold_chain_registry.go b/ignite/cmd/scaffold_chain_registry.go new file mode 100644 index 0000000000..0b257fe979 --- /dev/null +++ b/ignite/cmd/scaffold_chain_registry.go @@ -0,0 +1,81 @@ +package ignitecmd + +import ( + "github.com/spf13/cobra" + + "github.com/ignite/cli/v29/ignite/pkg/cliui" + "github.com/ignite/cli/v29/ignite/services/scaffolder" +) + +// NewScaffoldChainRegistry returns the command to scaffold the chain registry chain.json and assets.json files. +func NewScaffoldChainRegistry() *cobra.Command { + c := &cobra.Command{ + Use: "chain-registry", + Short: "Configs for the chain registry", + Long: `Scaffold the chain registry chain.json and assets.json files. + +The chain registry is a GitHub repo, hosted at https://github.com/cosmos/cosmos-registry, that +contains the chain.json and assets.json files of most of chains in the Cosmos ecosystem. +It is good practices, when creating a new chain, and about to launch a testnet or mainnet, to +publish the chain's metadata in the chain registry. + +Read more about the chain.json at https://github.com/cosmos/chain-registry?tab=readme-ov-file#chainjson +Read more about the assets.json at https://github.com/cosmos/chain-registry?tab=readme-ov-file#assetlists`, + Args: cobra.MinimumNArgs(1), + PreRunE: migrationPreRunHandler, + RunE: scaffoldChainRegistryFiles, + } + + flagSetPath(c) + flagSetClearCache(c) + + c.Flags().AddFlagSet(flagSetYes()) + + return c +} + +func scaffoldChainRegistryFiles(cmd *cobra.Command, args []string) error { + var appPath = flagGetPath(cmd) + + session := cliui.New(cliui.StartSpinnerWithText(statusScaffolding)) + defer session.End() + + cfg, _, err := getChainConfig(cmd) + if err != nil { + return err + } + + cacheStorage, err := newCache(cmd) + if err != nil { + return err + } + + sc, err := scaffolder.New(cmd.Context(), appPath, cfg.Build.Proto.Path) + if err != nil { + return err + } + + err = sc.CreateChainRegistryFiles() + if err != nil { + return err + } + + sm, err := sc.ApplyModifications() + if err != nil { + return err + } + + if err := sc.PostScaffold(cmd.Context(), cacheStorage, false); err != nil { + return err + } + + modificationsStr, err := sm.String() + if err != nil { + return err + } + + session.Println(modificationsStr) + session.Printf("\nšŸŽ‰ Chain Registry files (assets.json and chain.json) succesfully scaffolded.\n") + + return nil +} diff --git a/ignite/services/scaffolder/chain_registry.go b/ignite/services/scaffolder/chain_registry.go new file mode 100644 index 0000000000..6b218b9c65 --- /dev/null +++ b/ignite/services/scaffolder/chain_registry.go @@ -0,0 +1,269 @@ +package scaffolder + +// https://raw.githubusercontent.com/cosmos/chain-registry/master/chain.schema.json +// https://github.com/cosmos/chain-registry?tab=readme-ov-file#sample +type chainJSON struct { + Schema string `json:"$schema"` + ChainName string `json:"chain_name"` + ChainType string `json:"chain_type"` + ChainID string `json:"chain_id"` + Website string `json:"website"` + PrettyName string `json:"pretty_name"` + Status string `json:"status"` + NetworkType string `json:"network_type"` + Bech32Prefix string `json:"bech32_prefix"` + DaemonName string `json:"daemon_name"` + NodeHome string `json:"node_home"` + KeyAlgos []string `json:"key_algos"` + Slip44 int `json:"slip44"` + Fees struct { + FeeTokens []struct { + Denom string `json:"denom"` + FixedMinGasPrice float64 `json:"fixed_min_gas_price"` + LowGasPrice float64 `json:"low_gas_price"` + AverageGasPrice float64 `json:"average_gas_price"` + HighGasPrice float64 `json:"high_gas_price"` + } `json:"fee_tokens"` + } `json:"fees"` + Staking struct { + StakingTokens []struct { + Denom string `json:"denom"` + } `json:"staking_tokens"` + } `json:"staking"` + Codebase struct { + GitRepo string `json:"git_repo"` + RecommendedVersion string `json:"recommended_version"` + CompatibleVersions []string `json:"compatible_versions"` + Consensus struct { + Type string `json:"type"` + Version string `json:"version"` + } `json:"consensus"` + Binaries struct { + LinuxAmd64 string `json:"linux/amd64"` + LinuxArm64 string `json:"linux/arm64"` + DarwinAmd64 string `json:"darwin/amd64"` + DarwinArm64 string `json:"darwin/arm64"` + } `json:"binaries"` + Genesis struct { + GenesisURL string `json:"genesis_url"` + } `json:"genesis"` + Versions []struct { + Name string `json:"name"` + Tag string `json:"tag"` + RecommendedVersion string `json:"recommended_version"` + CompatibleVersions []string `json:"compatible_versions"` + Consensus struct { + Type string `json:"type"` + Version string `json:"version"` + } `json:"consensus"` + Height int `json:"height"` + Binaries struct { + LinuxAmd64 string `json:"linux/amd64"` + LinuxArm64 string `json:"linux/arm64"` + DarwinAmd64 string `json:"darwin/amd64"` + DarwinArm64 string `json:"darwin/arm64"` + WindowsAmd64 string `json:"windows/amd64"` + } `json:"binaries,omitempty"` + NextVersionName string `json:"next_version_name"` + Sdk struct { + Type string `json:"type"` + Version string `json:"version"` + Tag string `json:"tag"` + } `json:"sdk"` + Ibc struct { + Type string `json:"type"` + Version string `json:"version"` + } `json:"ibc"` + Proposal int `json:"proposal,omitempty"` + Binaries0 struct { + LinuxAmd64 string `json:"linux/amd64"` + LinuxArm64 string `json:"linux/arm64"` + DarwinAmd64 string `json:"darwin/amd64"` + DarwinArm64 string `json:"darwin/arm64"` + WindowsAmd64 string `json:"windows/amd64"` + WindowsArm64 string `json:"windows/arm64"` + } `json:"binaries,omitempty"` + Binaries1 struct { + LinuxAmd64 string `json:"linux/amd64"` + LinuxArm64 string `json:"linux/arm64"` + DarwinAmd64 string `json:"darwin/amd64"` + DarwinArm64 string `json:"darwin/arm64"` + WindowsAmd64 string `json:"windows/amd64"` + WindowsArm64 string `json:"windows/arm64"` + } `json:"binaries,omitempty"` + Binaries2 struct { + LinuxAmd64 string `json:"linux/amd64"` + LinuxArm64 string `json:"linux/arm64"` + DarwinAmd64 string `json:"darwin/amd64"` + DarwinArm64 string `json:"darwin/arm64"` + WindowsAmd64 string `json:"windows/amd64"` + WindowsArm64 string `json:"windows/arm64"` + } `json:"binaries,omitempty"` + Binaries3 struct { + LinuxAmd64 string `json:"linux/amd64"` + LinuxArm64 string `json:"linux/arm64"` + DarwinAmd64 string `json:"darwin/amd64"` + DarwinArm64 string `json:"darwin/arm64"` + WindowsAmd64 string `json:"windows/amd64"` + WindowsArm64 string `json:"windows/arm64"` + } `json:"binaries,omitempty"` + Binaries4 struct { + LinuxAmd64 string `json:"linux/amd64"` + LinuxArm64 string `json:"linux/arm64"` + DarwinAmd64 string `json:"darwin/amd64"` + DarwinArm64 string `json:"darwin/arm64"` + WindowsAmd64 string `json:"windows/amd64"` + WindowsArm64 string `json:"windows/arm64"` + } `json:"binaries,omitempty"` + Binaries5 struct { + LinuxAmd64 string `json:"linux/amd64"` + LinuxArm64 string `json:"linux/arm64"` + DarwinAmd64 string `json:"darwin/amd64"` + DarwinArm64 string `json:"darwin/arm64"` + WindowsAmd64 string `json:"windows/amd64"` + WindowsArm64 string `json:"windows/arm64"` + } `json:"binaries,omitempty"` + Binaries6 struct { + LinuxAmd64 string `json:"linux/amd64"` + LinuxArm64 string `json:"linux/arm64"` + DarwinAmd64 string `json:"darwin/amd64"` + DarwinArm64 string `json:"darwin/arm64"` + WindowsAmd64 string `json:"windows/amd64"` + WindowsArm64 string `json:"windows/arm64"` + } `json:"binaries,omitempty"` + Binaries7 struct { + LinuxAmd64 string `json:"linux/amd64"` + LinuxArm64 string `json:"linux/arm64"` + DarwinAmd64 string `json:"darwin/amd64"` + DarwinArm64 string `json:"darwin/arm64"` + WindowsAmd64 string `json:"windows/amd64"` + WindowsArm64 string `json:"windows/arm64"` + } `json:"binaries,omitempty"` + Cosmwasm struct { + Version string `json:"version"` + Repo string `json:"repo"` + Tag string `json:"tag"` + } `json:"cosmwasm,omitempty"` + Binaries8 struct { + LinuxAmd64 string `json:"linux/amd64"` + LinuxArm64 string `json:"linux/arm64"` + DarwinAmd64 string `json:"darwin/amd64"` + DarwinArm64 string `json:"darwin/arm64"` + } `json:"binaries,omitempty"` + } `json:"versions"` + Sdk struct { + Type string `json:"type"` + Version string `json:"version"` + Tag string `json:"tag"` + } `json:"sdk"` + Ibc struct { + Type string `json:"type"` + Version string `json:"version"` + } `json:"ibc"` + Cosmwasm struct { + Version string `json:"version"` + Repo string `json:"repo"` + Tag string `json:"tag"` + } `json:"cosmwasm"` + } `json:"codebase"` + LogoURIs struct { + Png string `json:"png"` + Svg string `json:"svg"` + } `json:"logo_URIs"` + Description string `json:"description"` + Peers struct { + Seeds []struct { + ID string `json:"id"` + Address string `json:"address"` + Provider string `json:"provider"` + } `json:"seeds"` + PersistentPeers []struct { + ID string `json:"id"` + Address string `json:"address"` + Provider string `json:"provider,omitempty"` + } `json:"persistent_peers"` + } `json:"peers"` + Apis struct { + RPC []struct { + Address string `json:"address"` + Provider string `json:"provider"` + } `json:"rpc"` + Rest []struct { + Address string `json:"address"` + Provider string `json:"provider"` + } `json:"rest"` + Grpc []struct { + Address string `json:"address"` + Provider string `json:"provider"` + } `json:"grpc"` + } `json:"apis"` + Explorers []struct { + Kind string `json:"kind"` + URL string `json:"url"` + TxPage string `json:"tx_page,omitempty"` + AccountPage string `json:"account_page,omitempty"` + ValidatorPage string `json:"validator_page,omitempty"` + ProposalPage string `json:"proposal_page,omitempty"` + BlockPage string `json:"block_page,omitempty"` + } `json:"explorers"` + Images []struct { + Png string `json:"png"` + Svg string `json:"svg"` + Theme struct { + PrimaryColorHex string `json:"primary_color_hex"` + } `json:"theme"` + } `json:"images"` +} + +// https://raw.githubusercontent.com/cosmos/chain-registry/master/assetlist.schema.json +// https://github.com/cosmos/chain-registry?tab=readme-ov-file#assetlists +type assetlistJson struct { + Schema string `json:"$schema"` + ChainName string `json:"chain_name"` + Assets []struct { + Description string `json:"description"` + ExtendedDescription string `json:"extended_description,omitempty"` + DenomUnits []struct { + Denom string `json:"denom"` + Exponent int `json:"exponent"` + } `json:"denom_units"` + Base string `json:"base"` + Name string `json:"name"` + Display string `json:"display"` + Symbol string `json:"symbol"` + LogoURIs struct { + Png string `json:"png"` + Svg string `json:"svg"` + } `json:"logo_URIs"` + CoingeckoID string `json:"coingecko_id,omitempty"` + Images []struct { + Png string `json:"png"` + Svg string `json:"svg"` + Theme struct { + PrimaryColorHex string `json:"primary_color_hex"` + } `json:"theme"` + } `json:"images"` + Socials struct { + Website string `json:"website"` + Twitter string `json:"twitter"` + } `json:"socials,omitempty"` + TypeAsset string `json:"type_asset"` + Traces []struct { + Type string `json:"type"` + Counterparty struct { + ChainName string `json:"chain_name"` + BaseDenom string `json:"base_denom"` + ChannelID string `json:"channel_id"` + } `json:"counterparty"` + Chain struct { + ChannelID string `json:"channel_id"` + Path string `json:"path"` + } `json:"chain"` + } `json:"traces,omitempty"` + } `json:"assets"` +} + +// CreateChainRegistryFiles creates a the chain registry files in the scaffolded chains. +func (s Scaffolder) CreateChainRegistryFiles() error { + return nil +} From 585bb8deab7ca89fb3a6fcdb2d80dd4c787c3a99 Mon Sep 17 00:00:00 2001 From: Julien Robert Date: Tue, 26 Nov 2024 13:12:01 +0100 Subject: [PATCH 02/12] cl --- changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/changelog.md b/changelog.md index 13a54de489..42cd367c78 100644 --- a/changelog.md +++ b/changelog.md @@ -22,6 +22,7 @@ - [#4326](https://github.com/ignite/cli/pull/4326) Add `buf.build` version to `ignite version` command - [#4362](https://github.com/ignite/cli/pull/4362) Scaffold `Makefile` - [#4289](https://github.com/ignite/cli/pull/4289) Cosmos SDK v0.52 support +- [#4413](https://github.com/ignite/cli/pull/4413) Add `ignite s chain-registry` command ### Changes From 97b308e8282da2c34e8dd706aa6243375eb2e244 Mon Sep 17 00:00:00 2001 From: Julien Robert Date: Fri, 6 Dec 2024 22:06:29 +0100 Subject: [PATCH 03/12] cl --- changelog.md | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/changelog.md b/changelog.md index e021565439..b62ad708d9 100644 --- a/changelog.md +++ b/changelog.md @@ -19,12 +19,9 @@ - [#4300](https://github.com/ignite/cli/pull/4300) Only panics the module in the most top function level - [#4327](https://github.com/ignite/cli/pull/4327) Use the TxConfig from simState instead create a new one - [#4326](https://github.com/ignite/cli/pull/4326) Add `buf.build` version to `ignite version` command -- [#4362](https://github.com/ignite/cli/pull/4362) Scaffold `Makefile` -- [#4289](https://github.com/ignite/cli/pull/4289) Cosmos SDK v0.52 support -- [#4413](https://github.com/ignite/cli/pull/4413) Add `ignite s chain-registry` command -- [#4289](https://github.com/ignite/cli/pull/4289), [#4423](https://github.com/ignite/cli/pull/4423) Cosmos SDK v0.52 support - [#4436](https://github.com/ignite/cli/pull/4436) Return tx hash to the faucet API - [#4289](https://github.com/ignite/cli/pull/4289), [#4423](https://github.com/ignite/cli/pull/4423), [#4432](https://github.com/ignite/cli/pull/4432) Cosmos SDK v0.52 support +- [#4413](https://github.com/ignite/cli/pull/4413) Add `ignite s chain-registry` command ### Changes From 81d201fa935fdcbb11b8dbd176d03e0ca0c29635 Mon Sep 17 00:00:00 2001 From: Julien Robert Date: Fri, 6 Dec 2024 22:59:04 +0100 Subject: [PATCH 04/12] updates --- ignite/cmd/scaffold_chain_registry.go | 3 +- ignite/services/scaffolder/chain_registry.go | 270 +++++++++---------- 2 files changed, 127 insertions(+), 146 deletions(-) diff --git a/ignite/cmd/scaffold_chain_registry.go b/ignite/cmd/scaffold_chain_registry.go index 0b257fe979..30e5032839 100644 --- a/ignite/cmd/scaffold_chain_registry.go +++ b/ignite/cmd/scaffold_chain_registry.go @@ -55,8 +55,7 @@ func scaffoldChainRegistryFiles(cmd *cobra.Command, args []string) error { return err } - err = sc.CreateChainRegistryFiles() - if err != nil { + if err = sc.CreateChainRegistryFiles(); err != nil { return err } diff --git a/ignite/services/scaffolder/chain_registry.go b/ignite/services/scaffolder/chain_registry.go index 6b218b9c65..a55fb0d796 100644 --- a/ignite/services/scaffolder/chain_registry.go +++ b/ignite/services/scaffolder/chain_registry.go @@ -1,21 +1,75 @@ package scaffolder +import ( + "encoding/json" + "os" +) + +const ( + // DefaultChainType is the default chain type for the chain.json + // More value are allowed by the chain registry schema, but Ignite only scaffold Cosmos chains. + DefaultChainType = "cosmos" +) + +// Status enumerates possible status for the chain.json +type Status uint8 + +const ( + StatusLive = iota + StatusUpcoming + StatusKilled +) + +func (s Status) String() string { + switch s { + case StatusLive: + return "live" + case StatusUpcoming: + return "upcoming" + case StatusKilled: + return "killed" + default: + return "unknown" + } +} + +// NetworkType enumerates possible network types for the chain.json +type NetworkType uint8 + +const ( + NetworkMainnet = iota + NetworkTestnet + NetworkDevnet +) + +func (n NetworkType) String() string { + switch n { + case NetworkMainnet: + return "mainnet" + case NetworkTestnet: + return "testnet" + case NetworkDevnet: + return "devnet" + default: + return "unknown" + } +} + // https://raw.githubusercontent.com/cosmos/chain-registry/master/chain.schema.json // https://github.com/cosmos/chain-registry?tab=readme-ov-file#sample type chainJSON struct { - Schema string `json:"$schema"` - ChainName string `json:"chain_name"` - ChainType string `json:"chain_type"` - ChainID string `json:"chain_id"` - Website string `json:"website"` - PrettyName string `json:"pretty_name"` - Status string `json:"status"` - NetworkType string `json:"network_type"` - Bech32Prefix string `json:"bech32_prefix"` - DaemonName string `json:"daemon_name"` - NodeHome string `json:"node_home"` - KeyAlgos []string `json:"key_algos"` - Slip44 int `json:"slip44"` + ChainName string `json:"chain_name"` + Status Status `json:"status"` + NetworkType NetworkType `json:"network_type"` + Website string `json:"website"` + PrettyName string `json:"pretty_name"` + ChainType string `json:"chain_type"` + ChainID string `json:"chain_id"` + Bech32Prefix string `json:"bech32_prefix"` + DaemonName string `json:"daemon_name"` + NodeHome string `json:"node_home"` + KeyAlgos []string `json:"key_algos"` + Slip44 int `json:"slip44"` Fees struct { FeeTokens []struct { Denom string `json:"denom"` @@ -29,143 +83,61 @@ type chainJSON struct { StakingTokens []struct { Denom string `json:"denom"` } `json:"staking_tokens"` + LockDuration struct { + Time string `json:"time"` + } `json:"lock_duration"` } `json:"staking"` Codebase struct { - GitRepo string `json:"git_repo"` + GitRepo string `json:"git_repo"` + Genesis struct { + Name string `json:"name"` + GenesisURL string `json:"genesis_url"` + } `json:"genesis"` RecommendedVersion string `json:"recommended_version"` CompatibleVersions []string `json:"compatible_versions"` Consensus struct { Type string `json:"type"` Version string `json:"version"` + Repo string `json:"repo"` + Tag string `json:"tag"` } `json:"consensus"` Binaries struct { - LinuxAmd64 string `json:"linux/amd64"` - LinuxArm64 string `json:"linux/arm64"` - DarwinAmd64 string `json:"darwin/amd64"` - DarwinArm64 string `json:"darwin/arm64"` + LinuxAmd64 string `json:"linux/amd64"` + LinuxArm64 string `json:"linux/arm64"` } `json:"binaries"` - Genesis struct { - GenesisURL string `json:"genesis_url"` - } `json:"genesis"` - Versions []struct { - Name string `json:"name"` - Tag string `json:"tag"` - RecommendedVersion string `json:"recommended_version"` - CompatibleVersions []string `json:"compatible_versions"` - Consensus struct { - Type string `json:"type"` - Version string `json:"version"` - } `json:"consensus"` - Height int `json:"height"` - Binaries struct { - LinuxAmd64 string `json:"linux/amd64"` - LinuxArm64 string `json:"linux/arm64"` - DarwinAmd64 string `json:"darwin/amd64"` - DarwinArm64 string `json:"darwin/arm64"` - WindowsAmd64 string `json:"windows/amd64"` - } `json:"binaries,omitempty"` - NextVersionName string `json:"next_version_name"` - Sdk struct { - Type string `json:"type"` - Version string `json:"version"` - Tag string `json:"tag"` - } `json:"sdk"` - Ibc struct { - Type string `json:"type"` - Version string `json:"version"` - } `json:"ibc"` - Proposal int `json:"proposal,omitempty"` - Binaries0 struct { - LinuxAmd64 string `json:"linux/amd64"` - LinuxArm64 string `json:"linux/arm64"` - DarwinAmd64 string `json:"darwin/amd64"` - DarwinArm64 string `json:"darwin/arm64"` - WindowsAmd64 string `json:"windows/amd64"` - WindowsArm64 string `json:"windows/arm64"` - } `json:"binaries,omitempty"` - Binaries1 struct { - LinuxAmd64 string `json:"linux/amd64"` - LinuxArm64 string `json:"linux/arm64"` - DarwinAmd64 string `json:"darwin/amd64"` - DarwinArm64 string `json:"darwin/arm64"` - WindowsAmd64 string `json:"windows/amd64"` - WindowsArm64 string `json:"windows/arm64"` - } `json:"binaries,omitempty"` - Binaries2 struct { - LinuxAmd64 string `json:"linux/amd64"` - LinuxArm64 string `json:"linux/arm64"` - DarwinAmd64 string `json:"darwin/amd64"` - DarwinArm64 string `json:"darwin/arm64"` - WindowsAmd64 string `json:"windows/amd64"` - WindowsArm64 string `json:"windows/arm64"` - } `json:"binaries,omitempty"` - Binaries3 struct { - LinuxAmd64 string `json:"linux/amd64"` - LinuxArm64 string `json:"linux/arm64"` - DarwinAmd64 string `json:"darwin/amd64"` - DarwinArm64 string `json:"darwin/arm64"` - WindowsAmd64 string `json:"windows/amd64"` - WindowsArm64 string `json:"windows/arm64"` - } `json:"binaries,omitempty"` - Binaries4 struct { - LinuxAmd64 string `json:"linux/amd64"` - LinuxArm64 string `json:"linux/arm64"` - DarwinAmd64 string `json:"darwin/amd64"` - DarwinArm64 string `json:"darwin/arm64"` - WindowsAmd64 string `json:"windows/amd64"` - WindowsArm64 string `json:"windows/arm64"` - } `json:"binaries,omitempty"` - Binaries5 struct { - LinuxAmd64 string `json:"linux/amd64"` - LinuxArm64 string `json:"linux/arm64"` - DarwinAmd64 string `json:"darwin/amd64"` - DarwinArm64 string `json:"darwin/arm64"` - WindowsAmd64 string `json:"windows/amd64"` - WindowsArm64 string `json:"windows/arm64"` - } `json:"binaries,omitempty"` - Binaries6 struct { - LinuxAmd64 string `json:"linux/amd64"` - LinuxArm64 string `json:"linux/arm64"` - DarwinAmd64 string `json:"darwin/amd64"` - DarwinArm64 string `json:"darwin/arm64"` - WindowsAmd64 string `json:"windows/amd64"` - WindowsArm64 string `json:"windows/arm64"` - } `json:"binaries,omitempty"` - Binaries7 struct { - LinuxAmd64 string `json:"linux/amd64"` - LinuxArm64 string `json:"linux/arm64"` - DarwinAmd64 string `json:"darwin/amd64"` - DarwinArm64 string `json:"darwin/arm64"` - WindowsAmd64 string `json:"windows/amd64"` - WindowsArm64 string `json:"windows/arm64"` - } `json:"binaries,omitempty"` - Cosmwasm struct { - Version string `json:"version"` - Repo string `json:"repo"` - Tag string `json:"tag"` - } `json:"cosmwasm,omitempty"` - Binaries8 struct { - LinuxAmd64 string `json:"linux/amd64"` - LinuxArm64 string `json:"linux/arm64"` - DarwinAmd64 string `json:"darwin/amd64"` - DarwinArm64 string `json:"darwin/arm64"` - } `json:"binaries,omitempty"` - } `json:"versions"` + Language struct { + Type string `json:"type"` + Version string `json:"version"` + } `json:"language"` Sdk struct { Type string `json:"type"` + Repo string `json:"repo"` Version string `json:"version"` Tag string `json:"tag"` } `json:"sdk"` Ibc struct { - Type string `json:"type"` - Version string `json:"version"` + Type string `json:"type"` + Version string `json:"version"` + IcsEnabled []string `json:"ics_enabled"` } `json:"ibc"` Cosmwasm struct { Version string `json:"version"` Repo string `json:"repo"` Tag string `json:"tag"` + Enabled bool `json:"enabled"` } `json:"cosmwasm"` } `json:"codebase"` + Images []struct { + ImageSync struct { + ChainName string `json:"chain_name"` + BaseDenom string `json:"base_denom"` + } `json:"image_sync"` + Svg string `json:"svg"` + Png string `json:"png"` + Theme struct { + PrimaryColorHex string `json:"primary_color_hex"` + } `json:"theme"` + } `json:"images"` LogoURIs struct { Png string `json:"png"` Svg string `json:"svg"` @@ -180,7 +152,7 @@ type chainJSON struct { PersistentPeers []struct { ID string `json:"id"` Address string `json:"address"` - Provider string `json:"provider,omitempty"` + Provider string `json:"provider"` } `json:"persistent_peers"` } `json:"peers"` Apis struct { @@ -198,27 +170,27 @@ type chainJSON struct { } `json:"grpc"` } `json:"apis"` Explorers []struct { - Kind string `json:"kind"` - URL string `json:"url"` - TxPage string `json:"tx_page,omitempty"` - AccountPage string `json:"account_page,omitempty"` - ValidatorPage string `json:"validator_page,omitempty"` - ProposalPage string `json:"proposal_page,omitempty"` - BlockPage string `json:"block_page,omitempty"` + Kind string `json:"kind"` + URL string `json:"url"` + TxPage string `json:"tx_page,omitempty"` + AccountPage string `json:"account_page,omitempty"` } `json:"explorers"` - Images []struct { - Png string `json:"png"` - Svg string `json:"svg"` - Theme struct { - PrimaryColorHex string `json:"primary_color_hex"` - } `json:"theme"` - } `json:"images"` + Keywords []string `json:"keywords"` +} + +// SaveJSON saves the chainJSON to the given out directory. +func (c chainJSON) SaveJSON(out string) error { + bz, err := json.MarshalIndent(c, "", " ") + if err != nil { + return err + } + + return os.WriteFile(out, bz, 0666) } // https://raw.githubusercontent.com/cosmos/chain-registry/master/assetlist.schema.json // https://github.com/cosmos/chain-registry?tab=readme-ov-file#assetlists -type assetlistJson struct { - Schema string `json:"$schema"` +type assetListJSON struct { ChainName string `json:"chain_name"` Assets []struct { Description string `json:"description"` @@ -263,6 +235,16 @@ type assetlistJson struct { } `json:"assets"` } +// SaveJSON saves the assetList to the given out directory. +func (c assetListJSON) SaveJSON(out string) error { + bz, err := json.MarshalIndent(c, "", " ") + if err != nil { + return err + } + + return os.WriteFile(out, bz, 0666) +} + // CreateChainRegistryFiles creates a the chain registry files in the scaffolded chains. func (s Scaffolder) CreateChainRegistryFiles() error { return nil From ea034aec915dd30f9f91254875bc5feabebe8e96 Mon Sep 17 00:00:00 2001 From: Julien Robert Date: Wed, 18 Dec 2024 00:24:49 +0100 Subject: [PATCH 05/12] updates --- ignite/cmd/scaffold_chain_registry.go | 2 +- ignite/config/chain/base/config.go | 8 ++++++ ignite/services/scaffolder/chain_registry.go | 30 ++++++++++++++++++-- 3 files changed, 37 insertions(+), 3 deletions(-) diff --git a/ignite/cmd/scaffold_chain_registry.go b/ignite/cmd/scaffold_chain_registry.go index 30e5032839..70d8d5d626 100644 --- a/ignite/cmd/scaffold_chain_registry.go +++ b/ignite/cmd/scaffold_chain_registry.go @@ -55,7 +55,7 @@ func scaffoldChainRegistryFiles(cmd *cobra.Command, args []string) error { return err } - if err = sc.CreateChainRegistryFiles(); err != nil { + if err = sc.AddChainInfo(cfg); err != nil { return err } diff --git a/ignite/config/chain/base/config.go b/ignite/config/chain/base/config.go index a9e6340e63..6fb2eca360 100644 --- a/ignite/config/chain/base/config.go +++ b/ignite/config/chain/base/config.go @@ -8,6 +8,13 @@ import ( "github.com/ignite/cli/v29/ignite/pkg/xyaml" ) +type ChainInfo struct { + Name string `yaml:"chain_name" doc:"Contains the name of the chain."` + PrettyName string `yaml:"pretty_name" docs:"Contains the pretty name of the chain."` + Website string `yaml:"website" doc:"Contains the website of the chain."` + ChainID string `yaml:"chain_id" docs:"Contains the chain ID."` +} + // Account holds the options related to setting up Cosmos wallets. type Account struct { Name string `yaml:"name" doc:"Local name associated with the Account's key pair."` @@ -133,6 +140,7 @@ const ( // Config defines a struct with the fields that are common to all config versions. type Config struct { + Chain ChainInfo `yaml:"chain_info" doc:"Defines the chain information."` Validation Validation `yaml:"validation,omitempty" doc:"Specifies the type of validation the blockchain uses (e.g., sovereign)."` Version version.Version `yaml:"version" doc:"Defines the configuration version number."` Build Build `yaml:"build,omitempty" doc:"Contains build configuration options."` diff --git a/ignite/services/scaffolder/chain_registry.go b/ignite/services/scaffolder/chain_registry.go index a55fb0d796..84d0861b02 100644 --- a/ignite/services/scaffolder/chain_registry.go +++ b/ignite/services/scaffolder/chain_registry.go @@ -3,6 +3,8 @@ package scaffolder import ( "encoding/json" "os" + + chainconfig "github.com/ignite/cli/v29/ignite/config/chain" ) const ( @@ -245,7 +247,31 @@ func (c assetListJSON) SaveJSON(out string) error { return os.WriteFile(out, bz, 0666) } -// CreateChainRegistryFiles creates a the chain registry files in the scaffolded chains. -func (s Scaffolder) CreateChainRegistryFiles() error { +// AddChainInfo generates the chain registry files in the scaffolded chains. +func (s Scaffolder) AddChainInfo(cfg *chainconfig.Config) error { + chain := chainJSON{ + ChainName: cfg.Chain.Name, + Status: StatusUpcoming, + NetworkType: NetworkDevnet, + Website: cfg.Chain.Name, + PrettyName: cfg.Chain.PrettyName, + ChainType: DefaultChainType, + ChainID: "", // get from genesis + // ...populate other fields based on cfg... + } + + assetList := assetListJSON{ + ChainName: chain.ChainName, + Assets: nil, + } + + if err := chain.SaveJSON("chain.json"); err != nil { + return err + } + + if err := assetList.SaveJSON("assets.json"); err != nil { + return err + } + return nil } From 7d795ed32a0fcd713ebd6ef06b8c419d7f1fa570 Mon Sep 17 00:00:00 2001 From: Julien Robert Date: Tue, 7 Jan 2025 10:13:36 +0100 Subject: [PATCH 06/12] typo --- ignite/cmd/scaffold_chain_registry.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ignite/cmd/scaffold_chain_registry.go b/ignite/cmd/scaffold_chain_registry.go index 70d8d5d626..25357f71d4 100644 --- a/ignite/cmd/scaffold_chain_registry.go +++ b/ignite/cmd/scaffold_chain_registry.go @@ -74,7 +74,7 @@ func scaffoldChainRegistryFiles(cmd *cobra.Command, args []string) error { } session.Println(modificationsStr) - session.Printf("\nšŸŽ‰ Chain Registry files (assets.json and chain.json) succesfully scaffolded.\n") + session.Printf("\nšŸŽ‰ Chain Registry files (assets.json and chain.json) successfully scaffolded.\n") return nil } From 79eb59c416d3eb96d168c82784dd5c2956b6f289 Mon Sep 17 00:00:00 2001 From: Julien Robert Date: Wed, 8 Jan 2025 14:20:24 +0100 Subject: [PATCH 07/12] renaming --- ignite/cmd/scaffold_chain_registry.go | 2 +- ignite/services/scaffolder/chain_registry.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ignite/cmd/scaffold_chain_registry.go b/ignite/cmd/scaffold_chain_registry.go index 25357f71d4..2ac13e6c87 100644 --- a/ignite/cmd/scaffold_chain_registry.go +++ b/ignite/cmd/scaffold_chain_registry.go @@ -55,7 +55,7 @@ func scaffoldChainRegistryFiles(cmd *cobra.Command, args []string) error { return err } - if err = sc.AddChainInfo(cfg); err != nil { + if err = sc.AddChainRegistryFiles(cfg); err != nil { return err } diff --git a/ignite/services/scaffolder/chain_registry.go b/ignite/services/scaffolder/chain_registry.go index 84d0861b02..5e4ec2bb2e 100644 --- a/ignite/services/scaffolder/chain_registry.go +++ b/ignite/services/scaffolder/chain_registry.go @@ -247,8 +247,8 @@ func (c assetListJSON) SaveJSON(out string) error { return os.WriteFile(out, bz, 0666) } -// AddChainInfo generates the chain registry files in the scaffolded chains. -func (s Scaffolder) AddChainInfo(cfg *chainconfig.Config) error { +// AddChainRegistryFiles generates the chain registry files in the scaffolded chains. +func (s Scaffolder) AddChainRegistryFiles(cfg *chainconfig.Config) error { chain := chainJSON{ ChainName: cfg.Chain.Name, Status: StatusUpcoming, From edb7360acbfe404d59b33d06a0d911ff626d6b1c Mon Sep 17 00:00:00 2001 From: Julien Robert Date: Wed, 8 Jan 2025 23:01:59 +0100 Subject: [PATCH 08/12] finalize chain-registry --- ignite/cmd/scaffold_chain_registry.go | 28 +- ignite/config/chain/base/config.go | 8 - ignite/pkg/xgit/xgit.go | 20 + ignite/services/scaffolder/chain_registry.go | 392 ++++++++++-------- .../cmd_chain_registry_test.go | 38 ++ 5 files changed, 286 insertions(+), 200 deletions(-) create mode 100644 integration/other_components/cmd_chain_registry_test.go diff --git a/ignite/cmd/scaffold_chain_registry.go b/ignite/cmd/scaffold_chain_registry.go index 2ac13e6c87..e2df4c898e 100644 --- a/ignite/cmd/scaffold_chain_registry.go +++ b/ignite/cmd/scaffold_chain_registry.go @@ -4,6 +4,7 @@ import ( "github.com/spf13/cobra" "github.com/ignite/cli/v29/ignite/pkg/cliui" + "github.com/ignite/cli/v29/ignite/services/chain" "github.com/ignite/cli/v29/ignite/services/scaffolder" ) @@ -21,7 +22,7 @@ publish the chain's metadata in the chain registry. Read more about the chain.json at https://github.com/cosmos/chain-registry?tab=readme-ov-file#chainjson Read more about the assets.json at https://github.com/cosmos/chain-registry?tab=readme-ov-file#assetlists`, - Args: cobra.MinimumNArgs(1), + Args: cobra.NoArgs, PreRunE: migrationPreRunHandler, RunE: scaffoldChainRegistryFiles, } @@ -35,8 +36,6 @@ Read more about the assets.json at https://github.com/cosmos/chain-registry?tab= } func scaffoldChainRegistryFiles(cmd *cobra.Command, args []string) error { - var appPath = flagGetPath(cmd) - session := cliui.New(cliui.StartSpinnerWithText(statusScaffolding)) defer session.End() @@ -45,36 +44,25 @@ func scaffoldChainRegistryFiles(cmd *cobra.Command, args []string) error { return err } - cacheStorage, err := newCache(cmd) + c, err := chain.NewWithHomeFlags(cmd) if err != nil { return err } + var appPath = flagGetPath(cmd) sc, err := scaffolder.New(cmd.Context(), appPath, cfg.Build.Proto.Path) if err != nil { return err } - if err = sc.AddChainRegistryFiles(cfg); err != nil { - return err - } - - sm, err := sc.ApplyModifications() - if err != nil { + if err = sc.AddChainRegistryFiles(c, cfg); err != nil { return err } - if err := sc.PostScaffold(cmd.Context(), cacheStorage, false); err != nil { - return err - } - - modificationsStr, err := sm.String() - if err != nil { - return err - } + // no need for post scaffolding, as we are just creating two files + // that are not part of the build process - session.Println(modificationsStr) - session.Printf("\nšŸŽ‰ Chain Registry files (assets.json and chain.json) successfully scaffolded.\n") + session.Printf("šŸŽ‰ chain-registry files successfully scaffolded\n") return nil } diff --git a/ignite/config/chain/base/config.go b/ignite/config/chain/base/config.go index 6fb2eca360..a9e6340e63 100644 --- a/ignite/config/chain/base/config.go +++ b/ignite/config/chain/base/config.go @@ -8,13 +8,6 @@ import ( "github.com/ignite/cli/v29/ignite/pkg/xyaml" ) -type ChainInfo struct { - Name string `yaml:"chain_name" doc:"Contains the name of the chain."` - PrettyName string `yaml:"pretty_name" docs:"Contains the pretty name of the chain."` - Website string `yaml:"website" doc:"Contains the website of the chain."` - ChainID string `yaml:"chain_id" docs:"Contains the chain ID."` -} - // Account holds the options related to setting up Cosmos wallets. type Account struct { Name string `yaml:"name" doc:"Local name associated with the Account's key pair."` @@ -140,7 +133,6 @@ const ( // Config defines a struct with the fields that are common to all config versions. type Config struct { - Chain ChainInfo `yaml:"chain_info" doc:"Defines the chain information."` Validation Validation `yaml:"validation,omitempty" doc:"Specifies the type of validation the blockchain uses (e.g., sovereign)."` Version version.Version `yaml:"version" doc:"Defines the configuration version number."` Build Build `yaml:"build,omitempty" doc:"Contains build configuration options."` diff --git a/ignite/pkg/xgit/xgit.go b/ignite/pkg/xgit/xgit.go index 54500b613f..c72be5e27f 100644 --- a/ignite/pkg/xgit/xgit.go +++ b/ignite/pkg/xgit/xgit.go @@ -159,3 +159,23 @@ func IsRepository(path string) (bool, error) { } return true, nil } + +// RespositoryURL returns the URL of the origin remote of a Git repository. +func RespositoryURL(path string) (string, error) { + repo, err := git.PlainOpenWithOptions(path, &defaultOpenOpts) + if err != nil { + return "", err + } + + cfg, err := repo.Config() + if err != nil { + return "", err + } + + origin, ok := cfg.Remotes["origin"] + if !ok { + return "", errors.Errorf("no origin remote found in %s", path) + } + + return origin.URLs[0], nil +} diff --git a/ignite/services/scaffolder/chain_registry.go b/ignite/services/scaffolder/chain_registry.go index 5e4ec2bb2e..d7b3374ddc 100644 --- a/ignite/services/scaffolder/chain_registry.go +++ b/ignite/services/scaffolder/chain_registry.go @@ -1,183 +1,112 @@ package scaffolder import ( + "bufio" "encoding/json" "os" + "path/filepath" + "strings" chainconfig "github.com/ignite/cli/v29/ignite/config/chain" + "github.com/ignite/cli/v29/ignite/pkg/errors" + "github.com/ignite/cli/v29/ignite/pkg/xgit" + "github.com/ignite/cli/v29/ignite/services/chain" + + sdk "github.com/cosmos/cosmos-sdk/types" ) const ( // DefaultChainType is the default chain type for the chain.json - // More value are allowed by the chain registry schema, but Ignite only scaffold Cosmos chains. + // More value are allowed by the chain registry schema, but Ignite only scaffolds Cosmos chains. DefaultChainType = "cosmos" -) -// Status enumerates possible status for the chain.json -type Status uint8 + // DefaultChainStatus is the default chain status for the chain.json + // More value are allowed by the chain registry schema, but Ignite only scaffolds upcoming chains. + DefaultChainStatus = "upcoming" -const ( - StatusLive = iota - StatusUpcoming - StatusKilled + // DefaultNetworkType is the default network type for the chain.json + // More value are allowed by the chain registry schema, but Ignite only scaffolds devnet chains. + DefaultNetworkType = "devnet" + + chainFilename = "chain.json" + assetListFilename = "assetlist.json" ) -func (s Status) String() string { - switch s { - case StatusLive: - return "live" - case StatusUpcoming: - return "upcoming" - case StatusKilled: - return "killed" - default: - return "unknown" - } +// https://raw.githubusercontent.com/cosmos/chain-registry/master/chain.schema.json +type chainJSON struct { + ChainName string `json:"chain_name"` + Status string `json:"status"` + NetworkType string `json:"network_type"` + Website string `json:"website"` + PrettyName string `json:"pretty_name"` + ChainType string `json:"chain_type"` + ChainID string `json:"chain_id"` + Bech32Prefix string `json:"bech32_prefix"` + DaemonName string `json:"daemon_name"` + NodeHome string `json:"node_home"` + KeyAlgos []string `json:"key_algos"` + Slip44 int `json:"slip44"` + Fees struct { + FeeTokens []FeeToken `json:"fee_tokens"` + } `json:"fees"` + Staking Staking `json:"staking"` + Codebase Codebase `json:"codebase"` + Description string `json:"description"` } -// NetworkType enumerates possible network types for the chain.json -type NetworkType uint8 +type Staking struct { + StakingTokens []StakingToken `json:"staking_tokens"` +} -const ( - NetworkMainnet = iota - NetworkTestnet - NetworkDevnet -) +type StakingToken struct { + Denom string `json:"denom"` +} -func (n NetworkType) String() string { - switch n { - case NetworkMainnet: - return "mainnet" - case NetworkTestnet: - return "testnet" - case NetworkDevnet: - return "devnet" - default: - return "unknown" - } +type Codebase struct { + GitRepo string `json:"git_repo"` + Genesis CodebaseGenesis `json:"genesis"` + RecommendedVersion string `json:"recommended_version"` + CompatibleVersions []string `json:"compatible_versions"` + Consensus CodebaseConsensus `json:"consensus"` + Sdk CodebaseSDK `json:"sdk"` + Ibc CodebaseIBC `json:"ibc,omitempty"` + Cosmwasm CodebaseCosmwam `json:"cosmwasm,omitempty"` } -// https://raw.githubusercontent.com/cosmos/chain-registry/master/chain.schema.json -// https://github.com/cosmos/chain-registry?tab=readme-ov-file#sample -type chainJSON struct { - ChainName string `json:"chain_name"` - Status Status `json:"status"` - NetworkType NetworkType `json:"network_type"` - Website string `json:"website"` - PrettyName string `json:"pretty_name"` - ChainType string `json:"chain_type"` - ChainID string `json:"chain_id"` - Bech32Prefix string `json:"bech32_prefix"` - DaemonName string `json:"daemon_name"` - NodeHome string `json:"node_home"` - KeyAlgos []string `json:"key_algos"` - Slip44 int `json:"slip44"` - Fees struct { - FeeTokens []struct { - Denom string `json:"denom"` - FixedMinGasPrice float64 `json:"fixed_min_gas_price"` - LowGasPrice float64 `json:"low_gas_price"` - AverageGasPrice float64 `json:"average_gas_price"` - HighGasPrice float64 `json:"high_gas_price"` - } `json:"fee_tokens"` - } `json:"fees"` - Staking struct { - StakingTokens []struct { - Denom string `json:"denom"` - } `json:"staking_tokens"` - LockDuration struct { - Time string `json:"time"` - } `json:"lock_duration"` - } `json:"staking"` - Codebase struct { - GitRepo string `json:"git_repo"` - Genesis struct { - Name string `json:"name"` - GenesisURL string `json:"genesis_url"` - } `json:"genesis"` - RecommendedVersion string `json:"recommended_version"` - CompatibleVersions []string `json:"compatible_versions"` - Consensus struct { - Type string `json:"type"` - Version string `json:"version"` - Repo string `json:"repo"` - Tag string `json:"tag"` - } `json:"consensus"` - Binaries struct { - LinuxAmd64 string `json:"linux/amd64"` - LinuxArm64 string `json:"linux/arm64"` - } `json:"binaries"` - Language struct { - Type string `json:"type"` - Version string `json:"version"` - } `json:"language"` - Sdk struct { - Type string `json:"type"` - Repo string `json:"repo"` - Version string `json:"version"` - Tag string `json:"tag"` - } `json:"sdk"` - Ibc struct { - Type string `json:"type"` - Version string `json:"version"` - IcsEnabled []string `json:"ics_enabled"` - } `json:"ibc"` - Cosmwasm struct { - Version string `json:"version"` - Repo string `json:"repo"` - Tag string `json:"tag"` - Enabled bool `json:"enabled"` - } `json:"cosmwasm"` - } `json:"codebase"` - Images []struct { - ImageSync struct { - ChainName string `json:"chain_name"` - BaseDenom string `json:"base_denom"` - } `json:"image_sync"` - Svg string `json:"svg"` - Png string `json:"png"` - Theme struct { - PrimaryColorHex string `json:"primary_color_hex"` - } `json:"theme"` - } `json:"images"` - LogoURIs struct { - Png string `json:"png"` - Svg string `json:"svg"` - } `json:"logo_URIs"` - Description string `json:"description"` - Peers struct { - Seeds []struct { - ID string `json:"id"` - Address string `json:"address"` - Provider string `json:"provider"` - } `json:"seeds"` - PersistentPeers []struct { - ID string `json:"id"` - Address string `json:"address"` - Provider string `json:"provider"` - } `json:"persistent_peers"` - } `json:"peers"` - Apis struct { - RPC []struct { - Address string `json:"address"` - Provider string `json:"provider"` - } `json:"rpc"` - Rest []struct { - Address string `json:"address"` - Provider string `json:"provider"` - } `json:"rest"` - Grpc []struct { - Address string `json:"address"` - Provider string `json:"provider"` - } `json:"grpc"` - } `json:"apis"` - Explorers []struct { - Kind string `json:"kind"` - URL string `json:"url"` - TxPage string `json:"tx_page,omitempty"` - AccountPage string `json:"account_page,omitempty"` - } `json:"explorers"` - Keywords []string `json:"keywords"` +type CodebaseGenesis struct { + GenesisURL string `json:"genesis_url"` +} + +type CodebaseConsensus struct { + Type string `json:"type"` + Version string `json:"version"` +} + +type CodebaseSDK struct { + Type string `json:"type"` + Version string `json:"version"` +} + +type CodebaseIBC struct { + Type string `json:"type"` + Version string `json:"version"` +} + +type CodebaseCosmwam struct { + Version string `json:"version,omitempty"` + Enabled bool `json:"enabled"` +} + +type Fees struct { + FeeTokens []FeeToken `json:"fee_tokens"` +} + +type FeeToken struct { + Denom string `json:"denom"` + FixedMinGasPrice float64 `json:"fixed_min_gas_price"` + LowGasPrice float64 `json:"low_gas_price"` + AverageGasPrice float64 `json:"average_gas_price"` + HighGasPrice float64 `json:"high_gas_price"` } // SaveJSON saves the chainJSON to the given out directory. @@ -248,30 +177,149 @@ func (c assetListJSON) SaveJSON(out string) error { } // AddChainRegistryFiles generates the chain registry files in the scaffolded chains. -func (s Scaffolder) AddChainRegistryFiles(cfg *chainconfig.Config) error { - chain := chainJSON{ - ChainName: cfg.Chain.Name, - Status: StatusUpcoming, - NetworkType: NetworkDevnet, - Website: cfg.Chain.Name, - PrettyName: cfg.Chain.PrettyName, - ChainType: DefaultChainType, - ChainID: "", // get from genesis - // ...populate other fields based on cfg... +func (s Scaffolder) AddChainRegistryFiles(chain *chain.Chain, cfg *chainconfig.Config) error { + binaryName, err := chain.Binary() + if err != nil { + return errors.Wrap(err, "failed to get binary name") + } + + chainHome, err := chain.DefaultHome() + if err != nil { + return errors.Wrap(err, "failed to get default home directory") + } + + chainID, err := chain.ID() + if err != nil { + return errors.Wrap(err, "failed to get chain ID") + } + + chainGitURL, _ /* do not fail on non-existing git repo */ := xgit.RespositoryURL(chain.AppPath()) + + var ( + consensus CodebaseConsensus + cosmwasm CodebaseCosmwam + ibc CodebaseIBC + ) + + consensusVersion, err := getVersionOfFromGoMod(chain, "github.com/cometbft/cometbft") + if err == nil { + consensus = CodebaseConsensus{ + Type: "cometbft", + Version: consensusVersion, + } + } + + cosmwasmVersion, err := getVersionOfFromGoMod(chain, "github.com/CosmWasm/wasmd") + if err == nil { + cosmwasm = CodebaseCosmwam{ + Version: cosmwasmVersion, + Enabled: true, + } + } + + ibcVersion, err := getVersionOfFromGoMod(chain, "github.com/cosmos/ibc-go") + if err == nil { + ibc = CodebaseIBC{ + Type: "go", + Version: ibcVersion, + } } - assetList := assetListJSON{ - ChainName: chain.ChainName, + // get validators from config and parse their coins + // we can assume it holds the base denom + defaultDenom := "stake" + if len(cfg.Validators) > 0 { + coin, err := sdk.ParseCoinNormalized(cfg.Validators[0].Bonded) + if err == nil { + defaultDenom = coin.Denom + } + } + + chainJson := chainJSON{ + ChainName: chain.Name(), + PrettyName: chain.Name(), + ChainType: DefaultChainType, + Status: DefaultChainStatus, + NetworkType: DefaultNetworkType, + Website: "https://example.com", + ChainID: chainID, + Bech32Prefix: "", + DaemonName: binaryName, + NodeHome: chainHome, + KeyAlgos: []string{"secp256k1"}, + Slip44: 118, + Fees: Fees{ + FeeTokens: []FeeToken{ + { + Denom: defaultDenom, + FixedMinGasPrice: 0.025, + LowGasPrice: 0.01, + AverageGasPrice: 0.025, + HighGasPrice: 0.03, + }, + }, + }, + Staking: Staking{ + StakingTokens: []StakingToken{ + { + Denom: defaultDenom, + }, + }, + }, + Codebase: Codebase{ + GitRepo: chainGitURL, + RecommendedVersion: "v1.0.0", + CompatibleVersions: []string{"v1.0.0"}, + Sdk: CodebaseSDK{ + Type: "cosmos", + Version: chain.Version.String(), + }, + Consensus: consensus, + Ibc: ibc, + Cosmwasm: cosmwasm, + }, + } + + assetListJson := assetListJSON{ + ChainName: chainJson.ChainName, Assets: nil, } - if err := chain.SaveJSON("chain.json"); err != nil { + if err := chainJson.SaveJSON(chainFilename); err != nil { return err } - if err := assetList.SaveJSON("assets.json"); err != nil { + if err := assetListJson.SaveJSON(assetListFilename); err != nil { return err } return nil } + +func getVersionOfFromGoMod(chain *chain.Chain, pkg string) (string, error) { + chainPath := chain.AppPath() + + // get the version from the go.mod file + file, err := os.Open(filepath.Join(chainPath, "go.mod")) + if err != nil { + return "", err + } + defer file.Close() + + scanner := bufio.NewScanner(file) + for scanner.Scan() { + line := scanner.Text() + if strings.Contains(line, pkg) { + parts := strings.Fields(line) + if len(parts) > 1 { + return parts[len(parts)-1], nil + } + } + } + + if err := scanner.Err(); err != nil { + return "", err + } + + return "", errors.New("consensus version not found in go.mod") +} diff --git a/integration/other_components/cmd_chain_registry_test.go b/integration/other_components/cmd_chain_registry_test.go new file mode 100644 index 0000000000..0d7ae667a2 --- /dev/null +++ b/integration/other_components/cmd_chain_registry_test.go @@ -0,0 +1,38 @@ +//go:build !relayer + +package other_components_test + +import ( + "os" + "path/filepath" + "testing" + + "github.com/ignite/cli/v29/ignite/pkg/cmdrunner/step" + envtest "github.com/ignite/cli/v29/integration" + "github.com/stretchr/testify/require" +) + +func TestCreateChainRegistry(t *testing.T) { + var ( + env = envtest.New(t) + app = env.Scaffold("github.com/test/mars") + ) + + env.Must(env.Exec("create chain-registry files", + step.NewSteps(step.New( + step.Exec(envtest.IgniteApp, + "s", + "chain-registry", + ), + step.Workdir(app.SourcePath()), + )), + )) + + _, statErr := os.Stat(filepath.Join(app.SourcePath(), "chain.json")) + require.False(t, os.IsNotExist(statErr), "chain.json cannot be found") + + _, statErr = os.Stat(filepath.Join(app.SourcePath(), "assetlist.json")) + require.False(t, os.IsNotExist(statErr), "assetlist.json cannot be found") + + app.EnsureSteady() +} From 667734ccd6ee5d118b0c82d804523e09243af59f Mon Sep 17 00:00:00 2001 From: Julien Robert Date: Wed, 8 Jan 2025 23:11:10 +0100 Subject: [PATCH 09/12] updates --- ignite/services/scaffolder/chain_registry.go | 151 ++++++++++--------- 1 file changed, 76 insertions(+), 75 deletions(-) diff --git a/ignite/services/scaffolder/chain_registry.go b/ignite/services/scaffolder/chain_registry.go index d7b3374ddc..adbb0bcea5 100644 --- a/ignite/services/scaffolder/chain_registry.go +++ b/ignite/services/scaffolder/chain_registry.go @@ -3,6 +3,7 @@ package scaffolder import ( "bufio" "encoding/json" + "fmt" "os" "path/filepath" "strings" @@ -47,61 +48,61 @@ type chainJSON struct { KeyAlgos []string `json:"key_algos"` Slip44 int `json:"slip44"` Fees struct { - FeeTokens []FeeToken `json:"fee_tokens"` + FeeTokens []feeToken `json:"fee_tokens"` } `json:"fees"` - Staking Staking `json:"staking"` - Codebase Codebase `json:"codebase"` + Staking staking `json:"staking"` + Codebase codebase `json:"codebase"` Description string `json:"description"` } -type Staking struct { - StakingTokens []StakingToken `json:"staking_tokens"` +type staking struct { + StakingTokens []stakingToken `json:"staking_tokens"` } -type StakingToken struct { +type stakingToken struct { Denom string `json:"denom"` } -type Codebase struct { +type codebase struct { GitRepo string `json:"git_repo"` - Genesis CodebaseGenesis `json:"genesis"` + Genesis codebaseGenesis `json:"genesis"` RecommendedVersion string `json:"recommended_version"` CompatibleVersions []string `json:"compatible_versions"` - Consensus CodebaseConsensus `json:"consensus"` - Sdk CodebaseSDK `json:"sdk"` - Ibc CodebaseIBC `json:"ibc,omitempty"` - Cosmwasm CodebaseCosmwam `json:"cosmwasm,omitempty"` + Consensus codebaseConsensus `json:"consensus"` + Sdk codebaseSDK `json:"sdk"` + Ibc codebaseIBC `json:"ibc,omitempty"` + Cosmwasm codebaseCosmwam `json:"cosmwasm,omitempty"` } -type CodebaseGenesis struct { +type codebaseGenesis struct { GenesisURL string `json:"genesis_url"` } -type CodebaseConsensus struct { +type codebaseConsensus struct { Type string `json:"type"` Version string `json:"version"` } -type CodebaseSDK struct { +type codebaseSDK struct { Type string `json:"type"` Version string `json:"version"` } -type CodebaseIBC struct { +type codebaseIBC struct { Type string `json:"type"` Version string `json:"version"` } -type CodebaseCosmwam struct { +type codebaseCosmwam struct { Version string `json:"version,omitempty"` Enabled bool `json:"enabled"` } -type Fees struct { - FeeTokens []FeeToken `json:"fee_tokens"` +type fees struct { + FeeTokens []feeToken `json:"fee_tokens"` } -type FeeToken struct { +type feeToken struct { Denom string `json:"denom"` FixedMinGasPrice float64 `json:"fixed_min_gas_price"` LowGasPrice float64 `json:"low_gas_price"` @@ -122,48 +123,30 @@ func (c chainJSON) SaveJSON(out string) error { // https://raw.githubusercontent.com/cosmos/chain-registry/master/assetlist.schema.json // https://github.com/cosmos/chain-registry?tab=readme-ov-file#assetlists type assetListJSON struct { - ChainName string `json:"chain_name"` - Assets []struct { - Description string `json:"description"` - ExtendedDescription string `json:"extended_description,omitempty"` - DenomUnits []struct { - Denom string `json:"denom"` - Exponent int `json:"exponent"` - } `json:"denom_units"` - Base string `json:"base"` - Name string `json:"name"` - Display string `json:"display"` - Symbol string `json:"symbol"` - LogoURIs struct { - Png string `json:"png"` - Svg string `json:"svg"` - } `json:"logo_URIs"` - CoingeckoID string `json:"coingecko_id,omitempty"` - Images []struct { - Png string `json:"png"` - Svg string `json:"svg"` - Theme struct { - PrimaryColorHex string `json:"primary_color_hex"` - } `json:"theme"` - } `json:"images"` - Socials struct { - Website string `json:"website"` - Twitter string `json:"twitter"` - } `json:"socials,omitempty"` - TypeAsset string `json:"type_asset"` - Traces []struct { - Type string `json:"type"` - Counterparty struct { - ChainName string `json:"chain_name"` - BaseDenom string `json:"base_denom"` - ChannelID string `json:"channel_id"` - } `json:"counterparty"` - Chain struct { - ChannelID string `json:"channel_id"` - Path string `json:"path"` - } `json:"chain"` - } `json:"traces,omitempty"` - } `json:"assets"` + ChainName string `json:"chain_name"` + Assets []asset `json:"assets"` +} + +type asset struct { + Description string `json:"description"` + DenomUnits []denomUnit `json:"denom_units"` + Base string `json:"base"` + Name string `json:"name"` + Display string `json:"display"` + Symbol string `json:"symbol"` + CoingeckoID string `json:"coingecko_id,omitempty"` + Socials socials `json:"socials,omitempty"` + TypeAsset string `json:"type_asset"` +} + +type denomUnit struct { + Denom string `json:"denom"` + Exponent int `json:"exponent"` +} + +type socials struct { + Website string `json:"website"` + Twitter string `json:"twitter"` } // SaveJSON saves the assetList to the given out directory. @@ -196,14 +179,14 @@ func (s Scaffolder) AddChainRegistryFiles(chain *chain.Chain, cfg *chainconfig.C chainGitURL, _ /* do not fail on non-existing git repo */ := xgit.RespositoryURL(chain.AppPath()) var ( - consensus CodebaseConsensus - cosmwasm CodebaseCosmwam - ibc CodebaseIBC + consensus codebaseConsensus + cosmwasm codebaseCosmwam + ibc codebaseIBC ) consensusVersion, err := getVersionOfFromGoMod(chain, "github.com/cometbft/cometbft") if err == nil { - consensus = CodebaseConsensus{ + consensus = codebaseConsensus{ Type: "cometbft", Version: consensusVersion, } @@ -211,7 +194,7 @@ func (s Scaffolder) AddChainRegistryFiles(chain *chain.Chain, cfg *chainconfig.C cosmwasmVersion, err := getVersionOfFromGoMod(chain, "github.com/CosmWasm/wasmd") if err == nil { - cosmwasm = CodebaseCosmwam{ + cosmwasm = codebaseCosmwam{ Version: cosmwasmVersion, Enabled: true, } @@ -219,7 +202,7 @@ func (s Scaffolder) AddChainRegistryFiles(chain *chain.Chain, cfg *chainconfig.C ibcVersion, err := getVersionOfFromGoMod(chain, "github.com/cosmos/ibc-go") if err == nil { - ibc = CodebaseIBC{ + ibc = codebaseIBC{ Type: "go", Version: ibcVersion, } @@ -248,8 +231,8 @@ func (s Scaffolder) AddChainRegistryFiles(chain *chain.Chain, cfg *chainconfig.C NodeHome: chainHome, KeyAlgos: []string{"secp256k1"}, Slip44: 118, - Fees: Fees{ - FeeTokens: []FeeToken{ + Fees: fees{ + FeeTokens: []feeToken{ { Denom: defaultDenom, FixedMinGasPrice: 0.025, @@ -259,18 +242,18 @@ func (s Scaffolder) AddChainRegistryFiles(chain *chain.Chain, cfg *chainconfig.C }, }, }, - Staking: Staking{ - StakingTokens: []StakingToken{ + Staking: staking{ + StakingTokens: []stakingToken{ { Denom: defaultDenom, }, }, }, - Codebase: Codebase{ + Codebase: codebase{ GitRepo: chainGitURL, RecommendedVersion: "v1.0.0", CompatibleVersions: []string{"v1.0.0"}, - Sdk: CodebaseSDK{ + Sdk: codebaseSDK{ Type: "cosmos", Version: chain.Version.String(), }, @@ -282,7 +265,25 @@ func (s Scaffolder) AddChainRegistryFiles(chain *chain.Chain, cfg *chainconfig.C assetListJson := assetListJSON{ ChainName: chainJson.ChainName, - Assets: nil, + Assets: []asset{ + { + Description: fmt.Sprintf("The native token of the %s chain", chainJson.ChainName), + DenomUnits: []denomUnit{ + { + Denom: defaultDenom, + Exponent: 0, + }, + }, + Base: defaultDenom, + Name: chainJson.ChainName, + Symbol: strings.ToUpper(defaultDenom), + TypeAsset: "sdk.coin", + Socials: socials{ + Website: "https://example.com", + Twitter: "https://x.com/ignite", + }, + }, + }, } if err := chainJson.SaveJSON(chainFilename); err != nil { From 341ff8ef66eb0428a09c39f5c3c1d0012ebe467c Mon Sep 17 00:00:00 2001 From: Julien Robert Date: Wed, 8 Jan 2025 23:16:13 +0100 Subject: [PATCH 10/12] lint --- ignite/cmd/scaffold_chain_registry.go | 2 +- ignite/services/scaffolder/chain_registry.go | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/ignite/cmd/scaffold_chain_registry.go b/ignite/cmd/scaffold_chain_registry.go index e2df4c898e..e566848fb3 100644 --- a/ignite/cmd/scaffold_chain_registry.go +++ b/ignite/cmd/scaffold_chain_registry.go @@ -49,7 +49,7 @@ func scaffoldChainRegistryFiles(cmd *cobra.Command, args []string) error { return err } - var appPath = flagGetPath(cmd) + appPath := flagGetPath(cmd) sc, err := scaffolder.New(cmd.Context(), appPath, cfg.Build.Proto.Path) if err != nil { return err diff --git a/ignite/services/scaffolder/chain_registry.go b/ignite/services/scaffolder/chain_registry.go index adbb0bcea5..c48a0bbb90 100644 --- a/ignite/services/scaffolder/chain_registry.go +++ b/ignite/services/scaffolder/chain_registry.go @@ -8,12 +8,12 @@ import ( "path/filepath" "strings" + sdk "github.com/cosmos/cosmos-sdk/types" + chainconfig "github.com/ignite/cli/v29/ignite/config/chain" "github.com/ignite/cli/v29/ignite/pkg/errors" "github.com/ignite/cli/v29/ignite/pkg/xgit" "github.com/ignite/cli/v29/ignite/services/chain" - - sdk "github.com/cosmos/cosmos-sdk/types" ) const ( @@ -117,7 +117,7 @@ func (c chainJSON) SaveJSON(out string) error { return err } - return os.WriteFile(out, bz, 0666) + return os.WriteFile(out, bz, 0o666) } // https://raw.githubusercontent.com/cosmos/chain-registry/master/assetlist.schema.json @@ -156,7 +156,7 @@ func (c assetListJSON) SaveJSON(out string) error { return err } - return os.WriteFile(out, bz, 0666) + return os.WriteFile(out, bz, 0o666) } // AddChainRegistryFiles generates the chain registry files in the scaffolded chains. From 5f5621b1e6e5c5f3d5834c2c62ea3ba0faccc976 Mon Sep 17 00:00:00 2001 From: Julien Robert Date: Wed, 8 Jan 2025 23:21:15 +0100 Subject: [PATCH 11/12] lint --- ignite/cmd/scaffold_chain_registry.go | 2 +- ignite/services/scaffolder/chain_registry.go | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/ignite/cmd/scaffold_chain_registry.go b/ignite/cmd/scaffold_chain_registry.go index e566848fb3..ba080a0952 100644 --- a/ignite/cmd/scaffold_chain_registry.go +++ b/ignite/cmd/scaffold_chain_registry.go @@ -35,7 +35,7 @@ Read more about the assets.json at https://github.com/cosmos/chain-registry?tab= return c } -func scaffoldChainRegistryFiles(cmd *cobra.Command, args []string) error { +func scaffoldChainRegistryFiles(cmd *cobra.Command, _ []string) error { session := cliui.New(cliui.StartSpinnerWithText(statusScaffolding)) defer session.End() diff --git a/ignite/services/scaffolder/chain_registry.go b/ignite/services/scaffolder/chain_registry.go index c48a0bbb90..b42da87717 100644 --- a/ignite/services/scaffolder/chain_registry.go +++ b/ignite/services/scaffolder/chain_registry.go @@ -117,7 +117,7 @@ func (c chainJSON) SaveJSON(out string) error { return err } - return os.WriteFile(out, bz, 0o666) + return os.WriteFile(out, bz, 0o600) } // https://raw.githubusercontent.com/cosmos/chain-registry/master/assetlist.schema.json @@ -156,7 +156,7 @@ func (c assetListJSON) SaveJSON(out string) error { return err } - return os.WriteFile(out, bz, 0o666) + return os.WriteFile(out, bz, 0o600) } // AddChainRegistryFiles generates the chain registry files in the scaffolded chains. @@ -218,7 +218,7 @@ func (s Scaffolder) AddChainRegistryFiles(chain *chain.Chain, cfg *chainconfig.C } } - chainJson := chainJSON{ + chainData := chainJSON{ ChainName: chain.Name(), PrettyName: chain.Name(), ChainType: DefaultChainType, @@ -263,11 +263,11 @@ func (s Scaffolder) AddChainRegistryFiles(chain *chain.Chain, cfg *chainconfig.C }, } - assetListJson := assetListJSON{ - ChainName: chainJson.ChainName, + assetListData := assetListJSON{ + ChainName: chainData.ChainName, Assets: []asset{ { - Description: fmt.Sprintf("The native token of the %s chain", chainJson.ChainName), + Description: fmt.Sprintf("The native token of the %s chain", chainData.ChainName), DenomUnits: []denomUnit{ { Denom: defaultDenom, @@ -275,7 +275,7 @@ func (s Scaffolder) AddChainRegistryFiles(chain *chain.Chain, cfg *chainconfig.C }, }, Base: defaultDenom, - Name: chainJson.ChainName, + Name: chainData.ChainName, Symbol: strings.ToUpper(defaultDenom), TypeAsset: "sdk.coin", Socials: socials{ @@ -286,11 +286,11 @@ func (s Scaffolder) AddChainRegistryFiles(chain *chain.Chain, cfg *chainconfig.C }, } - if err := chainJson.SaveJSON(chainFilename); err != nil { + if err := chainData.SaveJSON(chainFilename); err != nil { return err } - if err := assetListJson.SaveJSON(assetListFilename); err != nil { + if err := assetListData.SaveJSON(assetListFilename); err != nil { return err } From 1627882cb2d817999f11bde2bf5b0ef9d17048a8 Mon Sep 17 00:00:00 2001 From: Julien Robert Date: Sat, 11 Jan 2025 22:03:23 +0100 Subject: [PATCH 12/12] typos --- ignite/pkg/xgit/xgit.go | 4 ++-- ignite/services/scaffolder/chain_registry.go | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/ignite/pkg/xgit/xgit.go b/ignite/pkg/xgit/xgit.go index c72be5e27f..3d62cdd84a 100644 --- a/ignite/pkg/xgit/xgit.go +++ b/ignite/pkg/xgit/xgit.go @@ -160,8 +160,8 @@ func IsRepository(path string) (bool, error) { return true, nil } -// RespositoryURL returns the URL of the origin remote of a Git repository. -func RespositoryURL(path string) (string, error) { +// RepositoryURL returns the URL of the origin remote of a Git repository. +func RepositoryURL(path string) (string, error) { repo, err := git.PlainOpenWithOptions(path, &defaultOpenOpts) if err != nil { return "", err diff --git a/ignite/services/scaffolder/chain_registry.go b/ignite/services/scaffolder/chain_registry.go index b42da87717..bd1643aef0 100644 --- a/ignite/services/scaffolder/chain_registry.go +++ b/ignite/services/scaffolder/chain_registry.go @@ -71,7 +71,7 @@ type codebase struct { Consensus codebaseConsensus `json:"consensus"` Sdk codebaseSDK `json:"sdk"` Ibc codebaseIBC `json:"ibc,omitempty"` - Cosmwasm codebaseCosmwam `json:"cosmwasm,omitempty"` + Cosmwasm codebaseCosmwasm `json:"cosmwasm,omitempty"` } type codebaseGenesis struct { @@ -93,7 +93,7 @@ type codebaseIBC struct { Version string `json:"version"` } -type codebaseCosmwam struct { +type codebaseCosmwasm struct { Version string `json:"version,omitempty"` Enabled bool `json:"enabled"` } @@ -176,11 +176,11 @@ func (s Scaffolder) AddChainRegistryFiles(chain *chain.Chain, cfg *chainconfig.C return errors.Wrap(err, "failed to get chain ID") } - chainGitURL, _ /* do not fail on non-existing git repo */ := xgit.RespositoryURL(chain.AppPath()) + chainGitURL, _ /* do not fail on non-existing git repo */ := xgit.RepositoryURL(chain.AppPath()) var ( consensus codebaseConsensus - cosmwasm codebaseCosmwam + cosmwasm codebaseCosmwasm ibc codebaseIBC ) @@ -194,7 +194,7 @@ func (s Scaffolder) AddChainRegistryFiles(chain *chain.Chain, cfg *chainconfig.C cosmwasmVersion, err := getVersionOfFromGoMod(chain, "github.com/CosmWasm/wasmd") if err == nil { - cosmwasm = codebaseCosmwam{ + cosmwasm = codebaseCosmwasm{ Version: cosmwasmVersion, Enabled: true, }