diff --git a/api.go b/api.go index 6c2beab..91e71ce 100644 --- a/api.go +++ b/api.go @@ -11,6 +11,7 @@ type Method string const ( GetTransaction Method = "gettransaction" + ZGetTotalBalance = "z_gettotalbalance" ZListAddresses = "z_listaddresses" ZListReceivedByAddress = "z_listreceivedbyaddress" ZSendMany = "z_sendmany" @@ -55,6 +56,15 @@ func NewZListAddresses() []byte { return data } +// NewZGetTotalBalance constructs a properly formatted z_gettotalbalance request +func NewZGetTotalBalance(minConfirmations int) []byte { + request := setupZcashRequest() + request.Method = ZGetTotalBalance + request.Params = append(request.Params, minConfirmations) + data, _ := json.Marshal(request) + return data +} + // NewZListReceivedByAddress constructs a properly formatted z_listreceivedbyaddress request func NewZListReceivedByAddress(fromAddress string) []byte { request := setupZcashRequest() @@ -99,6 +109,9 @@ type ZcashTransaction struct { Memo Hex `json:"memo"` Change bool `json:"change"` OutIndex int `json:"outindex"` + + // The following parameters are not provided by the zcash node + Address string `json:"address"` } // ZcashResult represents the result of a zcash operation. Result can be any one of a number of defined types. @@ -115,3 +128,10 @@ type ZValidateAddressResponse struct { Diversifier Hex `json:"diversifier"` DiversifiedTransmissionKey Hex `json:"diversifiedtransmissionkey"` } + +// ZGetTotalBalanceResponse encapsulates the result returned from a z_gettotalbalance request +type ZGetTotalBalanceResponse struct { + Transparent string `json:"transparent"` + Private string `json:"private"` + Total string `json:"total"` +} diff --git a/testing/zcash_client_integration_test.go b/testing/zcash_client_integration_test.go index b32f648..9609f29 100644 --- a/testing/zcash_client_integration_test.go +++ b/testing/zcash_client_integration_test.go @@ -13,6 +13,38 @@ type ZcashConfig struct { Password string `json:"password"` } +func TestGetTotalBalance(t *testing.T) { + log.SetLevel(log.LevelDebug) + configFile, _ := ioutil.ReadFile("config.json") + config := ZcashConfig{} + _ = json.Unmarshal(configFile, &config) + + zc := zcashrpc.NewLocalClient(config.Username, config.Password) + result, err := zc.GetTotalBalance(1) + t.Logf("Result: %v %v", result, err) + if err != nil { + t.Errorf("Failed to get total balance: %v %v", result, err) + } +} + +func TestListTransactions(t *testing.T) { + log.SetLevel(log.LevelDebug) + configFile, _ := ioutil.ReadFile("config.json") + config := ZcashConfig{} + _ = json.Unmarshal(configFile, &config) + + zc := zcashrpc.NewLocalClient(config.Username, config.Password) + result, err := zc.ListReceivedTransactionsByAddress("zs1pjv7eneq9jshw0eyywpruv2cetl74sh84ymdnyv4c4vg8vl5k2qmlv0n7ye77g49lhqkg75v52f") + t.Logf("Result: %v %v", result, err) + if len(result) == 0 { + t.Errorf("Failed to list transactions") + } else { + for _, transaction := range result { + t.Logf("Transaction: %v", transaction) + } + } +} + func TestListAddresses(t *testing.T) { log.SetLevel(log.LevelDebug) configFile, _ := ioutil.ReadFile("config.json") diff --git a/zcash_client.go b/zcash_client.go index 7a1cdcf..a3054b4 100644 --- a/zcash_client.go +++ b/zcash_client.go @@ -9,10 +9,12 @@ import ( "io/ioutil" "net" "net/http" + "strconv" ) // ZcashClient defines an interface for any zcash client to present. type ZcashClient interface { + GetTotalBalance(minConfirmations int) (float64, error) GetTransaction(string) (Transaction, error) ListAddresses() ([]string, error) ListReceivedTransactionsByAddress(string) ([]ZcashTransaction, error) @@ -58,6 +60,17 @@ func NewOnionClient(onion string, username, password string, acn connectivity.AC return zc } +// Return the total value of funds stored in the node’s wallet. Set the minimum number of confirmations a private or transparent transaction must have in order to be included in the balance. Use 0 to count unconfirmed transactions. +func (zc *zcashClient) GetTotalBalance(minConfirmations int) (float64, error) { + body, err := zc.sendRequest(NewZGetTotalBalance(minConfirmations)) + var totalBalance ZGetTotalBalanceResponse + if err == nil { + result := &ZcashResult{Result: &totalBalance} + err = json.Unmarshal(body, &result) + } + return strconv.ParseFloat(totalBalance.Private, 64) +} + // GetTransaction returns a specific transaction given an id func (zc *zcashClient) GetTransaction(id string) (Transaction, error) { body, err := zc.sendRequest(NewGetTransaction(id)) @@ -88,6 +101,9 @@ func (zc *zcashClient) ListReceivedTransactionsByAddress(address string) ([]Zcas result := &ZcashResult{Result: &transactions} err = json.Unmarshal(body, &result) } + for i := range transactions { + transactions[i].Address = address + } return transactions, err }