Ori Newman 4658f9d05c
Implement BIP 39 and HD wallet features (#1705)
* Naive bip39 with address reuse

* Avoid address reuse in libkaspawallet

* Add wallet daemon

* Use daemon everywhere

* Add forceOverride

* Make CreateUnsignedTransaction endpoint receive amount in sompis

* Collect close UTXOs

* Filter out non-spendable UTXOs from selectUTXOs

* Use different paths for multisig and non multisig

* Fix tests to use non zero path

* Fix multisig cosigner index detection

* Add comments

* Fix dump_unencrypted_data.go according to bip39 and bip32

* Fix wrong derivation path for multisig on wallet creation

* Remove IsSynced endpoint and add validation if wallet is synced for the relevant endpoints

* Rename server address to daemon address

* Fix capacity for extendedPublicKeys

* Use ReadBytes instead of ReadLine

* Add validation when importing

* Increment before using index value, and use it as is

* Save keys file exactly where needed

* Use %+v printErrorAndExit

* Remove redundant consts

* Rnemae collectCloseUTXOs and collectFarUTXOs

* Move typedefs around

* Add comment to addressesToQuery

* Update collectUTXOsFromRecentAddresses comment about locks

* Split collectUTXOs to small functions

* Add sanity check

* Add addEntryToUTXOSet function

* Change validateIsSynced to isSynced

* Simplify createKeyPairsFromFunction logic

* Rename .Sync() to .Save()

* Fix typo

* Create bip39BitSize const

* Add consts to purposes

* Add multisig check for 'send'

* Rename updatedPSTxBytes to partiallySignedTransaction

* Change collectUTXOsFromFarAddresses's comment

* Use setters for last used indexes

* Don't use the pstx acronym

* Fix SetPath

* Remove spaces when reading lines

* Fix walletserver to daemonaddress

* Fix isUTXOSpendable to use DAA score

Co-authored-by: Svarog <feanorr@gmail.com>
2021-05-19 10:03:23 +03:00

61 lines
1.2 KiB
Go

package bip32
import (
"github.com/pkg/errors"
"strconv"
"strings"
)
type path struct {
isPublic bool
indexes []uint32
}
func parsePath(pathString string) (*path, error) {
parts := strings.Split(pathString, "/")
isPublic := false
switch parts[0] {
case "m":
isPublic = false
case "M":
isPublic = true
default:
return nil, errors.Errorf("%s is an invalid extended key type", parts[0])
}
indexParts := parts[1:]
indexes := make([]uint32, len(indexParts))
for i, part := range indexParts {
var err error
indexes[i], err = parseIndex(part)
if err != nil {
return nil, err
}
}
return &path{
isPublic: isPublic,
indexes: indexes,
}, nil
}
func parseIndex(indexString string) (uint32, error) {
const isHardenedSuffix = "'"
isHardened := strings.HasSuffix(indexString, isHardenedSuffix)
trimmedIndexString := strings.TrimSuffix(indexString, isHardenedSuffix)
index, err := strconv.Atoi(trimmedIndexString)
if err != nil {
return 0, err
}
if index >= hardenedIndexStart {
return 0, errors.Errorf("max index value is %d but got %d", hardenedIndexStart, index)
}
if isHardened {
return uint32(index) + hardenedIndexStart, nil
}
return uint32(index), nil
}