github.com/stafiprotocol/go-substrate-rpc-client@v1.4.7/subkey/derive.go (about)

     1  package subkey
     2  
     3  import (
     4  	"encoding/binary"
     5  	"errors"
     6  	"regexp"
     7  	"strconv"
     8  	"strings"
     9  
    10  	"golang.org/x/crypto/blake2b"
    11  )
    12  
    13  const (
    14  	// DevPhrase is default phrase used for dev test accounts
    15  	DevPhrase = "bottom drive obey lake curtain smoke basket hold race lonely fit walk"
    16  
    17  	junctionIDLen = 32
    18  )
    19  
    20  var (
    21  	re = regexp.MustCompile(`^(?P<phrase>[\d\w ]+)?(?P<path>(//?[^/]+)*)(///(?P<password>.*))?$`)
    22  
    23  	reJunction = regexp.MustCompile(`/(/?[^/]+)`)
    24  )
    25  
    26  type DeriveJunction struct {
    27  	ChainCode [32]byte
    28  	IsHard    bool
    29  }
    30  
    31  func deriveJunctions(codes []string) (djs []DeriveJunction, err error) {
    32  	for _, code := range codes {
    33  		dj, err := parseDeriveJunction(code)
    34  		if err != nil {
    35  			return nil, err
    36  		}
    37  
    38  		djs = append(djs, dj)
    39  	}
    40  
    41  	return djs, nil
    42  }
    43  
    44  func parseDeriveJunction(code string) (DeriveJunction, error) {
    45  	var jd DeriveJunction
    46  	if strings.HasPrefix(code, "/") {
    47  		jd.IsHard = true
    48  		code = strings.TrimPrefix(code, "/")
    49  	}
    50  
    51  	var bc []byte
    52  	u64, err := strconv.ParseUint(code, 10, 0)
    53  	if err == nil {
    54  		bc = make([]byte, 8)
    55  		binary.LittleEndian.PutUint64(bc, u64)
    56  	} else {
    57  		cl, err := compactUint(uint64(len(code)))
    58  		if err != nil {
    59  			return jd, err
    60  		}
    61  
    62  		bc = append(cl, code...)
    63  	}
    64  
    65  	if len(bc) > junctionIDLen {
    66  		b := blake2b.Sum256(bc)
    67  		bc = b[:]
    68  	}
    69  
    70  	copy(jd.ChainCode[:len(bc)], bc)
    71  	return jd, nil
    72  }
    73  
    74  func derivePath(path string) (parts []string) {
    75  	res := reJunction.FindAllStringSubmatch(path, -1)
    76  	for _, p := range res {
    77  		parts = append(parts, p[1])
    78  	}
    79  	return parts
    80  }
    81  
    82  func splitURI(suri string) (phrase string, pathMap string, password string, err error) {
    83  	res := re.FindStringSubmatch(suri)
    84  	if res == nil {
    85  		return phrase, pathMap, password, errors.New("invalid URI format")
    86  	}
    87  
    88  	phrase = res[1]
    89  	if phrase == "" {
    90  		phrase = DevPhrase
    91  	}
    92  
    93  	return phrase, res[2], res[5], nil
    94  }