func (server *OpencxServer) GetQchansByPeerParam(pubkey *koblitz.PublicKey, param *coinparam.Params) (qchans []*qln.Qchan, err error) {
	var peerIdx uint32
	if peerIdx, err = server.GetPeerFromPubkey(pubkey); err != nil {
		return
	}
	var peer *lnp2p.Peer
	if peer = server.ExchangeNode.PeerMan.GetPeerByIdx(int32(peerIdx)); err != nil {
		return
	}
	server.ExchangeNode.PeerMapMtx.Lock()
	var remotePeer *qln.RemotePeer
	var found bool
	if remotePeer, found = server.ExchangeNode.PeerMap[peer]; !found {
		err = fmt.Errorf("Could not find remote peer that peer manager is tracking, there's something wrong with the lit node")
		server.ExchangeNode.PeerMapMtx.Unlock()
		return
	}
	server.ExchangeNode.PeerMapMtx.Unlock()
	if err = server.ExchangeNode.PopulateQchanMap(remotePeer); err != nil {
		return
	}
	for _, qchan := range remotePeer.QCs {
		if qchan.Coin() == param.HDCoinType {
			qchans = append(qchans, qchan)
		}
	}
	return
}
GetQchansByPeerParam gets channel indexes for a param and pubkey / peer
package cxserver
import (
	"bytes"
	"fmt"
	"github.com/mit-dci/lit/consts"
	"github.com/mit-dci/lit/lnp2p"
	"github.com/mit-dci/lit/qln"
	"github.com/mit-dci/opencx/logging"
	"github.com/mit-dci/lit/lnutil"
	"github.com/mit-dci/lit/coinparam"
	"github.com/mit-dci/lit/crypto/koblitz"
	"github.com/mit-dci/lit/portxo"
	"github.com/mit-dci/lit/wire"
	"github.com/mit-dci/lit/btcutil/txscript"
	"github.com/mit-dci/lit/btcutil"
)
func (server *OpencxServer) WithdrawCoins(address string, pubkey *koblitz.PublicKey, amount uint64, params *coinparam.Params) (txid string, err error) {
	if int64(amount) < 0 {
		err = fmt.Errorf("That amount would have caused an overflow, enter something lower")
		return
	}
	var withdrawFunction func(string, *koblitz.PublicKey, uint64) (string, error)
	if withdrawFunction, err = server.withdrawFromChain(params); err != nil {
		err = fmt.Errorf("Error creating withdraw function: \n%s", err)
		return
	}
	if txid, err = withdrawFunction(address, pubkey, amount); err != nil {
		err = fmt.Errorf("Error withdrawing coins: \n%s", err)
		return
	}
	return
}
func (server *OpencxServer) WithdrawLightning(pubkey *koblitz.PublicKey, amount uint64, params *coinparam.Params) (txid string, err error) {
	if int64(amount) < 0 {
		err = fmt.Errorf("That amount would have caused an overflow, enter something lower")
		return
	}
	var withdrawFunction func(*koblitz.PublicKey, int64) (string, error)
	if withdrawFunction, err = server.withdrawFromLightning(params); err != nil {
		err = fmt.Errorf("Error creating withdraw function: \n%s", err)
		return
	}
	if txid, err = withdrawFunction(pubkey, int64(amount)); err != nil {
		err = fmt.Errorf("Error withdrawing coins: \n%s", err)
		return
	}
	return
}
func (server *OpencxServer) withdrawFromChain(params *coinparam.Params) (withdrawFunction func(string, *koblitz.PublicKey, uint64) (string, error), err error) {
	wallet, found := server.WalletMap[params]
	if !found {
		err = fmt.Errorf("Could not find wallet for those coin params")
		return
	}
	withdrawFunction = func(address string, pubkey *koblitz.PublicKey, amount uint64) (txid string, err error) {
		if amount == 0 {
			err = fmt.Errorf("You can't withdraw 0 %s", params.Name)
			return
		}
		if err = server.CreditUser(pubkey, amount, params); err != nil {
			err = fmt.Errorf("Error while crediting user for CreateChannel: %s\n", err)
			return
		}
		var addr btcutil.Address
		if addr, err = btcutil.DecodeAddress(address, params); err != nil {
			return
		}
		var payToUserScript []byte
		if payToUserScript, err = txscript.PayToAddrScript(addr); err != nil {
			return
		}
		var utxoSlice portxo.TxoSliceByBip69
		var overshoot int64
		if utxoSlice, overshoot, err = wallet.PickUtxos(int64(amount), int64(len(payToUserScript)), 1000, false); err != nil {
			return
		}
		var changeOut *wire.TxOut
		if changeOut, err = wallet.NewChangeOut(overshoot); err != nil {
			return
		}
		payToUserTxOut := wire.NewTxOut(int64(amount), payToUserScript)
		var withdrawTx *wire.MsgTx
		if withdrawTx, err = wallet.BuildAndSign(utxoSlice, []*wire.TxOut{changeOut, payToUserTxOut}, 0); err != nil {
			return
		}
		buf := new(bytes.Buffer)
		if err = withdrawTx.Serialize(buf); err != nil {
			return
		}
		if err = wallet.NewOutgoingTx(withdrawTx); err != nil {
			return
		}
		return withdrawTx.TxHash().String(), nil
	}
	return
}
func (server *OpencxServer) withdrawFromLightning(params *coinparam.Params) (withdrawFunction func(*koblitz.PublicKey, int64) (string, error), err error) {
	withdrawFunction = func(pubkey *koblitz.PublicKey, amount int64) (txid string, err error) {
		if amount <= 0 {
			err = fmt.Errorf("Can't withdraw <= 0")
			return
		}
		fee := server.ExchangeNode.SubWallet[params.HDCoinType].Fee() * 1000
		if amount < consts.MinOutput+fee {
			err = fmt.Errorf("You can't withdraw any less than %d %s", consts.MinOutput+fee, params.Name)
			return
		}
		var peerIdx uint32
		if peerIdx, err = server.GetPeerFromPubkey(pubkey); err != nil {
			err = fmt.Errorf("You may not have ever connected with the exchange, or you're using a different identity. The exchange can only authenticate for channel creating if you are the node: \n%s", err)
			return
		}
		logging.Infof("Checking if connected to peer")
		if !server.ExchangeNode.ConnectedToPeer(peerIdx) {
			err = fmt.Errorf("Not connected to peer! Please connect to the exchange. We don't know how to connect to you")
			return
		}
		var ccap int64
		if amount < consts.MinChanCapacity {
			ccap = consts.MinChanCapacity
		} else {
			ccap = amount + consts.MinOutput + fee
		}
		if err = server.CreditUser(pubkey, uint64(amount), params); err != nil {
			err = fmt.Errorf("Error while crediting user for CreateChannel: %s\n", err)
			return
		}
		noData := new([32]byte)
		logging.Infof("Trying to fund channel")
		var chanIdx uint32
		if chanIdx, err = server.ExchangeNode.FundChannel(peerIdx, params.HDCoinType, ccap, amount, *noData); err != nil {
			return
		}
		logging.Infof("Getting qchanidx")
		var qchan *qln.Qchan
		if qchan, err = server.ExchangeNode.GetQchanByIdx(chanIdx); err != nil {
			return
		}
		logging.Infof("We're pretty much done with this withdraw")
		txid = qchan.Op.Hash.String()
		return
	}
	return
}
func (server *OpencxServer) GetPeerFromPubkey(pubkey *koblitz.PublicKey) (peerIdx uint32, err error) {
	var pubkey33 [33]byte
	copy(pubkey33[:], pubkey.SerializeCompressed())
	litAddr := lnutil.LitAdrFromPubkey(pubkey33)
	if peerIdx, err = server.ExchangeNode.FindPeerIndexByAddress(litAddr); err != nil {
		return
	}
	return
}