Browse Source

增加接口:汇总在线钱包和离线钱包的余额

476052856 6 years ago
parent
commit
8238a16780

BIN
coinsapi


BIN
coinsapi.exe


+ 9 - 8
httphandler.go

@@ -20,14 +20,15 @@ import (
 //)
 
 var handler = map[string]func(w http.ResponseWriter, r *http.Request, js *simplejson.Json, body []byte) int{
-	CREATEADDR:     commonFunc,
-	TRANSINFO:      commonFunc,
-	COINBALANCE:    commonFunc,
-	SENDCOINS:      commonFunc,
-	CHAINHEIGHT:    commonFunc,
-	LISTUNSPENT:    commonFunc,
-	RAWTRANSFER:    commonFunc,
-	SUMCOINBALANCE: commonFunc,
+	CREATEADDR:      commonFunc,
+	TRANSINFO:       commonFunc,
+	COINBALANCE:     commonFunc,
+	SENDCOINS:       commonFunc,
+	CHAINHEIGHT:     commonFunc,
+	LISTUNSPENT:     commonFunc,
+	RAWTRANSFER:     commonFunc,
+	SUMCOINBALANCE:  commonFunc,
+	ACCOUNTSBALANCE: commonFunc,
 }
 
 func commonHandler(w http.ResponseWriter, r *http.Request) {

+ 28 - 0
src/bitcoin/bitcoinmain.go

@@ -479,6 +479,34 @@ func (m BitCoin) SumcoinBalance(parm interface{}) ([]byte, error) {
 	return nil, nil
 }
 
+func (m BitCoin) AccountsBalance(parm interface{}) (jbuf []byte, err error) {
+	var balancestotal, offlinebalancetotal float64
+	ilistunspent := m_unspent
+	accountbalance := make([]map[string]interface{}, 0)
+	offlinebalance := make([]map[string]interface{}, 0)
+	for _, value := range ilistunspent {
+		if value["spendable"] == true {
+			balancestotal += value["Amount"].(float64)
+			accountbalance = append(accountbalance, value)
+		} else {
+			offlinebalancetotal += value["Amount"].(float64)
+			offlinebalance = append(offlinebalance, value)
+		}
+	}
+	resptmp := make(map[string]interface{})
+	resptmp["errcode"] = 0
+	resptmp["cointype"] = "BTC"
+	resptmp["accountbalance"] = accountbalance
+	resptmp["balancestotal"] = balancestotal
+	resptmp["offlinebalance"] = offlinebalance
+	resptmp["offlinebalancetotal"] = offlinebalancetotal
+	if jbuf, err = json.Marshal(resptmp); err != nil {
+		LOG("ERROR", " inner json error:%v", err.Error())
+		return nil, fmt.Errorf(`{"errcode":%v,"mesage":"%s"}`, INNER_ERR, getErrMsg(INNER_ERR, nil))
+	}
+	return jbuf, nil
+}
+
 func AsyncRoutine() {
 	CachelistunspentTicker := time.NewTicker(120 * time.Second)
 	for {

+ 12 - 6
src/bucash/bucash.go

@@ -395,24 +395,30 @@ func (m BuCashApi) Listunspent(address []string) ([]map[string]interface{}, erro
 		return nil, err
 	}
 
-	var unspentValue map[string]float64
-	unspentValue = make(map[string]float64)
+	unspentValue := map[string]*listunspent{}
+
 	for _, unspentInfo := range unspentResult.Result {
 		addr := unspentInfo.Address
-		if unspentValue[addr] == 0 {
-			unspentValue[addr] = unspentInfo.Amount
+		if addr == "" {
+			break
+		}
+		if unspentValue[addr] == nil {
+			unspentValue[addr] = &listunspent{unspentInfo.Amount, unspentInfo.Spendable}
+
 		} else {
-			unspentValue[addr] += unspentInfo.Amount
+			unspentValue[addr].amout += unspentInfo.Amount
 		}
+
 	}
 
 	outputsArr := make([]map[string]interface{}, 0)
 	for k, v := range unspentValue {
 		requestData := make(map[string]interface{})
 		requestData["address"] = k
-		valuestr := fmt.Sprintf("%.8f", v)
+		valuestr := fmt.Sprintf("%.8f", v.amout)
 		value, _ := strconv.ParseFloat(valuestr, 64)
 		requestData["Amount"] = value
+		requestData["spendable"] = v.spendable
 		outputsArr = append(outputsArr, requestData)
 	}
 	return outputsArr, nil

+ 77 - 12
src/bucash/bucashcoins.go

@@ -5,6 +5,7 @@ import (
 	//"errors"
 	"fmt"
 	"strconv"
+	"sync"
 	. "template"
 	"time"
 
@@ -13,8 +14,10 @@ import (
 )
 
 var (
-	Config  config
-	CoinApi BuCashApi
+	Config       config
+	CoinApi      BuCashApi
+	m_unspent    []map[string]interface{}
+	m_mutUnspent sync.Mutex
 )
 
 type Bucash struct {
@@ -30,6 +33,9 @@ func (m Bucash) InitDriver(parm interface{}) bool {
 		return false
 	}
 	go m.getwalletinfo()
+
+	//缓存当前未花费的
+	go AsyncRoutine()
 	return true
 }
 
@@ -306,23 +312,31 @@ func (m Bucash) ChainHeight(parm interface{}) ([]byte, error) {
 }
 
 func (m Bucash) ListUnspent(parm interface{}) ([]byte, error) {
+	i_unspent := make([]map[string]interface{}, 0)
 	pjs := parm.(*simplejson.Json)
-	address, err := pjs.Get("address").StringArray()
-	if err != nil {
-		LOG("ERROR", "  input parm error:%v", err.Error())
-		return nil, fmt.Errorf(`{"errcode":%v,"mesage":"%s"}`, LISTUNSPENT_ERR, getErrMsg(LISTUNSPENT_ERR, nil))
-	}
-	unspent, err := CoinApi.Listunspent(address)
-	if err != nil {
-		LOG("ERROR", "  get listunspent:%v", err.Error())
-		return nil, fmt.Errorf(`{"errcode":%v,"mesage":"%s"}`, LISTUNSPENT_ERR, getErrMsg(LISTUNSPENT_ERR, nil))
+	Issync, err := pjs.Get("Sync").Bool()
+	if !Issync {
+		fmt.Println("The listunspent data Asynchrony!!!!")
+		i_unspent = m_unspent
+	} else {
+		address, err := pjs.Get("address").StringArray()
+		if err != nil {
+			LOG("ERROR", "  input parm error:%v", err.Error())
+			return nil, fmt.Errorf(`{"errcode":%v,"mesage":"%s"}`, LISTUNSPENT_ERR, getErrMsg(LISTUNSPENT_ERR, nil))
+		}
+		unspent, err := CoinApi.Listunspent(address)
+		if err != nil {
+			LOG("ERROR", "  get listunspent:%v", err.Error())
+			return nil, fmt.Errorf(`{"errcode":%v,"mesage":"%s"}`, LISTUNSPENT_ERR, getErrMsg(LISTUNSPENT_ERR, nil))
+		}
+		i_unspent = unspent
 	}
 
 	var jbuf []byte
 	resptmp := make(map[string]interface{})
 	resptmp["errcode"] = 0
 	resptmp["cointype"] = "BCC"
-	resptmp["unspents"] = unspent
+	resptmp["unspents"] = i_unspent
 
 	if jbuf, err = json.Marshal(resptmp); err != nil {
 		LOG("ERROR", " inner json error:%v", err.Error())
@@ -363,6 +377,57 @@ func (m Bucash) SendRawTransaction(parm interface{}) ([]byte, error) {
 func (m Bucash) SumcoinBalance(parm interface{}) ([]byte, error) {
 	return nil, nil
 }
+func (m Bucash) AccountsBalance(parm interface{}) (jbuf []byte, err error) {
+	var balancestotal, offlinebalancetotal float64
+	ilistunspent := m_unspent
+	accountbalance := make([]map[string]interface{}, 0)
+	offlinebalance := make([]map[string]interface{}, 0)
+	for _, value := range ilistunspent {
+		if value["spendable"] == true {
+			balancestotal += value["Amount"].(float64)
+			accountbalance = append(accountbalance, value)
+		} else {
+			offlinebalancetotal += value["Amount"].(float64)
+			offlinebalance = append(offlinebalance, value)
+		}
+	}
+	resptmp := make(map[string]interface{})
+	resptmp["errcode"] = 0
+	resptmp["cointype"] = "BCC"
+	resptmp["accountbalance"] = accountbalance
+	resptmp["balancestotal"] = balancestotal
+	resptmp["offlinebalance"] = offlinebalance
+	resptmp["offlinebalancetotal"] = offlinebalancetotal
+	if jbuf, err = json.Marshal(resptmp); err != nil {
+		LOG("ERROR", " inner json error:%v", err.Error())
+		return nil, fmt.Errorf(`{"errcode":%v,"mesage":"%s"}`, INNER_ERR, getErrMsg(INNER_ERR, nil))
+	}
+	return jbuf, nil
+}
+
+func AsyncRoutine() {
+	CachelistunspentTicker := time.NewTicker(120 * time.Second)
+	for {
+		select {
+		case _ = <-CachelistunspentTicker.C:
+			Cachelistunspent()
+		}
+	}
+}
+func Cachelistunspent() {
+	fmt.Println("cachelistunspent time:", time.Now().Format("2006-01-02 15:04:05"))
+	var address []string
+	m_unspent = make([]map[string]interface{}, 0)
+	unspent, err := CoinApi.Listunspent(address)
+	if err != nil {
+		LOG("ERROR", "  get listunspent:%v", err.Error())
+		//return nil, fmt.Errorf(`{"errcode":%v,"mesage":"%s"}`, LISTUNSPENT_ERR, getErrMsg(LISTUNSPENT_ERR, nil))
+	}
+	m_mutUnspent.Lock()
+	m_unspent = unspent
+	m_mutUnspent.Unlock()
+
+}
 
 func init() {
 	Register(NameCoin, &Bucash{})

+ 10 - 9
src/bucash/type.go

@@ -1,8 +1,5 @@
 package bucash
 
-import (
-)
-
 //  rpc  error struct
 type RpcError struct {
 	Code    int    `json:"code"`
@@ -57,7 +54,7 @@ type Listtransactions struct {
 	Txid          string  `json:"txid"`
 	Time          uint64  `json:"time"`
 	Timereceived  uint64  `json:"timereceived"`
-	Abandoned     bool	  `json:"abandoned"`
+	Abandoned     bool    `json:"abandoned"`
 	Label         string  `json:"label"`
 	Comment       string  `json:"comment"`
 	To            string  `json:"to"`
@@ -95,7 +92,6 @@ type Setfeeresult struct {
 	Id     string
 }
 
-
 //get wallet info result struct
 type walletInfo struct {
 	Walletversion       uint64
@@ -110,10 +106,11 @@ type walletInfo struct {
 }
 
 type WalletinfoResult struct {
-	Result walletInfo     `json:"result"`
-	Error  RpcError       `json:"error"`
-	Id     string         `json:"id"`
+	Result walletInfo `json:"result"`
+	Error  RpcError   `json:"error"`
+	Id     string     `json:"id"`
 }
+
 //list unspent info result struct
 type UnspentInfo struct {
 	Txid          string
@@ -135,4 +132,8 @@ type RpcUnspentResult struct {
 	Id     string        `json:"id"`
 }
 
-
+//simple   listunspent
+type listunspent struct {
+	amout     float64
+	spendable bool
+}

+ 31 - 1
src/dcrcash/dcrcash_test.go

@@ -234,6 +234,36 @@ func Test_SumCoinBalance(t *testing.T) {
 }
 */
 
+func Test_AccountsBalance(t *testing.T) {
+	client := http.DefaultClient
+	geturl := fmt.Sprintf(`http://localhost:15741/coinproxy/accountsbalance`)
+	timetamp := fmt.Sprintf("%v", time.Now().Unix())
+
+	t.Logf("post url:%v", geturl)
+
+	posdata := fmt.Sprintf(`{"cointype":"DCR","timestamp":"%v"}`, timetamp)
+	request, err := http.NewRequest("POST", geturl, strings.NewReader(posdata))
+	if err != nil {
+		t.Error("err:%s", err.Error())
+		return
+	}
+	resp, err := client.Do(request)
+	if err != nil {
+		t.Errorf("err:%s", err.Error())
+		return
+	}
+
+	defer resp.Body.Close()
+	rbs, err := ioutil.ReadAll(resp.Body)
+	if err != nil {
+		t.Errorf("err:%s", err.Error())
+		return
+	}
+
+	t.Logf("read bytes:%v", string(rbs))
+}
+
+/*
 func Test_TransferAccounts(t *testing.T) {
 	client := http.DefaultClient
 	geturl := fmt.Sprintf(`http://localhost:15741/coinproxy/sendcoins`)
@@ -263,7 +293,7 @@ func Test_TransferAccounts(t *testing.T) {
 	t.Logf("read bytes:%v", string(rbs))
 	return
 }
-
+*/
 func Signature(body []byte, timestamp string) string {
 
 	sha1Contain := sha1.New()

+ 31 - 2
src/dcrcash/dcrcashcoin.go

@@ -94,7 +94,7 @@ func (m DcrCash) getwalletinfo() bool {
 }
 
 func (m DcrCash) CoinBalance(parm interface{}) ([]byte, error) {
-	var totalbalance, maxConfirbalance, maxUnconfirbalance float64
+	var totalbalance, maxConfirbalance, maxUnconfirbalance, querytime float64
 	pjs := parm.(*simplejson.Json)
 	input, err := pjs.Get("Sync").Bool()
 	if !input {
@@ -102,6 +102,7 @@ func (m DcrCash) CoinBalance(parm interface{}) ([]byte, error) {
 		totalbalance = m_balanceparam["totalbalance"]
 		maxConfirbalance = m_balanceparam["confirmedbalance"]
 		maxUnconfirbalance = m_balanceparam["unconfirmed"]
+		querytime = m_balanceparam["ntime"]
 	} else {
 		acountBalace, err := CoinApi.WalleGetBalance("*")
 		if err != nil {
@@ -133,7 +134,7 @@ func (m DcrCash) CoinBalance(parm interface{}) ([]byte, error) {
 	resp["confirmedbalance"] = maxConfirbalance
 	resp["unconfirmed"] = maxUnconfirbalance
 	resp["totalbalance"] = totalbalance
-	resp["querybalancetime"] = m_balanceparam["ntime"]
+	resp["querybalancetime"] = querytime
 	resp["errcode"] = 0
 	resp["exact"] = 0
 	if jbuf, err = json.Marshal(resp); err != nil {
@@ -471,6 +472,34 @@ func (m DcrCash) ChainHeight(parm interface{}) ([]byte, error) {
 	return []byte(sendstr), nil
 }
 
+func (m DcrCash) AccountsBalance(parm interface{}) (jbuf []byte, err error) {
+	var balancestotal, offlinebalancetotal float64
+	ilistunspent := m_unspent
+	accountbalance := make([]map[string]interface{}, 0)
+	offlinebalance := make([]map[string]interface{}, 0)
+	for _, value := range ilistunspent {
+		if value["spendable"] == true {
+			balancestotal += value["Amount"].(float64)
+			accountbalance = append(accountbalance, value)
+		} else {
+			offlinebalancetotal += value["Amount"].(float64)
+			offlinebalance = append(offlinebalance, value)
+		}
+	}
+	resptmp := make(map[string]interface{})
+	resptmp["errcode"] = 0
+	resptmp["cointype"] = "DCR"
+	resptmp["accountbalance"] = accountbalance
+	resptmp["balancestotal"] = balancestotal
+	resptmp["offlinebalance"] = offlinebalance
+	resptmp["offlinebalancetotal"] = offlinebalancetotal
+	if jbuf, err = json.Marshal(resptmp); err != nil {
+		LOG("ERROR", " inner json error:%v", err.Error())
+		return nil, fmt.Errorf(`{"errcode":%v,"mesage":"%s"}`, INNER_ERR, getErrMsg(INNER_ERR, nil))
+	}
+	return jbuf, nil
+}
+
 func CacheGetbalance() {
 	fmt.Println("Cachegetbalance time:", time.Now().Format("2006-01-02 15:04:05"))
 	m_balanceparam = make(map[string]float64)

+ 3 - 0
src/lite/litecoins.go

@@ -343,6 +343,9 @@ func (m Lite) SumcoinBalance(parm interface{}) ([]byte, error) {
 	return nil, nil
 }
 
+func (m Lite) AccountsBalance(parm interface{}) ([]byte, error) {
+	return nil, nil
+}
 func init() {
 	Register(NameLite, &Lite{})
 }

+ 19 - 16
src/template/template.go

@@ -14,28 +14,31 @@ type Template interface {
 	ListUnspent(parm interface{}) ([]byte, error)
 	SendRawTransaction(parm interface{}) ([]byte, error)
 	SumcoinBalance(parm interface{}) ([]byte, error)
+	AccountsBalance(parm interface{}) ([]byte, error)
 }
 
 const (
-	CREATEADDR     = "/coinproxy/createaddr"
-	TRANSINFO      = "/coinproxy/query/transinfo"
-	COINBALANCE    = "/coinproxy/coinbalance"
-	SENDCOINS      = "/coinproxy/sendcoins"
-	CHAINHEIGHT    = "/coinproxy/blockchain/height"
-	LISTUNSPENT    = "/coinproxy/listunspent"
-	RAWTRANSFER    = "/coinproxy/sendrawtransaction"
-	SUMCOINBALANCE = "/coinproxy/sumcoinbalance"
+	CREATEADDR      = "/coinproxy/createaddr"
+	TRANSINFO       = "/coinproxy/query/transinfo"
+	COINBALANCE     = "/coinproxy/coinbalance"
+	SENDCOINS       = "/coinproxy/sendcoins"
+	CHAINHEIGHT     = "/coinproxy/blockchain/height"
+	LISTUNSPENT     = "/coinproxy/listunspent"
+	RAWTRANSFER     = "/coinproxy/sendrawtransaction"
+	SUMCOINBALANCE  = "/coinproxy/sumcoinbalance"
+	ACCOUNTSBALANCE = "/coinproxy/accountsbalance"
 )
 
 var Handler = map[string]func(Template, interface{}) ([]byte, error){
-	CREATEADDR:     Template.CreateAddress,
-	COINBALANCE:    Template.CoinBalance,
-	SENDCOINS:      Template.TransferAccounts,
-	TRANSINFO:      Template.TransInfo,
-	CHAINHEIGHT:    Template.ChainHeight,
-	LISTUNSPENT:    Template.ListUnspent,
-	RAWTRANSFER:    Template.SendRawTransaction,
-	SUMCOINBALANCE: Template.SumcoinBalance,
+	CREATEADDR:      Template.CreateAddress,
+	COINBALANCE:     Template.CoinBalance,
+	SENDCOINS:       Template.TransferAccounts,
+	TRANSINFO:       Template.TransInfo,
+	CHAINHEIGHT:     Template.ChainHeight,
+	LISTUNSPENT:     Template.ListUnspent,
+	RAWTRANSFER:     Template.SendRawTransaction,
+	SUMCOINBALANCE:  Template.SumcoinBalance,
+	ACCOUNTSBALANCE: Template.AccountsBalance,
 }
 var drivers = make(map[string]Template)
 

+ 3 - 1
src/zcash/zcashcoins.go

@@ -295,7 +295,9 @@ func (m Zcash) SendRawTransaction(parm interface{}) ([]byte, error) {
 func (m Zcash) SumcoinBalance(parm interface{}) ([]byte, error) {
 	return nil, nil
 }
-
+func (m Zcash) AccountsBalance(parm interface{}) ([]byte, error) {
+	return nil, nil
+}
 func init() {
 	Register(NameZcash, &Zcash{})
 }