import (
"encoding/json"
+ "fmt"
log "github.com/sirupsen/logrus"
"github.com/tendermint/go-wire/data/base58"
//SINGLE single sign
const SINGLE = 1
+//RecoveryIndex walletdb recovery cp number
+const RecoveryIndex = 5000
+
var walletKey = []byte("walletInfo")
var privKeyKey = []byte("keysInfo")
}
//NewWallet return a new wallet instance
-func NewWallet(walletDB db.DB, account *account.Manager, asset *asset.Registry, chain *protocol.Chain) (*Wallet, error) {
+func NewWallet(walletDB db.DB, account *account.Manager, asset *asset.Registry, chain *protocol.Chain, xpubs []pseudohsm.XPub) (*Wallet, error) {
w := &Wallet{
DB: walletDB,
AccountMgr: account,
keysInfo: make([]KeyInfo, 0),
}
- if err := w.loadWalletInfo(); err != nil {
+ if err := w.loadWalletInfo(xpubs); err != nil {
return nil, err
}
}
w.ImportPrivKey = w.getImportKeyFlag()
+
go w.walletUpdater()
return w, nil
//GetWalletInfo return stored wallet info and nil,if error,
//return initial wallet info and err
-func (w *Wallet) loadWalletInfo() error {
+func (w *Wallet) loadWalletInfo(xpubs []pseudohsm.XPub) error {
if rawWallet := w.DB.Get(walletKey); rawWallet != nil {
return json.Unmarshal(rawWallet, &w.status)
}
+ for i, v := range xpubs {
+ if err := w.ImportAccountXpubKey(i, v, RecoveryIndex); err != nil {
+ return err
+ }
+ }
+
block, err := w.chain.GetBlockByHeight(0)
if err != nil {
return err
//WalletUpdate process every valid block and reverse every invalid block which need to rollback
func (w *Wallet) walletUpdater() {
for {
- // config.GenesisBlock().hash
getRescanNotification(w)
checkRescanStatus(w)
for !w.chain.InMainChain(w.status.BestHeight, w.status.BestHash) {
return xpub, nil
}
+// ImportAccountXpubKey imports the account key in the Wallet Import Formt.
+func (w *Wallet) ImportAccountXpubKey(xpubIndex int, xpub pseudohsm.XPub, cpIndex uint64) error {
+ accountAlias := fmt.Sprintf("recovery_%d", xpubIndex)
+
+ if acc, _ := w.AccountMgr.FindByAlias(nil, accountAlias); acc != nil {
+ return account.ErrDuplicateAlias
+ }
+
+ newAccount, err := w.AccountMgr.Create(nil, []chainkd.XPub{xpub.XPub}, SINGLE, accountAlias, nil)
+ if err != nil {
+ return err
+ }
+
+ return w.recoveryAccountWalletDB(newAccount, &xpub, cpIndex, xpub.Alias)
+}
+
func (w *Wallet) recoveryAccountWalletDB(account *account.Account, XPub *pseudohsm.XPub, index uint64, keyAlias string) error {
if err := w.createProgram(account, XPub, index); err != nil {
return err
}
func (w *Wallet) rescanBlocks() {
- w.rescanProgress <- struct{}{}
+ select {
+ case <-w.rescanProgress:
+ w.rescanProgress <- struct{}{}
+ default:
+ return
+ }
}
//GetRescanStatus return key import rescan status
return nil
}
+ hsm, err := pseudohsm.New(config.KeysDir())
+ if err != nil {
+ cmn.Exit(cmn.Fmt("initialize HSM failed: %v", err))
+ }
+
if !config.Wallet.Disable {
+ xpubs, _ := hsm.ListKeys()
walletDB := dbm.NewDB("wallet", config.DBBackend, config.DBDir())
accounts = account.NewManager(walletDB, chain)
assets = asset.NewRegistry(walletDB, chain)
- wallet, err = w.NewWallet(walletDB, accounts, assets, chain)
+ wallet, err = w.NewWallet(walletDB, accounts, assets, chain, xpubs)
if err != nil {
log.WithField("error", err).Error("init NewWallet")
}
}
- hsm, err := pseudohsm.New(config.KeysDir())
- if err != nil {
- cmn.Exit(cmn.Fmt("initialize HSM failed: %v", err))
- }
bcReactor := bc.NewBlockchainReactor(chain, txPool, accounts, assets, sw, hsm, wallet, txFeed, accessTokens, config.Mining)
sw.AddReactor("BLOCKCHAIN", bcReactor)