github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/libs/cosmos-sdk/types/denom.go (about)

     1  package types
     2  
     3  import (
     4  	"fmt"
     5  )
     6  
     7  // denomUnits contains a mapping of denomination mapped to their respective unit
     8  // multipliers (e.g. 1atom = 10^-6uatom).
     9  var denomUnits = map[string]Dec{}
    10  
    11  // RegisterDenom registers a denomination with a corresponding unit. If the
    12  // denomination is already registered, an error will be returned.
    13  func RegisterDenom(denom string, unit Dec) error {
    14  	if err := ValidateDenom(denom); err != nil {
    15  		return err
    16  	}
    17  
    18  	if _, ok := denomUnits[denom]; ok {
    19  		return fmt.Errorf("denom %s already registered", denom)
    20  	}
    21  
    22  	denomUnits[denom] = unit
    23  	return nil
    24  }
    25  
    26  // GetDenomUnit returns a unit for a given denomination if it exists. A boolean
    27  // is returned if the denomination is registered.
    28  func GetDenomUnit(denom string) (Dec, bool) {
    29  	if err := ValidateDenom(denom); err != nil {
    30  		return ZeroDec(), false
    31  	}
    32  
    33  	unit, ok := denomUnits[denom]
    34  	if !ok {
    35  		return ZeroDec(), false
    36  	}
    37  
    38  	return unit, true
    39  }
    40  
    41  // ConvertCoin attempts to convert a coin to a given denomination. If the given
    42  // denomination is invalid or if neither denomination is registered, an error
    43  // is returned.
    44  func ConvertCoin(coin Coin, denom string) (Coin, error) {
    45  	if err := ValidateDenom(denom); err != nil {
    46  		return Coin{}, err
    47  	}
    48  
    49  	srcUnit, ok := GetDenomUnit(coin.Denom)
    50  	if !ok {
    51  		return Coin{}, fmt.Errorf("source denom not registered: %s", coin.Denom)
    52  	}
    53  
    54  	dstUnit, ok := GetDenomUnit(denom)
    55  	if !ok {
    56  		return Coin{}, fmt.Errorf("destination denom not registered: %s", denom)
    57  	}
    58  
    59  	if srcUnit.Equal(dstUnit) {
    60  		return NewCoin(denom, coin.Amount), nil
    61  	}
    62  
    63  	return NewCoin(denom, coin.Amount.Mul(srcUnit.Quo(dstUnit)).TruncateInt()), nil
    64  }