132 lines
4.0 KiB
Go
132 lines
4.0 KiB
Go
package zcashrpc
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/base64"
|
|
"encoding/json"
|
|
"git.openprivacy.ca/openprivacy/libricochet-go/connectivity"
|
|
"git.openprivacy.ca/openprivacy/libricochet-go/log"
|
|
"io/ioutil"
|
|
"net"
|
|
"net/http"
|
|
)
|
|
|
|
// ZcashClient defines an interface for any zcash client to present.
|
|
type ZcashClient interface {
|
|
ListReceivedTransactionsByAddress(string) ([]ZcashTransaction, error)
|
|
GetTransaction(string) (Transaction, error)
|
|
GetBlock(int) (Block, error)
|
|
SendOne(string, string, string, float64) ([]byte, error)
|
|
ValidateAddress(address string) (ZValidateAddressResponse, error)
|
|
}
|
|
|
|
type zcashClient struct {
|
|
client http.Client
|
|
address string
|
|
auth string
|
|
}
|
|
|
|
// NewLocalClient creates a new Zcash rpc client over a local address
|
|
func NewLocalClient(username, password string) ZcashClient {
|
|
zc := new(zcashClient)
|
|
zc.address = "127.0.0.1:8232"
|
|
zc.client = http.Client{
|
|
Transport: &http.Transport{
|
|
Dial: func(network, addr string) (net.Conn, error) {
|
|
conn, err := net.Dial("tcp", zc.address)
|
|
return conn, err
|
|
},
|
|
},
|
|
}
|
|
zc.auth = base64.StdEncoding.EncodeToString([]byte(username + ":" + password))
|
|
return zc
|
|
}
|
|
|
|
// NewOnionClient creates a new Zcash rpc client over an onion address
|
|
func NewOnionClient(onion string, username, password string, acn connectivity.ACN) ZcashClient {
|
|
zc := new(zcashClient)
|
|
zc.address = onion + ".onion:9878"
|
|
zc.client = http.Client{
|
|
Transport: &http.Transport{
|
|
Dial: func(network, addr string) (net.Conn, error) {
|
|
conn, _, err := acn.Open(onion)
|
|
return conn, err
|
|
},
|
|
},
|
|
}
|
|
zc.auth = base64.StdEncoding.EncodeToString([]byte(username + ":" + password))
|
|
return zc
|
|
}
|
|
|
|
// GetTransaction returns a specific transaction given an id
|
|
func (zc *zcashClient) GetBlock(id int) (Block, error) {
|
|
body, err := zc.sendRequest(NewGetBlock(id))
|
|
block := Block{}
|
|
if err == nil {
|
|
result := &ZcashResult{Result: &block}
|
|
err = json.Unmarshal(body, &result)
|
|
}
|
|
return block, err
|
|
}
|
|
|
|
// GetTransaction returns a specific transaction given an id
|
|
func (zc *zcashClient) GetTransaction(id string) (Transaction, error) {
|
|
body, err := zc.sendRequest(NewGetTransaction(id))
|
|
transaction := Transaction{}
|
|
if err == nil {
|
|
result := &ZcashResult{Result: &transaction}
|
|
err = json.Unmarshal(body, &result)
|
|
}
|
|
return transaction, err
|
|
}
|
|
|
|
// ListReceivedTransactionsByAddress returns all the transactions received by a given zcash address
|
|
func (zc *zcashClient) ListReceivedTransactionsByAddress(address string) ([]ZcashTransaction, error) {
|
|
body, err := zc.sendRequest(NewZListReceivedByAddress(address))
|
|
var transactions []ZcashTransaction
|
|
if err == nil {
|
|
result := &ZcashResult{Result: &transactions}
|
|
err = json.Unmarshal(body, &result)
|
|
}
|
|
return transactions, err
|
|
}
|
|
|
|
// SendOne uses z_sendmany to send a single payment to the given address from the given fromAddress
|
|
func (zc *zcashClient) SendOne(fromAddress string, toaddress string, memo string, amount float64) ([]byte, error) {
|
|
jsonStr := NewZSendMany(fromAddress, []ZcashAmount{NewZcashAmount(toaddress, memo, amount)})
|
|
log.Debugf("Zcash SendMany %s", jsonStr)
|
|
return zc.sendRequest(jsonStr)
|
|
}
|
|
|
|
// ValidateAddress returns the result of a z_validateaddress call
|
|
func (zc *zcashClient) ValidateAddress(address string) (ZValidateAddressResponse, error) {
|
|
body, err := zc.sendRequest(NewZValidateAddress(address))
|
|
var validation ZValidateAddressResponse
|
|
if err == nil {
|
|
result := &ZcashResult{Result: &validation}
|
|
log.Debugf("Result: %s", body)
|
|
err = json.Unmarshal(body, &result)
|
|
}
|
|
return validation, err
|
|
}
|
|
|
|
func (zc *zcashClient) sendRequest(jsonStr []byte) ([]byte, error) {
|
|
req, err := http.NewRequest("POST", "http://"+zc.address, bytes.NewBuffer(jsonStr))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
req.Header.Add("Authorization", "Basic "+zc.auth)
|
|
log.Debugf("Sending request to zcash server %v", req)
|
|
resp, err := zc.client.Do(req)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer resp.Body.Close()
|
|
body, err := ioutil.ReadAll(resp.Body)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
log.Debugf("Got response from zcash server %s", body)
|
|
return body, nil
|
|
}
|