Add websocket method getBalanceHistory

balanceHistory
Martin Boehm 2019-12-17 14:37:24 +01:00
parent 1cec22ecba
commit 15e2c0bf41
6 changed files with 153 additions and 50 deletions

View File

@ -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"`
}

View File

@ -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)

View File

@ -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 {

View File

@ -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

View File

@ -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"`

View File

@ -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 @@
<div class="col" id="getAccountUtxoResult">
</div>
</div>
<div class="row">
<div class="col">
<input class="btn btn-secondary" type="button" value="getBalanceHistory" onclick="getBalanceHistory()">
</div>
<div class="col-8">
<div class="row" style="margin: 0;">
<input type="text" placeholder="descriptor" class="form-control" id="getBalanceHistoryDescriptor" value="0xba98d6a5ac827632e3457de7512d211e4ff7e8bd">
</div>
<div class="row" style="margin: 0; margin-top: 5px;">
<input type="text" placeholder="from YYYY-MM-DD" style="width: 30%;margin-left: 5px;margin-right: 5px;" class="form-control" id="getBalanceHistoryFrom">
<input type="text" placeholder="to YYYY-MM-DD" style="width: 30%; margin-left: 5px; margin-right: 5px;" class="form-control" id="getBalanceHistoryTo">
<input type="text" placeholder="fiat" style="width: 20%; margin-left: 5px; margin-right: 5px;" class="form-control" id="getBalanceHistoryFiat">
</div>
</div>
<div class="col form-inline"></div>
</div>
<div class="row">
<div class="col" id="getBalanceHistoryResult">
</div>
</div>
<div class="row">
<div class="col">
<input class="btn btn-secondary" type="button" value="getTransaction" onclick="getTransaction()">
@ -492,6 +531,42 @@
<div class="row">
<div class="col" id="sendTransactionResult"></div>
</div>
<div class="row">
<div class="col-2">
<input class="btn btn-secondary" type="button" value="get fiat rates for dates" onclick="getFiatRatesForDates()">
</div>
<div class="col-1">
<input type="text" class="form-control" id="getFiatRatesForDatesCurrency" value="usd">
</div>
<div class="col-7">
<input type="text" class="form-control" id="getFiatRatesForDatesList" value="20191121140000,20191121143015">
</div>
</div>
<div class="row">
<div class="col" id="getFiatRatesForDatesResult"></div>
</div>
<div class="row">
<div class="col-2">
<input class="btn btn-secondary" type="button" value="get current fiat rates" onclick="getCurrentFiatRates()">
</div>
<div class="col-1">
<input type="text" class="form-control" id="getCurrentFiatRatesCurrency" value="usd">
</div>
</div>
<div class="row">
<div class="col" id="getCurrentFiatRatesResult"></div>
</div>
<div class="row">
<div class="col-2">
<input class="btn btn-secondary" type="button" value="get fiat rates tickers" onclick="getFiatRatesTickersList()">
</div>
<div class="col-8">
<input type="text" class="form-control" id="getFiatRatesTickersListDate" value="20191121140000">
</div>
</div>
<div class="row">
<div class="col" id="getFiatRatesTickersListResult"></div>
</div>
<div class="row">
<div class="col">
<input class="btn btn-secondary" type="button" value="subscribe new block" onclick="subscribeNewBlock()">
@ -524,52 +599,16 @@
<div class="col" id="subscribeAddressesResult"></div>
</div>
<div class="row">
<div class="col">
<input class="btn btn-secondary" type="button" value="get fiat rates for dates" onclick="getFiatRatesForDates()">
</div>
<div class="col-8">
<input type="text" class="form-control" id="getFiatRatesForDatesCurrency" value="usd">
</div>
<div class="col-8">
<input type="text" class="form-control" id="getFiatRatesForDatesList" value="20191121140000,20191121143015">
</div>
</div>
<div class="row">
<div class="col" id="getFiatRatesForDatesResult"></div>
</div>
<div class="row">
<div class="col">
<input class="btn btn-secondary" type="button" value="get current firat rates" onclick="getCurrentFiatRates()">
</div>
<div class="col-8">
<input type="text" class="form-control" id="getCurrentFiatRatesCurrency" value="usd">
</div>
</div>
<div class="row">
<div class="col" id="getCurrentFiatRatesResult"></div>
</div>
<div class="row">
<div class="col">
<input class="btn btn-secondary" type="button" value="get fiat rates tickers" onclick="getFiatRatesTickersList()">
</div>
<div class="col-8">
<input type="text" class="form-control" id="getFiatRatesTickersListDate" value="20191121140000">
</div>
</div>
<div class="row">
<div class="col" id="getFiatRatesTickersListResult"></div>
</div>
<div class="row">
<div class="col">
<div class="col-3">
<input class="btn btn-secondary" type="button" value="subscribe new fiat rates" onclick="subscribeNewFiatRatesTicker()">
</div>
<div class="col-4">
<div class="col-1">
<span id="subscribeNewFiatRatesTickerId"></span>
</div>
<div class="col-8">
<div class="col-1">
<input type="text" class="form-control" id="subscribeFiatRatesCurrency" value="usd">
</div>
<div class="col">
<div class="col-5">
<input class="btn btn-secondary" id="unsubscribeNewFiatRatesTickerButton" style="display: none;" type="button" value="unsubscribe" onclick="unsubscribeNewFiatRatesTicker()">
</div>
</div>
@ -577,6 +616,7 @@
<div class="col" id="subscribeNewFiatRatesTickerResult"></div>
</div>
</div>
<br><br>
</body>
<script>
document.getElementById('serverAddress').value = window.location.protocol + "//" + window.location.host;