-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add fee abstraction app (#130)
* add fee abstraction app * add readme and cghangelog * improve readme and changelog * fix integration tests * update docs * add registry and check if sdk is greater o equal than v0.51 * bump ignite version * Initialized with Ignite CLI * avoid create module with feeabs name * add more test cases and fix old cases * simplify integration logic * check if the app is served for integration * bump cli * remove v7 * Update fee-abstraction/README.md * remove version map --------- Co-authored-by: Developer Experience team at Ignite <hello@ignite.com>
- Loading branch information
Showing
17 changed files
with
2,440 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
{ | ||
"appName": "fee-abstraction", | ||
"appDescription": "Integrate the fee abstraction module from osmosis-labs to make it easy for new chains to accept the currencies of existing chains", | ||
"ignite": ">28.5.2", | ||
"dependencies": {}, | ||
"cosmosSDK": ">0.50.8", | ||
"authors": [ | ||
{ | ||
"name": "Danilo Pantani", | ||
"github": "Pantani" | ||
} | ||
], | ||
"repositoryUrl": "https://github.com/ignite/apps", | ||
"documentationUrl": "https://github.com/ignite/apps/blob/main/fee-abstraction/README.md", | ||
"license": { | ||
"name": "MIT", | ||
"url": "https://github.com/ignite/apps/blob/main/LICENSE" | ||
}, | ||
"keywords": [ | ||
"scaffolder", | ||
"fee-abstraction", | ||
"osmosis", | ||
"osmosis-labs", | ||
"cli", | ||
"cosmos-sdk", | ||
"ignite app" | ||
], | ||
"supportedPlatforms": [ | ||
"mac", | ||
"linux" | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
# Fee Abstraction App Changelog | ||
|
||
## Unreleased | ||
|
||
## [`v0.1.0`](https://github.com/ignite/apps/releases/tag/fee-abstraction/v0.1.0) | ||
|
||
* First release of the Fee Abstraction app compatible with Ignite >= v28.5.2 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
# Fee Abstraction | ||
|
||
The Fee Abstraction app is an extension for the [Ignite CLI](https://github.com/ignite/cli), designed to help developers seamlessly integrate the [Fee Abstraction](https://github.com/osmosis-labs/fee-abstraction) module from Osmosis Labs into their blockchain projects. | ||
|
||
This app extends the `ignite scaffold chain` command by adding a `--fee-abstraction` flag, which automatically incorporates the Fee Abstraction module into your chain. | ||
|
||
## Features | ||
|
||
- Effortless Integration: Easily integrate the Fee Abstraction module into your blockchain with a single command. | ||
|
||
## Prerequisites | ||
|
||
- Ignite CLI version v28.5.2 or greater. | ||
- Or migrate your chain using the [Ignite migration guides](https://docs.ignite.com/migration). | ||
- Knowledge of blockchain development and the Fee Abstraction module. | ||
|
||
## Installation | ||
|
||
To install the Fee Abstraction app, it need to be globally, run the following command: | ||
|
||
```shell | ||
ignite app install -g github.com/ignite/apps/fee-abstraction | ||
``` | ||
|
||
## Usage | ||
|
||
- Now you can scaffold your chain using the fee abstraction module: | ||
|
||
```shell | ||
ignite s chain mars --fee-abstraction | ||
``` | ||
|
||
This command will scaffold a new chain named `mars` with the Fee Abstraction module already integrated. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
package cmd | ||
|
||
import ( | ||
"os" | ||
"path/filepath" | ||
"sort" | ||
"strings" | ||
|
||
"github.com/ignite/cli/v28/ignite/pkg/cliui/colors" | ||
"github.com/ignite/cli/v28/ignite/pkg/xgenny" | ||
"github.com/ignite/cli/v28/ignite/services/chain" | ||
"github.com/ignite/cli/v28/ignite/services/plugin" | ||
) | ||
|
||
const ( | ||
flagVersion = "fee-abstraction-version" | ||
flagFeeAbsModule = "fee-abstraction" | ||
flagNoModule = "no-module" | ||
flagPath = "path" | ||
|
||
statusScaffolding = "Scaffolding..." | ||
|
||
defaultFeeAbsVersion = "v8.0.2" | ||
feeAbsModuleName = "feeabs" | ||
|
||
ScaffoldChainHook = "scaffold-chain" | ||
ScaffoldModuleHook = "scaffold-module" | ||
) | ||
|
||
var ( | ||
modifyPrefix = colors.Modified("modify ") | ||
createPrefix = colors.Success("create ") | ||
removePrefix = func(s string) string { | ||
return strings.TrimPrefix(strings.TrimPrefix(s, modifyPrefix), createPrefix) | ||
} | ||
) | ||
|
||
// GetCommands returns the list of fee-abstraction app commands. | ||
func GetCommands() []*plugin.Command { | ||
return []*plugin.Command{ | ||
{ | ||
Use: "fee-abstraction", | ||
Short: "Integrate the fee abstraction module from osmosis-labs", | ||
Long: "Integrate the fee abstraction module from osmosis-labs to make it easy for new chains to accept the currencies of existing chains", | ||
}, | ||
} | ||
} | ||
|
||
// GetHooks returns the list of fee-abstraction app hooks. | ||
func GetHooks() []*plugin.Hook { | ||
return []*plugin.Hook{ | ||
{ | ||
Name: ScaffoldChainHook, | ||
PlaceHookOn: "ignite scaffold chain", | ||
Flags: []*plugin.Flag{ | ||
{ | ||
Name: flagFeeAbsModule, | ||
Usage: "Create a project that includes the fee abstraction module", | ||
DefaultValue: "false", | ||
Type: plugin.FlagTypeBool, | ||
}, | ||
|
||
{ | ||
Name: flagVersion, | ||
Usage: "fee abstraction semantic version", | ||
Shorthand: "v", | ||
DefaultValue: defaultFeeAbsVersion, | ||
Type: plugin.FlagTypeString, | ||
}, | ||
}, | ||
}, | ||
{ | ||
Name: ScaffoldModuleHook, | ||
PlaceHookOn: "ignite scaffold module", | ||
}, | ||
} | ||
} | ||
|
||
func getPath(flags plugin.Flags) string { | ||
path, _ := flags.GetString(flagPath) | ||
return path | ||
} | ||
|
||
func getVersion(flags plugin.Flags) string { | ||
version, _ := flags.GetString(flagVersion) | ||
version = strings.Replace(version, "v", "", 1) | ||
return version | ||
} | ||
|
||
// newChain create new *chain.Chain with home and path flags. | ||
func newChain(chainFolder string, flags plugin.Flags, chainOption ...chain.Option) (*chain.Chain, error) { | ||
appPath := getPath(flags) | ||
absPath, err := filepath.Abs(appPath) | ||
if err != nil { | ||
return nil, err | ||
} | ||
absPath = filepath.Join(absPath, chainFolder) | ||
return chain.New(absPath, chainOption...) | ||
} | ||
|
||
// sourceModificationToString output the modifications into a readable text. | ||
func sourceModificationToString(sm xgenny.SourceModification) (string, error) { | ||
// get file names and add prefix | ||
var files []string | ||
for _, modified := range sm.ModifiedFiles() { | ||
// get the relative app path from the current directory | ||
relativePath, err := relativePath(modified) | ||
if err != nil { | ||
return "", err | ||
} | ||
files = append(files, modifyPrefix+relativePath) | ||
} | ||
for _, created := range sm.CreatedFiles() { | ||
// get the relative app path from the current directory | ||
relativePath, err := relativePath(created) | ||
if err != nil { | ||
return "", err | ||
} | ||
files = append(files, createPrefix+relativePath) | ||
} | ||
|
||
// sort filenames without prefix | ||
sort.Slice(files, func(i, j int) bool { | ||
s1 := removePrefix(files[i]) | ||
s2 := removePrefix(files[j]) | ||
|
||
return strings.Compare(s1, s2) == -1 | ||
}) | ||
|
||
return "\n" + strings.Join(files, "\n"), nil | ||
} | ||
|
||
// relativePath return the relative app path from the current directory. | ||
func relativePath(appPath string) (string, error) { | ||
pwd, err := os.Getwd() | ||
if err != nil { | ||
return "", err | ||
} | ||
path, err := filepath.Rel(pwd, appPath) | ||
if err != nil { | ||
return "", err | ||
} | ||
return path, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
package cmd | ||
|
||
import ( | ||
"context" | ||
|
||
"github.com/blang/semver/v4" | ||
"github.com/ignite/cli/v28/ignite/pkg/cliui" | ||
"github.com/ignite/cli/v28/ignite/pkg/errors" | ||
"github.com/ignite/cli/v28/ignite/pkg/gomodulepath" | ||
"github.com/ignite/cli/v28/ignite/pkg/placeholder" | ||
"github.com/ignite/cli/v28/ignite/services/chain" | ||
"github.com/ignite/cli/v28/ignite/services/plugin" | ||
|
||
"github.com/ignite/apps/fee-abstraction/services/scaffolder" | ||
) | ||
|
||
// ExecuteScaffoldPreHook executes the scaffold pre hook. | ||
func ExecuteScaffoldPreHook(h *plugin.ExecutedHook) error { | ||
var ( | ||
flags = plugin.Flags(h.Hook.Flags) | ||
noModule, _ = flags.GetBool(flagNoModule) | ||
name = h.ExecutedCommand.Args[0] | ||
) | ||
if !noModule && name == feeAbsModuleName { | ||
return errors.Errorf("cannot scaffold module with name %s", feeAbsModuleName) | ||
} | ||
return nil | ||
} | ||
|
||
// ExecuteScaffoldChainPostHook executes the scaffold chain post hook. | ||
func ExecuteScaffoldChainPostHook(ctx context.Context, h *plugin.ExecutedHook) error { | ||
var ( | ||
flags = plugin.Flags(h.Hook.Flags) | ||
feeAbsModule, _ = flags.GetBool(flagFeeAbsModule) | ||
name = h.ExecutedCommand.Args[0] | ||
) | ||
if !feeAbsModule { | ||
return nil | ||
} | ||
|
||
session := cliui.New(cliui.StartSpinnerWithText(statusScaffolding)) | ||
defer session.End() | ||
|
||
pathInfo, err := gomodulepath.Parse(name) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
version := getVersion(flags) | ||
semVersion, err := semver.Parse(version) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
c, err := newChain(pathInfo.Root, flags, chain.WithOutputer(session), chain.CollectEvents(session.EventBus())) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
sc, err := scaffolder.New(c, session) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
sm, err := sc.AddFeeAbstraction(ctx, placeholder.New(), scaffolder.WithVersion(semVersion)) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
modificationsStr, err := sourceModificationToString(sm) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
session.Println(modificationsStr) | ||
session.Printf("\n🎉 Fee Abstraction added (`%[1]v`).\n\n", c.AppPath()) | ||
|
||
return nil | ||
} |
Oops, something went wrong.