Skip to content

Commit

Permalink
rpcclient: Export symbols needed for custom commands (btcsuite#1457)
Browse files Browse the repository at this point in the history
* rpcclient: Export sendCmd and response

This facilitates using custom commands with rpcclient.

See btcsuite#1083

* rpcclient: Export receiveFuture

This facilitates using custom commands with rpcclient.

See btcsuite#1083

* rpcclient: Add customcommand example

* rpcclient: remove "Namecoin" from customcommand readme heading
  • Loading branch information
JeremyRand authored and kcalvinalvin committed Nov 17, 2021
1 parent 6c4d05b commit 12fdc0f
Show file tree
Hide file tree
Showing 11 changed files with 732 additions and 590 deletions.
230 changes: 115 additions & 115 deletions rpcclient/chain.go

Large diffs are not rendered by default.

32 changes: 32 additions & 0 deletions rpcclient/examples/customcommand/README.md
@@ -0,0 +1,32 @@
Custom Command Example
======================

This example shows how to use custom commands with the rpcclient package, by
implementing the `name_show` command from Namecoin Core.

## Running the Example

The first step is to use `go get` to download and install the rpcclient package:

```bash
$ go get github.com/btcsuite/btcd/rpcclient
```

Next, modify the `main.go` source to specify the correct RPC username and
password for the RPC server of your Namecoin Core node:

```Go
User: "yourrpcuser",
Pass: "yourrpcpass",
```

Finally, navigate to the example's directory and run it with:

```bash
$ cd $GOPATH/src/github.com/btcsuite/btcd/rpcclient/examples/customcommand
$ go run *.go
```

## License

This example is licensed under the [copyfree](http://copyfree.org) ISC License.
110 changes: 110 additions & 0 deletions rpcclient/examples/customcommand/main.go
@@ -0,0 +1,110 @@
// Copyright (c) 2014-2017 The btcsuite developers
// Copyright (c) 2019-2020 The Namecoin developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.

package main

import (
"encoding/json"
"log"

"github.com/btcsuite/btcd/btcjson"
"github.com/btcsuite/btcd/rpcclient"
)

// NameShowCmd defines the name_show JSON-RPC command.
type NameShowCmd struct {
Name string
}

// NameShowResult models the data from the name_show command.
type NameShowResult struct {
Name string `json:"name"`
NameEncoding string `json:"name_encoding"`
NameError string `json:"name_error"`
Value string `json:"value"`
ValueEncoding string `json:"value_encoding"`
ValueError string `json:"value_error"`
TxID string `json:"txid"`
Vout uint32 `json:"vout"`
Address string `json:"address"`
IsMine bool `json:"ismine"`
Height int32 `json:"height"`
ExpiresIn int32 `json:"expires_in"`
Expired bool `json:"expired"`
}

// FutureNameShowResult is a future promise to deliver the result
// of a NameShowAsync RPC invocation (or an applicable error).
type FutureNameShowResult chan *rpcclient.Response

// Receive waits for the Response promised by the future and returns detailed
// information about a name.
func (r FutureNameShowResult) Receive() (*NameShowResult, error) {
res, err := rpcclient.ReceiveFuture(r)
if err != nil {
return nil, err
}

// Unmarshal result as a name_show result object
var nameShow NameShowResult
err = json.Unmarshal(res, &nameShow)
if err != nil {
return nil, err
}

return &nameShow, nil
}

// NameShowAsync returns an instance of a type that can be used to get the
// result of the RPC at some future time by invoking the Receive function on
// the returned instance.
//
// See NameShow for the blocking version and more details.
func NameShowAsync(c *rpcclient.Client, name string) FutureNameShowResult {
cmd := &NameShowCmd{
Name: name,
}
return c.SendCmd(cmd)
}

// NameShow returns detailed information about a name.
func NameShow(c *rpcclient.Client, name string) (*NameShowResult, error) {
return NameShowAsync(c, name).Receive()
}

func init() {
// No special flags for commands in this file.
flags := btcjson.UsageFlag(0)

btcjson.MustRegisterCmd("name_show", (*NameShowCmd)(nil), flags)
}

func main() {
// Connect to local namecoin core RPC server using HTTP POST mode.
connCfg := &rpcclient.ConnConfig{
Host: "localhost:8336",
User: "yourrpcuser",
Pass: "yourrpcpass",
HTTPPostMode: true, // Namecoin core only supports HTTP POST mode
DisableTLS: true, // Namecoin core does not provide TLS by default
}
// Notice the notification parameter is nil since notifications are
// not supported in HTTP POST mode.
client, err := rpcclient.New(connCfg, nil)
if err != nil {
log.Fatal(err)
}
defer client.Shutdown()

// Get the current block count.
result, err := NameShow(client, "d/namecoin")
if err != nil {
log.Fatal(err)
}

value := result.Value

log.Printf("Value of d/namecoin: %s", value)
}
72 changes: 36 additions & 36 deletions rpcclient/extensions.go
Expand Up @@ -20,13 +20,13 @@ import (

// FutureDebugLevelResult is a future promise to deliver the result of a
// DebugLevelAsync RPC invocation (or an applicable error).
type FutureDebugLevelResult chan *response
type FutureDebugLevelResult chan *Response

// Receive waits for the response promised by the future and returns the result
// Receive waits for the Response promised by the future and returns the result
// of setting the debug logging level to the passed level specification or the
// list of of the available subsystems for the special keyword 'show'.
func (r FutureDebugLevelResult) Receive() (string, error) {
res, err := receiveFuture(r)
res, err := ReceiveFuture(r)
if err != nil {
return "", err
}
Expand All @@ -49,7 +49,7 @@ func (r FutureDebugLevelResult) Receive() (string, error) {
// NOTE: This is a btcd extension.
func (c *Client) DebugLevelAsync(levelSpec string) FutureDebugLevelResult {
cmd := btcjson.NewDebugLevelCmd(levelSpec)
return c.sendCmd(cmd)
return c.SendCmd(cmd)
}

// DebugLevel dynamically sets the debug logging level to the passed level
Expand All @@ -68,11 +68,11 @@ func (c *Client) DebugLevel(levelSpec string) (string, error) {

// FutureCreateEncryptedWalletResult is a future promise to deliver the error
// result of a CreateEncryptedWalletAsync RPC invocation.
type FutureCreateEncryptedWalletResult chan *response
type FutureCreateEncryptedWalletResult chan *Response

// Receive waits for and returns the error response promised by the future.
// Receive waits for and returns the error Response promised by the future.
func (r FutureCreateEncryptedWalletResult) Receive() error {
_, err := receiveFuture(r)
_, err := ReceiveFuture(r)
return err
}

Expand All @@ -85,7 +85,7 @@ func (r FutureCreateEncryptedWalletResult) Receive() error {
// NOTE: This is a btcwallet extension.
func (c *Client) CreateEncryptedWalletAsync(passphrase string) FutureCreateEncryptedWalletResult {
cmd := btcjson.NewCreateEncryptedWalletCmd(passphrase)
return c.sendCmd(cmd)
return c.SendCmd(cmd)
}

// CreateEncryptedWallet requests the creation of an encrypted wallet. Wallets
Expand All @@ -102,12 +102,12 @@ func (c *Client) CreateEncryptedWallet(passphrase string) error {

// FutureListAddressTransactionsResult is a future promise to deliver the result
// of a ListAddressTransactionsAsync RPC invocation (or an applicable error).
type FutureListAddressTransactionsResult chan *response
type FutureListAddressTransactionsResult chan *Response

// Receive waits for the response promised by the future and returns information
// Receive waits for the Response promised by the future and returns information
// about all transactions associated with the provided addresses.
func (r FutureListAddressTransactionsResult) Receive() ([]btcjson.ListTransactionsResult, error) {
res, err := receiveFuture(r)
res, err := ReceiveFuture(r)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -135,7 +135,7 @@ func (c *Client) ListAddressTransactionsAsync(addresses []btcutil.Address, accou
addrs = append(addrs, addr.EncodeAddress())
}
cmd := btcjson.NewListAddressTransactionsCmd(addrs, &account)
return c.sendCmd(cmd)
return c.SendCmd(cmd)
}

// ListAddressTransactions returns information about all transactions associated
Expand All @@ -148,12 +148,12 @@ func (c *Client) ListAddressTransactions(addresses []btcutil.Address, account st

// FutureGetBestBlockResult is a future promise to deliver the result of a
// GetBestBlockAsync RPC invocation (or an applicable error).
type FutureGetBestBlockResult chan *response
type FutureGetBestBlockResult chan *Response

// Receive waits for the response promised by the future and returns the hash
// Receive waits for the Response promised by the future and returns the hash
// and height of the block in the longest (best) chain.
func (r FutureGetBestBlockResult) Receive() (*chainhash.Hash, int32, error) {
res, err := receiveFuture(r)
res, err := ReceiveFuture(r)
if err != nil {
return nil, 0, err
}
Expand Down Expand Up @@ -183,7 +183,7 @@ func (r FutureGetBestBlockResult) Receive() (*chainhash.Hash, int32, error) {
// NOTE: This is a btcd extension.
func (c *Client) GetBestBlockAsync() FutureGetBestBlockResult {
cmd := btcjson.NewGetBestBlockCmd()
return c.sendCmd(cmd)
return c.SendCmd(cmd)
}

// GetBestBlock returns the hash and height of the block in the longest (best)
Expand All @@ -196,12 +196,12 @@ func (c *Client) GetBestBlock() (*chainhash.Hash, int32, error) {

// FutureGetCurrentNetResult is a future promise to deliver the result of a
// GetCurrentNetAsync RPC invocation (or an applicable error).
type FutureGetCurrentNetResult chan *response
type FutureGetCurrentNetResult chan *Response

// Receive waits for the response promised by the future and returns the network
// Receive waits for the Response promised by the future and returns the network
// the server is running on.
func (r FutureGetCurrentNetResult) Receive() (wire.BitcoinNet, error) {
res, err := receiveFuture(r)
res, err := ReceiveFuture(r)
if err != nil {
return 0, err
}
Expand All @@ -225,7 +225,7 @@ func (r FutureGetCurrentNetResult) Receive() (wire.BitcoinNet, error) {
// NOTE: This is a btcd extension.
func (c *Client) GetCurrentNetAsync() FutureGetCurrentNetResult {
cmd := btcjson.NewGetCurrentNetCmd()
return c.sendCmd(cmd)
return c.SendCmd(cmd)
}

// GetCurrentNet returns the network the server is running on.
Expand All @@ -240,15 +240,15 @@ func (c *Client) GetCurrentNet() (wire.BitcoinNet, error) {
//
// NOTE: This is a btcsuite extension ported from
// github.com/decred/dcrrpcclient.
type FutureGetHeadersResult chan *response
type FutureGetHeadersResult chan *Response

// Receive waits for the response promised by the future and returns the
// Receive waits for the Response promised by the future and returns the
// getheaders result.
//
// NOTE: This is a btcsuite extension ported from
// github.com/decred/dcrrpcclient.
func (r FutureGetHeadersResult) Receive() ([]wire.BlockHeader, error) {
res, err := receiveFuture(r)
res, err := ReceiveFuture(r)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -292,7 +292,7 @@ func (c *Client) GetHeadersAsync(blockLocators []chainhash.Hash, hashStop *chain
hash = hashStop.String()
}
cmd := btcjson.NewGetHeadersCmd(locators, hash)
return c.sendCmd(cmd)
return c.SendCmd(cmd)
}

// GetHeaders mimics the wire protocol getheaders and headers messages by
Expand All @@ -307,12 +307,12 @@ func (c *Client) GetHeaders(blockLocators []chainhash.Hash, hashStop *chainhash.

// FutureExportWatchingWalletResult is a future promise to deliver the result of
// an ExportWatchingWalletAsync RPC invocation (or an applicable error).
type FutureExportWatchingWalletResult chan *response
type FutureExportWatchingWalletResult chan *Response

// Receive waits for the response promised by the future and returns the
// Receive waits for the Response promised by the future and returns the
// exported wallet.
func (r FutureExportWatchingWalletResult) Receive() ([]byte, []byte, error) {
res, err := receiveFuture(r)
res, err := ReceiveFuture(r)
if err != nil {
return nil, nil, err
}
Expand Down Expand Up @@ -361,7 +361,7 @@ func (r FutureExportWatchingWalletResult) Receive() ([]byte, []byte, error) {
// NOTE: This is a btcwallet extension.
func (c *Client) ExportWatchingWalletAsync(account string) FutureExportWatchingWalletResult {
cmd := btcjson.NewExportWatchingWalletCmd(&account, btcjson.Bool(true))
return c.sendCmd(cmd)
return c.SendCmd(cmd)
}

// ExportWatchingWallet returns the raw bytes for a watching-only version of
Expand All @@ -376,12 +376,12 @@ func (c *Client) ExportWatchingWallet(account string) ([]byte, []byte, error) {

// FutureSessionResult is a future promise to deliver the result of a
// SessionAsync RPC invocation (or an applicable error).
type FutureSessionResult chan *response
type FutureSessionResult chan *Response

// Receive waits for the response promised by the future and returns the
// Receive waits for the Response promised by the future and returns the
// session result.
func (r FutureSessionResult) Receive() (*btcjson.SessionResult, error) {
res, err := receiveFuture(r)
res, err := ReceiveFuture(r)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -410,7 +410,7 @@ func (c *Client) SessionAsync() FutureSessionResult {
}

cmd := btcjson.NewSessionCmd()
return c.sendCmd(cmd)
return c.SendCmd(cmd)
}

// Session returns details regarding a websocket client's current connection.
Expand All @@ -427,16 +427,16 @@ func (c *Client) Session() (*btcjson.SessionResult, error) {
//
// NOTE: This is a btcsuite extension ported from
// github.com/decred/dcrrpcclient.
type FutureVersionResult chan *response
type FutureVersionResult chan *Response

// Receive waits for the response promised by the future and returns the version
// Receive waits for the Response promised by the future and returns the version
// result.
//
// NOTE: This is a btcsuite extension ported from
// github.com/decred/dcrrpcclient.
func (r FutureVersionResult) Receive() (map[string]btcjson.VersionResult,
error) {
res, err := receiveFuture(r)
res, err := ReceiveFuture(r)
if err != nil {
return nil, err
}
Expand All @@ -461,7 +461,7 @@ func (r FutureVersionResult) Receive() (map[string]btcjson.VersionResult,
// github.com/decred/dcrrpcclient.
func (c *Client) VersionAsync() FutureVersionResult {
cmd := btcjson.NewVersionCmd()
return c.sendCmd(cmd)
return c.SendCmd(cmd)
}

// Version returns information about the server's JSON-RPC API versions.
Expand Down

0 comments on commit 12fdc0f

Please sign in to comment.