github.com/decred/politeia@v1.4.0/util/dcr.go (about) 1 // Copyright (c) 2021 The Decred developers 2 // Use of this source code is governed by an ISC 3 // license that can be found in the LICENSE file. 4 5 package util 6 7 import ( 8 "fmt" 9 "regexp" 10 "strconv" 11 "strings" 12 13 "decred.org/dcrwallet/wallet/udb" 14 "github.com/decred/dcrd/chaincfg/v3" 15 "github.com/decred/dcrd/dcrec" 16 "github.com/decred/dcrd/dcrutil/v3" 17 "github.com/decred/dcrd/hdkeychain/v3" 18 ) 19 20 // DeriveChildAddress derives a child address using the provided xpub and 21 // index. 22 func DeriveChildAddress(params *chaincfg.Params, xpub string, index uint32) (string, error) { 23 // Parse the extended public key. 24 acctKey, err := hdkeychain.NewKeyFromString(xpub, params) 25 if err != nil { 26 return "", err 27 } 28 29 // Derive the appropriate branch key. 30 branchKey, err := acctKey.Child(udb.ExternalBranch) 31 if err != nil { 32 return "", err 33 } 34 35 // Derive the child address. 36 key, err := branchKey.Child(index) 37 if err != nil { 38 return "", err 39 } 40 pkh := dcrutil.Hash160(key.SerializedPubKey()) 41 addr, err := dcrutil.NewAddressPubKeyHash(pkh, params, dcrec.STEcdsaSecp256k1) 42 if err != nil { 43 return "", err 44 } 45 46 return addr.Address(), nil 47 } 48 49 // DcrStringToAtoms converts a DCR amount as a string into a uint64 50 // representing atoms. Supported input variations: "1", ".1", "0.1". 51 func DcrStringToAtoms(dcrstr string) (uint64, error) { 52 match, err := regexp.MatchString("(\\d*\\.)*\\d+", dcrstr) 53 if err != nil { 54 return 0, err 55 } 56 if !match { 57 return 0, fmt.Errorf("invalid DCR amount: %v", dcrstr) 58 } 59 60 var dcrsplit []string 61 if strings.Contains(dcrstr, ".") { 62 dcrsplit = strings.Split(dcrstr, ".") 63 if len(dcrsplit[0]) == 0 { 64 dcrsplit[0] = "0" 65 } 66 } else { 67 dcrsplit = []string{dcrstr, "0"} 68 } 69 70 whole, err := strconv.ParseUint(dcrsplit[0], 10, 64) 71 if err != nil { 72 return 0, err 73 } 74 75 dcrsplit[1] += "00000000" 76 fraction, err := strconv.ParseUint(dcrsplit[1][0:8], 10, 64) 77 if err != nil { 78 return 0, err 79 } 80 81 return ((whole * 1e8) + fraction), nil 82 }