Skip to content

Commit

Permalink
dep init
Browse files Browse the repository at this point in the history
  • Loading branch information
miguelmota committed Jul 5, 2018
1 parent 66d224c commit 82eb119
Show file tree
Hide file tree
Showing 163 changed files with 25,149 additions and 45 deletions.
60 changes: 60 additions & 0 deletions Gopkg.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

46 changes: 46 additions & 0 deletions Gopkg.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Gopkg.toml example
#
# Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md
# for detailed Gopkg.toml documentation.
#
# required = ["github.com/user/thing/cmd/thing"]
# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"]
#
# [[constraint]]
# name = "github.com/user/project"
# version = "1.0.0"
#
# [[constraint]]
# name = "github.com/user/project2"
# branch = "dev"
# source = "github.com/myfork/project2"
#
# [[override]]
# name = "github.com/x/y"
# version = "2.4.0"
#
# [prune]
# non-go = false
# go-tests = true
# unused-packages = true


[[constraint]]
branch = "master"
name = "github.com/btcsuite/btcd"

[[constraint]]
branch = "master"
name = "github.com/btcsuite/btcutil"

[[constraint]]
name = "github.com/ethereum/go-ethereum"
version = "1.8.11"

[[constraint]]
branch = "master"
name = "github.com/tyler-smith/go-bip39"

[prune]
go-tests = true
unused-packages = true
18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# go-ethereum-hdwallet

> Ethereum HD Wallet derivations from mnemonic
## Install

```bash
go get github.com/miguelmota/go-ethereum-hdwallet
```

## Example

```go
```

## License

MIT
5 changes: 5 additions & 0 deletions example/example.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package main

func main() {

}
143 changes: 98 additions & 45 deletions hdwallet.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ package hdwallet
import (
"crypto/ecdsa"
"errors"
"fmt"
"strconv"
"strings"

"github.com/btcsuite/btcd/chaincfg"
"github.com/btcsuite/btcutil/hdkeychain"
Expand All @@ -12,30 +15,14 @@ import (
"github.com/tyler-smith/go-bip39"
)

func generateMnemonic() (string, error) {
// Generate a mnemonic for memorization or user-friendly seeds
entropy, err := bip39.NewEntropy(128)
if err != nil {
return "", err
}
mnemonic, err := bip39.NewMnemonic(entropy)
if err != nil {
return "", err
}
return mnemonic, nil
}

// Wallet ...
type Wallet struct {
mnemonic string
path string
privateKey *ecdsa.PrivateKey
publicKey *ecdsa.PublicKey
}

func newChild(key *hdkeychain.ExtendedKey, n int) (*hdkeychain.ExtendedKey, error) {
childKey, err := key.Child(hdkeychain.HardenedKeyStart + uint32(n))
return childKey, err
mnemonic string
path string
root *hdkeychain.ExtendedKey
extendedKey *hdkeychain.ExtendedKey
privateKey *ecdsa.PrivateKey
publicKey *ecdsa.PublicKey
}

// Config ...
Expand All @@ -47,40 +34,82 @@ type Config struct {
// New ...
func New(config Config) (*Wallet, error) {
if config.Path == "" {
config.Path = `m/44/60/0/0`
config.Path = `m/44'/60'/0'/0`
}

seed := bip39.NewSeed(config.Mnemonic, "")
masterKey, err := hdkeychain.NewMaster(seed, &chaincfg.MainNetParams)
if err != nil {
return nil, err
parts := strings.Split(config.Path, "/")
var err error
var masterKey *hdkeychain.ExtendedKey
var key *hdkeychain.ExtendedKey
for _, part := range parts {
p := strings.Split(part, "'")
n := p[0]
h := (len(p) == 2)

if n == "m" {
masterKey, err = hdkeychain.NewMaster(seed, &chaincfg.MainNetParams)
if err != nil {
return nil, err
}
key = masterKey
continue
}

u64, err := strconv.ParseUint(n, 10, 32)
if err != nil {
return nil, err
}

key, err = newChild(key, uint32(u64), h)
if err != nil {
return nil, err
}
}

// m/44
bipKey, err := newChild(masterKey, 44)
privateKey, err := key.ECPrivKey()
privateKeyECDSA := privateKey.ToECDSA()
if err != nil {
return nil, err
}

// m/44/60
coinKey, err := newChild(bipKey, 60)
if err != nil {
return nil, err
publicKey := privateKeyECDSA.Public()
publicKeyECDSA, ok := publicKey.(*ecdsa.PublicKey)
if !ok {
return nil, errors.New("failed ot get public key")
}

// m/44/60/0
accountKey, err := newChild(coinKey, 0)
if err != nil {
return nil, err
wallet := &Wallet{
mnemonic: config.Mnemonic,
path: config.Path,
root: masterKey,
extendedKey: key,
privateKey: privateKeyECDSA,
publicKey: publicKeyECDSA,
}

// /m/44/60/0/0
pubKey, err := accountKey.Child(uint32(0))
if err != nil {
return nil, err
return wallet, nil
}

// Derive ...
func (s Wallet) Derive(index interface{}) (*Wallet, error) {
var idx uint32
switch v := index.(type) {
case int:
idx = uint32(v)
case int8:
idx = uint32(v)
case int16:
idx = uint32(v)
case uint:
idx = uint32(v)
case uint8:
idx = uint32(v)
case uint16:
idx = uint32(v)
}

address, err := pubKey.Child(uint32(0))
address, err := s.extendedKey.Child(idx)
if err != nil {
return nil, err
}
Expand All @@ -97,11 +126,14 @@ func New(config Config) (*Wallet, error) {
return nil, errors.New("failed ot get public key")
}

path := fmt.Sprintf("%s/%v", s.path, idx)

wallet := &Wallet{
mnemonic: config.Mnemonic,
path: config.Path,
privateKey: privateKeyECDSA,
publicKey: publicKeyECDSA,
path: path,
root: s.extendedKey,
extendedKey: address,
privateKey: privateKeyECDSA,
publicKey: publicKeyECDSA,
}

return wallet, nil
Expand Down Expand Up @@ -156,3 +188,24 @@ func (s Wallet) Path() string {
func (s Wallet) Mnemonic() string {
return s.mnemonic
}

func newChild(key *hdkeychain.ExtendedKey, n uint32, hardened bool) (*hdkeychain.ExtendedKey, error) {
if key == nil {
return nil, errors.New("key is nil")
}

if hardened {
n = hdkeychain.HardenedKeyStart + n
}

return key.Child(n)
}

// NewMnemonic ...
func NewMnemonic() (string, error) {
entropy, err := bip39.NewEntropy(128)
if err != nil {
return "", err
}
return bip39.NewMnemonic(entropy)
}
14 changes: 14 additions & 0 deletions hdwallet_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import (
"testing"
)

// TODO: tests

func TestNew(t *testing.T) {
mnemonic := "tag volcano eight thank tide danger coast health above argue embrace heavy"
/*
Expand All @@ -31,4 +33,16 @@ func TestNew(t *testing.T) {
fmt.Println(wallet.AddressHex())
fmt.Println("")
fmt.Println(wallet.Path())

wal, err := wallet.Derive(0)
if err != nil {
log.Fatal(err)
}
fmt.Println(wal.PrivateKeyHex())
fmt.Println("")
fmt.Println(wal.PublicKeyHex())
fmt.Println("")
fmt.Println(wal.AddressHex())
fmt.Println("")
fmt.Println(wal.Path())
}
16 changes: 16 additions & 0 deletions vendor/github.com/btcsuite/btcd/LICENSE

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 82eb119

Please sign in to comment.