Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add fee abstraction app #130

Merged
merged 17 commits into from
Nov 5, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions app.ignite.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ apps:
explorer:
description: Easy to use terminal chain explorer for testing your Ignite blockchains
path: ./explorer
fee-abstraction:
description: Integrate the fee abstraction module from osmosis-labs to make it easy for new chains to accept the currencies of existing chains
path: ./fee-abstraction
hermes:
description: A wrapper around the hermes IBC relayer
path: ./hermes
Expand Down
7 changes: 7 additions & 0 deletions fee-abstraction/CHANGELOG.md
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
33 changes: 33 additions & 0 deletions fee-abstraction/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Wasm
Pantani marked this conversation as resolved.
Show resolved Hide resolved
Pantani marked this conversation as resolved.
Show resolved Hide resolved

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.
136 changes: 136 additions & 0 deletions fee-abstraction/cmd/cmd.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
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"
flagPath = "path"
flagHome = "home"

statusScaffolding = "Scaffolding..."

defaultFeeAbsVersion = "v8.0.2"
)

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: "scaffold-chain",
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,
},
},
},
}
}

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
}
65 changes: 65 additions & 0 deletions fee-abstraction/cmd/hook.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package cmd

import (
"context"

"github.com/blang/semver/v4"
"github.com/ignite/cli/v28/ignite/pkg/cliui"
"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"
)

// ExecuteScaffoldChainHook executes the scaffold chain hook.
func ExecuteScaffoldChainHook(ctx context.Context, h *plugin.ExecutedHook, api plugin.ClientAPI) 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()))
Pantani marked this conversation as resolved.
Show resolved Hide resolved
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
}
Loading
Loading