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 }