func (w *Wallet) Stop() {
	w.quitMu.Lock()
	quit := w.quit
	w.quitMu.Unlock()
	select {
	case <-quit:
	default:
		close(quit)
		w.chainClientLock.Lock()
		if w.chainClient != nil {
			w.chainClient.Stop()
			w.chainClient = nil
		}
		w.chainClientLock.Unlock()
	}
}
Stop signals all wallet goroutines to shutdown.
package wallet
import (
	"bytes"
	"encoding/hex"
	"errors"
	"fmt"
	"sort"
	"strings"
	"sync"
	"time"
	"golang.org/x/net/proxy"
	"github.com/davecgh/go-spew/spew"
	"github.com/gcash/bchd/bchec"
	"github.com/gcash/bchd/blockchain"
	"github.com/gcash/bchd/btcjson"
	"github.com/gcash/bchd/chaincfg"
	"github.com/gcash/bchd/chaincfg/chainhash"
	"github.com/gcash/bchd/txscript"
	"github.com/gcash/bchd/wire"
	"github.com/gcash/bchutil"
	"github.com/gcash/bchutil/hdkeychain"
	"github.com/gcash/bchwallet/chain"
	"github.com/gcash/bchwallet/waddrmgr"
	"github.com/gcash/bchwallet/wallet/txauthor"
	"github.com/gcash/bchwallet/wallet/txrules"
	"github.com/gcash/bchwallet/walletdb"
	"github.com/gcash/bchwallet/walletdb/migration"
	"github.com/gcash/bchwallet/wtxmgr"
)
const (
	InsecurePubPassphrase = "public"
	walletDbWatchingOnlyName = "wowallet.db"
	recoveryBatchSize = 2000
)
var (
	ErrNotSynced = errors.New("wallet is not synchronized with the chain server")
	ErrWalletShuttingDown = errors.New("wallet shutting down")
	waddrmgrNamespaceKey = []byte("waddrmgr")
	wtxmgrNamespaceKey   = []byte("wtxmgr")
)
type Wallet struct {
	publicPassphrase []byte
	db      walletdb.DB
	Manager *waddrmgr.Manager
	TxStore *wtxmgr.Store
	chainClient        chain.Interface
	chainClientLock    sync.Mutex
	chainClientSynced  bool
	chainClientSyncMtx sync.Mutex
	lockedOutpoints map[wire.OutPoint]struct{}
	recoveryWindow uint32
	rescanAddJob        chan *RescanJob
	rescanBatch         chan *rescanBatch
	rescanNotifications chan interface{}  
	rescanProgress      chan *RescanProgressMsg
	rescanFinished      chan *RescanFinishedMsg
	recoveryProgess chan *RecoveryProgessMsg
	createTxRequests chan createTxRequest
	unlockRequests     chan unlockRequest
	lockRequests       chan struct{}
	holdUnlockRequests chan chan heldUnlock
	lockState          chan bool
	changePassphrase   chan changePassphraseRequest
	changePassphrases  chan changePassphrasesRequest
	reorganizingLock sync.Mutex
	reorganizeToHash chainhash.Hash
	reorganizing     bool
	NtfnServer *NotificationServer
	chainParams *chaincfg.Params
	wg          sync.WaitGroup
	started bool
	quit    chan struct{}
	quitMu  sync.Mutex
	recoveryInterruptChan chan struct{}
	filterInterruptChans  []chan struct{}
	recoveryLock          sync.Mutex
	proxyDialer proxy.Dialer
}
func (w *Wallet) Start() {
	w.quitMu.Lock()
	select {
	case <-w.quit:
		w.WaitForShutdown()
		w.quit = make(chan struct{})
	default:
		if w.started {
			w.quitMu.Unlock()
			return
		}
		w.started = true
	}
	w.quitMu.Unlock()
	w.wg.Add(2)
	go w.txCreator()
	go w.walletLocker()
	go w.recoveryInterruptHandler()
}
func (w *Wallet) recoveryInterruptHandler() {
	for {
		select {
		case <-w.quit:
			return
		case <-w.recoveryInterruptChan:
			w.recoveryLock.Lock()
			for _, c := range w.filterInterruptChans {
				close(c)
			}
			w.filterInterruptChans = []chan struct{}{}
			w.recoveryLock.Unlock()
		}
	}
}
func (w *Wallet) SynchronizeRPC(chainClient chain.Interface) {
	w.quitMu.Lock()
	select {
	case <-w.quit:
		w.quitMu.Unlock()
		return
	default:
	}
	w.quitMu.Unlock()
	w.chainClientLock.Lock()
	if w.chainClient != nil {
		w.chainClientLock.Unlock()
		return
	}
	w.chainClient = chainClient
	switch cc := chainClient.(type) {
	case *chain.NeutrinoClient:
		cc.SetStartTime(w.Manager.Birthday())
	case *chain.BitcoindClient:
		cc.SetBirthday(w.Manager.Birthday())
	}
	w.chainClientLock.Unlock()
	w.wg.Add(4)
	go w.handleChainNotifications()
	go w.rescanBatchHandler()
	go w.rescanProgressHandler()
	go w.rescanRPCHandler()
}
func (w *Wallet) requireChainClient() (chain.Interface, error) {
	w.chainClientLock.Lock()
	chainClient := w.chainClient
	w.chainClientLock.Unlock()
	if chainClient == nil {
		return nil, errors.New("blockchain RPC is inactive")
	}
	return chainClient, nil
}
func (w *Wallet) ChainClient() chain.Interface {
	w.chainClientLock.Lock()
	chainClient := w.chainClient
	w.chainClientLock.Unlock()
	return chainClient
}
func (w *Wallet) quitChan() <-chan struct{} {
	w.quitMu.Lock()
	c := w.quit
	w.quitMu.Unlock()
	return c
}