c39e35318d
This updates all code to make use of the new chainhash package since the old wire.ShaHash type and related functions have been removed in favor of the abstracted package. Also, while here, rename all variables that included sha in their name to include hash instead.
350 lines
11 KiB
Go
350 lines
11 KiB
Go
// Copyright (c) 2014-2015 The btcsuite developers
|
|
// Use of this source code is governed by an ISC
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package btcrpcclient
|
|
|
|
import (
|
|
"encoding/base64"
|
|
"encoding/json"
|
|
"fmt"
|
|
|
|
"github.com/btcsuite/btcd/btcjson"
|
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
|
"github.com/btcsuite/btcd/wire"
|
|
"github.com/btcsuite/btcutil"
|
|
)
|
|
|
|
// FutureDebugLevelResult is a future promise to deliver the result of a
|
|
// DebugLevelAsync RPC invocation (or an applicable error).
|
|
type FutureDebugLevelResult chan *response
|
|
|
|
// Receive waits for the response promised by the future and returns the result
|
|
// of setting the debug logging level to the passed level specification or the
|
|
// list of of the available subsystems for the special keyword 'show'.
|
|
func (r FutureDebugLevelResult) Receive() (string, error) {
|
|
res, err := receiveFuture(r)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
// Unmashal the result as a string.
|
|
var result string
|
|
err = json.Unmarshal(res, &result)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
return result, nil
|
|
}
|
|
|
|
// DebugLevelAsync returns an instance of a type that can be used to get the
|
|
// result of the RPC at some future time by invoking the Receive function on
|
|
// the returned instance.
|
|
//
|
|
// See DebugLevel for the blocking version and more details.
|
|
//
|
|
// NOTE: This is a btcd extension.
|
|
func (c *Client) DebugLevelAsync(levelSpec string) FutureDebugLevelResult {
|
|
cmd := btcjson.NewDebugLevelCmd(levelSpec)
|
|
return c.sendCmd(cmd)
|
|
}
|
|
|
|
// DebugLevel dynamically sets the debug logging level to the passed level
|
|
// specification.
|
|
//
|
|
// The levelspec can be either a debug level or of the form:
|
|
// <subsystem>=<level>,<subsystem2>=<level2>,...
|
|
//
|
|
// Additionally, the special keyword 'show' can be used to get a list of the
|
|
// available subsystems.
|
|
//
|
|
// NOTE: This is a btcd extension.
|
|
func (c *Client) DebugLevel(levelSpec string) (string, error) {
|
|
return c.DebugLevelAsync(levelSpec).Receive()
|
|
}
|
|
|
|
// FutureCreateEncryptedWalletResult is a future promise to deliver the error
|
|
// result of a CreateEncryptedWalletAsync RPC invocation.
|
|
type FutureCreateEncryptedWalletResult chan *response
|
|
|
|
// Receive waits for and returns the error response promised by the future.
|
|
func (r FutureCreateEncryptedWalletResult) Receive() error {
|
|
_, err := receiveFuture(r)
|
|
return err
|
|
}
|
|
|
|
// CreateEncryptedWalletAsync returns an instance of a type that can be used to
|
|
// get the result of the RPC at some future time by invoking the Receive
|
|
// function on the returned instance.
|
|
//
|
|
// See CreateEncryptedWallet for the blocking version and more details.
|
|
//
|
|
// NOTE: This is a btcwallet extension.
|
|
func (c *Client) CreateEncryptedWalletAsync(passphrase string) FutureCreateEncryptedWalletResult {
|
|
cmd := btcjson.NewCreateEncryptedWalletCmd(passphrase)
|
|
return c.sendCmd(cmd)
|
|
}
|
|
|
|
// CreateEncryptedWallet requests the creation of an encrypted wallet. Wallets
|
|
// managed by btcwallet are only written to disk with encrypted private keys,
|
|
// and generating wallets on the fly is impossible as it requires user input for
|
|
// the encryption passphrase. This RPC specifies the passphrase and instructs
|
|
// the wallet creation. This may error if a wallet is already opened, or the
|
|
// new wallet cannot be written to disk.
|
|
//
|
|
// NOTE: This is a btcwallet extension.
|
|
func (c *Client) CreateEncryptedWallet(passphrase string) error {
|
|
return c.CreateEncryptedWalletAsync(passphrase).Receive()
|
|
}
|
|
|
|
// FutureListAddressTransactionsResult is a future promise to deliver the result
|
|
// of a ListAddressTransactionsAsync RPC invocation (or an applicable error).
|
|
type FutureListAddressTransactionsResult chan *response
|
|
|
|
// Receive waits for the response promised by the future and returns information
|
|
// about all transactions associated with the provided addresses.
|
|
func (r FutureListAddressTransactionsResult) Receive() ([]btcjson.ListTransactionsResult, error) {
|
|
res, err := receiveFuture(r)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// Unmarshal the result as an array of listtransactions objects.
|
|
var transactions []btcjson.ListTransactionsResult
|
|
err = json.Unmarshal(res, &transactions)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return transactions, nil
|
|
}
|
|
|
|
// ListAddressTransactionsAsync returns an instance of a type that can be used
|
|
// to get the result of the RPC at some future time by invoking the Receive
|
|
// function on the returned instance.
|
|
//
|
|
// See ListAddressTransactions for the blocking version and more details.
|
|
//
|
|
// NOTE: This is a btcd extension.
|
|
func (c *Client) ListAddressTransactionsAsync(addresses []btcutil.Address, account string) FutureListAddressTransactionsResult {
|
|
// Convert addresses to strings.
|
|
addrs := make([]string, 0, len(addresses))
|
|
for _, addr := range addresses {
|
|
addrs = append(addrs, addr.EncodeAddress())
|
|
}
|
|
cmd := btcjson.NewListAddressTransactionsCmd(addrs, &account)
|
|
return c.sendCmd(cmd)
|
|
}
|
|
|
|
// ListAddressTransactions returns information about all transactions associated
|
|
// with the provided addresses.
|
|
//
|
|
// NOTE: This is a btcwallet extension.
|
|
func (c *Client) ListAddressTransactions(addresses []btcutil.Address, account string) ([]btcjson.ListTransactionsResult, error) {
|
|
return c.ListAddressTransactionsAsync(addresses, account).Receive()
|
|
}
|
|
|
|
// FutureGetBestBlockResult is a future promise to deliver the result of a
|
|
// GetBestBlockAsync RPC invocation (or an applicable error).
|
|
type FutureGetBestBlockResult chan *response
|
|
|
|
// Receive waits for the response promised by the future and returns the hash
|
|
// and height of the block in the longest (best) chain.
|
|
func (r FutureGetBestBlockResult) Receive() (*chainhash.Hash, int32, error) {
|
|
res, err := receiveFuture(r)
|
|
if err != nil {
|
|
return nil, 0, err
|
|
}
|
|
|
|
// Unmarshal result as a getbestblock result object.
|
|
var bestBlock btcjson.GetBestBlockResult
|
|
err = json.Unmarshal(res, &bestBlock)
|
|
if err != nil {
|
|
return nil, 0, err
|
|
}
|
|
|
|
// Convert to hash from string.
|
|
hash, err := chainhash.NewHashFromStr(bestBlock.Hash)
|
|
if err != nil {
|
|
return nil, 0, err
|
|
}
|
|
|
|
return hash, bestBlock.Height, nil
|
|
}
|
|
|
|
// GetBestBlockAsync returns an instance of a type that can be used to get the
|
|
// result of the RPC at some future time by invoking the Receive function on the
|
|
// returned instance.
|
|
//
|
|
// See GetBestBlock for the blocking version and more details.
|
|
//
|
|
// NOTE: This is a btcd extension.
|
|
func (c *Client) GetBestBlockAsync() FutureGetBestBlockResult {
|
|
cmd := btcjson.NewGetBestBlockCmd()
|
|
return c.sendCmd(cmd)
|
|
}
|
|
|
|
// GetBestBlock returns the hash and height of the block in the longest (best)
|
|
// chain.
|
|
//
|
|
// NOTE: This is a btcd extension.
|
|
func (c *Client) GetBestBlock() (*chainhash.Hash, int32, error) {
|
|
return c.GetBestBlockAsync().Receive()
|
|
}
|
|
|
|
// FutureGetCurrentNetResult is a future promise to deliver the result of a
|
|
// GetCurrentNetAsync RPC invocation (or an applicable error).
|
|
type FutureGetCurrentNetResult chan *response
|
|
|
|
// Receive waits for the response promised by the future and returns the network
|
|
// the server is running on.
|
|
func (r FutureGetCurrentNetResult) Receive() (wire.BitcoinNet, error) {
|
|
res, err := receiveFuture(r)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
|
|
// Unmarshal result as an int64.
|
|
var net int64
|
|
err = json.Unmarshal(res, &net)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
|
|
return wire.BitcoinNet(net), nil
|
|
}
|
|
|
|
// GetCurrentNetAsync returns an instance of a type that can be used to get the
|
|
// result of the RPC at some future time by invoking the Receive function on the
|
|
// returned instance.
|
|
//
|
|
// See GetCurrentNet for the blocking version and more details.
|
|
//
|
|
// NOTE: This is a btcd extension.
|
|
func (c *Client) GetCurrentNetAsync() FutureGetCurrentNetResult {
|
|
cmd := btcjson.NewGetCurrentNetCmd()
|
|
return c.sendCmd(cmd)
|
|
}
|
|
|
|
// GetCurrentNet returns the network the server is running on.
|
|
//
|
|
// NOTE: This is a btcd extension.
|
|
func (c *Client) GetCurrentNet() (wire.BitcoinNet, error) {
|
|
return c.GetCurrentNetAsync().Receive()
|
|
}
|
|
|
|
// FutureExportWatchingWalletResult is a future promise to deliver the result of
|
|
// an ExportWatchingWalletAsync RPC invocation (or an applicable error).
|
|
type FutureExportWatchingWalletResult chan *response
|
|
|
|
// Receive waits for the response promised by the future and returns the
|
|
// exported wallet.
|
|
func (r FutureExportWatchingWalletResult) Receive() ([]byte, []byte, error) {
|
|
res, err := receiveFuture(r)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
// Unmarshal result as a JSON object.
|
|
var obj map[string]interface{}
|
|
err = json.Unmarshal(res, &obj)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
// Check for the wallet and tx string fields in the object.
|
|
base64Wallet, ok := obj["wallet"].(string)
|
|
if !ok {
|
|
return nil, nil, fmt.Errorf("unexpected response type for "+
|
|
"exportwatchingwallet 'wallet' field: %T\n",
|
|
obj["wallet"])
|
|
}
|
|
base64TxStore, ok := obj["tx"].(string)
|
|
if !ok {
|
|
return nil, nil, fmt.Errorf("unexpected response type for "+
|
|
"exportwatchingwallet 'tx' field: %T\n",
|
|
obj["tx"])
|
|
}
|
|
|
|
walletBytes, err := base64.StdEncoding.DecodeString(base64Wallet)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
txStoreBytes, err := base64.StdEncoding.DecodeString(base64TxStore)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
return walletBytes, txStoreBytes, nil
|
|
|
|
}
|
|
|
|
// ExportWatchingWalletAsync returns an instance of a type that can be used to
|
|
// get the result of the RPC at some future time by invoking the Receive
|
|
// function on the returned instance.
|
|
//
|
|
// See ExportWatchingWallet for the blocking version and more details.
|
|
//
|
|
// NOTE: This is a btcwallet extension.
|
|
func (c *Client) ExportWatchingWalletAsync(account string) FutureExportWatchingWalletResult {
|
|
cmd := btcjson.NewExportWatchingWalletCmd(&account, btcjson.Bool(true))
|
|
return c.sendCmd(cmd)
|
|
}
|
|
|
|
// ExportWatchingWallet returns the raw bytes for a watching-only version of
|
|
// wallet.bin and tx.bin, respectively, for the specified account that can be
|
|
// used by btcwallet to enable a wallet which does not have the private keys
|
|
// necessary to spend funds.
|
|
//
|
|
// NOTE: This is a btcwallet extension.
|
|
func (c *Client) ExportWatchingWallet(account string) ([]byte, []byte, error) {
|
|
return c.ExportWatchingWalletAsync(account).Receive()
|
|
}
|
|
|
|
// FutureSessionResult is a future promise to deliver the result of a
|
|
// SessionAsync RPC invocation (or an applicable error).
|
|
type FutureSessionResult chan *response
|
|
|
|
// Receive waits for the response promised by the future and returns the
|
|
// session result.
|
|
func (r FutureSessionResult) Receive() (*btcjson.SessionResult, error) {
|
|
res, err := receiveFuture(r)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// Unmarshal result as a session result object.
|
|
var session btcjson.SessionResult
|
|
err = json.Unmarshal(res, &session)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &session, nil
|
|
}
|
|
|
|
// SessionAsync returns an instance of a type that can be used to get the result
|
|
// of the RPC at some future time by invoking the Receive function on the
|
|
// returned instance.
|
|
//
|
|
// See Session for the blocking version and more details.
|
|
//
|
|
// NOTE: This is a btcsuite extension.
|
|
func (c *Client) SessionAsync() FutureSessionResult {
|
|
// Not supported in HTTP POST mode.
|
|
if c.config.HTTPPostMode {
|
|
return newFutureError(ErrWebsocketsRequired)
|
|
}
|
|
|
|
cmd := btcjson.NewSessionCmd()
|
|
return c.sendCmd(cmd)
|
|
}
|
|
|
|
// Session returns details regarding a websocket client's current connection.
|
|
//
|
|
// This RPC requires the client to be running in websocket mode.
|
|
//
|
|
// NOTE: This is a btcsuite extension.
|
|
func (c *Client) Session() (*btcjson.SessionResult, error) {
|
|
return c.SessionAsync().Receive()
|
|
}
|