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() }