Skip to content

Commit

Permalink
init
Browse files Browse the repository at this point in the history
  • Loading branch information
miguelmota committed Jul 5, 2018
0 parents commit 66d224c
Show file tree
Hide file tree
Showing 3 changed files with 206 additions and 0 deletions.
14 changes: 14 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
.PHONY: all
all: build

.PHONY: build
build:
@go build . -o bin/hdwallet

.PHONY: test
test:
@go test -v .

.PHONY: deps/cp
deps/cp:
@cp -r "${GOPATH}/src/github.com/ethereum/go-ethereum/crypto/secp256k1/libsecp256k1" "vendor/github.com/ethereum/go-ethereum/crypto/secp256k1/"
158 changes: 158 additions & 0 deletions hdwallet.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
package hdwallet

import (
"crypto/ecdsa"
"errors"

"github.com/btcsuite/btcd/chaincfg"
"github.com/btcsuite/btcutil/hdkeychain"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/crypto"
"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
}

// Config ...
type Config struct {
Mnemonic string
Path string
}

// New ...
func New(config Config) (*Wallet, error) {
if config.Path == "" {
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
}

// m/44
bipKey, err := newChild(masterKey, 44)
if err != nil {
return nil, err
}

// m/44/60
coinKey, err := newChild(bipKey, 60)
if err != nil {
return nil, err
}

// m/44/60/0
accountKey, err := newChild(coinKey, 0)
if err != nil {
return nil, err
}

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

address, err := pubKey.Child(uint32(0))
if err != nil {
return nil, err
}

privateKey, err := address.ECPrivKey()
privateKeyECDSA := privateKey.ToECDSA()
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")
}

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

return wallet, nil
}

// PrivateKey ...
func (s Wallet) PrivateKey() *ecdsa.PrivateKey {
return s.privateKey
}

// PrivateKeyBytes ...
func (s Wallet) PrivateKeyBytes() []byte {
return crypto.FromECDSA(s.PrivateKey())
}

// PrivateKeyHex ...
func (s Wallet) PrivateKeyHex() string {
return hexutil.Encode(s.PrivateKeyBytes())[2:]
}

// PublicKey ...
func (s Wallet) PublicKey() *ecdsa.PublicKey {
return s.publicKey
}

// PublicKeyBytes ...
func (s Wallet) PublicKeyBytes() []byte {
return crypto.FromECDSAPub(s.PublicKey())
}

// PublicKeyHex ...
func (s Wallet) PublicKeyHex() string {
return hexutil.Encode(s.PublicKeyBytes())[4:]
}

// Address ...
func (s Wallet) Address() common.Address {
return crypto.PubkeyToAddress(*s.publicKey)
}

// AddressHex ...
func (s Wallet) AddressHex() string {
return s.Address().Hex()
}

// Path ...
func (s Wallet) Path() string {
return s.path
}

// Mnemonic ...
func (s Wallet) Mnemonic() string {
return s.mnemonic
}
34 changes: 34 additions & 0 deletions hdwallet_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package hdwallet

import (
"fmt"
"log"
"testing"
)

func TestNew(t *testing.T) {
mnemonic := "tag volcano eight thank tide danger coast health above argue embrace heavy"
/*
seed, err := bip32.NewSeed()
if err != nil {
log.Fatalln("Error generating seed:", err)
}
*/
//seed := bip39.NewSeed(mnemonic, "")

wallet, err := New(Config{
Mnemonic: mnemonic,
Path: "",
})
if err != nil {
log.Fatal(err)
}

fmt.Println(wallet.PrivateKeyHex())
fmt.Println("")
fmt.Println(wallet.PublicKeyHex())
fmt.Println("")
fmt.Println(wallet.AddressHex())
fmt.Println("")
fmt.Println(wallet.Path())
}

0 comments on commit 66d224c

Please sign in to comment.