diff --git a/rpcclient/infrastructure.go b/rpcclient/infrastructure.go index 7a8f1885d1..a2079886d3 100644 --- a/rpcclient/infrastructure.go +++ b/rpcclient/infrastructure.go @@ -25,6 +25,7 @@ import ( "time" "github.com/btcsuite/btcd/btcjson" + "github.com/btcsuite/btcd/chaincfg" "github.com/btcsuite/go-socks/socks" "github.com/btcsuite/websocket" ) @@ -138,6 +139,10 @@ type Client struct { // config holds the connection configuration assoiated with this client. config *ConnConfig + // chainParams holds the params for the chain that this client is using, + // and is used for many wallet methods. + chainParams *chaincfg.Params + // wsConn is the underlying websocket connection when not in HTTP POST // mode. wsConn *websocket.Conn @@ -283,31 +288,29 @@ func (c *Client) trackRegisteredNtfns(cmd interface{}) { } } -type ( - // inMessage is the first type that an incoming message is unmarshaled - // into. It supports both requests (for notification support) and - // responses. The partially-unmarshaled message is a notification if - // the embedded ID (from the response) is nil. Otherwise, it is a - // response. - inMessage struct { - ID *float64 `json:"id"` - *rawNotification - *rawResponse - } +// inMessage is the first type that an incoming message is unmarshaled +// into. It supports both requests (for notification support) and +// responses. The partially-unmarshaled message is a notification if +// the embedded ID (from the response) is nil. Otherwise, it is a +// response. +type inMessage struct { + ID *float64 `json:"id"` + *rawNotification + *rawResponse +} - // rawNotification is a partially-unmarshaled JSON-RPC notification. - rawNotification struct { - Method string `json:"method"` - Params []json.RawMessage `json:"params"` - } +// rawNotification is a partially-unmarshaled JSON-RPC notification. +type rawNotification struct { + Method string `json:"method"` + Params []json.RawMessage `json:"params"` +} - // rawResponse is a partially-unmarshaled JSON-RPC response. For this - // to be valid (according to JSON-RPC 1.0 spec), ID may not be nil. - rawResponse struct { - Result json.RawMessage `json:"result"` - Error *btcjson.RPCError `json:"error"` - } -) +// 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. +type rawResponse struct { + Result json.RawMessage `json:"result"` + Error *btcjson.RPCError `json:"error"` +} // response is the raw bytes of a JSON-RPC result, or the error if the response // error object was non-null. @@ -1093,6 +1096,11 @@ type ConnConfig struct { // Pass is the passphrase to use to authenticate to the RPC server. Pass string + // Params is the string representing the network that the server + // is running. If there is no parameter set in the config, then + // mainnet will be used by default. + Params string + // DisableTLS specifies whether transport layer security should be // disabled. It is recommended to always use TLS if the RPC server // supports it as otherwise your username and password is sent across @@ -1290,6 +1298,23 @@ func New(config *ConnConfig, ntfnHandlers *NotificationHandlers) (*Client, error shutdown: make(chan struct{}), } + // Default network is mainnet, no parameters are necessary but if mainnet + // is specified it will be the param + switch config.Params { + case "": + fallthrough + case chaincfg.MainNetParams.Name: + client.chainParams = &chaincfg.MainNetParams + case chaincfg.TestNet3Params.Name: + client.chainParams = &chaincfg.TestNet3Params + case chaincfg.RegressionNetParams.Name: + client.chainParams = &chaincfg.RegressionNetParams + case chaincfg.SimNetParams.Name: + client.chainParams = &chaincfg.SimNetParams + default: + return nil, fmt.Errorf("rpcclient.New: Unknown chain %s", config.Params) + } + if start { log.Infof("Established connection to RPC server %s", config.Host) diff --git a/rpcclient/wallet.go b/rpcclient/wallet.go index 27546f5de0..d43be26181 100644 --- a/rpcclient/wallet.go +++ b/rpcclient/wallet.go @@ -753,13 +753,16 @@ func (c *Client) SendManyComment(fromAccount string, // FutureAddMultisigAddressResult is a future promise to deliver the result of a // AddMultisigAddressAsync RPC invocation (or an applicable error). -type FutureAddMultisigAddressResult chan *response +type FutureAddMultisigAddressResult struct { + responseChannel chan *response + network *chaincfg.Params +} // Receive waits for the response promised by the future and returns the // multisignature address that requires the specified number of signatures for // the provided addresses. func (r FutureAddMultisigAddressResult) Receive() (btcutil.Address, error) { - res, err := receiveFuture(r) + res, err := receiveFuture(r.responseChannel) if err != nil { return nil, err } @@ -771,7 +774,7 @@ func (r FutureAddMultisigAddressResult) Receive() (btcutil.Address, error) { return nil, err } - return btcutil.DecodeAddress(addr, &chaincfg.MainNetParams) + return btcutil.DecodeAddress(addr, r.network) } // AddMultisigAddressAsync returns an instance of a type that can be used to get @@ -786,14 +789,17 @@ func (c *Client) AddMultisigAddressAsync(requiredSigs int, addresses []btcutil.A } cmd := btcjson.NewAddMultisigAddressCmd(requiredSigs, addrs, &account) - return c.sendCmd(cmd) + result := FutureAddMultisigAddressResult{ + network: c.chainParams, + responseChannel: c.sendCmd(cmd), + } + return result } // AddMultisigAddress adds a multisignature address that requires the specified // number of signatures for the provided addresses to the wallet. func (c *Client) AddMultisigAddress(requiredSigs int, addresses []btcutil.Address, account string) (btcutil.Address, error) { - return c.AddMultisigAddressAsync(requiredSigs, addresses, - account).Receive() + return c.AddMultisigAddressAsync(requiredSigs, addresses, account).Receive() } // FutureCreateMultisigResult is a future promise to deliver the result of a @@ -868,12 +874,15 @@ func (c *Client) CreateNewAccount(account string) error { // FutureGetNewAddressResult is a future promise to deliver the result of a // GetNewAddressAsync RPC invocation (or an applicable error). -type FutureGetNewAddressResult chan *response +type FutureGetNewAddressResult struct { + responseChannel chan *response + network *chaincfg.Params +} // Receive waits for the response promised by the future and returns a new // address. func (r FutureGetNewAddressResult) Receive() (btcutil.Address, error) { - res, err := receiveFuture(r) + res, err := receiveFuture(r.responseChannel) if err != nil { return nil, err } @@ -885,7 +894,7 @@ func (r FutureGetNewAddressResult) Receive() (btcutil.Address, error) { return nil, err } - return btcutil.DecodeAddress(addr, &chaincfg.MainNetParams) + return btcutil.DecodeAddress(addr, r.network) } // GetNewAddressAsync returns an instance of a type that can be used to get the @@ -895,23 +904,31 @@ func (r FutureGetNewAddressResult) Receive() (btcutil.Address, error) { // See GetNewAddress for the blocking version and more details. func (c *Client) GetNewAddressAsync(account string) FutureGetNewAddressResult { cmd := btcjson.NewGetNewAddressCmd(&account) - return c.sendCmd(cmd) + result := FutureGetNewAddressResult{ + network: c.chainParams, + responseChannel: c.sendCmd(cmd), + } + return result } -// GetNewAddress returns a new address. +// GetNewAddress returns a new address, and decodes based on the client's +// chain params. func (c *Client) GetNewAddress(account string) (btcutil.Address, error) { return c.GetNewAddressAsync(account).Receive() } // FutureGetRawChangeAddressResult is a future promise to deliver the result of // a GetRawChangeAddressAsync RPC invocation (or an applicable error). -type FutureGetRawChangeAddressResult chan *response +type FutureGetRawChangeAddressResult struct { + responseChannel chan *response + network *chaincfg.Params +} // Receive waits for the response promised by the future and returns a new // address for receiving change that will be associated with the provided // account. Note that this is only for raw transactions and NOT for normal use. func (r FutureGetRawChangeAddressResult) Receive() (btcutil.Address, error) { - res, err := receiveFuture(r) + res, err := receiveFuture(r.responseChannel) if err != nil { return nil, err } @@ -923,7 +940,7 @@ func (r FutureGetRawChangeAddressResult) Receive() (btcutil.Address, error) { return nil, err } - return btcutil.DecodeAddress(addr, &chaincfg.MainNetParams) + return btcutil.DecodeAddress(addr, r.network) } // GetRawChangeAddressAsync returns an instance of a type that can be used to @@ -933,7 +950,11 @@ func (r FutureGetRawChangeAddressResult) Receive() (btcutil.Address, error) { // See GetRawChangeAddress for the blocking version and more details. func (c *Client) GetRawChangeAddressAsync(account string) FutureGetRawChangeAddressResult { cmd := btcjson.NewGetRawChangeAddressCmd(&account) - return c.sendCmd(cmd) + result := FutureGetRawChangeAddressResult{ + network: c.chainParams, + responseChannel: c.sendCmd(cmd), + } + return result } // GetRawChangeAddress returns a new address for receiving change that will be @@ -945,12 +966,15 @@ func (c *Client) GetRawChangeAddress(account string) (btcutil.Address, error) { // FutureAddWitnessAddressResult is a future promise to deliver the result of // a AddWitnessAddressAsync RPC invocation (or an applicable error). -type FutureAddWitnessAddressResult chan *response +type FutureAddWitnessAddressResult struct { + responseChannel chan *response + network *chaincfg.Params +} // Receive waits for the response promised by the future and returns the new // address. func (r FutureAddWitnessAddressResult) Receive() (btcutil.Address, error) { - res, err := receiveFuture(r) + res, err := receiveFuture(r.responseChannel) if err != nil { return nil, err } @@ -962,7 +986,7 @@ func (r FutureAddWitnessAddressResult) Receive() (btcutil.Address, error) { return nil, err } - return btcutil.DecodeAddress(addr, &chaincfg.MainNetParams) + return btcutil.DecodeAddress(addr, r.network) } // AddWitnessAddressAsync returns an instance of a type that can be used to get @@ -972,7 +996,11 @@ func (r FutureAddWitnessAddressResult) Receive() (btcutil.Address, error) { // See AddWitnessAddress for the blocking version and more details. func (c *Client) AddWitnessAddressAsync(address string) FutureAddWitnessAddressResult { cmd := btcjson.NewAddWitnessAddressCmd(address) - return c.sendCmd(cmd) + response := FutureAddWitnessAddressResult{ + network: c.chainParams, + responseChannel: c.sendCmd(cmd), + } + return response } // AddWitnessAddress adds a witness address for a script and returns the new @@ -983,12 +1011,15 @@ func (c *Client) AddWitnessAddress(address string) (btcutil.Address, error) { // FutureGetAccountAddressResult is a future promise to deliver the result of a // GetAccountAddressAsync RPC invocation (or an applicable error). -type FutureGetAccountAddressResult chan *response +type FutureGetAccountAddressResult struct { + responseChannel chan *response + network *chaincfg.Params +} // Receive waits for the response promised by the future and returns the current // Bitcoin address for receiving payments to the specified account. func (r FutureGetAccountAddressResult) Receive() (btcutil.Address, error) { - res, err := receiveFuture(r) + res, err := receiveFuture(r.responseChannel) if err != nil { return nil, err } @@ -1000,7 +1031,7 @@ func (r FutureGetAccountAddressResult) Receive() (btcutil.Address, error) { return nil, err } - return btcutil.DecodeAddress(addr, &chaincfg.MainNetParams) + return btcutil.DecodeAddress(addr, r.network) } // GetAccountAddressAsync returns an instance of a type that can be used to get @@ -1010,7 +1041,11 @@ func (r FutureGetAccountAddressResult) Receive() (btcutil.Address, error) { // See GetAccountAddress for the blocking version and more details. func (c *Client) GetAccountAddressAsync(account string) FutureGetAccountAddressResult { cmd := btcjson.NewGetAccountAddressCmd(account) - return c.sendCmd(cmd) + result := FutureGetAccountAddressResult{ + network: c.chainParams, + responseChannel: c.sendCmd(cmd), + } + return result } // GetAccountAddress returns the current Bitcoin address for receiving payments @@ -1086,12 +1121,15 @@ func (c *Client) SetAccount(address btcutil.Address, account string) error { // FutureGetAddressesByAccountResult is a future promise to deliver the result // of a GetAddressesByAccountAsync RPC invocation (or an applicable error). -type FutureGetAddressesByAccountResult chan *response +type FutureGetAddressesByAccountResult struct { + responseChannel chan *response + network *chaincfg.Params +} // Receive waits for the response promised by the future and returns the list of // addresses associated with the passed account. func (r FutureGetAddressesByAccountResult) Receive() ([]btcutil.Address, error) { - res, err := receiveFuture(r) + res, err := receiveFuture(r.responseChannel) if err != nil { return nil, err } @@ -1103,17 +1141,15 @@ func (r FutureGetAddressesByAccountResult) Receive() ([]btcutil.Address, error) return nil, err } - addrs := make([]btcutil.Address, 0, len(addrStrings)) - for _, addrStr := range addrStrings { - addr, err := btcutil.DecodeAddress(addrStr, - &chaincfg.MainNetParams) + addresses := make([]btcutil.Address, len(addrStrings)) + for i, addrString := range addrStrings { + addresses[i], err = btcutil.DecodeAddress(addrString, r.network) if err != nil { return nil, err } - addrs = append(addrs, addr) } - return addrs, nil + return addresses, nil } // GetAddressesByAccountAsync returns an instance of a type that can be used to @@ -1123,7 +1159,11 @@ func (r FutureGetAddressesByAccountResult) Receive() ([]btcutil.Address, error) // See GetAddressesByAccount for the blocking version and more details. func (c *Client) GetAddressesByAccountAsync(account string) FutureGetAddressesByAccountResult { cmd := btcjson.NewGetAddressesByAccountCmd(account) - return c.sendCmd(cmd) + result := FutureGetAddressesByAccountResult{ + network: c.chainParams, + responseChannel: c.sendCmd(cmd), + } + return result } // GetAddressesByAccount returns the list of addresses associated with the