func (p *PurchaseManager) NotificationHandler() {
	p.quitMtx.Lock()
	quit := p.quit
	p.quitMtx.Unlock()
	s1, s2 := make(chan struct{}), make(chan struct{})
	close(s1)  
out:
	for {
		select {
		case v, ok := <-p.ntfnChan:
			if !ok {
				break out
			}
			p.wg.Add(1)
			go func(s1, s2 chan struct{}) {
				defer p.wg.Done()
				select {
				case <-s1:  
				case <-quit:
					return
				}
				if v.IsKeyBlock {
						p.purchase(int64(v.NewHeight), int64(v.NewKeyHeight))
				}
				close(s2)  
			}(s1, s2)
			s1, s2 = s2, make(chan struct{})
		case <-quit:
			break out
		}
	}
	p.wg.Done()
}
NotificationHandler handles notifications, which trigger ticket purchases.
package ticketbuyer
import (
	"sync"
	"github.com/HcashOrg/hcashwallet/wallet"
)
type PurchaseManager struct {
	w          *wallet.Wallet
	purchaser  *TicketPurchaser
	ntfnChan   <-chan *wallet.MainTipChangedNotification
	passphrase []byte
	wg         sync.WaitGroup
	quitMtx    sync.Mutex
	quit       chan struct{}
}
func NewPurchaseManager(w *wallet.Wallet, purchaser *TicketPurchaser,
	ntfnChan <-chan *wallet.MainTipChangedNotification, passphrase []byte) *PurchaseManager {
	return &PurchaseManager{
		w:          w,
		purchaser:  purchaser,
		ntfnChan:   ntfnChan,
		passphrase: passphrase,
		quit:       make(chan struct{}),
	}
}
func (p *PurchaseManager) purchase(height int64, keyHeight int64) {
	err := p.w.Unlock(p.passphrase, nil)
	if err != nil {
		log.Errorf("Failed to purchase tickets this round: %v", err)
		return
	}
	purchaseInfo, err := p.purchaser.Purchase(height, keyHeight)
	if err != nil {
		log.Errorf("Failed to purchase tickets this round: %v", err)
		return
	}
	log.Debugf("Purchased %v tickets this round", purchaseInfo.Purchased)
}
func (p *PurchaseManager) Purchaser() *TicketPurchaser {
	return p.purchaser
}