Add custom/raw request/response support.
This commit is contained in:
parent
793e66c785
commit
1ec6dde39c
9 changed files with 948 additions and 638 deletions
141
chain.go
141
chain.go
|
@ -7,7 +7,7 @@ package btcrpcclient
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"fmt"
|
"encoding/json"
|
||||||
"github.com/conformal/btcjson"
|
"github.com/conformal/btcjson"
|
||||||
"github.com/conformal/btcutil"
|
"github.com/conformal/btcutil"
|
||||||
"github.com/conformal/btcwire"
|
"github.com/conformal/btcwire"
|
||||||
|
@ -15,23 +15,22 @@ import (
|
||||||
|
|
||||||
// FutureGetBestBlockHashResult is a future promise to deliver the result of a
|
// FutureGetBestBlockHashResult is a future promise to deliver the result of a
|
||||||
// GetBestBlockAsync RPC invocation (or an applicable error).
|
// GetBestBlockAsync RPC invocation (or an applicable error).
|
||||||
type FutureGetBestBlockHashResult chan *futureResult
|
type FutureGetBestBlockHashResult chan *response
|
||||||
|
|
||||||
// Receive waits for the response promised by the future and returns the hash of
|
// Receive waits for the response promised by the future and returns the hash of
|
||||||
// the best block in the longest block chain.
|
// the best block in the longest block chain.
|
||||||
func (r FutureGetBestBlockHashResult) Receive() (*btcwire.ShaHash, error) {
|
func (r FutureGetBestBlockHashResult) Receive() (*btcwire.ShaHash, error) {
|
||||||
reply, err := receiveFuture(r)
|
res, err := receiveFuture(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure the returned data is the expected type.
|
// Unmarshal result as a string.
|
||||||
txHashStr, ok := reply.(string)
|
var txHashStr string
|
||||||
if !ok {
|
err = json.Unmarshal(res, &txHashStr)
|
||||||
return nil, fmt.Errorf("unexpected response type for "+
|
if err != nil {
|
||||||
"getbestblockhash: %T\n", reply)
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return btcwire.NewShaHashFromStr(txHashStr)
|
return btcwire.NewShaHashFromStr(txHashStr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,21 +57,21 @@ func (c *Client) GetBestBlockHash() (*btcwire.ShaHash, error) {
|
||||||
|
|
||||||
// FutureGetBlockResult is a future promise to deliver the result of a
|
// FutureGetBlockResult is a future promise to deliver the result of a
|
||||||
// GetBlockAsync RPC invocation (or an applicable error).
|
// GetBlockAsync RPC invocation (or an applicable error).
|
||||||
type FutureGetBlockResult chan *futureResult
|
type FutureGetBlockResult chan *response
|
||||||
|
|
||||||
// Receive waits for the response promised by the future and returns the raw
|
// Receive waits for the response promised by the future and returns the raw
|
||||||
// block requested from the server given its hash.
|
// block requested from the server given its hash.
|
||||||
func (r FutureGetBlockResult) Receive() (*btcutil.Block, error) {
|
func (r FutureGetBlockResult) Receive() (*btcutil.Block, error) {
|
||||||
reply, err := receiveFuture(r)
|
res, err := receiveFuture(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure the returned data is the expected type.
|
// Unmarshal result as a string.
|
||||||
blockHex, ok := reply.(string)
|
var blockHex string
|
||||||
if !ok {
|
err = json.Unmarshal(res, &blockHex)
|
||||||
return nil, fmt.Errorf("unexpected response type for "+
|
if err != nil {
|
||||||
"getblock (verbose=0): %T\n", reply)
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decode the serialized block hex to raw bytes.
|
// Decode the serialized block hex to raw bytes.
|
||||||
|
@ -120,24 +119,23 @@ func (c *Client) GetBlock(blockHash *btcwire.ShaHash) (*btcutil.Block, error) {
|
||||||
|
|
||||||
// FutureGetBlockVerboseResult is a future promise to deliver the result of a
|
// FutureGetBlockVerboseResult is a future promise to deliver the result of a
|
||||||
// GetBlockVerboseAsync RPC invocation (or an applicable error).
|
// GetBlockVerboseAsync RPC invocation (or an applicable error).
|
||||||
type FutureGetBlockVerboseResult chan *futureResult
|
type FutureGetBlockVerboseResult chan *response
|
||||||
|
|
||||||
// Receive waits for the response promised by the future and returns the data
|
// Receive waits for the response promised by the future and returns the data
|
||||||
// structure from the server with information about the requested block.
|
// structure from the server with information about the requested block.
|
||||||
func (r FutureGetBlockVerboseResult) Receive() (*btcjson.BlockResult, error) {
|
func (r FutureGetBlockVerboseResult) Receive() (*btcjson.BlockResult, error) {
|
||||||
reply, err := receiveFuture(r)
|
res, err := receiveFuture(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure the returned data is the expected type.
|
// Unmarshal the raw result into a BlockResult.
|
||||||
blockResult, ok := reply.(*btcjson.BlockResult)
|
var blockResult btcjson.BlockResult
|
||||||
if !ok {
|
err = json.Unmarshal(res, &blockResult)
|
||||||
return nil, fmt.Errorf("unexpected response type for "+
|
if err != nil {
|
||||||
"getblock (verbose=1): %T\n", reply)
|
return nil, err
|
||||||
}
|
}
|
||||||
|
return &blockResult, nil
|
||||||
return blockResult, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetBlockVerboseAsync returns an instance of a type that can be used to get
|
// GetBlockVerboseAsync returns an instance of a type that can be used to get
|
||||||
|
@ -170,24 +168,23 @@ func (c *Client) GetBlockVerbose(blockHash *btcwire.ShaHash, verboseTx bool) (*b
|
||||||
|
|
||||||
// FutureGetBlockCountResult is a future promise to deliver the result of a
|
// FutureGetBlockCountResult is a future promise to deliver the result of a
|
||||||
// GetBlockCountAsync RPC invocation (or an applicable error).
|
// GetBlockCountAsync RPC invocation (or an applicable error).
|
||||||
type FutureGetBlockCountResult chan *futureResult
|
type FutureGetBlockCountResult chan *response
|
||||||
|
|
||||||
// Receive waits for the response promised by the future and returns the number
|
// Receive waits for the response promised by the future and returns the number
|
||||||
// of blocks in the longest block chain.
|
// of blocks in the longest block chain.
|
||||||
func (r FutureGetBlockCountResult) Receive() (int64, error) {
|
func (r FutureGetBlockCountResult) Receive() (int64, error) {
|
||||||
reply, err := receiveFuture(r)
|
res, err := receiveFuture(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure the returned data is the expected type.
|
// Unmarshal the result as an int64.
|
||||||
count, ok := reply.(float64)
|
var count int64
|
||||||
if !ok {
|
err = json.Unmarshal(res, &count)
|
||||||
return 0, fmt.Errorf("unexpected response type for "+
|
if err != nil {
|
||||||
"getblockcount: %T\n", reply)
|
return 0, err
|
||||||
}
|
}
|
||||||
|
return count, nil
|
||||||
return int64(count), nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetBlockCountAsync returns an instance of a type that can be used to get the
|
// GetBlockCountAsync returns an instance of a type that can be used to get the
|
||||||
|
@ -212,23 +209,22 @@ func (c *Client) GetBlockCount() (int64, error) {
|
||||||
|
|
||||||
// FutureGetDifficultyResult is a future promise to deliver the result of a
|
// FutureGetDifficultyResult is a future promise to deliver the result of a
|
||||||
// GetDifficultyAsync RPC invocation (or an applicable error).
|
// GetDifficultyAsync RPC invocation (or an applicable error).
|
||||||
type FutureGetDifficultyResult chan *futureResult
|
type FutureGetDifficultyResult chan *response
|
||||||
|
|
||||||
// Receive waits for the response promised by the future and returns the
|
// Receive waits for the response promised by the future and returns the
|
||||||
// proof-of-work difficulty as a multiple of the minimum difficulty.
|
// proof-of-work difficulty as a multiple of the minimum difficulty.
|
||||||
func (r FutureGetDifficultyResult) Receive() (float64, error) {
|
func (r FutureGetDifficultyResult) Receive() (float64, error) {
|
||||||
reply, err := receiveFuture(r)
|
res, err := receiveFuture(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure the returned data is the expected type.
|
// Unmarshal the result as a float64.
|
||||||
difficulty, ok := reply.(float64)
|
var difficulty float64
|
||||||
if !ok {
|
err = json.Unmarshal(res, &difficulty)
|
||||||
return 0, fmt.Errorf("unexpected response type for "+
|
if err != nil {
|
||||||
"getdifficulty: %T\n", reply)
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return difficulty, nil
|
return difficulty, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -255,23 +251,22 @@ func (c *Client) GetDifficulty() (float64, error) {
|
||||||
|
|
||||||
// FutureGetBlockHashResult is a future promise to deliver the result of a
|
// FutureGetBlockHashResult is a future promise to deliver the result of a
|
||||||
// GetBlockHashAsync RPC invocation (or an applicable error).
|
// GetBlockHashAsync RPC invocation (or an applicable error).
|
||||||
type FutureGetBlockHashResult chan *futureResult
|
type FutureGetBlockHashResult chan *response
|
||||||
|
|
||||||
// Receive waits for the response promised by the future and returns the hash of
|
// Receive waits for the response promised by the future and returns the hash of
|
||||||
// the block in the best block chain at the given height.
|
// the block in the best block chain at the given height.
|
||||||
func (r FutureGetBlockHashResult) Receive() (*btcwire.ShaHash, error) {
|
func (r FutureGetBlockHashResult) Receive() (*btcwire.ShaHash, error) {
|
||||||
reply, err := receiveFuture(r)
|
res, err := receiveFuture(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure the returned data is the expected type.
|
// Unmarshal the result as a string-encoded sha.
|
||||||
txHashStr, ok := reply.(string)
|
var txHashStr string
|
||||||
if !ok {
|
err = json.Unmarshal(res, &txHashStr)
|
||||||
return nil, fmt.Errorf("unexpected response type for "+
|
if err != nil {
|
||||||
"getblockhash: %T\n", reply)
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return btcwire.NewShaHashFromStr(txHashStr)
|
return btcwire.NewShaHashFromStr(txHashStr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -298,23 +293,24 @@ func (c *Client) GetBlockHash(blockHeight int64) (*btcwire.ShaHash, error) {
|
||||||
|
|
||||||
// FutureGetRawMempoolResult is a future promise to deliver the result of a
|
// FutureGetRawMempoolResult is a future promise to deliver the result of a
|
||||||
// GetRawMempoolAsync RPC invocation (or an applicable error).
|
// GetRawMempoolAsync RPC invocation (or an applicable error).
|
||||||
type FutureGetRawMempoolResult chan *futureResult
|
type FutureGetRawMempoolResult chan *response
|
||||||
|
|
||||||
// Receive waits for the response promised by the future and returns the hashes
|
// Receive waits for the response promised by the future and returns the hashes
|
||||||
// of all transactions in the memory pool.
|
// of all transactions in the memory pool.
|
||||||
func (r FutureGetRawMempoolResult) Receive() ([]*btcwire.ShaHash, error) {
|
func (r FutureGetRawMempoolResult) Receive() ([]*btcwire.ShaHash, error) {
|
||||||
reply, err := receiveFuture(r)
|
res, err := receiveFuture(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure the returned data is the expected type.
|
// Unmarshal the result as an array of strings.
|
||||||
txHashStrs, ok := reply.([]string)
|
var txHashStrs []string
|
||||||
if !ok {
|
err = json.Unmarshal(res, &txHashStrs)
|
||||||
return nil, fmt.Errorf("unexpected response type for "+
|
if err != nil {
|
||||||
"getrawmempool (verbose=false): %T\n", reply)
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create a slice of ShaHash arrays from the string slice.
|
||||||
txHashes := make([]*btcwire.ShaHash, 0, len(txHashStrs))
|
txHashes := make([]*btcwire.ShaHash, 0, len(txHashStrs))
|
||||||
for _, hashStr := range txHashStrs {
|
for _, hashStr := range txHashStrs {
|
||||||
txHash, err := btcwire.NewShaHashFromStr(hashStr)
|
txHash, err := btcwire.NewShaHashFromStr(hashStr)
|
||||||
|
@ -352,24 +348,24 @@ func (c *Client) GetRawMempool() ([]*btcwire.ShaHash, error) {
|
||||||
|
|
||||||
// FutureGetRawMempoolVerboseResult is a future promise to deliver the result of
|
// FutureGetRawMempoolVerboseResult is a future promise to deliver the result of
|
||||||
// a GetRawMempoolVerboseAsync RPC invocation (or an applicable error).
|
// a GetRawMempoolVerboseAsync RPC invocation (or an applicable error).
|
||||||
type FutureGetRawMempoolVerboseResult chan *futureResult
|
type FutureGetRawMempoolVerboseResult chan *response
|
||||||
|
|
||||||
// Receive waits for the response promised by the future and returns a map of
|
// Receive waits for the response promised by the future and returns a map of
|
||||||
// transaction hashes to an associated data structure with information about the
|
// transaction hashes to an associated data structure with information about the
|
||||||
// transaction for all transactions in the memory pool.
|
// transaction for all transactions in the memory pool.
|
||||||
func (r FutureGetRawMempoolVerboseResult) Receive() (map[string]btcjson.GetRawMempoolResult, error) {
|
func (r FutureGetRawMempoolVerboseResult) Receive() (map[string]btcjson.GetRawMempoolResult, error) {
|
||||||
reply, err := receiveFuture(r)
|
res, err := receiveFuture(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure the returned data is the expected type.
|
// Unmarshal the result as a map of strings (tx shas) to their detailed
|
||||||
mempoolItems, ok := reply.(map[string]btcjson.GetRawMempoolResult)
|
// results.
|
||||||
if !ok {
|
var mempoolItems map[string]btcjson.GetRawMempoolResult
|
||||||
return nil, fmt.Errorf("unexpected response type for "+
|
err = json.Unmarshal(res, &mempoolItems)
|
||||||
"getrawmempool (verbose=true): %T\n", reply)
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return mempoolItems, nil
|
return mempoolItems, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -400,24 +396,23 @@ func (c *Client) GetRawMempoolVerbose() (map[string]btcjson.GetRawMempoolResult,
|
||||||
// FutureVerifyChainResult is a future promise to deliver the result of a
|
// FutureVerifyChainResult is a future promise to deliver the result of a
|
||||||
// VerifyChainAsync, VerifyChainLevelAsyncRPC, or VerifyChainBlocksAsync
|
// VerifyChainAsync, VerifyChainLevelAsyncRPC, or VerifyChainBlocksAsync
|
||||||
// invocation (or an applicable error).
|
// invocation (or an applicable error).
|
||||||
type FutureVerifyChainResult chan *futureResult
|
type FutureVerifyChainResult chan *response
|
||||||
|
|
||||||
// Receive waits for the response promised by the future and returns whether
|
// Receive waits for the response promised by the future and returns whether
|
||||||
// or not the chain verified based on the check level and number of blocks
|
// or not the chain verified based on the check level and number of blocks
|
||||||
// to verify specified in the original call.
|
// to verify specified in the original call.
|
||||||
func (r FutureVerifyChainResult) Receive() (bool, error) {
|
func (r FutureVerifyChainResult) Receive() (bool, error) {
|
||||||
reply, err := receiveFuture(r)
|
res, err := receiveFuture(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure the returned data is the expected type.
|
// Unmarshal the result as a boolean.
|
||||||
verified, ok := reply.(bool)
|
var verified bool
|
||||||
if !ok {
|
err = json.Unmarshal(res, &verified)
|
||||||
return false, fmt.Errorf("unexpected response type for "+
|
if err != nil {
|
||||||
"verifychain: %T\n", reply)
|
return false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return verified, nil
|
return verified, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ package btcrpcclient
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/conformal/btcjson"
|
"github.com/conformal/btcjson"
|
||||||
"github.com/conformal/btcutil"
|
"github.com/conformal/btcutil"
|
||||||
|
@ -15,24 +16,23 @@ import (
|
||||||
|
|
||||||
// FutureDebugLevelResult is a future promise to deliver the result of a
|
// FutureDebugLevelResult is a future promise to deliver the result of a
|
||||||
// DebugLevelAsync RPC invocation (or an applicable error).
|
// DebugLevelAsync RPC invocation (or an applicable error).
|
||||||
type FutureDebugLevelResult chan *futureResult
|
type FutureDebugLevelResult chan *response
|
||||||
|
|
||||||
// Receive waits for the response promised by the future and returns the result
|
// 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
|
// of setting the debug logging level to the passed level specification or the
|
||||||
// list of of the available subsystems for the special keyword 'show'.
|
// list of of the available subsystems for the special keyword 'show'.
|
||||||
func (r FutureDebugLevelResult) Receive() (string, error) {
|
func (r FutureDebugLevelResult) Receive() (string, error) {
|
||||||
reply, err := receiveFuture(r)
|
res, err := receiveFuture(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure the returned data is the expected type.
|
// Unmashal the result as a string.
|
||||||
result, ok := reply.(string)
|
var result string
|
||||||
if !ok {
|
err = json.Unmarshal(res, &result)
|
||||||
return "", fmt.Errorf("unexpected response type for "+
|
if err != nil {
|
||||||
"debuglevel: %T\n", reply)
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,7 +69,7 @@ func (c *Client) DebugLevel(levelSpec string) (string, error) {
|
||||||
|
|
||||||
// FutureCreateEncryptedWalletResult is a future promise to deliver the error
|
// FutureCreateEncryptedWalletResult is a future promise to deliver the error
|
||||||
// result of a CreateEncryptedWalletAsync RPC invocation.
|
// result of a CreateEncryptedWalletAsync RPC invocation.
|
||||||
type FutureCreateEncryptedWalletResult chan *futureResult
|
type FutureCreateEncryptedWalletResult chan *response
|
||||||
|
|
||||||
// Receive waits for and returns the error response promised by the future.
|
// Receive waits for and returns the error response promised by the future.
|
||||||
func (r FutureCreateEncryptedWalletResult) Receive() error {
|
func (r FutureCreateEncryptedWalletResult) Receive() error {
|
||||||
|
@ -104,28 +104,22 @@ func (c *Client) CreateEncryptedWallet(passphrase string) error {
|
||||||
|
|
||||||
// FutureListAddressTransactionsResult is a future promise to deliver the result
|
// FutureListAddressTransactionsResult is a future promise to deliver the result
|
||||||
// of a ListAddressTransactionsAsync RPC invocation (or an applicable error).
|
// of a ListAddressTransactionsAsync RPC invocation (or an applicable error).
|
||||||
type FutureListAddressTransactionsResult chan *futureResult
|
type FutureListAddressTransactionsResult chan *response
|
||||||
|
|
||||||
// Receive waits for the response promised by the future and returns information
|
// Receive waits for the response promised by the future and returns information
|
||||||
// about all transactions associated with the provided addresses.
|
// about all transactions associated with the provided addresses.
|
||||||
func (r FutureListAddressTransactionsResult) Receive() ([]btcjson.ListTransactionsResult, error) {
|
func (r FutureListAddressTransactionsResult) Receive() ([]btcjson.ListTransactionsResult, error) {
|
||||||
reply, err := receiveFuture(r)
|
res, err := receiveFuture(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// No transactions.
|
// Unmarshal the result as an array of listtransactions objects.
|
||||||
if reply == nil {
|
var transactions []btcjson.ListTransactionsResult
|
||||||
return nil, nil
|
err = json.Unmarshal(res, &transactions)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure the returned data is the expected type.
|
|
||||||
transactions, ok := reply.([]btcjson.ListTransactionsResult)
|
|
||||||
if !ok {
|
|
||||||
return nil, fmt.Errorf("unexpected response type for "+
|
|
||||||
"listaddresstransactions: %T\n", reply)
|
|
||||||
}
|
|
||||||
|
|
||||||
return transactions, nil
|
return transactions, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,30 +155,30 @@ func (c *Client) ListAddressTransactions(addresses []btcutil.Address, account st
|
||||||
|
|
||||||
// FutureGetBestBlockResult is a future promise to deliver the result of a
|
// FutureGetBestBlockResult is a future promise to deliver the result of a
|
||||||
// GetBestBlockAsync RPC invocation (or an applicable error).
|
// GetBestBlockAsync RPC invocation (or an applicable error).
|
||||||
type FutureGetBestBlockResult chan *futureResult
|
type FutureGetBestBlockResult chan *response
|
||||||
|
|
||||||
// Receive waits for the response promised by the future and returns the hash
|
// Receive waits for the response promised by the future and returns the hash
|
||||||
// and height of the block in the longest (best) chain.
|
// and height of the block in the longest (best) chain.
|
||||||
func (r FutureGetBestBlockResult) Receive() (*btcwire.ShaHash, int32, error) {
|
func (r FutureGetBestBlockResult) Receive() (*btcwire.ShaHash, int32, error) {
|
||||||
reply, err := receiveFuture(r)
|
res, err := receiveFuture(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, 0, err
|
return nil, 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure the returned data is the expected type.
|
// Unmarsal result as a getbestblock result object.
|
||||||
result, ok := reply.(*btcws.GetBestBlockResult)
|
var bestBlock btcws.GetBestBlockResult
|
||||||
if !ok {
|
err = json.Unmarshal(res, &bestBlock)
|
||||||
return nil, 0, fmt.Errorf("unexpected response type for "+
|
if err != nil {
|
||||||
"getbestblock: %T\n", reply)
|
return nil, 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert hash string.
|
// Convert hash string.
|
||||||
hash, err := btcwire.NewShaHashFromStr(result.Hash)
|
hash, err := btcwire.NewShaHashFromStr(bestBlock.Hash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, 0, err
|
return nil, 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return hash, result.Height, nil
|
return hash, bestBlock.Height, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetBestBlockAsync returns an instance of a type that can be used to get the
|
// GetBestBlockAsync returns an instance of a type that can be used to get the
|
||||||
|
@ -211,24 +205,24 @@ func (c *Client) GetBestBlock() (*btcwire.ShaHash, int32, error) {
|
||||||
|
|
||||||
// FutureGetCurrentNetResult is a future promise to deliver the result of a
|
// FutureGetCurrentNetResult is a future promise to deliver the result of a
|
||||||
// GetCurrentNetAsync RPC invocation (or an applicable error).
|
// GetCurrentNetAsync RPC invocation (or an applicable error).
|
||||||
type FutureGetCurrentNetResult chan *futureResult
|
type FutureGetCurrentNetResult chan *response
|
||||||
|
|
||||||
// Receive waits for the response promised by the future and returns the network
|
// Receive waits for the response promised by the future and returns the network
|
||||||
// the server is running on.
|
// the server is running on.
|
||||||
func (r FutureGetCurrentNetResult) Receive() (btcwire.BitcoinNet, error) {
|
func (r FutureGetCurrentNetResult) Receive() (btcwire.BitcoinNet, error) {
|
||||||
reply, err := receiveFuture(r)
|
res, err := receiveFuture(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure the returned data is the expected type.
|
// Unmarshal result as an int64.
|
||||||
fnet, ok := reply.(float64)
|
var net int64
|
||||||
if !ok {
|
err = json.Unmarshal(res, &net)
|
||||||
return 0, fmt.Errorf("unexpected response type for "+
|
if err != nil {
|
||||||
"getcurrentnet: %T\n", reply)
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return btcwire.BitcoinNet(fnet), nil
|
return btcwire.BitcoinNet(net), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetCurrentNetAsync returns an instance of a type that can be used to get the
|
// GetCurrentNetAsync returns an instance of a type that can be used to get the
|
||||||
|
@ -254,34 +248,35 @@ func (c *Client) GetCurrentNet() (btcwire.BitcoinNet, error) {
|
||||||
|
|
||||||
// FutureExportWatchingWalletResult is a future promise to deliver the result of
|
// FutureExportWatchingWalletResult is a future promise to deliver the result of
|
||||||
// an ExportWatchingWalletAsync RPC invocation (or an applicable error).
|
// an ExportWatchingWalletAsync RPC invocation (or an applicable error).
|
||||||
type FutureExportWatchingWalletResult chan *futureResult
|
type FutureExportWatchingWalletResult chan *response
|
||||||
|
|
||||||
// Receive waits for the response promised by the future and returns the
|
// Receive waits for the response promised by the future and returns the
|
||||||
// exported wallet.
|
// exported wallet.
|
||||||
func (r FutureExportWatchingWalletResult) Receive() ([]byte, []byte, error) {
|
func (r FutureExportWatchingWalletResult) Receive() ([]byte, []byte, error) {
|
||||||
reply, err := receiveFuture(r)
|
res, err := receiveFuture(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure the returned data is the expected type.
|
// Unmarshal result as a JSON object.
|
||||||
result, ok := reply.(map[string]interface{})
|
var obj map[string]interface{}
|
||||||
if !ok {
|
err = json.Unmarshal(res, &obj)
|
||||||
return nil, nil, fmt.Errorf("unexpected response type for "+
|
if err != nil {
|
||||||
"exportwatchingwallet: %T\n", reply)
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
base64Wallet, ok := result["wallet"].(string)
|
// Check for the wallet and tx string fields in the object.
|
||||||
|
base64Wallet, ok := obj["wallet"].(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, nil, fmt.Errorf("unexpected response type for "+
|
return nil, nil, fmt.Errorf("unexpected response type for "+
|
||||||
"exportwatchingwallet 'wallet' field: %T\n",
|
"exportwatchingwallet 'wallet' field: %T\n",
|
||||||
result["wallet"])
|
obj["wallet"])
|
||||||
}
|
}
|
||||||
base64TxStore, ok := result["tx"].(string)
|
base64TxStore, ok := obj["tx"].(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, nil, fmt.Errorf("unexpected response type for "+
|
return nil, nil, fmt.Errorf("unexpected response type for "+
|
||||||
"exportwatchingwallet 'tx' field: %T\n",
|
"exportwatchingwallet 'tx' field: %T\n",
|
||||||
result["tx"])
|
obj["tx"])
|
||||||
}
|
}
|
||||||
|
|
||||||
walletBytes, err := base64.StdEncoding.DecodeString(base64Wallet)
|
walletBytes, err := base64.StdEncoding.DecodeString(base64Wallet)
|
||||||
|
|
|
@ -64,27 +64,20 @@ const (
|
||||||
connectionRetryInterval = time.Second * 5
|
connectionRetryInterval = time.Second * 5
|
||||||
)
|
)
|
||||||
|
|
||||||
// futureResult holds information about a future promise to deliver the result
|
|
||||||
// of an asynchronous request.
|
|
||||||
type futureResult struct {
|
|
||||||
reply *btcjson.Reply
|
|
||||||
err error
|
|
||||||
}
|
|
||||||
|
|
||||||
// sendPostDetails houses an HTTP POST request to send to an RPC server as well
|
// sendPostDetails houses an HTTP POST request to send to an RPC server as well
|
||||||
// as the original JSON-RPC command and a channel to reply on when the server
|
// as the original JSON-RPC command and a channel to reply on when the server
|
||||||
// responds with the result.
|
// responds with the result.
|
||||||
type sendPostDetails struct {
|
type sendPostDetails struct {
|
||||||
command btcjson.Cmd
|
command btcjson.Cmd
|
||||||
request *http.Request
|
request *http.Request
|
||||||
responseChan chan *futureResult
|
responseChan chan *response
|
||||||
}
|
}
|
||||||
|
|
||||||
// jsonRequest holds information about a json request that is used to properly
|
// jsonRequest holds information about a json request that is used to properly
|
||||||
// detect, interpret, and deliver a reply to it.
|
// detect, interpret, and deliver a reply to it.
|
||||||
type jsonRequest struct {
|
type jsonRequest struct {
|
||||||
cmd btcjson.Cmd
|
cmd btcjson.Cmd
|
||||||
responseChan chan *futureResult
|
responseChan chan *response
|
||||||
}
|
}
|
||||||
|
|
||||||
// Client represents a Bitcoin RPC client which allows easy access to the
|
// Client represents a Bitcoin RPC client which allows easy access to the
|
||||||
|
@ -231,70 +224,96 @@ func (c *Client) trackRegisteredNtfns(cmd btcjson.Cmd) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// handleMessage is the main handler for incoming requests. It enforces
|
type (
|
||||||
// authentication, parses the incoming json, looks up and executes handlers
|
// inMessage is the first type that an incoming message is unmarshaled
|
||||||
// (including pass through for standard RPC commands), sends the appropriate
|
// into. It supports both requests (for notification support) and
|
||||||
// response. It also detects commands which are marked as long-running and
|
// responses. The partially-unmarshaled message is a notification if
|
||||||
// sends them off to the asyncHander for processing.
|
// the embedded ID (from the response) is nil. Otherwise, it is a
|
||||||
|
// response.
|
||||||
|
inMessage struct {
|
||||||
|
ID *uint64 `json:"id"`
|
||||||
|
*rawNotification
|
||||||
|
*rawResponse
|
||||||
|
}
|
||||||
|
|
||||||
|
// rawNotification is a partially-unmarshaled JSON-RPC notification.
|
||||||
|
rawNotification struct {
|
||||||
|
Method string `json:"method"`
|
||||||
|
Params []json.RawMessage `json:"params"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// rawResponse is a partially-unmarshaled JSON-RPC response. For this
|
||||||
|
// to be valid (according to JSON-RPC 1.0 spec), ID may not be nil.
|
||||||
|
rawResponse struct {
|
||||||
|
Result json.RawMessage `json:"result"`
|
||||||
|
Error *btcjson.Error `json:"error"`
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// response is the raw bytes of a JSON-RPC result, or the error if the response
|
||||||
|
// error object was non-null.
|
||||||
|
type response struct {
|
||||||
|
result []byte
|
||||||
|
err error
|
||||||
|
}
|
||||||
|
|
||||||
|
// result checks whether the unmarshaled response contains a non-nil error,
|
||||||
|
// returning an unmarshaled btcjson.Error (or an unmarshaling error) if so.
|
||||||
|
// If the response is not an error, the raw bytes of the request are
|
||||||
|
// returned for further unmashaling into specific result types.
|
||||||
|
func (r rawResponse) result() (result []byte, err error) {
|
||||||
|
if r.Error != nil {
|
||||||
|
return nil, r.Error
|
||||||
|
}
|
||||||
|
return r.Result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// handleMessage is the main handler for incoming notifications and responses.
|
||||||
func (c *Client) handleMessage(msg []byte) {
|
func (c *Client) handleMessage(msg []byte) {
|
||||||
// Attempt to unmarshal the message as a known JSON-RPC command.
|
// Attempt to unmarshal the message as either a notifiation or response.
|
||||||
if cmd, err := btcjson.ParseMarshaledCmd(msg); err == nil {
|
in := inMessage{}
|
||||||
// Commands that have an ID associated with them are not
|
err := json.Unmarshal(msg, &in)
|
||||||
// notifications. Since this is a client, it should not
|
if err != nil {
|
||||||
// be receiving non-notifications.
|
log.Warnf("Remote server sent invalid message: %v", err)
|
||||||
if cmd.Id() != nil {
|
return
|
||||||
// Invalid response
|
}
|
||||||
log.Warnf("Remote server sent a non-notification "+
|
|
||||||
"JSON-RPC Request (Id: %v)", cmd.Id())
|
// JSON-RPC 1.0 notifications are requests with a null id.
|
||||||
|
if in.ID == nil {
|
||||||
|
ntfn := in.rawNotification
|
||||||
|
if ntfn == nil {
|
||||||
|
log.Warn("Malformed notification: missing " +
|
||||||
|
"method and parameters")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if ntfn.Method == "" {
|
||||||
|
log.Warn("Malformed notification: missing method")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// params are not optional: nil isn't valid (but len == 0 is)
|
||||||
|
if ntfn.Params == nil {
|
||||||
|
log.Warn("Malformed notification: missing params")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Deliver the notification.
|
// Deliver the notification.
|
||||||
log.Tracef("Received notification [%s]", cmd.Method())
|
log.Tracef("Received notification [%s]", in.Method)
|
||||||
c.handleNotification(cmd)
|
c.handleNotification(in.rawNotification)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// The message was not a command/notification, so it should be a reply
|
if in.rawResponse == nil {
|
||||||
// to a previous request.
|
log.Warn("Malformed response: missing result and error")
|
||||||
|
|
||||||
var r btcjson.Reply
|
|
||||||
if err := json.Unmarshal([]byte(msg), &r); err != nil {
|
|
||||||
log.Warnf("Unable to unmarshal inbound message as " +
|
|
||||||
"notification or response")
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure the reply has an id.
|
id := *in.ID
|
||||||
if r.Id == nil {
|
log.Tracef("Received response for id %d (result %s)", id, in.Result)
|
||||||
log.Warnf("Received response with no id")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ensure the id is the expected type.
|
|
||||||
fid, ok := (*r.Id).(float64)
|
|
||||||
if !ok {
|
|
||||||
log.Warnf("Received unexpected id type: %T (value %v)",
|
|
||||||
*r.Id, *r.Id)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
id := uint64(fid)
|
|
||||||
log.Tracef("Received response for id %d (result %v)", id, r.Result)
|
|
||||||
request := c.removeRequest(id)
|
request := c.removeRequest(id)
|
||||||
|
|
||||||
// Nothing more to do if there is no request associated with this reply.
|
// Nothing more to do if there is no request associated with this reply.
|
||||||
if request == nil || request.responseChan == nil {
|
if request == nil || request.responseChan == nil {
|
||||||
log.Warnf("Received unexpected reply: %s (id %d)", r.Result, id)
|
log.Warnf("Received unexpected reply: %s (id %d)", in.Result,
|
||||||
return
|
id)
|
||||||
}
|
|
||||||
|
|
||||||
// Unmarshal the reply into a concrete result if possible and deliver
|
|
||||||
// it to the associated channel.
|
|
||||||
reply, err := btcjson.ReadResultCmd(request.cmd.Method(), []byte(msg))
|
|
||||||
if err != nil {
|
|
||||||
log.Warnf("Failed to unmarshal reply to command [%s] "+
|
|
||||||
"(id %d): %v", request.cmd.Method(), id, err)
|
|
||||||
request.responseChan <- &futureResult{reply: nil, err: err}
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -303,8 +322,9 @@ func (c *Client) handleMessage(msg []byte) {
|
||||||
// can automatically be re-established on reconnect.
|
// can automatically be re-established on reconnect.
|
||||||
c.trackRegisteredNtfns(request.cmd)
|
c.trackRegisteredNtfns(request.cmd)
|
||||||
|
|
||||||
// Deliver the reply.
|
// Deliver the response.
|
||||||
request.responseChan <- &futureResult{reply: &reply, err: nil}
|
result, err := in.rawResponse.result()
|
||||||
|
request.responseChan <- &response{result: result, err: err}
|
||||||
}
|
}
|
||||||
|
|
||||||
// wsInHandler handles all incoming messages for the websocket connection
|
// wsInHandler handles all incoming messages for the websocket connection
|
||||||
|
@ -576,24 +596,17 @@ func (c *Client) handleSendPostMessage(details *sendPostDetails) {
|
||||||
log.Tracef("Sending command [%s] with id %d", cmd.Method(), cmd.Id())
|
log.Tracef("Sending command [%s] with id %d", cmd.Method(), cmd.Id())
|
||||||
httpResponse, err := c.httpClient.Do(details.request)
|
httpResponse, err := c.httpClient.Do(details.request)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
details.responseChan <- &futureResult{reply: nil, err: err}
|
details.responseChan <- &response{result: nil, err: err}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read the raw bytes and close the response.
|
// Read the raw bytes and close the response.
|
||||||
respBytes, err := btcjson.GetRaw(httpResponse.Body)
|
resp, err := btcjson.GetRaw(httpResponse.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
details.responseChan <- &futureResult{reply: nil, err: err}
|
details.responseChan <- &response{result: nil, err: err}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
details.responseChan <- &response{result: resp, err: nil}
|
||||||
// Unmarshal the reply into a concrete result if possible.
|
|
||||||
reply, err := btcjson.ReadResultCmd(cmd.Method(), respBytes)
|
|
||||||
if err != nil {
|
|
||||||
details.responseChan <- &futureResult{reply: nil, err: err}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
details.responseChan <- &futureResult{reply: &reply, err: nil}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// sendPostHandler handles all outgoing messages when the client is running
|
// sendPostHandler handles all outgoing messages when the client is running
|
||||||
|
@ -620,9 +633,9 @@ cleanup:
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case details := <-c.sendPostChan:
|
case details := <-c.sendPostChan:
|
||||||
details.responseChan <- &futureResult{
|
details.responseChan <- &response{
|
||||||
reply: nil,
|
result: nil,
|
||||||
err: ErrClientShutdown,
|
err: ErrClientShutdown,
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -637,17 +650,17 @@ cleanup:
|
||||||
// sendPostRequest sends the passed HTTP request to the RPC server using the
|
// sendPostRequest sends the passed HTTP request to the RPC server using the
|
||||||
// HTTP client associated with the client. It is backed by a buffered channel,
|
// HTTP client associated with the client. It is backed by a buffered channel,
|
||||||
// so it will not block until the send channel is full.
|
// so it will not block until the send channel is full.
|
||||||
func (c *Client) sendPostRequest(req *http.Request, command btcjson.Cmd, responseChan chan *futureResult) {
|
func (c *Client) sendPostRequest(req *http.Request, command btcjson.Cmd, responseChan chan *response) {
|
||||||
// Don't send the message if shutting down.
|
// Don't send the message if shutting down.
|
||||||
select {
|
select {
|
||||||
case <-c.shutdown:
|
case <-c.shutdown:
|
||||||
responseChan <- &futureResult{reply: nil, err: ErrClientShutdown}
|
responseChan <- &response{result: nil, err: ErrClientShutdown}
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
|
|
||||||
c.sendPostChan <- &sendPostDetails{
|
c.sendPostChan <- &sendPostDetails{
|
||||||
request: req,
|
|
||||||
command: command,
|
command: command,
|
||||||
|
request: req,
|
||||||
responseChan: responseChan,
|
responseChan: responseChan,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -655,9 +668,9 @@ func (c *Client) sendPostRequest(req *http.Request, command btcjson.Cmd, respons
|
||||||
// newFutureError returns a new future result channel that already has the
|
// newFutureError returns a new future result channel that already has the
|
||||||
// passed error waitin on the channel with the reply set to nil. This is useful
|
// passed error waitin on the channel with the reply set to nil. This is useful
|
||||||
// to easily return errors from the various Async functions.
|
// to easily return errors from the various Async functions.
|
||||||
func newFutureError(err error) chan *futureResult {
|
func newFutureError(err error) chan *response {
|
||||||
responseChan := make(chan *futureResult, 1)
|
responseChan := make(chan *response, 1)
|
||||||
responseChan <- &futureResult{err: err}
|
responseChan <- &response{err: err}
|
||||||
return responseChan
|
return responseChan
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -665,27 +678,10 @@ func newFutureError(err error) chan *futureResult {
|
||||||
// reply or any errors. The examined errors include an error in the
|
// reply or any errors. The examined errors include an error in the
|
||||||
// futureResult and the error in the reply from the server. This will block
|
// futureResult and the error in the reply from the server. This will block
|
||||||
// until the result is available on the passed channel.
|
// until the result is available on the passed channel.
|
||||||
func receiveFuture(responseChan chan *futureResult) (interface{}, error) {
|
func receiveFuture(f chan *response) ([]byte, error) {
|
||||||
// Wait for a response on the returned channel.
|
// Wait for a response on the returned channel.
|
||||||
response := <-responseChan
|
r := <-f
|
||||||
if response.err != nil {
|
return r.result, r.err
|
||||||
return nil, response.err
|
|
||||||
}
|
|
||||||
|
|
||||||
// At this point, the command was either sent to the server and
|
|
||||||
// there is a response from it, or it is intentionally a nil result
|
|
||||||
// used to bybass sends for cases such a requesting notifications when
|
|
||||||
// there are no handlers.
|
|
||||||
reply := response.reply
|
|
||||||
if reply == nil {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if reply.Error != nil {
|
|
||||||
return nil, reply.Error
|
|
||||||
}
|
|
||||||
|
|
||||||
return reply.Result, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// marshalAndSendPost marshals the passed command to JSON-RPC and sends it to
|
// marshalAndSendPost marshals the passed command to JSON-RPC and sends it to
|
||||||
|
@ -694,10 +690,10 @@ func receiveFuture(responseChan chan *futureResult) (interface{}, error) {
|
||||||
// and closed for each command when using this method, however, the underlying
|
// and closed for each command when using this method, however, the underlying
|
||||||
// HTTP client might coalesce multiple commands depending on several factors
|
// HTTP client might coalesce multiple commands depending on several factors
|
||||||
// including the remote server configuration.
|
// including the remote server configuration.
|
||||||
func (c *Client) marshalAndSendPost(cmd btcjson.Cmd, responseChan chan *futureResult) {
|
func (c *Client) marshalAndSendPost(cmd btcjson.Cmd, responseChan chan *response) {
|
||||||
marshalledJSON, err := json.Marshal(cmd)
|
marshalledJSON, err := json.Marshal(cmd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
responseChan <- &futureResult{reply: nil, err: err}
|
responseChan <- &response{result: nil, err: err}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -709,7 +705,7 @@ func (c *Client) marshalAndSendPost(cmd btcjson.Cmd, responseChan chan *futureRe
|
||||||
url := protocol + "://" + c.config.Host
|
url := protocol + "://" + c.config.Host
|
||||||
req, err := http.NewRequest("POST", url, bytes.NewReader(marshalledJSON))
|
req, err := http.NewRequest("POST", url, bytes.NewReader(marshalledJSON))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
responseChan <- &futureResult{reply: nil, err: err}
|
responseChan <- &response{result: nil, err: err}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
req.Close = true
|
req.Close = true
|
||||||
|
@ -724,10 +720,10 @@ func (c *Client) marshalAndSendPost(cmd btcjson.Cmd, responseChan chan *futureRe
|
||||||
|
|
||||||
// marshalAndSend marshals the passed command to JSON-RPC and sends it to the
|
// marshalAndSend marshals the passed command to JSON-RPC and sends it to the
|
||||||
// server. It returns a response channel on which the reply will be delivered.
|
// server. It returns a response channel on which the reply will be delivered.
|
||||||
func (c *Client) marshalAndSend(cmd btcjson.Cmd, responseChan chan *futureResult) {
|
func (c *Client) marshalAndSend(cmd btcjson.Cmd, responseChan chan *response) {
|
||||||
marshalledJSON, err := json.Marshal(cmd)
|
marshalledJSON, err := cmd.MarshalJSON()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
responseChan <- &futureResult{reply: nil, err: err}
|
responseChan <- &response{result: nil, err: err}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -739,12 +735,12 @@ func (c *Client) marshalAndSend(cmd btcjson.Cmd, responseChan chan *futureResult
|
||||||
// response channel on which the reply will be deliver at some point in the
|
// response channel on which the reply will be deliver at some point in the
|
||||||
// future. It handles both websocket and HTTP POST mode depending on the
|
// future. It handles both websocket and HTTP POST mode depending on the
|
||||||
// configuration of the client.
|
// configuration of the client.
|
||||||
func (c *Client) sendCmd(cmd btcjson.Cmd) chan *futureResult {
|
func (c *Client) sendCmd(cmd btcjson.Cmd) chan *response {
|
||||||
// Choose which marshal and send function to use depending on whether
|
// Choose which marshal and send function to use depending on whether
|
||||||
// the client running in HTTP POST mode or not. When running in HTTP
|
// the client running in HTTP POST mode or not. When running in HTTP
|
||||||
// POST mode, the command is issued via an HTTP client. Otherwise,
|
// POST mode, the command is issued via an HTTP client. Otherwise,
|
||||||
// the command is issued via the asynchronous websocket channels.
|
// the command is issued via the asynchronous websocket channels.
|
||||||
responseChan := make(chan *futureResult, 1)
|
responseChan := make(chan *response, 1)
|
||||||
if c.config.HttpPostMode {
|
if c.config.HttpPostMode {
|
||||||
c.marshalAndSendPost(cmd, responseChan)
|
c.marshalAndSendPost(cmd, responseChan)
|
||||||
return responseChan
|
return responseChan
|
||||||
|
@ -804,9 +800,9 @@ func (c *Client) Disconnect() {
|
||||||
c.requestLock.Lock()
|
c.requestLock.Lock()
|
||||||
for e := c.requestList.Front(); e != nil; e = e.Next() {
|
for e := c.requestList.Front(); e != nil; e = e.Next() {
|
||||||
req := e.Value.(*jsonRequest)
|
req := e.Value.(*jsonRequest)
|
||||||
req.responseChan <- &futureResult{
|
req.responseChan <- &response{
|
||||||
reply: nil,
|
result: nil,
|
||||||
err: ErrClientDisconnect,
|
err: ErrClientDisconnect,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
c.requestLock.Unlock()
|
c.requestLock.Unlock()
|
||||||
|
@ -834,9 +830,9 @@ func (c *Client) Shutdown() {
|
||||||
c.requestLock.Lock()
|
c.requestLock.Lock()
|
||||||
for e := c.requestList.Front(); e != nil; e = e.Next() {
|
for e := c.requestList.Front(); e != nil; e = e.Next() {
|
||||||
req := e.Value.(*jsonRequest)
|
req := e.Value.(*jsonRequest)
|
||||||
req.responseChan <- &futureResult{
|
req.responseChan <- &response{
|
||||||
reply: nil,
|
result: nil,
|
||||||
err: ErrClientShutdown,
|
err: ErrClientShutdown,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
c.requestLock.Unlock()
|
c.requestLock.Unlock()
|
||||||
|
|
94
mining.go
94
mining.go
|
@ -6,28 +6,28 @@ package btcrpcclient
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"fmt"
|
"encoding/json"
|
||||||
"github.com/conformal/btcjson"
|
"github.com/conformal/btcjson"
|
||||||
"github.com/conformal/btcutil"
|
"github.com/conformal/btcutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
// FutureGetGenerateResult is a future promise to deliver the result of a
|
// FutureGetGenerateResult is a future promise to deliver the result of a
|
||||||
// GetGenerateAsync RPC invocation (or an applicable error).
|
// GetGenerateAsync RPC invocation (or an applicable error).
|
||||||
type FutureGetGenerateResult chan *futureResult
|
type FutureGetGenerateResult chan *response
|
||||||
|
|
||||||
// Receive waits for the response promised by the future and returns true if the
|
// Receive waits for the response promised by the future and returns true if the
|
||||||
// server is set to mine, otherwise false.
|
// server is set to mine, otherwise false.
|
||||||
func (r FutureGetGenerateResult) Receive() (bool, error) {
|
func (r FutureGetGenerateResult) Receive() (bool, error) {
|
||||||
reply, err := receiveFuture(r)
|
res, err := receiveFuture(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure the returned data is the expected type.
|
// Unmarshal result as a boolean.
|
||||||
result, ok := reply.(bool)
|
var result bool
|
||||||
if !ok {
|
err = json.Unmarshal(res, &result)
|
||||||
return false, fmt.Errorf("unexpected response type for "+
|
if err != nil {
|
||||||
"getgenerate: %T\n", reply)
|
return false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return result, nil
|
return result, nil
|
||||||
|
@ -55,7 +55,7 @@ func (c *Client) GetGenerate() (bool, error) {
|
||||||
|
|
||||||
// FutureSetGenerateResult is a future promise to deliver the result of a
|
// FutureSetGenerateResult is a future promise to deliver the result of a
|
||||||
// SetGenerateAsync RPC invocation (or an applicable error).
|
// SetGenerateAsync RPC invocation (or an applicable error).
|
||||||
type FutureSetGenerateResult chan *futureResult
|
type FutureSetGenerateResult chan *response
|
||||||
|
|
||||||
// Receive waits for the response promised by the future and returns an error if
|
// Receive waits for the response promised by the future and returns an error if
|
||||||
// any occurred when setting the server to generate coins (mine) or not.
|
// any occurred when setting the server to generate coins (mine) or not.
|
||||||
|
@ -90,22 +90,22 @@ func (c *Client) SetGenerate(enable bool, numCPUs int) error {
|
||||||
|
|
||||||
// FutureGetHashesPerSecResult is a future promise to deliver the result of a
|
// FutureGetHashesPerSecResult is a future promise to deliver the result of a
|
||||||
// GetHashesPerSecAsync RPC invocation (or an applicable error).
|
// GetHashesPerSecAsync RPC invocation (or an applicable error).
|
||||||
type FutureGetHashesPerSecResult chan *futureResult
|
type FutureGetHashesPerSecResult chan *response
|
||||||
|
|
||||||
// Receive waits for the response promised by the future and returns a recent
|
// Receive waits for the response promised by the future and returns a recent
|
||||||
// hashes per second performance measurement while generating coins (mining).
|
// hashes per second performance measurement while generating coins (mining).
|
||||||
// Zero is returned if the server is not mining.
|
// Zero is returned if the server is not mining.
|
||||||
func (r FutureGetHashesPerSecResult) Receive() (int64, error) {
|
func (r FutureGetHashesPerSecResult) Receive() (int64, error) {
|
||||||
reply, err := receiveFuture(r)
|
res, err := receiveFuture(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return -1, err
|
return -1, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure the returned data is the expected type.
|
// Unmarshal result as an int64.
|
||||||
result, ok := reply.(int64)
|
var result int64
|
||||||
if !ok {
|
err = json.Unmarshal(res, &result)
|
||||||
return -1, fmt.Errorf("unexpected response type for "+
|
if err != nil {
|
||||||
"getnetworkhashps: %T\n", reply)
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return result, nil
|
return result, nil
|
||||||
|
@ -135,24 +135,24 @@ func (c *Client) GetHashesPerSec() (int64, error) {
|
||||||
|
|
||||||
// FutureGetMiningInfoResult is a future promise to deliver the result of a
|
// FutureGetMiningInfoResult is a future promise to deliver the result of a
|
||||||
// GetMiningInfoAsync RPC invocation (or an applicable error).
|
// GetMiningInfoAsync RPC invocation (or an applicable error).
|
||||||
type FutureGetMiningInfoResult chan *futureResult
|
type FutureGetMiningInfoResult chan *response
|
||||||
|
|
||||||
// Receive waits for the response promised by the future and returns the mining
|
// Receive waits for the response promised by the future and returns the mining
|
||||||
// information.
|
// information.
|
||||||
func (r FutureGetMiningInfoResult) Receive() (*btcjson.GetMiningInfoResult, error) {
|
func (r FutureGetMiningInfoResult) Receive() (*btcjson.GetMiningInfoResult, error) {
|
||||||
reply, err := receiveFuture(r)
|
res, err := receiveFuture(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure the returned data is the expected type.
|
// Unmarshal result as a getmininginfo result object.
|
||||||
result, ok := reply.(*btcjson.GetMiningInfoResult)
|
var infoResult btcjson.GetMiningInfoResult
|
||||||
if !ok {
|
err = json.Unmarshal(res, &infoResult)
|
||||||
return nil, fmt.Errorf("unexpected response type for "+
|
if err != nil {
|
||||||
"getmininginfo: %T\n", reply)
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return result, nil
|
return &infoResult, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetMiningInfoAsync returns an instance of a type that can be used to get
|
// GetMiningInfoAsync returns an instance of a type that can be used to get
|
||||||
|
@ -177,22 +177,22 @@ func (c *Client) GetMiningInfo() (*btcjson.GetMiningInfoResult, error) {
|
||||||
|
|
||||||
// FutureGetNetworkHashPS is a future promise to deliver the result of a
|
// FutureGetNetworkHashPS is a future promise to deliver the result of a
|
||||||
// GetNetworkHashPSAsync RPC invocation (or an applicable error).
|
// GetNetworkHashPSAsync RPC invocation (or an applicable error).
|
||||||
type FutureGetNetworkHashPS chan *futureResult
|
type FutureGetNetworkHashPS chan *response
|
||||||
|
|
||||||
// Receive waits for the response promised by the future and returns the
|
// Receive waits for the response promised by the future and returns the
|
||||||
// estimated network hashes per second for the block heights provided by the
|
// estimated network hashes per second for the block heights provided by the
|
||||||
// parameters.
|
// parameters.
|
||||||
func (r FutureGetNetworkHashPS) Receive() (int64, error) {
|
func (r FutureGetNetworkHashPS) Receive() (int64, error) {
|
||||||
reply, err := receiveFuture(r)
|
res, err := receiveFuture(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return -1, err
|
return -1, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure the returned data is the expected type.
|
// Unmarshal result as an int64.
|
||||||
result, ok := reply.(int64)
|
var result int64
|
||||||
if !ok {
|
err = json.Unmarshal(res, &result)
|
||||||
return -1, fmt.Errorf("unexpected response type for "+
|
if err != nil {
|
||||||
"getnetworkhashps: %T\n", reply)
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return result, nil
|
return result, nil
|
||||||
|
@ -275,24 +275,24 @@ func (c *Client) GetNetworkHashPS3(blocks, height int) (int64, error) {
|
||||||
|
|
||||||
// FutureGetWork is a future promise to deliver the result of a
|
// FutureGetWork is a future promise to deliver the result of a
|
||||||
// GetWorkAsync RPC invocation (or an applicable error).
|
// GetWorkAsync RPC invocation (or an applicable error).
|
||||||
type FutureGetWork chan *futureResult
|
type FutureGetWork chan *response
|
||||||
|
|
||||||
// Receive waits for the response promised by the future and returns the hash
|
// Receive waits for the response promised by the future and returns the hash
|
||||||
// data to work on.
|
// data to work on.
|
||||||
func (r FutureGetWork) Receive() (*btcjson.GetWorkResult, error) {
|
func (r FutureGetWork) Receive() (*btcjson.GetWorkResult, error) {
|
||||||
reply, err := receiveFuture(r)
|
res, err := receiveFuture(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure the returned data is the expected type.
|
// Unmarshal result as a getwork result object.
|
||||||
result, ok := reply.(*btcjson.GetWorkResult)
|
var result btcjson.GetWorkResult
|
||||||
if !ok {
|
err = json.Unmarshal(res, &result)
|
||||||
return nil, fmt.Errorf("unexpected response type for "+
|
if err != nil {
|
||||||
"getwork (request data): %T\n", reply)
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return result, nil
|
return &result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetWorkAsync returns an instance of a type that can be used to get the result
|
// GetWorkAsync returns an instance of a type that can be used to get the result
|
||||||
|
@ -319,21 +319,21 @@ func (c *Client) GetWork() (*btcjson.GetWorkResult, error) {
|
||||||
|
|
||||||
// FutureGetWorkSubmit is a future promise to deliver the result of a
|
// FutureGetWorkSubmit is a future promise to deliver the result of a
|
||||||
// GetWorkSubmitAsync RPC invocation (or an applicable error).
|
// GetWorkSubmitAsync RPC invocation (or an applicable error).
|
||||||
type FutureGetWorkSubmit chan *futureResult
|
type FutureGetWorkSubmit chan *response
|
||||||
|
|
||||||
// Receive waits for the response promised by the future and returns whether
|
// Receive waits for the response promised by the future and returns whether
|
||||||
// or not the submitted block header was accepted.
|
// or not the submitted block header was accepted.
|
||||||
func (r FutureGetWorkSubmit) Receive() (bool, error) {
|
func (r FutureGetWorkSubmit) Receive() (bool, error) {
|
||||||
reply, err := receiveFuture(r)
|
res, err := receiveFuture(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure the returned data is the expected type.
|
// Unmarshal result as a boolean.
|
||||||
accepted, ok := reply.(bool)
|
var accepted bool
|
||||||
if !ok {
|
err = json.Unmarshal(res, &accepted)
|
||||||
return false, fmt.Errorf("unexpected response type for "+
|
if err != nil {
|
||||||
"getwork (submit data): %T\n", reply)
|
return false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return accepted, nil
|
return accepted, nil
|
||||||
|
@ -364,7 +364,7 @@ func (c *Client) GetWorkSubmit(data string) (bool, error) {
|
||||||
|
|
||||||
// FutureSubmitBlockResult is a future promise to deliver the result of a
|
// FutureSubmitBlockResult is a future promise to deliver the result of a
|
||||||
// SubmitBlockAsync RPC invocation (or an applicable error).
|
// SubmitBlockAsync RPC invocation (or an applicable error).
|
||||||
type FutureSubmitBlockResult chan *futureResult
|
type FutureSubmitBlockResult chan *response
|
||||||
|
|
||||||
// Receive waits for the response promised by the future and returns an error if
|
// Receive waits for the response promised by the future and returns an error if
|
||||||
// any occurred when submitting the block.
|
// any occurred when submitting the block.
|
||||||
|
|
80
net.go
80
net.go
|
@ -5,7 +5,7 @@
|
||||||
package btcrpcclient
|
package btcrpcclient
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"encoding/json"
|
||||||
"github.com/conformal/btcjson"
|
"github.com/conformal/btcjson"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ func (cmd AddNodeCommand) String() string {
|
||||||
|
|
||||||
// FutureAddNodeResult is a future promise to deliver the result of an
|
// FutureAddNodeResult is a future promise to deliver the result of an
|
||||||
// AddNodeAsync RPC invocation (or an applicable error).
|
// AddNodeAsync RPC invocation (or an applicable error).
|
||||||
type FutureAddNodeResult chan *futureResult
|
type FutureAddNodeResult chan *response
|
||||||
|
|
||||||
// Receive waits for the response promised by the future and returns an error if
|
// Receive waits for the response promised by the future and returns an error if
|
||||||
// any occurred when performing the specified command.
|
// any occurred when performing the specified command.
|
||||||
|
@ -73,21 +73,21 @@ func (c *Client) AddNode(host string, command AddNodeCommand) error {
|
||||||
|
|
||||||
// FutureGetAddedNodeInfoResult is a future promise to deliver the result of a
|
// FutureGetAddedNodeInfoResult is a future promise to deliver the result of a
|
||||||
// GetAddedNodeInfoAsync RPC invocation (or an applicable error).
|
// GetAddedNodeInfoAsync RPC invocation (or an applicable error).
|
||||||
type FutureGetAddedNodeInfoResult chan *futureResult
|
type FutureGetAddedNodeInfoResult chan *response
|
||||||
|
|
||||||
// Receive waits for the response promised by the future and returns information
|
// Receive waits for the response promised by the future and returns information
|
||||||
// about manually added (persistent) peers.
|
// about manually added (persistent) peers.
|
||||||
func (r FutureGetAddedNodeInfoResult) Receive() ([]btcjson.GetAddedNodeInfoResult, error) {
|
func (r FutureGetAddedNodeInfoResult) Receive() ([]btcjson.GetAddedNodeInfoResult, error) {
|
||||||
reply, err := receiveFuture(r)
|
res, err := receiveFuture(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure the returned data is the expected type.
|
// Unmarshal as an array of getaddednodeinfo result objects.
|
||||||
nodeInfo, ok := reply.([]btcjson.GetAddedNodeInfoResult)
|
var nodeInfo []btcjson.GetAddedNodeInfoResult
|
||||||
if !ok {
|
err = json.Unmarshal(res, &nodeInfo)
|
||||||
return nil, fmt.Errorf("unexpected response type for "+
|
if err != nil {
|
||||||
"getaddednodeinfo (dns=true): %T\n", reply)
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return nodeInfo, nil
|
return nodeInfo, nil
|
||||||
|
@ -118,21 +118,21 @@ func (c *Client) GetAddedNodeInfo(peer string) ([]btcjson.GetAddedNodeInfoResult
|
||||||
|
|
||||||
// FutureGetAddedNodeInfoNoDNSResult is a future promise to deliver the result
|
// FutureGetAddedNodeInfoNoDNSResult is a future promise to deliver the result
|
||||||
// of a GetAddedNodeInfoNoDNSAsync RPC invocation (or an applicable error).
|
// of a GetAddedNodeInfoNoDNSAsync RPC invocation (or an applicable error).
|
||||||
type FutureGetAddedNodeInfoNoDNSResult chan *futureResult
|
type FutureGetAddedNodeInfoNoDNSResult chan *response
|
||||||
|
|
||||||
// Receive waits for the response promised by the future and returns a list of
|
// Receive waits for the response promised by the future and returns a list of
|
||||||
// manually added (persistent) peers.
|
// manually added (persistent) peers.
|
||||||
func (r FutureGetAddedNodeInfoNoDNSResult) Receive() ([]string, error) {
|
func (r FutureGetAddedNodeInfoNoDNSResult) Receive() ([]string, error) {
|
||||||
reply, err := receiveFuture(r)
|
res, err := receiveFuture(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure the returned data is the expected type.
|
// Unmarshal result as an array of strings.
|
||||||
nodes, ok := reply.([]string)
|
var nodes []string
|
||||||
if !ok {
|
err = json.Unmarshal(res, &nodes)
|
||||||
return nil, fmt.Errorf("unexpected response type for "+
|
if err != nil {
|
||||||
"getaddednodeinfo (dns=false): %T\n", reply)
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return nodes, nil
|
return nodes, nil
|
||||||
|
@ -164,24 +164,24 @@ func (c *Client) GetAddedNodeInfoNoDNS(peer string) ([]string, error) {
|
||||||
|
|
||||||
// FutureGetConnectionCountResult is a future promise to deliver the result
|
// FutureGetConnectionCountResult is a future promise to deliver the result
|
||||||
// of a GetConnectionCountAsync RPC invocation (or an applicable error).
|
// of a GetConnectionCountAsync RPC invocation (or an applicable error).
|
||||||
type FutureGetConnectionCountResult chan *futureResult
|
type FutureGetConnectionCountResult chan *response
|
||||||
|
|
||||||
// Receive waits for the response promised by the future and returns the number
|
// Receive waits for the response promised by the future and returns the number
|
||||||
// of active connections to other peers.
|
// of active connections to other peers.
|
||||||
func (r FutureGetConnectionCountResult) Receive() (int64, error) {
|
func (r FutureGetConnectionCountResult) Receive() (int64, error) {
|
||||||
reply, err := receiveFuture(r)
|
res, err := receiveFuture(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure the returned data is the expected type.
|
// Unmarshal result as an int64.
|
||||||
fcount, ok := reply.(float64)
|
var count int64
|
||||||
if !ok {
|
err = json.Unmarshal(res, &count)
|
||||||
return 0, fmt.Errorf("unexpected response type for "+
|
if err != nil {
|
||||||
"getconnectioncount: %T\n", reply)
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return int64(fcount), nil
|
return count, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetConnectionCountAsync returns an instance of a type that can be used to get
|
// GetConnectionCountAsync returns an instance of a type that can be used to get
|
||||||
|
@ -206,7 +206,7 @@ func (c *Client) GetConnectionCount() (int64, error) {
|
||||||
|
|
||||||
// FuturePingResult is a future promise to deliver the result of a PingAsync RPC
|
// FuturePingResult is a future promise to deliver the result of a PingAsync RPC
|
||||||
// invocation (or an applicable error).
|
// invocation (or an applicable error).
|
||||||
type FuturePingResult chan *futureResult
|
type FuturePingResult chan *response
|
||||||
|
|
||||||
// Receive waits for the response promised by the future and returns the result
|
// Receive waits for the response promised by the future and returns the result
|
||||||
// of queueing a ping to be sent to each connected peer.
|
// of queueing a ping to be sent to each connected peer.
|
||||||
|
@ -244,21 +244,21 @@ func (c *Client) Ping() error {
|
||||||
|
|
||||||
// FutureGetPeerInfoResult is a future promise to deliver the result of a
|
// FutureGetPeerInfoResult is a future promise to deliver the result of a
|
||||||
// GetPeerInfoAsync RPC invocation (or an applicable error).
|
// GetPeerInfoAsync RPC invocation (or an applicable error).
|
||||||
type FutureGetPeerInfoResult chan *futureResult
|
type FutureGetPeerInfoResult chan *response
|
||||||
|
|
||||||
// Receive waits for the response promised by the future and returns data about
|
// Receive waits for the response promised by the future and returns data about
|
||||||
// each connected network peer.
|
// each connected network peer.
|
||||||
func (r FutureGetPeerInfoResult) Receive() ([]btcjson.GetPeerInfoResult, error) {
|
func (r FutureGetPeerInfoResult) Receive() ([]btcjson.GetPeerInfoResult, error) {
|
||||||
reply, err := receiveFuture(r)
|
res, err := receiveFuture(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure the returned data is the expected type.
|
// Unmarshal result as an array of getpeerinfo result objects.
|
||||||
peerInfo, ok := reply.([]btcjson.GetPeerInfoResult)
|
var peerInfo []btcjson.GetPeerInfoResult
|
||||||
if !ok {
|
err = json.Unmarshal(res, &peerInfo)
|
||||||
return nil, fmt.Errorf("unexpected response type for "+
|
if err != nil {
|
||||||
"getpeerinfo: %T\n", reply)
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return peerInfo, nil
|
return peerInfo, nil
|
||||||
|
@ -286,24 +286,24 @@ func (c *Client) GetPeerInfo() ([]btcjson.GetPeerInfoResult, error) {
|
||||||
|
|
||||||
// FutureGetNetTotalsResult is a future promise to deliver the result of a
|
// FutureGetNetTotalsResult is a future promise to deliver the result of a
|
||||||
// GetNetTotalsAsync RPC invocation (or an applicable error).
|
// GetNetTotalsAsync RPC invocation (or an applicable error).
|
||||||
type FutureGetNetTotalsResult chan *futureResult
|
type FutureGetNetTotalsResult chan *response
|
||||||
|
|
||||||
// Receive waits for the response promised by the future and returns network
|
// Receive waits for the response promised by the future and returns network
|
||||||
// traffic statistics.
|
// traffic statistics.
|
||||||
func (r FutureGetNetTotalsResult) Receive() (*btcjson.GetNetTotalsResult, error) {
|
func (r FutureGetNetTotalsResult) Receive() (*btcjson.GetNetTotalsResult, error) {
|
||||||
reply, err := receiveFuture(r)
|
res, err := receiveFuture(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure the returned data is the expected type.
|
// Unmarshal result as a getnettotals result object.
|
||||||
totals, ok := reply.(*btcjson.GetNetTotalsResult)
|
var totals btcjson.GetNetTotalsResult
|
||||||
if !ok {
|
err = json.Unmarshal(res, &totals)
|
||||||
return nil, fmt.Errorf("unexpected response type for "+
|
if err != nil {
|
||||||
"getnettotals: %T\n", reply)
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return totals, nil
|
return &totals, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetNetTotalsAsync returns an instance of a type that can be used to get the
|
// GetNetTotalsAsync returns an instance of a type that can be used to get the
|
||||||
|
|
392
notify.go
392
notify.go
|
@ -7,7 +7,9 @@ package btcrpcclient
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"github.com/conformal/btcjson"
|
"github.com/conformal/btcjson"
|
||||||
"github.com/conformal/btcutil"
|
"github.com/conformal/btcutil"
|
||||||
"github.com/conformal/btcwire"
|
"github.com/conformal/btcwire"
|
||||||
|
@ -68,9 +70,9 @@ func newNotificationState() *notificationState {
|
||||||
// result waiting on the channel with the reply set to nil. This is useful
|
// result waiting on the channel with the reply set to nil. This is useful
|
||||||
// to ignore things such as notifications when the caller didn't specify any
|
// to ignore things such as notifications when the caller didn't specify any
|
||||||
// notification handlers.
|
// notification handlers.
|
||||||
func newNilFutureResult() chan *futureResult {
|
func newNilFutureResult() chan *response {
|
||||||
responseChan := make(chan *futureResult, 1)
|
responseChan := make(chan *response, 1)
|
||||||
responseChan <- &futureResult{reply: nil}
|
responseChan <- &response{result: nil, err: nil}
|
||||||
return responseChan
|
return responseChan
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,183 +163,192 @@ type NotificationHandlers struct {
|
||||||
// for this package needs to be updated for a new notification type or
|
// for this package needs to be updated for a new notification type or
|
||||||
// the caller is using a custom notification this package does not know
|
// the caller is using a custom notification this package does not know
|
||||||
// about.
|
// about.
|
||||||
OnUnknownNotification func(ntfn interface{})
|
OnUnknownNotification func(method string, params []json.RawMessage)
|
||||||
}
|
}
|
||||||
|
|
||||||
// handleNotification examines the passed notification type, performs
|
// handleNotification examines the passed notification type, performs
|
||||||
// conversions to get the raw notification types into higher level types and
|
// conversions to get the raw notification types into higher level types and
|
||||||
// delivers the notification to the appropriate On<X> handler registered with
|
// delivers the notification to the appropriate On<X> handler registered with
|
||||||
// the client.
|
// the client.
|
||||||
func (c *Client) handleNotification(cmd btcjson.Cmd) {
|
func (c *Client) handleNotification(ntfn *rawNotification) {
|
||||||
// Ignore the notification if the client is not interested in any
|
// Ignore the notification if the client is not interested in any
|
||||||
// notifications.
|
// notifications.
|
||||||
if c.ntfnHandlers == nil {
|
if c.ntfnHandlers == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
switch ntfn := cmd.(type) {
|
switch ntfn.Method {
|
||||||
// OnBlockConnected
|
// OnBlockConnected
|
||||||
case *btcws.BlockConnectedNtfn:
|
case btcws.BlockConnectedNtfnMethod:
|
||||||
// Ignore the notification is the client is not interested in
|
// Ignore the notification is the client is not interested in
|
||||||
// it.
|
// it.
|
||||||
if c.ntfnHandlers.OnBlockConnected == nil {
|
if c.ntfnHandlers.OnBlockConnected == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
hash, err := btcwire.NewShaHashFromStr(ntfn.Hash)
|
blockSha, blockHeight, err := parseChainNtfnParams(ntfn.Params)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warnf("Received block connected notification with "+
|
log.Warnf("Received invalid block connected "+
|
||||||
"invalid hash string: %q", ntfn.Hash)
|
"notification: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.ntfnHandlers.OnBlockConnected(hash, ntfn.Height)
|
c.ntfnHandlers.OnBlockConnected(blockSha, blockHeight)
|
||||||
|
|
||||||
// OnBlockDisconnected
|
// OnBlockDisconnected
|
||||||
case *btcws.BlockDisconnectedNtfn:
|
case btcws.BlockDisconnectedNtfnMethod:
|
||||||
// Ignore the notification is the client is not interested in
|
// Ignore the notification is the client is not interested in
|
||||||
// it.
|
// it.
|
||||||
if c.ntfnHandlers.OnBlockDisconnected == nil {
|
if c.ntfnHandlers.OnBlockDisconnected == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
hash, err := btcwire.NewShaHashFromStr(ntfn.Hash)
|
blockSha, blockHeight, err := parseChainNtfnParams(ntfn.Params)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warnf("Received block disconnected notification "+
|
log.Warnf("Received invalid block connected "+
|
||||||
"with invalid hash string: %q", ntfn.Hash)
|
"notification: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.ntfnHandlers.OnBlockDisconnected(hash, ntfn.Height)
|
c.ntfnHandlers.OnBlockDisconnected(blockSha, blockHeight)
|
||||||
|
|
||||||
// OnRecvTx
|
// OnRecvTx
|
||||||
case *btcws.RecvTxNtfn:
|
case btcws.RecvTxNtfnMethod:
|
||||||
// Ignore the notification is the client is not interested in
|
// Ignore the notification is the client is not interested in
|
||||||
// it.
|
// it.
|
||||||
if c.ntfnHandlers.OnRecvTx == nil {
|
if c.ntfnHandlers.OnRecvTx == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decode the serialized transaction hex to raw bytes.
|
tx, block, err := parseChainTxNtfnParams(ntfn.Params)
|
||||||
serializedTx, err := hex.DecodeString(ntfn.HexTx)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warnf("Received recvtx notification with invalid "+
|
log.Warnf("Received invalid recvtx notification: %v",
|
||||||
"transaction hex '%q': %v", ntfn.HexTx, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deserialize the transaction.
|
|
||||||
var msgTx btcwire.MsgTx
|
|
||||||
err = msgTx.Deserialize(bytes.NewReader(serializedTx))
|
|
||||||
if err != nil {
|
|
||||||
log.Warnf("Received recvtx notification with "+
|
|
||||||
"transaction that failed to deserialize: %v",
|
|
||||||
err)
|
err)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.ntfnHandlers.OnRecvTx(btcutil.NewTx(&msgTx), ntfn.Block)
|
c.ntfnHandlers.OnRecvTx(tx, block)
|
||||||
|
|
||||||
// OnRedeemingTx
|
// OnRedeemingTx
|
||||||
case *btcws.RedeemingTxNtfn:
|
case btcws.RedeemingTxNtfnMethod:
|
||||||
// Ignore the notification is the client is not interested in
|
// Ignore the notification is the client is not interested in
|
||||||
// it.
|
// it.
|
||||||
if c.ntfnHandlers.OnRedeemingTx == nil {
|
if c.ntfnHandlers.OnRedeemingTx == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decode the serialized transaction hex to raw bytes.
|
tx, block, err := parseChainTxNtfnParams(ntfn.Params)
|
||||||
serializedTx, err := hex.DecodeString(ntfn.HexTx)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warnf("Received redeemingtx notification with "+
|
log.Warnf("Received invalid redeemingtx "+
|
||||||
"invalid transaction hex '%q': %v", ntfn.HexTx,
|
"notification: %v", err)
|
||||||
err)
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Deserialize the transaction.
|
c.ntfnHandlers.OnRedeemingTx(tx, block)
|
||||||
var msgTx btcwire.MsgTx
|
|
||||||
err = msgTx.Deserialize(bytes.NewReader(serializedTx))
|
|
||||||
if err != nil {
|
|
||||||
log.Warnf("Received redeemingtx notification with "+
|
|
||||||
"transaction that failed to deserialize: %v",
|
|
||||||
err)
|
|
||||||
}
|
|
||||||
|
|
||||||
c.ntfnHandlers.OnRedeemingTx(btcutil.NewTx(&msgTx), ntfn.Block)
|
|
||||||
|
|
||||||
// OnRescanProgress
|
// OnRescanProgress
|
||||||
case *btcws.RescanProgressNtfn:
|
case btcws.RescanProgressNtfnMethod:
|
||||||
// Ignore the notification is the client is not interested in
|
// Ignore the notification is the client is not interested in
|
||||||
// it.
|
// it.
|
||||||
if c.ntfnHandlers.OnRescanProgress == nil {
|
if c.ntfnHandlers.OnRescanProgress == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.ntfnHandlers.OnRescanProgress(ntfn.LastProcessed)
|
lastProcessed, err := parseRescanProgressNtfnParams(ntfn.Params)
|
||||||
|
if err != nil {
|
||||||
|
log.Warnf("Received invalid rescanprogress "+
|
||||||
|
"notification: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.ntfnHandlers.OnRescanProgress(lastProcessed)
|
||||||
|
|
||||||
// OnTxAccepted
|
// OnTxAccepted
|
||||||
case *btcws.TxAcceptedNtfn:
|
case btcws.TxAcceptedNtfnMethod:
|
||||||
// Ignore the notification is the client is not interested in
|
// Ignore the notification is the client is not interested in
|
||||||
// it.
|
// it.
|
||||||
if c.ntfnHandlers.OnTxAccepted == nil {
|
if c.ntfnHandlers.OnTxAccepted == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
hash, err := btcwire.NewShaHashFromStr(ntfn.TxID)
|
hash, amt, err := parseTxAcceptedNtfnParams(ntfn.Params)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warnf("Received tx accepted notification with "+
|
log.Warnf("Received invalid tx accepted "+
|
||||||
"invalid hash string: %q", ntfn.TxID)
|
"notification: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.ntfnHandlers.OnTxAccepted(hash, btcutil.Amount(ntfn.Amount))
|
c.ntfnHandlers.OnTxAccepted(hash, amt)
|
||||||
|
|
||||||
// OnTxAcceptedVerbose
|
// OnTxAcceptedVerbose
|
||||||
case *btcws.TxAcceptedVerboseNtfn:
|
case btcws.TxAcceptedVerboseNtfnMethod:
|
||||||
// Ignore the notification is the client is not interested in
|
// Ignore the notification is the client is not interested in
|
||||||
// it.
|
// it.
|
||||||
if c.ntfnHandlers.OnTxAcceptedVerbose == nil {
|
if c.ntfnHandlers.OnTxAcceptedVerbose == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.ntfnHandlers.OnTxAcceptedVerbose(ntfn.RawTx)
|
rawTx, err := parseTxAcceptedVerboseNtfnParams(ntfn.Params)
|
||||||
|
if err != nil {
|
||||||
|
log.Warnf("Received invalid tx accepted verbose "+
|
||||||
|
"notification: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.ntfnHandlers.OnTxAcceptedVerbose(rawTx)
|
||||||
|
|
||||||
// OnBtcdConnected
|
// OnBtcdConnected
|
||||||
case *btcws.BtcdConnectedNtfn:
|
case btcws.BtcdConnectedNtfnMethod:
|
||||||
// Ignore the notification is the client is not interested in
|
// Ignore the notification is the client is not interested in
|
||||||
// it.
|
// it.
|
||||||
if c.ntfnHandlers.OnBtcdConnected == nil {
|
if c.ntfnHandlers.OnBtcdConnected == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.ntfnHandlers.OnBtcdConnected(ntfn.Connected)
|
connected, err := parseBtcdConnectedNtfnParams(ntfn.Params)
|
||||||
|
if err != nil {
|
||||||
|
log.Warnf("Received invalid btcd connected "+
|
||||||
|
"notification: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.ntfnHandlers.OnBtcdConnected(connected)
|
||||||
|
|
||||||
// OnAccountBalance
|
// OnAccountBalance
|
||||||
case *btcws.AccountBalanceNtfn:
|
case btcws.AccountBalanceNtfnMethod:
|
||||||
// Ignore the notification is the client is not interested in
|
// Ignore the notification is the client is not interested in
|
||||||
// it.
|
// it.
|
||||||
if c.ntfnHandlers.OnAccountBalance == nil {
|
if c.ntfnHandlers.OnAccountBalance == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
balance, err := btcjson.JSONToAmount(ntfn.Balance)
|
account, bal, conf, err := parseAccountBalanceNtfnParams(ntfn.Params)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warnf("Received account balance notification with "+
|
log.Warnf("Received invalid account balance "+
|
||||||
"an amount that does not parse: %v",
|
"notification: %v", err)
|
||||||
ntfn.Balance)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.ntfnHandlers.OnAccountBalance(ntfn.Account,
|
c.ntfnHandlers.OnAccountBalance(account, bal, conf)
|
||||||
btcutil.Amount(balance), ntfn.Confirmed)
|
|
||||||
|
|
||||||
// OnWalletLockState
|
// OnWalletLockState
|
||||||
case *btcws.WalletLockStateNtfn:
|
case btcws.WalletLockStateNtfnMethod:
|
||||||
// Ignore the notification is the client is not interested in
|
// Ignore the notification is the client is not interested in
|
||||||
// it.
|
// it.
|
||||||
if c.ntfnHandlers.OnWalletLockState == nil {
|
if c.ntfnHandlers.OnWalletLockState == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.ntfnHandlers.OnWalletLockState(ntfn.Locked)
|
// The account name is not notified, so the return value is
|
||||||
|
// discarded.
|
||||||
|
_, locked, err := parseWalletLockStateNtfnParams(ntfn.Params)
|
||||||
|
if err != nil {
|
||||||
|
log.Warnf("Received invalid wallet lock state "+
|
||||||
|
"notification: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.ntfnHandlers.OnWalletLockState(locked)
|
||||||
|
|
||||||
// OnUnknownNotification
|
// OnUnknownNotification
|
||||||
default:
|
default:
|
||||||
|
@ -345,13 +356,250 @@ func (c *Client) handleNotification(cmd btcjson.Cmd) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.ntfnHandlers.OnUnknownNotification(ntfn)
|
c.ntfnHandlers.OnUnknownNotification(ntfn.Method, ntfn.Params)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// wrongNumParams is an error type describing an unparseable JSON-RPC
|
||||||
|
// notificiation due to an incorrect number of parameters for the
|
||||||
|
// expected notification type. The value is the number of parameters
|
||||||
|
// of the invalid notification.
|
||||||
|
type wrongNumParams int
|
||||||
|
|
||||||
|
// Error satisifies the builtin error interface.
|
||||||
|
func (e wrongNumParams) Error() string {
|
||||||
|
return fmt.Sprintf("wrong number of parameters (%d)", e)
|
||||||
|
}
|
||||||
|
|
||||||
|
// parseChainNtfnParams parses out the block hash and height from the parameters
|
||||||
|
// of blockconnected and blockdisconnected notifications.
|
||||||
|
func parseChainNtfnParams(params []json.RawMessage) (*btcwire.ShaHash,
|
||||||
|
int32, error) {
|
||||||
|
|
||||||
|
if len(params) != 2 {
|
||||||
|
return nil, 0, wrongNumParams(len(params))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unmarshal first parameter as a string.
|
||||||
|
var blockShaStr string
|
||||||
|
err := json.Unmarshal(params[0], &blockShaStr)
|
||||||
|
if err != nil {
|
||||||
|
return nil, 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unmarshal second parameter as an integer.
|
||||||
|
var blockHeight int32
|
||||||
|
err = json.Unmarshal(params[1], &blockHeight)
|
||||||
|
if err != nil {
|
||||||
|
return nil, 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create ShaHash from block sha string.
|
||||||
|
blockSha, err := btcwire.NewShaHashFromStr(blockShaStr)
|
||||||
|
if err != nil {
|
||||||
|
return nil, 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return blockSha, blockHeight, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// parseChainTxNtfnParams parses out the transaction and optional details about
|
||||||
|
// the block it's mined in from the parameters of recvtx and redeemingtx
|
||||||
|
// notifications.
|
||||||
|
func parseChainTxNtfnParams(params []json.RawMessage) (*btcutil.Tx,
|
||||||
|
*btcws.BlockDetails, error) {
|
||||||
|
|
||||||
|
if len(params) == 0 || len(params) > 2 {
|
||||||
|
return nil, nil, wrongNumParams(len(params))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unmarshal first parameter as a string.
|
||||||
|
var txHex string
|
||||||
|
err := json.Unmarshal(params[0], &txHex)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// If present, unmarshal second optional parameter as the block details
|
||||||
|
// JSON object.
|
||||||
|
var block *btcws.BlockDetails
|
||||||
|
if len(params) > 1 {
|
||||||
|
err = json.Unmarshal(params[1], &block)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hex decode and deserialize the transaction.
|
||||||
|
serializedTx, err := hex.DecodeString(txHex)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
var msgTx btcwire.MsgTx
|
||||||
|
err = msgTx.Deserialize(bytes.NewReader(serializedTx))
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Change recvtx and redeemingtx callback signatures to use
|
||||||
|
// nicer types for details about the block (block sha as a
|
||||||
|
// btcwire.ShaHash, block time as a time.Time, etc.).
|
||||||
|
return btcutil.NewTx(&msgTx), block, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// parseRescanProgressNtfnParams parses out the height of the last rescanned
|
||||||
|
// from the parameters of a rescanprogress notification.
|
||||||
|
func parseRescanProgressNtfnParams(params []json.RawMessage) (int32, error) {
|
||||||
|
if len(params) != 1 {
|
||||||
|
return 0, wrongNumParams(len(params))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unmarshal first parameter as an integer.
|
||||||
|
var height int32
|
||||||
|
err := json.Unmarshal(params[0], &height)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return height, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// parseTxAcceptedNtfnParams parses out the transaction hash and total amount
|
||||||
|
// from the parameters of a txaccepted notification.
|
||||||
|
func parseTxAcceptedNtfnParams(params []json.RawMessage) (*btcwire.ShaHash,
|
||||||
|
btcutil.Amount, error) {
|
||||||
|
|
||||||
|
if len(params) != 2 {
|
||||||
|
return nil, 0, wrongNumParams(len(params))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unmarshal first parameter as a string.
|
||||||
|
var txShaStr string
|
||||||
|
err := json.Unmarshal(params[0], &txShaStr)
|
||||||
|
if err != nil {
|
||||||
|
return nil, 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unmarshal second parameter as an integer.
|
||||||
|
var amt int64
|
||||||
|
err = json.Unmarshal(params[1], &amt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decode string encoding of transaction sha.
|
||||||
|
txSha, err := btcwire.NewShaHashFromStr(txShaStr)
|
||||||
|
if err != nil {
|
||||||
|
return nil, 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return txSha, btcutil.Amount(amt), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// parseTxAcceptedVerboseNtfnParams parses out details about a raw transaction
|
||||||
|
// from the parameters of a txacceptedverbose notification.
|
||||||
|
func parseTxAcceptedVerboseNtfnParams(params []json.RawMessage) (*btcjson.TxRawResult,
|
||||||
|
error) {
|
||||||
|
|
||||||
|
if len(params) != 1 {
|
||||||
|
return nil, wrongNumParams(len(params))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unmarshal first parameter as a raw transaction result object.
|
||||||
|
var rawTx btcjson.TxRawResult
|
||||||
|
err := json.Unmarshal(params[0], &rawTx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: change txacceptedverbose notifiation callbacks to use nicer
|
||||||
|
// types for all details about the transaction (i.e. decoding hashes
|
||||||
|
// from their string encoding).
|
||||||
|
return &rawTx, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// parseBtcdConnectedNtfnParams parses out the connection status of btcd
|
||||||
|
// and btcwallet from the parameters of a btcdconnected notification.
|
||||||
|
func parseBtcdConnectedNtfnParams(params []json.RawMessage) (bool, error) {
|
||||||
|
if len(params) != 1 {
|
||||||
|
return false, wrongNumParams(len(params))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unmarshal first parameter as a boolean.
|
||||||
|
var connected bool
|
||||||
|
err := json.Unmarshal(params[0], &connected)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return connected, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// parseAccountBalanceNtfnParams parses out the account name, total balance,
|
||||||
|
// and whether or not the balance is confirmed or unconfirmed from the
|
||||||
|
// parameters of an accountbalance notification.
|
||||||
|
func parseAccountBalanceNtfnParams(params []json.RawMessage) (account string,
|
||||||
|
balance btcutil.Amount, confirmed bool, err error) {
|
||||||
|
|
||||||
|
if len(params) != 3 {
|
||||||
|
return "", 0, false, wrongNumParams(len(params))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unmarshal first parameter as a string.
|
||||||
|
err = json.Unmarshal(params[0], &account)
|
||||||
|
if err != nil {
|
||||||
|
return "", 0, false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unmarshal second parameter as a floating point number.
|
||||||
|
var fbal float64
|
||||||
|
err = json.Unmarshal(params[1], &fbal)
|
||||||
|
if err != nil {
|
||||||
|
return "", 0, false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unmarshal third parameter as a boolean.
|
||||||
|
err = json.Unmarshal(params[2], &confirmed)
|
||||||
|
if err != nil {
|
||||||
|
return "", 0, false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bounds check amount.
|
||||||
|
bal, err := btcjson.JSONToAmount(fbal)
|
||||||
|
if err != nil {
|
||||||
|
return "", 0, false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return account, btcutil.Amount(bal), confirmed, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// parseWalletLockStateNtfnParams parses out the account name and locked
|
||||||
|
// state of an account from the parameters of a walletlockstate notification.
|
||||||
|
func parseWalletLockStateNtfnParams(params []json.RawMessage) (account string,
|
||||||
|
locked bool, err error) {
|
||||||
|
|
||||||
|
if len(params) != 2 {
|
||||||
|
return "", false, wrongNumParams(len(params))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unmarshal first parameter as a string.
|
||||||
|
err = json.Unmarshal(params[0], &account)
|
||||||
|
if err != nil {
|
||||||
|
return "", false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unmarshal second parameter as a boolean.
|
||||||
|
err = json.Unmarshal(params[1], &locked)
|
||||||
|
if err != nil {
|
||||||
|
return "", false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return account, locked, nil
|
||||||
|
}
|
||||||
|
|
||||||
// FutureNotifyBlocksResult is a future promise to deliver the result of a
|
// FutureNotifyBlocksResult is a future promise to deliver the result of a
|
||||||
// NotifyBlocksAsync RPC invocation (or an applicable error).
|
// NotifyBlocksAsync RPC invocation (or an applicable error).
|
||||||
type FutureNotifyBlocksResult chan *futureResult
|
type FutureNotifyBlocksResult chan *response
|
||||||
|
|
||||||
// Receive waits for the response promised by the future and returns an error
|
// Receive waits for the response promised by the future and returns an error
|
||||||
// if the registration was not successful.
|
// if the registration was not successful.
|
||||||
|
@ -405,7 +653,7 @@ func (c *Client) NotifyBlocks() error {
|
||||||
|
|
||||||
// FutureNotifySpentResult is a future promise to deliver the result of a
|
// FutureNotifySpentResult is a future promise to deliver the result of a
|
||||||
// NotifySpentAsync RPC invocation (or an applicable error).
|
// NotifySpentAsync RPC invocation (or an applicable error).
|
||||||
type FutureNotifySpentResult chan *futureResult
|
type FutureNotifySpentResult chan *response
|
||||||
|
|
||||||
// Receive waits for the response promised by the future and returns an error
|
// Receive waits for the response promised by the future and returns an error
|
||||||
// if the registration was not successful.
|
// if the registration was not successful.
|
||||||
|
@ -484,7 +732,7 @@ func (c *Client) NotifySpent(outpoints []*btcwire.OutPoint) error {
|
||||||
|
|
||||||
// FutureNotifyNewTransactionsResult is a future promise to deliver the result
|
// FutureNotifyNewTransactionsResult is a future promise to deliver the result
|
||||||
// of a NotifyNewTransactionsAsync RPC invocation (or an applicable error).
|
// of a NotifyNewTransactionsAsync RPC invocation (or an applicable error).
|
||||||
type FutureNotifyNewTransactionsResult chan *futureResult
|
type FutureNotifyNewTransactionsResult chan *response
|
||||||
|
|
||||||
// Receive waits for the response promised by the future and returns an error
|
// Receive waits for the response promised by the future and returns an error
|
||||||
// if the registration was not successful.
|
// if the registration was not successful.
|
||||||
|
@ -542,7 +790,7 @@ func (c *Client) NotifyNewTransactions(verbose bool) error {
|
||||||
|
|
||||||
// FutureNotifyReceivedResult is a future promise to deliver the result of a
|
// FutureNotifyReceivedResult is a future promise to deliver the result of a
|
||||||
// NotifyReceivedAsync RPC invocation (or an applicable error).
|
// NotifyReceivedAsync RPC invocation (or an applicable error).
|
||||||
type FutureNotifyReceivedResult chan *futureResult
|
type FutureNotifyReceivedResult chan *response
|
||||||
|
|
||||||
// Receive waits for the response promised by the future and returns an error
|
// Receive waits for the response promised by the future and returns an error
|
||||||
// if the registration was not successful.
|
// if the registration was not successful.
|
||||||
|
@ -630,7 +878,7 @@ func (c *Client) NotifyReceived(addresses []btcutil.Address) error {
|
||||||
|
|
||||||
// FutureRescanResult is a future promise to deliver the result of a RescanAsync
|
// FutureRescanResult is a future promise to deliver the result of a RescanAsync
|
||||||
// or RescanEndHeightAsync RPC invocation (or an applicable error).
|
// or RescanEndHeightAsync RPC invocation (or an applicable error).
|
||||||
type FutureRescanResult chan *futureResult
|
type FutureRescanResult chan *response
|
||||||
|
|
||||||
// Receive waits for the response promised by the future and returns an error
|
// Receive waits for the response promised by the future and returns an error
|
||||||
// if the rescan was not successful.
|
// if the rescan was not successful.
|
||||||
|
|
90
rawrequest.go
Normal file
90
rawrequest.go
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
// Copyright (c) 2014 Conformal Systems LLC.
|
||||||
|
// Use of this source code is governed by an ISC
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package btcrpcclient
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"github.com/conformal/btcjson"
|
||||||
|
)
|
||||||
|
|
||||||
|
// rawRequest satisifies the btcjson.Cmd interface for btcjson raw commands.
|
||||||
|
// This type exists here rather than making btcjson.RawCmd satisify the Cmd
|
||||||
|
// interface due to conflict between the Id and Method field names vs method
|
||||||
|
// names.
|
||||||
|
type rawRequest struct {
|
||||||
|
btcjson.RawCmd
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enforce that rawRequest is a btcjson.Cmd.
|
||||||
|
var _ btcjson.Cmd = &rawRequest{}
|
||||||
|
|
||||||
|
// Id returns the JSON-RPC id of the request.
|
||||||
|
func (r *rawRequest) Id() interface{} {
|
||||||
|
return r.RawCmd.Id
|
||||||
|
}
|
||||||
|
|
||||||
|
// Method returns the method string of the request.
|
||||||
|
func (r *rawRequest) Method() string {
|
||||||
|
return r.RawCmd.Method
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSON marshals the raw request as a JSON-RPC 1.0 object.
|
||||||
|
func (r *rawRequest) MarshalJSON() ([]byte, error) {
|
||||||
|
return json.Marshal(r.RawCmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON unmarshals a JSON-RPC 1.0 object into the raw request.
|
||||||
|
func (r *rawRequest) UnmarshalJSON(b []byte) error {
|
||||||
|
return json.Unmarshal(b, &r.RawCmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FutureRawResult is a future promise to deliver the result of a RawRequest RPC
|
||||||
|
// invocation (or an applicable error).
|
||||||
|
type FutureRawResult chan *response
|
||||||
|
|
||||||
|
// Receive waits for the response promised by the future and returns the raw
|
||||||
|
// response, or an error if the request was unsuccessful.
|
||||||
|
func (r FutureRawResult) Receive() (json.RawMessage, error) {
|
||||||
|
return receiveFuture(r)
|
||||||
|
}
|
||||||
|
|
||||||
|
// RawRequestAsync returns an instance of a type that can be used to get the
|
||||||
|
// result of a custom RPC request at some future time by invoking the Receive
|
||||||
|
// function on the returned instance.
|
||||||
|
//
|
||||||
|
// See RawRequest for the blocking version and more details.
|
||||||
|
func (c *Client) RawRequestAsync(method string, params []json.RawMessage) FutureRawResult {
|
||||||
|
// Method may not be empty.
|
||||||
|
if method == "" {
|
||||||
|
return newFutureError(errors.New("no method"))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Marshal parameters as "[]" instead of "null" when no parameters
|
||||||
|
// are passed.
|
||||||
|
if params == nil {
|
||||||
|
params = []json.RawMessage{}
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd := &rawRequest{
|
||||||
|
RawCmd: btcjson.RawCmd{
|
||||||
|
Jsonrpc: "1.0",
|
||||||
|
Id: c.NextID(),
|
||||||
|
Method: method,
|
||||||
|
Params: params,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.sendCmd(cmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
// RawRequest allows the caller to send a raw or custom request to the server.
|
||||||
|
// This method may be used to send and receive requests and responses for
|
||||||
|
// requests that are not handled by this client package, or to proxy partially
|
||||||
|
// unmarshaled requests to another JSON-RPC server if a request cannot be
|
||||||
|
// handled directly.
|
||||||
|
func (c *Client) RawRequest(method string, params []json.RawMessage) (json.RawMessage, error) {
|
||||||
|
return c.RawRequestAsync(method, params).Receive()
|
||||||
|
}
|
|
@ -7,7 +7,7 @@ package btcrpcclient
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"fmt"
|
"encoding/json"
|
||||||
"github.com/conformal/btcjson"
|
"github.com/conformal/btcjson"
|
||||||
"github.com/conformal/btcutil"
|
"github.com/conformal/btcutil"
|
||||||
"github.com/conformal/btcwire"
|
"github.com/conformal/btcwire"
|
||||||
|
@ -58,21 +58,21 @@ func (s SigHashType) String() string {
|
||||||
|
|
||||||
// FutureGetRawTransactionResult is a future promise to deliver the result of a
|
// FutureGetRawTransactionResult is a future promise to deliver the result of a
|
||||||
// GetRawTransactionAsync RPC invocation (or an applicable error).
|
// GetRawTransactionAsync RPC invocation (or an applicable error).
|
||||||
type FutureGetRawTransactionResult chan *futureResult
|
type FutureGetRawTransactionResult chan *response
|
||||||
|
|
||||||
// Receive waits for the response promised by the future and returns a
|
// Receive waits for the response promised by the future and returns a
|
||||||
// transaction given its hash.
|
// transaction given its hash.
|
||||||
func (r FutureGetRawTransactionResult) Receive() (*btcutil.Tx, error) {
|
func (r FutureGetRawTransactionResult) Receive() (*btcutil.Tx, error) {
|
||||||
reply, err := receiveFuture(r)
|
res, err := receiveFuture(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure the returned data is the expected type.
|
// Unmarshal result as a string.
|
||||||
txHex, ok := reply.(string)
|
var txHex string
|
||||||
if !ok {
|
err = json.Unmarshal(res, &txHex)
|
||||||
return nil, fmt.Errorf("unexpected response type for "+
|
if err != nil {
|
||||||
"getrawtransaction (verbose=0): %T\n", reply)
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decode the serialized transaction hex to raw bytes.
|
// Decode the serialized transaction hex to raw bytes.
|
||||||
|
@ -120,24 +120,24 @@ func (c *Client) GetRawTransaction(txHash *btcwire.ShaHash) (*btcutil.Tx, error)
|
||||||
// FutureGetRawTransactionVerboseResult is a future promise to deliver the
|
// FutureGetRawTransactionVerboseResult is a future promise to deliver the
|
||||||
// result of a GetRawTransactionVerboseAsync RPC invocation (or an applicable
|
// result of a GetRawTransactionVerboseAsync RPC invocation (or an applicable
|
||||||
// error).
|
// error).
|
||||||
type FutureGetRawTransactionVerboseResult chan *futureResult
|
type FutureGetRawTransactionVerboseResult chan *response
|
||||||
|
|
||||||
// Receive waits for the response promised by the future and returns information
|
// Receive waits for the response promised by the future and returns information
|
||||||
// about a transaction given its hash.
|
// about a transaction given its hash.
|
||||||
func (r FutureGetRawTransactionVerboseResult) Receive() (*btcjson.TxRawResult, error) {
|
func (r FutureGetRawTransactionVerboseResult) Receive() (*btcjson.TxRawResult, error) {
|
||||||
reply, err := receiveFuture(r)
|
res, err := receiveFuture(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure the returned data is the expected type.
|
// Unmarshal result as a gettrawtransaction result object.
|
||||||
result, ok := reply.(*btcjson.TxRawResult)
|
var rawTxResult btcjson.TxRawResult
|
||||||
if !ok {
|
err = json.Unmarshal(res, &rawTxResult)
|
||||||
return nil, fmt.Errorf("unexpected response type for "+
|
if err != nil {
|
||||||
"getrawtransaction (verbose=1): %T\n", reply)
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return result, nil
|
return &rawTxResult, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetRawTransactionVerboseAsync returns an instance of a type that can be used
|
// GetRawTransactionVerboseAsync returns an instance of a type that can be used
|
||||||
|
@ -170,24 +170,24 @@ func (c *Client) GetRawTransactionVerbose(txHash *btcwire.ShaHash) (*btcjson.TxR
|
||||||
|
|
||||||
// FutureDecodeRawTransactionResult is a future promise to deliver the result
|
// FutureDecodeRawTransactionResult is a future promise to deliver the result
|
||||||
// of a DecodeRawTransactionAsync RPC invocation (or an applicable error).
|
// of a DecodeRawTransactionAsync RPC invocation (or an applicable error).
|
||||||
type FutureDecodeRawTransactionResult chan *futureResult
|
type FutureDecodeRawTransactionResult chan *response
|
||||||
|
|
||||||
// Receive waits for the response promised by the future and returns information
|
// Receive waits for the response promised by the future and returns information
|
||||||
// about a transaction given its serialized bytes.
|
// about a transaction given its serialized bytes.
|
||||||
func (r FutureDecodeRawTransactionResult) Receive() (*btcjson.TxRawResult, error) {
|
func (r FutureDecodeRawTransactionResult) Receive() (*btcjson.TxRawResult, error) {
|
||||||
reply, err := receiveFuture(r)
|
res, err := receiveFuture(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure the returned data is the expected type.
|
// Unmarshal result as a decoderawtransaction result object.
|
||||||
result, ok := reply.(*btcjson.TxRawResult)
|
var rawTxResult btcjson.TxRawResult
|
||||||
if !ok {
|
err = json.Unmarshal(res, &rawTxResult)
|
||||||
return nil, fmt.Errorf("unexpected response type for "+
|
if err != nil {
|
||||||
"decoderawtransaction: %T\n", reply)
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return result, nil
|
return &rawTxResult, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// DecodeRawTransactionAsync returns an instance of a type that can be used to
|
// DecodeRawTransactionAsync returns an instance of a type that can be used to
|
||||||
|
@ -214,22 +214,22 @@ func (c *Client) DecodeRawTransaction(serializedTx []byte) (*btcjson.TxRawResult
|
||||||
|
|
||||||
// FutureCreateRawTransactionResult is a future promise to deliver the result
|
// FutureCreateRawTransactionResult is a future promise to deliver the result
|
||||||
// of a CreateRawTransactionAsync RPC invocation (or an applicable error).
|
// of a CreateRawTransactionAsync RPC invocation (or an applicable error).
|
||||||
type FutureCreateRawTransactionResult chan *futureResult
|
type FutureCreateRawTransactionResult chan *response
|
||||||
|
|
||||||
// Receive waits for the response promised by the future and returns a new
|
// Receive waits for the response promised by the future and returns a new
|
||||||
// transaction spending the provided inputs and sending to the provided
|
// transaction spending the provided inputs and sending to the provided
|
||||||
// addresses.
|
// addresses.
|
||||||
func (r FutureCreateRawTransactionResult) Receive() (*btcwire.MsgTx, error) {
|
func (r FutureCreateRawTransactionResult) Receive() (*btcwire.MsgTx, error) {
|
||||||
reply, err := receiveFuture(r)
|
res, err := receiveFuture(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure the returned data is the expected type.
|
// Unmarshal result as a string.
|
||||||
txHex, ok := reply.(string)
|
var txHex string
|
||||||
if !ok {
|
err = json.Unmarshal(res, &txHex)
|
||||||
return nil, fmt.Errorf("unexpected response type for "+
|
if err != nil {
|
||||||
"createrawtransaction: %T\n", reply)
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decode the serialized transaction hex to raw bytes.
|
// Decode the serialized transaction hex to raw bytes.
|
||||||
|
@ -277,22 +277,22 @@ func (c *Client) CreateRawTransaction(inputs []btcjson.TransactionInput,
|
||||||
|
|
||||||
// FutureSendRawTransactionResult is a future promise to deliver the result
|
// FutureSendRawTransactionResult is a future promise to deliver the result
|
||||||
// of a SendRawTransactionAsync RPC invocation (or an applicable error).
|
// of a SendRawTransactionAsync RPC invocation (or an applicable error).
|
||||||
type FutureSendRawTransactionResult chan *futureResult
|
type FutureSendRawTransactionResult chan *response
|
||||||
|
|
||||||
// Receive waits for the response promised by the future and returns the result
|
// Receive waits for the response promised by the future and returns the result
|
||||||
// of submitting the encoded transaction to the server which then relays it to
|
// of submitting the encoded transaction to the server which then relays it to
|
||||||
// the network.
|
// the network.
|
||||||
func (r FutureSendRawTransactionResult) Receive() (*btcwire.ShaHash, error) {
|
func (r FutureSendRawTransactionResult) Receive() (*btcwire.ShaHash, error) {
|
||||||
reply, err := receiveFuture(r)
|
res, err := receiveFuture(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure the returned data is the expected type.
|
// Unmarshal result as a string.
|
||||||
txHashStr, ok := reply.(string)
|
var txHashStr string
|
||||||
if !ok {
|
err = json.Unmarshal(res, &txHashStr)
|
||||||
return nil, fmt.Errorf("unexpected response type for "+
|
if err != nil {
|
||||||
"decoderawtransaction: %T\n", reply)
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return btcwire.NewShaHashFromStr(txHashStr)
|
return btcwire.NewShaHashFromStr(txHashStr)
|
||||||
|
@ -332,25 +332,25 @@ func (c *Client) SendRawTransaction(tx *btcwire.MsgTx, allowHighFees bool) (*btc
|
||||||
// FutureSignRawTransactionResult is a future promise to deliver the result
|
// FutureSignRawTransactionResult is a future promise to deliver the result
|
||||||
// of one of the SignRawTransactionAsync family of RPC invocations (or an
|
// of one of the SignRawTransactionAsync family of RPC invocations (or an
|
||||||
// applicable error).
|
// applicable error).
|
||||||
type FutureSignRawTransactionResult chan *futureResult
|
type FutureSignRawTransactionResult chan *response
|
||||||
|
|
||||||
// Receive waits for the response promised by the future and returns the
|
// Receive waits for the response promised by the future and returns the
|
||||||
// signed transaction as well as whether or not all inputs are now signed.
|
// signed transaction as well as whether or not all inputs are now signed.
|
||||||
func (r FutureSignRawTransactionResult) Receive() (*btcwire.MsgTx, bool, error) {
|
func (r FutureSignRawTransactionResult) Receive() (*btcwire.MsgTx, bool, error) {
|
||||||
reply, err := receiveFuture(r)
|
res, err := receiveFuture(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, false, err
|
return nil, false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure the returned data is the expected type.
|
// Unmarshal as a signrawtransaction result.
|
||||||
result, ok := reply.(*btcjson.SignRawTransactionResult)
|
var signRawTxResult btcjson.SignRawTransactionResult
|
||||||
if !ok {
|
err = json.Unmarshal(res, &signRawTxResult)
|
||||||
return nil, false, fmt.Errorf("unexpected response type for "+
|
if err != nil {
|
||||||
"signrawtransaction: %T\n", reply)
|
return nil, false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decode the serialized transaction hex to raw bytes.
|
// Decode the serialized transaction hex to raw bytes.
|
||||||
serializedTx, err := hex.DecodeString(result.Hex)
|
serializedTx, err := hex.DecodeString(signRawTxResult.Hex)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, false, err
|
return nil, false, err
|
||||||
}
|
}
|
||||||
|
@ -361,7 +361,7 @@ func (r FutureSignRawTransactionResult) Receive() (*btcwire.MsgTx, bool, error)
|
||||||
return nil, false, err
|
return nil, false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return &msgTx, result.Complete, nil
|
return &msgTx, signRawTxResult.Complete, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// SignRawTransactionAsync returns an instance of a type that can be used to get
|
// SignRawTransactionAsync returns an instance of a type that can be used to get
|
||||||
|
|
374
wallet.go
374
wallet.go
|
@ -5,7 +5,7 @@
|
||||||
package btcrpcclient
|
package btcrpcclient
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"encoding/json"
|
||||||
"github.com/conformal/btcjson"
|
"github.com/conformal/btcjson"
|
||||||
"github.com/conformal/btcnet"
|
"github.com/conformal/btcnet"
|
||||||
"github.com/conformal/btcutil"
|
"github.com/conformal/btcutil"
|
||||||
|
@ -19,24 +19,24 @@ import (
|
||||||
|
|
||||||
// FutureGetTransactionResult is a future promise to deliver the result
|
// FutureGetTransactionResult is a future promise to deliver the result
|
||||||
// of a GetTransactionAsync RPC invocation (or an applicable error).
|
// of a GetTransactionAsync RPC invocation (or an applicable error).
|
||||||
type FutureGetTransactionResult chan *futureResult
|
type FutureGetTransactionResult chan *response
|
||||||
|
|
||||||
// Receive waits for the response promised by the future and returns detailed
|
// Receive waits for the response promised by the future and returns detailed
|
||||||
// information about a wallet transaction.
|
// information about a wallet transaction.
|
||||||
func (r FutureGetTransactionResult) Receive() (*btcjson.GetTransactionResult, error) {
|
func (r FutureGetTransactionResult) Receive() (*btcjson.GetTransactionResult, error) {
|
||||||
reply, err := receiveFuture(r)
|
res, err := receiveFuture(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure the returned data is the expected type.
|
// Unmarshal result as a gettransaction result object
|
||||||
result, ok := reply.(*btcjson.GetTransactionResult)
|
var getTx btcjson.GetTransactionResult
|
||||||
if !ok {
|
err = json.Unmarshal(res, &getTx)
|
||||||
return nil, fmt.Errorf("unexpected response type for "+
|
if err != nil {
|
||||||
"gettransaction: %T\n", reply)
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return result, nil
|
return &getTx, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetTransactionAsync returns an instance of a type that can be used to get the
|
// GetTransactionAsync returns an instance of a type that can be used to get the
|
||||||
|
@ -69,26 +69,21 @@ func (c *Client) GetTransaction(txHash *btcwire.ShaHash) (*btcjson.GetTransactio
|
||||||
// FutureListTransactionsResult is a future promise to deliver the result of a
|
// FutureListTransactionsResult is a future promise to deliver the result of a
|
||||||
// ListTransactionsAsync, ListTransactionsCountAsync, or
|
// ListTransactionsAsync, ListTransactionsCountAsync, or
|
||||||
// ListTransactionsCountFromAsync RPC invocation (or an applicable error).
|
// ListTransactionsCountFromAsync RPC invocation (or an applicable error).
|
||||||
type FutureListTransactionsResult chan *futureResult
|
type FutureListTransactionsResult chan *response
|
||||||
|
|
||||||
// Receive waits for the response promised by the future and returns a list of
|
// Receive waits for the response promised by the future and returns a list of
|
||||||
// the most recent transactions.
|
// the most recent transactions.
|
||||||
func (r FutureListTransactionsResult) Receive() ([]btcjson.ListTransactionsResult, error) {
|
func (r FutureListTransactionsResult) Receive() ([]btcjson.ListTransactionsResult, error) {
|
||||||
reply, err := receiveFuture(r)
|
res, err := receiveFuture(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// No transactions.
|
// Unmarshal result as an array of listtransaction result objects.
|
||||||
if reply == nil {
|
var transactions []btcjson.ListTransactionsResult
|
||||||
return nil, nil
|
err = json.Unmarshal(res, &transactions)
|
||||||
}
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
// Ensure the returned data is the expected type.
|
|
||||||
transactions, ok := reply.([]btcjson.ListTransactionsResult)
|
|
||||||
if !ok {
|
|
||||||
return nil, fmt.Errorf("unexpected response type for "+
|
|
||||||
"listtransactions: %T\n", reply)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return transactions, nil
|
return transactions, nil
|
||||||
|
@ -167,7 +162,7 @@ func (c *Client) ListTransactionsCountFrom(account string, count, from int) ([]b
|
||||||
// FutureListUnspentResult is a future promise to deliver the result of a
|
// FutureListUnspentResult is a future promise to deliver the result of a
|
||||||
// ListUnspentAsync, ListUnspentMinAsync, ListUnspentMinMaxAsync, or
|
// ListUnspentAsync, ListUnspentMinAsync, ListUnspentMinMaxAsync, or
|
||||||
// ListUnspentMinMaxAddressesAsync RPC invocation (or an applicable error).
|
// ListUnspentMinMaxAddressesAsync RPC invocation (or an applicable error).
|
||||||
type FutureListUnspentResult chan *futureResult
|
type FutureListUnspentResult chan *response
|
||||||
|
|
||||||
// Receive waits for the response promised by the future and returns all
|
// Receive waits for the response promised by the future and returns all
|
||||||
// unspent wallet transaction outputs returned by the RPC call. If the
|
// unspent wallet transaction outputs returned by the RPC call. If the
|
||||||
|
@ -175,21 +170,16 @@ type FutureListUnspentResult chan *futureResult
|
||||||
// or ListUnspentMinMaxAddressesAsync, the range may be limited by the
|
// or ListUnspentMinMaxAddressesAsync, the range may be limited by the
|
||||||
// parameters of the RPC invocation.
|
// parameters of the RPC invocation.
|
||||||
func (r FutureListUnspentResult) Receive() ([]btcjson.ListUnspentResult, error) {
|
func (r FutureListUnspentResult) Receive() ([]btcjson.ListUnspentResult, error) {
|
||||||
reply, err := receiveFuture(r)
|
res, err := receiveFuture(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// No unspent transaction outputs.
|
// Unmarshal result as an array of listunspent results.
|
||||||
if reply == nil {
|
var unspent []btcjson.ListUnspentResult
|
||||||
return nil, nil
|
err = json.Unmarshal(res, &unspent)
|
||||||
}
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
// Ensure the returned data is the expected type.
|
|
||||||
unspent, ok := reply.([]btcjson.ListUnspentResult)
|
|
||||||
if !ok {
|
|
||||||
return nil, fmt.Errorf("unexpected response type for "+
|
|
||||||
"listunspent: %T\n", reply)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return unspent, nil
|
return unspent, nil
|
||||||
|
@ -291,25 +281,25 @@ func (c *Client) ListUnspentMinMaxAddresses(minConf, maxConf int, addrs []btcuti
|
||||||
// FutureListSinceBlockResult is a future promise to deliver the result of a
|
// FutureListSinceBlockResult is a future promise to deliver the result of a
|
||||||
// ListSinceBlockAsync or ListSinceBlockMinConfAsync RPC invocation (or an
|
// ListSinceBlockAsync or ListSinceBlockMinConfAsync RPC invocation (or an
|
||||||
// applicable error).
|
// applicable error).
|
||||||
type FutureListSinceBlockResult chan *futureResult
|
type FutureListSinceBlockResult chan *response
|
||||||
|
|
||||||
// Receive waits for the response promised by the future and returns all
|
// Receive waits for the response promised by the future and returns all
|
||||||
// transactions added in blocks since the specified block hash, or all
|
// transactions added in blocks since the specified block hash, or all
|
||||||
// transactions if it is nil.
|
// transactions if it is nil.
|
||||||
func (r FutureListSinceBlockResult) Receive() (*btcjson.ListSinceBlockResult, error) {
|
func (r FutureListSinceBlockResult) Receive() (*btcjson.ListSinceBlockResult, error) {
|
||||||
reply, err := receiveFuture(r)
|
res, err := receiveFuture(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure the returned data is the expected type.
|
// Unmarshal result as a listsinceblock result object.
|
||||||
listResult, ok := reply.(*btcjson.ListSinceBlockResult)
|
var listResult btcjson.ListSinceBlockResult
|
||||||
if !ok {
|
err = json.Unmarshal(res, &listResult)
|
||||||
return nil, fmt.Errorf("unexpected response type for "+
|
if err != nil {
|
||||||
"listsinceblock: %T\n", reply)
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return listResult, nil
|
return &listResult, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ListSinceBlockAsync returns an instance of a type that can be used to get
|
// ListSinceBlockAsync returns an instance of a type that can be used to get
|
||||||
|
@ -376,7 +366,7 @@ func (c *Client) ListSinceBlockMinConf(blockHash *btcwire.ShaHash, minConfirms i
|
||||||
|
|
||||||
// FutureSetTxFeeResult is a future promise to deliver the result of a
|
// FutureSetTxFeeResult is a future promise to deliver the result of a
|
||||||
// SetTxFeeAsync RPC invocation (or an applicable error).
|
// SetTxFeeAsync RPC invocation (or an applicable error).
|
||||||
type FutureSetTxFeeResult chan *futureResult
|
type FutureSetTxFeeResult chan *response
|
||||||
|
|
||||||
// Receive waits for the response promised by the future and returns the result
|
// Receive waits for the response promised by the future and returns the result
|
||||||
// of setting an optional transaction fee per KB that helps ensure transactions
|
// of setting an optional transaction fee per KB that helps ensure transactions
|
||||||
|
@ -413,20 +403,21 @@ func (c *Client) SetTxFee(fee btcutil.Amount) error {
|
||||||
|
|
||||||
// FutureSendToAddressResult is a future promise to deliver the result of a
|
// FutureSendToAddressResult is a future promise to deliver the result of a
|
||||||
// SendToAddressAsync RPC invocation (or an applicable error).
|
// SendToAddressAsync RPC invocation (or an applicable error).
|
||||||
type FutureSendToAddressResult chan *futureResult
|
type FutureSendToAddressResult chan *response
|
||||||
|
|
||||||
// Receive waits for the response promised by the future and returns the hash
|
// Receive waits for the response promised by the future and returns the hash
|
||||||
// of the transaction sending the passed amount to the given address.
|
// of the transaction sending the passed amount to the given address.
|
||||||
func (r FutureSendToAddressResult) Receive() (*btcwire.ShaHash, error) {
|
func (r FutureSendToAddressResult) Receive() (*btcwire.ShaHash, error) {
|
||||||
reply, err := receiveFuture(r)
|
res, err := receiveFuture(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
txHash, ok := reply.(string)
|
// Unmarshal result as a string.
|
||||||
if !ok {
|
var txHash string
|
||||||
return nil, fmt.Errorf("unexpected response type for "+
|
err = json.Unmarshal(res, &txHash)
|
||||||
"sendtoaddress: %T\n", reply)
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return btcwire.NewShaHashFromStr(txHash)
|
return btcwire.NewShaHashFromStr(txHash)
|
||||||
|
@ -500,22 +491,22 @@ func (c *Client) SendToAddressComment(address btcutil.Address, amount btcutil.Am
|
||||||
// FutureSendFromResult is a future promise to deliver the result of a
|
// FutureSendFromResult is a future promise to deliver the result of a
|
||||||
// SendFromAsync, SendFromMinConfAsync, or SendFromCommentAsync RPC invocation
|
// SendFromAsync, SendFromMinConfAsync, or SendFromCommentAsync RPC invocation
|
||||||
// (or an applicable error).
|
// (or an applicable error).
|
||||||
type FutureSendFromResult chan *futureResult
|
type FutureSendFromResult chan *response
|
||||||
|
|
||||||
// Receive waits for the response promised by the future and returns the hash
|
// Receive waits for the response promised by the future and returns the hash
|
||||||
// of the transaction sending amount to the given address using the provided
|
// of the transaction sending amount to the given address using the provided
|
||||||
// account as a source of funds.
|
// account as a source of funds.
|
||||||
func (r FutureSendFromResult) Receive() (*btcwire.ShaHash, error) {
|
func (r FutureSendFromResult) Receive() (*btcwire.ShaHash, error) {
|
||||||
reply, err := receiveFuture(r)
|
res, err := receiveFuture(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure the returned data is the expected type.
|
// Unmarshal result as a string.
|
||||||
txHash, ok := reply.(string)
|
var txHash string
|
||||||
if !ok {
|
err = json.Unmarshal(res, &txHash)
|
||||||
return nil, fmt.Errorf("unexpected response type for "+
|
if err != nil {
|
||||||
"sendfrom: %T\n", reply)
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return btcwire.NewShaHashFromStr(txHash)
|
return btcwire.NewShaHashFromStr(txHash)
|
||||||
|
@ -622,22 +613,22 @@ func (c *Client) SendFromComment(fromAccount string, toAddress btcutil.Address,
|
||||||
// FutureSendManyResult is a future promise to deliver the result of a
|
// FutureSendManyResult is a future promise to deliver the result of a
|
||||||
// SendManyAsync, SendManyMinConfAsync, or SendManyCommentAsync RPC invocation
|
// SendManyAsync, SendManyMinConfAsync, or SendManyCommentAsync RPC invocation
|
||||||
// (or an applicable error).
|
// (or an applicable error).
|
||||||
type FutureSendManyResult chan *futureResult
|
type FutureSendManyResult chan *response
|
||||||
|
|
||||||
// Receive waits for the response promised by the future and returns the hash
|
// Receive waits for the response promised by the future and returns the hash
|
||||||
// of the transaction sending multiple amounts to multiple addresses using the
|
// of the transaction sending multiple amounts to multiple addresses using the
|
||||||
// provided account as a source of funds.
|
// provided account as a source of funds.
|
||||||
func (r FutureSendManyResult) Receive() (*btcwire.ShaHash, error) {
|
func (r FutureSendManyResult) Receive() (*btcwire.ShaHash, error) {
|
||||||
reply, err := receiveFuture(r)
|
res, err := receiveFuture(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure the returned data is the expected type.
|
// Unmashal result as a string.
|
||||||
txHash, ok := reply.(string)
|
var txHash string
|
||||||
if !ok {
|
err = json.Unmarshal(res, &txHash)
|
||||||
return nil, fmt.Errorf("unexpected response type for "+
|
if err != nil {
|
||||||
"sendmany: %T\n", reply)
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return btcwire.NewShaHashFromStr(txHash)
|
return btcwire.NewShaHashFromStr(txHash)
|
||||||
|
@ -760,22 +751,22 @@ func (c *Client) SendManyComment(fromAccount string,
|
||||||
|
|
||||||
// FutureAddMultisigAddressResult is a future promise to deliver the result of a
|
// FutureAddMultisigAddressResult is a future promise to deliver the result of a
|
||||||
// AddMultisigAddressAsync RPC invocation (or an applicable error).
|
// AddMultisigAddressAsync RPC invocation (or an applicable error).
|
||||||
type FutureAddMultisigAddressResult chan *futureResult
|
type FutureAddMultisigAddressResult chan *response
|
||||||
|
|
||||||
// Receive waits for the response promised by the future and returns the
|
// Receive waits for the response promised by the future and returns the
|
||||||
// multisignature address that requires the specified number of signatures for
|
// multisignature address that requires the specified number of signatures for
|
||||||
// the provided addresses.
|
// the provided addresses.
|
||||||
func (r FutureAddMultisigAddressResult) Receive() (btcutil.Address, error) {
|
func (r FutureAddMultisigAddressResult) Receive() (btcutil.Address, error) {
|
||||||
reply, err := receiveFuture(r)
|
res, err := receiveFuture(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure the returned data is the expected type.
|
// Unmarshal result as a string.
|
||||||
addr, ok := reply.(string)
|
var addr string
|
||||||
if !ok {
|
err = json.Unmarshal(res, &addr)
|
||||||
return nil, fmt.Errorf("unexpected response type for "+
|
if err != nil {
|
||||||
"addmultisigaddress: %T\n", reply)
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return btcutil.DecodeAddress(addr, &btcnet.MainNetParams)
|
return btcutil.DecodeAddress(addr, &btcnet.MainNetParams)
|
||||||
|
@ -811,24 +802,24 @@ func (c *Client) AddMultisigAddress(requiredSigs int, addresses []btcutil.Addres
|
||||||
|
|
||||||
// FutureCreateMultisigResult is a future promise to deliver the result of a
|
// FutureCreateMultisigResult is a future promise to deliver the result of a
|
||||||
// CreateMultisigAsync RPC invocation (or an applicable error).
|
// CreateMultisigAsync RPC invocation (or an applicable error).
|
||||||
type FutureCreateMultisigResult chan *futureResult
|
type FutureCreateMultisigResult chan *response
|
||||||
|
|
||||||
// Receive waits for the response promised by the future and returns the
|
// Receive waits for the response promised by the future and returns the
|
||||||
// multisignature address and script needed to redeem it.
|
// multisignature address and script needed to redeem it.
|
||||||
func (r FutureCreateMultisigResult) Receive() (*btcjson.CreateMultiSigResult, error) {
|
func (r FutureCreateMultisigResult) Receive() (*btcjson.CreateMultiSigResult, error) {
|
||||||
reply, err := receiveFuture(r)
|
res, err := receiveFuture(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure the returned data is the expected type.
|
// Unmarshal result as a createmultisig result object.
|
||||||
result, ok := reply.(*btcjson.CreateMultiSigResult)
|
var multisigRes btcjson.CreateMultiSigResult
|
||||||
if !ok {
|
err = json.Unmarshal(res, &multisigRes)
|
||||||
return nil, fmt.Errorf("unexpected response type for "+
|
if err != nil {
|
||||||
"createmultisig: %T\n", reply)
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return result, nil
|
return &multisigRes, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateMultisigAsync returns an instance of a type that can be used to get
|
// CreateMultisigAsync returns an instance of a type that can be used to get
|
||||||
|
@ -861,21 +852,21 @@ func (c *Client) CreateMultisig(requiredSigs int, addresses []btcutil.Address) (
|
||||||
|
|
||||||
// FutureGetNewAddressResult is a future promise to deliver the result of a
|
// FutureGetNewAddressResult is a future promise to deliver the result of a
|
||||||
// GetNewAddressAsync RPC invocation (or an applicable error).
|
// GetNewAddressAsync RPC invocation (or an applicable error).
|
||||||
type FutureGetNewAddressResult chan *futureResult
|
type FutureGetNewAddressResult chan *response
|
||||||
|
|
||||||
// Receive waits for the response promised by the future and returns a new
|
// Receive waits for the response promised by the future and returns a new
|
||||||
// address.
|
// address.
|
||||||
func (r FutureGetNewAddressResult) Receive() (btcutil.Address, error) {
|
func (r FutureGetNewAddressResult) Receive() (btcutil.Address, error) {
|
||||||
reply, err := receiveFuture(r)
|
res, err := receiveFuture(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure the returned data is the expected type.
|
// Unmarshal result as a string.
|
||||||
addr, ok := reply.(string)
|
var addr string
|
||||||
if !ok {
|
err = json.Unmarshal(res, &addr)
|
||||||
return nil, fmt.Errorf("unexpected response type for "+
|
if err != nil {
|
||||||
"getnewaddress: %T\n", reply)
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return btcutil.DecodeAddress(addr, &btcnet.MainNetParams)
|
return btcutil.DecodeAddress(addr, &btcnet.MainNetParams)
|
||||||
|
@ -903,22 +894,22 @@ func (c *Client) GetNewAddress() (btcutil.Address, error) {
|
||||||
|
|
||||||
// FutureGetRawChangeAddressResult is a future promise to deliver the result of
|
// FutureGetRawChangeAddressResult is a future promise to deliver the result of
|
||||||
// a GetRawChangeAddressAsync RPC invocation (or an applicable error).
|
// a GetRawChangeAddressAsync RPC invocation (or an applicable error).
|
||||||
type FutureGetRawChangeAddressResult chan *futureResult
|
type FutureGetRawChangeAddressResult chan *response
|
||||||
|
|
||||||
// Receive waits for the response promised by the future and returns a new
|
// Receive waits for the response promised by the future and returns a new
|
||||||
// address for receiving change that will be associated with the provided
|
// address for receiving change that will be associated with the provided
|
||||||
// account. Note that this is only for raw transactions and NOT for normal use.
|
// account. Note that this is only for raw transactions and NOT for normal use.
|
||||||
func (r FutureGetRawChangeAddressResult) Receive() (btcutil.Address, error) {
|
func (r FutureGetRawChangeAddressResult) Receive() (btcutil.Address, error) {
|
||||||
reply, err := receiveFuture(r)
|
res, err := receiveFuture(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure the returned data is the expected type.
|
// Unmarshal result as a string.
|
||||||
addr, ok := reply.(string)
|
var addr string
|
||||||
if !ok {
|
err = json.Unmarshal(res, &addr)
|
||||||
return nil, fmt.Errorf("unexpected response type for "+
|
if err != nil {
|
||||||
"getrawchangeaddress: %T\n", reply)
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return btcutil.DecodeAddress(addr, &btcnet.MainNetParams)
|
return btcutil.DecodeAddress(addr, &btcnet.MainNetParams)
|
||||||
|
@ -948,21 +939,21 @@ func (c *Client) GetRawChangeAddress(account string) (btcutil.Address, error) {
|
||||||
|
|
||||||
// FutureGetAccountAddressResult is a future promise to deliver the result of a
|
// FutureGetAccountAddressResult is a future promise to deliver the result of a
|
||||||
// GetAccountAddressAsync RPC invocation (or an applicable error).
|
// GetAccountAddressAsync RPC invocation (or an applicable error).
|
||||||
type FutureGetAccountAddressResult chan *futureResult
|
type FutureGetAccountAddressResult chan *response
|
||||||
|
|
||||||
// Receive waits for the response promised by the future and returns the current
|
// Receive waits for the response promised by the future and returns the current
|
||||||
// Bitcoin address for receiving payments to the specified account.
|
// Bitcoin address for receiving payments to the specified account.
|
||||||
func (r FutureGetAccountAddressResult) Receive() (btcutil.Address, error) {
|
func (r FutureGetAccountAddressResult) Receive() (btcutil.Address, error) {
|
||||||
reply, err := receiveFuture(r)
|
res, err := receiveFuture(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure the returned data is the expected type.
|
// Unmarshal result as a string.
|
||||||
addr, ok := reply.(string)
|
var addr string
|
||||||
if !ok {
|
err = json.Unmarshal(res, &addr)
|
||||||
return nil, fmt.Errorf("unexpected response type for "+
|
if err != nil {
|
||||||
"getaccountaddress: %T\n", reply)
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return btcutil.DecodeAddress(addr, &btcnet.MainNetParams)
|
return btcutil.DecodeAddress(addr, &btcnet.MainNetParams)
|
||||||
|
@ -991,21 +982,21 @@ func (c *Client) GetAccountAddress(account string) (btcutil.Address, error) {
|
||||||
|
|
||||||
// FutureGetAccountResult is a future promise to deliver the result of a
|
// FutureGetAccountResult is a future promise to deliver the result of a
|
||||||
// GetAccountAsync RPC invocation (or an applicable error).
|
// GetAccountAsync RPC invocation (or an applicable error).
|
||||||
type FutureGetAccountResult chan *futureResult
|
type FutureGetAccountResult chan *response
|
||||||
|
|
||||||
// Receive waits for the response promised by the future and returns the account
|
// Receive waits for the response promised by the future and returns the account
|
||||||
// associated with the passed address.
|
// associated with the passed address.
|
||||||
func (r FutureGetAccountResult) Receive() (string, error) {
|
func (r FutureGetAccountResult) Receive() (string, error) {
|
||||||
reply, err := receiveFuture(r)
|
res, err := receiveFuture(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure the returned data is the expected type.
|
// Unmarshal result as a string.
|
||||||
account, ok := reply.(string)
|
var account string
|
||||||
if !ok {
|
err = json.Unmarshal(res, &account)
|
||||||
return "", fmt.Errorf("unexpected response type for "+
|
if err != nil {
|
||||||
"getaccount: %T\n", reply)
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
return account, nil
|
return account, nil
|
||||||
|
@ -1034,7 +1025,7 @@ func (c *Client) GetAccount(address btcutil.Address) (string, error) {
|
||||||
|
|
||||||
// FutureSetAccountResult is a future promise to deliver the result of a
|
// FutureSetAccountResult is a future promise to deliver the result of a
|
||||||
// SetAccountAsync RPC invocation (or an applicable error).
|
// SetAccountAsync RPC invocation (or an applicable error).
|
||||||
type FutureSetAccountResult chan *futureResult
|
type FutureSetAccountResult chan *response
|
||||||
|
|
||||||
// Receive waits for the response promised by the future and returns the result
|
// Receive waits for the response promised by the future and returns the result
|
||||||
// of setting the account to be associated with the passed address.
|
// of setting the account to be associated with the passed address.
|
||||||
|
@ -1070,21 +1061,21 @@ func (c *Client) SetAccount(address btcutil.Address, account string) error {
|
||||||
|
|
||||||
// FutureGetAddressesByAccountResult is a future promise to deliver the result
|
// FutureGetAddressesByAccountResult is a future promise to deliver the result
|
||||||
// of a GetAddressesByAccountAsync RPC invocation (or an applicable error).
|
// of a GetAddressesByAccountAsync RPC invocation (or an applicable error).
|
||||||
type FutureGetAddressesByAccountResult chan *futureResult
|
type FutureGetAddressesByAccountResult chan *response
|
||||||
|
|
||||||
// Receive waits for the response promised by the future and returns the list of
|
// Receive waits for the response promised by the future and returns the list of
|
||||||
// addresses associated with the passed account.
|
// addresses associated with the passed account.
|
||||||
func (r FutureGetAddressesByAccountResult) Receive() ([]btcutil.Address, error) {
|
func (r FutureGetAddressesByAccountResult) Receive() ([]btcutil.Address, error) {
|
||||||
reply, err := receiveFuture(r)
|
res, err := receiveFuture(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure the returned data is the expected type.
|
// Unmashal result as an array of string.
|
||||||
addrStrings, ok := reply.([]string)
|
var addrStrings []string
|
||||||
if !ok {
|
err = json.Unmarshal(res, &addrStrings)
|
||||||
return nil, fmt.Errorf("unexpected response type for "+
|
if err != nil {
|
||||||
"getaddressesbyaccount: %T\n", reply)
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
addrs := make([]btcutil.Address, 0, len(addrStrings))
|
addrs := make([]btcutil.Address, 0, len(addrStrings))
|
||||||
|
@ -1122,24 +1113,24 @@ func (c *Client) GetAddressesByAccount(account string) ([]btcutil.Address, error
|
||||||
|
|
||||||
// FutureValidateAddressResult is a future promise to deliver the result of a
|
// FutureValidateAddressResult is a future promise to deliver the result of a
|
||||||
// ValidateAddressAsync RPC invocation (or an applicable error).
|
// ValidateAddressAsync RPC invocation (or an applicable error).
|
||||||
type FutureValidateAddressResult chan *futureResult
|
type FutureValidateAddressResult chan *response
|
||||||
|
|
||||||
// Receive waits for the response promised by the future and returns information
|
// Receive waits for the response promised by the future and returns information
|
||||||
// about the given bitcoin address.
|
// about the given bitcoin address.
|
||||||
func (r FutureValidateAddressResult) Receive() (*btcjson.ValidateAddressResult, error) {
|
func (r FutureValidateAddressResult) Receive() (*btcjson.ValidateAddressResult, error) {
|
||||||
reply, err := receiveFuture(r)
|
res, err := receiveFuture(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure the returned data is the expected type.
|
// Unmarshal result as a validateaddress result object.
|
||||||
result, ok := reply.(*btcjson.ValidateAddressResult)
|
var addrResult btcjson.ValidateAddressResult
|
||||||
if !ok {
|
err = json.Unmarshal(res, &addrResult)
|
||||||
return nil, fmt.Errorf("unexpected response type for "+
|
if err != nil {
|
||||||
"validateaddress: %T\n", reply)
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return result, nil
|
return &addrResult, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ValidateAddressAsync returns an instance of a type that can be used to get
|
// ValidateAddressAsync returns an instance of a type that can be used to get
|
||||||
|
@ -1165,7 +1156,7 @@ func (c *Client) ValidateAddress(address btcutil.Address) (*btcjson.ValidateAddr
|
||||||
|
|
||||||
// FutureKeyPoolRefillResult is a future promise to deliver the result of a
|
// FutureKeyPoolRefillResult is a future promise to deliver the result of a
|
||||||
// KeyPoolRefillAsync RPC invocation (or an applicable error).
|
// KeyPoolRefillAsync RPC invocation (or an applicable error).
|
||||||
type FutureKeyPoolRefillResult chan *futureResult
|
type FutureKeyPoolRefillResult chan *response
|
||||||
|
|
||||||
// Receive waits for the response promised by the future and returns the result
|
// Receive waits for the response promised by the future and returns the result
|
||||||
// of refilling the key pool.
|
// of refilling the key pool.
|
||||||
|
@ -1228,21 +1219,21 @@ func (c *Client) KeyPoolRefillSize(newSize uint) error {
|
||||||
// FutureListAccountsResult is a future promise to deliver the result of a
|
// FutureListAccountsResult is a future promise to deliver the result of a
|
||||||
// ListAccountsAsync or ListAccountsMinConfAsync RPC invocation (or an
|
// ListAccountsAsync or ListAccountsMinConfAsync RPC invocation (or an
|
||||||
// applicable error).
|
// applicable error).
|
||||||
type FutureListAccountsResult chan *futureResult
|
type FutureListAccountsResult chan *response
|
||||||
|
|
||||||
// Receive waits for the response promised by the future and returns returns a
|
// Receive waits for the response promised by the future and returns returns a
|
||||||
// map of account names and their associated balances.
|
// map of account names and their associated balances.
|
||||||
func (r FutureListAccountsResult) Receive() (map[string]btcutil.Amount, error) {
|
func (r FutureListAccountsResult) Receive() (map[string]btcutil.Amount, error) {
|
||||||
reply, err := receiveFuture(r)
|
res, err := receiveFuture(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure the returned data is the expected type.
|
// Unmarshal result as a json object.
|
||||||
accounts, ok := reply.(map[string]float64)
|
var accounts map[string]float64
|
||||||
if !ok {
|
err = json.Unmarshal(res, &accounts)
|
||||||
return nil, fmt.Errorf("unexpected response type for "+
|
if err != nil {
|
||||||
"listaccounts: %T\n", reply)
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
accountsMap := make(map[string]btcutil.Amount)
|
accountsMap := make(map[string]btcutil.Amount)
|
||||||
|
@ -1307,21 +1298,21 @@ func (c *Client) ListAccountsMinConf(minConfirms int) (map[string]btcutil.Amount
|
||||||
// FutureGetBalanceResult is a future promise to deliver the result of a
|
// FutureGetBalanceResult is a future promise to deliver the result of a
|
||||||
// GetBalanceAsync or GetBalanceMinConfAsync RPC invocation (or an applicable
|
// GetBalanceAsync or GetBalanceMinConfAsync RPC invocation (or an applicable
|
||||||
// error).
|
// error).
|
||||||
type FutureGetBalanceResult chan *futureResult
|
type FutureGetBalanceResult chan *response
|
||||||
|
|
||||||
// Receive waits for the response promised by the future and returns the
|
// Receive waits for the response promised by the future and returns the
|
||||||
// available balance from the server for the specified account.
|
// available balance from the server for the specified account.
|
||||||
func (r FutureGetBalanceResult) Receive() (btcutil.Amount, error) {
|
func (r FutureGetBalanceResult) Receive() (btcutil.Amount, error) {
|
||||||
reply, err := receiveFuture(r)
|
res, err := receiveFuture(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure the returned data is the expected type.
|
// Unmarshal result as a floating point number.
|
||||||
balance, ok := reply.(float64)
|
var balance float64
|
||||||
if !ok {
|
err = json.Unmarshal(res, &balance)
|
||||||
return 0, fmt.Errorf("unexpected response type for "+
|
if err != nil {
|
||||||
"getbalance: %T\n", reply)
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
satoshi, err := btcjson.JSONToAmount(balance)
|
satoshi, err := btcjson.JSONToAmount(balance)
|
||||||
|
@ -1391,21 +1382,21 @@ func (c *Client) GetBalanceMinConf(account string, minConfirms int) (btcutil.Amo
|
||||||
// FutureGetReceivedByAccountResult is a future promise to deliver the result of
|
// FutureGetReceivedByAccountResult is a future promise to deliver the result of
|
||||||
// a GetReceivedByAccountAsync or GetReceivedByAccountMinConfAsync RPC
|
// a GetReceivedByAccountAsync or GetReceivedByAccountMinConfAsync RPC
|
||||||
// invocation (or an applicable error).
|
// invocation (or an applicable error).
|
||||||
type FutureGetReceivedByAccountResult chan *futureResult
|
type FutureGetReceivedByAccountResult chan *response
|
||||||
|
|
||||||
// Receive waits for the response promised by the future and returns the total
|
// Receive waits for the response promised by the future and returns the total
|
||||||
// amount received with the specified account.
|
// amount received with the specified account.
|
||||||
func (r FutureGetReceivedByAccountResult) Receive() (btcutil.Amount, error) {
|
func (r FutureGetReceivedByAccountResult) Receive() (btcutil.Amount, error) {
|
||||||
reply, err := receiveFuture(r)
|
res, err := receiveFuture(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure the returned data is the expected type.
|
// Unmarshal result as a floating point number.
|
||||||
balance, ok := reply.(float64)
|
var balance float64
|
||||||
if !ok {
|
err = json.Unmarshal(res, &balance)
|
||||||
return 0, fmt.Errorf("unexpected response type for "+
|
if err != nil {
|
||||||
"getreceivedbyaccount: %T\n", reply)
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
satoshi, err := btcjson.JSONToAmount(balance)
|
satoshi, err := btcjson.JSONToAmount(balance)
|
||||||
|
@ -1466,21 +1457,21 @@ func (c *Client) GetReceivedByAccountMinConf(account string, minConfirms int) (b
|
||||||
|
|
||||||
// FutureGetUnconfirmedBalanceResult is a future promise to deliver the result
|
// FutureGetUnconfirmedBalanceResult is a future promise to deliver the result
|
||||||
// of a GetUnconfirmedBalanceAsync RPC invocation (or an applicable error).
|
// of a GetUnconfirmedBalanceAsync RPC invocation (or an applicable error).
|
||||||
type FutureGetUnconfirmedBalanceResult chan *futureResult
|
type FutureGetUnconfirmedBalanceResult chan *response
|
||||||
|
|
||||||
// Receive waits for the response promised by the future and returns returns the
|
// Receive waits for the response promised by the future and returns returns the
|
||||||
// unconfirmed balance from the server for the specified account.
|
// unconfirmed balance from the server for the specified account.
|
||||||
func (r FutureGetUnconfirmedBalanceResult) Receive() (btcutil.Amount, error) {
|
func (r FutureGetUnconfirmedBalanceResult) Receive() (btcutil.Amount, error) {
|
||||||
reply, err := receiveFuture(r)
|
res, err := receiveFuture(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure the returned data is the expected type.
|
// Unmarshal result as a floating point number.
|
||||||
balance, ok := reply.(float64)
|
var balance float64
|
||||||
if !ok {
|
err = json.Unmarshal(res, &balance)
|
||||||
return 0, fmt.Errorf("unexpected response type for "+
|
if err != nil {
|
||||||
"getunconfirmedbalance: %T\n", reply)
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
satoshi, err := btcjson.JSONToAmount(balance)
|
satoshi, err := btcjson.JSONToAmount(balance)
|
||||||
|
@ -1515,21 +1506,21 @@ func (c *Client) GetUnconfirmedBalance(account string) (btcutil.Amount, error) {
|
||||||
// FutureGetReceivedByAddressResult is a future promise to deliver the result of
|
// FutureGetReceivedByAddressResult is a future promise to deliver the result of
|
||||||
// a GetReceivedByAddressAsync or GetReceivedByAddressMinConfAsync RPC
|
// a GetReceivedByAddressAsync or GetReceivedByAddressMinConfAsync RPC
|
||||||
// invocation (or an applicable error).
|
// invocation (or an applicable error).
|
||||||
type FutureGetReceivedByAddressResult chan *futureResult
|
type FutureGetReceivedByAddressResult chan *response
|
||||||
|
|
||||||
// Receive waits for the response promised by the future and returns the total
|
// Receive waits for the response promised by the future and returns the total
|
||||||
// amount received by the specified address.
|
// amount received by the specified address.
|
||||||
func (r FutureGetReceivedByAddressResult) Receive() (btcutil.Amount, error) {
|
func (r FutureGetReceivedByAddressResult) Receive() (btcutil.Amount, error) {
|
||||||
reply, err := receiveFuture(r)
|
res, err := receiveFuture(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure the returned data is the expected type.
|
// Unmarshal result as a floating point number.
|
||||||
balance, ok := reply.(float64)
|
var balance float64
|
||||||
if !ok {
|
err = json.Unmarshal(res, &balance)
|
||||||
return 0, fmt.Errorf("unexpected response type for "+
|
if err != nil {
|
||||||
"getreceivedbyaddress: %T\n", reply)
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
satoshi, err := btcjson.JSONToAmount(balance)
|
satoshi, err := btcjson.JSONToAmount(balance)
|
||||||
|
@ -1594,29 +1585,24 @@ func (c *Client) GetReceivedByAddressMinConf(address btcutil.Address, minConfirm
|
||||||
// of a ListReceivedByAccountAsync, ListReceivedByAccountMinConfAsync, or
|
// of a ListReceivedByAccountAsync, ListReceivedByAccountMinConfAsync, or
|
||||||
// ListReceivedByAccountIncludeEmptyAsync RPC invocation (or an applicable
|
// ListReceivedByAccountIncludeEmptyAsync RPC invocation (or an applicable
|
||||||
// error).
|
// error).
|
||||||
type FutureListReceivedByAccountResult chan *futureResult
|
type FutureListReceivedByAccountResult chan *response
|
||||||
|
|
||||||
// Receive waits for the response promised by the future and returns a list of
|
// Receive waits for the response promised by the future and returns a list of
|
||||||
// balances by account.
|
// balances by account.
|
||||||
func (r FutureListReceivedByAccountResult) Receive() ([]btcjson.ListReceivedByAccountResult, error) {
|
func (r FutureListReceivedByAccountResult) Receive() ([]btcjson.ListReceivedByAccountResult, error) {
|
||||||
reply, err := receiveFuture(r)
|
res, err := receiveFuture(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// No results.
|
// Unmarshal as an array of listreceivedbyaccount result objects.
|
||||||
if reply == nil {
|
var received []btcjson.ListReceivedByAccountResult
|
||||||
return nil, nil
|
err = json.Unmarshal(res, &received)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure the returned data is the expected type.
|
return received, nil
|
||||||
result, ok := reply.([]btcjson.ListReceivedByAccountResult)
|
|
||||||
if !ok {
|
|
||||||
return nil, fmt.Errorf("unexpected response type for "+
|
|
||||||
"listreceivedbyaccount: %T\n", reply)
|
|
||||||
}
|
|
||||||
|
|
||||||
return result, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ListReceivedByAccountAsync returns an instance of a type that can be used to
|
// ListReceivedByAccountAsync returns an instance of a type that can be used to
|
||||||
|
@ -1702,7 +1688,7 @@ func (c *Client) ListReceivedByAccountIncludeEmpty(minConfirms int, includeEmpty
|
||||||
|
|
||||||
// FutureWalletLockResult is a future promise to deliver the result of a
|
// FutureWalletLockResult is a future promise to deliver the result of a
|
||||||
// WalletLockAsync RPC invocation (or an applicable error).
|
// WalletLockAsync RPC invocation (or an applicable error).
|
||||||
type FutureWalletLockResult chan *futureResult
|
type FutureWalletLockResult chan *response
|
||||||
|
|
||||||
// Receive waits for the response promised by the future and returns the result
|
// Receive waits for the response promised by the future and returns the result
|
||||||
// of locking the wallet.
|
// of locking the wallet.
|
||||||
|
@ -1759,7 +1745,7 @@ func (c *Client) WalletPassphrase(passphrase string, timeoutSecs int64) error {
|
||||||
|
|
||||||
// FutureWalletPassphraseChangeResult is a future promise to deliver the result
|
// FutureWalletPassphraseChangeResult is a future promise to deliver the result
|
||||||
// of a WalletPassphraseChangeAsync RPC invocation (or an applicable error).
|
// of a WalletPassphraseChangeAsync RPC invocation (or an applicable error).
|
||||||
type FutureWalletPassphraseChangeResult chan *futureResult
|
type FutureWalletPassphraseChangeResult chan *response
|
||||||
|
|
||||||
// Receive waits for the response promised by the future and returns the result
|
// Receive waits for the response promised by the future and returns the result
|
||||||
// of changing the wallet passphrase.
|
// of changing the wallet passphrase.
|
||||||
|
@ -1799,21 +1785,21 @@ func (c *Client) WalletPassphraseChange(old, new string) error {
|
||||||
|
|
||||||
// FutureSignMessageResult is a future promise to deliver the result of a
|
// FutureSignMessageResult is a future promise to deliver the result of a
|
||||||
// SignMessageAsync RPC invocation (or an applicable error).
|
// SignMessageAsync RPC invocation (or an applicable error).
|
||||||
type FutureSignMessageResult chan *futureResult
|
type FutureSignMessageResult chan *response
|
||||||
|
|
||||||
// Receive waits for the response promised by the future and returns the message
|
// Receive waits for the response promised by the future and returns the message
|
||||||
// signed with the private key of the specified address.
|
// signed with the private key of the specified address.
|
||||||
func (r FutureSignMessageResult) Receive() (string, error) {
|
func (r FutureSignMessageResult) Receive() (string, error) {
|
||||||
reply, err := receiveFuture(r)
|
res, err := receiveFuture(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure the returned data is the expected type.
|
// Unmarshal result as a string.
|
||||||
b64, ok := reply.(string)
|
var b64 string
|
||||||
if !ok {
|
err = json.Unmarshal(res, &b64)
|
||||||
return "", fmt.Errorf("unexpected response type for "+
|
if err != nil {
|
||||||
"signmessage: %T\n", reply)
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
return b64, nil
|
return b64, nil
|
||||||
|
@ -1845,21 +1831,21 @@ func (c *Client) SignMessage(address btcutil.Address, message string) (string, e
|
||||||
|
|
||||||
// FutureVerifyMessageResult is a future promise to deliver the result of a
|
// FutureVerifyMessageResult is a future promise to deliver the result of a
|
||||||
// VerifyMessageAsync RPC invocation (or an applicable error).
|
// VerifyMessageAsync RPC invocation (or an applicable error).
|
||||||
type FutureVerifyMessageResult chan *futureResult
|
type FutureVerifyMessageResult chan *response
|
||||||
|
|
||||||
// Receive waits for the response promised by the future and returns whether or
|
// Receive waits for the response promised by the future and returns whether or
|
||||||
// not the message was successfully verified.
|
// not the message was successfully verified.
|
||||||
func (r FutureVerifyMessageResult) Receive() (bool, error) {
|
func (r FutureVerifyMessageResult) Receive() (bool, error) {
|
||||||
reply, err := receiveFuture(r)
|
res, err := receiveFuture(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure the returned data is the expected type.
|
// Unmarshal result as a boolean.
|
||||||
verified, ok := reply.(bool)
|
var verified bool
|
||||||
if !ok {
|
err = json.Unmarshal(res, &verified)
|
||||||
return false, fmt.Errorf("unexpected response type for "+
|
if err != nil {
|
||||||
"verifymessage: %T\n", reply)
|
return false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return verified, nil
|
return verified, nil
|
||||||
|
@ -1895,22 +1881,22 @@ func (c *Client) VerifyMessage(address btcutil.Address, signature, message strin
|
||||||
|
|
||||||
// FutureDumpPrivKeyResult is a future promise to deliver the result of a
|
// FutureDumpPrivKeyResult is a future promise to deliver the result of a
|
||||||
// DumpPrivKeyAsync RPC invocation (or an applicable error).
|
// DumpPrivKeyAsync RPC invocation (or an applicable error).
|
||||||
type FutureDumpPrivKeyResult chan *futureResult
|
type FutureDumpPrivKeyResult chan *response
|
||||||
|
|
||||||
// Receive waits for the response promised by the future and returns the private
|
// Receive waits for the response promised by the future and returns the private
|
||||||
// key corresponding to the passed address encoded in the wallet import format
|
// key corresponding to the passed address encoded in the wallet import format
|
||||||
// (WIF)
|
// (WIF)
|
||||||
func (r FutureDumpPrivKeyResult) Receive() (*btcutil.WIF, error) {
|
func (r FutureDumpPrivKeyResult) Receive() (*btcutil.WIF, error) {
|
||||||
reply, err := receiveFuture(r)
|
res, err := receiveFuture(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure the returned data is the expected type.
|
// Unmarshal result as a string.
|
||||||
privKeyWIF, ok := reply.(string)
|
var privKeyWIF string
|
||||||
if !ok {
|
err = json.Unmarshal(res, &privKeyWIF)
|
||||||
return nil, fmt.Errorf("unexpected response type for "+
|
if err != nil {
|
||||||
"dumpprivkey: %T\n", reply)
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return btcutil.DecodeWIF(privKeyWIF)
|
return btcutil.DecodeWIF(privKeyWIF)
|
||||||
|
@ -1943,7 +1929,7 @@ func (c *Client) DumpPrivKey(address btcutil.Address) (*btcutil.WIF, error) {
|
||||||
|
|
||||||
// FutureImportPrivKeyResult is a future promise to deliver the result of an
|
// FutureImportPrivKeyResult is a future promise to deliver the result of an
|
||||||
// ImportPrivKeyAsync RPC invocation (or an applicable error).
|
// ImportPrivKeyAsync RPC invocation (or an applicable error).
|
||||||
type FutureImportPrivKeyResult chan *futureResult
|
type FutureImportPrivKeyResult chan *response
|
||||||
|
|
||||||
// Receive waits for the response promised by the future and returns the result
|
// Receive waits for the response promised by the future and returns the result
|
||||||
// of importing the passed private key which must be the wallet import format
|
// of importing the passed private key which must be the wallet import format
|
||||||
|
|
Loading…
Reference in a new issue