mukan-ignite/ignite/services/chain/faucet.go
Mukan Erkin Törük c32551b6f7
Some checks failed
Docs Deploy / build_and_deploy (push) Has been cancelled
Generate Docs / cli (push) Has been cancelled
Generate Config Doc / cli (push) Has been cancelled
Go formatting / go-formatting (push) Has been cancelled
Check links / markdown-link-check (push) Has been cancelled
Integration / pre-test (push) Has been cancelled
Integration / test on (push) Has been cancelled
Integration / status (push) Has been cancelled
Lint / Lint Go code (push) Has been cancelled
Test / test (ubuntu-latest) (push) Has been cancelled
refactor: replace all github.com upstream refs with git.cw.tr/mukan-network
2026-05-11 03:36:24 +03:00

153 lines
4.5 KiB
Go

package chain
import (
"context"
"fmt"
"os"
"strings"
"time"
sdkmath "cosmossdk.io/math"
sdk "github.com/cosmos/cosmos-sdk/types"
chainconfig "git.cw.tr/mukan-network/mukan-ignite/ignite/config/chain"
chaincmdrunner "git.cw.tr/mukan-network/mukan-ignite/ignite/pkg/chaincmd/runner"
"git.cw.tr/mukan-network/mukan-ignite/ignite/pkg/cosmosfaucet"
"git.cw.tr/mukan-network/mukan-ignite/ignite/pkg/errors"
"git.cw.tr/mukan-network/mukan-ignite/ignite/pkg/xurl"
"git.cw.tr/mukan-network/mukan-ignite/ignite/pkg/xyaml"
)
var (
// ErrFaucetIsNotEnabled is returned when faucet is not enabled in the config.yml.
ErrFaucetIsNotEnabled = errors.New("faucet is not enabled in the config.yml")
// ErrFaucetAccountDoesNotExist returned when specified faucet account in the config.yml does not exist.
ErrFaucetAccountDoesNotExist = errors.New("specified account (faucet.name) does not exist")
)
var envAPIAddress = os.Getenv("API_ADDRESS")
// Faucet returns the faucet for the chain or an error if the faucet
// configuration is wrong or not configured (not enabled) at all.
func (c *Chain) Faucet(ctx context.Context) (cosmosfaucet.Faucet, error) {
id, err := c.ID()
if err != nil {
return cosmosfaucet.Faucet{}, err
}
conf, err := c.Config()
if err != nil {
return cosmosfaucet.Faucet{}, err
}
commands, err := c.Commands(ctx)
if err != nil {
return cosmosfaucet.Faucet{}, err
}
// validate if the faucet initialization in the config.yml is correct.
if conf.Faucet.Name == nil {
return cosmosfaucet.Faucet{}, ErrFaucetIsNotEnabled
}
if _, err := commands.ShowAccount(ctx, *conf.Faucet.Name); err != nil {
if errors.Is(err, chaincmdrunner.ErrAccountDoesNotExist) {
return cosmosfaucet.Faucet{}, ErrFaucetAccountDoesNotExist
}
return cosmosfaucet.Faucet{}, err
}
// construct faucet options.
validator, err := chainconfig.FirstValidator(conf)
if err != nil {
return cosmosfaucet.Faucet{}, err
}
servers, err := validator.GetServers()
if err != nil {
return cosmosfaucet.Faucet{}, err
}
apiAddress := servers.API.Address
if envAPIAddress != "" {
apiAddress = envAPIAddress
}
apiAddress, err = xurl.HTTP(apiAddress)
if err != nil {
return cosmosfaucet.Faucet{}, errors.Errorf("invalid host api address format: %w", err)
}
faucetOptions := []cosmosfaucet.Option{
cosmosfaucet.Account(*conf.Faucet.Name, "", "", "", ""),
cosmosfaucet.ChainID(id),
cosmosfaucet.OpenAPI(apiAddress),
cosmosfaucet.Version(c.Version),
}
// check if indexer is enabled or not.
if indexerDisabled(validator.Config) {
faucetOptions = append(faucetOptions, cosmosfaucet.IndexerDisabled())
c.ev.Send("⚠️ CometBFT indexer disabled. Faucet can't check account limits or verify transaction status.")
}
// parse coins to pass to the faucet as coins.
for _, coin := range conf.Faucet.Coins {
parsedCoin, err := sdk.ParseCoinNormalized(coin)
if err != nil {
return cosmosfaucet.Faucet{}, errors.Errorf("%w: %s", err, coin)
}
var amountMax sdkmath.Int
// find out the max amount for this coin.
for _, coinMax := range conf.Faucet.CoinsMax {
parsedMax, err := sdk.ParseCoinNormalized(coinMax)
if err != nil {
return cosmosfaucet.Faucet{}, errors.Errorf("%w: %s", err, coin)
}
if parsedMax.Denom == parsedCoin.Denom {
amountMax = parsedMax.Amount
break
}
}
faucetOptions = append(faucetOptions, cosmosfaucet.Coin(parsedCoin.Amount, amountMax, parsedCoin.Denom))
}
// parse fees to pass to the faucet as fees.
if fee := conf.Faucet.TxFee; fee != "" {
parsedFee, err := sdk.ParseCoinNormalized(fee)
if err != nil {
return cosmosfaucet.Faucet{}, errors.Errorf("%w: %s", err, fee)
}
faucetOptions = append(faucetOptions, cosmosfaucet.FeeAmount(parsedFee.Amount, parsedFee.Denom))
}
if conf.Faucet.RateLimitWindow != "" {
rateLimitWindow, err := time.ParseDuration(conf.Faucet.RateLimitWindow)
if err != nil {
return cosmosfaucet.Faucet{}, errors.Errorf("%w: %s", err, conf.Faucet.RateLimitWindow)
}
faucetOptions = append(faucetOptions, cosmosfaucet.RefreshWindow(rateLimitWindow))
}
// init the faucet with options and return.
return cosmosfaucet.New(ctx, commands, faucetOptions...)
}
// indexerDisabled checks if the indexer is disabled in the config.yml.
// More specifically, it checks if a kv indexer is used (psql indexer is not supported).
func indexerDisabled(valCfg xyaml.Map) bool {
const txIndexKey = "tx_index"
v, ok := valCfg[txIndexKey]
if !ok {
return false
}
return !strings.Contains(fmt.Sprintf("%v", v), "kv")
}