diff --git a/api/types.go b/api/types.go index e98634bd..66acb903 100644 --- a/api/types.go +++ b/api/types.go @@ -299,10 +299,11 @@ func (a Utxos) Less(i, j int) bool { // BalanceHistory contains info about one point in time of balance history type BalanceHistory struct { - Time uint32 `json:"blockTime"` + Time uint32 `json:"time"` Txs uint32 `json:"txs"` ReceivedSat *Amount `json:"received"` SentSat *Amount `json:"sent"` + FiatRate string `json:"fiatrate,omitempty"` Txid string `json:"txid,omitempty"` } diff --git a/api/xpub.go b/api/xpub.go index 5e014b96..f33af72f 100644 --- a/api/xpub.go +++ b/api/xpub.go @@ -590,8 +590,8 @@ func (w *Worker) GetXpubUtxo(xpub string, onlyConfirmed bool, gap int) (Utxos, e return r, nil } -// GetUtxoBalanceHistory returns history of balance for given xpub -func (w *Worker) GetUtxoBalanceHistory(xpub string, fromTime, toTime time.Time, gap int) (BalanceHistories, error) { +// GetXpubBalanceHistory returns history of balance for given xpub +func (w *Worker) GetXpubBalanceHistory(xpub string, fromTime, toTime time.Time, gap int) (BalanceHistories, error) { bhs := make(BalanceHistories, 0) start := time.Now() fromUnix, fromHeight, toUnix, toHeight := w.balanceHistoryHeightsFromTo(fromTime, toTime) diff --git a/server/public.go b/server/public.go index 535f178e..e128cdb3 100644 --- a/server/public.go +++ b/server/public.go @@ -1058,7 +1058,7 @@ func (s *PublicServer) apiBalanceHistory(r *http.Request, apiVersion int) (inter // time.RFC3339 toTime, _ = time.Parse("2006-01-02", t) } - history, err = s.api.GetUtxoBalanceHistory(r.URL.Path[i+1:], fromTime, toTime, gap) + history, err = s.api.GetXpubBalanceHistory(r.URL.Path[i+1:], fromTime, toTime, gap) if err == nil { s.metrics.ExplorerViews.With(common.Labels{"action": "api-xpub-balancehistory"}).Inc() } else { diff --git a/server/public_test.go b/server/public_test.go index 014f4b83..f609bce1 100644 --- a/server/public_test.go +++ b/server/public_test.go @@ -752,7 +752,7 @@ func httpTestsBitcoinType(t *testing.T, ts *httptest.Server) { status: http.StatusOK, contentType: "application/json; charset=utf-8", body: []string{ - `[{"blockTime":1521514800,"txs":1,"received":"12345","sent":"0"},{"blockTime":1521594000,"txs":1,"received":"0","sent":"12345"}]`, + `[{"time":1521514800,"txs":1,"received":"12345","sent":"0"},{"time":1521594000,"txs":1,"received":"0","sent":"12345"}]`, }, }, { @@ -761,7 +761,7 @@ func httpTestsBitcoinType(t *testing.T, ts *httptest.Server) { status: http.StatusOK, contentType: "application/json; charset=utf-8", body: []string{ - `[{"blockTime":1521514800,"txs":1,"received":"9876","sent":"0"},{"blockTime":1521594000,"txs":1,"received":"9000","sent":"9876"}]`, + `[{"time":1521514800,"txs":1,"received":"9876","sent":"0"},{"time":1521594000,"txs":1,"received":"9000","sent":"9876"}]`, }, }, { @@ -770,7 +770,7 @@ func httpTestsBitcoinType(t *testing.T, ts *httptest.Server) { status: http.StatusOK, contentType: "application/json; charset=utf-8", body: []string{ - `[{"blockTime":1521514800,"txs":1,"received":"12345","sent":"0"}]`, + `[{"time":1521514800,"txs":1,"received":"12345","sent":"0"}]`, }, }, { @@ -779,7 +779,7 @@ func httpTestsBitcoinType(t *testing.T, ts *httptest.Server) { status: http.StatusOK, contentType: "application/json; charset=utf-8", body: []string{ - `[{"blockTime":1521514800,"txs":1,"received":"1","sent":"0"},{"blockTime":1521594000,"txs":1,"received":"118641975500","sent":"1"}]`, + `[{"time":1521514800,"txs":1,"received":"1","sent":"0"},{"time":1521594000,"txs":1,"received":"118641975500","sent":"1"}]`, }, }, { @@ -788,7 +788,7 @@ func httpTestsBitcoinType(t *testing.T, ts *httptest.Server) { status: http.StatusOK, contentType: "application/json; charset=utf-8", body: []string{ - `[{"blockTime":1521514800,"txs":1,"received":"1","sent":"0"}]`, + `[{"time":1521514800,"txs":1,"received":"1","sent":"0"}]`, }, }, { @@ -797,7 +797,7 @@ func httpTestsBitcoinType(t *testing.T, ts *httptest.Server) { status: http.StatusOK, contentType: "application/json; charset=utf-8", body: []string{ - `[{"blockTime":1521594000,"txs":1,"received":"118641975500","sent":"1"}]`, + `[{"time":1521594000,"txs":1,"received":"118641975500","sent":"1"}]`, }, }, { @@ -1309,6 +1309,38 @@ func websocketTestsBitcoinType(t *testing.T, ts *httptest.Server) { }, want: `{"id":"30","data":{"data_timestamp":"20191121140000","available_currencies":["eur","usd"]}}`, }, + { + name: "websocket getBalanceHistory Addr2", + req: websocketReq{ + Method: "getBalanceHistory", + Params: map[string]interface{}{ + "descriptor": "mtGXQvBowMkBpnhLckhxhbwYK44Gs9eEtz", + }, + }, + want: `{"id":"31","data":[{"time":1521514800,"txs":1,"received":"12345","sent":"0"},{"time":1521594000,"txs":1,"received":"0","sent":"12345"}]}`, + }, + { + name: "websocket getBalanceHistory xpub", + req: websocketReq{ + Method: "getBalanceHistory", + Params: map[string]interface{}{ + "descriptor": dbtestdata.Xpub, + }, + }, + want: `{"id":"32","data":[{"time":1521514800,"txs":1,"received":"1","sent":"0"},{"time":1521594000,"txs":1,"received":"118641975500","sent":"1"}]}`, + }, + { + name: "websocket getBalanceHistory xpub from=2018-03-20&to=2018-03-21", + req: websocketReq{ + Method: "getBalanceHistory", + Params: map[string]interface{}{ + "descriptor": dbtestdata.Xpub, + "from": "2018-03-20", + "to": "2018-03-21", + }, + }, + want: `{"id":"33","data":[{"time":1521514800,"txs":1,"received":"1","sent":"0"}]}`, + }, } // send all requests at once diff --git a/server/websocket.go b/server/websocket.go index fa47835b..112fde63 100644 --- a/server/websocket.go +++ b/server/websocket.go @@ -253,6 +253,36 @@ var requestHandlers = map[string]func(*WebsocketServer, *websocketChannel, *webs } return }, + "getBalanceHistory": func(s *WebsocketServer, c *websocketChannel, req *websocketReq) (rv interface{}, err error) { + r := struct { + Descriptor string `json:"descriptor"` + From string `json:"from"` + To string `json:"to"` + Fiat string `json:"fiat"` + Gap int `json:"gap"` + }{} + err = json.Unmarshal(req.Params, &r) + if err == nil { + var fromTime, toTime time.Time + if r.From != "" { + fromTime, err = time.Parse("2006-01-02", r.From) + if err != nil { + return + } + } + if r.To != "" { + toTime, err = time.Parse("2006-01-02", r.To) + if err != nil { + return + } + } + rv, err = s.api.GetXpubBalanceHistory(r.Descriptor, fromTime, toTime, r.Gap) + if err != nil { + rv, err = s.api.GetBalanceHistory(r.Descriptor, fromTime, toTime) + } + } + return + }, "getTransaction": func(s *WebsocketServer, c *websocketChannel, req *websocketReq) (rv interface{}, err error) { r := struct { Txid string `json:"txid"` diff --git a/static/test-websocket.html b/static/test-websocket.html index ae9c2504..efe27efd 100644 --- a/static/test-websocket.html +++ b/static/test-websocket.html @@ -161,6 +161,25 @@ }); } + function getBalanceHistory() { + const descriptor = document.getElementById('getBalanceHistoryDescriptor').value.trim(); + const from = parseInt(document.getElementById("getBalanceHistoryFrom").value); + const to = parseInt(document.getElementById("getBalanceHistoryTo").value); + const fiat = document.getElementById("getBalanceHistoryFiat").value.trim(); + const method = 'getBalanceHistory'; + const params = { + descriptor, + from, + to, + fiat + // default gap=20 + }; + send(method, params, function (result) { + document.getElementById('getBalanceHistoryResult').innerText = JSON.stringify(result).replace(/,/g, ", "); + }); + } + + function getTransaction() { const txid = document.getElementById('getTransactionTxid').value.trim(); const method = 'getTransaction'; @@ -431,6 +450,26 @@