From 9ca93b30ad11ec34348d2d788c58019571bf9524 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Thu, 1 Jan 2015 16:34:07 -0600 Subject: [PATCH] Update to make use of latest version of btcjson. This commit contains several changes needed to update the client to use the latest version of btcjson. In addition, it contains a couple of other minor changes along the way. While the underlying changes are quite large, the public API of this package is still the same, so caller should generally not have to update their code due to that. However, the underlying btcjson package API has changed significantly. Since this package hides the vast majority of that from callers, it should not afffect them very much. However, one area in particular to watch out for is that the old btcjson.Error is now btcjson.RPCError, so any callers doing any type assertions there will need to update. The following is a summary of the changes: - The underlying btcjson significantly changed how commands work, so the internals of this package have been reworked to be based off of requests instead of the now non-existant btcjson.Cmd interface - Update all call sites of btcjson.NewCmd since they can no longer error or take varargs - The ids for each request are part of the request now instead of the command to match the new btcjson model and are strict uint64s so type assertions are no longer needed (slightly improved efficiency) - Remove the old temporary workaround for the getbalance command with an account of "*" since btcwallet has since been fixed - Change all instances of JSONToAmount to btcutil.NewAmount since that function was removed in favor of btcutil.Amount - Change all btcws invocations to btcjson since they have been combined --- chain.go | 97 ++------- doc.go | 6 +- extensions.go | 37 +--- infrastructure.go | 231 ++++++++++---------- mining.go | 72 +------ net.go | 51 +---- notify.go | 100 ++++----- rawrequest.go | 67 +++--- rawtransactions.go | 73 ++----- wallet.go | 515 +++++++++------------------------------------ 10 files changed, 353 insertions(+), 896 deletions(-) diff --git a/chain.go b/chain.go index 95c0586f..2d8a725e 100644 --- a/chain.go +++ b/chain.go @@ -9,7 +9,7 @@ import ( "encoding/hex" "encoding/json" - "github.com/btcsuite/btcd/btcjson" + "github.com/btcsuite/btcd/btcjson/v2/btcjson" "github.com/btcsuite/btcd/wire" "github.com/btcsuite/btcutil" ) @@ -41,12 +41,7 @@ func (r FutureGetBestBlockHashResult) Receive() (*wire.ShaHash, error) { // // See GetBestBlockHash for the blocking version and more details. func (c *Client) GetBestBlockHashAsync() FutureGetBestBlockHashResult { - id := c.NextID() - cmd, err := btcjson.NewGetBestBlockHashCmd(id) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewGetBestBlockHashCmd() return c.sendCmd(cmd) } @@ -101,12 +96,7 @@ func (c *Client) GetBlockAsync(blockHash *wire.ShaHash) FutureGetBlockResult { hash = blockHash.String() } - id := c.NextID() - cmd, err := btcjson.NewGetBlockCmd(id, hash, false) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewGetBlockCmd(hash, btcjson.Bool(false), nil) return c.sendCmd(cmd) } @@ -124,14 +114,14 @@ type FutureGetBlockVerboseResult chan *response // Receive waits for the response promised by the future and returns the data // structure from the server with information about the requested block. -func (r FutureGetBlockVerboseResult) Receive() (*btcjson.BlockResult, error) { +func (r FutureGetBlockVerboseResult) Receive() (*btcjson.GetBlockVerboseResult, error) { res, err := receiveFuture(r) if err != nil { return nil, err } // Unmarshal the raw result into a BlockResult. - var blockResult btcjson.BlockResult + var blockResult btcjson.GetBlockVerboseResult err = json.Unmarshal(res, &blockResult) if err != nil { return nil, err @@ -150,12 +140,7 @@ func (c *Client) GetBlockVerboseAsync(blockHash *wire.ShaHash, verboseTx bool) F hash = blockHash.String() } - id := c.NextID() - cmd, err := btcjson.NewGetBlockCmd(id, hash, true, verboseTx) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewGetBlockCmd(hash, btcjson.Bool(true), &verboseTx) return c.sendCmd(cmd) } @@ -163,7 +148,7 @@ func (c *Client) GetBlockVerboseAsync(blockHash *wire.ShaHash, verboseTx bool) F // about a block given its hash. // // See GetBlock to retrieve a raw block instead. -func (c *Client) GetBlockVerbose(blockHash *wire.ShaHash, verboseTx bool) (*btcjson.BlockResult, error) { +func (c *Client) GetBlockVerbose(blockHash *wire.ShaHash, verboseTx bool) (*btcjson.GetBlockVerboseResult, error) { return c.GetBlockVerboseAsync(blockHash, verboseTx).Receive() } @@ -194,12 +179,7 @@ func (r FutureGetBlockCountResult) Receive() (int64, error) { // // See GetBlockCount for the blocking version and more details. func (c *Client) GetBlockCountAsync() FutureGetBlockCountResult { - id := c.NextID() - cmd, err := btcjson.NewGetBlockCountCmd(id) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewGetBlockCountCmd() return c.sendCmd(cmd) } @@ -235,12 +215,7 @@ func (r FutureGetDifficultyResult) Receive() (float64, error) { // // See GetDifficulty for the blocking version and more details. func (c *Client) GetDifficultyAsync() FutureGetDifficultyResult { - id := c.NextID() - cmd, err := btcjson.NewGetDifficultyCmd(id) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewGetDifficultyCmd() return c.sendCmd(cmd) } @@ -277,12 +252,7 @@ func (r FutureGetBlockHashResult) Receive() (*wire.ShaHash, error) { // // See GetBlockHash for the blocking version and more details. func (c *Client) GetBlockHashAsync(blockHeight int64) FutureGetBlockHashResult { - id := c.NextID() - cmd, err := btcjson.NewGetBlockHashCmd(id, blockHeight) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewGetBlockHashCmd(blockHeight) return c.sendCmd(cmd) } @@ -330,12 +300,7 @@ func (r FutureGetRawMempoolResult) Receive() ([]*wire.ShaHash, error) { // // See GetRawMempool for the blocking version and more details. func (c *Client) GetRawMempoolAsync() FutureGetRawMempoolResult { - id := c.NextID() - cmd, err := btcjson.NewGetRawMempoolCmd(id, false) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewGetRawMempoolCmd(btcjson.Bool(false)) return c.sendCmd(cmd) } @@ -354,7 +319,7 @@ type FutureGetRawMempoolVerboseResult chan *response // 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 for all transactions in the memory pool. -func (r FutureGetRawMempoolVerboseResult) Receive() (map[string]btcjson.GetRawMempoolResult, error) { +func (r FutureGetRawMempoolVerboseResult) Receive() (map[string]btcjson.GetRawMempoolVerboseResult, error) { res, err := receiveFuture(r) if err != nil { return nil, err @@ -362,7 +327,7 @@ func (r FutureGetRawMempoolVerboseResult) Receive() (map[string]btcjson.GetRawMe // Unmarshal the result as a map of strings (tx shas) to their detailed // results. - var mempoolItems map[string]btcjson.GetRawMempoolResult + var mempoolItems map[string]btcjson.GetRawMempoolVerboseResult err = json.Unmarshal(res, &mempoolItems) if err != nil { return nil, err @@ -376,12 +341,7 @@ func (r FutureGetRawMempoolVerboseResult) Receive() (map[string]btcjson.GetRawMe // // See GetRawMempoolVerbose for the blocking version and more details. func (c *Client) GetRawMempoolVerboseAsync() FutureGetRawMempoolVerboseResult { - id := c.NextID() - cmd, err := btcjson.NewGetRawMempoolCmd(id, true) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewGetRawMempoolCmd(btcjson.Bool(true)) return c.sendCmd(cmd) } @@ -390,7 +350,7 @@ func (c *Client) GetRawMempoolVerboseAsync() FutureGetRawMempoolVerboseResult { // the memory pool. // // See GetRawMempool to retrieve only the transaction hashes instead. -func (c *Client) GetRawMempoolVerbose() (map[string]btcjson.GetRawMempoolResult, error) { +func (c *Client) GetRawMempoolVerbose() (map[string]btcjson.GetRawMempoolVerboseResult, error) { return c.GetRawMempoolVerboseAsync().Receive() } @@ -423,12 +383,7 @@ func (r FutureVerifyChainResult) Receive() (bool, error) { // // See VerifyChain for the blocking version and more details. func (c *Client) VerifyChainAsync() FutureVerifyChainResult { - id := c.NextID() - cmd, err := btcjson.NewVerifyChainCmd(id) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewVerifyChainCmd(nil, nil) return c.sendCmd(cmd) } @@ -446,12 +401,7 @@ func (c *Client) VerifyChain() (bool, error) { // // See VerifyChainLevel for the blocking version and more details. func (c *Client) VerifyChainLevelAsync(checkLevel int32) FutureVerifyChainResult { - id := c.NextID() - cmd, err := btcjson.NewVerifyChainCmd(id, checkLevel) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewVerifyChainCmd(&checkLevel, nil) return c.sendCmd(cmd) } @@ -474,12 +424,7 @@ func (c *Client) VerifyChainLevel(checkLevel int32) (bool, error) { // // See VerifyChainBlocks for the blocking version and more details. func (c *Client) VerifyChainBlocksAsync(checkLevel, numBlocks int32) FutureVerifyChainResult { - id := c.NextID() - cmd, err := btcjson.NewVerifyChainCmd(id, checkLevel, numBlocks) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewVerifyChainCmd(&checkLevel, &numBlocks) return c.sendCmd(cmd) } @@ -537,11 +482,7 @@ func (c *Client) GetTxOutAsync(txHash *wire.ShaHash, index int, mempool bool) Fu hash = txHash.String() } - id := c.NextID() - cmd, err := btcjson.NewGetTxOutCmd(id, hash, index, mempool) - if err != nil { - return newFutureError(err) - } + cmd := btcjson.NewGetTxOutCmd(hash, index, &mempool) return c.sendCmd(cmd) } diff --git a/doc.go b/doc.go index 8f7a0589..ee5be686 100644 --- a/doc.go +++ b/doc.go @@ -141,14 +141,14 @@ the type can vary, but usually will be best handled by simply showing/logging it. The third category of errors, that is errors returned by the server, can be -detected by type asserting the error in a *btcjson.Error. For example, to +detected by type asserting the error in a *btcjson.RPCError. For example, to detect if a command is unimplemented by the remote RPC server: amount, err := client.GetBalance("") if err != nil { - if jerr, ok := err.(*btcjson.Error); ok { + if jerr, ok := err.(*btcjson.RPCError); ok { switch jerr.Code { - case btcjson.ErrUnimplemented.Code: + case btcjson.ErrRPCUnimplemented: // Handle not implemented error // Handle other specific errors you care about diff --git a/extensions.go b/extensions.go index a823a0df..d30f370d 100644 --- a/extensions.go +++ b/extensions.go @@ -9,8 +9,7 @@ import ( "encoding/json" "fmt" - "github.com/btcsuite/btcd/btcjson" - "github.com/btcsuite/btcd/btcjson/btcws" + "github.com/btcsuite/btcd/btcjson/v2/btcjson" "github.com/btcsuite/btcd/wire" "github.com/btcsuite/btcutil" ) @@ -45,12 +44,7 @@ func (r FutureDebugLevelResult) Receive() (string, error) { // // NOTE: This is a btcd extension. func (c *Client) DebugLevelAsync(levelSpec string) FutureDebugLevelResult { - id := c.NextID() - cmd, err := btcjson.NewDebugLevelCmd(id, levelSpec) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewDebugLevelCmd(levelSpec) return c.sendCmd(cmd) } @@ -86,8 +80,7 @@ func (r FutureCreateEncryptedWalletResult) Receive() error { // // NOTE: This is a btcwallet extension. func (c *Client) CreateEncryptedWalletAsync(passphrase string) FutureCreateEncryptedWalletResult { - id := c.NextID() - cmd := btcws.NewCreateEncryptedWalletCmd(id, passphrase) + cmd := btcjson.NewCreateEncryptedWalletCmd(passphrase) return c.sendCmd(cmd) } @@ -137,12 +130,7 @@ func (c *Client) ListAddressTransactionsAsync(addresses []btcutil.Address, accou for _, addr := range addresses { addrs = append(addrs, addr.EncodeAddress()) } - id := c.NextID() - cmd, err := btcws.NewListAddressTransactionsCmd(id, addrs, account) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewListAddressTransactionsCmd(addrs, &account) return c.sendCmd(cmd) } @@ -167,7 +155,7 @@ func (r FutureGetBestBlockResult) Receive() (*wire.ShaHash, int32, error) { } // Unmarsal result as a getbestblock result object. - var bestBlock btcws.GetBestBlockResult + var bestBlock btcjson.GetBestBlockResult err = json.Unmarshal(res, &bestBlock) if err != nil { return nil, 0, err @@ -190,9 +178,7 @@ func (r FutureGetBestBlockResult) Receive() (*wire.ShaHash, int32, error) { // // NOTE: This is a btcd extension. func (c *Client) GetBestBlockAsync() FutureGetBestBlockResult { - id := c.NextID() - cmd := btcws.NewGetBestBlockCmd(id) - + cmd := btcjson.NewGetBestBlockCmd() return c.sendCmd(cmd) } @@ -234,9 +220,7 @@ func (r FutureGetCurrentNetResult) Receive() (wire.BitcoinNet, error) { // // NOTE: This is a btcd extension. func (c *Client) GetCurrentNetAsync() FutureGetCurrentNetResult { - id := c.NextID() - cmd := btcws.NewGetCurrentNetCmd(id) - + cmd := btcjson.NewGetCurrentNetCmd() return c.sendCmd(cmd) } @@ -302,12 +286,7 @@ func (r FutureExportWatchingWalletResult) Receive() ([]byte, []byte, error) { // // NOTE: This is a btcwallet extension. func (c *Client) ExportWatchingWalletAsync(account string) FutureExportWatchingWalletResult { - id := c.NextID() - cmd, err := btcws.NewExportWatchingWalletCmd(id, account, true) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewExportWatchingWalletCmd(&account, btcjson.Bool(true)) return c.sendCmd(cmd) } diff --git a/infrastructure.go b/infrastructure.go index 383143c3..4e63f4a0 100644 --- a/infrastructure.go +++ b/infrastructure.go @@ -13,6 +13,7 @@ import ( "encoding/json" "errors" "fmt" + "io/ioutil" "net" "net/http" "net/url" @@ -20,8 +21,7 @@ import ( "sync/atomic" "time" - "github.com/btcsuite/btcd/btcjson" - "github.com/btcsuite/btcd/btcjson/btcws" + "github.com/btcsuite/btcd/btcjson/v2/btcjson" "github.com/btcsuite/go-socks/socks" "github.com/btcsuite/websocket" ) @@ -87,16 +87,18 @@ const ( // as the original JSON-RPC command and a channel to reply on when the server // responds with the result. type sendPostDetails struct { - command btcjson.Cmd - request *http.Request - responseChan chan *response + httpRequest *http.Request + jsonRequest *jsonRequest } // jsonRequest holds information about a json request that is used to properly // detect, interpret, and deliver a reply to it. type jsonRequest struct { - cmd btcjson.Cmd - responseChan chan *response + id uint64 + method string + cmd interface{} + marshalledJSON []byte + responseChan chan *response } // Client represents a Bitcoin RPC client which allows easy access to the @@ -163,15 +165,15 @@ func (c *Client) NextID() uint64 { return atomic.AddUint64(&c.id, 1) } -// addRequest associates the passed jsonRequest with the passed id. This allows -// the response from the remote server to be unmarshalled to the appropriate -// type and sent to the specified channel when it is received. +// addRequest associates the passed jsonRequest with its id. This allows the +// response from the remote server to be unmarshalled to the appropriate type +// and sent to the specified channel when it is received. // // If the client has already begun shutting down, ErrClientShutdown is returned // and the request is not added. // // This function is safe for concurrent access. -func (c *Client) addRequest(id uint64, request *jsonRequest) error { +func (c *Client) addRequest(jReq *jsonRequest) error { c.requestLock.Lock() defer c.requestLock.Unlock() @@ -187,9 +189,8 @@ func (c *Client) addRequest(id uint64, request *jsonRequest) error { default: } - // TODO(davec): Already there? - element := c.requestList.PushBack(request) - c.requestMap[id] = element + element := c.requestList.PushBack(jReq) + c.requestMap[jReq.id] = element return nil } @@ -224,7 +225,7 @@ func (c *Client) removeAllRequests() { // trackRegisteredNtfns examines the passed command to see if it is one of // the notification commands and updates the notification state that is used // to automatically re-establish registered notifications on reconnects. -func (c *Client) trackRegisteredNtfns(cmd btcjson.Cmd) { +func (c *Client) trackRegisteredNtfns(cmd interface{}) { // Nothing to do if the caller is not interested in notifications. if c.ntfnHandlers == nil { return @@ -234,23 +235,23 @@ func (c *Client) trackRegisteredNtfns(cmd btcjson.Cmd) { defer c.ntfnState.Unlock() switch bcmd := cmd.(type) { - case *btcws.NotifyBlocksCmd: + case *btcjson.NotifyBlocksCmd: c.ntfnState.notifyBlocks = true - case *btcws.NotifyNewTransactionsCmd: - if bcmd.Verbose { + case *btcjson.NotifyNewTransactionsCmd: + if bcmd.Verbose != nil && *bcmd.Verbose { c.ntfnState.notifyNewTxVerbose = true } else { c.ntfnState.notifyNewTx = true } - case *btcws.NotifySpentCmd: + case *btcjson.NotifySpentCmd: for _, op := range bcmd.OutPoints { c.ntfnState.notifySpent[op] = struct{}{} } - case *btcws.NotifyReceivedCmd: + case *btcjson.NotifyReceivedCmd: for _, addr := range bcmd.Addresses { c.ntfnState.notifyReceived[addr] = struct{}{} } @@ -278,8 +279,8 @@ type ( // 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"` + Result json.RawMessage `json:"result"` + Error *btcjson.RPCError `json:"error"` } ) @@ -291,7 +292,7 @@ type response struct { } // result checks whether the unmarshaled response contains a non-nil error, -// returning an unmarshaled btcjson.Error (or an unmarshaling error) if so. +// returning an unmarshaled btcjson.RPCError (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) { @@ -303,7 +304,8 @@ func (r rawResponse) result() (result []byte, err error) { // handleMessage is the main handler for incoming notifications and responses. func (c *Client) handleMessage(msg []byte) { - // Attempt to unmarshal the message as either a notifiation or response. + // Attempt to unmarshal the message as either a notification or + // response. var in inMessage err := json.Unmarshal(msg, &in) if err != nil { @@ -441,7 +443,7 @@ func (c *Client) sendMessage(marshalledJSON []byte) { // reregisterNtfns creates and sends commands needed to re-establish the current // notification state associated with the client. It should only be called on -// on reconnect by the resendCmds function. +// on reconnect by the resendRequests function. func (c *Client) reregisterNtfns() error { // Nothing to do if the caller is not interested in notifications. if c.ntfnHandlers == nil { @@ -480,7 +482,7 @@ func (c *Client) reregisterNtfns() error { // outpoints in one command if needed. nslen := len(stateCopy.notifySpent) if nslen > 0 { - outpoints := make([]btcws.OutPoint, 0, nslen) + outpoints := make([]btcjson.OutPoint, 0, nslen) for op := range stateCopy.notifySpent { outpoints = append(outpoints, op) } @@ -513,10 +515,10 @@ var ignoreResends = map[string]struct{}{ "rescan": struct{}{}, } -// resendCmds resends any commands that had not completed when the client +// resendRequests resends any requests that had not completed when the client // disconnected. It is intended to be called once the client has reconnected as // a separate goroutine. -func (c *Client) resendCmds() { +func (c *Client) resendRequests() { // Set the notification state back up. If anything goes wrong, // disconnect the client. if err := c.reregisterNtfns(); err != nil { @@ -525,37 +527,39 @@ func (c *Client) resendCmds() { return } - // Since it's possible to block on send and more commands might be + // Since it's possible to block on send and more requests might be // added by the caller while resending, make a copy of all of the - // commands that need to be resent now and work from the copy. This + // requests that need to be resent now and work from the copy. This // also allows the lock to be released quickly. c.requestLock.Lock() - resendCmds := make([]*jsonRequest, 0, c.requestList.Len()) + resendReqs := make([]*jsonRequest, 0, c.requestList.Len()) var nextElem *list.Element for e := c.requestList.Front(); e != nil; e = nextElem { nextElem = e.Next() - req := e.Value.(*jsonRequest) - if _, ok := ignoreResends[req.cmd.Method()]; ok { + jReq := e.Value.(*jsonRequest) + if _, ok := ignoreResends[jReq.method]; ok { // If a request is not sent on reconnect, remove it // from the request structures, since no reply is // expected. - delete(c.requestMap, req.cmd.Id().(uint64)) + delete(c.requestMap, jReq.id) c.requestList.Remove(e) } else { - resendCmds = append(resendCmds, req) + resendReqs = append(resendReqs, jReq) } } c.requestLock.Unlock() - for _, req := range resendCmds { + for _, jReq := range resendReqs { // Stop resending commands if the client disconnected again // since the next reconnect will handle them. if c.Disconnected() { return } - c.marshalAndSend(req.cmd, req.responseChan) + log.Tracef("Sending command [%s] with id %d", jReq.method, + jReq.id) + c.sendMessage(jReq.marshalledJSON) } } @@ -624,9 +628,9 @@ out: // new connection. c.start() - // Reissue pending commands in another goroutine since + // Reissue pending requests in another goroutine since // the send can block. - go c.resendCmds() + go c.resendRequests() // Break out of the reconnect loop back to wait for // disconnect again. @@ -638,40 +642,41 @@ out: } // handleSendPostMessage handles performing the passed HTTP request, reading the -// result, unmarshalling it, and delivering the unmarhsalled result to the +// result, unmarshalling it, and delivering the unmarshalled result to the // provided response channel. func (c *Client) handleSendPostMessage(details *sendPostDetails) { - // Post the request. - cmd := details.command - log.Tracef("Sending command [%s] with id %d", cmd.Method(), cmd.Id()) - httpResponse, err := c.httpClient.Do(details.request) + jReq := details.jsonRequest + log.Tracef("Sending command [%s] with id %d", jReq.method, jReq.id) + httpResponse, err := c.httpClient.Do(details.httpRequest) if err != nil { - details.responseChan <- &response{err: err} + jReq.responseChan <- &response{err: err} return } // Read the raw bytes and close the response. - respBytes, err := btcjson.GetRaw(httpResponse.Body) + respBytes, err := ioutil.ReadAll(httpResponse.Body) + httpResponse.Body.Close() if err != nil { - details.responseChan <- &response{err: err} + err = fmt.Errorf("error reading json reply: %v", err) + jReq.responseChan <- &response{err: err} return } // Handle unsuccessful HTTP responses if httpResponse.StatusCode < 200 || httpResponse.StatusCode >= 300 { - details.responseChan <- &response{err: errors.New(string(respBytes))} + jReq.responseChan <- &response{err: errors.New(string(respBytes))} return } var resp rawResponse err = json.Unmarshal(respBytes, &resp) if err != nil { - details.responseChan <- &response{err: err} + jReq.responseChan <- &response{err: err} return } res, err := resp.result() - details.responseChan <- &response{result: res, err: err} + jReq.responseChan <- &response{result: res, err: err} } // sendPostHandler handles all outgoing messages when the client is running @@ -698,7 +703,7 @@ cleanup: for { select { case details := <-c.sendPostChan: - details.responseChan <- &response{ + details.jsonRequest.responseChan <- &response{ result: nil, err: ErrClientShutdown, } @@ -715,18 +720,17 @@ cleanup: // 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, // so it will not block until the send channel is full. -func (c *Client) sendPostRequest(req *http.Request, command btcjson.Cmd, responseChan chan *response) { +func (c *Client) sendPostRequest(httpReq *http.Request, jReq *jsonRequest) { // Don't send the message if shutting down. select { case <-c.shutdown: - responseChan <- &response{result: nil, err: ErrClientShutdown} + jReq.responseChan <- &response{result: nil, err: ErrClientShutdown} default: } c.sendPostChan <- &sendPostDetails{ - command: command, - request: req, - responseChan: responseChan, + jsonRequest: jReq, + httpRequest: httpReq, } } @@ -749,66 +753,45 @@ func receiveFuture(f chan *response) ([]byte, error) { return r.result, r.err } -// marshalAndSendPost marshals the passed command to JSON-RPC and sends it to -// the server by issuing an HTTP POST request and returns a response channel -// on which the reply will be delivered. Typically a new connection is opened -// and closed for each command when using this method, however, the underlying -// HTTP client might coalesce multiple commands depending on several factors -// including the remote server configuration. -func (c *Client) marshalAndSendPost(cmd btcjson.Cmd, responseChan chan *response) { - marshalledJSON, err := json.Marshal(cmd) - if err != nil { - responseChan <- &response{result: nil, err: err} - return - } - +// sendPost sends the passed request to the server by issuing an HTTP POST +// request using the provided response channel for the reply. Typically a new +// connection is opened and closed for each command when using this method, +// however, the underlying HTTP client might coalesce multiple commands +// depending on several factors including the remote server configuration. +func (c *Client) sendPost(jReq *jsonRequest) { // Generate a request to the configured RPC server. protocol := "http" if !c.config.DisableTLS { protocol = "https" } url := protocol + "://" + c.config.Host - req, err := http.NewRequest("POST", url, bytes.NewReader(marshalledJSON)) + bodyReader := bytes.NewReader(jReq.marshalledJSON) + httpReq, err := http.NewRequest("POST", url, bodyReader) if err != nil { - responseChan <- &response{result: nil, err: err} + jReq.responseChan <- &response{result: nil, err: err} return } - req.Close = true - req.Header.Set("Content-Type", "application/json") + httpReq.Close = true + httpReq.Header.Set("Content-Type", "application/json") // Configure basic access authorization. - req.SetBasicAuth(c.config.User, c.config.Pass) + httpReq.SetBasicAuth(c.config.User, c.config.Pass) - log.Tracef("Sending command [%s] with id %d", cmd.Method(), cmd.Id()) - c.sendPostRequest(req, cmd, responseChan) + log.Tracef("Sending command [%s] with id %d", jReq.method, jReq.id) + c.sendPostRequest(httpReq, jReq) } -// 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. -func (c *Client) marshalAndSend(cmd btcjson.Cmd, responseChan chan *response) { - marshalledJSON, err := cmd.MarshalJSON() - if err != nil { - responseChan <- &response{result: nil, err: err} - return - } - - log.Tracef("Sending command [%s] with id %d", cmd.Method(), cmd.Id()) - c.sendMessage(marshalledJSON) -} - -// sendCmd sends the passed command to the associated server and returns a -// 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 -// configuration of the client. -func (c *Client) sendCmd(cmd btcjson.Cmd) chan *response { +// sendRequest sends the passed json request to the associated server using the +// provided response channel for the reply. It handles both websocket and HTTP +// POST mode depending on the configuration of the client. +func (c *Client) sendRequest(jReq *jsonRequest) { // Choose which marshal and send function to use depending on whether // the client running in HTTP POST mode or not. When running in HTTP // POST mode, the command is issued via an HTTP client. Otherwise, // the command is issued via the asynchronous websocket channels. - responseChan := make(chan *response, 1) if c.config.HttpPostMode { - c.marshalAndSendPost(cmd, responseChan) - return responseChan + c.sendPost(jReq) + return } // Check whether the websocket connection has never been established, @@ -816,26 +799,58 @@ func (c *Client) sendCmd(cmd btcjson.Cmd) chan *response { select { case <-c.connEstablished: default: - responseChan <- &response{err: ErrClientNotConnected} - return responseChan + jReq.responseChan <- &response{err: ErrClientNotConnected} + return } - err := c.addRequest(cmd.Id().(uint64), &jsonRequest{ - cmd: cmd, - responseChan: responseChan, - }) - if err != nil { - responseChan <- &response{err: err} - return responseChan + // Add the request to the internal tracking map so the response from the + // remote server can be properly detected and routed to the response + // channel. Then send the marshalled request via the websocket + // connection. + if err := c.addRequest(jReq); err != nil { + jReq.responseChan <- &response{err: err} + return } - c.marshalAndSend(cmd, responseChan) + log.Tracef("Sending command [%s] with id %d", jReq.method, jReq.id) + c.sendMessage(jReq.marshalledJSON) +} + +// sendCmd sends the passed command to the associated server and returns a +// response channel on which the reply will be delivered at some point in the +// future. It handles both websocket and HTTP POST mode depending on the +// configuration of the client. +func (c *Client) sendCmd(cmd interface{}) chan *response { + // Get the method associated with the command. + method, err := btcjson.CmdMethod(cmd) + if err != nil { + return newFutureError(err) + } + + // Marshal the command. + id := c.NextID() + marshalledJSON, err := btcjson.MarshalCmd(id, cmd) + if err != nil { + return newFutureError(err) + } + + // Generate the request and send it along with a channel to respond on. + responseChan := make(chan *response, 1) + jReq := &jsonRequest{ + id: id, + method: method, + cmd: cmd, + marshalledJSON: marshalledJSON, + responseChan: responseChan, + } + c.sendRequest(jReq) + return responseChan } // sendCmdAndWait sends the passed command to the associated server, waits // for the reply, and returns the result from it. It will return the error // field in the reply if there is one. -func (c *Client) sendCmdAndWait(cmd btcjson.Cmd) (interface{}, error) { +func (c *Client) sendCmdAndWait(cmd interface{}) (interface{}, error) { // Marshal the command to JSON-RPC, send it to the connected server, and // wait for a response on the returned channel. return receiveFuture(c.sendCmd(cmd)) diff --git a/mining.go b/mining.go index ecba727b..e64504d8 100644 --- a/mining.go +++ b/mining.go @@ -9,7 +9,7 @@ import ( "encoding/json" "errors" - "github.com/btcsuite/btcd/btcjson" + "github.com/btcsuite/btcd/btcjson/v2/btcjson" "github.com/btcsuite/btcutil" ) @@ -41,12 +41,7 @@ func (r FutureGetGenerateResult) Receive() (bool, error) { // // See GetGenerate for the blocking version and more details. func (c *Client) GetGenerateAsync() FutureGetGenerateResult { - id := c.NextID() - cmd, err := btcjson.NewGetGenerateCmd(id) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewGetGenerateCmd() return c.sendCmd(cmd) } @@ -76,12 +71,7 @@ func (r FutureSetGenerateResult) Receive() error { // // See SetGenerate for the blocking version and more details. func (c *Client) SetGenerateAsync(enable bool, numCPUs int) FutureSetGenerateResult { - id := c.NextID() - cmd, err := btcjson.NewSetGenerateCmd(id, enable, numCPUs) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewSetGenerateCmd(enable, &numCPUs) return c.sendCmd(cmd) } @@ -119,12 +109,7 @@ func (r FutureGetHashesPerSecResult) Receive() (int64, error) { // // See GetHashesPerSec for the blocking version and more details. func (c *Client) GetHashesPerSecAsync() FutureGetHashesPerSecResult { - id := c.NextID() - cmd, err := btcjson.NewGetHashesPerSecCmd(id) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewGetHashesPerSecCmd() return c.sendCmd(cmd) } @@ -163,12 +148,7 @@ func (r FutureGetMiningInfoResult) Receive() (*btcjson.GetMiningInfoResult, erro // // See GetMiningInfo for the blocking version and more details. func (c *Client) GetMiningInfoAsync() FutureGetMiningInfoResult { - id := c.NextID() - cmd, err := btcjson.NewGetMiningInfoCmd(id) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewGetMiningInfoCmd() return c.sendCmd(cmd) } @@ -206,12 +186,7 @@ func (r FutureGetNetworkHashPS) Receive() (int64, error) { // // See GetNetworkHashPS for the blocking version and more details. func (c *Client) GetNetworkHashPSAsync() FutureGetNetworkHashPS { - id := c.NextID() - cmd, err := btcjson.NewGetNetworkHashPSCmd(id) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewGetNetworkHashPSCmd(nil, nil) return c.sendCmd(cmd) } @@ -230,12 +205,7 @@ func (c *Client) GetNetworkHashPS() (int64, error) { // // See GetNetworkHashPS2 for the blocking version and more details. func (c *Client) GetNetworkHashPS2Async(blocks int) FutureGetNetworkHashPS { - id := c.NextID() - cmd, err := btcjson.NewGetNetworkHashPSCmd(id, blocks) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewGetNetworkHashPSCmd(&blocks, nil) return c.sendCmd(cmd) } @@ -256,12 +226,7 @@ func (c *Client) GetNetworkHashPS2(blocks int) (int64, error) { // // See GetNetworkHashPS3 for the blocking version and more details. func (c *Client) GetNetworkHashPS3Async(blocks, height int) FutureGetNetworkHashPS { - id := c.NextID() - cmd, err := btcjson.NewGetNetworkHashPSCmd(id, blocks, height) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewGetNetworkHashPSCmd(&blocks, &height) return c.sendCmd(cmd) } @@ -303,12 +268,7 @@ func (r FutureGetWork) Receive() (*btcjson.GetWorkResult, error) { // // See GetWork for the blocking version and more details. func (c *Client) GetWorkAsync() FutureGetWork { - id := c.NextID() - cmd, err := btcjson.NewGetWorkCmd(id) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewGetWorkCmd(nil) return c.sendCmd(cmd) } @@ -347,12 +307,7 @@ func (r FutureGetWorkSubmit) Receive() (bool, error) { // // See GetWorkSubmit for the blocking version and more details. func (c *Client) GetWorkSubmitAsync(data string) FutureGetWorkSubmit { - id := c.NextID() - cmd, err := btcjson.NewGetWorkCmd(id, data) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewGetWorkCmd(&data) return c.sendCmd(cmd) } @@ -406,12 +361,7 @@ func (c *Client) SubmitBlockAsync(block *btcutil.Block, options *btcjson.SubmitB blockHex = hex.EncodeToString(blockBytes) } - id := c.NextID() - cmd, err := btcjson.NewSubmitBlockCmd(id, blockHex, options) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewSubmitBlockCmd(blockHex, options) return c.sendCmd(cmd) } diff --git a/net.go b/net.go index ecf69613..b843c98f 100644 --- a/net.go +++ b/net.go @@ -7,7 +7,7 @@ package btcrpcclient import ( "encoding/json" - "github.com/btcsuite/btcd/btcjson" + "github.com/btcsuite/btcd/btcjson/v2/btcjson" ) // AddNodeCommand enumerates the available commands that the AddNode function @@ -54,12 +54,7 @@ func (r FutureAddNodeResult) Receive() error { // // See AddNode for the blocking version and more details. func (c *Client) AddNodeAsync(host string, command AddNodeCommand) FutureAddNodeResult { - id := c.NextID() - cmd, err := btcjson.NewAddNodeCmd(id, host, string(command)) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewAddNodeCmd(host, btcjson.AddNodeSubCmd(command)) return c.sendCmd(cmd) } @@ -100,12 +95,7 @@ func (r FutureGetAddedNodeInfoResult) Receive() ([]btcjson.GetAddedNodeInfoResul // // See GetAddedNodeInfo for the blocking version and more details. func (c *Client) GetAddedNodeInfoAsync(peer string) FutureGetAddedNodeInfoResult { - id := c.NextID() - cmd, err := btcjson.NewGetAddedNodeInfoCmd(id, true, peer) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewGetAddedNodeInfoCmd(true, &peer) return c.sendCmd(cmd) } @@ -145,12 +135,7 @@ func (r FutureGetAddedNodeInfoNoDNSResult) Receive() ([]string, error) { // // See GetAddedNodeInfoNoDNS for the blocking version and more details. func (c *Client) GetAddedNodeInfoNoDNSAsync(peer string) FutureGetAddedNodeInfoNoDNSResult { - id := c.NextID() - cmd, err := btcjson.NewGetAddedNodeInfoCmd(id, false, peer) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewGetAddedNodeInfoCmd(false, &peer) return c.sendCmd(cmd) } @@ -191,12 +176,7 @@ func (r FutureGetConnectionCountResult) Receive() (int64, error) { // // See GetConnectionCount for the blocking version and more details. func (c *Client) GetConnectionCountAsync() FutureGetConnectionCountResult { - id := c.NextID() - cmd, err := btcjson.NewGetConnectionCountCmd(id) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewGetConnectionCountCmd() return c.sendCmd(cmd) } @@ -226,12 +206,7 @@ func (r FuturePingResult) Receive() error { // // See Ping for the blocking version and more details. func (c *Client) PingAsync() FuturePingResult { - id := c.NextID() - cmd, err := btcjson.NewPingCmd(id) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewPingCmd() return c.sendCmd(cmd) } @@ -271,12 +246,7 @@ func (r FutureGetPeerInfoResult) Receive() ([]btcjson.GetPeerInfoResult, error) // // See GetPeerInfo for the blocking version and more details. func (c *Client) GetPeerInfoAsync() FutureGetPeerInfoResult { - id := c.NextID() - cmd, err := btcjson.NewGetPeerInfoCmd(id) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewGetPeerInfoCmd() return c.sendCmd(cmd) } @@ -313,12 +283,7 @@ func (r FutureGetNetTotalsResult) Receive() (*btcjson.GetNetTotalsResult, error) // // See GetNetTotals for the blocking version and more details. func (c *Client) GetNetTotalsAsync() FutureGetNetTotalsResult { - id := c.NextID() - cmd, err := btcjson.NewGetNetTotalsCmd(id) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewGetNetTotalsCmd() return c.sendCmd(cmd) } diff --git a/notify.go b/notify.go index 44c556e6..aacaa3f4 100644 --- a/notify.go +++ b/notify.go @@ -13,8 +13,7 @@ import ( "sync" "time" - "github.com/btcsuite/btcd/btcjson" - "github.com/btcsuite/btcd/btcjson/btcws" + "github.com/btcsuite/btcd/btcjson/v2/btcjson" "github.com/btcsuite/btcd/wire" "github.com/btcsuite/btcutil" ) @@ -37,7 +36,7 @@ type notificationState struct { notifyNewTx bool notifyNewTxVerbose bool notifyReceived map[string]struct{} - notifySpent map[btcws.OutPoint]struct{} + notifySpent map[btcjson.OutPoint]struct{} } // Copy returns a deep copy of the receiver. @@ -52,7 +51,7 @@ func (s *notificationState) Copy() *notificationState { for addr := range s.notifyReceived { stateCopy.notifyReceived[addr] = struct{}{} } - stateCopy.notifySpent = make(map[btcws.OutPoint]struct{}) + stateCopy.notifySpent = make(map[btcjson.OutPoint]struct{}) for op := range s.notifySpent { stateCopy.notifySpent[op] = struct{}{} } @@ -64,7 +63,7 @@ func (s *notificationState) Copy() *notificationState { func newNotificationState() *notificationState { return ¬ificationState{ notifyReceived: make(map[string]struct{}), - notifySpent: make(map[btcws.OutPoint]struct{}), + notifySpent: make(map[btcjson.OutPoint]struct{}), } } @@ -110,7 +109,7 @@ type NotificationHandlers struct { // connected to the longest (best) chain. It will only be invoked if a // preceding call to NotifyReceived, Rescan, or RescanEndHeight has been // made to register for the notification and the function is non-nil. - OnRecvTx func(transaction *btcutil.Tx, details *btcws.BlockDetails) + OnRecvTx func(transaction *btcutil.Tx, details *btcjson.BlockDetails) // OnRedeemingTx is invoked when a transaction that spends a registered // outpoint is received into the memory pool and also connected to the @@ -122,7 +121,7 @@ type NotificationHandlers struct { // for the outpoints that are now "owned" as a result of receiving // funds to the registered addresses. This means it is possible for // this to invoked indirectly as the result of a NotifyReceived call. - OnRedeemingTx func(transaction *btcutil.Tx, details *btcws.BlockDetails) + OnRedeemingTx func(transaction *btcutil.Tx, details *btcjson.BlockDetails) // OnRescanFinished is invoked after a rescan finishes due to a previous // call to Rescan or RescanEndHeight. Finished rescans should be @@ -188,7 +187,7 @@ func (c *Client) handleNotification(ntfn *rawNotification) { switch ntfn.Method { // OnBlockConnected - case btcws.BlockConnectedNtfnMethod: + case btcjson.BlockConnectedNtfnMethod: // Ignore the notification if the client is not interested in // it. if c.ntfnHandlers.OnBlockConnected == nil { @@ -205,7 +204,7 @@ func (c *Client) handleNotification(ntfn *rawNotification) { c.ntfnHandlers.OnBlockConnected(blockSha, blockHeight) // OnBlockDisconnected - case btcws.BlockDisconnectedNtfnMethod: + case btcjson.BlockDisconnectedNtfnMethod: // Ignore the notification if the client is not interested in // it. if c.ntfnHandlers.OnBlockDisconnected == nil { @@ -222,7 +221,7 @@ func (c *Client) handleNotification(ntfn *rawNotification) { c.ntfnHandlers.OnBlockDisconnected(blockSha, blockHeight) // OnRecvTx - case btcws.RecvTxNtfnMethod: + case btcjson.RecvTxNtfnMethod: // Ignore the notification if the client is not interested in // it. if c.ntfnHandlers.OnRecvTx == nil { @@ -239,7 +238,7 @@ func (c *Client) handleNotification(ntfn *rawNotification) { c.ntfnHandlers.OnRecvTx(tx, block) // OnRedeemingTx - case btcws.RedeemingTxNtfnMethod: + case btcjson.RedeemingTxNtfnMethod: // Ignore the notification if the client is not interested in // it. if c.ntfnHandlers.OnRedeemingTx == nil { @@ -256,7 +255,7 @@ func (c *Client) handleNotification(ntfn *rawNotification) { c.ntfnHandlers.OnRedeemingTx(tx, block) // OnRescanFinished - case btcws.RescanFinishedNtfnMethod: + case btcjson.RescanFinishedNtfnMethod: // Ignore the notification if the client is not interested in // it. if c.ntfnHandlers.OnRescanFinished == nil { @@ -273,7 +272,7 @@ func (c *Client) handleNotification(ntfn *rawNotification) { c.ntfnHandlers.OnRescanFinished(hash, height, blkTime) // OnRescanProgress - case btcws.RescanProgressNtfnMethod: + case btcjson.RescanProgressNtfnMethod: // Ignore the notification if the client is not interested in // it. if c.ntfnHandlers.OnRescanProgress == nil { @@ -290,7 +289,7 @@ func (c *Client) handleNotification(ntfn *rawNotification) { c.ntfnHandlers.OnRescanProgress(hash, height, blkTime) // OnTxAccepted - case btcws.TxAcceptedNtfnMethod: + case btcjson.TxAcceptedNtfnMethod: // Ignore the notification if the client is not interested in // it. if c.ntfnHandlers.OnTxAccepted == nil { @@ -307,7 +306,7 @@ func (c *Client) handleNotification(ntfn *rawNotification) { c.ntfnHandlers.OnTxAccepted(hash, amt) // OnTxAcceptedVerbose - case btcws.TxAcceptedVerboseNtfnMethod: + case btcjson.TxAcceptedVerboseNtfnMethod: // Ignore the notification if the client is not interested in // it. if c.ntfnHandlers.OnTxAcceptedVerbose == nil { @@ -324,7 +323,7 @@ func (c *Client) handleNotification(ntfn *rawNotification) { c.ntfnHandlers.OnTxAcceptedVerbose(rawTx) // OnBtcdConnected - case btcws.BtcdConnectedNtfnMethod: + case btcjson.BtcdConnectedNtfnMethod: // Ignore the notification if the client is not interested in // it. if c.ntfnHandlers.OnBtcdConnected == nil { @@ -341,7 +340,7 @@ func (c *Client) handleNotification(ntfn *rawNotification) { c.ntfnHandlers.OnBtcdConnected(connected) // OnAccountBalance - case btcws.AccountBalanceNtfnMethod: + case btcjson.AccountBalanceNtfnMethod: // Ignore the notification if the client is not interested in // it. if c.ntfnHandlers.OnAccountBalance == nil { @@ -358,7 +357,7 @@ func (c *Client) handleNotification(ntfn *rawNotification) { c.ntfnHandlers.OnAccountBalance(account, bal, conf) // OnWalletLockState - case btcws.WalletLockStateNtfnMethod: + case btcjson.WalletLockStateNtfnMethod: // Ignore the notification if the client is not interested in // it. if c.ntfnHandlers.OnWalletLockState == nil { @@ -433,7 +432,7 @@ func parseChainNtfnParams(params []json.RawMessage) (*wire.ShaHash, // the block it's mined in from the parameters of recvtx and redeemingtx // notifications. func parseChainTxNtfnParams(params []json.RawMessage) (*btcutil.Tx, - *btcws.BlockDetails, error) { + *btcjson.BlockDetails, error) { if len(params) == 0 || len(params) > 2 { return nil, nil, wrongNumParams(len(params)) @@ -448,7 +447,7 @@ func parseChainTxNtfnParams(params []json.RawMessage) (*btcutil.Tx, // If present, unmarshal second optional parameter as the block details // JSON object. - var block *btcws.BlockDetails + var block *btcjson.BlockDetails if len(params) > 1 { err = json.Unmarshal(params[1], &block) if err != nil { @@ -558,7 +557,7 @@ func parseTxAcceptedVerboseNtfnParams(params []json.RawMessage) (*btcjson.TxRawR return nil, err } - // TODO: change txacceptedverbose notifiation callbacks to use nicer + // TODO: change txacceptedverbose notification callbacks to use nicer // types for all details about the transaction (i.e. decoding hashes // from their string encoding). return &rawTx, nil @@ -611,7 +610,7 @@ func parseAccountBalanceNtfnParams(params []json.RawMessage) (account string, } // Bounds check amount. - bal, err := btcjson.JSONToAmount(fbal) + bal, err := btcutil.NewAmount(fbal) if err != nil { return "", 0, false, err } @@ -677,9 +676,7 @@ func (c *Client) NotifyBlocksAsync() FutureNotifyBlocksResult { return newNilFutureResult() } - id := c.NextID() - cmd := btcws.NewNotifyBlocksCmd(id) - + cmd := btcjson.NewNotifyBlocksCmd() return c.sendCmd(cmd) } @@ -715,7 +712,7 @@ func (r FutureNotifySpentResult) Receive() error { // notifySpentInternal is the same as notifySpentAsync except it accepts // the converted outpoints as a parameter so the client can more efficiently // recreate the previous notification state on reconnect. -func (c *Client) notifySpentInternal(outpoints []btcws.OutPoint) FutureNotifySpentResult { +func (c *Client) notifySpentInternal(outpoints []btcjson.OutPoint) FutureNotifySpentResult { // Not supported in HTTP POST mode. if c.config.HttpPostMode { return newFutureError(ErrNotificationsNotSupported) @@ -727,9 +724,7 @@ func (c *Client) notifySpentInternal(outpoints []btcws.OutPoint) FutureNotifySpe return newNilFutureResult() } - id := c.NextID() - cmd := btcws.NewNotifySpentCmd(id, outpoints) - + cmd := btcjson.NewNotifySpentCmd(outpoints) return c.sendCmd(cmd) } @@ -752,13 +747,11 @@ func (c *Client) NotifySpentAsync(outpoints []*wire.OutPoint) FutureNotifySpentR return newNilFutureResult() } - id := c.NextID() - ops := make([]btcws.OutPoint, 0, len(outpoints)) + ops := make([]btcjson.OutPoint, 0, len(outpoints)) for _, outpoint := range outpoints { - ops = append(ops, *btcws.NewOutPointFromWire(outpoint)) + ops = append(ops, *btcjson.NewOutPointFromWire(outpoint)) } - cmd := btcws.NewNotifySpentCmd(id, ops) - + cmd := btcjson.NewNotifySpentCmd(ops) return c.sendCmd(cmd) } @@ -810,12 +803,7 @@ func (c *Client) NotifyNewTransactionsAsync(verbose bool) FutureNotifyNewTransac return newNilFutureResult() } - id := c.NextID() - cmd, err := btcws.NewNotifyNewTransactionsCmd(id, verbose) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewNotifyNewTransactionsCmd(&verbose) return c.sendCmd(cmd) } @@ -865,9 +853,7 @@ func (c *Client) notifyReceivedInternal(addresses []string) FutureNotifyReceived } // Convert addresses to strings. - id := c.NextID() - cmd := btcws.NewNotifyReceivedCmd(id, addresses) - + cmd := btcjson.NewNotifyReceivedCmd(addresses) return c.sendCmd(cmd) } @@ -895,9 +881,7 @@ func (c *Client) NotifyReceivedAsync(addresses []btcutil.Address) FutureNotifyRe for _, addr := range addresses { addrs = append(addrs, addr.String()) } - id := c.NextID() - cmd := btcws.NewNotifyReceivedCmd(id, addrs) - + cmd := btcjson.NewNotifyReceivedCmd(addrs) return c.sendCmd(cmd) } @@ -978,17 +962,12 @@ func (c *Client) RescanAsync(startBlock *wire.ShaHash, } // Convert outpoints. - ops := make([]btcws.OutPoint, 0, len(outpoints)) + ops := make([]btcjson.OutPoint, 0, len(outpoints)) for _, op := range outpoints { - ops = append(ops, *btcws.NewOutPointFromWire(op)) - } - - id := c.NextID() - cmd, err := btcws.NewRescanCmd(id, startBlockShaStr, addrs, ops) - if err != nil { - return newFutureError(err) + ops = append(ops, *btcjson.NewOutPointFromWire(op)) } + cmd := btcjson.NewRescanCmd(startBlockShaStr, addrs, ops, nil) return c.sendCmd(cmd) } @@ -1063,18 +1042,13 @@ func (c *Client) RescanEndBlockAsync(startBlock *wire.ShaHash, } // Convert outpoints. - ops := make([]btcws.OutPoint, 0, len(outpoints)) + ops := make([]btcjson.OutPoint, 0, len(outpoints)) for _, op := range outpoints { - ops = append(ops, *btcws.NewOutPointFromWire(op)) - } - - id := c.NextID() - cmd, err := btcws.NewRescanCmd(id, startBlockShaStr, addrs, ops, - endBlockShaStr) - if err != nil { - return newFutureError(err) + ops = append(ops, *btcjson.NewOutPointFromWire(op)) } + cmd := btcjson.NewRescanCmd(startBlockShaStr, addrs, ops, + &endBlockShaStr) return c.sendCmd(cmd) } diff --git a/rawrequest.go b/rawrequest.go index 44a557e4..95aeeeaa 100644 --- a/rawrequest.go +++ b/rawrequest.go @@ -8,40 +8,9 @@ import ( "encoding/json" "errors" - "github.com/btcsuite/btcd/btcjson" + "github.com/btcsuite/btcd/btcjson/v2/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 @@ -69,16 +38,34 @@ func (c *Client) RawRequestAsync(method string, params []json.RawMessage) Future params = []json.RawMessage{} } - cmd := &rawRequest{ - RawCmd: btcjson.RawCmd{ - Jsonrpc: "1.0", - Id: c.NextID(), - Method: method, - Params: params, - }, + // Create a raw JSON-RPC request using the provided method and params + // and marshal it. This is done rather than using the sendCmd function + // since that relies on marshalling registered btcjson commands rather + // than custom commands. + id := c.NextID() + rawRequest := &btcjson.Request{ + Jsonrpc: "1.0", + ID: id, + Method: method, + Params: params, + } + marshalledJSON, err := json.Marshal(rawRequest) + if err != nil { + return newFutureError(err) } - return c.sendCmd(cmd) + // Generate the request and send it along with a channel to respond on. + responseChan := make(chan *response, 1) + jReq := &jsonRequest{ + id: id, + method: method, + cmd: nil, + marshalledJSON: marshalledJSON, + responseChan: responseChan, + } + c.sendRequest(jReq) + + return responseChan } // RawRequest allows the caller to send a raw or custom request to the server. diff --git a/rawtransactions.go b/rawtransactions.go index e75f0bb4..77013e7d 100644 --- a/rawtransactions.go +++ b/rawtransactions.go @@ -9,7 +9,7 @@ import ( "encoding/hex" "encoding/json" - "github.com/btcsuite/btcd/btcjson" + "github.com/btcsuite/btcd/btcjson/v2/btcjson" "github.com/btcsuite/btcd/wire" "github.com/btcsuite/btcutil" ) @@ -101,12 +101,7 @@ func (c *Client) GetRawTransactionAsync(txHash *wire.ShaHash) FutureGetRawTransa hash = txHash.String() } - id := c.NextID() - cmd, err := btcjson.NewGetRawTransactionCmd(id, hash, 0) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewGetRawTransactionCmd(hash, btcjson.Int(0)) return c.sendCmd(cmd) } @@ -152,12 +147,7 @@ func (c *Client) GetRawTransactionVerboseAsync(txHash *wire.ShaHash) FutureGetRa hash = txHash.String() } - id := c.NextID() - cmd, err := btcjson.NewGetRawTransactionCmd(id, hash, 1) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewGetRawTransactionCmd(hash, btcjson.Int(1)) return c.sendCmd(cmd) } @@ -197,13 +187,8 @@ func (r FutureDecodeRawTransactionResult) Receive() (*btcjson.TxRawResult, error // // See DecodeRawTransaction for the blocking version and more details. func (c *Client) DecodeRawTransactionAsync(serializedTx []byte) FutureDecodeRawTransactionResult { - id := c.NextID() txHex := hex.EncodeToString(serializedTx) - cmd, err := btcjson.NewDecodeRawTransactionCmd(id, txHex) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewDecodeRawTransactionCmd(txHex) return c.sendCmd(cmd) } @@ -255,16 +240,11 @@ func (r FutureCreateRawTransactionResult) Receive() (*wire.MsgTx, error) { func (c *Client) CreateRawTransactionAsync(inputs []btcjson.TransactionInput, amounts map[btcutil.Address]btcutil.Amount) FutureCreateRawTransactionResult { - id := c.NextID() - convertedAmts := make(map[string]int64, len(amounts)) + convertedAmts := make(map[string]float64, len(amounts)) for addr, amount := range amounts { - convertedAmts[addr.String()] = int64(amount) + convertedAmts[addr.String()] = amount.ToBTC() } - cmd, err := btcjson.NewCreateRawTransactionCmd(id, inputs, convertedAmts) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewCreateRawTransactionCmd(inputs, convertedAmts) return c.sendCmd(cmd) } @@ -315,12 +295,7 @@ func (c *Client) SendRawTransactionAsync(tx *wire.MsgTx, allowHighFees bool) Fut txHex = hex.EncodeToString(buf.Bytes()) } - id := c.NextID() - cmd, err := btcjson.NewSendRawTransactionCmd(id, txHex, allowHighFees) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewSendRawTransactionCmd(txHex, &allowHighFees) return c.sendCmd(cmd) } @@ -381,12 +356,7 @@ func (c *Client) SignRawTransactionAsync(tx *wire.MsgTx) FutureSignRawTransactio txHex = hex.EncodeToString(buf.Bytes()) } - id := c.NextID() - cmd, err := btcjson.NewSignRawTransactionCmd(id, txHex) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewSignRawTransactionCmd(txHex, nil, nil, nil) return c.sendCmd(cmd) } @@ -417,12 +387,7 @@ func (c *Client) SignRawTransaction2Async(tx *wire.MsgTx, inputs []btcjson.RawTx txHex = hex.EncodeToString(buf.Bytes()) } - id := c.NextID() - cmd, err := btcjson.NewSignRawTransactionCmd(id, txHex, inputs) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewSignRawTransactionCmd(txHex, &inputs, nil, nil) return c.sendCmd(cmd) } @@ -459,13 +424,8 @@ func (c *Client) SignRawTransaction3Async(tx *wire.MsgTx, txHex = hex.EncodeToString(buf.Bytes()) } - id := c.NextID() - cmd, err := btcjson.NewSignRawTransactionCmd(id, txHex, inputs, - privKeysWIF) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewSignRawTransactionCmd(txHex, &inputs, &privKeysWIF, + nil) return c.sendCmd(cmd) } @@ -512,13 +472,8 @@ func (c *Client) SignRawTransaction4Async(tx *wire.MsgTx, txHex = hex.EncodeToString(buf.Bytes()) } - id := c.NextID() - cmd, err := btcjson.NewSignRawTransactionCmd(id, txHex, inputs, - privKeysWIF, string(hashType)) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewSignRawTransactionCmd(txHex, &inputs, &privKeysWIF, + btcjson.String(string(hashType))) return c.sendCmd(cmd) } diff --git a/wallet.go b/wallet.go index 4542819a..57427a93 100644 --- a/wallet.go +++ b/wallet.go @@ -8,8 +8,8 @@ import ( "encoding/json" "strconv" - "github.com/btcsuite/btcd/btcjson" - "github.com/btcsuite/btcd/btcjson/btcws" + "github.com/btcsuite/btcd/btcjson/v2/btcjson" + "github.com/btcsuite/btcd/chaincfg" "github.com/btcsuite/btcd/wire" "github.com/btcsuite/btcutil" @@ -52,12 +52,7 @@ func (c *Client) GetTransactionAsync(txHash *wire.ShaHash) FutureGetTransactionR hash = txHash.String() } - id := c.NextID() - cmd, err := btcjson.NewGetTransactionCmd(id, hash) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewGetTransactionCmd(hash, nil) return c.sendCmd(cmd) } @@ -97,12 +92,7 @@ func (r FutureListTransactionsResult) Receive() ([]btcjson.ListTransactionsResul // // See ListTransactions for the blocking version and more details. func (c *Client) ListTransactionsAsync(account string) FutureListTransactionsResult { - id := c.NextID() - cmd, err := btcjson.NewListTransactionsCmd(id, account) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewListTransactionsCmd(&account, nil, nil, nil) return c.sendCmd(cmd) } @@ -120,12 +110,7 @@ func (c *Client) ListTransactions(account string) ([]btcjson.ListTransactionsRes // // See ListTransactionsCount for the blocking version and more details. func (c *Client) ListTransactionsCountAsync(account string, count int) FutureListTransactionsResult { - id := c.NextID() - cmd, err := btcjson.NewListTransactionsCmd(id, account, count) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewListTransactionsCmd(&account, &count, nil, nil) return c.sendCmd(cmd) } @@ -144,12 +129,7 @@ func (c *Client) ListTransactionsCount(account string, count int) ([]btcjson.Lis // // See ListTransactionsCountFrom for the blocking version and more details. func (c *Client) ListTransactionsCountFromAsync(account string, count, from int) FutureListTransactionsResult { - id := c.NextID() - cmd, err := btcjson.NewListTransactionsCmd(id, account, count, from) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewListTransactionsCmd(&account, &count, &from, nil) return c.sendCmd(cmd) } @@ -193,12 +173,7 @@ func (r FutureListUnspentResult) Receive() ([]btcjson.ListUnspentResult, error) // // See ListUnspent for the blocking version and more details. func (c *Client) ListUnspentAsync() FutureListUnspentResult { - id := c.NextID() - cmd, err := btcjson.NewListUnspentCmd(id) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewListUnspentCmd(nil, nil, nil) return c.sendCmd(cmd) } @@ -208,12 +183,7 @@ func (c *Client) ListUnspentAsync() FutureListUnspentResult { // // See ListUnspentMin for the blocking version and more details. func (c *Client) ListUnspentMinAsync(minConf int) FutureListUnspentResult { - id := c.NextID() - cmd, err := btcjson.NewListUnspentCmd(id, minConf) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewListUnspentCmd(&minConf, nil, nil) return c.sendCmd(cmd) } @@ -223,12 +193,7 @@ func (c *Client) ListUnspentMinAsync(minConf int) FutureListUnspentResult { // // See ListUnspentMinMax for the blocking version and more details. func (c *Client) ListUnspentMinMaxAsync(minConf, maxConf int) FutureListUnspentResult { - id := c.NextID() - cmd, err := btcjson.NewListUnspentCmd(id, minConf, maxConf) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewListUnspentCmd(&minConf, &maxConf, nil) return c.sendCmd(cmd) } @@ -243,12 +208,7 @@ func (c *Client) ListUnspentMinMaxAddressesAsync(minConf, maxConf int, addrs []b addrStrs = append(addrStrs, a.EncodeAddress()) } - id := c.NextID() - cmd, err := btcjson.NewListUnspentCmd(id, minConf, maxConf, addrStrs) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewListUnspentCmd(&minConf, &maxConf, &addrStrs) return c.sendCmd(cmd) } @@ -315,12 +275,7 @@ func (c *Client) ListSinceBlockAsync(blockHash *wire.ShaHash) FutureListSinceBlo hash = blockHash.String() } - id := c.NextID() - cmd, err := btcjson.NewListSinceBlockCmd(id, hash) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewListSinceBlockCmd(&hash, nil, nil) return c.sendCmd(cmd) } @@ -344,12 +299,7 @@ func (c *Client) ListSinceBlockMinConfAsync(blockHash *wire.ShaHash, minConfirms hash = blockHash.String() } - id := c.NextID() - cmd, err := btcjson.NewListSinceBlockCmd(id, hash, minConfirms) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewListSinceBlockCmd(&hash, &minConfirms, nil) return c.sendCmd(cmd) } @@ -383,7 +333,6 @@ func (r FutureLockUnspentResult) Receive() error { // // See LockUnspent for the blocking version and more details. func (c *Client) LockUnspentAsync(unlock bool, ops []*wire.OutPoint) FutureLockUnspentResult { - id := c.NextID() outputs := make([]btcjson.TransactionInput, len(ops)) for i, op := range ops { outputs[i] = btcjson.TransactionInput{ @@ -391,11 +340,7 @@ func (c *Client) LockUnspentAsync(unlock bool, ops []*wire.OutPoint) FutureLockU Vout: op.Index, } } - cmd, err := btcjson.NewLockUnspentCmd(id, unlock, outputs) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewLockUnspentCmd(unlock, outputs) return c.sendCmd(cmd) } @@ -458,12 +403,7 @@ func (r FutureListLockUnspentResult) Receive() ([]*wire.OutPoint, error) { // // See ListLockUnspent for the blocking version and more details. func (c *Client) ListLockUnspentAsync() FutureListLockUnspentResult { - id := c.NextID() - cmd, err := btcjson.NewListLockUnspentCmd(id) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewListLockUnspentCmd() return c.sendCmd(cmd) } @@ -496,12 +436,7 @@ func (r FutureSetTxFeeResult) Receive() error { // // See SetTxFee for the blocking version and more details. func (c *Client) SetTxFeeAsync(fee btcutil.Amount) FutureSetTxFeeResult { - id := c.NextID() - cmd, err := btcjson.NewSetTxFeeCmd(id, int64(fee)) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewSetTxFeeCmd(fee.ToBTC()) return c.sendCmd(cmd) } @@ -539,13 +474,8 @@ func (r FutureSendToAddressResult) Receive() (*wire.ShaHash, error) { // // See SendToAddress for the blocking version and more details. func (c *Client) SendToAddressAsync(address btcutil.Address, amount btcutil.Amount) FutureSendToAddressResult { - id := c.NextID() addr := address.EncodeAddress() - cmd, err := btcjson.NewSendToAddressCmd(id, addr, int64(amount)) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewSendToAddressCmd(addr, amount.ToBTC(), nil, nil) return c.sendCmd(cmd) } @@ -570,14 +500,9 @@ func (c *Client) SendToAddressCommentAsync(address btcutil.Address, amount btcutil.Amount, comment, commentTo string) FutureSendToAddressResult { - id := c.NextID() addr := address.EncodeAddress() - cmd, err := btcjson.NewSendToAddressCmd(id, addr, int64(amount), - comment, commentTo) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewSendToAddressCmd(addr, amount.ToBTC(), &comment, + &commentTo) return c.sendCmd(cmd) } @@ -628,13 +553,9 @@ func (r FutureSendFromResult) Receive() (*wire.ShaHash, error) { // // See SendFrom for the blocking version and more details. func (c *Client) SendFromAsync(fromAccount string, toAddress btcutil.Address, amount btcutil.Amount) FutureSendFromResult { - id := c.NextID() addr := toAddress.EncodeAddress() - cmd, err := btcjson.NewSendFromCmd(id, fromAccount, addr, int64(amount)) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewSendFromCmd(fromAccount, addr, amount.ToBTC(), nil, + nil, nil) return c.sendCmd(cmd) } @@ -656,14 +577,9 @@ func (c *Client) SendFrom(fromAccount string, toAddress btcutil.Address, amount // // See SendFromMinConf for the blocking version and more details. func (c *Client) SendFromMinConfAsync(fromAccount string, toAddress btcutil.Address, amount btcutil.Amount, minConfirms int) FutureSendFromResult { - id := c.NextID() addr := toAddress.EncodeAddress() - cmd, err := btcjson.NewSendFromCmd(id, fromAccount, addr, int64(amount), - minConfirms) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewSendFromCmd(fromAccount, addr, amount.ToBTC(), + &minConfirms, nil, nil) return c.sendCmd(cmd) } @@ -690,14 +606,9 @@ func (c *Client) SendFromCommentAsync(fromAccount string, toAddress btcutil.Address, amount btcutil.Amount, minConfirms int, comment, commentTo string) FutureSendFromResult { - id := c.NextID() addr := toAddress.EncodeAddress() - cmd, err := btcjson.NewSendFromCmd(id, fromAccount, addr, int64(amount), - minConfirms, comment, commentTo) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewSendFromCmd(fromAccount, addr, amount.ToBTC(), + &minConfirms, &comment, &commentTo) return c.sendCmd(cmd) } @@ -750,16 +661,11 @@ func (r FutureSendManyResult) Receive() (*wire.ShaHash, error) { // // See SendMany for the blocking version and more details. func (c *Client) SendManyAsync(fromAccount string, amounts map[btcutil.Address]btcutil.Amount) FutureSendManyResult { - convertedAmounts := make(map[string]int64, len(amounts)) + convertedAmounts := make(map[string]float64, len(amounts)) for addr, amount := range amounts { - convertedAmounts[addr.EncodeAddress()] = int64(amount) + convertedAmounts[addr.EncodeAddress()] = amount.ToBTC() } - id := c.NextID() - cmd, err := btcjson.NewSendManyCmd(id, fromAccount, convertedAmounts) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewSendManyCmd(fromAccount, convertedAmounts, nil, nil) return c.sendCmd(cmd) } @@ -784,17 +690,12 @@ func (c *Client) SendManyMinConfAsync(fromAccount string, amounts map[btcutil.Address]btcutil.Amount, minConfirms int) FutureSendManyResult { - convertedAmounts := make(map[string]int64, len(amounts)) + convertedAmounts := make(map[string]float64, len(amounts)) for addr, amount := range amounts { - convertedAmounts[addr.EncodeAddress()] = int64(amount) + convertedAmounts[addr.EncodeAddress()] = amount.ToBTC() } - id := c.NextID() - cmd, err := btcjson.NewSendManyCmd(id, fromAccount, convertedAmounts, - minConfirms) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewSendManyCmd(fromAccount, convertedAmounts, + &minConfirms, nil) return c.sendCmd(cmd) } @@ -823,17 +724,12 @@ func (c *Client) SendManyCommentAsync(fromAccount string, amounts map[btcutil.Address]btcutil.Amount, minConfirms int, comment string) FutureSendManyResult { - convertedAmounts := make(map[string]int64, len(amounts)) + convertedAmounts := make(map[string]float64, len(amounts)) for addr, amount := range amounts { - convertedAmounts[addr.EncodeAddress()] = int64(amount) + convertedAmounts[addr.EncodeAddress()] = amount.ToBTC() } - id := c.NextID() - cmd, err := btcjson.NewSendManyCmd(id, fromAccount, convertedAmounts, - minConfirms, comment) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewSendManyCmd(fromAccount, convertedAmounts, + &minConfirms, &comment) return c.sendCmd(cmd) } @@ -888,18 +784,12 @@ func (r FutureAddMultisigAddressResult) Receive() (btcutil.Address, error) { // // See AddMultisigAddress for the blocking version and more details. func (c *Client) AddMultisigAddressAsync(requiredSigs int, addresses []btcutil.Address, account string) FutureAddMultisigAddressResult { - id := c.NextID() - addrs := make([]string, 0, len(addresses)) for _, addr := range addresses { addrs = append(addrs, addr.String()) } - cmd, err := btcjson.NewAddMultisigAddressCmd(id, requiredSigs, addrs, account) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewAddMultisigAddressCmd(requiredSigs, addrs, &account) return c.sendCmd(cmd) } @@ -938,18 +828,12 @@ func (r FutureCreateMultisigResult) Receive() (*btcjson.CreateMultiSigResult, er // // See CreateMultisig for the blocking version and more details. func (c *Client) CreateMultisigAsync(requiredSigs int, addresses []btcutil.Address) FutureCreateMultisigResult { - id := c.NextID() - addrs := make([]string, 0, len(addresses)) for _, addr := range addresses { addrs = append(addrs, addr.String()) } - cmd, err := btcjson.NewCreateMultisigCmd(id, requiredSigs, addrs) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewCreateMultisigCmd(requiredSigs, addrs) return c.sendCmd(cmd) } @@ -981,8 +865,7 @@ func (r FutureCreateNewAccountResult) Receive() error { // // See CreateNewAccount for the blocking version and more details. func (c *Client) CreateNewAccountAsync(account string) FutureCreateNewAccountResult { - id := c.NextID() - cmd := btcws.NewCreateNewAccountCmd(id, account) + cmd := btcjson.NewCreateNewAccountCmd(account) return c.sendCmd(cmd) } @@ -1019,12 +902,7 @@ func (r FutureGetNewAddressResult) Receive() (btcutil.Address, error) { // // See GetNewAddress for the blocking version and more details. func (c *Client) GetNewAddressAsync() FutureGetNewAddressResult { - id := c.NextID() - cmd, err := btcjson.NewGetNewAddressCmd(id) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewGetNewAddressCmd(nil) return c.sendCmd(cmd) } @@ -1062,12 +940,7 @@ func (r FutureGetRawChangeAddressResult) Receive() (btcutil.Address, error) { // // See GetRawChangeAddress for the blocking version and more details. func (c *Client) GetRawChangeAddressAsync(account string) FutureGetRawChangeAddressResult { - id := c.NextID() - cmd, err := btcjson.NewGetRawChangeAddressCmd(id, account) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewGetRawChangeAddressCmd(&account) return c.sendCmd(cmd) } @@ -1106,12 +979,7 @@ func (r FutureGetAccountAddressResult) Receive() (btcutil.Address, error) { // // See GetAccountAddress for the blocking version and more details. func (c *Client) GetAccountAddressAsync(account string) FutureGetAccountAddressResult { - id := c.NextID() - cmd, err := btcjson.NewGetAccountAddressCmd(id, account) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewGetAccountAddressCmd(account) return c.sendCmd(cmd) } @@ -1149,13 +1017,8 @@ func (r FutureGetAccountResult) Receive() (string, error) { // // See GetAccount for the blocking version and more details. func (c *Client) GetAccountAsync(address btcutil.Address) FutureGetAccountResult { - id := c.NextID() addr := address.EncodeAddress() - cmd, err := btcjson.NewGetAccountCmd(id, addr) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewGetAccountCmd(addr) return c.sendCmd(cmd) } @@ -1185,13 +1048,8 @@ func (r FutureSetAccountResult) Receive() error { // // See SetAccount for the blocking version and more details. func (c *Client) SetAccountAsync(address btcutil.Address, account string) FutureSetAccountResult { - id := c.NextID() addr := address.EncodeAddress() - cmd, err := btcjson.NewSetAccountCmd(id, addr, account) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewSetAccountCmd(addr, account) return c.sendCmd(cmd) } @@ -1238,12 +1096,7 @@ func (r FutureGetAddressesByAccountResult) Receive() ([]btcutil.Address, error) // // See GetAddressesByAccount for the blocking version and more details. func (c *Client) GetAddressesByAccountAsync(account string) FutureGetAddressesByAccountResult { - id := c.NextID() - cmd, err := btcjson.NewGetAddressesByAccountCmd(id, account) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewGetAddressesByAccountCmd(account) return c.sendCmd(cmd) } @@ -1282,12 +1135,8 @@ func (r FutureMoveResult) Receive() (bool, error) { // // See Move for the blocking version and more details. func (c *Client) MoveAsync(fromAccount, toAccount string, amount btcutil.Amount) FutureMoveResult { - id := c.NextID() - cmd, err := btcjson.NewMoveCmd(id, fromAccount, toAccount, int64(amount)) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewMoveCmd(fromAccount, toAccount, amount.ToBTC(), nil, + nil) return c.sendCmd(cmd) } @@ -1307,13 +1156,8 @@ func (c *Client) Move(fromAccount, toAccount string, amount btcutil.Amount) (boo func (c *Client) MoveMinConfAsync(fromAccount, toAccount string, amount btcutil.Amount, minConfirms int) FutureMoveResult { - id := c.NextID() - cmd, err := btcjson.NewMoveCmd(id, fromAccount, toAccount, int64(amount), - minConfirms) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewMoveCmd(fromAccount, toAccount, amount.ToBTC(), + &minConfirms, nil) return c.sendCmd(cmd) } @@ -1335,13 +1179,8 @@ func (c *Client) MoveMinConf(fromAccount, toAccount string, amount btcutil.Amoun func (c *Client) MoveCommentAsync(fromAccount, toAccount string, amount btcutil.Amount, minConfirms int, comment string) FutureMoveResult { - id := c.NextID() - cmd, err := btcjson.NewMoveCmd(id, fromAccount, toAccount, int64(amount), - minConfirms, comment) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewMoveCmd(fromAccount, toAccount, amount.ToBTC(), + &minConfirms, &comment) return c.sendCmd(cmd) } @@ -1378,15 +1217,14 @@ func (r FutureRenameAccountResult) Receive() error { // returned instance. // // See RenameAccount for the blocking version and more details. -func (c *Client) RenameAccountAsync(oldaccount, newaccount string) FutureRenameAccountResult { - id := c.NextID() - cmd := btcws.NewRenameAccountCmd(id, oldaccount, newaccount) +func (c *Client) RenameAccountAsync(oldAccount, newAccount string) FutureRenameAccountResult { + cmd := btcjson.NewRenameAccountCmd(oldAccount, newAccount) return c.sendCmd(cmd) } // RenameAccount creates a new wallet account. -func (c *Client) RenameAccount(oldaccount, newaccount string) error { - return c.RenameAccountAsync(oldaccount, newaccount).Receive() +func (c *Client) RenameAccount(oldAccount, newAccount string) error { + return c.RenameAccountAsync(oldAccount, newAccount).Receive() } // FutureValidateAddressResult is a future promise to deliver the result of a @@ -1395,14 +1233,14 @@ type FutureValidateAddressResult chan *response // Receive waits for the response promised by the future and returns information // about the given bitcoin address. -func (r FutureValidateAddressResult) Receive() (*btcjson.ValidateAddressResult, error) { +func (r FutureValidateAddressResult) Receive() (*btcjson.ValidateAddressWalletResult, error) { res, err := receiveFuture(r) if err != nil { return nil, err } // Unmarshal result as a validateaddress result object. - var addrResult btcjson.ValidateAddressResult + var addrResult btcjson.ValidateAddressWalletResult err = json.Unmarshal(res, &addrResult) if err != nil { return nil, err @@ -1417,18 +1255,13 @@ func (r FutureValidateAddressResult) Receive() (*btcjson.ValidateAddressResult, // // See ValidateAddress for the blocking version and more details. func (c *Client) ValidateAddressAsync(address btcutil.Address) FutureValidateAddressResult { - id := c.NextID() addr := address.EncodeAddress() - cmd, err := btcjson.NewValidateAddressCmd(id, addr) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewValidateAddressCmd(addr) return c.sendCmd(cmd) } // ValidateAddress returns information about the given bitcoin address. -func (c *Client) ValidateAddress(address btcutil.Address) (*btcjson.ValidateAddressResult, error) { +func (c *Client) ValidateAddress(address btcutil.Address) (*btcjson.ValidateAddressWalletResult, error) { return c.ValidateAddressAsync(address).Receive() } @@ -1453,12 +1286,7 @@ func (r FutureKeyPoolRefillResult) Receive() error { // // See KeyPoolRefill for the blocking version and more details. func (c *Client) KeyPoolRefillAsync() FutureKeyPoolRefillResult { - id := c.NextID() - cmd, err := btcjson.NewKeyPoolRefillCmd(id) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewKeyPoolRefillCmd(nil) return c.sendCmd(cmd) } @@ -1475,12 +1303,7 @@ func (c *Client) KeyPoolRefill() error { // // See KeyPoolRefillSize for the blocking version and more details. func (c *Client) KeyPoolRefillSizeAsync(newSize uint) FutureKeyPoolRefillResult { - id := c.NextID() - cmd, err := btcjson.NewKeyPoolRefillCmd(id, newSize) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewKeyPoolRefillCmd(&newSize) return c.sendCmd(cmd) } @@ -1516,12 +1339,12 @@ func (r FutureListAccountsResult) Receive() (map[string]btcutil.Amount, error) { accountsMap := make(map[string]btcutil.Amount) for k, v := range accounts { - satoshi, err := btcjson.JSONToAmount(v) + amount, err := btcutil.NewAmount(v) if err != nil { return nil, err } - accountsMap[k] = btcutil.Amount(satoshi) + accountsMap[k] = amount } return accountsMap, nil @@ -1533,12 +1356,7 @@ func (r FutureListAccountsResult) Receive() (map[string]btcutil.Amount, error) { // // See ListAccounts for the blocking version and more details. func (c *Client) ListAccountsAsync() FutureListAccountsResult { - id := c.NextID() - cmd, err := btcjson.NewListAccountsCmd(id) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewListAccountsCmd(nil) return c.sendCmd(cmd) } @@ -1556,12 +1374,7 @@ func (c *Client) ListAccounts() (map[string]btcutil.Amount, error) { // // See ListAccountsMinConf for the blocking version and more details. func (c *Client) ListAccountsMinConfAsync(minConfirms int) FutureListAccountsResult { - id := c.NextID() - cmd, err := btcjson.NewListAccountsCmd(id, minConfirms) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewListAccountsCmd(&minConfirms) return c.sendCmd(cmd) } @@ -1593,12 +1406,12 @@ func (r FutureGetBalanceResult) Receive() (btcutil.Amount, error) { return 0, err } - satoshi, err := btcjson.JSONToAmount(balance) + amount, err := btcutil.NewAmount(balance) if err != nil { return 0, err } - return btcutil.Amount(satoshi), nil + return amount, nil } // FutureGetBalanceParseResult is same as FutureGetBalanceResult except @@ -1626,12 +1439,12 @@ func (r FutureGetBalanceParseResult) Receive() (btcutil.Amount, error) { if err != nil { return 0, err } - satoshi, err := btcjson.JSONToAmount(balance) + amount, err := btcutil.NewAmount(balance) if err != nil { return 0, err } - return btcutil.Amount(satoshi), nil + return amount, nil } // GetBalanceAsync returns an instance of a type that can be used to get the @@ -1640,16 +1453,7 @@ func (r FutureGetBalanceParseResult) Receive() (btcutil.Amount, error) { // // See GetBalance for the blocking version and more details. func (c *Client) GetBalanceAsync(account string) FutureGetBalanceResult { - // TODO(davec): Remove this hack once btcwallet is fixed. - if account == "*" { - account = "" - } - id := c.NextID() - cmd, err := btcjson.NewGetBalanceCmd(id, account) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewGetBalanceCmd(&account, nil) return c.sendCmd(cmd) } @@ -1668,16 +1472,7 @@ func (c *Client) GetBalance(account string) (btcutil.Amount, error) { // // See GetBalanceMinConf for the blocking version and more details. func (c *Client) GetBalanceMinConfAsync(account string, minConfirms int) FutureGetBalanceResult { - // TODO(davec): Remove this hack once btcwallet is fixed. - if account == "*" { - account = "" - } - id := c.NextID() - cmd, err := btcjson.NewGetBalanceCmd(id, account, minConfirms) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewGetBalanceCmd(&account, &minConfirms) return c.sendCmd(cmd) } @@ -1714,12 +1509,12 @@ func (r FutureGetReceivedByAccountResult) Receive() (btcutil.Amount, error) { return 0, err } - satoshi, err := btcjson.JSONToAmount(balance) + amount, err := btcutil.NewAmount(balance) if err != nil { return 0, err } - return btcutil.Amount(satoshi), nil + return amount, nil } // GetReceivedByAccountAsync returns an instance of a type that can be used to @@ -1728,12 +1523,7 @@ func (r FutureGetReceivedByAccountResult) Receive() (btcutil.Amount, error) { // // See GetReceivedByAccount for the blocking version and more details. func (c *Client) GetReceivedByAccountAsync(account string) FutureGetReceivedByAccountResult { - id := c.NextID() - cmd, err := btcjson.NewGetReceivedByAccountCmd(id, account) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewGetReceivedByAccountCmd(account, nil) return c.sendCmd(cmd) } @@ -1752,12 +1542,7 @@ func (c *Client) GetReceivedByAccount(account string) (btcutil.Amount, error) { // // See GetReceivedByAccountMinConf for the blocking version and more details. func (c *Client) GetReceivedByAccountMinConfAsync(account string, minConfirms int) FutureGetReceivedByAccountResult { - id := c.NextID() - cmd, err := btcjson.NewGetReceivedByAccountCmd(id, account, minConfirms) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewGetReceivedByAccountCmd(account, &minConfirms) return c.sendCmd(cmd) } @@ -1789,12 +1574,12 @@ func (r FutureGetUnconfirmedBalanceResult) Receive() (btcutil.Amount, error) { return 0, err } - satoshi, err := btcjson.JSONToAmount(balance) + amount, err := btcutil.NewAmount(balance) if err != nil { return 0, err } - return btcutil.Amount(satoshi), nil + return amount, nil } // GetUnconfirmedBalanceAsync returns an instance of a type that can be used to @@ -1803,12 +1588,7 @@ func (r FutureGetUnconfirmedBalanceResult) Receive() (btcutil.Amount, error) { // // See GetUnconfirmedBalance for the blocking version and more details. func (c *Client) GetUnconfirmedBalanceAsync(account string) FutureGetUnconfirmedBalanceResult { - id := c.NextID() - cmd, err := btcws.NewGetUnconfirmedBalanceCmd(id, account) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewGetUnconfirmedBalanceCmd(&account) return c.sendCmd(cmd) } @@ -1838,12 +1618,12 @@ func (r FutureGetReceivedByAddressResult) Receive() (btcutil.Amount, error) { return 0, err } - satoshi, err := btcjson.JSONToAmount(balance) + amount, err := btcutil.NewAmount(balance) if err != nil { return 0, err } - return btcutil.Amount(satoshi), nil + return amount, nil } // GetReceivedByAddressAsync returns an instance of a type that can be used to @@ -1852,13 +1632,8 @@ func (r FutureGetReceivedByAddressResult) Receive() (btcutil.Amount, error) { // // See GetReceivedByAddress for the blocking version and more details. func (c *Client) GetReceivedByAddressAsync(address btcutil.Address) FutureGetReceivedByAddressResult { - id := c.NextID() addr := address.EncodeAddress() - cmd, err := btcjson.NewGetReceivedByAddressCmd(id, addr) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewGetReceivedByAddressCmd(addr, nil) return c.sendCmd(cmd) } @@ -1878,13 +1653,8 @@ func (c *Client) GetReceivedByAddress(address btcutil.Address) (btcutil.Amount, // // See GetReceivedByAddressMinConf for the blocking version and more details. func (c *Client) GetReceivedByAddressMinConfAsync(address btcutil.Address, minConfirms int) FutureGetReceivedByAddressResult { - id := c.NextID() addr := address.EncodeAddress() - cmd, err := btcjson.NewGetReceivedByAddressCmd(id, addr, minConfirms) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewGetReceivedByAddressCmd(addr, &minConfirms) return c.sendCmd(cmd) } @@ -1926,12 +1696,7 @@ func (r FutureListReceivedByAccountResult) Receive() ([]btcjson.ListReceivedByAc // // See ListReceivedByAccount for the blocking version and more details. func (c *Client) ListReceivedByAccountAsync() FutureListReceivedByAccountResult { - id := c.NextID() - cmd, err := btcjson.NewListReceivedByAccountCmd(id) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewListReceivedByAccountCmd(nil, nil, nil) return c.sendCmd(cmd) } @@ -1952,12 +1717,7 @@ func (c *Client) ListReceivedByAccount() ([]btcjson.ListReceivedByAccountResult, // // See ListReceivedByAccountMinConf for the blocking version and more details. func (c *Client) ListReceivedByAccountMinConfAsync(minConfirms int) FutureListReceivedByAccountResult { - id := c.NextID() - cmd, err := btcjson.NewListReceivedByAccountCmd(id, minConfirms) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewListReceivedByAccountCmd(&minConfirms, nil, nil) return c.sendCmd(cmd) } @@ -1978,12 +1738,8 @@ func (c *Client) ListReceivedByAccountMinConf(minConfirms int) ([]btcjson.ListRe // // See ListReceivedByAccountIncludeEmpty for the blocking version and more details. func (c *Client) ListReceivedByAccountIncludeEmptyAsync(minConfirms int, includeEmpty bool) FutureListReceivedByAccountResult { - id := c.NextID() - cmd, err := btcjson.NewListReceivedByAccountCmd(id, minConfirms, includeEmpty) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewListReceivedByAccountCmd(&minConfirms, &includeEmpty, + nil) return c.sendCmd(cmd) } @@ -2027,12 +1783,7 @@ func (r FutureListReceivedByAddressResult) Receive() ([]btcjson.ListReceivedByAd // // See ListReceivedByAddress for the blocking version and more details. func (c *Client) ListReceivedByAddressAsync() FutureListReceivedByAddressResult { - id := c.NextID() - cmd, err := btcjson.NewListReceivedByAddressCmd(id) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewListReceivedByAddressCmd(nil, nil, nil) return c.sendCmd(cmd) } @@ -2053,12 +1804,7 @@ func (c *Client) ListReceivedByAddress() ([]btcjson.ListReceivedByAddressResult, // // See ListReceivedByAddressMinConf for the blocking version and more details. func (c *Client) ListReceivedByAddressMinConfAsync(minConfirms int) FutureListReceivedByAddressResult { - id := c.NextID() - cmd, err := btcjson.NewListReceivedByAddressCmd(id, minConfirms) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewListReceivedByAddressCmd(&minConfirms, nil, nil) return c.sendCmd(cmd) } @@ -2079,13 +1825,8 @@ func (c *Client) ListReceivedByAddressMinConf(minConfirms int) ([]btcjson.ListRe // // See ListReceivedByAccountIncludeEmpty for the blocking version and more details. func (c *Client) ListReceivedByAddressIncludeEmptyAsync(minConfirms int, includeEmpty bool) FutureListReceivedByAddressResult { - id := c.NextID() - cmd, err := btcjson.NewListReceivedByAddressCmd(id, minConfirms, - includeEmpty) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewListReceivedByAddressCmd(&minConfirms, &includeEmpty, + nil) return c.sendCmd(cmd) } @@ -2124,12 +1865,7 @@ func (r FutureWalletLockResult) Receive() error { // // See WalletLock for the blocking version and more details. func (c *Client) WalletLockAsync() FutureWalletLockResult { - id := c.NextID() - cmd, err := btcjson.NewWalletLockCmd(id) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewWalletLockCmd() return c.sendCmd(cmd) } @@ -2146,13 +1882,8 @@ func (c *Client) WalletLock() error { // decryption key which is then stored in memory for the specified timeout // (in seconds). func (c *Client) WalletPassphrase(passphrase string, timeoutSecs int64) error { - id := c.NextID() - cmd, err := btcjson.NewWalletPassphraseCmd(id, passphrase, timeoutSecs) - if err != nil { - return err - } - - _, err = c.sendCmdAndWait(cmd) + cmd := btcjson.NewWalletPassphraseCmd(passphrase, timeoutSecs) + _, err := c.sendCmdAndWait(cmd) if err != nil { return err } @@ -2181,12 +1912,7 @@ func (r FutureWalletPassphraseChangeResult) Receive() error { // // See WalletPassphraseChange for the blocking version and more details. func (c *Client) WalletPassphraseChangeAsync(old, new string) FutureWalletPassphraseChangeResult { - id := c.NextID() - cmd, err := btcjson.NewWalletPassphraseChangeCmd(id, old, new) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewWalletPassphraseChangeCmd(old, new) return c.sendCmd(cmd) } @@ -2228,13 +1954,8 @@ func (r FutureSignMessageResult) Receive() (string, error) { // // See SignMessage for the blocking version and more details. func (c *Client) SignMessageAsync(address btcutil.Address, message string) FutureSignMessageResult { - id := c.NextID() addr := address.EncodeAddress() - cmd, err := btcjson.NewSignMessageCmd(id, addr, message) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewSignMessageCmd(addr, message) return c.sendCmd(cmd) } @@ -2274,13 +1995,8 @@ func (r FutureVerifyMessageResult) Receive() (bool, error) { // // See VerifyMessage for the blocking version and more details. func (c *Client) VerifyMessageAsync(address btcutil.Address, signature, message string) FutureVerifyMessageResult { - id := c.NextID() addr := address.EncodeAddress() - cmd, err := btcjson.NewVerifyMessageCmd(id, addr, signature, message) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewVerifyMessageCmd(addr, signature, message) return c.sendCmd(cmd) } @@ -2325,13 +2041,8 @@ func (r FutureDumpPrivKeyResult) Receive() (*btcutil.WIF, error) { // // See DumpPrivKey for the blocking version and more details. func (c *Client) DumpPrivKeyAsync(address btcutil.Address) FutureDumpPrivKeyResult { - id := c.NextID() addr := address.EncodeAddress() - cmd, err := btcjson.NewDumpPrivKeyCmd(id, addr) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewDumpPrivKeyCmd(addr) return c.sendCmd(cmd) } @@ -2371,12 +2082,7 @@ func (c *Client) ImportPrivKeyAsync(privKeyWIF *btcutil.WIF) FutureImportPrivKey wif = privKeyWIF.String() } - id := c.NextID() - cmd, err := btcjson.NewImportPrivKeyCmd(id, wif) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewImportPrivKeyCmd(wif, nil, nil) return c.sendCmd(cmd) } @@ -2397,12 +2103,7 @@ func (c *Client) ImportPrivKeyLabelAsync(privKeyWIF *btcutil.WIF, label string) wif = privKeyWIF.String() } - id := c.NextID() - cmd, err := btcjson.NewImportPrivKeyCmd(id, wif, label) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewImportPrivKeyCmd(wif, &label, nil) return c.sendCmd(cmd) } @@ -2423,12 +2124,7 @@ func (c *Client) ImportPrivKeyRescanAsync(privKeyWIF *btcutil.WIF, label string, wif = privKeyWIF.String() } - id := c.NextID() - cmd, err := btcjson.NewImportPrivKeyCmd(id, wif, label, rescan) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewImportPrivKeyCmd(wif, &label, &rescan) return c.sendCmd(cmd) } @@ -2452,14 +2148,14 @@ type FutureGetInfoResult chan *response // Receive waits for the response promised by the future and returns the info // provided by the server. -func (r FutureGetInfoResult) Receive() (*btcjson.InfoResult, error) { +func (r FutureGetInfoResult) Receive() (*btcjson.InfoWalletResult, error) { res, err := receiveFuture(r) if err != nil { return nil, err } // Unmarshal result as a getinfo result object. - var infoRes btcjson.InfoResult + var infoRes btcjson.InfoWalletResult err = json.Unmarshal(res, &infoRes) if err != nil { return nil, err @@ -2474,19 +2170,14 @@ func (r FutureGetInfoResult) Receive() (*btcjson.InfoResult, error) { // // See GetInfo for the blocking version and more details. func (c *Client) GetInfoAsync() FutureGetInfoResult { - id := c.NextID() - cmd, err := btcjson.NewGetInfoCmd(id) - if err != nil { - return newFutureError(err) - } - + cmd := btcjson.NewGetInfoCmd() return c.sendCmd(cmd) } // GetInfo returns miscellaneous info regarding the RPC server. The returned // info object may be void of wallet information if the remote server does // not include wallet functionality. -func (c *Client) GetInfo() (*btcjson.InfoResult, error) { +func (c *Client) GetInfo() (*btcjson.InfoWalletResult, error) { return c.GetInfoAsync().Receive() }