github.com/decred/dcrlnd@v0.7.6/channeldb/migration_01_to_11/zpay32/amountunits.go (about)

     1  package zpay32
     2  
     3  import (
     4  	"fmt"
     5  	"strconv"
     6  
     7  	lnwire "github.com/decred/dcrlnd/channeldb/migration/lnwire21"
     8  )
     9  
    10  var (
    11  	// toMAtoms is a map from a unit to a function that converts an amount
    12  	// of that unit to MilliAtoms.
    13  	toMAtoms = map[byte]func(uint64) (lnwire.MilliAtom, error){
    14  		'm': mDcrToMAtoms,
    15  		'u': uDcrToMAtoms,
    16  		'n': nDcrToMAtoms,
    17  		'p': pDcrToMAtoms,
    18  	}
    19  )
    20  
    21  // mDcrToMAtoms converts the given amount in milliDCR to MilliAtoms.
    22  func mDcrToMAtoms(m uint64) (lnwire.MilliAtom, error) {
    23  	return lnwire.MilliAtom(m) * 100000000, nil
    24  }
    25  
    26  // uDcrToMAtoms converts the given amount in microDCR to MilliAtoms.
    27  func uDcrToMAtoms(u uint64) (lnwire.MilliAtom, error) {
    28  	return lnwire.MilliAtom(u * 100000), nil
    29  }
    30  
    31  // nDcrToMAtoms converts the given amount in nanoDCR to MilliAtoms.
    32  func nDcrToMAtoms(n uint64) (lnwire.MilliAtom, error) {
    33  	return lnwire.MilliAtom(n * 100), nil
    34  }
    35  
    36  // pDcrToMAtoms converts the given amount in picoDCR to MilliAtoms.
    37  func pDcrToMAtoms(p uint64) (lnwire.MilliAtom, error) {
    38  	if p < 10 {
    39  		return 0, fmt.Errorf("minimum amount is 10p")
    40  	}
    41  	if p%10 != 0 {
    42  		return 0, fmt.Errorf("amount %d pDCR not expressible in mAt",
    43  			p)
    44  	}
    45  	return lnwire.MilliAtom(p / 10), nil
    46  }
    47  
    48  // decodeAmount returns the amount encoded by the provided string in MilliAtom.
    49  func decodeAmount(amount string) (lnwire.MilliAtom, error) {
    50  	if len(amount) < 1 {
    51  		return 0, fmt.Errorf("amount must be non-empty")
    52  	}
    53  
    54  	// If last character is a digit, then the amount can just be
    55  	// interpreted as DCR.
    56  	char := amount[len(amount)-1]
    57  	digit := char - '0'
    58  	if digit <= 9 {
    59  		dcr, err := strconv.ParseUint(amount, 10, 64)
    60  		if err != nil {
    61  			return 0, err
    62  		}
    63  		return lnwire.MilliAtom(dcr) * mAtPerDcr, nil
    64  	}
    65  
    66  	// If not a digit, it must be part of the known units.
    67  	conv, ok := toMAtoms[char]
    68  	if !ok {
    69  		return 0, fmt.Errorf("unknown multiplier %c", char)
    70  	}
    71  
    72  	// Known unit.
    73  	num := amount[:len(amount)-1]
    74  	if len(num) < 1 {
    75  		return 0, fmt.Errorf("number must be non-empty")
    76  	}
    77  
    78  	am, err := strconv.ParseUint(num, 10, 64)
    79  	if err != nil {
    80  		return 0, err
    81  	}
    82  
    83  	return conv(am)
    84  }