Skip to content

Commit

Permalink
Update logic seed type on restore wallet, update logic when backup th…
Browse files Browse the repository at this point in the history
…e wallet
  • Loading branch information
JustinBeBoy committed Mar 29, 2024
1 parent 88ced32 commit 104387d
Show file tree
Hide file tree
Showing 7 changed files with 73 additions and 67 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ require (
github.com/nxadm/tail v1.4.8
github.com/onsi/ginkgo v1.15.0
github.com/onsi/gomega v1.10.5
github.com/tyler-smith/go-bip39 v1.1.0
github.com/yeqown/go-qrcode v1.5.1
go.etcd.io/bbolt v1.3.8
golang.org/x/crypto v0.11.0
Expand Down Expand Up @@ -197,7 +198,6 @@ require (
github.com/tadvi/systray v0.0.0-20190226123456-11a2b8fa57af // indirect
github.com/tklauser/go-sysconf v0.3.5 // indirect
github.com/tklauser/numcpus v0.2.2 // indirect
github.com/tyler-smith/go-bip39 v1.1.0 // indirect
github.com/urfave/cli/v2 v2.17.2-0.20221006022127-8f469abc00aa // indirect
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
github.com/yeqown/reedsolomon v1.0.0 // indirect
Expand Down
14 changes: 12 additions & 2 deletions libwallet/assets/wallet/wallet_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package wallet

import (
"context"
"encoding/hex"
"fmt"
"net"
"os"
Expand Down Expand Up @@ -203,11 +204,11 @@ func generateSeed(assetType utils.AssetType, wordSeedType WordSeedType) (v strin
}

if len(entropy) > 0 {
//Use bip39 for 12-word seeds and 24-word seeds
if wordSeedType == WordSeed33 {
return walletseed.EncodeMnemonic(entropy), nil
}
// Create Seed phrase from entropy
// Use bip39 for 12-word seeds and 24-word seeds
seedPhrase, err := bip39.NewMnemonic(entropy)
if err != nil {
return "", err
Expand All @@ -232,7 +233,16 @@ func DecodeSeedMnemonic(seedMnemonic string, assetType utils.AssetType, seedType
if seedType == WordSeed33 {
hashedSeed, err = walletseed.DecodeUserInput(seedMnemonic)
} else {
hashedSeed, err = bip39.EntropyFromMnemonic(seedMnemonic)
words := strings.Split(strings.TrimSpace(seedMnemonic), " ")
if len(words) == 1 {
var err error
hashedSeed, err = hex.DecodeString(words[0])
if err != nil {
return nil, err
}
} else {
hashedSeed, err = bip39.EntropyFromMnemonic(seedMnemonic)
}
}
default:
err = fmt.Errorf("%v: (%v)", utils.ErrAssetUnknown, assetType)
Expand Down
41 changes: 24 additions & 17 deletions ui/page/components/restore_page.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,24 +172,31 @@ func (pg *Restore) seedInputLayout(gtx C) D {
pg.seedInputEditor.Hint = values.String(values.StrEnterWalletHex)
pg.confirmSeedButton.Text = values.String(values.StrValidateWalHex)
}
return layout.Inset{
Top: values.MarginPadding16,
}.Layout(gtx, func(gtx C) D {
return pg.Theme.Card().Layout(gtx, func(gtx C) D {
return HorizontalInset(values.MarginPadding16).Layout(gtx, func(gtx layout.Context) layout.Dimensions {
return layout.Flex{Axis: layout.Vertical}.Layout(gtx,
layout.Rigid(layout.Spacer{Height: values.MarginPadding24}.Layout),
layout.Rigid(pg.seedInputEditor.Layout),
layout.Rigid(func(gtx C) D {
gtx.Constraints.Min.X = gtx.Constraints.Max.X
return layout.E.Layout(gtx, func(gtx C) D {
return VerticalInset(values.MarginPadding16).Layout(gtx, pg.confirmSeedButton.Layout)
})
}),
)
return layout.Stack{}.Layout(gtx,
layout.Expanded(func(gtx layout.Context) layout.Dimensions {
return layout.Inset{
Top: values.MarginPadding56,
}.Layout(gtx, func(gtx C) D {
return pg.Theme.Card().Layout(gtx, func(gtx C) D {
return HorizontalInset(values.MarginPadding16).Layout(gtx, func(gtx layout.Context) layout.Dimensions {
return layout.Flex{Axis: layout.Vertical}.Layout(gtx,
layout.Rigid(layout.Spacer{Height: values.MarginPadding24}.Layout),
layout.Rigid(pg.seedInputEditor.Layout),
layout.Rigid(func(gtx C) D {
gtx.Constraints.Min.X = gtx.Constraints.Max.X
return layout.E.Layout(gtx, func(gtx C) D {
return VerticalInset(values.MarginPadding16).Layout(gtx, pg.confirmSeedButton.Layout)
})
}),
)
})
})
})
})
})
}),
layout.Expanded(func(gtx layout.Context) layout.Dimensions {
return layout.E.Layout(gtx, pg.seedTypeDropdown.Layout)
}),
)
}

func (pg *Restore) indexLayout(gtx C) D {
Expand Down
47 changes: 17 additions & 30 deletions ui/page/components/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"strings"
"time"

"decred.org/dcrwallet/v3/pgpwordlist"
"gioui.org/layout"
"gioui.org/unit"

Expand All @@ -20,6 +21,7 @@ import (
"github.com/crypto-power/cryptopower/ui/values"
"github.com/decred/dcrd/dcrutil/v4"
"github.com/ltcsuite/ltcd/ltcutil"
"github.com/tyler-smith/go-bip39"
)

const (
Expand Down Expand Up @@ -65,40 +67,25 @@ func RetryFunc(retryAttempts int, sleepDur time.Duration, funcDesc string, errFu
// seedtest
func SeedWordsToHex(seedWords string, wordSeedType sharedW.WordSeedType) (string, error) {
var seedHex string
wordList := wordSeedType.AllSeeds()
wordIndexes := make(map[string]uint16, len(wordList))
for i, word := range wordList {
wordIndexes[strings.ToLower(word)] = uint16(i)
}

words := strings.Split(strings.TrimSpace(seedWords), " ")
seedByte := make([]byte, len(words))
idx := 0
for _, w := range words {
w = strings.TrimSpace(w)
if w == "" {
continue
}
b, ok := wordIndexes[strings.ToLower(w)]
if !ok {
return seedHex, fmt.Errorf("word %v is not in the PGP word list", w)
}
if int(b%2) != idx%2 {
return seedHex, fmt.Errorf("word %v is not valid at position %v, "+
"check for missing words", w, idx)
var seedByte []byte
var err error
if wordSeedType == sharedW.WordSeed33 {
words := strings.Split(strings.TrimSpace(seedWords), " ")
seedByte, err = pgpwordlist.DecodeMnemonics(words)
if checksumByte(seedByte[:len(seedByte)-1]) != seedByte[len(seedByte)-1] {
return seedHex, fmt.Errorf("seed checksum mismatch")
}
seedByte[idx] = byte(b / 2)
idx++
}
seedByte = seedByte[:len(seedByte)-1]

seedByte = seedByte[:idx]
if checksumByte(seedByte[:len(seedByte)-1]) != seedByte[len(seedByte)-1] {
return seedHex, fmt.Errorf("seed checksum mismatch")
if len(seedByte) < MinSeedBytes || len(seedByte) > MaxSeedBytes {
return seedHex, fmt.Errorf("invalid seed bytes length")
}
} else {
seedByte, err = bip39.EntropyFromMnemonic(seedWords)
}
seedByte = seedByte[:len(seedByte)-1]

if len(seedByte) < MinSeedBytes || len(seedByte) > MaxSeedBytes {
return seedHex, fmt.Errorf("invalid seed bytes length")
if err != nil {
return "", err
}

seedHex = hex.EncodeToString(seedByte)
Expand Down
28 changes: 15 additions & 13 deletions ui/page/seedbackup/save_seed.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ func NewSaveSeedPage(l *load.Load, wallet sharedW.Asset, redirect Redirectfunc)
return pg
}

func (pg *SaveSeedPage) setWordSeedType(words string) {
func (pg *SaveSeedPage) setWordSeedType(words []string) {
switch len(words) {
case 12:
pg.wordSeedType = sharedW.WordSeed12
Expand Down Expand Up @@ -130,9 +130,8 @@ func (pg *SaveSeedPage) OnNavigatedTo() {
}
m.Dismiss()
pg.seed = seed
pg.setWordSeedType(seed)

wordList := strings.Split(seed, " ")
pg.setWordSeedType(wordList)
if pg.IsMobileView() {
pg.rows = divideWordsIntoRows(wordList, 2)
} else {
Expand Down Expand Up @@ -215,12 +214,12 @@ func (pg *SaveSeedPage) Layout(gtx C) D {
return pg.Theme.List(pg.pageContainer).Layout(gtx, 1, func(gtx C, i int) D {
return layout.Flex{Axis: layout.Vertical}.Layout(gtx,
layout.Rigid(func(gtx C) D {
label := pg.Theme.Label(values.TextSize16, values.String(values.StrWriteDownAll33Words))
label := pg.Theme.Label(values.TextSize16, values.StringF(values.String(values.StrWriteDownAllXWords), pg.wordSeedType.ToInt()))
label.Color = pg.Theme.Color.GrayText1
return label.Layout(gtx)
}),
layout.Rigid(func(gtx C) D {
label := pg.Theme.Label(values.TextSize14, values.String(values.StrYourSeedWords))
label := pg.Theme.Label(values.TextSize14, values.StringF(values.String(values.StrYourSeedWords), pg.wordSeedType.ToInt()))
label.Color = pg.Theme.Color.GrayText1
return cryptomaterial.LinearLayout{
Width: cryptomaterial.MatchParent,
Expand All @@ -234,7 +233,7 @@ func (pg *SaveSeedPage) Layout(gtx C) D {
layout.Rigid(label.Layout),
layout.Rigid(func(gtx C) D {
return pg.Theme.List(pg.seedList).Layout(gtx, len(pg.rows), func(gtx C, index int) D {
return pg.desktopSeedRow(gtx, pg.rows[index])
return pg.seedRow(gtx, pg.rows[index])
})
}),
)
Expand All @@ -251,25 +250,28 @@ func (pg *SaveSeedPage) Layout(gtx C) D {
return container(gtx, pg.IsMobileView(), *pg.Theme, layout, pg.infoText, pg.actionButton, true)
}

func (pg *SaveSeedPage) desktopSeedRow(gtx C, row saveSeedRow) D {
func (pg *SaveSeedPage) seedRow(gtx C, row saveSeedRow) D {
topMargin := values.MarginPadding8
if row.rowIndex == 1 {
if row.rowIndex == 0 {
topMargin = values.MarginPadding16
}

var flexChils []layout.FlexChild
itemIndex := row.rowIndex + 1
if pg.IsMobileView() {
itemWidth := gtx.Constraints.Max.X / 2 // Divide total width into 2 rows for mobile
addIndex := pg.wordSeedType.ToInt() / 2
flexChils = []layout.FlexChild{
seedItem(pg.Theme, itemWidth, row.rowIndex, row.word1),
seedItem(pg.Theme, itemWidth, row.rowIndex+17, row.word2),
seedItem(pg.Theme, itemWidth, itemIndex, row.word1),
seedItem(pg.Theme, itemWidth, itemIndex+addIndex, row.word2),
}
} else {
itemWidth := gtx.Constraints.Max.X / 3 // Divide total width into 3 rows for deskop
addIndex := pg.wordSeedType.ToInt() / 3
flexChils = []layout.FlexChild{
seedItem(pg.Theme, itemWidth, row.rowIndex, row.word1),
seedItem(pg.Theme, itemWidth, row.rowIndex+11, row.word2),
seedItem(pg.Theme, itemWidth, row.rowIndex+22, row.word3),
seedItem(pg.Theme, itemWidth, itemIndex, row.word1),
seedItem(pg.Theme, itemWidth, itemIndex+addIndex, row.word2),
seedItem(pg.Theme, itemWidth, itemIndex+(addIndex*2), row.word3),
}
}
return cryptomaterial.LinearLayout{
Expand Down
6 changes: 3 additions & 3 deletions ui/values/localizable/en.go
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ const EN = `
"immatureRewards" = "Immature Rewards"
"immatureStakeGen" = "Immature Stake Gen"
"import" = "Import"
"importantSeedPhrase" = "The 33-word seed phrase is EXTREMELY IMPORTANT."
"importantSeedPhrase" = "The word seed phrase is EXTREMELY IMPORTANT."
"imported" = "imported"
"importExistingWallet" = "Import an existing wallet"
"importWatchingOnlyWallet" = "Import a watch-only wallet"
Expand Down Expand Up @@ -770,7 +770,7 @@ const EN = `
"whatIsDex" = "What is Decred Decentralized Exchange?"
"word" = "Word"
"wouldTradeCex" = "Would you like to trade on CEX?"
"writeDownAll33Words" = "Write down all 33 words in the correct order."
"writeDownAllXWords" = "Write down all %d words in the correct order."
"writeDownSeed" = "Write down seed phrase"
"wroteAllWords" = "I have written down all 33 words"
"xInputsConsumed" = "%d Inputs consumed"
Expand All @@ -782,7 +782,7 @@ const EN = `
"yes" = "Yes"
"yesterday" = "Yesterday"
"yourAddress" = "Your Address"
"yourSeedWord" = "Your 33-word seed phrase"
"yourSeedWord" = "Your %d-word seed phrase"
"yourself" = "Yourself"
"trade" = "Trade"
"setTradePassword" = "Set Trade Password"
Expand Down
2 changes: 1 addition & 1 deletion ui/values/strings.go
Original file line number Diff line number Diff line change
Expand Up @@ -880,7 +880,7 @@ const (
StrWhatToCallWallet = "whatToCallWallet"
StrWord = "word"
StrWouldTradeCex = "wouldTradeCex"
StrWriteDownAll33Words = "writeDownAll33Words"
StrWriteDownAllXWords = "writeDownAllXWords"
StrWriteDownSeed = "writeDownSeed"
StrWroteAllWords = "wroteAllWords"
StrXInputsConsumed = "xInputsConsumed"
Expand Down

0 comments on commit 104387d

Please sign in to comment.