Skip to content

Commit

Permalink
Merge 92a8782 into 24cad95
Browse files Browse the repository at this point in the history
  • Loading branch information
mauricio1802 committed Dec 1, 2019
2 parents 24cad95 + 92a8782 commit 6fcc0fa
Show file tree
Hide file tree
Showing 9 changed files with 158 additions and 37 deletions.
126 changes: 110 additions & 16 deletions src/coin/skycoin/models/wallet.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,10 @@ import (
var logWallet = logging.MustGetLogger("Skycoin Wallet")

const (
Sky = params.SkycoinTicker
CoinHour = params.CoinHoursTicker
CalculatedHour = params.CalculatedHoursTicker
WalletTypeDeterministic = "deterministic"
WalletTypeCollection = "collection"
WalletTypeBip44 = "bip44"

WalletTypeXPub = "xpub"
Sky = params.SkycoinTicker
CoinHour = params.CoinHoursTicker
CalculatedHour = params.CalculatedHoursTicker

walletExt = ".wlt"
WalletTimestampFormat = "2006_01_02"

Expand Down Expand Up @@ -72,6 +68,7 @@ type SkycoinRemoteWallet struct {
poolSection string
}

// ListWallets returns an iterator over wallets in the set
func (wltSrv *SkycoinRemoteWallet) ListWallets() core.WalletIterator {
logWallet.Info("Listing wallets")
c, err := NewSkycoinApiClient(wltSrv.poolSection)
Expand All @@ -97,7 +94,8 @@ func (wltSrv *SkycoinRemoteWallet) ListWallets() core.WalletIterator {
return NewSkycoinWalletIterator(wallets)
}

func (wltSrv *SkycoinRemoteWallet) CreateWallet(label string, seed string, IsEncrypted bool, pwd core.PasswordReader, scanAddressesN int) (core.Wallet, error) {
// CreateWallet instantiates a new wallet given account seed
func (wltSrv *SkycoinRemoteWallet) CreateWallet(label string, seed string, wltType string, IsEncrypted bool, pwd core.PasswordReader, scanAddressesN int) (core.Wallet, error) {
logWallet.Info("Creating wallet")
wlt := &RemoteWallet{} //nolint megacheck False negative
c, err := NewSkycoinApiClient(wltSrv.poolSection)
Expand All @@ -113,7 +111,7 @@ func (wltSrv *SkycoinRemoteWallet) CreateWallet(label string, seed string, IsEnc
return nil, err
}
wltOpt := api.CreateWalletOptions{}
wltOpt.Type = WalletTypeDeterministic
wltOpt.Type = wltType
wltOpt.Seed = seed
wltOpt.Password = password
wltOpt.Encrypt = true
Expand All @@ -129,7 +127,7 @@ func (wltSrv *SkycoinRemoteWallet) CreateWallet(label string, seed string, IsEnc
wlt = walletResponseToWallet(*wltR)
} else {
wltOpt := api.CreateWalletOptions{}
wltOpt.Type = WalletTypeDeterministic
wltOpt.Type = wltType
wltOpt.Seed = seed
wltOpt.Encrypt = false
wltOpt.Label = label
Expand All @@ -147,6 +145,19 @@ func (wltSrv *SkycoinRemoteWallet) CreateWallet(label string, seed string, IsEnc
return wlt, nil
}

// DefaultWalletType default wallet type
func (wltSrv *SkycoinRemoteWallet) DefaultWalletType() string {
return wallet.WalletTypeBip44
}

// SupportedWalletTypes list supported wallet type names
func (wltSrv *SkycoinRemoteWallet) SupportedWalletTypes() []string {
return []string{
wallet.WalletTypeDeterministic,
wallet.WalletTypeBip44,
}
}

func (wltSrv *SkycoinRemoteWallet) Encrypt(walletName string, pwd core.PasswordReader) {
logWallet.Info("Encrypting remote wallet")
c, err := NewSkycoinApiClient(wltSrv.poolSection)
Expand Down Expand Up @@ -205,6 +216,8 @@ func (wltSrv *SkycoinRemoteWallet) IsEncrypted(walletName string) (bool, error)
}
return wlt.Meta.Encrypted, nil
}

// GetWallet to lookup wallet by ID
func (wltSrv *SkycoinRemoteWallet) GetWallet(id string) core.Wallet {
logWallet.Info("Getting remote wallet")
c, err := NewSkycoinApiClient(wltSrv.poolSection)
Expand Down Expand Up @@ -802,7 +815,7 @@ func (wltSrv *SkycoinLocalWallet) GetWallet(id string) core.Wallet {
}
}

func (wltSrv *SkycoinLocalWallet) CreateWallet(label string, seed string, IsEncrypted bool, pwd core.PasswordReader, scanAddressesN int) (core.Wallet, error) {
func (wltSrv *SkycoinLocalWallet) CreateWallet(label string, seed string, wltType string, IsEncrypted bool, pwd core.PasswordReader, scanAddressesN int) (core.Wallet, error) {
logWallet.Info("Creating Skycoin local wallet")
password, err := pwd("Insert Password")

Expand All @@ -812,11 +825,12 @@ func (wltSrv *SkycoinLocalWallet) CreateWallet(label string, seed string, IsEncr
}

passwordByte := []byte(password)

opts := wallet.Options{
Label: label,
Seed: seed,
Encrypt: IsEncrypted,
Type: WalletTypeDeterministic,
Type: wltType,
Password: passwordByte,
}
wltName := wltSrv.newUnicWalletFilename()
Expand Down Expand Up @@ -851,6 +865,19 @@ func (wltSrv *SkycoinLocalWallet) CreateWallet(label string, seed string, IsEncr
}, nil
}

// DefaultWalletType default wallet type
func (wltSrv *SkycoinLocalWallet) DefaultWalletType() string {
return wallet.WalletTypeBip44
}

// SupportedWalletTypes list supported wallet type names
func (wltSrv *SkycoinLocalWallet) SupportedWalletTypes() []string {
return []string{
wallet.WalletTypeDeterministic,
wallet.WalletTypeBip44,
}
}

func (wltSrv *SkycoinLocalWallet) newUnicWalletFilename() string {
name := ""
for {
Expand Down Expand Up @@ -1290,19 +1317,76 @@ func (wlt LocalWallet) Spend(unspent, new []core.TransactionOutput, change core.

return createTransaction(nil, new, unspent, change, options, createTxnFunc)
}

func (wlt *LocalWallet) GenAddresses(addrType core.AddressType, startIndex, count uint32, pwd core.PasswordReader) core.AddressIterator {

if addrType != core.AccountAddress && addrType != core.ChangeAddress {
logWallet.Error("Incorret address type")
return nil
}
logWallet.Info("Generating addresses in local wallet")
walletName := filepath.Join(wlt.WalletDir, wlt.Id)
walletLoaded, err := wallet.Load(walletName)
if err != nil {
logWallet.WithError(err).WithField("filename", walletName).Error("Call to wallet.Load(filename) inside GenAddresses failed.")
return nil
}

if addrType == core.ChangeAddress && walletLoaded.Type() != wallet.WalletTypeBip44 {
logWallet.Error("Incorrect address type")
return nil
}

genAddr := func(w wallet.Wallet, n uint64) ([]cipher.Addresser, error) {
return w.GenerateAddresses(n)
}

addressCount := walletLoaded.EntriesLen()

getAddrs := func(w wallet.Wallet) []cipher.Addresser {
return w.GetAddresses()[startIndex : startIndex+count]
}

if walletLoaded.Type() == wallet.WalletTypeBip44 {
addressCount = len((*(walletLoaded.(*wallet.Bip44Wallet))).ExternalEntries)

getAddrs = func(w wallet.Wallet) []cipher.Addresser {
addresser := make([]cipher.Addresser, 0)
for _, entry := range (*(walletLoaded.(*wallet.Bip44Wallet))).ExternalEntries[startIndex : startIndex+count] {
addresser = append(addresser, entry.Address)
}
return addresser
}

}
if addrType == core.ChangeAddress {
addressCount = len((*(walletLoaded.(*wallet.Bip44Wallet))).ChangeEntries)

genAddr = func(w wallet.Wallet, n uint64) ([]cipher.Addresser, error) {
addresser := make([]cipher.Addresser, 0)
for i := uint64(0); i < n; i++ {
addrs, err := w.(*wallet.Bip44Wallet).GenerateChangeEntry()
if err != nil {
return nil, err
}
addresser = append(addresser, addrs.Address)
}
return addresser, nil
}

getAddrs = func(w wallet.Wallet) []cipher.Addresser {
addresser := make([]cipher.Addresser, 0)
for _, entry := range (*(walletLoaded.(*wallet.Bip44Wallet))).ChangeEntries[startIndex : startIndex+count] {
addresser = append(addresser, entry.Address)
}
return addresser
}
}

if uint32(addressCount) < (startIndex + count) {
diff := (startIndex + count) - uint32(addressCount)
genAddressesInFile := func(w wallet.Wallet, n uint64) ([]cipher.Addresser, error) {
return w.GenerateAddresses(n)
return genAddr(w, n)
}

if walletLoaded.IsEncrypted() {
Expand All @@ -1316,8 +1400,11 @@ func (wlt *LocalWallet) GenAddresses(addrType core.AddressType, startIndex, coun
var addrs []cipher.Addresser
if err := wallet.GuardUpdate(w, passwordBytes, func(wlt wallet.Wallet) error {
var err error
addrs, err = wlt.GenerateAddresses(n)

addrs, err = genAddr(wlt, n)

logWallet.WithError(err).WithField("num", n).Error("Call to wlt.GenerateAddresses(num) inside wallet.GuardUpdate failed")

return err
}); err != nil {
logWallet.WithError(err).Error("Call to wallet.GuardUpdate inside genAddressesInFile failed")
Expand Down Expand Up @@ -1346,14 +1433,15 @@ func (wlt *LocalWallet) GenAddresses(addrType core.AddressType, startIndex, coun
return nil
}

addrs := walletLoaded.GetAddresses()[startIndex : startIndex+count]
addrs := getAddrs(walletLoaded)
skyAddrs := make([]core.Address, 0)
for _, addr := range addrs {
skyAddrs = append(skyAddrs, &SkycoinAddress{address: addr.String()})
}
return NewSkycoinAddressIterator(skyAddrs)

}

func (wlt *LocalWallet) GetCryptoAccount() core.CryptoAccount {
logWallet.Info("Getting CryptoAccount from local wallet")
return wlt
Expand Down Expand Up @@ -1461,4 +1549,10 @@ var (
_ core.Wallet = &RemoteWallet{}
_ skytypes.SkycoinWallet = &LocalWallet{}
_ skytypes.SkycoinWallet = &RemoteWallet{}
_ core.WalletEnv = &WalletNode{}
_ core.WalletEnv = &WalletDirectory{}
_ core.WalletSet = &SkycoinRemoteWallet{}
_ core.WalletStorage = &SkycoinRemoteWallet{}
_ core.WalletSet = &SkycoinLocalWallet{}
_ core.WalletStorage = &SkycoinLocalWallet{}
)
21 changes: 16 additions & 5 deletions src/coin/skycoin/models/wallet_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"github.com/skycoin/skycoin/src/coin"
"github.com/skycoin/skycoin/src/readable"
"github.com/skycoin/skycoin/src/testutil"
"github.com/skycoin/skycoin/src/wallet"
"github.com/stretchr/testify/require"
)

Expand Down Expand Up @@ -89,15 +90,15 @@ func TestSkycoinRemoteWalletCreateWallet(t *testing.T) {
seed, label, pwd, scanN := "seed", "label", "pwd", 666

wltOpt1 := api.CreateWalletOptions{
Type: WalletTypeDeterministic,
Type: wallet.WalletTypeDeterministic,
Seed: seed,
Label: label,
Password: pwd,
ScanN: scanN,
Encrypt: true,
}
wltOpt2 := api.CreateWalletOptions{
Type: WalletTypeDeterministic,
Type: wallet.WalletTypeDeterministic,
Seed: seed,
Label: label,
ScanN: scanN,
Expand All @@ -112,12 +113,12 @@ func TestSkycoinRemoteWalletCreateWallet(t *testing.T) {
return "pwd", nil
}

wlt1, err := wltSrv.CreateWallet(label, seed, true, pwdReader, scanN)
wlt1, err := wltSrv.CreateWallet(label, seed, wallet.WalletTypeDeterministic, true, pwdReader, scanN)
require.NoError(t, err)
require.Equal(t, "walletEncrypted", wlt1.GetLabel())
require.Equal(t, "FiberCrypto", wlt1.GetId())

wlt2, err := wltSrv.CreateWallet(label, seed, false, pwdReader, scanN)
wlt2, err := wltSrv.CreateWallet(label, seed, wallet.WalletTypeDeterministic, false, pwdReader, scanN)
require.NoError(t, err)
require.Equal(t, "walletNonEncrypted", wlt2.GetLabel())
require.Equal(t, "FiberCrypto", wlt2.GetId())
Expand Down Expand Up @@ -800,7 +801,7 @@ func makeLocalWalletsFromKeyData(t *testing.T, keysData []KeyData) []core.Wallet
var err error
if w, isFound = walletsCache[kd.Mnemonic]; !isFound {
if w = walletSet.GetWallet(walletID); w == nil {
w, err = walletSet.CreateWallet(walletID, kd.Mnemonic, false, func(string) (string, error) { return "", nil }, 0)
w, err = walletSet.CreateWallet(walletID, kd.Mnemonic, wallet.WalletTypeDeterministic, false, func(string) (string, error) { return "", nil }, 0)
require.NoError(t, err)
}
walletsCache[kd.Mnemonic] = w
Expand Down Expand Up @@ -1190,3 +1191,13 @@ func TestLocalWalletSpend(t *testing.T) {
require.Equal(t, uint64(sky), val)
require.Equal(t, crtTxn.Transaction.TxID, ret.GetId())
}

func TestSkycoinWalletTypes(t *testing.T) {
var wltSet core.WalletSet = &SkycoinRemoteWallet{}
require.Equal(t, wallet.WalletTypeBip44, wltSet.DefaultWalletType())
require.Equal(t, []string{wallet.WalletTypeDeterministic, wallet.WalletTypeBip44}, wltSet.SupportedWalletTypes())

wltSet = &SkycoinLocalWallet{}
require.Equal(t, wallet.WalletTypeBip44, wltSet.DefaultWalletType())
require.Equal(t, []string{wallet.WalletTypeDeterministic, wallet.WalletTypeBip44}, wltSet.SupportedWalletTypes())
}
6 changes: 5 additions & 1 deletion src/core/wallet.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,11 @@ type WalletSet interface {
// GetWallet to lookup wallet by ID
GetWallet(id string) Wallet
// CreateWallet instantiates a new wallet given account seed
CreateWallet(name string, seed string, isEncryptrd bool, pwd PasswordReader, scanAddressesN int) (Wallet, error)
CreateWallet(name string, seed string, walletType string, isEncryptrd bool, pwd PasswordReader, scanAddressesN int) (Wallet, error)
// DefaultWalletType default wallet type
DefaultWalletType() string
// SupportedWalletTypes list supported wallet type names
SupportedWalletTypes() []string
}

// WalletStorage provides access to the underlying wallets data store
Expand Down
2 changes: 1 addition & 1 deletion src/models/pending/Pending.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ package pending
func init() {
PendingTransactionList_QmlRegisterType2("PendingModels", 1, 0, "QPendingList")
PendingTransaction_QmlRegisterType2("PendingModels", 1, 0, "QPendingTransaction")
}
}
13 changes: 7 additions & 6 deletions src/models/walletsManager.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ type WalletManager struct {
_ func(string) `slot:"updateAddresses"`
_ func() `slot:"updateWallets"`
_ func() `constructor:"init"`
_ func(seed string, label string, password string, scanN int) *QWallet `slot:"createEncryptedWallet"`
_ func(seed string, label string, scanN int) *QWallet `slot:"createUnencryptedWallet"`
_ func(seed string, label string, walletType string, password string, scanN int) *QWallet `slot:"createEncryptedWallet"`
_ func(seed string, label string, walletType string, scanN int) *QWallet `slot:"createUnencryptedWallet"`
_ func(entropy int) string `slot:"getNewSeed"`
_ func(seed string) int `slot:"verifySeed"`
_ func(id string, n int, password string) `slot:"newWalletAddress"`
Expand Down Expand Up @@ -486,12 +486,13 @@ func (walletM *WalletManager) signTxn(id, source, password string, index []int,
return qTxn
}

func (walletM *WalletManager) createEncryptedWallet(seed, label, password string, scanN int) *QWallet {
func (walletM *WalletManager) createEncryptedWallet(seed, label, wltType, password string, scanN int) *QWallet {
logWalletManager.Info("Creating encrypted wallet")
pwd := func(message string) (string, error) {
return password, nil
}
wlt, err := walletM.WalletEnv.GetWalletSet().CreateWallet(label, seed, true, pwd, scanN)
fmt.Println("WALLET TYPE ", wltType)
wlt, err := walletM.WalletEnv.GetWalletSet().CreateWallet(label, seed, wltType, true, pwd, scanN)
if err != nil {
logWalletManager.WithError(err).Error("Couldn't create encrypted wallet")
return nil
Expand All @@ -502,13 +503,13 @@ func (walletM *WalletManager) createEncryptedWallet(seed, label, password string

}

func (walletM *WalletManager) createUnencryptedWallet(seed, label string, scanN int) *QWallet {
func (walletM *WalletManager) createUnencryptedWallet(seed, label, wltType string, scanN int) *QWallet {
logWalletManager.Info("Creating encrypted wallet")
pwd := func(message string) (string, error) {
return "", nil
}

wlt, err := walletM.WalletEnv.GetWalletSet().CreateWallet(label, seed, false, pwd, scanN)
wlt, err := walletM.WalletEnv.GetWalletSet().CreateWallet(label, seed, wltType, false, pwd, scanN)
if err != nil {
logWalletManager.WithError(err).Error("Couldn't create unencrypted wallet")
return nil
Expand Down
Loading

0 comments on commit 6fcc0fa

Please sign in to comment.